15 added + 1 modified, total 16 files
- TODO:
- FIXME("(this=%p,0x%08lx): stub\n",This,(DWORD)hnd);
- FIXME("(this=%p,%p,%p,%08lx): stub!\n", iface, lpCallback, lpvRef, dwFlags);
- FIXME("(this=%p,%p,%p,%08lx): stub!\n", iface, lpCallback, lpvRef, dwFlags);
- FIXME("(this=%p,%s,%p): stub!\n",
- FIXME("(this=%p,%p,%ld,0x%08lx): stub!\n",
- FIXME("(this=%p,%p,%ld,0x%08lx): stub!\n",
- FIXME("(this=%p,%p): stub!\n",
- FIXME("(this=%p,%p): stub!\n",
- FIXME("(this=%p,%p,0x%08lx): stub!\n",
- FIXME("(this=%p,%p,%ld,%s): stub!\n",
- FIXME("(this=%p,%s,%p,%p,%p): stub!\n",
- FIXME("(this=%p,%p,%p,0x%08lx): stub!\n",
- FIXME("(this=%p,%p,%p,0x%08lx): stub!\n",
- FIXME("(this=%p,%p,%s): stub!\n",
- FIXME("(this=%p,%p,%s): stub!\n",
- FIXME("(this=%p,%p): stub!\n",
- FIXME("(this=%p,0x%08lx): stub!\n",
- FIXME("(this=%p,%p,%p,0x%08lx): stub!\n",
- FIXME("(this=%p,%p): stub!\n",
- FIXME("(this=%p,0x%08lx,%p,%p,0x%08lx): stub!\n",
- FIXME("(%p)->(%s,%p,%p,%08lx): stub !\n", iface, lpszFileName, pec, pvRef, dwFlags);
- FIXME("(%p)->(%s,%p,%p,%08lx): stub !\n", iface, debugstr_w(lpszFileName), pec, pvRef, dwFlags);
- FIXME("(%p)->(%s,%08lx,%p,%08lx): stub !\n", iface, lpszFileName, dwEntries, rgDiFileEft, dwFlags);
- FIXME("(%p)->(%s,%08lx,%p,%08lx): stub !\n", iface, debugstr_w(lpszFileName), dwEntries, rgDiFileEft, dwFlags);
- FIXME("(%p)->(%p,%s,%08lx): stub !\n", iface, lpdiaf, lpszUserName, dwFlags);
- FIXME("(%p)->(%p,%s,%08lx): stub !\n", iface, lpdiaf, debugstr_w(lpszUserName), dwFlags);
- FIXME("(%p)->(%p,%s,%08lx): stub !\n", iface, lpdiaf, lpszUserName, dwFlags);
- FIXME("(%p)->(%p,%s,%08lx): stub !\n", iface, lpdiaf, debugstr_w(lpszUserName), dwFlags);
- FIXME("(%p)->(%p): stub !\n", iface, lpdiDevImageInfoHeader);
- FIXME("(%p)->(%p): stub !\n", iface, lpdiDevImageInfoHeader);
- FIXME("(%p)->(%s): stub\n",This,debugstr_guid(rguid));
- FIXME("(%p)->(%08lx,%08lx): stub\n",This, (DWORD) hwndOwner, dwFlags);
- FIXME("(%p)->(%s, %s, %p): stub\n", This, debugstr_guid(rguid), pszName, pguidInstance);
- FIXME("(%p)->(%s, %s, %p): stub\n", This, debugstr_guid(rguid), debugstr_w(pszName), pguidInstance);
- FIXME("(this=%p,%s,%p,%p,%p,%04lx): stub\n", This, ptszUserName, lpdiActionFormat,
- FIXME("(this=%p,%s,%p,%p,%p,%04lx): stub\n", This, debugstr_w(ptszUserName), lpdiActionFormat,
- FIXME("(this=%p,%p,%p,%04lx,%p): stub\n", This, lpdiCallback, lpdiCDParams,
- FIXME("(this=%p,%p,%p,%04lx,%p): stub\n", This, lpdiCallback, lpdiCDParams,
- FIXME("(%p)->(%s,%p),stub!\n",This,debugstr_guid(riid),ppobj);
- FIXME: reuse already created dinput if present? */
- FIXME("(%p,%p,%s,%p) Interface not found!\n",This,pOuter,debugstr_guid(riid),ppobj);
- FIXME("(%p)->(%d),stub!\n",This,dolock);
- FIXME("(void): stub\n");
- FIXME("(%p,%p,%p): no interface found.\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
- FIXME do deadzone and saturation here */
- FIXME don't go off array */
- FIXME("found a joystick at %s!\n",buf);
- TODO:
- FIXME("axe %d: cur=%d, min=%d, max=%d, fuzz=%d, flat=%d\n",
- FIXME("%d in deadzone, return mid.\n",val);
- FIXME("unhandled joystick button %x, value %d\n",ie.code,ie.value);
- FIXME("unhandled joystick axe event (code %d, value %d)\n",ie.code,ie.value);
- FIXME("joystick cannot handle type %d event (code %d)\n",ie.type,ie.code);
- FIXME("len %ld is not sizeof(DIJOYSTATE) or DIJOYSTATE2, unsupported format.\n",len);
- FIXME("(%p)->(dods=%ld,entries=%ld,fl=0x%08lx),STUB!\n",This,dodsize,*entries,flags);
- FIXME("DIGDD_PEEK\n");
- FIXME("(this=%p,%s,%p)\n",This,debugstr_guid(rguid),ph);
- FIXME("ph.dwSize = %ld, ph.dwHeaderSize =%ld, ph.dwObj = %ld, ph.dwHow= %ld\n",ph->dwSize, ph->dwHeaderSize,ph->dwObj,ph->dwHow);
- FIXME("buffersize = %ld\n",pd->dwData);
- FIXME("proprange(%ld,%ld)\n",pr->lMin,pr->lMax);
- FIXME("setting proprange %ld - %ld for dwObj %ld\n",pr->lMin,pr->lMax,ph->dwObj);
- FIXME("setting deadzone(%ld)\n",pd->dwData);
- FIXME("Unknown type %ld (%s)\n",(DWORD)rguid,debugstr_guid(rguid));
- FIXME: needs more items */
- FIXME("unhandled abs axis %d, ignoring!\n",i);
- FIXME("unimplemented axis range query.\n");
- FIXME: currently this can be only one.
- FIXME("Not more than one keyboard can be acquired at the same time.\n");
- FIXME: This is ugly and not thread safe :/ */
- FIXME: This is ugly but needed on Windows */
- FIXME mouse are bit choppy here.
- FIXME("Unknown type %ld (%s)\n",(DWORD)rguid,debugstr_guid(rguid));
- FIXME("Unknown type %ld (%s)\n",(DWORD)rguid,debugstr_guid(rguid));
reactos/lib/dinput
diff -N Makefile
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ Makefile 29 Nov 2004 00:13:49 -0000 1.4
@@ -0,0 +1,9 @@
+# $Id: Makefile,v 1.4 2004/11/29 00:13:49 greatlrd Exp $
+
+PATH_TO_TOP = ../..
+
+TARGET_TYPE = winedll
+
+include $(PATH_TO_TOP)/rules.mak
+
+include $(TOOLS_PATH)/helper.mk
reactos/lib/dinput
diff -N Makefile.in
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ Makefile.in 29 Nov 2004 00:13:49 -0000 1.1
@@ -0,0 +1,23 @@
+TOPSRCDIR = @top_srcdir@
+TOPOBJDIR = ../..
+SRCDIR = @srcdir@
+VPATH = @srcdir@
+MODULE = dinput.dll
+IMPORTS = ole32 user32 advapi32 kernel32
+EXTRALIBS = -ldxguid -luuid
+
+C_SRCS = \
+ data_formats.c \
+ device.c \
+ dinput_main.c \
+ joystick_linux.c \
+ joystick_linuxinput.c \
+ keyboard.c \
+ mouse.c \
+ regsvr.c
+
+RC_SRCS = version.rc
+
+@MAKE_DLL_RULES@
+
+### Dependencies:
reactos/lib/dinput
diff -N Makefile.ros
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ Makefile.ros 29 Nov 2004 00:13:49 -0000 1.1
@@ -0,0 +1,28 @@
+# $Id: Makefile.ros,v 1.1 2004/11/29 00:13:49 greatlrd Exp $
+
+TARGET_NAME = dinput
+
+TARGET_OBJECTS = data_formats.o device.o dinput_main.o joystick_linux.o joystick_linuxinput.o keyboard.o mouse.o regsvr.o
+
+TARGET_CFLAGS = -D__REACTOS__
+
+TARGET_SDKLIBS = libwine.a ole32.a user32.a advapi32.a kernel32.a ole32.a wine_uuid.a ntdll.a winmm.a dxguid.a
+
+
+
+TARGET_RC_SRCS = version.rc
+TARGET_RC_BINSRC =
+TARGET_RC_BINARIES =
+
+default: all
+
+authors.c:
+ifeq ($(HOST),mingw32-linux)
+ echo 'const char * const SHELL_Authors[] = { "WINE team", "ReactOS team", 0 };' > authors.c
+else
+ echo const char * const SHELL_Authors[] = { "WINE team", "ReactOS team", 0 }; > authors.c
+endif
+
+DEP_OBJECTS = $(TARGET_OBJECTS)
+
+include $(TOOLS_PATH)/depend.mk
reactos/lib/dinput
diff -N Makefile.ros-template
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ Makefile.ros-template 29 Nov 2004 00:13:49 -0000 1.1
@@ -0,0 +1,28 @@
+# $Id: Makefile.ros-template,v 1.1 2004/11/29 00:13:49 greatlrd Exp $
+
+TARGET_NAME = dinput
+
+TARGET_OBJECTS = @C_SRCS@
+
+TARGET_CFLAGS = @EXTRADEFS@ -D__REACTOS__
+
+TARGET_SDKLIBS = libwine.a @IMPORTS@ ole32.a wine_uuid.a ntdll.a winmm.a dxguid.a
+
+
+
+TARGET_RC_SRCS = @RC_SRCS@
+TARGET_RC_BINSRC = @RC_BINSRC@
+TARGET_RC_BINARIES = @RC_BINARIES@
+
+default: all
+
+authors.c:
+ifeq ($(HOST),mingw32-linux)
+ echo 'const char * const SHELL_Authors[] = { "WINE team", "ReactOS team", 0 };' > authors.c
+else
+ echo const char * const SHELL_Authors[] = { "WINE team", "ReactOS team", 0 }; > authors.c
+endif
+
+DEP_OBJECTS = $(TARGET_OBJECTS)
+
+include $(TOOLS_PATH)/depend.mk
reactos/lib/dinput
diff -N data_formats.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ data_formats.c 29 Nov 2004 00:13:49 -0000 1.1
@@ -0,0 +1,302 @@
+/*
+ * Copyright (c) 2004 Robert Reif
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* TODO:
+ * add keyboard
+ */
+
+#include <stdarg.h>
+
+#include "windef.h"
+#include "dinput.h"
+
+#define numObjects(x) (sizeof(x) / sizeof(x[0]))
+
+DIOBJECTDATAFORMAT dfDIJoystick[] = {
+ { &GUID_XAxis,DIJOFS_X,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
+ { &GUID_YAxis,DIJOFS_Y,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
+ { &GUID_ZAxis,DIJOFS_Z,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
+ { &GUID_RxAxis,DIJOFS_RX,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
+ { &GUID_RyAxis,DIJOFS_RY,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
+ { &GUID_RzAxis,DIJOFS_RZ,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
+ { &GUID_Slider,DIJOFS_SLIDER(0),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
+ { &GUID_Slider,DIJOFS_SLIDER(1),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
+ { &GUID_POV,DIJOFS_POV(0),DIDFT_OPTIONAL|DIDFT_POV|DIDFT_ANYINSTANCE,0},
+ { &GUID_POV,DIJOFS_POV(1),DIDFT_OPTIONAL|DIDFT_POV|DIDFT_ANYINSTANCE,0},
+ { &GUID_POV,DIJOFS_POV(2),DIDFT_OPTIONAL|DIDFT_POV|DIDFT_ANYINSTANCE,0},
+ { &GUID_POV,DIJOFS_POV(3),DIDFT_OPTIONAL|DIDFT_POV|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(0),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(1),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(2),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(3),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(4),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(5),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(6),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(7),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(8),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(9),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(10),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(11),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(12),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(13),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(14),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(15),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(16),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(17),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(18),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(19),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(20),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(21),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(22),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(23),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(24),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(25),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(26),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(27),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(28),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(29),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(30),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(31),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+};
+
+const DIDATAFORMAT c_dfDIJoystick = {
+ sizeof(DIDATAFORMAT),
+ sizeof(DIOBJECTDATAFORMAT),
+ DIDF_ABSAXIS,
+ sizeof(DIJOYSTATE2),
+ numObjects(dfDIJoystick),
+ dfDIJoystick
+};
+
+DIOBJECTDATAFORMAT dfDIJoystick2[] = {
+ { &GUID_XAxis,DIJOFS_X,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
+ { &GUID_YAxis,DIJOFS_Y,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
+ { &GUID_ZAxis,DIJOFS_Z,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
+ { &GUID_RxAxis,DIJOFS_RX,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
+ { &GUID_RyAxis,DIJOFS_RY,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
+ { &GUID_RzAxis,DIJOFS_RZ,DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
+ { &GUID_Slider,DIJOFS_SLIDER(0),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
+ { &GUID_Slider,DIJOFS_SLIDER(1),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
+ { &GUID_POV,DIJOFS_POV(0),DIDFT_OPTIONAL|DIDFT_POV|DIDFT_ANYINSTANCE,0},
+ { &GUID_POV,DIJOFS_POV(1),DIDFT_OPTIONAL|DIDFT_POV|DIDFT_ANYINSTANCE,0},
+ { &GUID_POV,DIJOFS_POV(2),DIDFT_OPTIONAL|DIDFT_POV|DIDFT_ANYINSTANCE,0},
+ { &GUID_POV,DIJOFS_POV(3),DIDFT_OPTIONAL|DIDFT_POV|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(0),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(1),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(2),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(3),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(4),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(5),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(6),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(7),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(8),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(9),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(10),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(11),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(12),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(13),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(14),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(15),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(16),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(17),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(18),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(19),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(20),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(21),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(22),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(23),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(24),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(25),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(26),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(27),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(28),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(29),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(30),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(31),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(32),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(33),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(34),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(35),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(36),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(37),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(38),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(39),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(40),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(41),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(42),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(43),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(44),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(45),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(46),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(47),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(48),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(49),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(50),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(51),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(52),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(53),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(54),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(55),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(56),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(57),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(58),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(59),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(60),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(61),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(62),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(63),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(64),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(65),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(66),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(67),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(68),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(69),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(70),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(71),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(72),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(73),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(74),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(75),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(76),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(77),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(78),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(79),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(80),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(81),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(82),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(83),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(84),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(85),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(86),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(87),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(88),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(89),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(90),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(91),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(92),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(93),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(94),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(95),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(96),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(97),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(98),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(99),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(100),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(101),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(102),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(103),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(104),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(105),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(106),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(107),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(108),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(109),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(110),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(111),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(112),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(113),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(114),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(115),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(116),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(117),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(118),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(119),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(120),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(121),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(122),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(123),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(124),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(125),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(126),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { NULL,DIJOFS_BUTTON(127),DIDFT_OPTIONAL|DIDFT_BUTTON|DIDFT_ANYINSTANCE,0},
+ { &GUID_XAxis,FIELD_OFFSET(DIJOYSTATE2,lVX),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
+ { &GUID_YAxis,FIELD_OFFSET(DIJOYSTATE2,lVY),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
+ { &GUID_ZAxis,FIELD_OFFSET(DIJOYSTATE2,lVZ),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
+ { &GUID_RxAxis,FIELD_OFFSET(DIJOYSTATE2,lVRx),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
+ { &GUID_RyAxis,FIELD_OFFSET(DIJOYSTATE2,lVRy),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
+ { &GUID_RzAxis,FIELD_OFFSET(DIJOYSTATE2,lVRz),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
+ { &GUID_Slider,FIELD_OFFSET(DIJOYSTATE2,rglVSlider[0]),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
+ { &GUID_Slider,FIELD_OFFSET(DIJOYSTATE2,rglVSlider[1]),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
+ { &GUID_XAxis,FIELD_OFFSET(DIJOYSTATE2,lAX),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
+ { &GUID_YAxis,FIELD_OFFSET(DIJOYSTATE2,lAY),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
+ { &GUID_ZAxis,FIELD_OFFSET(DIJOYSTATE2,lAZ),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
+ { &GUID_RxAxis,FIELD_OFFSET(DIJOYSTATE2,lARx),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
+ { &GUID_RyAxis,FIELD_OFFSET(DIJOYSTATE2,lARy),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
+ { &GUID_RzAxis,FIELD_OFFSET(DIJOYSTATE2,lARz),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
+ { &GUID_Slider,FIELD_OFFSET(DIJOYSTATE2,rglASlider[0]),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
+ { &GUID_Slider,FIELD_OFFSET(DIJOYSTATE2,rglASlider[1]),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
+ { &GUID_XAxis,FIELD_OFFSET(DIJOYSTATE2,lFX),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
+ { &GUID_YAxis,FIELD_OFFSET(DIJOYSTATE2,lFY),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
+ { &GUID_ZAxis,FIELD_OFFSET(DIJOYSTATE2,lFZ),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
+ { &GUID_RxAxis,FIELD_OFFSET(DIJOYSTATE2,lFRx),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
+ { &GUID_RyAxis,FIELD_OFFSET(DIJOYSTATE2,lFRy),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
+ { &GUID_RzAxis,FIELD_OFFSET(DIJOYSTATE2,lFRz),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
+ { &GUID_Slider,FIELD_OFFSET(DIJOYSTATE2,rglFSlider[0]),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
+ { &GUID_Slider,FIELD_OFFSET(DIJOYSTATE2,rglFSlider[1]),DIDFT_OPTIONAL|DIDFT_AXIS|DIDFT_ANYINSTANCE,0},
+};
+
+const DIDATAFORMAT c_dfDIJoystick2 = {
+ sizeof(DIDATAFORMAT),
+ sizeof(DIOBJECTDATAFORMAT),
+ DIDF_ABSAXIS,
+ sizeof(DIJOYSTATE2),
+ numObjects(dfDIJoystick2),
+ dfDIJoystick2
+};
+
+DIOBJECTDATAFORMAT dfDIMouse[] = {
+ { &GUID_XAxis, DIMOFS_X, DIDFT_ANYINSTANCE | DIDFT_AXIS, 0 },
+ { &GUID_YAxis, DIMOFS_Y, DIDFT_ANYINSTANCE | DIDFT_AXIS, 0 },
+ { &GUID_ZAxis, DIMOFS_Z, DIDFT_OPTIONAL | DIDFT_ANYINSTANCE | DIDFT_AXIS, 0 },
+ { &GUID_Button, DIMOFS_BUTTON0, DIDFT_ANYINSTANCE | DIDFT_BUTTON, 0 },
+ { &GUID_Button, DIMOFS_BUTTON1, DIDFT_ANYINSTANCE | DIDFT_BUTTON, 0 },
+ { &GUID_Button, DIMOFS_BUTTON2, DIDFT_OPTIONAL | DIDFT_ANYINSTANCE | DIDFT_BUTTON, 0 },
+ { &GUID_Button, DIMOFS_BUTTON3, DIDFT_OPTIONAL | DIDFT_ANYINSTANCE | DIDFT_BUTTON, 0 }
+};
+
+const DIDATAFORMAT c_dfDIMouse = {
+ sizeof(DIDATAFORMAT),
+ sizeof(DIOBJECTDATAFORMAT),
+ DIDF_RELAXIS,
+ sizeof(DIMOUSESTATE),
+ numObjects(dfDIMouse),
+ dfDIMouse
+};
+
+DIOBJECTDATAFORMAT dfDIMouse2[] = {
+ { &GUID_XAxis, DIMOFS_X, DIDFT_ANYINSTANCE | DIDFT_AXIS, 0 },
+ { &GUID_YAxis, DIMOFS_Y, DIDFT_ANYINSTANCE | DIDFT_AXIS, 0 },
+ { &GUID_ZAxis, DIMOFS_Z, DIDFT_OPTIONAL | DIDFT_ANYINSTANCE | DIDFT_AXIS, 0 },
+ { &GUID_Button, DIMOFS_BUTTON0, DIDFT_ANYINSTANCE | DIDFT_BUTTON, 0 },
+ { &GUID_Button, DIMOFS_BUTTON1, DIDFT_ANYINSTANCE | DIDFT_BUTTON, 0 },
+ { &GUID_Button, DIMOFS_BUTTON2, DIDFT_OPTIONAL | DIDFT_ANYINSTANCE | DIDFT_BUTTON, 0 },
+ { &GUID_Button, DIMOFS_BUTTON3, DIDFT_OPTIONAL | DIDFT_ANYINSTANCE | DIDFT_BUTTON, 0 },
+ { &GUID_Button, DIMOFS_BUTTON4, DIDFT_OPTIONAL | DIDFT_ANYINSTANCE | DIDFT_BUTTON, 0 },
+ { &GUID_Button, DIMOFS_BUTTON5, DIDFT_OPTIONAL | DIDFT_ANYINSTANCE | DIDFT_BUTTON, 0 },
+ { &GUID_Button, DIMOFS_BUTTON6, DIDFT_OPTIONAL | DIDFT_ANYINSTANCE | DIDFT_BUTTON, 0 },
+ { &GUID_Button, DIMOFS_BUTTON7, DIDFT_OPTIONAL | DIDFT_ANYINSTANCE | DIDFT_BUTTON, 0 }
+};
+
+const DIDATAFORMAT c_dfDIMouse2 = {
+ sizeof(DIDATAFORMAT),
+ sizeof(DIOBJECTDATAFORMAT),
+ DIDF_RELAXIS,
+ sizeof(DIMOUSESTATE2),
+ numObjects(dfDIMouse2),
+ dfDIMouse2
+};
reactos/lib/dinput
diff -N device.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ device.c 29 Nov 2004 00:13:49 -0000 1.1
@@ -0,0 +1,884 @@
+/* DirectInput Device
+ *
+ * Copyright 1998 Marcus Meissner
+ * Copyright 1998,1999 Lionel Ulmer
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/* This file contains all the Device specific functions that can be used as stubs
+ by real device implementations.
+
+ It also contains all the helper functions.
+*/
+#include "config.h"
+
+#include <stdarg.h>
+#include <string.h>
+#include "wine/debug.h"
+#include "wine/unicode.h"
+#include "windef.h"
+#include "winbase.h"
+#include "winerror.h"
+#include "dinput.h"
+#include "device_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(dinput);
+
+/******************************************************************************
+ * Various debugging tools
+ */
+void _dump_cooperativelevel_DI(DWORD dwFlags) {
+ if (TRACE_ON(dinput)) {
+ unsigned int i;
+ static const struct {
+ DWORD mask;
+ const char *name;
+ } flags[] = {
+#define FE(x) { x, #x}
+ FE(DISCL_BACKGROUND),
+ FE(DISCL_EXCLUSIVE),
+ FE(DISCL_FOREGROUND),
+ FE(DISCL_NONEXCLUSIVE)
+#undef FE
+ };
+ for (i = 0; i < (sizeof(flags) / sizeof(flags[0])); i++)
+ if (flags[i].mask & dwFlags)
+ DPRINTF("%s ",flags[i].name);
+ DPRINTF("\n");
+ }
+}
+
+void _dump_EnumObjects_flags(DWORD dwFlags) {
+ if (TRACE_ON(dinput)) {
+ unsigned int i;
+ DWORD type, instance;
+ static const struct {
+ DWORD mask;
+ const char *name;
+ } flags[] = {
+#define FE(x) { x, #x}
+ FE(DIDFT_RELAXIS),
+ FE(DIDFT_ABSAXIS),
+ FE(DIDFT_PSHBUTTON),
+ FE(DIDFT_TGLBUTTON),
+ FE(DIDFT_POV),
+ FE(DIDFT_COLLECTION),
+ FE(DIDFT_NODATA),
+ FE(DIDFT_FFACTUATOR),
+ FE(DIDFT_FFEFFECTTRIGGER),
+ FE(DIDFT_OUTPUT)
+#undef FE
+ };
+ type = (dwFlags & 0xFF0000FF);
+ instance = ((dwFlags >> 8) & 0xFFFF);
+ DPRINTF("Type:");
+ if (type == DIDFT_ALL) {
+ DPRINTF(" DIDFT_ALL");
+ } else {
+ for (i = 0; i < (sizeof(flags) / sizeof(flags[0])); i++) {
+ if (flags[i].mask & type) {
+ type &= ~flags[i].mask;
+ DPRINTF(" %s",flags[i].name);
+ }
+ }
+ if (type) {
+ DPRINTF(" (unhandled: %08lx)", type);
+ }
+ }
+ DPRINTF(" / Instance: ");
+ if (instance == ((DIDFT_ANYINSTANCE >> 8) & 0xFFFF)) {
+ DPRINTF("DIDFT_ANYINSTANCE");
+ } else {
+ DPRINTF("%3ld", instance);
+ }
+ }
+}
+
+void _dump_DIPROPHEADER(LPCDIPROPHEADER diph) {
+ if (TRACE_ON(dinput)) {
+ DPRINTF(" - dwObj = 0x%08lx\n", diph->dwObj);
+ DPRINTF(" - dwHow = %s\n",
+ ((diph->dwHow == DIPH_DEVICE) ? "DIPH_DEVICE" :
+ ((diph->dwHow == DIPH_BYOFFSET) ? "DIPH_BYOFFSET" :
+ ((diph->dwHow == DIPH_BYID)) ? "DIPH_BYID" : "unknown")));
+ }
+}
+
+void _dump_OBJECTINSTANCEA(DIDEVICEOBJECTINSTANCEA *ddoi) {
+ if (TRACE_ON(dinput)) {
+ DPRINTF(" - enumerating : %s ('%s') - %2ld - 0x%08lx - %s\n",
+ debugstr_guid(&ddoi->guidType), _dump_dinput_GUID(&ddoi->guidType), ddoi->dwOfs, ddoi->dwType, ddoi->tszName);
+ }
+}
+
+void _dump_OBJECTINSTANCEW(DIDEVICEOBJECTINSTANCEW *ddoi) {
+ if (TRACE_ON(dinput)) {
+ DPRINTF(" - enumerating : %s ('%s'), - %2ld - 0x%08lx - %s\n",
+ debugstr_guid(&ddoi->guidType), _dump_dinput_GUID(&ddoi->guidType), ddoi->dwOfs, ddoi->dwType, debugstr_w(ddoi->tszName));
+ }
+}
+
+/* This function is a helper to convert a GUID into any possible DInput GUID out there */
+const char *_dump_dinput_GUID(const GUID *guid) {
+ unsigned int i;
+ static const struct {
+ const GUID *guid;
+ const char *name;
+ } guids[] = {
+#define FE(x) { &x, #x}
+ FE(GUID_XAxis),
+ FE(GUID_YAxis),
+ FE(GUID_ZAxis),
+ FE(GUID_RxAxis),
+ FE(GUID_RyAxis),
+ FE(GUID_RzAxis),
+ FE(GUID_Slider),
+ FE(GUID_Button),
+ FE(GUID_Key),
+ FE(GUID_POV),
+ FE(GUID_Unknown),
+ FE(GUID_SysMouse),
+ FE(GUID_SysKeyboard),
+ FE(GUID_Joystick),
+ FE(GUID_ConstantForce),
+ FE(GUID_RampForce),
+ FE(GUID_Square),
+ FE(GUID_Sine),
+ FE(GUID_Triangle),
+ FE(GUID_SawtoothUp),
+ FE(GUID_SawtoothDown),
+ FE(GUID_Spring),
+ FE(GUID_Damper),
+ FE(GUID_Inertia),
+ FE(GUID_Friction),
+ FE(GUID_CustomForce)
+#undef FE
+ };
+ if (guid == NULL)
+ return "null GUID";
+ for (i = 0; i < (sizeof(guids) / sizeof(guids[0])); i++) {
+ if (IsEqualGUID(guids[i].guid, guid)) {
+ return guids[i].name;
+ }
+ }
+ return "Unknown GUID";
+}
+
+void _dump_DIDATAFORMAT(const DIDATAFORMAT *df) {
+ unsigned int i;
+
+ TRACE("Dumping DIDATAFORMAT structure:\n");
+ TRACE(" - dwSize: %ld\n", df->dwSize);
+ if (df->dwSize != sizeof(DIDATAFORMAT)) {
+ WARN("Non-standard DIDATAFORMAT structure size (%ld instead of %d).\n", df->dwSize, sizeof(DIDATAFORMAT));
+ }
+ TRACE(" - dwObjsize: %ld\n", df->dwObjSize);
+ if (df->dwObjSize != sizeof(DIOBJECTDATAFORMAT)) {
+ WARN("Non-standard DIOBJECTDATAFORMAT structure size (%ld instead of %d).\n", df->dwObjSize, sizeof(DIOBJECTDATAFORMAT));
+ }
+ TRACE(" - dwFlags: 0x%08lx (", df->dwFlags);
+ switch (df->dwFlags) {
+ case DIDF_ABSAXIS: TRACE("DIDF_ABSAXIS"); break;
+ case DIDF_RELAXIS: TRACE("DIDF_RELAXIS"); break;
+ default: TRACE("unknown"); break;
+ }
+ TRACE(")\n");
+ TRACE(" - dwDataSize: %ld\n", df->dwDataSize);
+ TRACE(" - dwNumObjs: %ld\n", df->dwNumObjs);
+
+ for (i = 0; i < df->dwNumObjs; i++) {
+ TRACE(" - Object %d:\n", i);
+ TRACE(" * GUID: %s ('%s')\n", debugstr_guid(df->rgodf[i].pguid), _dump_dinput_GUID(df->rgodf[i].pguid));
+ TRACE(" * dwOfs: %ld\n", df->rgodf[i].dwOfs);
+ TRACE(" * dwType: 0x%08lx\n", df->rgodf[i].dwType);
+ TRACE(" "); _dump_EnumObjects_flags(df->rgodf[i].dwType); TRACE("\n");
+ TRACE(" * dwFlags: 0x%08lx\n", df->rgodf[i].dwFlags);
+ }
+}
+
+/* Conversion between internal data buffer and external data buffer */
+void fill_DataFormat(void *out, const void *in, DataFormat *df) {
+ int i;
+ char *in_c = (char *) in;
+ char *out_c = (char *) out;
+
+ if (df->dt == NULL) {
+ /* This means that the app uses Wine's internal data format */
+ memcpy(out, in, df->internal_format_size);
+ } else {
+ for (i = 0; i < df->size; i++) {
+ if (df->dt[i].offset_in >= 0) {
+ switch (df->dt[i].size) {
+ case 1:
+ TRACE("Copying (c) to %d from %d (value %d)\n",
+ df->dt[i].offset_out, df->dt[i].offset_in, *((char *) (in_c + df->dt[i].offset_in)));
+ *((char *) (out_c + df->dt[i].offset_out)) = *((char *) (in_c + df->dt[i].offset_in));
+ break;
+
+ case 2:
+ TRACE("Copying (s) to %d from %d (value %d)\n",
+ df->dt[i].offset_out, df->dt[i].offset_in, *((short *) (in_c + df->dt[i].offset_in)));
+ *((short *) (out_c + df->dt[i].offset_out)) = *((short *) (in_c + df->dt[i].offset_in));
+ break;
+
+ case 4:
+ TRACE("Copying (i) to %d from %d (value %d)\n",
+ df->dt[i].offset_out, df->dt[i].offset_in, *((int *) (in_c + df->dt[i].offset_in)));
+ *((int *) (out_c + df->dt[i].offset_out)) = *((int *) (in_c + df->dt[i].offset_in));
+ break;
+
+ default:
+ memcpy((out_c + df->dt[i].offset_out), (in_c + df->dt[i].offset_in), df->dt[i].size);
+ break;
+ }
+ } else {
+ switch (df->dt[i].size) {
+ case 1:
+ TRACE("Copying (c) to %d default value %d\n",
+ df->dt[i].offset_out, df->dt[i].value);
+ *((char *) (out_c + df->dt[i].offset_out)) = (char) df->dt[i].value;
+ break;
+
+ case 2:
+ TRACE("Copying (s) to %d default value %d\n",
+ df->dt[i].offset_out, df->dt[i].value);
+ *((short *) (out_c + df->dt[i].offset_out)) = (short) df->dt[i].value;
+ break;
+
+ case 4:
+ TRACE("Copying (i) to %d default value %d\n",
+ df->dt[i].offset_out, df->dt[i].value);
+ *((int *) (out_c + df->dt[i].offset_out)) = (int) df->dt[i].value;
+ break;
+
+ default:
+ memset((out_c + df->dt[i].offset_out), df->dt[i].size, 0);
+ break;
+ }
+ }
+ }
+ }
+}
+
+void release_DataFormat(DataFormat * format)
+{
+ TRACE("Deleting DataTransform : \n");
+
+ HeapFree(GetProcessHeap(), 0, format->dt);
+}
+
+DataFormat *create_DataFormat(const DIDATAFORMAT *wine_format, LPCDIDATAFORMAT asked_format, int *offset) {
+ DataFormat *ret;
+ DataTransform *dt;
+ unsigned int i, j;
+ int same = 1;
+ int *done;
+ int index = 0;
+ DWORD next = 0;
+
+ ret = (DataFormat *) HeapAlloc(GetProcessHeap(), 0, sizeof(DataFormat));
+
+ done = (int *) HeapAlloc(GetProcessHeap(), 0, sizeof(int) * asked_format->dwNumObjs);
+ memset(done, 0, sizeof(int) * asked_format->dwNumObjs);
+
+ dt = (DataTransform *) HeapAlloc(GetProcessHeap(), 0, asked_format->dwNumObjs * sizeof(DataTransform));
+
+ TRACE("Creating DataTransform : \n");
+
+ for (i = 0; i < wine_format->dwNumObjs; i++) {
+ offset[i] = -1;
+
+ for (j = 0; j < asked_format->dwNumObjs; j++) {
+ if (done[j] == 1)
+ continue;
+
+ if (/* Check if the application either requests any GUID and if not, it if matches
+ * the GUID of the Wine object.
+ */
+ ((asked_format->rgodf[j].pguid == NULL) ||
+ (IsEqualGUID(wine_format->rgodf[i].pguid, asked_format->rgodf[j].pguid)))
+ &&
+ (/* Then check if it accepts any instance id, and if not, if it matches Wine's
+ * instance id.
+ */
+ ((asked_format->rgodf[j].dwType & 0x00FFFF00) == DIDFT_ANYINSTANCE) ||
+ (DIDFT_GETINSTANCE(wine_format->rgodf[i].dwType) == DIDFT_GETINSTANCE(asked_format->rgodf[j].dwType)))) {
+
+ done[j] = 1;
+
+ TRACE("Matching : \n");
+ TRACE(" - Asked (%d) :\n", j);
+ TRACE(" * GUID: %s ('%s')\n",
+ debugstr_guid(asked_format->rgodf[j].pguid),
+ _dump_dinput_GUID(asked_format->rgodf[j].pguid));
+ TRACE(" * Offset: %3ld\n", asked_format->rgodf[j].dwOfs);
+ TRACE(" * dwType: %08lx\n", asked_format->rgodf[j].dwType);
+ TRACE(" "); _dump_EnumObjects_flags(asked_format->rgodf[j].dwType); TRACE("\n");
+
+ TRACE(" - Wine (%d) :\n", j);
+ TRACE(" * GUID: %s ('%s')\n",
+ debugstr_guid(wine_format->rgodf[j].pguid),
+ _dump_dinput_GUID(wine_format->rgodf[j].pguid));
+ TRACE(" * Offset: %3ld\n", wine_format->rgodf[j].dwOfs);
+ TRACE(" * dwType: %08lx\n", wine_format->rgodf[j].dwType);
+ TRACE(" "); _dump_EnumObjects_flags(wine_format->rgodf[j].dwType); TRACE("\n");
+
+ if (wine_format->rgodf[i].dwType & DIDFT_BUTTON)
+ dt[index].size = sizeof(BYTE);
+ else
+ dt[index].size = sizeof(DWORD);
+ dt[index].offset_in = wine_format ->rgodf[i].dwOfs;
+ if (asked_format->rgodf[j].dwOfs < next) {
+ WARN("bad format: dwOfs=%ld, changing to %ld\n", asked_format->rgodf[j].dwOfs, next);
+ dt[index].offset_out = next;
+ offset[i] = next;
+ } else {
+ dt[index].offset_out = asked_format->rgodf[j].dwOfs;
+ offset[i] = asked_format->rgodf[j].dwOfs;
+ }
+ dt[index].value = 0;
+ next = next + dt[index].size;
+
+ if (wine_format->rgodf[i].dwOfs != dt[index].offset_out)
+ same = 0;
+
+ index++;
+ break;
+ }
+ }
+
+ if (j == asked_format->dwNumObjs)
+ same = 0;
+ }
+
+ TRACE("Setting to default value :\n");
+ for (j = 0; j < asked_format->dwNumObjs; j++) {
+ if (done[j] == 0) {
+ TRACE(" - Asked (%d) :\n", j);
+ TRACE(" * GUID: %s ('%s')\n",
+ debugstr_guid(asked_format->rgodf[j].pguid),
+ _dump_dinput_GUID(asked_format->rgodf[j].pguid));
+ TRACE(" * Offset: %3ld\n", asked_format->rgodf[j].dwOfs);
+ TRACE(" * dwType: %08lx\n", asked_format->rgodf[j].dwType);
+ TRACE(" "); _dump_EnumObjects_flags(asked_format->rgodf[j].dwType); TRACE("\n");
+
+ if (asked_format->rgodf[j].dwType & DIDFT_BUTTON)
+ dt[index].size = sizeof(BYTE);
+ else
+ dt[index].size = sizeof(DWORD);
+ dt[index].offset_in = -1;
+ dt[index].offset_out = asked_format->rgodf[j].dwOfs;
+ dt[index].value = 0;
+ index++;
+
+ same = 0;
+ }
+ }
+
+ ret->internal_format_size = wine_format->dwDataSize;
+ ret->size = index;
+ if (same) {
+ ret->dt = NULL;
+ HeapFree(GetProcessHeap(), 0, dt);
+ } else {
+ ret->dt = dt;
+ }
+
+ HeapFree(GetProcessHeap(), 0, done);
+
+ return ret;
+}
+
+BOOL DIEnumDevicesCallbackAtoW(LPCDIDEVICEOBJECTINSTANCEA lpddi, LPVOID lpvRef) {
+ DIDEVICEOBJECTINSTANCEW ddtmp;
+ device_enumobjects_AtoWcb_data* data;
+
+ data = (device_enumobjects_AtoWcb_data*) lpvRef;
+
+ memset(&ddtmp, 0, sizeof(DIDEVICEINSTANCEW));
+
+ ddtmp.dwSize = sizeof(DIDEVICEINSTANCEW);
+ ddtmp.guidType = lpddi->guidType;
+ ddtmp.dwOfs = lpddi->dwOfs;
+ ddtmp.dwType = lpddi->dwType;
+ ddtmp.dwFlags = lpddi->dwFlags;
+ MultiByteToWideChar(CP_ACP, 0, lpddi->tszName, -1, ddtmp.tszName, MAX_PATH);
+
+ if (lpddi->dwSize == sizeof(DIDEVICEINSTANCEA)) {
+ /**
+ * if dwSize < sizeof(DIDEVICEINSTANCEA of DInput version >= 5)
+ * force feedback and other newer datas aren't available
+ */
+ ddtmp.dwFFMaxForce = lpddi->dwFFMaxForce;
+ ddtmp.dwFFForceResolution = lpddi->dwFFForceResolution;
+ ddtmp.wCollectionNumber = lpddi->wCollectionNumber;
+ ddtmp.wDesignatorIndex = lpddi->wDesignatorIndex;
+ ddtmp.wUsagePage = lpddi->wUsagePage;
+ ddtmp.wUsage = lpddi->wUsage;
+ ddtmp.dwDimension = lpddi->dwDimension;
+ ddtmp.wExponent = lpddi->wExponent;
+ ddtmp.wReserved = lpddi->wReserved;
+ }
+ return data->lpCallBack(&ddtmp, data->lpvRef);
+}
+
+/******************************************************************************
+ * IDirectInputDeviceA
+ */
+
+HRESULT WINAPI IDirectInputDevice2AImpl_SetDataFormat(
+ LPDIRECTINPUTDEVICE8A iface,LPCDIDATAFORMAT df
+) {
+ IDirectInputDevice2AImpl *This = (IDirectInputDevice2AImpl *)iface;
+
+ TRACE("(this=%p,%p)\n",This,df);
+
+ _dump_DIDATAFORMAT(df);
+
+ return DI_OK;
+}
+
+HRESULT WINAPI IDirectInputDevice2AImpl_SetCooperativeLevel(
+ LPDIRECTINPUTDEVICE8A iface,HWND hwnd,DWORD dwflags
+) {
+ IDirectInputDevice2AImpl *This = (IDirectInputDevice2AImpl *)iface;
+ TRACE("(this=%p,0x%08lx,0x%08lx)\n",This,(DWORD)hwnd,dwflags);
+ if (TRACE_ON(dinput)) {
+ TRACE(" cooperative level : ");
+ _dump_cooperativelevel_DI(dwflags);
+ }
+ return DI_OK;
+}
+
+HRESULT WINAPI IDirectInputDevice2AImpl_SetEventNotification(
+ LPDIRECTINPUTDEVICE8A iface,HANDLE hnd
+) {
+ IDirectInputDevice2AImpl *This = (IDirectInputDevice2AImpl *)iface;
+ FIXME("(this=%p,0x%08lx): stub\n",This,(DWORD)hnd);
+ return DI_OK;
+}
+
+ULONG WINAPI IDirectInputDevice2AImpl_Release(LPDIRECTINPUTDEVICE8A iface)
+{
+ IDirectInputDevice2AImpl *This = (IDirectInputDevice2AImpl *)iface;
+ ULONG ref;
+ ref = InterlockedDecrement(&(This->ref));
+ if (ref == 0)
+ HeapFree(GetProcessHeap(),0,This);
+ return ref;
+}
+
+HRESULT WINAPI IDirectInputDevice2AImpl_QueryInterface(
+ LPDIRECTINPUTDEVICE8A iface,REFIID riid,LPVOID *ppobj
+)
+{
+ IDirectInputDevice2AImpl *This = (IDirectInputDevice2AImpl *)iface;
+
+ TRACE("(this=%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
+ if (IsEqualGUID(&IID_IUnknown,riid)) {
+ IDirectInputDevice2_AddRef(iface);
+ *ppobj = This;
+ return DI_OK;
+ }
+ if (IsEqualGUID(&IID_IDirectInputDeviceA,riid)) {
+ IDirectInputDevice2_AddRef(iface);
+ *ppobj = This;
+ return DI_OK;
+ }
+ if (IsEqualGUID(&IID_IDirectInputDevice2A,riid)) {
+ IDirectInputDevice2_AddRef(iface);
+ *ppobj = This;
+ return DI_OK;
+ }
+ if (IsEqualGUID(&IID_IDirectInputDevice7A,riid)) {
+ IDirectInputDevice7_AddRef(iface);
+ *ppobj = This;
+ return DI_OK;
+ }
+ TRACE("Unsupported interface !\n");
+ return E_FAIL;
+}
+
+HRESULT WINAPI IDirectInputDevice2WImpl_QueryInterface(
+ LPDIRECTINPUTDEVICE8W iface,REFIID riid,LPVOID *ppobj
+)
+{
+ IDirectInputDevice2AImpl *This = (IDirectInputDevice2AImpl *)iface;
+
+ TRACE("(this=%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
+ if (IsEqualGUID(&IID_IUnknown,riid)) {
+ IDirectInputDevice2_AddRef(iface);
+ *ppobj = This;
+ return DI_OK;
+ }
+ if (IsEqualGUID(&IID_IDirectInputDeviceW,riid)) {
+ IDirectInputDevice2_AddRef(iface);
+ *ppobj = This;
+ return DI_OK;
+ }
+ if (IsEqualGUID(&IID_IDirectInputDevice2W,riid)) {
+ IDirectInputDevice2_AddRef(iface);
+ *ppobj = This;
+ return DI_OK;
+ }
+ if (IsEqualGUID(&IID_IDirectInputDevice7W,riid)) {
+ IDirectInputDevice7_AddRef(iface);
+ *ppobj = This;
+ return DI_OK;
+ }
+ TRACE("Unsupported interface !\n");
+ return E_FAIL;
+}
+
+ULONG WINAPI IDirectInputDevice2AImpl_AddRef(
+ LPDIRECTINPUTDEVICE8A iface)
+{
+ IDirectInputDevice2AImpl *This = (IDirectInputDevice2AImpl *)iface;
+ return InterlockedIncrement(&(This->ref));
+}
+
+HRESULT WINAPI IDirectInputDevice2AImpl_EnumObjects(
+ LPDIRECTINPUTDEVICE8A iface,
+ LPDIENUMDEVICEOBJECTSCALLBACKA lpCallback,
+ LPVOID lpvRef,
+ DWORD dwFlags)
+{
+ FIXME("(this=%p,%p,%p,%08lx): stub!\n", iface, lpCallback, lpvRef, dwFlags);
+ if (TRACE_ON(dinput)) {
+ DPRINTF(" - flags = ");
+ _dump_EnumObjects_flags(dwFlags);
+ DPRINTF("\n");
+ }
+
+ return DI_OK;
+}
+
+HRESULT WINAPI IDirectInputDevice2WImpl_EnumObjects(
+ LPDIRECTINPUTDEVICE8W iface,
+ LPDIENUMDEVICEOBJECTSCALLBACKW lpCallback,
+ LPVOID lpvRef,
+ DWORD dwFlags)
+{
+ FIXME("(this=%p,%p,%p,%08lx): stub!\n", iface, lpCallback, lpvRef, dwFlags);
+ if (TRACE_ON(dinput)) {
+ DPRINTF(" - flags = ");
+ _dump_EnumObjects_flags(dwFlags);
+ DPRINTF("\n");
+ }
+
+ return DI_OK;
+}
+
+HRESULT WINAPI IDirectInputDevice2AImpl_GetProperty(
+ LPDIRECTINPUTDEVICE8A iface,
+ REFGUID rguid,
+ LPDIPROPHEADER pdiph)
+{
+ FIXME("(this=%p,%s,%p): stub!\n",
+ iface, debugstr_guid(rguid), pdiph);
+
+ if (TRACE_ON(dinput))
+ _dump_DIPROPHEADER(pdiph);
+
+ return DI_OK;
+}
+
+HRESULT WINAPI IDirectInputDevice2AImpl_GetObjectInfo(
+ LPDIRECTINPUTDEVICE8A iface,
+ LPDIDEVICEOBJECTINSTANCEA pdidoi,
+ DWORD dwObj,
+ DWORD dwHow)
+{
+ FIXME("(this=%p,%p,%ld,0x%08lx): stub!\n",
+ iface, pdidoi, dwObj, dwHow);
+
+ return DI_OK;
+}
+
+HRESULT WINAPI IDirectInputDevice2WImpl_GetObjectInfo(
+ LPDIRECTINPUTDEVICE8W iface,
+ LPDIDEVICEOBJECTINSTANCEW pdidoi,
+ DWORD dwObj,
+ DWORD dwHow)
+{
+ FIXME("(this=%p,%p,%ld,0x%08lx): stub!\n",
+ iface, pdidoi, dwObj, dwHow);
+
+ return DI_OK;
+}
+
+HRESULT WINAPI IDirectInputDevice2AImpl_GetDeviceInfo(
+ LPDIRECTINPUTDEVICE8A iface,
+ LPDIDEVICEINSTANCEA pdidi)
+{
+ FIXME("(this=%p,%p): stub!\n",
+ iface, pdidi);
+
+ return DI_OK;
+}
+
+HRESULT WINAPI IDirectInputDevice2WImpl_GetDeviceInfo(
+ LPDIRECTINPUTDEVICE8W iface,
+ LPDIDEVICEINSTANCEW pdidi)
+{
+ FIXME("(this=%p,%p): stub!\n",
+ iface, pdidi);
+
+ return DI_OK;
+}
+
+HRESULT WINAPI IDirectInputDevice2AImpl_RunControlPanel(
+ LPDIRECTINPUTDEVICE8A iface,
+ HWND hwndOwner,
+ DWORD dwFlags)
+{
+ FIXME("(this=%p,%p,0x%08lx): stub!\n",
+ iface, hwndOwner, dwFlags);
+
+ return DI_OK;
+}
+
+HRESULT WINAPI IDirectInputDevice2AImpl_Initialize(
+ LPDIRECTINPUTDEVICE8A iface,
+ HINSTANCE hinst,
+ DWORD dwVersion,
+ REFGUID rguid)
+{
+ FIXME("(this=%p,%p,%ld,%s): stub!\n",
+ iface, hinst, dwVersion, debugstr_guid(rguid));
+ return DI_OK;
+}
+
+/******************************************************************************
+ * IDirectInputDevice2A
+ */
+
+HRESULT WINAPI IDirectInputDevice2AImpl_CreateEffect(
+ LPDIRECTINPUTDEVICE8A iface,
+ REFGUID rguid,
+ LPCDIEFFECT lpeff,
+ LPDIRECTINPUTEFFECT *ppdef,
+ LPUNKNOWN pUnkOuter)
+{
+ FIXME("(this=%p,%s,%p,%p,%p): stub!\n",
+ iface, debugstr_guid(rguid), lpeff, ppdef, pUnkOuter);
+ return DI_OK;
+}
+
+HRESULT WINAPI IDirectInputDevice2AImpl_EnumEffects(
+ LPDIRECTINPUTDEVICE8A iface,
+ LPDIENUMEFFECTSCALLBACKA lpCallback,
+ LPVOID lpvRef,
+ DWORD dwFlags)
+{
+ FIXME("(this=%p,%p,%p,0x%08lx): stub!\n",
+ iface, lpCallback, lpvRef, dwFlags);
+
+ return DI_OK;
+}
+
+HRESULT WINAPI IDirectInputDevice2WImpl_EnumEffects(
+ LPDIRECTINPUTDEVICE8W iface,
+ LPDIENUMEFFECTSCALLBACKW lpCallback,
+ LPVOID lpvRef,
+ DWORD dwFlags)
+{
+ FIXME("(this=%p,%p,%p,0x%08lx): stub!\n",
+ iface, lpCallback, lpvRef, dwFlags);
+
+ return DI_OK;
+}
+
+HRESULT WINAPI IDirectInputDevice2AImpl_GetEffectInfo(
+ LPDIRECTINPUTDEVICE8A iface,
+ LPDIEFFECTINFOA lpdei,
+ REFGUID rguid)
+{
+ FIXME("(this=%p,%p,%s): stub!\n",
+ iface, lpdei, debugstr_guid(rguid));
+ return DI_OK;
+}
+
+HRESULT WINAPI IDirectInputDevice2WImpl_GetEffectInfo(
+ LPDIRECTINPUTDEVICE8W iface,
+ LPDIEFFECTINFOW lpdei,
+ REFGUID rguid)
+{
+ FIXME("(this=%p,%p,%s): stub!\n",
+ iface, lpdei, debugstr_guid(rguid));
+ return DI_OK;
+}
+
+HRESULT WINAPI IDirectInputDevice2AImpl_GetForceFeedbackState(
+ LPDIRECTINPUTDEVICE8A iface,
+ LPDWORD pdwOut)
+{
+ FIXME("(this=%p,%p): stub!\n",
+ iface, pdwOut);
+ return DI_OK;
+}
+
+HRESULT WINAPI IDirectInputDevice2AImpl_SendForceFeedbackCommand(
+ LPDIRECTINPUTDEVICE8A iface,
+ DWORD dwFlags)
+{
+ FIXME("(this=%p,0x%08lx): stub!\n",
+ iface, dwFlags);
+ return DI_OK;
+}
+
+HRESULT WINAPI IDirectInputDevice2AImpl_EnumCreatedEffectObjects(
+ LPDIRECTINPUTDEVICE8A iface,
+ LPDIENUMCREATEDEFFECTOBJECTSCALLBACK lpCallback,
+ LPVOID lpvRef,
+ DWORD dwFlags)
+{
+ FIXME("(this=%p,%p,%p,0x%08lx): stub!\n",
+ iface, lpCallback, lpvRef, dwFlags);
+ if (lpCallback)
+ lpCallback(NULL, lpvRef);
+ return DI_OK;
+}
+
+HRESULT WINAPI IDirectInputDevice2AImpl_Escape(
+ LPDIRECTINPUTDEVICE8A iface,
+ LPDIEFFESCAPE lpDIEEsc)
+{
+ FIXME("(this=%p,%p): stub!\n",
+ iface, lpDIEEsc);
+ return DI_OK;
+}
+
+HRESULT WINAPI IDirectInputDevice2AImpl_Poll(
+ LPDIRECTINPUTDEVICE8A iface)
+{
+ /* Because wine devices do not need to be polled, just return DI_NOEFFECT */
+ return DI_NOEFFECT;
+}
+
+HRESULT WINAPI IDirectInputDevice2AImpl_SendDeviceData(
+ LPDIRECTINPUTDEVICE8A iface,
+ DWORD cbObjectData,
+ LPCDIDEVICEOBJECTDATA rgdod,
+ LPDWORD pdwInOut,
+ DWORD dwFlags)
+{
+ FIXME("(this=%p,0x%08lx,%p,%p,0x%08lx): stub!\n",
+ iface, cbObjectData, rgdod, pdwInOut, dwFlags);
+
+ return DI_OK;
+}
+
+HRESULT WINAPI IDirectInputDevice7AImpl_EnumEffectsInFile(LPDIRECTINPUTDEVICE8A iface,
+ LPCSTR lpszFileName,
+ LPDIENUMEFFECTSINFILECALLBACK pec,
+ LPVOID pvRef,
+ DWORD dwFlags)
+{
+ FIXME("(%p)->(%s,%p,%p,%08lx): stub !\n", iface, lpszFileName, pec, pvRef, dwFlags);
+
+ return DI_OK;
+}
+
+HRESULT WINAPI IDirectInputDevice7WImpl_EnumEffectsInFile(LPDIRECTINPUTDEVICE8W iface,
+ LPCWSTR lpszFileName,
+ LPDIENUMEFFECTSINFILECALLBACK pec,
+ LPVOID pvRef,
+ DWORD dwFlags)
+{
+ FIXME("(%p)->(%s,%p,%p,%08lx): stub !\n", iface, debugstr_w(lpszFileName), pec, pvRef, dwFlags);
+
+ return DI_OK;
+}
+
+HRESULT WINAPI IDirectInputDevice7AImpl_WriteEffectToFile(LPDIRECTINPUTDEVICE8A iface,
+ LPCSTR lpszFileName,
+ DWORD dwEntries,
+ LPDIFILEEFFECT rgDiFileEft,
+ DWORD dwFlags)
+{
+ FIXME("(%p)->(%s,%08lx,%p,%08lx): stub !\n", iface, lpszFileName, dwEntries, rgDiFileEft, dwFlags);
+
+ return DI_OK;
+}
+
+HRESULT WINAPI IDirectInputDevice7WImpl_WriteEffectToFile(LPDIRECTINPUTDEVICE8W iface,
+ LPCWSTR lpszFileName,
+ DWORD dwEntries,
+ LPDIFILEEFFECT rgDiFileEft,
+ DWORD dwFlags)
+{
+ FIXME("(%p)->(%s,%08lx,%p,%08lx): stub !\n", iface, debugstr_w(lpszFileName), dwEntries, rgDiFileEft, dwFlags);
+
+ return DI_OK;
+}
+
+HRESULT WINAPI IDirectInputDevice8AImpl_BuildActionMap(LPDIRECTINPUTDEVICE8A iface,
+ LPDIACTIONFORMATA lpdiaf,
+ LPCSTR lpszUserName,
+ DWORD dwFlags)
+{
+ FIXME("(%p)->(%p,%s,%08lx): stub !\n", iface, lpdiaf, lpszUserName, dwFlags);
+
+ return DI_OK;
+}
+
+HRESULT WINAPI IDirectInputDevice8WImpl_BuildActionMap(LPDIRECTINPUTDEVICE8W iface,
+ LPDIACTIONFORMATW lpdiaf,
+ LPCWSTR lpszUserName,
+ DWORD dwFlags)
+{
+ FIXME("(%p)->(%p,%s,%08lx): stub !\n", iface, lpdiaf, debugstr_w(lpszUserName), dwFlags);
+
+ return DI_OK;
+}
+
+HRESULT WINAPI IDirectInputDevice8AImpl_SetActionMap(LPDIRECTINPUTDEVICE8A iface,
+ LPDIACTIONFORMATA lpdiaf,
+ LPCSTR lpszUserName,
+ DWORD dwFlags)
+{
+ FIXME("(%p)->(%p,%s,%08lx): stub !\n", iface, lpdiaf, lpszUserName, dwFlags);
+
+ return DI_OK;
+}
+
+HRESULT WINAPI IDirectInputDevice8WImpl_SetActionMap(LPDIRECTINPUTDEVICE8W iface,
+ LPDIACTIONFORMATW lpdiaf,
+ LPCWSTR lpszUserName,
+ DWORD dwFlags)
+{
+ FIXME("(%p)->(%p,%s,%08lx): stub !\n", iface, lpdiaf, debugstr_w(lpszUserName), dwFlags);
+
+ return DI_OK;
+}
+
+HRESULT WINAPI IDirectInputDevice8AImpl_GetImageInfo(LPDIRECTINPUTDEVICE8A iface,
+ LPDIDEVICEIMAGEINFOHEADERA lpdiDevImageInfoHeader)
+{
+ FIXME("(%p)->(%p): stub !\n", iface, lpdiDevImageInfoHeader);
+
+ return DI_OK;
+}
+
+HRESULT WINAPI IDirectInputDevice8WImpl_GetImageInfo(LPDIRECTINPUTDEVICE8W iface,
+ LPDIDEVICEIMAGEINFOHEADERW lpdiDevImageInfoHeader)
+{
+ FIXME("(%p)->(%p): stub !\n", iface, lpdiDevImageInfoHeader);
+
+ return DI_OK;
+}
reactos/lib/dinput
diff -N device_private.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ device_private.h 29 Nov 2004 00:13:49 -0000 1.1
@@ -0,0 +1,236 @@
+/*
+ * Copyright 2000 Lionel Ulmer
+ * Copyright 2000-2001 TransGaming Technologies Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __WINE_DLLS_DINPUT_DINPUTDEVICE_PRIVATE_H
+#define __WINE_DLLS_DINPUT_DINPUTDEVICE_PRIVATE_H
+
+#include <stdarg.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "dinput.h"
+
+/* Device implementation */
+typedef struct IDirectInputDevice2AImpl IDirectInputDevice2AImpl;
+struct IDirectInputDevice2AImpl
+{
+ IDirectInputDevice2AVtbl *lpVtbl;
+ DWORD ref;
+ GUID guid;
+};
+
+/* Routines to do DataFormat / WineFormat conversions */
+typedef struct {
+ int size;
+ int offset_in;
+ int offset_out;
+ int value;
+} DataTransform;
+
+typedef struct {
+ int size;
+ int internal_format_size;
+ DataTransform *dt;
+} DataFormat;
+extern void fill_DataFormat(void *out, const void *in, DataFormat *df) ;
+extern DataFormat *create_DataFormat(const DIDATAFORMAT *wine_format, LPCDIDATAFORMAT asked_format, int *offset) ;
+extern void release_DataFormat(DataFormat *df) ;
+
+/* Used to fill events in the queue */
+#define GEN_EVENT(offset,data,xtime,seq) \
+{ \
+ /* If queue_len > 0, queuing is requested -> TRACE the event queued */ \
+ if (This->queue_len > 0) { \
+ int nq; \
+ TRACE(" queueing %d at offset %d (queue head %d / size %d)\n", \
+ (int) (data), (int) (offset), \
+ (int) (This->queue_head), (int) (This->queue_len)); \
+ \
+ nq = This->queue_head+1; \
+ while (nq >= This->queue_len) nq -= This->queue_len; \
+ if ((offset >= 0) && (nq != This->queue_tail)) { \
+ This->data_queue[This->queue_head].dwOfs = offset; \
+ This->data_queue[This->queue_head].dwData = data; \
+ This->data_queue[This->queue_head].dwTimeStamp = xtime; \
+ This->data_queue[This->queue_head].dwSequence = seq; \
+ This->queue_head = nq; \
+ } else \
+ This->overflow = TRUE; \
+ } \
+}
+
+/**
+ * Callback Data used by specific callback
+ * for EnumObject on 'W' interfaces
+ */
+typedef struct {
+ LPDIENUMDEVICEOBJECTSCALLBACKW lpCallBack;
+ LPVOID lpvRef;
+} device_enumobjects_AtoWcb_data;
+
+extern BOOL DIEnumDevicesCallbackAtoW(LPCDIDEVICEOBJECTINSTANCEA, LPVOID);
+
+
+/* Various debug tools */
+extern void _dump_cooperativelevel_DI(DWORD dwFlags) ;
+extern void _dump_EnumObjects_flags(DWORD dwFlags) ;
+extern void _dump_DIPROPHEADER(LPCDIPROPHEADER diph) ;
+extern void _dump_OBJECTINSTANCEA(DIDEVICEOBJECTINSTANCEA *ddoi) ;
+extern void _dump_OBJECTINSTANCEW(DIDEVICEOBJECTINSTANCEW *ddoi) ;
+extern void _dump_DIDATAFORMAT(const DIDATAFORMAT *df) ;
+extern const char *_dump_dinput_GUID(const GUID *guid) ;
+
+/* And the stubs */
+extern HRESULT WINAPI IDirectInputDevice2AImpl_SetDataFormat(
+ LPDIRECTINPUTDEVICE8A iface,LPCDIDATAFORMAT df ) ;
+extern HRESULT WINAPI IDirectInputDevice2AImpl_SetCooperativeLevel(
+ LPDIRECTINPUTDEVICE8A iface,HWND hwnd,DWORD dwflags ) ;
+extern HRESULT WINAPI IDirectInputDevice2AImpl_SetEventNotification(
+ LPDIRECTINPUTDEVICE8A iface,HANDLE hnd ) ;
+extern ULONG WINAPI IDirectInputDevice2AImpl_Release(LPDIRECTINPUTDEVICE8A iface) ;
+extern HRESULT WINAPI IDirectInputDevice2AImpl_QueryInterface(LPDIRECTINPUTDEVICE8A iface,REFIID riid,LPVOID *ppobj);
+extern HRESULT WINAPI IDirectInputDevice2WImpl_QueryInterface(LPDIRECTINPUTDEVICE8W iface,REFIID riid,LPVOID *ppobj);
+extern ULONG WINAPI IDirectInputDevice2AImpl_AddRef(
+ LPDIRECTINPUTDEVICE8A iface) ;
+extern HRESULT WINAPI IDirectInputDevice2AImpl_EnumObjects(
+ LPDIRECTINPUTDEVICE8A iface,
+ LPDIENUMDEVICEOBJECTSCALLBACKA lpCallback,
+ LPVOID lpvRef,
+ DWORD dwFlags) ;
+extern HRESULT WINAPI IDirectInputDevice2WImpl_EnumObjects(
+ LPDIRECTINPUTDEVICE8W iface,
+ LPDIENUMDEVICEOBJECTSCALLBACKW lpCallback,
+ LPVOID lpvRef,
+ DWORD dwFlags) ;
+extern HRESULT WINAPI IDirectInputDevice2AImpl_GetProperty(
+ LPDIRECTINPUTDEVICE8A iface,
+ REFGUID rguid,
+ LPDIPROPHEADER pdiph) ;
+extern HRESULT WINAPI IDirectInputDevice2AImpl_GetObjectInfo(
+ LPDIRECTINPUTDEVICE8A iface,
+ LPDIDEVICEOBJECTINSTANCEA pdidoi,
+ DWORD dwObj,
+ DWORD dwHow) ;
+extern HRESULT WINAPI IDirectInputDevice2WImpl_GetObjectInfo(LPDIRECTINPUTDEVICE8W iface,
+ LPDIDEVICEOBJECTINSTANCEW pdidoi,
+ DWORD dwObj,
+ DWORD dwHow);
+extern HRESULT WINAPI IDirectInputDevice2AImpl_GetDeviceInfo(
+ LPDIRECTINPUTDEVICE8A iface,
+ LPDIDEVICEINSTANCEA pdidi) ;
+extern HRESULT WINAPI IDirectInputDevice2WImpl_GetDeviceInfo(
+ LPDIRECTINPUTDEVICE8W iface,
+ LPDIDEVICEINSTANCEW pdidi) ;
+extern HRESULT WINAPI IDirectInputDevice2AImpl_RunControlPanel(
+ LPDIRECTINPUTDEVICE8A iface,
+ HWND hwndOwner,
+ DWORD dwFlags) ;
+extern HRESULT WINAPI IDirectInputDevice2AImpl_Initialize(
+ LPDIRECTINPUTDEVICE8A iface,
+ HINSTANCE hinst,
+ DWORD dwVersion,
+ REFGUID rguid) ;
+extern HRESULT WINAPI IDirectInputDevice2AImpl_CreateEffect(
+ LPDIRECTINPUTDEVICE8A iface,
+ REFGUID rguid,
+ LPCDIEFFECT lpeff,
+ LPDIRECTINPUTEFFECT *ppdef,
+ LPUNKNOWN pUnkOuter) ;
+extern HRESULT WINAPI IDirectInputDevice2AImpl_EnumEffects(
+ LPDIRECTINPUTDEVICE8A iface,
+ LPDIENUMEFFECTSCALLBACKA lpCallback,
+ LPVOID lpvRef,
+ DWORD dwFlags) ;
+extern HRESULT WINAPI IDirectInputDevice2WImpl_EnumEffects(
+ LPDIRECTINPUTDEVICE8W iface,
+ LPDIENUMEFFECTSCALLBACKW lpCallback,
+ LPVOID lpvRef,
+ DWORD dwFlags) ;
+extern HRESULT WINAPI IDirectInputDevice2AImpl_GetEffectInfo(
+ LPDIRECTINPUTDEVICE8A iface,
+ LPDIEFFECTINFOA lpdei,
+ REFGUID rguid) ;
+extern HRESULT WINAPI IDirectInputDevice2WImpl_GetEffectInfo(
+ LPDIRECTINPUTDEVICE8W iface,
+ LPDIEFFECTINFOW lpdei,
+ REFGUID rguid) ;
+extern HRESULT WINAPI IDirectInputDevice2AImpl_GetForceFeedbackState(
+ LPDIRECTINPUTDEVICE8A iface,
+ LPDWORD pdwOut) ;
+extern HRESULT WINAPI IDirectInputDevice2AImpl_SendForceFeedbackCommand(
+ LPDIRECTINPUTDEVICE8A iface,
+ DWORD dwFlags) ;
+extern HRESULT WINAPI IDirectInputDevice2AImpl_EnumCreatedEffectObjects(
+ LPDIRECTINPUTDEVICE8A iface,
+ LPDIENUMCREATEDEFFECTOBJECTSCALLBACK lpCallback,
+ LPVOID lpvRef,
+ DWORD dwFlags) ;
+extern HRESULT WINAPI IDirectInputDevice2AImpl_Escape(
+ LPDIRECTINPUTDEVICE8A iface,
+ LPDIEFFESCAPE lpDIEEsc) ;
+extern HRESULT WINAPI IDirectInputDevice2AImpl_Poll(
+ LPDIRECTINPUTDEVICE8A iface) ;
+extern HRESULT WINAPI IDirectInputDevice2AImpl_SendDeviceData(
+ LPDIRECTINPUTDEVICE8A iface,
+ DWORD cbObjectData,
+ LPCDIDEVICEOBJECTDATA rgdod,
+ LPDWORD pdwInOut,
+ DWORD dwFlags) ;
+extern HRESULT WINAPI IDirectInputDevice7AImpl_EnumEffectsInFile(LPDIRECTINPUTDEVICE8A iface,
+ LPCSTR lpszFileName,
+ LPDIENUMEFFECTSINFILECALLBACK pec,
+ LPVOID pvRef,
+ DWORD dwFlags) ;
+extern HRESULT WINAPI IDirectInputDevice7WImpl_EnumEffectsInFile(LPDIRECTINPUTDEVICE8W iface,
+ LPCWSTR lpszFileName,
+ LPDIENUMEFFECTSINFILECALLBACK pec,
+ LPVOID pvRef,
+ DWORD dwFlags) ;
+extern HRESULT WINAPI IDirectInputDevice7AImpl_WriteEffectToFile(LPDIRECTINPUTDEVICE8A iface,
+ LPCSTR lpszFileName,
+ DWORD dwEntries,
+ LPDIFILEEFFECT rgDiFileEft,
+ DWORD dwFlags) ;
+extern HRESULT WINAPI IDirectInputDevice7WImpl_WriteEffectToFile(LPDIRECTINPUTDEVICE8W iface,
+ LPCWSTR lpszFileName,
+ DWORD dwEntries,
+ LPDIFILEEFFECT rgDiFileEft,
+ DWORD dwFlags) ;
+extern HRESULT WINAPI IDirectInputDevice8AImpl_BuildActionMap(LPDIRECTINPUTDEVICE8A iface,
+ LPDIACTIONFORMATA lpdiaf,
+ LPCSTR lpszUserName,
+ DWORD dwFlags);
+extern HRESULT WINAPI IDirectInputDevice8WImpl_BuildActionMap(LPDIRECTINPUTDEVICE8W iface,
+ LPDIACTIONFORMATW lpdiaf,
+ LPCWSTR lpszUserName,
+ DWORD dwFlags);
+extern HRESULT WINAPI IDirectInputDevice8AImpl_SetActionMap(LPDIRECTINPUTDEVICE8A iface,
+ LPDIACTIONFORMATA lpdiaf,
+ LPCSTR lpszUserName,
+ DWORD dwFlags);
+extern HRESULT WINAPI IDirectInputDevice8WImpl_SetActionMap(LPDIRECTINPUTDEVICE8W iface,
+ LPDIACTIONFORMATW lpdiaf,
+ LPCWSTR lpszUserName,
+ DWORD dwFlags);
+extern HRESULT WINAPI IDirectInputDevice8AImpl_GetImageInfo(LPDIRECTINPUTDEVICE8A iface,
+ LPDIDEVICEIMAGEINFOHEADERA lpdiDevImageInfoHeader);
+extern HRESULT WINAPI IDirectInputDevice8WImpl_GetImageInfo(LPDIRECTINPUTDEVICE8W iface,
+ LPDIDEVICEIMAGEINFOHEADERW lpdiDevImageInfoHeader);
+
+#endif /* __WINE_DLLS_DINPUT_DINPUTDEVICE_PRIVATE_H */
reactos/lib/dinput
diff -N dinput.stubs.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ dinput.stubs.c 29 Nov 2004 00:13:49 -0000 1.1
@@ -0,0 +1,3 @@
+/* File generated automatically from dinput.spec; do not edit! */
+/* This file can be copied, modified and distributed without restriction. */
+
reactos/lib/dinput
diff -N dinput_main.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ dinput_main.c 29 Nov 2004 00:13:49 -0000 1.1
@@ -0,0 +1,756 @@
+/* DirectInput
+ *
+ * Copyright 1998 Marcus Meissner
+ * Copyright 1998,1999 Lionel Ulmer
+ * Copyright 2000-2002 TransGaming Technologies Inc.
+ *
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+/* Status:
+ *
+ * - Tomb Raider 2 Demo:
+ * Playable using keyboard only.
+ * - WingCommander Prophecy Demo:
+ * Doesn't get Input Focus.
+ *
+ * - Fallout : works great in X and DGA mode
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include <assert.h>
+#include <stdarg.h>
+#include <string.h>
+
+#define COBJMACROS
+
+#include "wine/debug.h"
+#include "wine/unicode.h"
+#include "windef.h"
+#include "winbase.h"
+#include "winuser.h"
+#include "winerror.h"
+#include "dinput_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(dinput);
+
+static IDirectInput7AVtbl ddi7avt;
+static IDirectInput7WVtbl ddi7wvt;
+static IDirectInput8AVtbl ddi8avt;
+static IDirectInput8WVtbl ddi8wvt;
+
+/* This array will be filled a dinput.so loading */
+#define MAX_WINE_DINPUT_DEVICES 4
+static dinput_device * dinput_devices[MAX_WINE_DINPUT_DEVICES];
+static int nrof_dinput_devices = 0;
+
+HINSTANCE DINPUT_instance = NULL;
+
+BOOL WINAPI DllMain( HINSTANCE inst, DWORD reason, LPVOID reserv)
+{
+ switch(reason)
+ {
+ case DLL_PROCESS_ATTACH:
+ DisableThreadLibraryCalls(inst);
+ DINPUT_instance = inst;
+ break;
+ case DLL_PROCESS_DETACH:
+ break;
+ }
+ return TRUE;
+}
+
+/* register a direct draw driver. We better not use malloc for we are in
+ * the ELF startup initialisation at this point.
+ */
+void dinput_register_device(dinput_device *device) {
+ int i;
+
+ /* insert according to priority */
+ for (i=0;i<nrof_dinput_devices;i++) {
+ if (dinput_devices[i]->pref <= device->pref) {
+ memcpy(dinput_devices+i+1,dinput_devices+i,sizeof(dinput_devices[0])*(nrof_dinput_devices-i));
+ dinput_devices[i] = device;
+ break;
+ }
+ }
+ if (i==nrof_dinput_devices) /* not found, or too low priority */
+ dinput_devices[nrof_dinput_devices] = device;
+
+ nrof_dinput_devices++;
+
+ /* increase MAX_DDRAW_DRIVERS if the line below triggers */
+ assert(nrof_dinput_devices <= MAX_WINE_DINPUT_DEVICES);
+}
+
+/******************************************************************************
+ * DirectInputCreateEx (DINPUT.@)
+ */
+HRESULT WINAPI DirectInputCreateEx(
+ HINSTANCE hinst, DWORD dwVersion, REFIID riid, LPVOID *ppDI,
+ LPUNKNOWN punkOuter)
+{
+ IDirectInputImpl* This;
+
+ TRACE("(0x%08lx,%04lx,%s,%p,%p)\n", (DWORD)hinst,dwVersion,debugstr_guid(riid),ppDI,punkOuter);
+
+ if (IsEqualGUID(&IID_IDirectInputA,riid) ||
+ IsEqualGUID(&IID_IDirectInput2A,riid) ||
+ IsEqualGUID(&IID_IDirectInput7A,riid)) {
+ This = (IDirectInputImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInputImpl));
+ This->lpVtbl = &ddi7avt;
+ This->ref = 1;
+ This->version = 1;
+ *ppDI = This;
+
+ return DI_OK;
+ }
+
+ if (IsEqualGUID(&IID_IDirectInputW,riid) ||
+ IsEqualGUID(&IID_IDirectInput2W,riid) ||
+ IsEqualGUID(&IID_IDirectInput7W,riid)) {
+ This = (IDirectInputImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInputImpl));
+ This->lpVtbl = &ddi7wvt;
+ This->ref = 1;
+ This->version = 1;
+ *ppDI = This;
+
+ return DI_OK;
+ }
+
+ if (IsEqualGUID(&IID_IDirectInput8A,riid)) {
+ This = (IDirectInputImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInputImpl));
+ This->lpVtbl = &ddi8avt;
+ This->ref = 1;
+ This->version = 8;
+ *ppDI = This;
+
+ return DI_OK;
+ }
+
+ if (IsEqualGUID(&IID_IDirectInput8W,riid)) {
+ This = (IDirectInputImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInputImpl));
+ This->lpVtbl = &ddi8wvt;
+ This->ref = 1;
+ This->version = 8;
+ *ppDI = This;
+
+ return DI_OK;
+ }
+
+ return DIERR_OLDDIRECTINPUTVERSION;
+}
+
+/******************************************************************************
+ * DirectInputCreateA (DINPUT.@)
+ */
+HRESULT WINAPI DirectInputCreateA(HINSTANCE hinst, DWORD dwVersion, LPDIRECTINPUTA *ppDI, LPUNKNOWN punkOuter)
+{
+ IDirectInputImpl* This;
+ TRACE("(0x%08lx,%04lx,%p,%p)\n", (DWORD)hinst,dwVersion,ppDI,punkOuter);
+
+ //trace:dinput:DirectInputCreateA (0x00400000,0500,0x42bafc54,(nil))
+ This = (IDirectInputImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInputImpl));
+ This->lpVtbl = &ddi7avt;
+ This->ref = 1;
+ if (dwVersion > 0x0700) {
+ This->version = 8;
+ } else {
+ /* We do not differientiate between version 1, 2 and 7 */
+ This->version = 1;
+ }
+ *ppDI = (IDirectInputA*)This;
+ return 0;
+
+}
+
+/******************************************************************************
+ * DirectInputCreateW (DINPUT.@)
+ */
+HRESULT WINAPI DirectInputCreateW(HINSTANCE hinst, DWORD dwVersion, LPDIRECTINPUTW *ppDI, LPUNKNOWN punkOuter)
+{
+ IDirectInputImpl* This;
+ TRACE("(0x%08lx,%04lx,%p,%p)\n", (DWORD)hinst,dwVersion,ppDI,punkOuter);
+ This = (IDirectInputImpl*)HeapAlloc(GetProcessHeap(),0,sizeof(IDirectInputImpl));
+ This->lpVtbl = &ddi7wvt;
+ This->ref = 1;
+ if (dwVersion >= 0x0800) {
+ This->version = 8;
+ } else {
+ /* We do not differientiate between version 1, 2 and 7 */
+ This->version = 1;
+ }
+ *ppDI = (IDirectInputW*)This;
+ return 0;
+}
+
+static char *_dump_DIDEVTYPE_value(DWORD dwDevType) {
+ switch (dwDevType) {
+ case 0: return "All devices";
+ case DIDEVTYPE_MOUSE: return "DIDEVTYPE_MOUSE";
+ case DIDEVTYPE_KEYBOARD: return "DIDEVTYPE_KEYBOARD";
+ case DIDEVTYPE_JOYSTICK: return "DIDEVTYPE_JOYSTICK";
+ case DIDEVTYPE_DEVICE: return "DIDEVTYPE_DEVICE";
+ default: return "Unkown";
+ }
+}
+
+static void _dump_EnumDevices_dwFlags(DWORD dwFlags) {
+ if (TRACE_ON(dinput)) {
+ unsigned int i;
+ static const struct {
+ DWORD mask;
+ const char *name;
+ } flags[] = {
+#define FE(x) { x, #x}
+ FE(DIEDFL_ALLDEVICES),
+ FE(DIEDFL_ATTACHEDONLY),
+ FE(DIEDFL_FORCEFEEDBACK),
+ FE(DIEDFL_INCLUDEALIASES),
+ FE(DIEDFL_INCLUDEPHANTOMS)
+#undef FE
+ };
+ if (dwFlags == 0) {
+ DPRINTF("DIEDFL_ALLDEVICES");
+ return;
+ }
+ for (i = 0; i < (sizeof(flags) / sizeof(flags[0])); i++)
+ if (flags[i].mask & dwFlags)
+ DPRINTF("%s ",flags[i].name);
+ }
+}
+
+/******************************************************************************
+ * IDirectInputA_EnumDevices
+ */
+static HRESULT WINAPI IDirectInputAImpl_EnumDevices(
+ LPDIRECTINPUT7A iface, DWORD dwDevType, LPDIENUMDEVICESCALLBACKA lpCallback,
+ LPVOID pvRef, DWORD dwFlags)
+{
+ IDirectInputImpl *This = (IDirectInputImpl *)iface;
+ DIDEVICEINSTANCEA devInstance;
+ int i, j, r;
+
+ TRACE("(this=%p,0x%04lx '%s',%p,%p,%04lx)\n",
+ This, dwDevType, _dump_DIDEVTYPE_value(dwDevType),
+ lpCallback, pvRef, dwFlags);
+
+ if (nrof_dinput_devices==0){
+ scan_mouse();
+ scan_keyboard();
+ }
+
+ TRACE(" flags: "); _dump_EnumDevices_dwFlags(dwFlags); TRACE("\n");
+
+
+ for (i = 0; i < nrof_dinput_devices; i++) {
+ for (j = 0, r = -1; r != 0; j++) {
+ devInstance.dwSize = sizeof(devInstance);
+ TRACE(" - checking device %d ('%s')\n", i, dinput_devices[i]->name);
+
+
+ if ((r = dinput_devices[i]->enum_deviceA(dwDevType, dwFlags, &devInstance, This->version, j))) {
+ if (lpCallback(&devInstance,pvRef) == DIENUM_STOP)
+ return 0;
+ }
+ }
+ }
+
+ return 0;
+}
+/******************************************************************************
+ * IDirectInputW_EnumDevices
+ */
+static HRESULT WINAPI IDirectInputWImpl_EnumDevices(
+ LPDIRECTINPUT7W iface, DWORD dwDevType, LPDIENUMDEVICESCALLBACKW lpCallback,
+ LPVOID pvRef, DWORD dwFlags)
+{
+ IDirectInputImpl *This = (IDirectInputImpl *)iface;
+ DIDEVICEINSTANCEW devInstance;
+ int i, j, r;
+
+ if (nrof_dinput_devices==0){
+ scan_mouse();
+ scan_keyboard();
+ }
+
+ TRACE("(this=%p,0x%04lx '%s',%p,%p,%04lx)\n",
+ This, dwDevType, _dump_DIDEVTYPE_value(dwDevType),
+ lpCallback, pvRef, dwFlags);
+ TRACE(" flags: "); _dump_EnumDevices_dwFlags(dwFlags); TRACE("\n");
+
+
+ for (i = 0; i < nrof_dinput_devices; i++) {
+ for (j = 0, r = -1; r != 0; j++) {
+ devInstance.dwSize = sizeof(devInstance);
+ TRACE(" - checking device %d ('%s')\n", i, dinput_devices[i]->name);
+ if ((r = dinput_devices[i]->enum_deviceW(dwDevType, dwFlags, &devInstance, This->version, j))) {
+ if (lpCallback(&devInstance,pvRef) == DIENUM_STOP)
+ return 0;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static ULONG WINAPI IDirectInputAImpl_AddRef(LPDIRECTINPUT7A iface)
+{
+ IDirectInputImpl *This = (IDirectInputImpl *)iface;
+ return InterlockedIncrement((&This->ref));
+}
+
+static ULONG WINAPI IDirectInputAImpl_Release(LPDIRECTINPUT7A iface)
+{
+ IDirectInputImpl *This = (IDirectInputImpl *)iface;
+ ULONG ref;
+ ref = InterlockedDecrement(&(This->ref));
+ if (ref == 0)
+ HeapFree(GetProcessHeap(),0,This);
+ return ref;
+}
+
+static HRESULT WINAPI IDirectInputAImpl_QueryInterface(LPDIRECTINPUT7A iface, REFIID riid, LPVOID *ppobj) {
+ IDirectInputImpl *This = (IDirectInputImpl *)iface;
+
+ TRACE("(this=%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
+ if (IsEqualGUID(&IID_IUnknown,riid) ||
+ IsEqualGUID(&IID_IDirectInputA,riid) ||
+ IsEqualGUID(&IID_IDirectInput2A,riid) ||
+ IsEqualGUID(&IID_IDirectInput7A,riid)) {
+ IDirectInputAImpl_AddRef(iface);
+ *ppobj = This;
+ return 0;
+ }
+ TRACE("Unsupported interface !\n");
+ return E_FAIL;
+}
+
+static HRESULT WINAPI IDirectInputWImpl_QueryInterface(LPDIRECTINPUT7W iface, REFIID riid, LPVOID *ppobj) {
+ IDirectInputImpl *This = (IDirectInputImpl *)iface;
+
+ TRACE("(this=%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
+ if (IsEqualGUID(&IID_IUnknown,riid) ||
+ IsEqualGUID(&IID_IDirectInputW,riid) ||
+ IsEqualGUID(&IID_IDirectInput2W,riid) ||
+ IsEqualGUID(&IID_IDirectInput7W,riid)) {
+ IDirectInputAImpl_AddRef((LPDIRECTINPUT7A) iface);
+ *ppobj = This;
+ return 0;
+ }
+ TRACE("Unsupported interface !\n");
+ return E_FAIL;
+}
+
+static HRESULT WINAPI IDirectInputAImpl_CreateDevice(
+ LPDIRECTINPUT7A iface,REFGUID rguid,LPDIRECTINPUTDEVICEA* pdev,
+ LPUNKNOWN punk
+) {
+ IDirectInputImpl *This = (IDirectInputImpl *)iface;
+ HRESULT ret_value = DIERR_DEVICENOTREG;
+ int i;
+
+ TRACE("(this=%p,%s,%p,%p)\n",This,debugstr_guid(rguid),pdev,punk);
+
+ if (nrof_dinput_devices==0){
+ scan_mouse();
+ scan_keyboard();
+ }
+
+ /* Loop on all the devices to see if anyone matches the given GUID */
+ for (i = 0; i < nrof_dinput_devices; i++) {
+ HRESULT ret;
+ if ((ret = dinput_devices[i]->create_deviceA(This, rguid, NULL, pdev)) == DI_OK)
+ return DI_OK;
+
+ if (ret == DIERR_NOINTERFACE)
+ ret_value = DIERR_NOINTERFACE;
+ }
+
+ return ret_value;
+}
+
+static HRESULT WINAPI IDirectInputWImpl_CreateDevice(LPDIRECTINPUT7A iface,
+ REFGUID rguid, LPDIRECTINPUTDEVICEW* pdev, LPUNKNOWN punk) {
+ IDirectInputImpl *This = (IDirectInputImpl *)iface;
+ HRESULT ret_value = DIERR_DEVICENOTREG;
+ int i;
+
+ TRACE("(this=%p,%s,%p,%p)\n",This,debugstr_guid(rguid),pdev,punk);
+
+ if (nrof_dinput_devices==0){
+ scan_mouse();
+ scan_keyboard();
+ }
+
+ /* Loop on all the devices to see if anyone matches the given GUID */
+ for (i = 0; i < nrof_dinput_devices; i++) {
+ HRESULT ret;
+ if ((ret = dinput_devices[i]->create_deviceW(This, rguid, NULL, pdev)) == DI_OK)
+ return DI_OK;
+
+ if (ret == DIERR_NOINTERFACE)
+ ret_value = DIERR_NOINTERFACE;
+ }
+
+ return ret_value;
+}
+
+static HRESULT WINAPI IDirectInputAImpl_Initialize(LPDIRECTINPUT7A iface, HINSTANCE hinst, DWORD x) {
+ return DIERR_ALREADYINITIALIZED;
+}
+
+static HRESULT WINAPI IDirectInputAImpl_GetDeviceStatus(LPDIRECTINPUT7A iface,
+ REFGUID rguid) {
+ IDirectInputImpl *This = (IDirectInputImpl *)iface;
+
+ FIXME("(%p)->(%s): stub\n",This,debugstr_guid(rguid));
+
+ return DI_OK;
+}
+
+static HRESULT WINAPI IDirectInputAImpl_RunControlPanel(LPDIRECTINPUT7A iface,
+ HWND hwndOwner,
+ DWORD dwFlags) {
+ IDirectInputImpl *This = (IDirectInputImpl *)iface;
+ FIXME("(%p)->(%08lx,%08lx): stub\n",This, (DWORD) hwndOwner, dwFlags);
+
+ return DI_OK;
+}
+
+static HRESULT WINAPI IDirectInput2AImpl_FindDevice(LPDIRECTINPUT7A iface, REFGUID rguid,
+ LPCSTR pszName, LPGUID pguidInstance) {
+ IDirectInputImpl *This = (IDirectInputImpl *)iface;
+ FIXME("(%p)->(%s, %s, %p): stub\n", This, debugstr_guid(rguid), pszName, pguidInstance);
+
+ return DI_OK;
+}
+
+static HRESULT WINAPI IDirectInput2WImpl_FindDevice(LPDIRECTINPUT7W iface, REFGUID rguid,
+ LPCWSTR pszName, LPGUID pguidInstance) {
+ IDirectInputImpl *This = (IDirectInputImpl *)iface;
+ FIXME("(%p)->(%s, %s, %p): stub\n", This, debugstr_guid(rguid), debugstr_w(pszName), pguidInstance);
+
+ return DI_OK;
+}
+
+static HRESULT WINAPI IDirectInput7AImpl_CreateDeviceEx(LPDIRECTINPUT7A iface, REFGUID rguid,
+ REFIID riid, LPVOID* pvOut, LPUNKNOWN lpUnknownOuter)
+{
+ IDirectInputImpl *This = (IDirectInputImpl *)iface;
+ HRESULT ret_value = DIERR_DEVICENOTREG;
+ int i;
+
+ TRACE("(%p)->(%s, %s, %p, %p)\n", This, debugstr_guid(rguid), debugstr_guid(riid), pvOut, lpUnknownOuter);
+
+ if (nrof_dinput_devices==0){
+ scan_mouse();
+ scan_keyboard();
+ }
+
+ /* Loop on all the devices to see if anyone matches the given GUID */
+ for (i = 0; i < nrof_dinput_devices; i++) {
+ HRESULT ret;
+ if ((ret = dinput_devices[i]->create_deviceA(This, rguid, riid, (LPDIRECTINPUTDEVICEA*) pvOut)) == DI_OK)
+ return DI_OK;
+
+ if (ret == DIERR_NOINTERFACE)
+ ret_value = DIERR_NOINTERFACE;
+ }
+
+ return ret_value;
+}
+
+static HRESULT WINAPI IDirectInput7WImpl_CreateDeviceEx(LPDIRECTINPUT7W iface, REFGUID rguid,
+ REFIID riid, LPVOID* pvOut, LPUNKNOWN lpUnknownOuter)
+{
+ IDirectInputImpl *This = (IDirectInputImpl *)iface;
+ HRESULT ret_value = DIERR_DEVICENOTREG;
+ int i;
+
+ TRACE("(%p)->(%s, %s, %p, %p)\n", This, debugstr_guid(rguid), debugstr_guid(riid), pvOut, lpUnknownOuter);
+
+ if (nrof_dinput_devices==0){
+ scan_mouse();
+ scan_keyboard();
+ }
+
+
+
+ /* Loop on all the devices to see if anyone matches the given GUID */
+ for (i = 0; i < nrof_dinput_devices; i++) {
+ HRESULT ret;
+ if ((ret = dinput_devices[i]->create_deviceW(This, rguid, riid, (LPDIRECTINPUTDEVICEW*) pvOut)) == DI_OK)
+ return DI_OK;
+
+ if (ret == DIERR_NOINTERFACE)
+ ret_value = DIERR_NOINTERFACE;
+ }
+
+ return ret_value;
+}
+
+static HRESULT WINAPI IDirectInput8AImpl_QueryInterface(LPDIRECTINPUT8A iface, REFIID riid, LPVOID *ppobj) {
+ IDirectInputImpl *This = (IDirectInputImpl *)iface;
+
+ TRACE("(this=%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
+ if (IsEqualGUID(&IID_IUnknown,riid) ||
+ IsEqualGUID(&IID_IDirectInput8A,riid)) {
+ IDirectInputAImpl_AddRef((LPDIRECTINPUT7A) iface);
+ *ppobj = This;
+ return 0;
+ }
+ TRACE("Unsupported interface !\n");
+ return E_NOINTERFACE;
+}
+
+static HRESULT WINAPI IDirectInput8WImpl_QueryInterface(LPDIRECTINPUT8W iface, REFIID riid, LPVOID *ppobj) {
+ IDirectInputImpl *This = (IDirectInputImpl *)iface;
+
+ TRACE("(this=%p,%s,%p)\n",This,debugstr_guid(riid),ppobj);
+ if (IsEqualGUID(&IID_IUnknown,riid) ||
+ IsEqualGUID(&IID_IDirectInput8W,riid)) {
+ IDirectInputAImpl_AddRef((LPDIRECTINPUT7A) iface);
+ *ppobj = This;
+ return 0;
+ }
+ TRACE("Unsupported interface !\n");
+ return E_NOINTERFACE;
+}
+
+static HRESULT WINAPI IDirectInput8AImpl_EnumDevicesBySemantics(
+ LPDIRECTINPUT8A iface, LPCSTR ptszUserName, LPDIACTIONFORMATA lpdiActionFormat,
+ LPDIENUMDEVICESBYSEMANTICSCBA lpCallback,
+ LPVOID pvRef, DWORD dwFlags
+)
+{
+ IDirectInputImpl *This = (IDirectInputImpl *)iface;
+
+ FIXME("(this=%p,%s,%p,%p,%p,%04lx): stub\n", This, ptszUserName, lpdiActionFormat,
+ lpCallback, pvRef, dwFlags);
+ return 0;
+}
+
+static HRESULT WINAPI IDirectInput8WImpl_EnumDevicesBySemantics(
+ LPDIRECTINPUT8W iface, LPCWSTR ptszUserName, LPDIACTIONFORMATW lpdiActionFormat,
+ LPDIENUMDEVICESBYSEMANTICSCBW lpCallback,
+ LPVOID pvRef, DWORD dwFlags
+)
+{
+ IDirectInputImpl *This = (IDirectInputImpl *)iface;
+
+ FIXME("(this=%p,%s,%p,%p,%p,%04lx): stub\n", This, debugstr_w(ptszUserName), lpdiActionFormat,
+ lpCallback, pvRef, dwFlags);
+ return 0;
+}
+
+static HRESULT WINAPI IDirectInput8AImpl_ConfigureDevices(
+ LPDIRECTINPUT8A iface, LPDICONFIGUREDEVICESCALLBACK lpdiCallback,
+ LPDICONFIGUREDEVICESPARAMSA lpdiCDParams, DWORD dwFlags, LPVOID pvRefData
+)
+{
+ IDirectInputImpl *This = (IDirectInputImpl *)iface;
+
+ FIXME("(this=%p,%p,%p,%04lx,%p): stub\n", This, lpdiCallback, lpdiCDParams,
+ dwFlags, pvRefData);
+ return 0;
+}
+
+static HRESULT WINAPI IDirectInput8WImpl_ConfigureDevices(
+ LPDIRECTINPUT8W iface, LPDICONFIGUREDEVICESCALLBACK lpdiCallback,
+ LPDICONFIGUREDEVICESPARAMSW lpdiCDParams, DWORD dwFlags, LPVOID pvRefData
+)
+{
+ IDirectInputImpl *This = (IDirectInputImpl *)iface;
+
+ FIXME("(this=%p,%p,%p,%04lx,%p): stub\n", This, lpdiCallback, lpdiCDParams,
+ dwFlags, pvRefData);
+ return 0;
+}
+
+#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
+# define XCAST(fun) (typeof(ddi7avt.fun))
+#else
+# define XCAST(fun) (void*)
+#endif
+
+static IDirectInput7AVtbl ddi7avt = {
+ XCAST(QueryInterface)IDirectInputAImpl_QueryInterface,
+ XCAST(AddRef)IDirectInputAImpl_AddRef,
+ XCAST(Release)IDirectInputAImpl_Release,
+ XCAST(CreateDevice)IDirectInputAImpl_CreateDevice,
+ XCAST(EnumDevices)IDirectInputAImpl_EnumDevices,
+ XCAST(GetDeviceStatus)IDirectInputAImpl_GetDeviceStatus,
+ XCAST(RunControlPanel)IDirectInputAImpl_RunControlPanel,
+ XCAST(Initialize)IDirectInputAImpl_Initialize,
+ XCAST(FindDevice)IDirectInput2AImpl_FindDevice,
+ XCAST(CreateDeviceEx)IDirectInput7AImpl_CreateDeviceEx
+};
+
+#undef XCAST
+#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
+# define XCAST(fun) (typeof(ddi7wvt.fun))
+#else
+# define XCAST(fun) (void*)
+#endif
+
+static IDirectInput7WVtbl ddi7wvt = {
+ XCAST(QueryInterface)IDirectInputWImpl_QueryInterface,
+ XCAST(AddRef)IDirectInputAImpl_AddRef,
+ XCAST(Release)IDirectInputAImpl_Release,
+ XCAST(CreateDevice)IDirectInputWImpl_CreateDevice,
+ XCAST(EnumDevices)IDirectInputWImpl_EnumDevices,
+ XCAST(GetDeviceStatus)IDirectInputAImpl_GetDeviceStatus,
+ XCAST(RunControlPanel)IDirectInputAImpl_RunControlPanel,
+ XCAST(Initialize)IDirectInputAImpl_Initialize,
+ XCAST(FindDevice)IDirectInput2WImpl_FindDevice,
+ XCAST(CreateDeviceEx)IDirectInput7WImpl_CreateDeviceEx
+};
+#undef XCAST
+
+#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
+# define XCAST(fun) (typeof(ddi8avt.fun))
+#else
+# define XCAST(fun) (void*)
+#endif
+
+static IDirectInput8AVtbl ddi8avt = {
+ XCAST(QueryInterface)IDirectInput8AImpl_QueryInterface,
+ XCAST(AddRef)IDirectInputAImpl_AddRef,
+ XCAST(Release)IDirectInputAImpl_Release,
+ XCAST(CreateDevice)IDirectInputAImpl_CreateDevice,
+ XCAST(EnumDevices)IDirectInputAImpl_EnumDevices,
+ XCAST(GetDeviceStatus)IDirectInputAImpl_GetDeviceStatus,
+ XCAST(RunControlPanel)IDirectInputAImpl_RunControlPanel,
+ XCAST(Initialize)IDirectInputAImpl_Initialize,
+ XCAST(FindDevice)IDirectInput2AImpl_FindDevice,
+ XCAST(EnumDevicesBySemantics)IDirectInput8AImpl_EnumDevicesBySemantics,
+ XCAST(ConfigureDevices)IDirectInput8AImpl_ConfigureDevices
+};
+#undef XCAST
+
+#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
+# define XCAST(fun) (typeof(ddi8wvt.fun))
+#else
+# define XCAST(fun) (void*)
+#endif
+static IDirectInput8WVtbl ddi8wvt = {
+ XCAST(QueryInterface)IDirectInput8WImpl_QueryInterface,
+ XCAST(AddRef)IDirectInputAImpl_AddRef,
+ XCAST(Release)IDirectInputAImpl_Release,
+ XCAST(CreateDevice)IDirectInputWImpl_CreateDevice,
+ XCAST(EnumDevices)IDirectInputWImpl_EnumDevices,
+ XCAST(GetDeviceStatus)IDirectInputAImpl_GetDeviceStatus,
+ XCAST(RunControlPanel)IDirectInputAImpl_RunControlPanel,
+ XCAST(Initialize)IDirectInputAImpl_Initialize,
+ XCAST(FindDevice)IDirectInput2WImpl_FindDevice,
+ XCAST(EnumDevicesBySemantics)IDirectInput8WImpl_EnumDevicesBySemantics,
+ XCAST(ConfigureDevices)IDirectInput8WImpl_ConfigureDevices
+};
+#undef XCAST
+
+/*******************************************************************************
+ * DirectInput ClassFactory
+ */
+typedef struct
+{
+ /* IUnknown fields */
+ IClassFactoryVtbl *lpVtbl;
+ DWORD ref;
+} IClassFactoryImpl;
+
+static HRESULT WINAPI DICF_QueryInterface(LPCLASSFACTORY iface,REFIID riid,LPVOID *ppobj) {
+ IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
+
+ FIXME("(%p)->(%s,%p),stub!\n",This,debugstr_guid(riid),ppobj);
+ return E_NOINTERFACE;
+}
+
+static ULONG WINAPI DICF_AddRef(LPCLASSFACTORY iface) {
+ IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
+ return InterlockedIncrement(&(This->ref));
+}
+
+static ULONG WINAPI DICF_Release(LPCLASSFACTORY iface) {
+ IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
+ /* static class, won't be freed */
+ return InterlockedDecrement(&(This->ref));
+}
+
+static HRESULT WINAPI DICF_CreateInstance(
+ LPCLASSFACTORY iface,LPUNKNOWN pOuter,REFIID riid,LPVOID *ppobj
+) {
+ IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
+
+ TRACE("(%p)->(%p,%s,%p)\n",This,pOuter,debugstr_guid(riid),ppobj);
+ if ( IsEqualGUID( &IID_IDirectInputA, riid ) ||
+ IsEqualGUID( &IID_IDirectInputW, riid ) ||
+ IsEqualGUID( &IID_IDirectInput2A, riid ) ||
+ IsEqualGUID( &IID_IDirectInput2W, riid ) ||
+ IsEqualGUID( &IID_IDirectInput7A, riid ) ||
+ IsEqualGUID( &IID_IDirectInput7W, riid ) ||
+ IsEqualGUID( &IID_IDirectInput8A, riid ) ||
+ IsEqualGUID( &IID_IDirectInput8W, riid ) ) {
+ /* FIXME: reuse already created dinput if present? */
+ return DirectInputCreateEx(0,0,riid,ppobj,pOuter);
+ }
+
+ FIXME("(%p,%p,%s,%p) Interface not found!\n",This,pOuter,debugstr_guid(riid),ppobj);
+ return E_NOINTERFACE;
+}
+
+static HRESULT WINAPI DICF_LockServer(LPCLASSFACTORY iface,BOOL dolock) {
+ IClassFactoryImpl *This = (IClassFactoryImpl *)iface;
+ FIXME("(%p)->(%d),stub!\n",This,dolock);
+ return S_OK;
+}
+
+static IClassFactoryVtbl DICF_Vtbl = {
+ DICF_QueryInterface,
+ DICF_AddRef,
+ DICF_Release,
+ DICF_CreateInstance,
+ DICF_LockServer
+};
+static IClassFactoryImpl DINPUT_CF = {&DICF_Vtbl, 1 };
+
+/***********************************************************************
+ * DllCanUnloadNow (DINPUT.@)
+ */
+HRESULT WINAPI DINPUT_DllCanUnloadNow(void)
+{
+ FIXME("(void): stub\n");
+
+ return S_FALSE;
+}
+
+/***********************************************************************
+ * DllGetClassObject (DINPUT.@)
+ */
+HRESULT WINAPI DINPUT_DllGetClassObject(REFCLSID rclsid, REFIID riid,
+ LPVOID *ppv)
+{
+ TRACE("(%p,%p,%p)\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
+ if ( IsEqualCLSID( &IID_IClassFactory, riid ) ) {
+ *ppv = (LPVOID)&DINPUT_CF;
+ IClassFactory_AddRef((IClassFactory*)*ppv);
+ return S_OK;
+ }
+
+ FIXME("(%p,%p,%p): no interface found.\n", debugstr_guid(rclsid), debugstr_guid(riid), ppv);
+ return CLASS_E_CLASSNOTAVAILABLE;
+}
reactos/lib/dinput
diff -N dinput_private.h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ dinput_private.h 29 Nov 2004 00:13:49 -0000 1.1
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2000 Lionel Ulmer
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __WINE_DLLS_DINPUT_DINPUT_PRIVATE_H
+#define __WINE_DLLS_DINPUT_DINPUT_PRIVATE_H
+
+#include <stdarg.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "dinput.h"
+
+/* Implementation specification */
+typedef struct IDirectInputImpl IDirectInputImpl;
+struct IDirectInputImpl
+{
+ LPVOID lpVtbl;
+ DWORD ref;
+
+ /* Used to have an unique sequence number for all the events */
+ DWORD evsequence;
+
+ int version;
+};
+
+/* Function called by all devices that Wine supports */
+typedef struct dinput_device {
+ INT pref;
+ const char *name;
+ BOOL (*enum_deviceA)(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, int version, int id);
+ BOOL (*enum_deviceW)(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, int version, int id);
+ HRESULT (*create_deviceA)(IDirectInputImpl *dinput, REFGUID rguid, REFIID riid, LPDIRECTINPUTDEVICEA* pdev);
+ HRESULT (*create_deviceW)(IDirectInputImpl *dinput, REFGUID rguid, REFIID riid, LPDIRECTINPUTDEVICEW* pdev);
+} dinput_device;
+
+extern void dinput_register_device(dinput_device *device);
+
+extern HINSTANCE DINPUT_instance;
+
+void scan_keyboard();
+void scan_mouse();
+
+#endif /* __WINE_DLLS_DINPUT_DINPUT_PRIVATE_H */
reactos/lib/dinput
diff -N joystick_linux.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ joystick_linux.c 29 Nov 2004 00:13:49 -0000 1.1
@@ -0,0 +1,1715 @@
+/* DirectInput Joystick device
+ *
+ * Copyright 1998 Marcus Meissner
+ * Copyright 1998,1999 Lionel Ulmer
+ * Copyright 2000-2001 TransGaming Technologies Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+/*
+ * To Do:
+ * dead zone
+ * force feedback
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#ifdef HAVE_LINUX_22_JOYSTICK_API
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <errno.h>
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+#endif
+#include <sys/fcntl.h>
+#ifdef HAVE_SYS_IOCTL_H
+# include <sys/ioctl.h>
+#endif
+#include <errno.h>
+#ifdef HAVE_SYS_ERRNO_H
+# include <sys/errno.h>
+#endif
+#ifdef HAVE_LINUX_IOCTL_H
+# include <linux/ioctl.h>
+#endif
+#ifdef HAVE_LINUX_JOYSTICK_H
+# include <linux/joystick.h>
+#endif
+#define JOYDEV "/dev/js"
+
+#include "wine/debug.h"
+#include "wine/unicode.h"
+#include "windef.h"
+#include "winbase.h"
+#include "winerror.h"
+#include "winreg.h"
+#include "dinput.h"
+
+#include "dinput_private.h"
+#include "device_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(dinput);
+
+typedef struct {
+ LONG lMin;
+ LONG lMax;
+ LONG lDeadZone;
+ LONG lSaturation;
+} ObjProps;
+
+typedef struct {
+ LONG lX;
+ LONG lY;
+} POV;
+
+typedef struct JoystickImpl JoystickImpl;
+static IDirectInputDevice8AVtbl JoystickAvt;
+static IDirectInputDevice8WVtbl JoystickWvt;
+struct JoystickImpl
+{
+ LPVOID lpVtbl;
+ DWORD ref;
+ GUID guid;
+ char dev[32];
+
+ /* The 'parent' DInput */
+ IDirectInputImpl *dinput;
+
+ /* joystick private */
+ int joyfd;
+ DIJOYSTATE2 js; /* wine data */
+ LPDIDATAFORMAT user_df; /* user defined format */
+ DataFormat *transform; /* wine to user format converter */
+ int *offsets; /* object offsets */
+ ObjProps *props;
+ HANDLE hEvent;
+ LPDIDEVICEOBJECTDATA data_queue;
+ int queue_head, queue_tail, queue_len;
+ BOOL acquired;
+ char *name;
+ DIDEVCAPS devcaps;
+ LONG deadzone;
+ int *axis_map;
+ int axes;
+ int buttons;
+ POV povs[4];
+ CRITICAL_SECTION crit;
+ BOOL overflow;
+};
+
+static GUID DInput_Wine_Joystick_GUID = { /* 9e573ed9-7734-11d2-8d4a-23903fb6bdf7 */
+ 0x9e573ed9,
+ 0x7734,
+ 0x11d2,
+ {0x8d, 0x4a, 0x23, 0x90, 0x3f, 0xb6, 0xbd, 0xf7}
+};
+
+static void _dump_DIDEVCAPS(LPDIDEVCAPS lpDIDevCaps)
+{
+ TRACE("dwSize: %ld\n", lpDIDevCaps->dwSize);
+ TRACE("dwFlags: %08lx\n",lpDIDevCaps->dwFlags);
+ TRACE("dwDevType: %08lx %s\n", lpDIDevCaps->dwDevType,
+ lpDIDevCaps->dwDevType == DIDEVTYPE_DEVICE ? "DIDEVTYPE_DEVICE" :
+ lpDIDevCaps->dwDevType == DIDEVTYPE_DEVICE ? "DIDEVTYPE_DEVICE" :
+ lpDIDevCaps->dwDevType == DIDEVTYPE_MOUSE ? "DIDEVTYPE_MOUSE" :
+ lpDIDevCaps->dwDevType == DIDEVTYPE_KEYBOARD ? "DIDEVTYPE_KEYBOARD" :
+ lpDIDevCaps->dwDevType == DIDEVTYPE_JOYSTICK ? "DIDEVTYPE_JOYSTICK" :
+ lpDIDevCaps->dwDevType == DIDEVTYPE_HID ? "DIDEVTYPE_HID" : "UNKNOWN");
+ TRACE("dwAxes: %ld\n",lpDIDevCaps->dwAxes);
+ TRACE("dwButtons: %ld\n",lpDIDevCaps->dwButtons);
+ TRACE("dwPOVs: %ld\n",lpDIDevCaps->dwPOVs);
+ if (lpDIDevCaps->dwSize > sizeof(DIDEVCAPS_DX3)) {
+ TRACE("dwFFSamplePeriod: %ld\n",lpDIDevCaps->dwFFSamplePeriod);
+ TRACE("dwFFMinTimeResolution: %ld\n",lpDIDevCaps->dwFFMinTimeResolution);
+ TRACE("dwFirmwareRevision: %ld\n",lpDIDevCaps->dwFirmwareRevision);
+ TRACE("dwHardwareRevision: %ld\n",lpDIDevCaps->dwHardwareRevision);
+ TRACE("dwFFDriverVersion: %ld\n",lpDIDevCaps->dwFFDriverVersion);
+ }
+}
+
+static BOOL joydev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, int version, int id)
+{
+ int fd = -1;
+ char dev[32];
+
+ if (dwFlags & DIEDFL_FORCEFEEDBACK) {
+ WARN("force feedback not supported\n");
+ return FALSE;
+ }
+
+ if ((dwDevType==0) || (GET_DIDEVICE_TYPE(dwDevType)==DIDEVTYPE_JOYSTICK)) {
+ /* check whether we have a joystick */
+ sprintf(dev, "%s%d", JOYDEV, id);
+ if ((fd = open(dev,O_RDONLY)) < 0) {
+ WARN("open(%s,O_RDONLY) failed: %s\n", dev, strerror(errno));
+ return FALSE;
+ }
+
+ /* Return joystick */
+ lpddi->guidInstance = DInput_Wine_Joystick_GUID;
+ lpddi->guidInstance.Data3 = id;
+ lpddi->guidProduct = DInput_Wine_Joystick_GUID;
+ /* we only support traditional joysticks for now */
+ if (version >= 8)
+ lpddi->dwDevType = DI8DEVTYPE_JOYSTICK | (DI8DEVTYPEJOYSTICK_STANDARD << 8);
+ else
+ lpddi->dwDevType = DIDEVTYPE_JOYSTICK | (DIDEVTYPEJOYSTICK_TRADITIONAL << 8);
+ sprintf(lpddi->tszInstanceName, "Joystick %d", id);
+#if defined(JSIOCGNAME)
+ if (ioctl(fd,JSIOCGNAME(sizeof(lpddi->tszProductName)),lpddi->tszProductName) < 0) {
+ WARN("ioctl(%s,JSIOCGNAME) failed: %s\n", dev, strerror(errno));
+ strcpy(lpddi->tszProductName, "Wine Joystick");
+ }
+#else
+ strcpy(lpddi->tszProductName, "Wine Joystick");
+#endif
+
+ lpddi->guidFFDriver = GUID_NULL;
+ close(fd);
+ TRACE("Enumerating the linux Joystick device: %s (%s)\n", dev, lpddi->tszProductName);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static BOOL joydev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, int version, int id)
+{
+ int fd = -1;
+ char name[MAX_PATH];
+ char dev[32];
+ char friendly[32];
+
+ if (dwFlags & DIEDFL_FORCEFEEDBACK) {
+ WARN("force feedback not supported\n");
+ return FALSE;
+ }
+
+ if ((dwDevType==0) || (GET_DIDEVICE_TYPE(dwDevType)==DIDEVTYPE_JOYSTICK)) {
+ /* check whether we have a joystick */
+ sprintf(dev, "%s%d", JOYDEV, id);
+ if ((fd = open(dev,O_RDONLY)) < 0) {
+ WARN("open(%s,O_RDONLY) failed: %s\n", dev, strerror(errno));
+ return FALSE;
+ }
+
+ /* Return joystick */
+ lpddi->guidInstance = DInput_Wine_Joystick_GUID;
+ lpddi->guidInstance.Data3 = id;
+ lpddi->guidProduct = DInput_Wine_Joystick_GUID;
+ /* we only support traditional joysticks for now */
+ if (version >= 8)
+ lpddi->dwDevType = DI8DEVTYPE_JOYSTICK | (DI8DEVTYPEJOYSTICK_STANDARD << 8);
+ else
+ lpddi->dwDevType = DIDEVTYPE_JOYSTICK | (DIDEVTYPEJOYSTICK_TRADITIONAL << 8);
+ sprintf(friendly, "Joystick %d", id);
+ MultiByteToWideChar(CP_ACP, 0, friendly, -1, lpddi->tszInstanceName, MAX_PATH);
+#if defined(JSIOCGNAME)
+ if (ioctl(fd,JSIOCGNAME(sizeof(name)),name) < 0) {
+ WARN("ioctl(%s,JSIOCGNAME) failed: %s\n", dev, strerror(errno));
+ strcpy(name, "Wine Joystick");
+ }
+#else
+ strcpy(name, "Wine Joystick");
+#endif
+ MultiByteToWideChar(CP_ACP, 0, name, -1, lpddi->tszProductName, MAX_PATH);
+ lpddi->guidFFDriver = GUID_NULL;
+ close(fd);
+ TRACE("Enumerating the linux Joystick device: %s (%s)\n",dev,name);
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/*
+ * Get a config key from either the app-specific or the default config
+ */
+
+inline static DWORD get_config_key( HKEY defkey, HKEY appkey, const char *name,
+ char *buffer, DWORD size )
+{
+ if (appkey && !RegQueryValueExA( appkey, name, 0, NULL, buffer, &size ))
+ return 0;
+
+ if (defkey && !RegQueryValueExA( defkey, name, 0, NULL, buffer, &size ))
+ return 0;
+
+ return ERROR_FILE_NOT_FOUND;
+}
+
+/*
+ * Setup the dinput options.
+ */
+
+static HRESULT setup_dinput_options(JoystickImpl * device)
+{
+ char buffer[MAX_PATH+1];
+ HKEY hkey, appkey = 0;
+ DWORD len;
+
+ buffer[MAX_PATH]='\0';
+
+ if (RegOpenKeyA( HKEY_LOCAL_MACHINE, "Software\\Wine\\dinput", &hkey)) hkey = 0;
+
+ len = GetModuleFileNameA( 0, buffer, MAX_PATH );
+ if (len && len < MAX_PATH) {
+ HKEY tmpkey;
+
+ if (!RegOpenKeyA( HKEY_LOCAL_MACHINE, "Software\\Wine\\AppDefaults", &tmpkey )) {
+ char appname[MAX_PATH+16];
+ char *p = strrchr( buffer, '\\' );
+ if (p!=NULL) {
+ strcpy(appname,p+1);
+ strcat(appname,"\\dinput");
+ TRACE("appname = [%s] \n",appname);
+ if (RegOpenKeyA( tmpkey, appname, &appkey )) appkey = 0;
+ }
+ RegCloseKey( tmpkey );
+ }
+ }
+
+ /* get options */
+
+ if (!get_config_key( hkey, appkey, "DefaultDeadZone", buffer, MAX_PATH )) {
+ device->deadzone = atoi(buffer);
+ TRACE("setting default deadzone to: \"%s\" %ld\n", buffer, device->deadzone);
+ }
+
+ if (!get_config_key( hkey, appkey, device->name, buffer, MAX_PATH )) {
+ int tokens = 0;
+ int axis = 0;
+ int pov = 0;
+ char *delim = ",";
+ char * ptr;
+ TRACE("\"%s\" = \"%s\"\n", device->name, buffer);
+
+ device->axis_map = HeapAlloc(GetProcessHeap(), 0, device->axes * sizeof(int));
+ if (device->axis_map == 0)
+ return DIERR_OUTOFMEMORY;
+
+ if ((ptr = strtok(buffer, delim)) != NULL) {
+ do {
+ if (strcmp(ptr, "X") == 0) {
+ device->axis_map[tokens] = 0;
+ axis++;
+ } else if (strcmp(ptr, "Y") == 0) {
+ device->axis_map[tokens] = 1;
+ axis++;
+ } else if (strcmp(ptr, "Z") == 0) {
+ device->axis_map[tokens] = 2;
+ axis++;
+ } else if (strcmp(ptr, "Rx") == 0) {
+ device->axis_map[tokens] = 3;
+ axis++;
+ } else if (strcmp(ptr, "Ry") == 0) {
+ device->axis_map[tokens] = 4;
+ axis++;
+ } else if (strcmp(ptr, "Rz") == 0) {
+ device->axis_map[tokens] = 5;
+ axis++;
+ } else if (strcmp(ptr, "Slider1") == 0) {
+ device->axis_map[tokens] = 6;
+ axis++;
+ } else if (strcmp(ptr, "Slider2") == 0) {
+ device->axis_map[tokens] = 7;
+ axis++;
+ } else if (strcmp(ptr, "POV1") == 0) {
+ device->axis_map[tokens++] = 8;
+ device->axis_map[tokens] = 8;
+ pov++;
+ } else if (strcmp(ptr, "POV2") == 0) {
+ device->axis_map[tokens++] = 9;
+ device->axis_map[tokens] = 9;
+ pov++;
+ } else if (strcmp(ptr, "POV3") == 0) {
+ device->axis_map[tokens++] = 10;
+ device->axis_map[tokens] = 10;
+ pov++;
+ } else if (strcmp(ptr, "POV4") == 0) {
+ device->axis_map[tokens++] = 11;
+ device->axis_map[tokens] = 11;
+ pov++;
+ } else {
+ ERR("invalid joystick axis type: %s\n", ptr);
+ device->axis_map[tokens] = tokens;
+ axis++;
+ }
+
+ tokens++;
+ } while ((ptr = strtok(NULL, delim)) != NULL);
+
+ if (tokens != device->devcaps.dwAxes) {
+ ERR("not all joystick axes mapped: %d axes(%d,%d), %d arguments\n", device->axes, axis, pov,tokens);
+ while (tokens < device->axes) {
+ device->axis_map[tokens] = tokens;
+ tokens++;
+ }
+ }
+ }
+
+ device->devcaps.dwAxes = axis;
+ device->devcaps.dwPOVs = pov;
+ }
+
+ if (appkey)
+ RegCloseKey( appkey );
+
+ if (hkey)
+ RegCloseKey( hkey );
+
+ return DI_OK;
+}
+
+void calculate_ids(JoystickImpl* device)
+{
+ int i;
+ int axis = 0;
+ int button = 0;
+ int pov = 0;
+ int axis_base;
+ int pov_base;
+ int button_base;
+
+ /* Make two passes over the format. The first counts the number
+ * for each type and the second sets the id */
+ for (i = 0; i < device->user_df->dwNumObjs; i++) {
+ if (DIDFT_GETTYPE(device->user_df->rgodf[i].dwType) & DIDFT_AXIS)
+ axis++;
+ else if (DIDFT_GETTYPE(device->user_df->rgodf[i].dwType) & DIDFT_POV)
+ pov++;
+ else if (DIDFT_GETTYPE(device->user_df->rgodf[i].dwType) & DIDFT_BUTTON)
+ button++;
+ }
+
+ axis_base = 0;
+ pov_base = axis;
+ button_base = axis + pov;
+
+ axis = 0;
+ button = 0;
+ pov = 0;
+
+ for (i = 0; i < device->user_df->dwNumObjs; i++) {
+ DWORD type = 0;
+ if (DIDFT_GETTYPE(device->user_df->rgodf[i].dwType) & DIDFT_AXIS) {
+ axis++;
+ type = DIDFT_GETTYPE(device->user_df->rgodf[i].dwType) |
+ DIDFT_MAKEINSTANCE(axis + axis_base);
+ TRACE("axis type = 0x%08lx\n", type);
+ } else if (DIDFT_GETTYPE(device->user_df->rgodf[i].dwType) & DIDFT_POV) {
+ pov++;
+ type = DIDFT_GETTYPE(device->user_df->rgodf[i].dwType) |
+ DIDFT_MAKEINSTANCE(pov + pov_base);
+ TRACE("POV type = 0x%08lx\n", type);
+ } else if (DIDFT_GETTYPE(device->user_df->rgodf[i].dwType) & DIDFT_BUTTON) {
+ button++;
+ type = DIDFT_GETTYPE(device->user_df->rgodf[i].dwType) |
+ DIDFT_MAKEINSTANCE(button + button_base);
+ TRACE("button type = 0x%08lx\n", type);
+ }
+ device->user_df->rgodf[i].dwType = type;
+ }
+}
+
+static HRESULT alloc_device(REFGUID rguid, LPVOID jvt, IDirectInputImpl *dinput, LPDIRECTINPUTDEVICEA* pdev)
+{
+ DWORD i;
+ JoystickImpl* newDevice;
+ char name[MAX_PATH];
+ HRESULT hr;
+
+ newDevice = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(JoystickImpl));
+ if (newDevice == 0) {
+ WARN("out of memory\n");
+ *pdev = 0;
+ return DIERR_OUTOFMEMORY;
+ }
+
+ sprintf(newDevice->dev, "%s%d", JOYDEV, rguid->Data3);
+
+ if ((newDevice->joyfd = open(newDevice->dev,O_RDONLY)) < 0) {
+ WARN("open(%s,O_RDONLY) failed: %s\n", newDevice->dev, strerror(errno));
+ HeapFree(GetProcessHeap(), 0, newDevice);
+ return DIERR_DEVICENOTREG;
+ }
+
+ /* get the device name */
+#if defined(JSIOCGNAME)
+ if (ioctl(newDevice->joyfd,JSIOCGNAME(MAX_PATH),name) < 0) {
+ WARN("ioctl(%s,JSIOCGNAME) failed: %s\n", newDevice->dev, strerror(errno));
+ strcpy(name, "Wine Joystick");
+ }
+#else
+ strcpy(name, "Wine Joystick");
+#endif
+
+ /* copy the device name */
+ newDevice->name = HeapAlloc(GetProcessHeap(),0,strlen(name) + 1);
+ strcpy(newDevice->name, name);
+
+#ifdef JSIOCGAXES
+ if (ioctl(newDevice->joyfd,JSIOCGAXES,&newDevice->axes) < 0) {
+ WARN("ioctl(%s,JSIOCGAXES) failed: %s, defauting to 2\n", newDevice->dev, strerror(errno));
+ newDevice->axes = 2;
+ }
+#endif
+#ifdef JSIOCGBUTTONS
+ if (ioctl(newDevice->joyfd,JSIOCGBUTTONS,&newDevice->buttons) < 0) {
+ WARN("ioctl(%s,JSIOCGBUTTONS) failed: %s, defauting to 2\n", newDevice->dev, strerror(errno));
+ newDevice->buttons = 2;
+ }
+#endif
+
+ newDevice->lpVtbl = jvt;
+ newDevice->ref = 1;
+ newDevice->dinput = dinput;
+ newDevice->acquired = FALSE;
+ newDevice->overflow = FALSE;
+ CopyMemory(&(newDevice->guid),rguid,sizeof(*rguid));
+
+ /* setup_dinput_options may change these */
+ newDevice->deadzone = 5000;
+ newDevice->devcaps.dwButtons = newDevice->buttons;
+ newDevice->devcaps.dwAxes = newDevice->axes;
+ newDevice->devcaps.dwPOVs = 0;
+
+ /* do any user specified configuration */
+ hr = setup_dinput_options(newDevice);
+ if (hr != DI_OK)
+ goto FAILED1;
+
+ if (newDevice->axis_map == 0) {
+ newDevice->axis_map = HeapAlloc(GetProcessHeap(), 0, newDevice->axes * sizeof(int));
+ if (newDevice->axis_map == 0)
+ goto FAILED;
+
+ for (i = 0; i < newDevice->axes; i++)
+ newDevice->axis_map[i] = i;
+ }
+
+ /* wine uses DIJOYSTATE2 as it's internal format so copy
+ * the already defined format c_dfDIJoystick2 */
+ newDevice->user_df = HeapAlloc(GetProcessHeap(),0,c_dfDIJoystick2.dwSize);
+ if (newDevice->user_df == 0)
+ goto FAILED;
+
+ CopyMemory(newDevice->user_df, &c_dfDIJoystick2, c_dfDIJoystick2.dwSize);
+
+ /* copy default objects */
+ newDevice->user_df->rgodf = HeapAlloc(GetProcessHeap(),0,c_dfDIJoystick2.dwNumObjs*c_dfDIJoystick2.dwObjSize);
+ if (newDevice->user_df->rgodf == 0)
+ goto FAILED;
+
+ CopyMemory(newDevice->user_df->rgodf,c_dfDIJoystick2.rgodf,c_dfDIJoystick2.dwNumObjs*c_dfDIJoystick2.dwObjSize);
+
+ /* create default properties */
+ newDevice->props = HeapAlloc(GetProcessHeap(),0,c_dfDIJoystick2.dwNumObjs*sizeof(ObjProps));
+ if (newDevice->props == 0)
+ goto FAILED;
+
+ /* initialize default properties */
+ for (i = 0; i < c_dfDIJoystick2.dwNumObjs; i++) {
+ newDevice->props[i].lMin = 0;
+ newDevice->props[i].lMax = 0xffff;
+ newDevice->props[i].lDeadZone = newDevice->deadzone; /* % * 1000 */
+ newDevice->props[i].lSaturation = 0;
+ }
+
+ /* create an offsets array */
+ newDevice->offsets = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,c_dfDIJoystick2.dwNumObjs*sizeof(int));
+ if (newDevice->offsets == 0)
+ goto FAILED;
+
+ /* create the default transform filter */
+ newDevice->transform = create_DataFormat(&c_dfDIJoystick2, newDevice->user_df, newDevice->offsets);
+
+ calculate_ids(newDevice);
+
+ IDirectInputDevice_AddRef((LPDIRECTINPUTDEVICE8A)newDevice->dinput);
+ InitializeCriticalSection(&(newDevice->crit));
+ newDevice->crit.DebugInfo->Spare[1] = (DWORD)"DINPUT_Mouse";
+
+ newDevice->devcaps.dwSize = sizeof(newDevice->devcaps);
+ newDevice->devcaps.dwFlags = DIDC_ATTACHED;
+ newDevice->devcaps.dwDevType = DIDEVTYPE_JOYSTICK;
+ newDevice->devcaps.dwFFSamplePeriod = 0;
+ newDevice->devcaps.dwFFMinTimeResolution = 0;
+ newDevice->devcaps.dwFirmwareRevision = 0;
+ newDevice->devcaps.dwHardwareRevision = 0;
+ newDevice->devcaps.dwFFDriverVersion = 0;
+
+ if (TRACE_ON(dinput)) {
+ _dump_DIDATAFORMAT(newDevice->user_df);
+ for (i = 0; i < (newDevice->axes); i++)
+ TRACE("axis_map[%ld] = %d\n", i, newDevice->axis_map[i]);
+ _dump_DIDEVCAPS(&newDevice->devcaps);
+ }
+
+ *pdev = (LPDIRECTINPUTDEVICEA)newDevice;
+
+ return DI_OK;
+
+FAILED:
+ hr = DIERR_OUTOFMEMORY;
+FAILED1:
+ if (newDevice->axis_map)
+ HeapFree(GetProcessHeap(),0,newDevice->axis_map);
+ if (newDevice->name)
+ HeapFree(GetProcessHeap(),0,newDevice->name);
+ if (newDevice->props)
+ HeapFree(GetProcessHeap(),0,newDevice->props);
+ if (newDevice->user_df->rgodf)
+ HeapFree(GetProcessHeap(),0,newDevice->user_df->rgodf);
+ if (newDevice->user_df)
+ HeapFree(GetProcessHeap(),0,newDevice->user_df);
+ if (newDevice)
+ HeapFree(GetProcessHeap(),0,newDevice);
+ *pdev = 0;
+
+ return hr;
+}
+
+static BOOL IsJoystickGUID(REFGUID guid)
+{
+ GUID wine_joystick = DInput_Wine_Joystick_GUID;
+ GUID dev_guid = *guid;
+
+ wine_joystick.Data3 = 0;
+ dev_guid.Data3 = 0;
+
+ return IsEqualGUID(&wine_joystick, &dev_guid);
+}
+
+static HRESULT joydev_create_deviceA(IDirectInputImpl *dinput, REFGUID rguid, REFIID riid, LPDIRECTINPUTDEVICEA* pdev)
+{
+ if ((IsEqualGUID(&GUID_Joystick,rguid)) ||
+ (IsJoystickGUID(rguid))) {
+ if ((riid == NULL) ||
+ IsEqualGUID(&IID_IDirectInputDeviceA,riid) ||
+ IsEqualGUID(&IID_IDirectInputDevice2A,riid) ||
+ IsEqualGUID(&IID_IDirectInputDevice7A,riid) ||
+ IsEqualGUID(&IID_IDirectInputDevice8A,riid)) {
+ return alloc_device(rguid, &JoystickAvt, dinput, pdev);
+ } else {
+ WARN("no interface\n");
+ *pdev = 0;
+ return DIERR_NOINTERFACE;
+ }
+ }
+
+ WARN("invalid device GUID\n");
+ *pdev = 0;
+ return DIERR_DEVICENOTREG;
+}
+
+static HRESULT joydev_create_deviceW(IDirectInputImpl *dinput, REFGUID rguid, REFIID riid, LPDIRECTINPUTDEVICEW* pdev)
+{
+ if ((IsEqualGUID(&GUID_Joystick,rguid)) ||
+ (IsJoystickGUID(rguid))) {
+ if ((riid == NULL) ||
+ IsEqualGUID(&IID_IDirectInputDeviceW,riid) ||
+ IsEqualGUID(&IID_IDirectInputDevice2W,riid) ||
+ IsEqualGUID(&IID_IDirectInputDevice7W,riid) ||
+ IsEqualGUID(&IID_IDirectInputDevice8W,riid)) {
+ return alloc_device(rguid, &JoystickWvt, dinput, (LPDIRECTINPUTDEVICEA *)pdev);
+ } else {
+ WARN("no interface\n");
+ *pdev = 0;
+ return DIERR_NOINTERFACE;
+ }
+ }
+
+ WARN("invalid device GUID\n");
+ *pdev = 0;
+ return DIERR_DEVICENOTREG;
+}
+
+static dinput_device joydev = {
+ 10,
+ "Wine Linux joystick driver",
+ joydev_enum_deviceA,
+ joydev_enum_deviceW,
+ joydev_create_deviceA,
+ joydev_create_deviceW
+};
+
+DECL_GLOBAL_CONSTRUCTOR(joydev_register) { dinput_register_device(&joydev); }
+
+
+
+/******************************************************************************
+ * Joystick
+ */
+static ULONG WINAPI JoystickAImpl_Release(LPDIRECTINPUTDEVICE8A iface)
+{
+ JoystickImpl *This = (JoystickImpl *)iface;
+ ULONG ref;
+
+ ref = InterlockedDecrement((&This->ref));
+ if (ref)
+ return ref;
+
+ /* Free the device name */
+ if (This->name)
+ HeapFree(GetProcessHeap(),0,This->name);
+
+ /* Free the axis map */
+ if (This->axis_map)
+ HeapFree(GetProcessHeap(),0,This->axis_map);
+
+ /* Free the data queue */
+ if (This->data_queue != NULL)
+ HeapFree(GetProcessHeap(),0,This->data_queue);
+
+ /* Free the DataFormat */
+ HeapFree(GetProcessHeap(), 0, This->user_df->rgodf);
+ HeapFree(GetProcessHeap(), 0, This->user_df);
+
+ /* Free the properties */
+ HeapFree(GetProcessHeap(), 0, This->props);
+
+ /* Free the offsets array */
+ HeapFree(GetProcessHeap(),0,This->offsets);
+
+ /* release the data transform filter */
+ release_DataFormat(This->transform);
+
+ This->crit.DebugInfo->Spare[1] = 0;
+ DeleteCriticalSection(&(This->crit));
+ IDirectInputDevice_Release((LPDIRECTINPUTDEVICE8A)This->dinput);
+
+ HeapFree(GetProcessHeap(),0,This);
+ return 0;
+}
+
+/******************************************************************************
+ * SetDataFormat : the application can choose the format of the data
+ * the device driver sends back with GetDeviceState.
+ */
+static HRESULT WINAPI JoystickAImpl_SetDataFormat(
+ LPDIRECTINPUTDEVICE8A iface,
+ LPCDIDATAFORMAT df)
+{
+ JoystickImpl *This = (JoystickImpl *)iface;
+ unsigned int i;
+ LPDIDATAFORMAT new_df = 0;
+ LPDIOBJECTDATAFORMAT new_rgodf = 0;
+ ObjProps * new_props = 0;
+
+ TRACE("(%p,%p)\n",This,df);
+
+ if (This->acquired) {
+ WARN("acquired\n");
+ return DIERR_ACQUIRED;
+ }
+
+ if (TRACE_ON(dinput))
+ _dump_DIDATAFORMAT(df);
+
+ /* Store the new data format */
+ new_df = HeapAlloc(GetProcessHeap(),0,df->dwSize);
+ if (new_df == 0)
+ goto FAILED;
+
+ new_rgodf = HeapAlloc(GetProcessHeap(),0,df->dwNumObjs*df->dwObjSize);
+ if (new_rgodf == 0)
+ goto FAILED;
+
+ new_props = HeapAlloc(GetProcessHeap(),0,df->dwNumObjs*sizeof(ObjProps));
+ if (new_props == 0)
+ goto FAILED;
+
+ HeapFree(GetProcessHeap(),0,This->user_df);
+ HeapFree(GetProcessHeap(),0,This->user_df->rgodf);
+ HeapFree(GetProcessHeap(),0,This->props);
+ release_DataFormat(This->transform);
+
+ This->user_df = new_df;
+ CopyMemory(This->user_df, df, df->dwSize);
+ This->user_df->rgodf = new_rgodf;
+ CopyMemory(This->user_df->rgodf,df->rgodf,df->dwNumObjs*df->dwObjSize);
+ This->props = new_props;
+ for (i = 0; i < df->dwNumObjs; i++) {
+ This->props[i].lMin = 0;
+ This->props[i].lMax = 0xffff;
+ This->props[i].lDeadZone = 1000;
+ This->props[i].lSaturation = 0;
+ }
+ This->transform = create_DataFormat(&c_dfDIJoystick2, This->user_df, This->offsets);
+
+ calculate_ids(This);
+
+ return DI_OK;
+
+FAILED:
+ WARN("out of memory\n");
+ if (new_props)
+ HeapFree(GetProcessHeap(),0,new_props);
+ if (new_rgodf)
+ HeapFree(GetProcessHeap(),0,new_rgodf);
+ if (new_df)
+ HeapFree(GetProcessHeap(),0,new_df);
+ return DIERR_OUTOFMEMORY;
+}
+
+/******************************************************************************
+ * Acquire : gets exclusive control of the joystick
+ */
+static HRESULT WINAPI JoystickAImpl_Acquire(LPDIRECTINPUTDEVICE8A iface)
+{
+ JoystickImpl *This = (JoystickImpl *)iface;
+
+ TRACE("(%p)\n",This);
+
+ if (This->acquired) {
+ WARN("already acquired\n");
+ return S_FALSE;
+ }
+
+ /* open the joystick device */
+ if (This->joyfd==-1) {
+ TRACE("opening joystick device %s\n", This->dev);
+
+ This->joyfd=open(This->dev,O_RDONLY);
+ if (This->joyfd==-1) {
+ ERR("open(%s) failed: %s\n", This->dev, strerror(errno));
+ return DIERR_NOTFOUND;
+ }
+ }
+
+ This->acquired = TRUE;
+
+ return DI_OK;
+}
+
+/******************************************************************************
+ * Unacquire : frees the joystick
+ */
+static HRESULT WINAPI JoystickAImpl_Unacquire(LPDIRECTINPUTDEVICE8A iface)
+{
+ JoystickImpl *This = (JoystickImpl *)iface;
+
+ TRACE("(%p)\n",This);
+
+ if (!This->acquired) {
+ WARN("not acquired\n");
+ return DIERR_NOTACQUIRED;
+ }
+
+ if (This->joyfd!=-1) {
+ TRACE("closing joystick device\n");
+ close(This->joyfd);
+ This->joyfd = -1;
+ This->acquired = FALSE;
+ return DI_OK;
+ }
+
+ This->acquired = FALSE;
+
+ return DI_NOEFFECT;
+}
+
+LONG map_axis(JoystickImpl * This, short val, short index)
+{
+ double fval = val;
+ double fmin = This->props[index].lMin;
+ double fmax = This->props[index].lMax;
+ double fret;
+
+ fret = (((fval + 32767.0) * (fmax - fmin)) / (32767.0*2.0)) + fmin;
+
+ if (fret >= 0.0)
+ fret += 0.5;
+ else
+ fret -= 0.5;
+
+ return fret;
+}
+
+/* convert wine format offset to user format object index */
+int offset_to_object(JoystickImpl *This, int offset)
+{
+ int i;
+
+ for (i = 0; i < This->user_df->dwNumObjs; i++) {
+ if (This->user_df->rgodf[i].dwOfs == offset)
+ return i;
+ }
+
+ return -1;
+}
+
+static LONG calculate_pov(JoystickImpl *This, int index)
+{
+ if (This->povs[index].lX < 16384) {
+ if (This->povs[index].lY < 16384)
+ This->js.rgdwPOV[index] = 31500;
+ else if (This->povs[index].lY > 49150)
+ This->js.rgdwPOV[index] = 22500;
+ else
+ This->js.rgdwPOV[index] = 27000;
+ } else if (This->povs[index].lX > 49150) {
+ if (This->povs[index].lY < 16384)
+ This->js.rgdwPOV[index] = 4500;
+ else if (This->povs[index].lY > 49150)
+ This->js.rgdwPOV[index] = 13500;
+ else
+ This->js.rgdwPOV[index] = 9000;
+ } else {
+ if (This->povs[index].lY < 16384)
+ This->js.rgdwPOV[index] = 0;
+ else if (This->povs[index].lY > 49150)
+ This->js.rgdwPOV[index] = 18000;
+ else
+ This->js.rgdwPOV[index] = -1;
+ }
+
+ return This->js.rgdwPOV[index];
+}
+
+static void joy_polldev(JoystickImpl *This) {
+ struct timeval tv;
+ fd_set readfds;
+ struct js_event jse;
+ TRACE("(%p)\n", This);
+
+ if (This->joyfd==-1) {
+ WARN("no device\n");
+ return;
+ }
+ while (1) {
+ memset(&tv,0,sizeof(tv));
+ FD_ZERO(&readfds);FD_SET(This->joyfd,&readfds);
+ if (1>select(This->joyfd+1,&readfds,NULL,NULL,&tv))
+ return;
+ /* we have one event, so we can read */
+ if (sizeof(jse)!=read(This->joyfd,&jse,sizeof(jse))) {
+ return;
+ }
+ TRACE("js_event: type 0x%x, number %d, value %d\n",
+ jse.type,jse.number,jse.value);
+ if (jse.type & JS_EVENT_BUTTON) {
+ int offset = This->offsets[jse.number + 12];
+ int value = jse.value?0x80:0x00;
+
+ This->js.rgbButtons[jse.number] = value;
+ GEN_EVENT(offset,value,jse.time,(This->dinput->evsequence)++);
+ } else if (jse.type & JS_EVENT_AXIS) {
+ int number = This->axis_map[jse.number]; /* wine format object index */
+ if (number < 12) {
+ int offset = This->offsets[number];
+ int index = offset_to_object(This, offset);
+ LONG value = map_axis(This, jse.value, index);
+
+ /* FIXME do deadzone and saturation here */
+
+ TRACE("changing axis %d => %d\n", jse.number, number);
+ switch (number) {
+ case 0:
+ This->js.lX = value;
+ break;
+ case 1:
+ This->js.lY = value;
+ break;
+ case 2:
+ This->js.lZ = value;
+ break;
+ case 3:
+ This->js.lRx = value;
+ break;
+ case 4:
+ This->js.lRy = value;
+ break;
+ case 5:
+ This->js.lRz = value;
+ break;
+ case 6:
+ This->js.rglSlider[0] = value;
+ break;
+ case 7:
+ This->js.rglSlider[1] = value;
+ break;
+ case 8:
+ /* FIXME don't go off array */
+ if (This->axis_map[jse.number + 1] == number)
+ This->povs[0].lX = value;
+ else if (This->axis_map[jse.number - 1] == number)
+ This->povs[0].lY = value;
+ value = calculate_pov(This, 0);
+ break;
+ case 9:
+ if (This->axis_map[jse.number + 1] == number)
+ This->povs[1].lX = value;
+ else if (This->axis_map[jse.number - 1] == number)
+ This->povs[1].lY = value;
+ value = calculate_pov(This, 1);
+ break;
+ case 10:
+ if (This->axis_map[jse.number + 1] == number)
+ This->povs[2].lX = value;
+ else if (This->axis_map[jse.number - 1] == number)
+ This->povs[2].lY = value;
+ value = calculate_pov(This, 2);
+ break;
+ case 11:
+ if (This->axis_map[jse.number + 1] == number)
+ This->povs[3].lX = value;
+ else if (This->axis_map[jse.number - 1] == number)
+ This->povs[3].lY = value;
+ value = calculate_pov(This, 3);
+ break;
+ }
+
+ GEN_EVENT(offset,value,jse.time,(This->dinput->evsequence)++);
+ } else
+ WARN("axis %d not supported\n", number);
+ }
+ }
+}
+
+/******************************************************************************
+ * GetDeviceState : returns the "state" of the joystick.
+ *
+ */
+static HRESULT WINAPI JoystickAImpl_GetDeviceState(
+ LPDIRECTINPUTDEVICE8A iface,
[truncated at 1000 lines; 719 more skipped]
reactos/lib/dinput
diff -N joystick_linuxinput.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ joystick_linuxinput.c 29 Nov 2004 00:13:49 -0000 1.1
@@ -0,0 +1,1090 @@
+/* DirectInput Joystick device
+ *
+ * Copyright 1998,2000 Marcus Meissner
+ * Copyright 1998,1999 Lionel Ulmer
+ * Copyright 2000-2001 TransGaming Technologies Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#ifdef HAVE_LINUX_INPUT_H
+
+#include <assert.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+#endif
+#include <sys/fcntl.h>
+#ifdef HAVE_SYS_IOCTL_H
+# include <sys/ioctl.h>
+#endif
+#include <errno.h>
+#ifdef HAVE_SYS_ERRNO_H
+# include <sys/errno.h>
+#endif
+
+#ifdef HAVE_CORRECT_LINUXINPUT_H
+
+#ifdef HAVE_LINUX_INPUT_H
+# include <linux/input.h>
+#endif
+
+
+#define EVDEVPREFIX "/dev/input/event"
+
+#include "wine/debug.h"
+#include "wine/unicode.h"
+#include "windef.h"
+#include "winbase.h"
+#include "winerror.h"
+#include "dinput.h"
+
+#include "dinput_private.h"
+#include "device_private.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(dinput);
+
+/* Wine joystick driver object instances */
+#define WINE_JOYSTICK_AXIS_BASE 0
+#define WINE_JOYSTICK_BUTTON_BASE 8
+
+typedef struct JoystickImpl JoystickImpl;
+static IDirectInputDevice8AVtbl JoystickAvt;
+static IDirectInputDevice8WVtbl JoystickWvt;
+struct JoystickImpl
+{
+ LPVOID lpVtbl;
+ DWORD ref;
+ GUID guid;
+
+
+ /* The 'parent' DInput */
+ IDirectInputImpl *dinput;
+
+ /* joystick private */
+ /* what range and deadzone the game wants */
+ LONG wantmin[ABS_MAX];
+ LONG wantmax[ABS_MAX];
+ LONG deadz[ABS_MAX];
+
+ /* autodetecting ranges per axe by following movement */
+ LONG havemax[ABS_MAX];
+ LONG havemin[ABS_MAX];
+
+ int joyfd;
+
+ LPDIDATAFORMAT df;
+ HANDLE hEvent;
+ LPDIDEVICEOBJECTDATA data_queue;
+ int queue_head, queue_tail, queue_len;
+ BOOL overflow;
+ DIJOYSTATE2 js;
+
+ /* data returned by the EVIOCGABS() ioctl */
+ int axes[ABS_MAX+1][5];
+
+#define AXE_ABS 0
+#define AXE_ABSMIN 1
+#define AXE_ABSMAX 2
+#define AXE_ABSFUZZ 3
+#define AXE_ABSFLAT 4
+
+
+ /* data returned by EVIOCGBIT for EV_ABS and EV_KEY */
+ BYTE absbits[(ABS_MAX+7)/8];
+ BYTE keybits[(KEY_MAX+7)/8];
+};
+
+/* This GUID is slightly different from the linux joystick one. Take note. */
+static GUID DInput_Wine_Joystick_GUID = { /* 9e573eda-7734-11d2-8d4a-23903fb6bdf7 */
+ 0x9e573eda,
+ 0x7734,
+ 0x11d2,
+ {0x8d, 0x4a, 0x23, 0x90, 0x3f, 0xb6, 0xbd, 0xf7}
+};
+
+static void fake_current_js_state(JoystickImpl *ji);
+
+#define test_bit(arr,bit) (((BYTE*)arr)[bit>>3]&(1<<(bit&7)))
+
+static int joydev_have(void)
+{
+ int i, fd;
+ int havejoy = 0;
+
+ for (i=0;i<64;i++) {
+ char buf[200];
+ BYTE absbits[(ABS_MAX+7)/8],keybits[(KEY_MAX+7)/8];
+
+ sprintf(buf,EVDEVPREFIX"%d",i);
+ if (-1!=(fd=open(buf,O_RDONLY))) {
+ if (-1==ioctl(fd,EVIOCGBIT(EV_ABS,sizeof(absbits)),absbits)) {
+ perror("EVIOCGBIT EV_ABS");
+ close(fd);
+ continue;
+ }
+ if (-1==ioctl(fd,EVIOCGBIT(EV_KEY,sizeof(keybits)),keybits)) {
+ perror("EVIOCGBIT EV_KEY");
+ close(fd);
+ continue;
+ }
+ /* A true joystick has at least axis X and Y, and at least 1
+ * button. copied from linux/drivers/input/joydev.c */
+ if (test_bit(absbits,ABS_X) && test_bit(absbits,ABS_Y) &&
+ ( test_bit(keybits,BTN_TRIGGER) ||
+ test_bit(keybits,BTN_A) ||
+ test_bit(keybits,BTN_1)
+ )
+ ) {
+ FIXME("found a joystick at %s!\n",buf);
+ havejoy = 1;
+ }
+ close(fd);
+ }
+ if (havejoy || (errno==ENODEV))
+ break;
+ }
+ return havejoy;
+}
+
+static BOOL joydev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, int version, int id)
+{
+ int havejoy = 0;
+
+ if (id != 0)
+ return FALSE;
+
+ if ((dwDevType != 0) && (GET_DIDEVICE_TYPE(dwDevType) != DIDEVTYPE_JOYSTICK))
+ return FALSE;
+
+ if (dwFlags & DIEDFL_FORCEFEEDBACK)
+ return FALSE;
+
+ havejoy = joydev_have();
+
+ if (!havejoy)
+ return FALSE;
+
+ TRACE("Enumerating the linuxinput Joystick device\n");
+
+ /* Return joystick */
+ lpddi->guidInstance = GUID_Joystick;
+ lpddi->guidProduct = DInput_Wine_Joystick_GUID;
+
+ lpddi->guidFFDriver = GUID_NULL;
+ if (version >= 8)
+ lpddi->dwDevType = DI8DEVTYPE_JOYSTICK | (DI8DEVTYPEJOYSTICK_STANDARD << 8);
+ else
+ lpddi->dwDevType = DIDEVTYPE_JOYSTICK | (DIDEVTYPEJOYSTICK_TRADITIONAL << 8);
+
+ strcpy(lpddi->tszInstanceName, "Joystick");
+ /* ioctl JSIOCGNAME(len) */
+ strcpy(lpddi->tszProductName, "Wine Joystick");
+ return TRUE;
+}
+
+static BOOL joydev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, int version, int id)
+{
+ int havejoy = 0;
+
+ if (id != 0)
+ return FALSE;
+
+ if ((dwDevType != 0) && (GET_DIDEVICE_TYPE(dwDevType) != DIDEVTYPE_JOYSTICK))
+ return FALSE;
+
+ if (dwFlags & DIEDFL_FORCEFEEDBACK)
+ return FALSE;
+
+ havejoy = joydev_have();
+
+ if (!havejoy)
+ return FALSE;
+
+ TRACE("Enumerating the linuxinput Joystick device\n");
+
+ /* Return joystick */
+ lpddi->guidInstance = GUID_Joystick;
+ lpddi->guidProduct = DInput_Wine_Joystick_GUID;
+
+ lpddi->guidFFDriver = GUID_NULL;
+ lpddi->dwDevType = DIDEVTYPE_JOYSTICK | (DIDEVTYPEJOYSTICK_TRADITIONAL<<8);
+
+ MultiByteToWideChar(CP_ACP, 0, "Joystick", -1, lpddi->tszInstanceName, MAX_PATH);
+ /* ioctl JSIOCGNAME(len) */
+ MultiByteToWideChar(CP_ACP, 0, "Wine Joystick", -1, lpddi->tszProductName, MAX_PATH);
+ return TRUE;
+}
+
+static JoystickImpl *alloc_device(REFGUID rguid, LPVOID jvt, IDirectInputImpl *dinput)
+{
+ JoystickImpl* newDevice;
+ int i;
+
+ newDevice = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(JoystickImpl));
+ newDevice->lpVtbl = jvt;
+ newDevice->ref = 1;
+ newDevice->joyfd = -1;
+ newDevice->dinput = dinput;
+ memcpy(&(newDevice->guid),rguid,sizeof(*rguid));
+ for (i=0;i<ABS_MAX;i++) {
+ newDevice->wantmin[i] = -32768;
+ newDevice->wantmax[i] = 32767;
+ /* TODO:
+ * direct input defines a default for the deadzone somewhere; but as long
+ * as in map_axis the code for the dead zone is commented out its no
+ * problem
+ */
+ newDevice->deadz[i] = 0;
+ }
+ fake_current_js_state(newDevice);
+ return newDevice;
+}
+
+static HRESULT joydev_create_deviceA(IDirectInputImpl *dinput, REFGUID rguid, REFIID riid, LPDIRECTINPUTDEVICEA* pdev)
+{
+ int havejoy = 0;
+
+ havejoy = joydev_have();
+
+ if (!havejoy)
+ return DIERR_DEVICENOTREG;
+
+ if ((IsEqualGUID(&GUID_Joystick,rguid)) ||
+ (IsEqualGUID(&DInput_Wine_Joystick_GUID,rguid))) {
+ if ((riid == NULL) ||
+ IsEqualGUID(&IID_IDirectInputDeviceA,riid) ||
+ IsEqualGUID(&IID_IDirectInputDevice2A,riid) ||
+ IsEqualGUID(&IID_IDirectInputDevice7A,riid) ||
+ IsEqualGUID(&IID_IDirectInputDevice8A,riid)) {
+ *pdev = (IDirectInputDeviceA*) alloc_device(rguid, &JoystickAvt, dinput);
+ TRACE("Creating a Joystick device (%p)\n", *pdev);
+ return DI_OK;
+ } else
+ return DIERR_NOINTERFACE;
+ }
+
+ return DIERR_DEVICENOTREG;
+}
+
+
+static HRESULT joydev_create_deviceW(IDirectInputImpl *dinput, REFGUID rguid, REFIID riid, LPDIRECTINPUTDEVICEW* pdev)
+{
+ int havejoy = 0;
+
+ havejoy = joydev_have();
+
+ if (!havejoy)
+ return DIERR_DEVICENOTREG;
+
+ if ((IsEqualGUID(&GUID_Joystick,rguid)) ||
+ (IsEqualGUID(&DInput_Wine_Joystick_GUID,rguid))) {
+ if ((riid == NULL) ||
+ IsEqualGUID(&IID_IDirectInputDeviceW,riid) ||
+ IsEqualGUID(&IID_IDirectInputDevice2W,riid) ||
+ IsEqualGUID(&IID_IDirectInputDevice7W,riid) ||
+ IsEqualGUID(&IID_IDirectInputDevice8W,riid)) {
+ *pdev = (IDirectInputDeviceW*) alloc_device(rguid, &JoystickWvt, dinput);
+ TRACE("Creating a Joystick device (%p)\n", *pdev);
+ return DI_OK;
+ } else
+ return DIERR_NOINTERFACE;
+ }
+
+ return DIERR_DEVICENOTREG;
+}
+
+static dinput_device joydev = {
+ 20,
+ "Wine Linux-input joystick driver",
+ joydev_enum_deviceA,
+ joydev_enum_deviceW,
+ joydev_create_deviceA,
+ joydev_create_deviceW
+};
+
+DECL_GLOBAL_CONSTRUCTOR(joydev_register) { dinput_register_device(&joydev); }
+
+/******************************************************************************
+ * Joystick
+ */
+static ULONG WINAPI JoystickAImpl_Release(LPDIRECTINPUTDEVICE8A iface)
+{
+ JoystickImpl *This = (JoystickImpl *)iface;
+ ULONG ref;
+
+ ref = InterlockedDecrement(&(This->ref));
+ if (ref)
+ return ref;
+
+ /* Free the data queue */
+ if (This->data_queue != NULL)
+ HeapFree(GetProcessHeap(),0,This->data_queue);
+
+ /* Free the DataFormat */
+ HeapFree(GetProcessHeap(), 0, This->df);
+
+ HeapFree(GetProcessHeap(),0,This);
+ return 0;
+}
+
+/******************************************************************************
+ * SetDataFormat : the application can choose the format of the data
+ * the device driver sends back with GetDeviceState.
+ */
+static HRESULT WINAPI JoystickAImpl_SetDataFormat(
+ LPDIRECTINPUTDEVICE8A iface,LPCDIDATAFORMAT df
+)
+{
+ JoystickImpl *This = (JoystickImpl *)iface;
+
+ TRACE("(this=%p,%p)\n",This,df);
+
+ _dump_DIDATAFORMAT(df);
+
+ /* Store the new data format */
+ This->df = HeapAlloc(GetProcessHeap(),0,df->dwSize);
+ memcpy(This->df, df, df->dwSize);
+ This->df->rgodf = HeapAlloc(GetProcessHeap(),0,df->dwNumObjs*df->dwObjSize);
+ memcpy(This->df->rgodf,df->rgodf,df->dwNumObjs*df->dwObjSize);
+
+ return 0;
+}
+
+/******************************************************************************
+ * Acquire : gets exclusive control of the joystick
+ */
+static HRESULT WINAPI JoystickAImpl_Acquire(LPDIRECTINPUTDEVICE8A iface)
+{
+ int i;
+ JoystickImpl *This = (JoystickImpl *)iface;
+ char buf[200];
+
+ TRACE("(this=%p)\n",This);
+ if (This->joyfd!=-1)
+ return 0;
+ for (i=0;i<64;i++) {
+ sprintf(buf,EVDEVPREFIX"%d",i);
+ if (-1==(This->joyfd=open(buf,O_RDONLY))) {
+ if (errno==ENODEV)
+ return DIERR_NOTFOUND;
+ perror(buf);
+ continue;
+ }
+ if ((-1!=ioctl(This->joyfd,EVIOCGBIT(EV_ABS,sizeof(This->absbits)),This->absbits)) &&
+ (-1!=ioctl(This->joyfd,EVIOCGBIT(EV_KEY,sizeof(This->keybits)),This->keybits)) &&
+ (test_bit(This->absbits,ABS_X) && test_bit(This->absbits,ABS_Y) &&
+ (test_bit(This->keybits,BTN_TRIGGER)||
+ test_bit(This->keybits,BTN_A) ||
+ test_bit(This->keybits,BTN_1)
+ )
+ )
+ )
+ break;
+ close(This->joyfd);
+ This->joyfd = -1;
+ }
+ if (This->joyfd==-1)
+ return DIERR_NOTFOUND;
+
+ for (i=0;i<ABS_MAX;i++) {
+ if (test_bit(This->absbits,i)) {
+ if (-1==ioctl(This->joyfd,EVIOCGABS(i),&(This->axes[i])))
+ continue;
+ FIXME("axe %d: cur=%d, min=%d, max=%d, fuzz=%d, flat=%d\n",
+ i,
+ This->axes[i][AXE_ABS],
+ This->axes[i][AXE_ABSMIN],
+ This->axes[i][AXE_ABSMAX],
+ This->axes[i][AXE_ABSFUZZ],
+ This->axes[i][AXE_ABSFLAT]
+ );
+ This->havemin[i] = This->axes[i][AXE_ABSMIN];
+ This->havemax[i] = This->axes[i][AXE_ABSMAX];
+ }
+ }
+ MESSAGE("\n");
+
+ fake_current_js_state(This);
+
+ return 0;
+}
+
+/******************************************************************************
+ * Unacquire : frees the joystick
+ */
+static HRESULT WINAPI JoystickAImpl_Unacquire(LPDIRECTINPUTDEVICE8A iface)
+{
+ JoystickImpl *This = (JoystickImpl *)iface;
+
+ TRACE("(this=%p)\n",This);
+ if (This->joyfd!=-1) {
+ close(This->joyfd);
+ This->joyfd = -1;
+ return DI_OK;
+ }
+ else
+ return DI_NOEFFECT;
+}
+
+/*
+ * This maps the read value (from the input event) to a value in the
+ * 'wanted' range. It also autodetects the possible range of the axe and
+ * adapts values accordingly.
+ */
+static int
+map_axis(JoystickImpl* This, int axis, int val) {
+ int xmin = This->axes[axis][AXE_ABSMIN];
+ int xmax = This->axes[axis][AXE_ABSMAX];
+ int hmax = This->havemax[axis];
+ int hmin = This->havemin[axis];
+ int wmin = This->wantmin[axis];
+ int wmax = This->wantmax[axis];
+ int ret;
+
+ if (val > hmax) This->havemax[axis] = hmax = val;
+ if (val < hmin) This->havemin[axis] = hmin = val;
+
+ if (xmin == xmax) return val;
+
+ /* map the value from the hmin-hmax range into the wmin-wmax range */
+ ret = (val * (wmax-wmin)) / (hmax-hmin) + wmin;
+
+#if 0
+ /* deadzone doesn't work comfortably enough right now. needs more testing*/
+ if ((ret > -deadz/2 ) && (ret < deadz/2)) {
+ FIXME("%d in deadzone, return mid.\n",val);
+ return (wmax-wmin)/2+wmin;
+ }
+#endif
+ return ret;
+}
+
+/*
+ * set the current state of the js device as it would be with the middle
+ * values on the axes
+ */
+static void fake_current_js_state(JoystickImpl *ji)
+{
+ ji->js.lX = map_axis(ji, ABS_X, ji->axes[ABS_X ][AXE_ABS]);
+ ji->js.lY = map_axis(ji, ABS_Y, ji->axes[ABS_Y ][AXE_ABS]);
+ ji->js.lZ = map_axis(ji, ABS_Z, ji->axes[ABS_Z ][AXE_ABS]);
+ ji->js.lRx = map_axis(ji, ABS_RX, ji->axes[ABS_RX][AXE_ABS]);
+ ji->js.lRy = map_axis(ji, ABS_RY, ji->axes[ABS_RY][AXE_ABS]);
+ ji->js.lRz = map_axis(ji, ABS_RZ, ji->axes[ABS_RZ][AXE_ABS]);
+}
+
+static void joy_polldev(JoystickImpl *This) {
+ struct timeval tv;
+ fd_set readfds;
+ struct input_event ie;
+
+ if (This->joyfd==-1)
+ return;
+
+ while (1) {
+ memset(&tv,0,sizeof(tv));
+ FD_ZERO(&readfds);
+ FD_SET(This->joyfd,&readfds);
+
+ if (1>select(This->joyfd+1,&readfds,NULL,NULL,&tv))
+ return;
+
+ /* we have one event, so we can read */
+ if (sizeof(ie)!=read(This->joyfd,&ie,sizeof(ie)))
+ return;
+
+ TRACE("input_event: type %d, code %d, value %d\n",ie.type,ie.code,ie.value);
+ switch (ie.type) {
+ case EV_KEY: /* button */
+ switch (ie.code) {
+ case BTN_TRIGGER: /* normal flight stick */
+ case BTN_A: /* gamepad */
+ case BTN_1: /* generic */
+ This->js.rgbButtons[0] = ie.value?0x80:0x00;
+ GEN_EVENT(DIJOFS_BUTTON(0),ie.value?0x80:0x0,ie.time.tv_usec,(This->dinput->evsequence)++);
+ break;
+ case BTN_THUMB:
+ case BTN_B:
+ case BTN_2:
+ This->js.rgbButtons[1] = ie.value?0x80:0x00;
+ GEN_EVENT(DIJOFS_BUTTON(1),ie.value?0x80:0x0,ie.time.tv_usec,(This->dinput->evsequence)++);
+ break;
+ case BTN_THUMB2:
+ case BTN_C:
+ case BTN_3:
+ This->js.rgbButtons[2] = ie.value?0x80:0x00;
+ GEN_EVENT(DIJOFS_BUTTON(2),ie.value?0x80:0x0,ie.time.tv_usec,(This->dinput->evsequence)++);
+ break;
+ case BTN_TOP:
+ case BTN_X:
+ case BTN_4:
+ This->js.rgbButtons[3] = ie.value?0x80:0x00;
+ GEN_EVENT(DIJOFS_BUTTON(3),ie.value?0x80:0x0,ie.time.tv_usec,(This->dinput->evsequence)++);
+ break;
+ case BTN_TOP2:
+ case BTN_Y:
+ case BTN_5:
+ This->js.rgbButtons[4] = ie.value?0x80:0x00;
+ GEN_EVENT(DIJOFS_BUTTON(4),ie.value?0x80:0x0,ie.time.tv_usec,(This->dinput->evsequence)++);
+ break;
+ case BTN_PINKIE:
+ case BTN_Z:
+ case BTN_6:
+ This->js.rgbButtons[5] = ie.value?0x80:0x00;
+ GEN_EVENT(DIJOFS_BUTTON(5),ie.value?0x80:0x0,ie.time.tv_usec,(This->dinput->evsequence)++);
+ break;
+ case BTN_BASE:
+ case BTN_TL:
+ case BTN_7:
+ This->js.rgbButtons[6] = ie.value?0x80:0x00;
+ GEN_EVENT(DIJOFS_BUTTON(6),ie.value?0x80:0x0,ie.time.tv_usec,(This->dinput->evsequence)++);
+ break;
+ case BTN_BASE2:
+ case BTN_TR:
+ case BTN_8:
+ This->js.rgbButtons[7] = ie.value?0x80:0x00;
+ GEN_EVENT(DIJOFS_BUTTON(7),ie.value?0x80:0x0,ie.time.tv_usec,(This->dinput->evsequence)++);
+ break;
+ case BTN_BASE3:
+ case BTN_TL2:
+ case BTN_9:
+ This->js.rgbButtons[8] = ie.value?0x80:0x00;
+ GEN_EVENT(DIJOFS_BUTTON(8),ie.value?0x80:0x0,ie.time.tv_usec,(This->dinput->evsequence)++);
+ break;
+ case BTN_BASE4:
+ case BTN_TR2:
+ This->js.rgbButtons[9] = ie.value?0x80:0x00;
+ GEN_EVENT(DIJOFS_BUTTON(9),ie.value?0x80:0x0,ie.time.tv_usec,(This->dinput->evsequence)++);
+ break;
+ case BTN_BASE5:
+ case BTN_SELECT:
+ This->js.rgbButtons[10] = ie.value?0x80:0x00;
+ GEN_EVENT(DIJOFS_BUTTON(10),ie.value?0x80:0x0,ie.time.tv_usec,(This->dinput->evsequence)++);
+ break;
+ default:
+ FIXME("unhandled joystick button %x, value %d\n",ie.code,ie.value);
+ break;
+ }
+ break;
+ case EV_ABS:
+ switch (ie.code) {
+ case ABS_X:
+ This->js.lX = map_axis(This,ABS_X,ie.value);
+ GEN_EVENT(DIJOFS_X,This->js.lX,ie.time.tv_usec,(This->dinput->evsequence)++);
+ break;
+ case ABS_Y:
+ This->js.lY = map_axis(This,ABS_Y,ie.value);
+ GEN_EVENT(DIJOFS_Y,This->js.lY,ie.time.tv_usec,(This->dinput->evsequence)++);
+ break;
+ case ABS_Z:
+ This->js.lZ = map_axis(This,ABS_Z,ie.value);
+ GEN_EVENT(DIJOFS_Z,This->js.lZ,ie.time.tv_usec,(This->dinput->evsequence)++);
+ break;
+ case ABS_RX:
+ This->js.lRx = map_axis(This,ABS_RX,ie.value);
+ GEN_EVENT(DIJOFS_RX,This->js.lRx,ie.time.tv_usec,(This->dinput->evsequence)++);
+ break;
+ case ABS_RY:
+ This->js.lRy = map_axis(This,ABS_RY,ie.value);
+ GEN_EVENT(DIJOFS_RY,This->js.lRy,ie.time.tv_usec,(This->dinput->evsequence)++);
+ break;
+ case ABS_RZ:
+ This->js.lRz = map_axis(This,ABS_RZ,ie.value);
+ GEN_EVENT(DIJOFS_RZ,This->js.lRz,ie.time.tv_usec,(This->dinput->evsequence)++);
+ break;
+ default:
+ FIXME("unhandled joystick axe event (code %d, value %d)\n",ie.code,ie.value);
+ break;
+ }
+ break;
+ default:
+ FIXME("joystick cannot handle type %d event (code %d)\n",ie.type,ie.code);
+ break;
+ }
+ }
+}
+
+/******************************************************************************
+ * GetDeviceState : returns the "state" of the joystick.
+ *
+ */
+static HRESULT WINAPI JoystickAImpl_GetDeviceState(
+ LPDIRECTINPUTDEVICE8A iface,DWORD len,LPVOID ptr
+) {
+ JoystickImpl *This = (JoystickImpl *)iface;
+
+ joy_polldev(This);
+
+ TRACE("(this=%p,0x%08lx,%p)\n",This,len,ptr);
+ if ((len != sizeof(DIJOYSTATE)) && (len != sizeof(DIJOYSTATE2))) {
+ FIXME("len %ld is not sizeof(DIJOYSTATE) or DIJOYSTATE2, unsupported format.\n",len);
+ return E_FAIL;
+ }
+ memcpy(ptr,&(This->js),len);
+ This->queue_head = 0;
+ This->queue_tail = 0;
+ return 0;
+}
+
+/******************************************************************************
+ * GetDeviceData : gets buffered input data.
+ */
+static HRESULT WINAPI JoystickAImpl_GetDeviceData(LPDIRECTINPUTDEVICE8A iface,
+ DWORD dodsize,
+ LPDIDEVICEOBJECTDATA dod,
+ LPDWORD entries,
+ DWORD flags
+) {
+ JoystickImpl *This = (JoystickImpl *)iface;
+
+ FIXME("(%p)->(dods=%ld,entries=%ld,fl=0x%08lx),STUB!\n",This,dodsize,*entries,flags);
+
+ joy_polldev(This);
+ if (flags & DIGDD_PEEK)
+ FIXME("DIGDD_PEEK\n");
+
+ if (dod == NULL) {
+ } else {
+ }
+ return 0;
+}
+
+/******************************************************************************
+ * SetProperty : change input device properties
+ */
+static HRESULT WINAPI JoystickAImpl_SetProperty(LPDIRECTINPUTDEVICE8A iface,
+ REFGUID rguid,
+ LPCDIPROPHEADER ph)
+{
+ JoystickImpl *This = (JoystickImpl *)iface;
+
+ FIXME("(this=%p,%s,%p)\n",This,debugstr_guid(rguid),ph);
+ FIXME("ph.dwSize = %ld, ph.dwHeaderSize =%ld, ph.dwObj = %ld, ph.dwHow= %ld\n",ph->dwSize, ph->dwHeaderSize,ph->dwObj,ph->dwHow);
+
+ if (!HIWORD(rguid)) {
+ switch ((DWORD)rguid) {
+ case (DWORD) DIPROP_BUFFERSIZE: {
+ LPCDIPROPDWORD pd = (LPCDIPROPDWORD)ph;
+
+ FIXME("buffersize = %ld\n",pd->dwData);
+ break;
+ }
+ case (DWORD)DIPROP_RANGE: {
+ LPCDIPROPRANGE pr = (LPCDIPROPRANGE)ph;
+
+ FIXME("proprange(%ld,%ld)\n",pr->lMin,pr->lMax);
+ switch (ph->dwObj) {
+ case 0: /* X */
+ case 4: /* Y */
+ case 8: /* Z */
+ case 12: /* Rx */
+ case 16: /* Ry */
+ case 20: /* Rz */
+ This->wantmin[ph->dwObj/4] = pr->lMin;
+ This->wantmax[ph->dwObj/4] = pr->lMax;
+ break;
+ default:
+ FIXME("setting proprange %ld - %ld for dwObj %ld\n",pr->lMin,pr->lMax,ph->dwObj);
+ }
+ break;
+ }
+ case (DWORD)DIPROP_DEADZONE: {
+ LPCDIPROPDWORD pd = (LPCDIPROPDWORD)ph;
+
+ FIXME("setting deadzone(%ld)\n",pd->dwData);
+ This->deadz[ph->dwObj/4] = pd->dwData;
+ break;
+ }
+ default:
+ FIXME("Unknown type %ld (%s)\n",(DWORD)rguid,debugstr_guid(rguid));
+ break;
+ }
+ }
+ fake_current_js_state(This);
+ return 0;
+}
+
+/******************************************************************************
+ * SetEventNotification : specifies event to be sent on state change
+ */
+static HRESULT WINAPI JoystickAImpl_SetEventNotification(
+ LPDIRECTINPUTDEVICE8A iface, HANDLE hnd
+) {
+ JoystickImpl *This = (JoystickImpl *)iface;
+
+ TRACE("(this=%p,0x%08lx)\n",This,(DWORD)hnd);
+ This->hEvent = hnd;
+ return DI_OK;
+}
+
+static HRESULT WINAPI JoystickAImpl_GetCapabilities(
+ LPDIRECTINPUTDEVICE8A iface,
+ LPDIDEVCAPS lpDIDevCaps)
+{
+ JoystickImpl *This = (JoystickImpl *)iface;
+ int xfd = This->joyfd;
+ int i,axes,buttons;
+ int wasacquired = 1;
+
+ TRACE("%p->(%p)\n",iface,lpDIDevCaps);
+ if (xfd==-1) {
+ /* yes, games assume we return something, even if unacquired */
+ JoystickAImpl_Acquire(iface);
+ xfd = This->joyfd;
+ wasacquired = 0;
+ }
+ lpDIDevCaps->dwFlags = DIDC_ATTACHED;
+ lpDIDevCaps->dwDevType = DIDEVTYPE_JOYSTICK;
+
+ axes=0;
+ for (i=0;i<ABS_MAX;i++) if (test_bit(This->absbits,i)) axes++;
+ buttons=0;
+ for (i=0;i<KEY_MAX;i++) if (test_bit(This->keybits,i)) buttons++;
+
+ lpDIDevCaps->dwAxes = axes;
+ lpDIDevCaps->dwButtons = buttons;
+
+ if (!wasacquired)
+ JoystickAImpl_Unacquire(iface);
+
+ return DI_OK;
+}
+
+static HRESULT WINAPI JoystickAImpl_Poll(LPDIRECTINPUTDEVICE8A iface) {
+ JoystickImpl *This = (JoystickImpl *)iface;
+ TRACE("(),stub!\n");
+
+ joy_polldev(This);
+ return DI_OK;
+}
+
+/******************************************************************************
+ * EnumObjects : enumerate the different buttons and axis...
+ */
+static HRESULT WINAPI JoystickAImpl_EnumObjects(
+ LPDIRECTINPUTDEVICE8A iface,
+ LPDIENUMDEVICEOBJECTSCALLBACKA lpCallback,
+ LPVOID lpvRef,
+ DWORD dwFlags)
+{
+ JoystickImpl *This = (JoystickImpl *)iface;
+ DIDEVICEOBJECTINSTANCEA ddoi;
+ int xfd = This->joyfd;
+
+
+ TRACE("(this=%p,%p,%p,%08lx)\n", This, lpCallback, lpvRef, dwFlags);
+ if (TRACE_ON(dinput)) {
+ TRACE(" - flags = ");
+ _dump_EnumObjects_flags(dwFlags);
+ TRACE("\n");
+ }
+
+ if (xfd == -1) return DIERR_NOTACQUIRED;
+
+ /* Only the fields till dwFFMaxForce are relevant */
+ ddoi.dwSize = FIELD_OFFSET(DIDEVICEOBJECTINSTANCEA, dwFFMaxForce);
+
+ /* For the joystick, do as is done in the GetCapabilities function */
+ /* FIXME: needs more items */
+ if ((dwFlags == DIDFT_ALL) ||
+ (dwFlags & DIDFT_AXIS)) {
+ BYTE i;
+
+ for (i = 0; i < ABS_MAX; i++) {
+ if (!test_bit(This->absbits,i)) continue;
+
+ switch (i) {
+ case ABS_X:
+ ddoi.guidType = GUID_XAxis;
+ ddoi.dwOfs = DIJOFS_X;
+ break;
+ case ABS_Y:
+ ddoi.guidType = GUID_YAxis;
+ ddoi.dwOfs = DIJOFS_Y;
+ break;
+ case ABS_Z:
+ ddoi.guidType = GUID_ZAxis;
+ ddoi.dwOfs = DIJOFS_Z;
+ break;
+ case ABS_RX:
+ ddoi.guidType = GUID_RxAxis;
+ ddoi.dwOfs = DIJOFS_RX;
+ break;
+ case ABS_RY:
+ ddoi.guidType = GUID_RyAxis;
+ ddoi.dwOfs = DIJOFS_RY;
+ break;
+ case ABS_RZ:
+ ddoi.guidType = GUID_RzAxis;
+ ddoi.dwOfs = DIJOFS_RZ;
+ break;
+ case ABS_THROTTLE:
+ ddoi.guidType = GUID_Slider;
+ ddoi.dwOfs = DIJOFS_SLIDER(0);
+ break;
+ default:
+ FIXME("unhandled abs axis %d, ignoring!\n",i);
+ }
+ ddoi.dwType = DIDFT_MAKEINSTANCE((1<<i) << WINE_JOYSTICK_AXIS_BASE) | DIDFT_ABSAXIS;
+ sprintf(ddoi.tszName, "%d-Axis", i);
+ _dump_OBJECTINSTANCEA(&ddoi);
+ if (lpCallback(&ddoi, lpvRef) != DIENUM_CONTINUE)
+ return DI_OK;
+ }
+ }
+
+ if ((dwFlags == DIDFT_ALL) ||
+ (dwFlags & DIDFT_BUTTON)) {
+ int i;
+
+ /*The DInput SDK says that GUID_Button is only for mouse buttons but well*/
+
+ ddoi.guidType = GUID_Button;
+
+ for (i = 0; i < KEY_MAX; i++) {
+ if (!test_bit(This->keybits,i)) continue;
+
+ switch (i) {
+ case BTN_TRIGGER:
+ case BTN_A:
+ case BTN_1:
+ ddoi.dwOfs = DIJOFS_BUTTON(0);
+ ddoi.dwType = DIDFT_MAKEINSTANCE((0x0001 << 0) << WINE_JOYSTICK_BUTTON_BASE) | DIDFT_PSHBUTTON;
+ break;
+ case BTN_THUMB:
+ case BTN_B:
+ case BTN_2:
+ ddoi.dwOfs = DIJOFS_BUTTON(1);
+ ddoi.dwType = DIDFT_MAKEINSTANCE((0x0001 << 1) << WINE_JOYSTICK_BUTTON_BASE) | DIDFT_PSHBUTTON;
+ break;
+ case BTN_THUMB2:
+ case BTN_C:
+ case BTN_3:
+ ddoi.dwOfs = DIJOFS_BUTTON(2);
+ ddoi.dwType = DIDFT_MAKEINSTANCE((0x0001 << 2) << WINE_JOYSTICK_BUTTON_BASE) | DIDFT_PSHBUTTON;
+ break;
+ case BTN_TOP:
+ case BTN_X:
+ case BTN_4:
+ ddoi.dwOfs = DIJOFS_BUTTON(3);
+ ddoi.dwType = DIDFT_MAKEINSTANCE((0x0001 << 3) << WINE_JOYSTICK_BUTTON_BASE) | DIDFT_PSHBUTTON;
+ break;
+ case BTN_TOP2:
+ case BTN_Y:
+ case BTN_5:
+ ddoi.dwOfs = DIJOFS_BUTTON(4);
+ ddoi.dwType = DIDFT_MAKEINSTANCE((0x0001 << 4) << WINE_JOYSTICK_BUTTON_BASE) | DIDFT_PSHBUTTON;
+ break;
+ case BTN_PINKIE:
+ case BTN_Z:
+ case BTN_6:
+ ddoi.dwOfs = DIJOFS_BUTTON(5);
+ ddoi.dwType = DIDFT_MAKEINSTANCE((0x0001 << 5) << WINE_JOYSTICK_BUTTON_BASE) | DIDFT_PSHBUTTON;
+ break;
+ case BTN_BASE:
+ case BTN_TL:
+ case BTN_7:
+ ddoi.dwOfs = DIJOFS_BUTTON(6);
+ ddoi.dwType = DIDFT_MAKEINSTANCE((0x0001 << 6) << WINE_JOYSTICK_BUTTON_BASE) | DIDFT_PSHBUTTON;
+ break;
+ case BTN_BASE2:
+ case BTN_TR:
+ case BTN_8:
+ ddoi.dwOfs = DIJOFS_BUTTON(7);
+ ddoi.dwType = DIDFT_MAKEINSTANCE((0x0001 << 7) << WINE_JOYSTICK_BUTTON_BASE) | DIDFT_PSHBUTTON;
+ break;
+ case BTN_BASE3:
+ case BTN_TL2:
+ case BTN_9:
+ ddoi.dwOfs = DIJOFS_BUTTON(8);
+ ddoi.dwType = DIDFT_MAKEINSTANCE((0x0001 << 8) << WINE_JOYSTICK_BUTTON_BASE) | DIDFT_PSHBUTTON;
+ break;
+ case BTN_BASE4:
+ case BTN_TR2:
+ ddoi.dwOfs = DIJOFS_BUTTON(9);
+ ddoi.dwType = DIDFT_MAKEINSTANCE((0x0001 << 9) << WINE_JOYSTICK_BUTTON_BASE) | DIDFT_PSHBUTTON;
+ break;
+ case BTN_BASE5:
+ case BTN_SELECT:
+ ddoi.dwOfs = DIJOFS_BUTTON(10);
+ ddoi.dwType = DIDFT_MAKEINSTANCE((0x0001 << 10) << WINE_JOYSTICK_BUTTON_BASE) | DIDFT_PSHBUTTON;
+ break;
+ }
+ sprintf(ddoi.tszName, "%d-Button", i);
+ _dump_OBJECTINSTANCEA(&ddoi);
+ if (lpCallback(&ddoi, lpvRef) != DIENUM_CONTINUE)
+ return DI_OK;
+ }
+ }
+
+ if (xfd!=This->joyfd)
+ close(xfd);
+
+ return DI_OK;
+}
+
+static HRESULT WINAPI JoystickWImpl_EnumObjects(LPDIRECTINPUTDEVICE8W iface,
+ LPDIENUMDEVICEOBJECTSCALLBACKW lpCallback,
+ LPVOID lpvRef,
+ DWORD dwFlags)
+{
+ JoystickImpl *This = (JoystickImpl *)iface;
+
+ device_enumobjects_AtoWcb_data data;
+
+ data.lpCallBack = lpCallback;
+ data.lpvRef = lpvRef;
+
+ return JoystickAImpl_EnumObjects((LPDIRECTINPUTDEVICE8A) This, (LPDIENUMDEVICEOBJECTSCALLBACKA) DIEnumDevicesCallbackAtoW, (LPVOID) &data, dwFlags);
+}
+
+/******************************************************************************
+ * GetProperty : get input device properties
+ */
+static HRESULT WINAPI JoystickAImpl_GetProperty(LPDIRECTINPUTDEVICE8A iface,
+ REFGUID rguid,
+ LPDIPROPHEADER pdiph)
+{
+ JoystickImpl *This = (JoystickImpl *)iface;
+
+ TRACE("(this=%p,%s,%p): stub!\n",
+ iface, debugstr_guid(rguid), pdiph);
+
+ if (TRACE_ON(dinput))
+ _dump_DIPROPHEADER(pdiph);
+
+ if (!HIWORD(rguid)) {
+ switch ((DWORD)rguid) {
+ case (DWORD) DIPROP_BUFFERSIZE: {
+ LPDIPROPDWORD pd = (LPDIPROPDWORD)pdiph;
+
+ TRACE(" return buffersize = %d\n",This->queue_len);
+ pd->dwData = This->queue_len;
+ break;
+ }
+
+ case (DWORD) DIPROP_RANGE: {
+ /* LPDIPROPRANGE pr = (LPDIPROPRANGE) pdiph; */
+ if ((pdiph->dwHow == DIPH_BYID) &&
+ (pdiph->dwObj & DIDFT_ABSAXIS)) {
+ /* The app is querying the current range of the axis : return the lMin and lMax values */
+ FIXME("unimplemented axis range query.\n");
+ }
+
+ break;
[truncated at 1000 lines; 94 more skipped]
reactos/lib/dinput
diff -N keyboard.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ keyboard.c 29 Nov 2004 00:13:49 -0000 1.1
@@ -0,0 +1,868 @@
+/* DirectInput Keyboard device
+ *
+ * Copyright 1998 Marcus Meissner
+ * Copyright 1998,1999 Lionel Ulmer
+ * Copyright 2000-2001 TransGaming Technologies Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include <stdarg.h>
+#include <string.h>
+#include "windef.h"
+#include "winbase.h"
+#include "winuser.h"
+#include "winerror.h"
+#include "dinput.h"
+
+#include "dinput_private.h"
+#include "device_private.h"
+#include "wine/debug.h"
+#include "wine/unicode.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(dinput);
+
+//fast fix misning from mingw headers
+#ifdef __REACTOS__
+#define LLKHF_EXTENDED (KF_EXTENDED >> 8)
+#define LLKHF_INJECTED 0x00000010
+//#define LLKHF_ALTDOWN (KF_ALTDOWN >> 8)
+#define LLKHF_UP (KF_UP >> 8)
+#endif
+
+static IDirectInputDevice8AVtbl SysKeyboardAvt;
+static IDirectInputDevice8WVtbl SysKeyboardWvt;
+
+typedef struct SysKeyboardImpl SysKeyboardImpl;
+struct SysKeyboardImpl
+{
+ LPVOID lpVtbl;
+ DWORD ref;
+ GUID guid;
+
+ IDirectInputImpl* dinput;
+
+ HANDLE hEvent;
+ /* SysKeyboardAImpl */
+ int acquired;
+ int buffersize; /* set in 'SetProperty' */
+ LPDIDEVICEOBJECTDATA buffer; /* buffer for 'GetDeviceData'.
+ Alloc at 'Acquire', Free at
+ 'Unacquire' */
+ int count; /* number of objects in use in
+ 'buffer' */
+ int start; /* 'buffer' rotates. This is the
+ first in use (if count > 0) */
+ BOOL overflow; /* return DI_BUFFEROVERFLOW in
+ 'GetDeviceData' */
+ CRITICAL_SECTION crit;
+};
+
+SysKeyboardImpl *current; /* Today's acquired device
+FIXME: currently this can be only one.
+Maybe this should be a linked list or st.
+I don't know what the rules are for multiple acquired keyboards,
+but 'DI_LOSTFOCUS' and 'DI_UNACQUIRED' exist for a reason.
+*/
+
+static BYTE DInputKeyState[256]; /* array for 'GetDeviceState' */
+
+static CRITICAL_SECTION keyboard_crit;
+static CRITICAL_SECTION_DEBUG critsect_debug =
+{
+ 0, 0, &keyboard_crit,
+ { &critsect_debug.ProcessLocksList, &critsect_debug.ProcessLocksList },
+ 0, 0, { 0, (DWORD)(__FILE__ ": keyboard_crit") }
+};
+static CRITICAL_SECTION keyboard_crit = { &critsect_debug, -1, 0, 0, 0, 0 };
+
+static DWORD keyboard_users;
+
+#ifndef __REACTOS__
+static HHOOK keyboard_hook;
+#endif
+
+#ifdef __REACTOS__
+void reactos_input_keyboard();
+
+void reactos_input_keyboard()
+{
+ MSG msg;
+ BOOL fDone;
+ int disk_code = -1;
+ BOOL down;
+ BYTE oldDInputKeyState[256];
+ int t;
+
+ memcpy(&oldDInputKeyState,&DInputKeyState,256);
+ GetKeyboardState(DInputKeyState);
+
+ for( t=0;t<255;t++)
+ {
+ if (oldDInputKeyState[t]!=DInputKeyState[t]) disk_code=t;
+ }
+
+
+ if (disk_code!=-1) {
+ if (current->buffer != NULL)
+ {
+ int n;
+ n = (current->start + current->count) % current->buffersize;
+
+ current->buffer[n].dwOfs = (BYTE) disk_code;
+ current->buffer[n].dwData = DInputKeyState[disk_code];
+ current->buffer[n].dwTimeStamp = 10;
+ current->buffer[n].dwSequence = current->dinput->evsequence++;
+
+
+ if (current->count == current->buffersize)
+ {
+ current->start = ++current->start % current->buffersize;
+ current->overflow = TRUE;
+ }
+ else
+ current->count++;
+
+ }
+ }
+
+
+}
+#endif
+#ifndef __REACTOS__
+LRESULT CALLBACK KeyboardCallback( int code, WPARAM wparam, LPARAM lparam )
+{
+ TRACE("(%d,%d,%ld)\n", code, wparam, lparam);
+
+ if (code == HC_ACTION)
+ {
+ BYTE dik_code;
+ BOOL down;
+ DWORD timestamp;
+
+ {
+ KBDLLHOOKSTRUCT *hook = (KBDLLHOOKSTRUCT *)lparam;
+ dik_code = hook->scanCode;
+ if (hook->flags & LLKHF_EXTENDED) dik_code |= 0x80;
+ down = !(hook->flags & LLKHF_UP);
+ timestamp = hook->time;
+ }
+
+ DInputKeyState[dik_code] = (down ? 0x80 : 0);
+ TRACE(" setting %02X to %02X\n", dik_code, DInputKeyState[dik_code]);
+
+ if (current != NULL)
+ {
+ if (current->hEvent)
+ SetEvent(current->hEvent);
+
+ if (current->buffer != NULL)
+ {
+ int n;
+
+ EnterCriticalSection(&(current->crit));
+
+ n = (current->start + current->count) % current->buffersize;
+
+ current->buffer[n].dwOfs = dik_code;
+ current->buffer[n].dwData = down ? 0x80 : 0;
+ current->buffer[n].dwTimeStamp = timestamp;
+ current->buffer[n].dwSequence = current->dinput->evsequence++;
+
+ TRACE("Adding event at offset %d : %ld - %ld - %ld - %ld\n", n,
+ current->buffer[n].dwOfs, current->buffer[n].dwData, current->buffer[n].dwTimeStamp, current->buffer[n].dwSequence);
+
+ if (current->count == current->buffersize)
+ {
+ current->start = ++current->start % current->buffersize;
+ current->overflow = TRUE;
+ }
+ else
+ current->count++;
+
+ LeaveCriticalSection(&(current->crit));
+ }
+ }
+ }
+
+ return CallNextHookEx(keyboard_hook, code, wparam, lparam);
+}
+#endif
+
+static GUID DInput_Wine_Keyboard_GUID = { /* 0ab8648a-7735-11d2-8c73-71df54a96441 */
+ 0x0ab8648a,
+ 0x7735,
+ 0x11d2,
+ {0x8c, 0x73, 0x71, 0xdf, 0x54, 0xa9, 0x64, 0x41}
+};
+
+static void fill_keyboard_dideviceinstanceA(LPDIDEVICEINSTANCEA lpddi, int version) {
+ DWORD dwSize;
+ DIDEVICEINSTANCEA ddi;
+
+ dwSize = lpddi->dwSize;
+
+ TRACE("%ld %p\n", dwSize, lpddi);
+
+ memset(lpddi, 0, dwSize);
+ memset(&ddi, 0, sizeof(ddi));
+
+ ddi.dwSize = dwSize;
+ ddi.guidInstance = GUID_SysKeyboard;/* DInput's GUID */
+ ddi.guidProduct = DInput_Wine_Keyboard_GUID; /* Vendor's GUID */
+ if (version >= 8)
+ ddi.dwDevType = DI8DEVTYPE_KEYBOARD | (DI8DEVTYPEKEYBOARD_UNKNOWN << 8);
+ else
+ ddi.dwDevType = DIDEVTYPE_KEYBOARD | (DIDEVTYPEKEYBOARD_UNKNOWN << 8);
+ strcpy(ddi.tszInstanceName, "Keyboard");
+ strcpy(ddi.tszProductName, "Wine Keyboard");
+
+ memcpy(lpddi, &ddi, (dwSize < sizeof(ddi) ? dwSize : sizeof(ddi)));
+}
+
+static void fill_keyboard_dideviceinstanceW(LPDIDEVICEINSTANCEW lpddi, int version) {
+ DWORD dwSize;
+ DIDEVICEINSTANCEW ddi;
+
+ dwSize = lpddi->dwSize;
+
+ TRACE("%ld %p\n", dwSize, lpddi);
+
+ memset(lpddi, 0, dwSize);
+ memset(&ddi, 0, sizeof(ddi));
+
+ ddi.dwSize = dwSize;
+ ddi.guidInstance = GUID_SysKeyboard;/* DInput's GUID */
+ ddi.guidProduct = DInput_Wine_Keyboard_GUID; /* Vendor's GUID */
+ if (version >= 8)
+ ddi.dwDevType = DI8DEVTYPE_KEYBOARD | (DI8DEVTYPEKEYBOARD_UNKNOWN << 8);
+ else
+ ddi.dwDevType = DIDEVTYPE_KEYBOARD | (DIDEVTYPEKEYBOARD_UNKNOWN << 8);
+ MultiByteToWideChar(CP_ACP, 0, "Keyboard", -1, ddi.tszInstanceName, MAX_PATH);
+ MultiByteToWideChar(CP_ACP, 0, "Wine Keyboard", -1, ddi.tszProductName, MAX_PATH);
+
+ memcpy(lpddi, &ddi, (dwSize < sizeof(ddi) ? dwSize : sizeof(ddi)));
+}
+
+static BOOL keyboarddev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, int version, int id)
+{
+ if (id != 0)
+ return FALSE;
+
+ if ((dwDevType == 0) ||
+ ((dwDevType == DIDEVTYPE_KEYBOARD) && (version < 8)) ||
+ ((dwDevType == DI8DEVTYPE_KEYBOARD) && (version >= 8))) {
+ TRACE("Enumerating the Keyboard device\n");
+
+ fill_keyboard_dideviceinstanceA(lpddi, version);
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static BOOL keyboarddev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, int version, int id)
+{
+ if (id != 0)
+ return FALSE;
+
+ if ((dwDevType == 0) ||
+ ((dwDevType == DIDEVTYPE_KEYBOARD) && (version < 8)) ||
+ ((dwDevType == DI8DEVTYPE_KEYBOARD) && (version >= 8))) {
+ TRACE("Enumerating the Keyboard device\n");
+
+ fill_keyboard_dideviceinstanceW(lpddi, version);
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static SysKeyboardImpl *alloc_device_keyboard(REFGUID rguid, LPVOID kvt, IDirectInputImpl *dinput)
+{
+ SysKeyboardImpl* newDevice;
+ newDevice = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(SysKeyboardImpl));
+ newDevice->lpVtbl = kvt;
+ newDevice->ref = 1;
+ memcpy(&(newDevice->guid),rguid,sizeof(*rguid));
+ newDevice->dinput = dinput;
+
+#ifndef __REACTOS__
+ EnterCriticalSection(&keyboard_crit);
+
+ if (!keyboard_users++)
+ keyboard_hook = SetWindowsHookExW( WH_KEYBOARD_LL, KeyboardCallback, DINPUT_instance, 0 );
+
+ LeaveCriticalSection(&keyboard_crit);
+#endif
+ return newDevice;
+}
+
+
+static HRESULT keyboarddev_create_deviceA(IDirectInputImpl *dinput, REFGUID rguid, REFIID riid, LPDIRECTINPUTDEVICEA* pdev)
+{
+ if ((IsEqualGUID(&GUID_SysKeyboard,rguid)) || /* Generic Keyboard */
+ (IsEqualGUID(&DInput_Wine_Keyboard_GUID,rguid))) { /* Wine Keyboard */
+ if ((riid == NULL) ||
+ IsEqualGUID(&IID_IDirectInputDeviceA,riid) ||
+ IsEqualGUID(&IID_IDirectInputDevice2A,riid) ||
+ IsEqualGUID(&IID_IDirectInputDevice7A,riid) ||
+ IsEqualGUID(&IID_IDirectInputDevice8A,riid)) {
+ *pdev = (IDirectInputDeviceA*) alloc_device_keyboard(rguid, &SysKeyboardAvt, dinput);
+ TRACE("Creating a Keyboard device (%p)\n", *pdev);
+ return DI_OK;
+ } else
+ return DIERR_NOINTERFACE;
+ }
+ return DIERR_DEVICENOTREG;
+}
+
+static HRESULT keyboarddev_create_deviceW(IDirectInputImpl *dinput, REFGUID rguid, REFIID riid, LPDIRECTINPUTDEVICEW* pdev)
+{
+ if ((IsEqualGUID(&GUID_SysKeyboard,rguid)) || /* Generic Keyboard */
+ (IsEqualGUID(&DInput_Wine_Keyboard_GUID,rguid))) { /* Wine Keyboard */
+ if ((riid == NULL) ||
+ IsEqualGUID(&IID_IDirectInputDeviceW,riid) ||
+ IsEqualGUID(&IID_IDirectInputDevice2W,riid) ||
+ IsEqualGUID(&IID_IDirectInputDevice7W,riid) ||
+ IsEqualGUID(&IID_IDirectInputDevice8W,riid)) {
+ *pdev = (IDirectInputDeviceW*) alloc_device_keyboard(rguid, &SysKeyboardWvt, dinput);
+ TRACE("Creating a Keyboard device (%p)\n", *pdev);
+ return DI_OK;
+ } else
+ return DIERR_NOINTERFACE;
+ }
+ return DIERR_DEVICENOTREG;
+}
+
+dinput_device keyboarddev = {
+ 100,
+ "Wine keyboard driver",
+ keyboarddev_enum_deviceA,
+ keyboarddev_enum_deviceW,
+ keyboarddev_create_deviceA,
+ keyboarddev_create_deviceW
+};
+
+void scan_keyboard()
+{
+ dinput_register_device(&keyboarddev);
+}
+
+DECL_GLOBAL_CONSTRUCTOR(keyboarddev_register) { dinput_register_device(&keyboarddev); }
+
+static ULONG WINAPI SysKeyboardAImpl_Release(LPDIRECTINPUTDEVICE8A iface)
+{
+ SysKeyboardImpl *This = (SysKeyboardImpl *)iface;
+ ULONG ref;
+
+ ref = InterlockedDecrement(&(This->ref));
+ if (ref)
+ return ref;
+
+#ifndef __REACTOS__
+ EnterCriticalSection(&keyboard_crit);
+ if (!--keyboard_users) {
+ UnhookWindowsHookEx( keyboard_hook );
+ keyboard_hook = 0;
+ }
+ LeaveCriticalSection(&keyboard_crit);
+#endif
+
+ /* Free the data queue */
+ if (This->buffer != NULL)
+ HeapFree(GetProcessHeap(),0,This->buffer);
+
+ DeleteCriticalSection(&(This->crit));
+
+ HeapFree(GetProcessHeap(),0,This);
+ return DI_OK;
+}
+
+static HRESULT WINAPI SysKeyboardAImpl_SetProperty(
+ LPDIRECTINPUTDEVICE8A iface,REFGUID rguid,LPCDIPROPHEADER ph
+)
+{
+ SysKeyboardImpl *This = (SysKeyboardImpl *)iface;
+
+ TRACE("(this=%p,%s,%p)\n",This,debugstr_guid(rguid),ph);
+ TRACE("(size=%ld,headersize=%ld,obj=%ld,how=%ld\n",
+ ph->dwSize,ph->dwHeaderSize,ph->dwObj,ph->dwHow);
+ if (!HIWORD(rguid)) {
+ switch ((DWORD)rguid) {
+ case (DWORD) DIPROP_BUFFERSIZE: {
+ LPCDIPROPDWORD pd = (LPCDIPROPDWORD)ph;
+
+ TRACE("(buffersize=%ld)\n",pd->dwData);
+
+ if (This->acquired)
+ return DIERR_INVALIDPARAM;
+
+ This->buffersize = pd->dwData;
+
+ break;
+ }
+ default:
+ WARN("Unknown type %ld\n",(DWORD)rguid);
+ break;
+ }
+ }
+ return DI_OK;
+}
+
+
+static HRESULT WINAPI SysKeyboardAImpl_GetDeviceState(
+ LPDIRECTINPUTDEVICE8A iface,DWORD len,LPVOID ptr
+)
+{
+ TRACE("(%p)->(%ld,%p)\n", iface, len, ptr);
+
+#ifdef __REACTOS__
+ reactos_input_keyboard();
+#endif
+
+ /* Note: device does not need to be acquired */
+ if (len != 256)
+ return DIERR_INVALIDPARAM;
+
+ MsgWaitForMultipleObjectsEx(0, NULL, 0, 0, 0);
+
+ if (TRACE_ON(dinput)) {
+ int i;
+ for (i = 0; i < 256; i++) {
+ if (DInputKeyState[i] != 0x00) {
+ TRACE(" - %02X: %02x\n", i, DInputKeyState[i]);
+ }
+ }
+ }
+
+ memcpy(ptr, DInputKeyState, 256);
+ return DI_OK;
+}
+
+static HRESULT WINAPI SysKeyboardAImpl_GetDeviceData(
+ LPDIRECTINPUTDEVICE8A iface,DWORD dodsize,LPDIDEVICEOBJECTDATA dod,
+ LPDWORD entries,DWORD flags
+)
+{
+
+ SysKeyboardImpl *This = (SysKeyboardImpl *)iface;
+ int ret = DI_OK, i = 0;
+#ifdef __REACTOS__
+ reactos_input_keyboard();
+#endif
+
+ TRACE("(this=%p,%ld,%p,%p(%ld)),0x%08lx)\n",
+ This,dodsize,dod,entries,entries?*entries:0,flags);
+
+ if (This->acquired == 0)
+ return DIERR_NOTACQUIRED;
+
+ if (This->buffer == NULL)
+ return DIERR_NOTBUFFERED;
+
+ if (dodsize < sizeof(DIDEVICEOBJECTDATA_DX3))
+ return DIERR_INVALIDPARAM;
+
+ MsgWaitForMultipleObjectsEx(0, NULL, 0, 0, 0);
+
+ EnterCriticalSection(&(This->crit));
+
+ /* Copy item at a time for the case dodsize > sizeof(buffer[n]) */
+ while ((i < *entries || *entries == INFINITE) && i < This->count)
+ {
+ if (dod != NULL)
+ {
+ int n = (This->start + i) % This->buffersize;
+ LPDIDEVICEOBJECTDATA pd
+ = (LPDIDEVICEOBJECTDATA)((BYTE *)dod + dodsize * i);
+ pd->dwOfs = This->buffer[n].dwOfs;
+ pd->dwData = This->buffer[n].dwData;
+ pd->dwTimeStamp = This->buffer[n].dwTimeStamp;
+ pd->dwSequence = This->buffer[n].dwSequence;
+ }
+ i++;
+ }
+
+ *entries = i;
+
+ if (This->overflow)
+ ret = DI_BUFFEROVERFLOW;
+
+ if (!(flags & DIGDD_PEEK))
+ {
+ /* Empty buffer */
+ This->count -= i;
+ This->start = (This->start + i) % This->buffersize;
+ This->overflow = FALSE;
+ }
+
+ LeaveCriticalSection(&(This->crit));
+
+ TRACE("Returning %ld events queued\n", *entries);
+
+ return ret;
+}
+
+static HRESULT WINAPI SysKeyboardAImpl_EnumObjects(
+ LPDIRECTINPUTDEVICE8A iface,
+ LPDIENUMDEVICEOBJECTSCALLBACKA lpCallback,
+ LPVOID lpvRef,
+ DWORD dwFlags)
+{
+ SysKeyboardImpl *This = (SysKeyboardImpl *)iface;
+ DIDEVICEOBJECTINSTANCEA ddoi;
+ int i;
+
+ TRACE("(this=%p,%p,%p,%08lx)\n", This, lpCallback, lpvRef, dwFlags);
+ if (TRACE_ON(dinput)) {
+ TRACE(" - flags = ");
+ _dump_EnumObjects_flags(dwFlags);
+ TRACE("\n");
+ }
+
+ /* Only the fields till dwFFMaxForce are relevant */
+ memset(&ddoi, 0, sizeof(ddoi));
+ ddoi.dwSize = FIELD_OFFSET(DIDEVICEOBJECTINSTANCEA, dwFFMaxForce);
+
+ for (i = 0; i < 256; i++) {
+ /* Report 255 keys :-) */
+ ddoi.guidType = GUID_Key;
+ ddoi.dwOfs = i;
+ ddoi.dwType = DIDFT_MAKEINSTANCE(i) | DIDFT_BUTTON;
+ GetKeyNameTextA(((i & 0x7f) << 16) | ((i & 0x80) << 17), ddoi.tszName, sizeof(ddoi.tszName));
+ _dump_OBJECTINSTANCEA(&ddoi);
+ if (lpCallback(&ddoi, lpvRef) != DIENUM_CONTINUE) return DI_OK;
+ }
+
+ return DI_OK;
+}
+
+static HRESULT WINAPI SysKeyboardWImpl_EnumObjects(LPDIRECTINPUTDEVICE8W iface,
+ LPDIENUMDEVICEOBJECTSCALLBACKW lpCallback,
+ LPVOID lpvRef,
+ DWORD dwFlags)
+{
+ SysKeyboardImpl *This = (SysKeyboardImpl *)iface;
+
+ device_enumobjects_AtoWcb_data data;
+
+ data.lpCallBack = lpCallback;
+ data.lpvRef = lpvRef;
+
+ return SysKeyboardAImpl_EnumObjects((LPDIRECTINPUTDEVICE8A) This, (LPDIENUMDEVICEOBJECTSCALLBACKA) DIEnumDevicesCallbackAtoW, (LPVOID) &data, dwFlags);
+}
+
+static HRESULT WINAPI SysKeyboardAImpl_Unacquire(LPDIRECTINPUTDEVICE8A iface);
+
+static HRESULT WINAPI SysKeyboardAImpl_Acquire(LPDIRECTINPUTDEVICE8A iface)
+{
+ SysKeyboardImpl *This = (SysKeyboardImpl *)iface;
+
+ TRACE("(this=%p)\n",This);
+
+ if (This->acquired)
+ return S_FALSE;
+
+ This->acquired = 1;
+
+ if (current != NULL)
+ {
+ FIXME("Not more than one keyboard can be acquired at the same time.\n");
+ SysKeyboardAImpl_Unacquire(iface);
+ }
+
+ current = This;
+
+ if (This->buffersize > 0)
+ {
+ This->buffer = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
+ This->buffersize * sizeof(*(This->buffer)));
+ This->start = 0;
+ This->count = 0;
+ This->overflow = FALSE;
+ InitializeCriticalSection(&(This->crit));
+ }
+ else
+ This->buffer = NULL;
+
+
+ return DI_OK;
+}
+
+static HRESULT WINAPI SysKeyboardAImpl_Unacquire(LPDIRECTINPUTDEVICE8A iface)
+{
+ SysKeyboardImpl *This = (SysKeyboardImpl *)iface;
+ TRACE("(this=%p)\n",This);
+
+ if (This->acquired == 0)
+ return DI_NOEFFECT;
+
+ if (current == This)
+ current = NULL;
+ else
+ ERR("this != current\n");
+
+ This->acquired = 0;
+
+ if (This->buffersize >= 0)
+ {
+ HeapFree(GetProcessHeap(), 0, This->buffer);
+ This->buffer = NULL;
+ DeleteCriticalSection(&(This->crit));
+ }
+
+ return DI_OK;
+}
+
+static HRESULT WINAPI SysKeyboardAImpl_SetEventNotification(LPDIRECTINPUTDEVICE8A iface,
+ HANDLE hnd) {
+ SysKeyboardImpl *This = (SysKeyboardImpl *)iface;
+
+ TRACE("(this=%p,0x%08lx)\n",This,(DWORD)hnd);
+
+ This->hEvent = hnd;
+ return DI_OK;
+}
+
+/******************************************************************************
+ * GetCapabilities : get the device capablitites
+ */
+static HRESULT WINAPI SysKeyboardAImpl_GetCapabilities(
+ LPDIRECTINPUTDEVICE8A iface,
+ LPDIDEVCAPS lpDIDevCaps)
+{
+ SysKeyboardImpl *This = (SysKeyboardImpl *)iface;
+
+ TRACE("(this=%p,%p)\n",This,lpDIDevCaps);
+
+ if (lpDIDevCaps->dwSize == sizeof(DIDEVCAPS)) {
+ lpDIDevCaps->dwFlags = DIDC_ATTACHED;
+ if (This->dinput->version >= 8)
+ lpDIDevCaps->dwDevType = DI8DEVTYPE_KEYBOARD | (DI8DEVTYPEKEYBOARD_UNKNOWN << 8);
+ else
+ lpDIDevCaps->dwDevType = DIDEVTYPE_KEYBOARD | (DIDEVTYPEKEYBOARD_UNKNOWN << 8);
+ lpDIDevCaps->dwAxes = 0;
+ lpDIDevCaps->dwButtons = 256;
+ lpDIDevCaps->dwPOVs = 0;
+ lpDIDevCaps->dwFFSamplePeriod = 0;
+ lpDIDevCaps->dwFFMinTimeResolution = 0;
+ lpDIDevCaps->dwFirmwareRevision = 100;
+ lpDIDevCaps->dwHardwareRevision = 100;
+ lpDIDevCaps->dwFFDriverVersion = 0;
+ } else if (lpDIDevCaps->dwSize == sizeof(DIDEVCAPS_DX3)) {
+ lpDIDevCaps->dwFlags = DIDC_ATTACHED;
+ lpDIDevCaps->dwDevType = DIDEVTYPE_KEYBOARD | (DIDEVTYPEKEYBOARD_UNKNOWN << 8);
+ lpDIDevCaps->dwAxes = 0;
+ lpDIDevCaps->dwButtons = 256;
+ lpDIDevCaps->dwPOVs = 0;
+ } else {
+ WARN("invalid parameter\n");
+ return DIERR_INVALIDPARAM;
+ }
+
+ return DI_OK;
+}
+
+/******************************************************************************
+ * GetObjectInfo : get information about a device object such as a button
+ * or axis
+ */
+static HRESULT WINAPI
+SysKeyboardAImpl_GetObjectInfo(
+ LPDIRECTINPUTDEVICE8A iface,
+ LPDIDEVICEOBJECTINSTANCEA pdidoi,
+ DWORD dwObj,
+ DWORD dwHow)
+{
+ SysKeyboardImpl *This = (SysKeyboardImpl *)iface;
+ DIDEVICEOBJECTINSTANCEA ddoi;
+ DWORD dwSize = pdidoi->dwSize;
+
+ TRACE("(this=%p,%p,%ld,0x%08lx)\n", This, pdidoi, dwObj, dwHow);
+
+ if (dwHow == DIPH_BYID) {
+ WARN(" querying by id not supported yet...\n");
+ return DI_OK;
+ }
+
+ memset(pdidoi, 0, dwSize);
+ memset(&ddoi, 0, sizeof(ddoi));
+
+ ddoi.dwSize = dwSize;
+ ddoi.guidType = GUID_Key;
+ ddoi.dwOfs = dwObj;
+ ddoi.dwType = DIDFT_MAKEINSTANCE(dwObj) | DIDFT_BUTTON;
+ GetKeyNameTextA(((dwObj & 0x7f) << 16) | ((dwObj & 0x80) << 17), ddoi.tszName, sizeof(ddoi.tszName));
+
+ /* And return our just filled device object instance structure */
+ memcpy(pdidoi, &ddoi, (dwSize < sizeof(ddoi) ? dwSize : sizeof(ddoi)));
+
+ _dump_OBJECTINSTANCEA(pdidoi);
+
+ return DI_OK;
+}
+
+static HRESULT WINAPI SysKeyboardWImpl_GetObjectInfo(LPDIRECTINPUTDEVICE8W iface,
+ LPDIDEVICEOBJECTINSTANCEW pdidoi,
+ DWORD dwObj,
+ DWORD dwHow)
+{
+ SysKeyboardImpl *This = (SysKeyboardImpl *)iface;
+ DIDEVICEOBJECTINSTANCEW ddoi;
+ DWORD dwSize = pdidoi->dwSize;
+
+ TRACE("(this=%p,%p,%ld,0x%08lx)\n", This, pdidoi, dwObj, dwHow);
+
+ if (dwHow == DIPH_BYID) {
+ WARN(" querying by id not supported yet...\n");
+ return DI_OK;
+ }
+
+ memset(pdidoi, 0, dwSize);
+ memset(&ddoi, 0, sizeof(ddoi));
+
+ ddoi.dwSize = dwSize;
+ ddoi.guidType = GUID_Key;
+ ddoi.dwOfs = dwObj;
+ ddoi.dwType = DIDFT_MAKEINSTANCE(dwObj) | DIDFT_BUTTON;
+ GetKeyNameTextW(((dwObj & 0x7f) << 16) | ((dwObj & 0x80) << 17), ddoi.tszName, sizeof(ddoi.tszName));
+
+ /* And return our just filled device object instance structure */
+ memcpy(pdidoi, &ddoi, (dwSize < sizeof(ddoi) ? dwSize : sizeof(ddoi)));
+
+ _dump_OBJECTINSTANCEW(pdidoi);
+
+ return DI_OK;
+}
+
+/******************************************************************************
+ * GetDeviceInfo : get information about a device's identity
+ */
+static HRESULT WINAPI SysKeyboardAImpl_GetDeviceInfo(
+ LPDIRECTINPUTDEVICE8A iface,
+ LPDIDEVICEINSTANCEA pdidi)
+{
+ SysKeyboardImpl *This = (SysKeyboardImpl *)iface;
+ TRACE("(this=%p,%p)\n", This, pdidi);
+
+ if (pdidi->dwSize != sizeof(DIDEVICEINSTANCEA)) {
+ WARN(" dinput3 not supporte yet...\n");
+ return DI_OK;
+ }
+
+ fill_keyboard_dideviceinstanceA(pdidi, This->dinput->version);
+
+ return DI_OK;
+}
+
+static HRESULT WINAPI SysKeyboardWImpl_GetDeviceInfo(LPDIRECTINPUTDEVICE8W iface, LPDIDEVICEINSTANCEW pdidi)
+{
+ SysKeyboardImpl *This = (SysKeyboardImpl *)iface;
+ TRACE("(this=%p,%p)\n", This, pdidi);
+
+ if (pdidi->dwSize != sizeof(DIDEVICEINSTANCEW)) {
+ WARN(" dinput3 not supporte yet...\n");
+ return DI_OK;
+ }
+
+ fill_keyboard_dideviceinstanceW(pdidi, This->dinput->version);
+
+ return DI_OK;
+}
+
+static IDirectInputDevice8AVtbl SysKeyboardAvt =
+{
+ IDirectInputDevice2AImpl_QueryInterface,
+ IDirectInputDevice2AImpl_AddRef,
+ SysKeyboardAImpl_Release,
+ SysKeyboardAImpl_GetCapabilities,
+ SysKeyboardAImpl_EnumObjects,
+ IDirectInputDevice2AImpl_GetProperty,
+ SysKeyboardAImpl_SetProperty,
+ SysKeyboardAImpl_Acquire,
+ SysKeyboardAImpl_Unacquire,
+ SysKeyboardAImpl_GetDeviceState,
+ SysKeyboardAImpl_GetDeviceData,
+ IDirectInputDevice2AImpl_SetDataFormat,
+ SysKeyboardAImpl_SetEventNotification,
+ IDirectInputDevice2AImpl_SetCooperativeLevel,
+ SysKeyboardAImpl_GetObjectInfo,
+ SysKeyboardAImpl_GetDeviceInfo,
+ IDirectInputDevice2AImpl_RunControlPanel,
+ IDirectInputDevice2AImpl_Initialize,
+ IDirectInputDevice2AImpl_CreateEffect,
+ IDirectInputDevice2AImpl_EnumEffects,
+ IDirectInputDevice2AImpl_GetEffectInfo,
+ IDirectInputDevice2AImpl_GetForceFeedbackState,
+ IDirectInputDevice2AImpl_SendForceFeedbackCommand,
+ IDirectInputDevice2AImpl_EnumCreatedEffectObjects,
+ IDirectInputDevice2AImpl_Escape,
+ IDirectInputDevice2AImpl_Poll,
+ IDirectInputDevice2AImpl_SendDeviceData,
+ IDirectInputDevice7AImpl_EnumEffectsInFile,
+ IDirectInputDevice7AImpl_WriteEffectToFile,
+ IDirectInputDevice8AImpl_BuildActionMap,
+ IDirectInputDevice8AImpl_SetActionMap,
+ IDirectInputDevice8AImpl_GetImageInfo
+};
+
+#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
+# define XCAST(fun) (typeof(SysKeyboardWvt.fun))
+#else
+# define XCAST(fun) (void*)
+#endif
+
+static IDirectInputDevice8WVtbl SysKeyboardWvt =
+{
+ IDirectInputDevice2WImpl_QueryInterface,
+ XCAST(AddRef)IDirectInputDevice2AImpl_AddRef,
+ XCAST(Release)SysKeyboardAImpl_Release,
+ XCAST(GetCapabilities)SysKeyboardAImpl_GetCapabilities,
+ SysKeyboardWImpl_EnumObjects,
+ XCAST(GetProperty)IDirectInputDevice2AImpl_GetProperty,
+ XCAST(SetProperty)SysKeyboardAImpl_SetProperty,
+ XCAST(Acquire)SysKeyboardAImpl_Acquire,
+ XCAST(Unacquire)SysKeyboardAImpl_Unacquire,
+ XCAST(GetDeviceState)SysKeyboardAImpl_GetDeviceState,
+ XCAST(GetDeviceData)SysKeyboardAImpl_GetDeviceData,
+ XCAST(SetDataFormat)IDirectInputDevice2AImpl_SetDataFormat,
+ XCAST(SetEventNotification)SysKeyboardAImpl_SetEventNotification,
+ XCAST(SetCooperativeLevel)IDirectInputDevice2AImpl_SetCooperativeLevel,
+ SysKeyboardWImpl_GetObjectInfo,
+ SysKeyboardWImpl_GetDeviceInfo,
+ XCAST(RunControlPanel)IDirectInputDevice2AImpl_RunControlPanel,
+ XCAST(Initialize)IDirectInputDevice2AImpl_Initialize,
+ XCAST(CreateEffect)IDirectInputDevice2AImpl_CreateEffect,
+ IDirectInputDevice2WImpl_EnumEffects,
+ IDirectInputDevice2WImpl_GetEffectInfo,
+ XCAST(GetForceFeedbackState)IDirectInputDevice2AImpl_GetForceFeedbackState,
+ XCAST(SendForceFeedbackCommand)IDirectInputDevice2AImpl_SendForceFeedbackCommand,
+ XCAST(EnumCreatedEffectObjects)IDirectInputDevice2AImpl_EnumCreatedEffectObjects,
+ XCAST(Escape)IDirectInputDevice2AImpl_Escape,
+ XCAST(Poll)IDirectInputDevice2AImpl_Poll,
+ XCAST(SendDeviceData)IDirectInputDevice2AImpl_SendDeviceData,
+ IDirectInputDevice7WImpl_EnumEffectsInFile,
+ IDirectInputDevice7WImpl_WriteEffectToFile,
+ IDirectInputDevice8WImpl_BuildActionMap,
+ IDirectInputDevice8WImpl_SetActionMap,
+ IDirectInputDevice8WImpl_GetImageInfo
+};
+#undef XCAST
reactos/lib/dinput
diff -N mouse.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ mouse.c 29 Nov 2004 00:13:49 -0000 1.1
@@ -0,0 +1,1253 @@
+/* DirectInput Mouse device
+ *
+ * Copyright 1998 Marcus Meissner
+ * Copyright 1998,1999 Lionel Ulmer
+ * Copyright 2000-2001 TransGaming Technologies Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#include <stdarg.h>
+#include <string.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winuser.h"
+#include "winerror.h"
+#include "dinput.h"
+
+#include "dinput_private.h"
+#include "device_private.h"
+#include "wine/debug.h"
+#include "wine/unicode.h"
+
+#define MOUSE_HACK
+
+WINE_DEFAULT_DEBUG_CHANNEL(dinput);
+typedef struct {
+ POINT pt;
+ DWORD mouseData;
+ DWORD flags;
+ DWORD time;
+ ULONG_PTR dwExtraInfo;
+} MSLLHOOKSTRUCT, *PMSLLHOOKSTRUCT;
+
+/* Wine mouse driver object instances */
+#define WINE_MOUSE_X_AXIS_INSTANCE 0
+#define WINE_MOUSE_Y_AXIS_INSTANCE 1
+#define WINE_MOUSE_Z_AXIS_INSTANCE 2
+#define WINE_MOUSE_L_BUTTON_INSTANCE 0
+#define WINE_MOUSE_R_BUTTON_INSTANCE 1
+#define WINE_MOUSE_M_BUTTON_INSTANCE 2
+#define WINE_MOUSE_D_BUTTON_INSTANCE 3
+
+/* ------------------------------- */
+/* Wine mouse internal data format */
+/* ------------------------------- */
+
+/* Constants used to access the offset array */
+#define WINE_MOUSE_X_POSITION 0
+#define WINE_MOUSE_Y_POSITION 1
+#define WINE_MOUSE_Z_POSITION 2
+#define WINE_MOUSE_L_POSITION 3
+#define WINE_MOUSE_R_POSITION 4
+#define WINE_MOUSE_M_POSITION 5
+
+typedef struct {
+ LONG lX;
+ LONG lY;
+ LONG lZ;
+ BYTE rgbButtons[4];
+} Wine_InternalMouseData;
+
+#define WINE_INTERNALMOUSE_NUM_OBJS 6
+
+static const DIOBJECTDATAFORMAT Wine_InternalMouseObjectFormat[WINE_INTERNALMOUSE_NUM_OBJS] = {
+ { &GUID_XAxis, FIELD_OFFSET(Wine_InternalMouseData, lX),
+ DIDFT_MAKEINSTANCE(WINE_MOUSE_X_AXIS_INSTANCE) | DIDFT_RELAXIS, 0 },
+ { &GUID_YAxis, FIELD_OFFSET(Wine_InternalMouseData, lY),
+ DIDFT_MAKEINSTANCE(WINE_MOUSE_Y_AXIS_INSTANCE) | DIDFT_RELAXIS, 0 },
+ { &GUID_ZAxis, FIELD_OFFSET(Wine_InternalMouseData, lZ),
+ DIDFT_MAKEINSTANCE(WINE_MOUSE_Z_AXIS_INSTANCE) | DIDFT_RELAXIS, 0 },
+ { &GUID_Button, (FIELD_OFFSET(Wine_InternalMouseData, rgbButtons)) + 0,
+ DIDFT_MAKEINSTANCE(WINE_MOUSE_L_BUTTON_INSTANCE) | DIDFT_PSHBUTTON, 0 },
+ { &GUID_Button, (FIELD_OFFSET(Wine_InternalMouseData, rgbButtons)) + 1,
+ DIDFT_MAKEINSTANCE(WINE_MOUSE_R_BUTTON_INSTANCE) | DIDFT_PSHBUTTON, 0 },
+ { &GUID_Button, (FIELD_OFFSET(Wine_InternalMouseData, rgbButtons)) + 2,
+ DIDFT_MAKEINSTANCE(WINE_MOUSE_M_BUTTON_INSTANCE) | DIDFT_PSHBUTTON, 0 }
+};
+
+static const DIDATAFORMAT Wine_InternalMouseFormat = {
+ 0, /* dwSize - unused */
+ 0, /* dwObjsize - unused */
+ 0, /* dwFlags - unused */
+ sizeof(Wine_InternalMouseData),
+ WINE_INTERNALMOUSE_NUM_OBJS, /* dwNumObjs */
+ (LPDIOBJECTDATAFORMAT) Wine_InternalMouseObjectFormat
+};
+
+static IDirectInputDevice8AVtbl SysMouseAvt;
+static IDirectInputDevice8WVtbl SysMouseWvt;
+
+typedef struct SysMouseImpl SysMouseImpl;
+
+typedef enum {
+ WARP_DONE, /* Warping has been done */
+ WARP_NEEDED, /* Warping is needed */
+ WARP_STARTED /* Warping has been done, waiting for the warp event */
+} WARP_STATUS;
+
+struct SysMouseImpl
+{
+ LPVOID lpVtbl;
+ DWORD ref;
+ GUID guid;
+
+ IDirectInputImpl *dinput;
+
+ /* The current data format and the conversion between internal
+ and external data formats */
+ DIDATAFORMAT *df;
+ DataFormat *wine_df;
+ int offset_array[WINE_INTERNALMOUSE_NUM_OBJS];
+
+ /* SysMouseAImpl */
+ BYTE absolute;
+ /* Previous position for relative moves */
+ LONG prevX, prevY;
+ /* These are used in case of relative -> absolute transitions */
+ POINT org_coords;
+ HHOOK hook;
+ HWND win;
+ DWORD dwCoopLevel;
+ POINT mapped_center;
+ DWORD win_centerX, win_centerY;
+ LPDIDEVICEOBJECTDATA data_queue;
+ int queue_head, queue_tail, queue_len;
+ BOOL overflow;
+ /* warping: whether we need to move mouse back to middle once we
+ * reach window borders (for e.g. shooters, "surface movement" games) */
+ WARP_STATUS need_warp;
+ int acquired;
+ HANDLE hEvent;
+ CRITICAL_SECTION crit;
+
+ /* This is for mouse reporting. */
+ Wine_InternalMouseData m_state;
+};
+
+/* FIXME: This is ugly and not thread safe :/ */
+static IDirectInputDevice8A* current_lock = NULL;
+
+/* FIXME: This is ugly but needed on Windows */
+static int mouse_set = 0;
+
+static GUID DInput_Wine_Mouse_GUID = { /* 9e573ed8-7734-11d2-8d4a-23903fb6bdf7 */
+ 0x9e573ed8,
+ 0x7734,
+ 0x11d2,
+ {0x8d, 0x4a, 0x23, 0x90, 0x3f, 0xb6, 0xbd, 0xf7}
+};
+
+static void fill_mouse_dideviceinstanceA(LPDIDEVICEINSTANCEA lpddi, int version) {
+ DWORD dwSize;
+ DIDEVICEINSTANCEA ddi;
+
+ dwSize = lpddi->dwSize;
+
+ TRACE("%ld %p\n", dwSize, lpddi);
+
+ memset(lpddi, 0, dwSize);
+ memset(&ddi, 0, sizeof(ddi));
+
+ ddi.dwSize = dwSize;
+ ddi.guidInstance = GUID_SysMouse;/* DInput's GUID */
+ ddi.guidProduct = DInput_Wine_Mouse_GUID; /* Vendor's GUID */
+ if (version >= 8)
+ ddi.dwDevType = DI8DEVTYPE_MOUSE | (DI8DEVTYPEMOUSE_TRADITIONAL << 8);
+ else
+ ddi.dwDevType = DIDEVTYPE_MOUSE | (DIDEVTYPEMOUSE_TRADITIONAL << 8);
+ strcpy(ddi.tszInstanceName, "Mouse");
+ strcpy(ddi.tszProductName, "Wine Mouse");
+
+ memcpy(lpddi, &ddi, (dwSize < sizeof(ddi) ? dwSize : sizeof(ddi)));
+}
+
+static void fill_mouse_dideviceinstanceW(LPDIDEVICEINSTANCEW lpddi, int version) {
+ DWORD dwSize;
+ DIDEVICEINSTANCEW ddi;
+
+ dwSize = lpddi->dwSize;
+
+ TRACE("%ld %p\n", dwSize, lpddi);
+
+ memset(lpddi, 0, dwSize);
+ memset(&ddi, 0, sizeof(ddi));
+
+ ddi.dwSize = dwSize;
+ ddi.guidInstance = GUID_SysMouse;/* DInput's GUID */
+ ddi.guidProduct = DInput_Wine_Mouse_GUID; /* Vendor's GUID */
+ if (version >= 8)
+ ddi.dwDevType = DI8DEVTYPE_MOUSE | (DI8DEVTYPEMOUSE_TRADITIONAL << 8);
+ else
+ ddi.dwDevType = DIDEVTYPE_MOUSE | (DIDEVTYPEMOUSE_TRADITIONAL << 8);
+ MultiByteToWideChar(CP_ACP, 0, "Mouse", -1, ddi.tszInstanceName, MAX_PATH);
+ MultiByteToWideChar(CP_ACP, 0, "Wine Mouse", -1, ddi.tszProductName, MAX_PATH);
+
+ memcpy(lpddi, &ddi, (dwSize < sizeof(ddi) ? dwSize : sizeof(ddi)));
+}
+
+static BOOL mousedev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, int version, int id)
+{
+ if (id != 0)
+ return FALSE;
+
+ if ((dwDevType == 0) ||
+ ((dwDevType == DIDEVTYPE_MOUSE) && (version < 8)) ||
+ ((dwDevType == DI8DEVTYPE_MOUSE) && (version >= 8))) {
+ TRACE("Enumerating the mouse device\n");
+
+ fill_mouse_dideviceinstanceA(lpddi, version);
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static BOOL mousedev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, int version, int id)
+{
+ if (id != 0)
+ return FALSE;
+
+ if ((dwDevType == 0) ||
+ ((dwDevType == DIDEVTYPE_MOUSE) && (version < 8)) ||
+ ((dwDevType == DI8DEVTYPE_MOUSE) && (version >= 8))) {
+ TRACE("Enumerating the mouse device\n");
+
+ fill_mouse_dideviceinstanceW(lpddi, version);
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+static SysMouseImpl *alloc_device_mouse(REFGUID rguid, LPVOID mvt, IDirectInputImpl *dinput)
+{
+ int offset_array[WINE_INTERNALMOUSE_NUM_OBJS] = {
+ FIELD_OFFSET(Wine_InternalMouseData, lX),
+ FIELD_OFFSET(Wine_InternalMouseData, lY),
+ FIELD_OFFSET(Wine_InternalMouseData, lZ),
+ FIELD_OFFSET(Wine_InternalMouseData, rgbButtons) + 0,
+ FIELD_OFFSET(Wine_InternalMouseData, rgbButtons) + 1,
+ FIELD_OFFSET(Wine_InternalMouseData, rgbButtons) + 2
+ };
+ SysMouseImpl* newDevice;
+ newDevice = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(SysMouseImpl));
+ newDevice->ref = 1;
+ newDevice->lpVtbl = mvt;
+#ifndef __REACTOS__
+ InitializeCriticalSection(&(newDevice->crit));
+#endif
+ memcpy(&(newDevice->guid),rguid,sizeof(*rguid));
+
+ /* Per default, Wine uses its internal data format */
+ newDevice->df = (DIDATAFORMAT *) &Wine_InternalMouseFormat;
+ memcpy(newDevice->offset_array, offset_array, WINE_INTERNALMOUSE_NUM_OBJS * sizeof(int));
+ newDevice->wine_df = (DataFormat *) HeapAlloc(GetProcessHeap(), 0, sizeof(DataFormat));
+ newDevice->wine_df->size = 0;
+ newDevice->wine_df->internal_format_size = Wine_InternalMouseFormat.dwDataSize;
+ newDevice->wine_df->dt = NULL;
+ newDevice->dinput = dinput;
+
+ return newDevice;
+}
+
+static HRESULT mousedev_create_deviceA(IDirectInputImpl *dinput, REFGUID rguid, REFIID riid, LPDIRECTINPUTDEVICEA* pdev)
+{
+ if ((IsEqualGUID(&GUID_SysMouse,rguid)) || /* Generic Mouse */
+ (IsEqualGUID(&DInput_Wine_Mouse_GUID,rguid))) { /* Wine Mouse */
+ if ((riid == NULL) ||
+ IsEqualGUID(&IID_IDirectInputDeviceA,riid) ||
+ IsEqualGUID(&IID_IDirectInputDevice2A,riid) ||
+ IsEqualGUID(&IID_IDirectInputDevice7A,riid) ||
+ IsEqualGUID(&IID_IDirectInputDevice8A,riid)) {
+ *pdev = (IDirectInputDeviceA*) alloc_device_mouse(rguid, &SysMouseAvt, dinput);
+ TRACE("Creating a Mouse device (%p)\n", *pdev);
+ return DI_OK;
+ } else
+ return DIERR_NOINTERFACE;
+ }
+
+ return DIERR_DEVICENOTREG;
+}
+
+static HRESULT mousedev_create_deviceW(IDirectInputImpl *dinput, REFGUID rguid, REFIID riid, LPDIRECTINPUTDEVICEW* pdev)
+{
+ if ((IsEqualGUID(&GUID_SysMouse,rguid)) || /* Generic Mouse */
+ (IsEqualGUID(&DInput_Wine_Mouse_GUID,rguid))) { /* Wine Mouse */
+ if ((riid == NULL) ||
+ IsEqualGUID(&IID_IDirectInputDeviceW,riid) ||
+ IsEqualGUID(&IID_IDirectInputDevice2W,riid) ||
+ IsEqualGUID(&IID_IDirectInputDevice7W,riid) ||
+ IsEqualGUID(&IID_IDirectInputDevice8W,riid)) {
+ *pdev = (IDirectInputDeviceW*) alloc_device_mouse(rguid, &SysMouseWvt, dinput);
+ TRACE("Creating a Mouse device (%p)\n", *pdev);
+ return DI_OK;
+ } else
+ return DIERR_NOINTERFACE;
+ }
+
+ return DIERR_DEVICENOTREG;
+}
+
+static dinput_device mousedev = {
+ 100,
+ "Wine mouse driver",
+ mousedev_enum_deviceA,
+ mousedev_enum_deviceW,
+ mousedev_create_deviceA,
+ mousedev_create_deviceW
+};
+
+void scan_mouse()
+{
+ dinput_register_device(&mousedev);
+}
+
+DECL_GLOBAL_CONSTRUCTOR(mousedev_register) { dinput_register_device(&mousedev); }
+
+/******************************************************************************
+ * SysMouseA (DInput Mouse support)
+ */
+
+/******************************************************************************
+ * Release : release the mouse buffer.
+ */
+static ULONG WINAPI SysMouseAImpl_Release(LPDIRECTINPUTDEVICE8A iface)
+{
+ SysMouseImpl *This = (SysMouseImpl *)iface;
+ ULONG ref;
+
+ ref = InterlockedDecrement(&(This->ref));
+ if (ref)
+ return ref;
+
+ /* Free the data queue */
+ if (This->data_queue != NULL)
+ HeapFree(GetProcessHeap(),0,This->data_queue);
+
+#ifndef __REACTOS__
+ if (This->hook) {
+ UnhookWindowsHookEx( This->hook );
+ if (This->dwCoopLevel & DISCL_EXCLUSIVE)
+ ShowCursor(TRUE); /* show cursor */
+ }
+ DeleteCriticalSection(&(This->crit));
+#endif
+
+#ifdef __REACTOS__
+if (This->dwCoopLevel & DISCL_EXCLUSIVE)
+ ShowCursor(TRUE); /* show cursor */
+
+#endif
+ /* Free the DataFormat */
+ if (This->df != &(Wine_InternalMouseFormat)) {
+ HeapFree(GetProcessHeap(), 0, This->df->rgodf);
+ HeapFree(GetProcessHeap(), 0, This->df);
+ }
+
+ HeapFree(GetProcessHeap(),0,This);
+ return 0;
+}
+
+
+/******************************************************************************
+ * SetCooperativeLevel : store the window in which we will do our
+ * grabbing.
+ */
+static HRESULT WINAPI SysMouseAImpl_SetCooperativeLevel(
+ LPDIRECTINPUTDEVICE8A iface,HWND hwnd,DWORD dwflags
+)
+{
+ SysMouseImpl *This = (SysMouseImpl *)iface;
+
+ TRACE("(this=%p,0x%08lx,0x%08lx)\n",This,(DWORD)hwnd,dwflags);
+
+ if (TRACE_ON(dinput)) {
+ TRACE(" cooperative level : ");
+ _dump_cooperativelevel_DI(dwflags);
+ }
+
+ /* Store the window which asks for the mouse */
+ if (!hwnd)
+ hwnd = GetDesktopWindow();
+ This->win = hwnd;
+ This->dwCoopLevel = dwflags;
+
+ return DI_OK;
+}
+
+
+/******************************************************************************
+ * SetDataFormat : the application can choose the format of the data
+ * the device driver sends back with GetDeviceState.
+ *
+ * For the moment, only the "standard" configuration (c_dfDIMouse) is supported
+ * in absolute and relative mode.
+ */
+static HRESULT WINAPI SysMouseAImpl_SetDataFormat(
+ LPDIRECTINPUTDEVICE8A iface,LPCDIDATAFORMAT df
+)
+{
+ SysMouseImpl *This = (SysMouseImpl *)iface;
+
+ TRACE("(this=%p,%p)\n",This,df);
+
+ _dump_DIDATAFORMAT(df);
+
+ /* Tests under windows show that a call to SetDataFormat always sets the mouse
+ in relative mode whatever the dwFlags value (DIDF_ABSAXIS/DIDF_RELAXIS).
+ To switch in absolute mode, SetProperty must be used. */
+ This->absolute = 0;
+
+ /* Store the new data format */
+ This->df = HeapAlloc(GetProcessHeap(),0,df->dwSize);
+ memcpy(This->df, df, df->dwSize);
+ This->df->rgodf = HeapAlloc(GetProcessHeap(),0,df->dwNumObjs*df->dwObjSize);
+ memcpy(This->df->rgodf,df->rgodf,df->dwNumObjs*df->dwObjSize);
+
+ /* Prepare all the data-conversion filters */
+ This->wine_df = create_DataFormat(&(Wine_InternalMouseFormat), df, This->offset_array);
+
+ return DI_OK;
+}
+
+/* low-level mouse hook */
+static LRESULT CALLBACK dinput_mouse_hook( int code, WPARAM wparam, LPARAM lparam )
+{
+ LRESULT ret;
+ MSLLHOOKSTRUCT *hook = (MSLLHOOKSTRUCT *)lparam;
+ SysMouseImpl* This = (SysMouseImpl*) current_lock;
+ DWORD dwCoop;
+ static long last_event = 0;
+ int wdata;
+
+ if (code != HC_ACTION) return CallNextHookEx( This->hook, code, wparam, lparam );
+
+ EnterCriticalSection(&(This->crit));
+ dwCoop = This->dwCoopLevel;
+
+ /* Only allow mouse events every 10 ms.
+ * This is to allow the cursor to start acceleration before
+ * the warps happen. But if it involves a mouse button event we
+ * allow it since we don't want to loose the clicks.
+ */
+ if (((GetCurrentTime() - last_event) < 10)
+ && wparam == WM_MOUSEMOVE)
+ goto end;
+ else last_event = GetCurrentTime();
+
+ /* Mouse moved -> send event if asked */
+ if (This->hEvent)
+ SetEvent(This->hEvent);
+
+ if (wparam == WM_MOUSEMOVE) {
+ if (This->absolute) {
+ if (hook->pt.x != This->prevX)
+ GEN_EVENT(This->offset_array[WINE_MOUSE_X_POSITION], hook->pt.x, hook->time, 0);
+ if (hook->pt.y != This->prevY)
+ GEN_EVENT(This->offset_array[WINE_MOUSE_Y_POSITION], hook->pt.y, hook->time, 0);
+ } else {
+ /* Now, warp handling */
+ if ((This->need_warp == WARP_STARTED) &&
+ (hook->pt.x == This->mapped_center.x) && (hook->pt.y == This->mapped_center.y)) {
+ /* Warp has been done... */
+ This->need_warp = WARP_DONE;
+ goto end;
+ }
+
+ /* Relative mouse input with absolute mouse event : the real fun starts here... */
+ if ((This->need_warp == WARP_NEEDED) ||
+ (This->need_warp == WARP_STARTED)) {
+ if (hook->pt.x != This->prevX)
+ GEN_EVENT(This->offset_array[WINE_MOUSE_X_POSITION], hook->pt.x - This->prevX,
+ hook->time, (This->dinput->evsequence)++);
+ if (hook->pt.y != This->prevY)
+ GEN_EVENT(This->offset_array[WINE_MOUSE_Y_POSITION], hook->pt.y - This->prevY,
+ hook->time, (This->dinput->evsequence)++);
+ } else {
+ /* This is the first time the event handler has been called after a
+ GetDeviceData or GetDeviceState. */
+ if (hook->pt.x != This->mapped_center.x) {
+ GEN_EVENT(This->offset_array[WINE_MOUSE_X_POSITION], hook->pt.x - This->mapped_center.x,
+ hook->time, (This->dinput->evsequence)++);
+ This->need_warp = WARP_NEEDED;
+ }
+
+ if (hook->pt.y != This->mapped_center.y) {
+ GEN_EVENT(This->offset_array[WINE_MOUSE_Y_POSITION], hook->pt.y - This->mapped_center.y,
+ hook->time, (This->dinput->evsequence)++);
+ This->need_warp = WARP_NEEDED;
+ }
+ }
+ }
+
+ This->prevX = hook->pt.x;
+ This->prevY = hook->pt.y;
+
+ if (This->absolute) {
+ This->m_state.lX = hook->pt.x;
+ This->m_state.lY = hook->pt.y;
+ } else {
+ This->m_state.lX = hook->pt.x - This->mapped_center.x;
+ This->m_state.lY = hook->pt.y - This->mapped_center.y;
+ }
+ }
+
+ TRACE(" msg %x pt %ld %ld (W=%d)\n",
+ wparam, hook->pt.x, hook->pt.y, (!This->absolute) && This->need_warp );
+
+ switch(wparam) {
+ case WM_LBUTTONDOWN:
+ GEN_EVENT(This->offset_array[WINE_MOUSE_L_POSITION], 0xFF,
+ hook->time, This->dinput->evsequence++);
+ This->m_state.rgbButtons[0] = 0xFF;
+ break;
+ case WM_LBUTTONUP:
+ GEN_EVENT(This->offset_array[WINE_MOUSE_L_POSITION], 0x00,
+ hook->time, This->dinput->evsequence++);
+ This->m_state.rgbButtons[0] = 0x00;
+ break;
+ case WM_RBUTTONDOWN:
+ GEN_EVENT(This->offset_array[WINE_MOUSE_R_POSITION], 0xFF,
+ hook->time, This->dinput->evsequence++);
+ This->m_state.rgbButtons[1] = 0xFF;
+ break;
+ case WM_RBUTTONUP:
+ GEN_EVENT(This->offset_array[WINE_MOUSE_R_POSITION], 0x00,
+ hook->time, This->dinput->evsequence++);
+ This->m_state.rgbButtons[1] = 0x00;
+ break;
+ case WM_MBUTTONDOWN:
+ GEN_EVENT(This->offset_array[WINE_MOUSE_M_POSITION], 0xFF,
+ hook->time, This->dinput->evsequence++);
+ This->m_state.rgbButtons[2] = 0xFF;
+ break;
+ case WM_MBUTTONUP:
+ GEN_EVENT(This->offset_array[WINE_MOUSE_M_POSITION], 0x00,
+ hook->time, This->dinput->evsequence++);
+ This->m_state.rgbButtons[2] = 0x00;
+ break;
+ case WM_MOUSEWHEEL:
+ wdata = (short)HIWORD(hook->mouseData);
+ GEN_EVENT(This->offset_array[WINE_MOUSE_Z_POSITION], wdata,
+ hook->time, This->dinput->evsequence++);
+ This->m_state.lZ += wdata;
+ break;
+ }
+
+ TRACE("(X: %ld - Y: %ld L: %02x M: %02x R: %02x)\n",
+ This->m_state.lX, This->m_state.lY,
+ This->m_state.rgbButtons[0], This->m_state.rgbButtons[2], This->m_state.rgbButtons[1]);
+
+ end:
+ LeaveCriticalSection(&(This->crit));
+
+ if (dwCoop & DISCL_NONEXCLUSIVE) {
+ /* Pass the events down to previous handlers (e.g. win32 input) */
+ ret = CallNextHookEx( This->hook, code, wparam, lparam );
+ } else {
+ /* Ignore message */
+ ret = 1;
+ }
+ return ret;
+}
+
+
+static void dinput_window_check(SysMouseImpl* This) {
+ RECT rect;
+ DWORD centerX, centerY;
+
+ /* make sure the window hasn't moved */
+ GetWindowRect(This->win, &rect);
+ centerX = (rect.right - rect.left) / 2;
+ centerY = (rect.bottom - rect.top ) / 2;
+ if (This->win_centerX != centerX || This->win_centerY != centerY) {
+ This->win_centerX = centerX;
+ This->win_centerY = centerY;
+ }
+ This->mapped_center.x = This->win_centerX;
+ This->mapped_center.y = This->win_centerY;
+ MapWindowPoints(This->win, HWND_DESKTOP, &This->mapped_center, 1);
+}
+
+
+/******************************************************************************
+ * Acquire : gets exclusive control of the mouse
+ */
+static HRESULT WINAPI SysMouseAImpl_Acquire(LPDIRECTINPUTDEVICE8A iface)
+{
+ SysMouseImpl *This = (SysMouseImpl *)iface;
+ RECT rect;
+
+ TRACE("(this=%p)\n",This);
+
+ if (This->acquired == 0) {
+ POINT point;
+
+ /* Store (in a global variable) the current lock */
+ current_lock = (IDirectInputDevice8A*)This;
+
+ /* Init the mouse state */
+ GetCursorPos( &point );
+ if (This->absolute) {
+ This->m_state.lX = point.x;
+ This->m_state.lY = point.y;
+ This->prevX = point.x;
+ This->prevY = point.y;
+ } else {
+ This->m_state.lX = 0;
+ This->m_state.lY = 0;
+ This->org_coords = point;
+ }
+ This->m_state.lZ = 0;
+ This->m_state.rgbButtons[0] = ((GetKeyState(VK_LBUTTON) & 0x80) ? 0xFF : 0x00);
+ This->m_state.rgbButtons[1] = ((GetKeyState(VK_RBUTTON) & 0x80) ? 0xFF : 0x00);
+ This->m_state.rgbButtons[2] = ((GetKeyState(VK_MBUTTON) & 0x80) ? 0xFF : 0x00);
+
+ /* Install our mouse hook */
+ if (This->dwCoopLevel & DISCL_EXCLUSIVE)
+ ShowCursor(FALSE); /* hide cursor */
+#ifndef __REACTOS__
+ This->hook = SetWindowsHookExA( WH_MOUSE_LL, dinput_mouse_hook, DINPUT_instance, 0 );
+#endif
+ /* Get the window dimension and find the center */
+ GetWindowRect(This->win, &rect);
+ This->win_centerX = (rect.right - rect.left) / 2;
+ This->win_centerY = (rect.bottom - rect.top ) / 2;
+
+ /* Warp the mouse to the center of the window */
+ if (This->absolute == 0) {
+ This->mapped_center.x = This->win_centerX;
+ This->mapped_center.y = This->win_centerY;
+ MapWindowPoints(This->win, HWND_DESKTOP, &This->mapped_center, 1);
+ TRACE("Warping mouse to %ld - %ld\n", This->mapped_center.x, This->mapped_center.y);
+ SetCursorPos( This->mapped_center.x, This->mapped_center.y );
+#ifdef MOUSE_HACK
+ This->need_warp = WARP_DONE;
+#else
+ This->need_warp = WARP_STARTED;
+#endif
+ }
+
+ This->acquired = 1;
+ return DI_OK;
+ }
+ return S_FALSE;
+}
+
+/******************************************************************************
+ * Unacquire : frees the mouse
+ */
+static HRESULT WINAPI SysMouseAImpl_Unacquire(LPDIRECTINPUTDEVICE8A iface)
+{
+ SysMouseImpl *This = (SysMouseImpl *)iface;
+
+ TRACE("(this=%p)\n",This);
+
+ if (This->acquired) {
+ /* Reinstall previous mouse event handler */
+
+#ifndef __REACTOS__
+ if (This->hook) {
+ UnhookWindowsHookEx( This->hook );
+ This->hook = 0;
+
+ if (This->dwCoopLevel & DISCL_EXCLUSIVE)
+ ShowCursor(TRUE); /* show cursor */
+ }
+#endif
+#ifdef __REACTOS__
+ if (This->dwCoopLevel & DISCL_EXCLUSIVE)
+ ShowCursor(TRUE); /* show cursor */
+#endif
+
+ /* No more locks */
+ current_lock = NULL;
+
+ /* Unacquire device */
+ This->acquired = 0;
+
+ /* And put the mouse cursor back where it was at acquire time */
+ if (This->absolute == 0) {
+ TRACE(" warping mouse back to (%ld , %ld)\n", This->org_coords.x, This->org_coords.y);
+ SetCursorPos(This->org_coords.x, This->org_coords.y);
+ }
+ } else {
+ return DI_NOEFFECT;
+ }
+
+ return DI_OK;
+}
+
+// if you call poll then to getdevicestate
+// it did not send back right value in windows
+int poll_mouse=0;
+static HRESULT WINAPI SysMouseAImpl_Poll(LPDIRECTINPUTDEVICE8A iface)
+{
+ int retValue = DI_OK;
+
+SysMouseImpl *This = (SysMouseImpl *)iface;
+ if (poll_mouse==0) {
+ retValue=SysMouseAImpl_Acquire(iface);
+ poll_mouse=1;
+ if (retValue!=DI_OK) retValue=DIERR_NOTACQUIRED;
+ else retValue = DI_OK;
+ }
+
+ return retValue;
+}
+
+
+/******************************************************************************
+ * GetDeviceState : returns the "state" of the mouse.
+ *
+ * For the moment, only the "standard" return structure (DIMOUSESTATE) is
+ * supported.
+ */
+static HRESULT WINAPI SysMouseAImpl_GetDeviceState(
+ LPDIRECTINPUTDEVICE8A iface,DWORD len,LPVOID ptr
+) {
+ SysMouseImpl *This = (SysMouseImpl *)iface;
+ POINT point;
+
+#ifndef __REACTOS__
+ EnterCriticalSection(&(This->crit));
+#endif
+ TRACE("(this=%p,0x%08lx,%p): \n",This,len,ptr);
+
+ /* Copy the current mouse state */
+ fill_DataFormat(ptr, &(This->m_state), This->wine_df);
+
+
+ // this fix windows bugs when
+ // some program calling on mouse poll
+ if (poll_mouse==1) poll_mouse=0;
+ else {
+ if (This->absolute == 0) {
+ This->m_state.lX = 0;
+ This->m_state.lY = 0;
+ This->m_state.lZ = 0;
+ }
+ }
+
+
+ /* Check if we need to do a mouse warping */
+ if (This->need_warp == WARP_NEEDED) {
+ dinput_window_check(This);
+ TRACE("Warping mouse to %ld - %ld\n", This->mapped_center.x, This->mapped_center.y);
+ if (mouse_set==0){
+ SetCursorPos( This->mapped_center.x, This->mapped_center.y );
+ mouse_set++;
+ }
+
+#ifdef MOUSE_HACK
+ This->need_warp = WARP_DONE;
+#else
+ This->need_warp = WARP_STARTED;
+#endif
+ }
+
+#ifndef __REACTOS__
+ LeaveCriticalSection(&(This->crit));
+#endif
+
+ TRACE("(X: %ld - Y: %ld - Z: %ld L: %02x M: %02x R: %02x)\n",
+ This->m_state.lX, This->m_state.lY, This->m_state.lZ,
+ This->m_state.rgbButtons[0], This->m_state.rgbButtons[2], This->m_state.rgbButtons[1]);
+
+ return DI_OK;
+}
+
+/******************************************************************************
+ * GetDeviceState : gets buffered input data.
+ */
+
+static HRESULT WINAPI SysMouseAImpl_GetDeviceData(LPDIRECTINPUTDEVICE8A iface,
+ DWORD dodsize,
+ LPDIDEVICEOBJECTDATA dod,
+ LPDWORD entries,
+ DWORD flags
+) {
+ SysMouseImpl *This = (SysMouseImpl *)iface;
+ DWORD len;
+ int nqtail;
+
+
+ TRACE("(%p)->(dods=%ld,entries=%ld,fl=0x%08lx)\n",This,dodsize,*entries,flags);
+
+
+ // windows does not get any data if
+ // we do not call manual to mouse Acquire
+ // this is only need if some apps calling on getdevice data direcly
+ // in windows GetdeviceData does always update first the data
+ // then return it.
+ SysMouseAImpl_Acquire(iface);
+
+
+ if (This->acquired == 0) {
+ WARN(" application tries to get data from an unacquired device !\n");
+ return DIERR_NOTACQUIRED;
+ }
+
+
+#ifndef __REACTOS__
+ EnterCriticalSection(&(This->crit));
+#endif
+
+ // FIXME mouse are bit choppy here.
+
+ len = ((This->queue_head < This->queue_tail) ? This->queue_len : 0)
+ + (This->queue_head - This->queue_tail);
+ if (len > *entries) len = *entries;
+
+ if (dod == NULL) {
+ if (len)
+ TRACE("Application discarding %ld event(s).\n", len);
+
+ *entries = len;
+ nqtail = This->queue_tail + len;
+ while (nqtail >= This->queue_len) nqtail -= This->queue_len;
+ } else {
+ if (dodsize < sizeof(DIDEVICEOBJECTDATA_DX3)) {
+ ERR("Wrong structure size !\n");
+#ifndef __REACTOS__
+ LeaveCriticalSection(&(This->crit));
+#endif
+ return DIERR_INVALIDPARAM;
+ }
+
+ if (len)
+ TRACE("Application retrieving %ld event(s).\n", len);
+
+ *entries = 0;
+ nqtail = This->queue_tail;
+ while (len) {
+ DWORD span = ((This->queue_head < nqtail) ? This->queue_len : This->queue_head) - nqtail;
+ if (span > len)
+ span = len;
+
+ /* Copy the buffered data into the application queue */
+ memcpy(dod + *entries, This->data_queue + nqtail, span * dodsize);
+
+ /* Advance position */
+ nqtail += span;
+ if (nqtail >= This->queue_len) nqtail -= This->queue_len;
+ *entries += span;
+ len -= span;
+ }
+ }
+ if (!(flags & DIGDD_PEEK))
+ This->queue_tail = nqtail;
+#ifndef __REACTOS__
+ LeaveCriticalSection(&(This->crit));
+#endif
+ /* Check if we need to do a mouse warping */
+
+
+ if (This->need_warp == WARP_NEEDED) {
+ dinput_window_check(This);
+ TRACE("Warping mouse to %ld - %ld\n", This->mapped_center.x, This->mapped_center.y);
+ if (mouse_set==0){
+ SetCursorPos( This->mapped_center.x, This->mapped_center.y );
+ mouse_set++;
+ }
+
+#ifdef MOUSE_HACK
+ This->need_warp = WARP_DONE;
+#else
+ This->need_warp = WARP_STARTED;
+#endif
+ }
+ return DI_OK;
+}
+
+/******************************************************************************
+ * SetProperty : change input device properties
+ */
+static HRESULT WINAPI SysMouseAImpl_SetProperty(LPDIRECTINPUTDEVICE8A iface,
+ REFGUID rguid,
+ LPCDIPROPHEADER ph)
+{
+ SysMouseImpl *This = (SysMouseImpl *)iface;
+
+ TRACE("(this=%p,%s,%p)\n",This,debugstr_guid(rguid),ph);
+
+ if (!HIWORD(rguid)) {
+ switch ((DWORD)rguid) {
+ case (DWORD) DIPROP_BUFFERSIZE: {
+ LPCDIPROPDWORD pd = (LPCDIPROPDWORD)ph;
+
+ TRACE("buffersize = %ld\n",pd->dwData);
+
+ This->data_queue = (LPDIDEVICEOBJECTDATA)HeapAlloc(GetProcessHeap(),0,
+ pd->dwData * sizeof(DIDEVICEOBJECTDATA));
+ This->queue_head = 0;
+ This->queue_tail = 0;
+ This->queue_len = pd->dwData;
+ break;
+ }
+ case (DWORD) DIPROP_AXISMODE: {
+ LPCDIPROPDWORD pd = (LPCDIPROPDWORD)ph;
+ This->absolute = !(pd->dwData);
+ TRACE("Using %s coordinates mode now\n", This->absolute ? "absolute" : "relative");
+ break;
+ }
+ default:
+ FIXME("Unknown type %ld (%s)\n",(DWORD)rguid,debugstr_guid(rguid));
+ break;
+ }
+ }
+
+ return DI_OK;
+}
+
+/******************************************************************************
+ * GetProperty : get input device properties
+ */
+static HRESULT WINAPI SysMouseAImpl_GetProperty(LPDIRECTINPUTDEVICE8A iface,
+ REFGUID rguid,
+ LPDIPROPHEADER pdiph)
+{
+ SysMouseImpl *This = (SysMouseImpl *)iface;
+
+ TRACE("(this=%p,%s,%p): stub!\n",
+ iface, debugstr_guid(rguid), pdiph);
+
+ if (TRACE_ON(dinput))
+ _dump_DIPROPHEADER(pdiph);
+
+ if (!HIWORD(rguid)) {
+ switch ((DWORD)rguid) {
+ case (DWORD) DIPROP_BUFFERSIZE: {
+ LPDIPROPDWORD pd = (LPDIPROPDWORD)pdiph;
+
+ TRACE(" return buffersize = %d\n",This->queue_len);
+ pd->dwData = This->queue_len;
+ break;
+ }
+
+ case (DWORD) DIPROP_GRANULARITY: {
+ LPDIPROPDWORD pr = (LPDIPROPDWORD) pdiph;
+
+ /* We'll just assume that the app asks about the Z axis */
+ pr->dwData = WHEEL_DELTA;
+
+ break;
+ }
+
+ case (DWORD) DIPROP_RANGE: {
+ LPDIPROPRANGE pr = (LPDIPROPRANGE) pdiph;
+
+ if ((pdiph->dwHow == DIPH_BYID) &&
+ ((pdiph->dwObj == (DIDFT_MAKEINSTANCE(WINE_MOUSE_X_AXIS_INSTANCE) | DIDFT_RELAXIS)) ||
+ (pdiph->dwObj == (DIDFT_MAKEINSTANCE(WINE_MOUSE_Y_AXIS_INSTANCE) | DIDFT_RELAXIS)))) {
+ /* Querying the range of either the X or the Y axis. As I do
+ not know the range, do as if the range were
+ unrestricted...*/
+ pr->lMin = DIPROPRANGE_NOMIN;
+ pr->lMax = DIPROPRANGE_NOMAX;
+ }
+
+ break;
+ }
+
+ default:
+ FIXME("Unknown type %ld (%s)\n",(DWORD)rguid,debugstr_guid(rguid));
+ break;
+ }
+ }
+
+ return DI_OK;
+}
+
+
+
+/******************************************************************************
+ * SetEventNotification : specifies event to be sent on state change
+ */
[truncated at 1000 lines; 257 more skipped]
reactos/lib/dinput
diff -N regsvr.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ regsvr.c 29 Nov 2004 00:13:49 -0000 1.1
@@ -0,0 +1,558 @@
+/*
+ * self-registerable dll functions for dinput.dll
+ *
+ * Copyright (C) 2003 John K. Hohm
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include <stdarg.h>
+#include <string.h>
+
+#include "windef.h"
+#include "winbase.h"
+#include "wingdi.h"
+#include "winuser.h"
+#include "winreg.h"
+#include "winerror.h"
+
+#include "dinput.h"
+
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(dinput);
+
+/*
+ * Near the bottom of this file are the exported DllRegisterServer and
+ * DllUnregisterServer, which make all this worthwhile.
+ */
+
+/***********************************************************************
+ * interface for self-registering
+ */
+struct regsvr_interface
+{
+ IID const *iid; /* NULL for end of list */
+ LPCSTR name; /* can be NULL to omit */
+ IID const *base_iid; /* can be NULL to omit */
+ int num_methods; /* can be <0 to omit */
+ CLSID const *ps_clsid; /* can be NULL to omit */
+ CLSID const *ps_clsid32; /* can be NULL to omit */
+};
+
+static HRESULT register_interfaces(struct regsvr_interface const *list);
+static HRESULT unregister_interfaces(struct regsvr_interface const *list);
+
+struct regsvr_coclass
+{
+ CLSID const *clsid; /* NULL for end of list */
+ LPCSTR name; /* can be NULL to omit */
+ LPCSTR ips; /* can be NULL to omit */
+ LPCSTR ips32; /* can be NULL to omit */
+ LPCSTR ips32_tmodel; /* can be NULL to omit */
+ LPCSTR progid; /* can be NULL to omit */
+ LPCSTR viprogid; /* can be NULL to omit */
+ LPCSTR progid_extra; /* can be NULL to omit */
+};
+
+static HRESULT register_coclasses(struct regsvr_coclass const *list);
+static HRESULT unregister_coclasses(struct regsvr_coclass const *list);
+
+/***********************************************************************
+ * static string constants
+ */
+static WCHAR const interface_keyname[10] = {
+ 'I', 'n', 't', 'e', 'r', 'f', 'a', 'c', 'e', 0 };
+static WCHAR const base_ifa_keyname[14] = {
+ 'B', 'a', 's', 'e', 'I', 'n', 't', 'e', 'r', 'f', 'a', 'c',
+ 'e', 0 };
+static WCHAR const num_methods_keyname[11] = {
+ 'N', 'u', 'm', 'M', 'e', 't', 'h', 'o', 'd', 's', 0 };
+static WCHAR const ps_clsid_keyname[15] = {
+ 'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's',
+ 'i', 'd', 0 };
+static WCHAR const ps_clsid32_keyname[17] = {
+ 'P', 'r', 'o', 'x', 'y', 'S', 't', 'u', 'b', 'C', 'l', 's',
+ 'i', 'd', '3', '2', 0 };
+static WCHAR const clsid_keyname[6] = {
+ 'C', 'L', 'S', 'I', 'D', 0 };
+static WCHAR const curver_keyname[7] = {
+ 'C', 'u', 'r', 'V', 'e', 'r', 0 };
+static WCHAR const ips_keyname[13] = {
+ 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
+ 0 };
+static WCHAR const ips32_keyname[15] = {
+ 'I', 'n', 'P', 'r', 'o', 'c', 'S', 'e', 'r', 'v', 'e', 'r',
+ '3', '2', 0 };
+static WCHAR const progid_keyname[7] = {
+ 'P', 'r', 'o', 'g', 'I', 'D', 0 };
+static WCHAR const viprogid_keyname[25] = {
+ 'V', 'e', 'r', 's', 'i', 'o', 'n', 'I', 'n', 'd', 'e', 'p',
+ 'e', 'n', 'd', 'e', 'n', 't', 'P', 'r', 'o', 'g', 'I', 'D',
+ 0 };
+static char const tmodel_valuename[] = "ThreadingModel";
+
+/***********************************************************************
+ * static helper functions
+ */
+static LONG register_key_guid(HKEY base, WCHAR const *name, GUID const *guid);
+static LONG register_key_defvalueW(HKEY base, WCHAR const *name,
+ WCHAR const *value);
+static LONG register_key_defvalueA(HKEY base, WCHAR const *name,
+ char const *value);
+static LONG register_progid(WCHAR const *clsid,
+ char const *progid, char const *curver_progid,
+ char const *name, char const *extra);
+static LONG recursive_delete_key(HKEY key);
+static LONG recursive_delete_keyA(HKEY base, char const *name);
+static LONG recursive_delete_keyW(HKEY base, WCHAR const *name);
+
+/***********************************************************************
+ * register_interfaces
+ */
+static HRESULT register_interfaces(struct regsvr_interface const *list)
+{
+ LONG res = ERROR_SUCCESS;
+ HKEY interface_key;
+
+ res = RegCreateKeyExW(HKEY_CLASSES_ROOT, interface_keyname, 0, NULL, 0,
+ KEY_READ | KEY_WRITE, NULL, &interface_key, NULL);
+ if (res != ERROR_SUCCESS) goto error_return;
+
+ for (; res == ERROR_SUCCESS && list->iid; ++list) {
+ WCHAR buf[39];
+ HKEY iid_key;
+
+ StringFromGUID2(list->iid, buf, 39);
+ res = RegCreateKeyExW(interface_key, buf, 0, NULL, 0,
+ KEY_READ | KEY_WRITE, NULL, &iid_key, NULL);
+ if (res != ERROR_SUCCESS) goto error_close_interface_key;
+
+ if (list->name) {
+ res = RegSetValueExA(iid_key, NULL, 0, REG_SZ,
+ (CONST BYTE*)(list->name),
+ strlen(list->name) + 1);
+ if (res != ERROR_SUCCESS) goto error_close_iid_key;
+ }
+
+ if (list->base_iid) {
+ register_key_guid(iid_key, base_ifa_keyname, list->base_iid);
+ if (res != ERROR_SUCCESS) goto error_close_iid_key;
+ }
+
+ if (0 <= list->num_methods) {
+ static WCHAR const fmt[3] = { '%', 'd', 0 };
+ HKEY key;
+
+ res = RegCreateKeyExW(iid_key, num_methods_keyname, 0, NULL, 0,
+ KEY_READ | KEY_WRITE, NULL, &key, NULL);
+ if (res != ERROR_SUCCESS) goto error_close_iid_key;
+
+ wsprintfW(buf, fmt, list->num_methods);
+ res = RegSetValueExW(key, NULL, 0, REG_SZ,
+ (CONST BYTE*)buf,
+ (lstrlenW(buf) + 1) * sizeof(WCHAR));
+ RegCloseKey(key);
+
+ if (res != ERROR_SUCCESS) goto error_close_iid_key;
+ }
+
+ if (list->ps_clsid) {
+ register_key_guid(iid_key, ps_clsid_keyname, list->ps_clsid);
+ if (res != ERROR_SUCCESS) goto error_close_iid_key;
+ }
+
+ if (list->ps_clsid32) {
+ register_key_guid(iid_key, ps_clsid32_keyname, list->ps_clsid32);
+ if (res != ERROR_SUCCESS) goto error_close_iid_key;
+ }
+
+ error_close_iid_key:
+ RegCloseKey(iid_key);
+ }
+
+error_close_interface_key:
+ RegCloseKey(interface_key);
+error_return:
+ return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
+}
+
+/***********************************************************************
+ * unregister_interfaces
+ */
+static HRESULT unregister_interfaces(struct regsvr_interface const *list)
+{
+ LONG res = ERROR_SUCCESS;
+ HKEY interface_key;
+
+ res = RegOpenKeyExW(HKEY_CLASSES_ROOT, interface_keyname, 0,
+ KEY_READ | KEY_WRITE, &interface_key);
+ if (res == ERROR_FILE_NOT_FOUND) return S_OK;
+ if (res != ERROR_SUCCESS) goto error_return;
+
+ for (; res == ERROR_SUCCESS && list->iid; ++list) {
+ WCHAR buf[39];
+
+ StringFromGUID2(list->iid, buf, 39);
+ res = recursive_delete_keyW(interface_key, buf);
+ }
+
+ RegCloseKey(interface_key);
+error_return:
+ return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
+}
+
+/***********************************************************************
+ * register_coclasses
+ */
+static HRESULT register_coclasses(struct regsvr_coclass const *list)
+{
+ LONG res = ERROR_SUCCESS;
+ HKEY coclass_key;
+
+ res = RegCreateKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0, NULL, 0,
+ KEY_READ | KEY_WRITE, NULL, &coclass_key, NULL);
+ if (res != ERROR_SUCCESS) goto error_return;
+
+ for (; res == ERROR_SUCCESS && list->clsid; ++list) {
+ WCHAR buf[39];
+ HKEY clsid_key;
+
+ StringFromGUID2(list->clsid, buf, 39);
+ res = RegCreateKeyExW(coclass_key, buf, 0, NULL, 0,
+ KEY_READ | KEY_WRITE, NULL, &clsid_key, NULL);
+ if (res != ERROR_SUCCESS) goto error_close_coclass_key;
+
+ if (list->name) {
+ res = RegSetValueExA(clsid_key, NULL, 0, REG_SZ,
+ (CONST BYTE*)(list->name),
+ strlen(list->name) + 1);
+ if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+ }
+
+ if (list->ips) {
+ res = register_key_defvalueA(clsid_key, ips_keyname, list->ips);
+ if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+ }
+
+ if (list->ips32) {
+ HKEY ips32_key;
+
+ res = RegCreateKeyExW(clsid_key, ips32_keyname, 0, NULL, 0,
+ KEY_READ | KEY_WRITE, NULL,
+ &ips32_key, NULL);
+ if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+
+ res = RegSetValueExA(ips32_key, NULL, 0, REG_SZ,
+ (CONST BYTE*)list->ips32,
+ lstrlenA(list->ips32) + 1);
+ if (res == ERROR_SUCCESS && list->ips32_tmodel)
+ res = RegSetValueExA(ips32_key, tmodel_valuename, 0, REG_SZ,
+ (CONST BYTE*)list->ips32_tmodel,
+ strlen(list->ips32_tmodel) + 1);
+ RegCloseKey(ips32_key);
+ if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+ }
+
+ if (list->progid) {
+ res = register_key_defvalueA(clsid_key, progid_keyname,
+ list->progid);
+ if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+
+ res = register_progid(buf, list->progid, NULL,
+ list->name, list->progid_extra);
+ if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+ }
+
+ if (list->viprogid) {
+ res = register_key_defvalueA(clsid_key, viprogid_keyname,
+ list->viprogid);
+ if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+
+ res = register_progid(buf, list->viprogid, list->progid,
+ list->name, list->progid_extra);
+ if (res != ERROR_SUCCESS) goto error_close_clsid_key;
+ }
+
+ error_close_clsid_key:
+ RegCloseKey(clsid_key);
+ }
+
+error_close_coclass_key:
+ RegCloseKey(coclass_key);
+error_return:
+ return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
+}
+
+/***********************************************************************
+ * unregister_coclasses
+ */
+static HRESULT unregister_coclasses(struct regsvr_coclass const *list)
+{
+ LONG res = ERROR_SUCCESS;
+ HKEY coclass_key;
+
+ res = RegOpenKeyExW(HKEY_CLASSES_ROOT, clsid_keyname, 0,
+ KEY_READ | KEY_WRITE, &coclass_key);
+ if (res == ERROR_FILE_NOT_FOUND) return S_OK;
+ if (res != ERROR_SUCCESS) goto error_return;
+
+ for (; res == ERROR_SUCCESS && list->clsid; ++list) {
+ WCHAR buf[39];
+
+ StringFromGUID2(list->clsid, buf, 39);
+ res = recursive_delete_keyW(coclass_key, buf);
+ if (res != ERROR_SUCCESS) goto error_close_coclass_key;
+
+ if (list->progid) {
+ res = recursive_delete_keyA(HKEY_CLASSES_ROOT, list->progid);
+ if (res != ERROR_SUCCESS) goto error_close_coclass_key;
+ }
+
+ if (list->viprogid) {
+ res = recursive_delete_keyA(HKEY_CLASSES_ROOT, list->viprogid);
+ if (res != ERROR_SUCCESS) goto error_close_coclass_key;
+ }
+ }
+
+error_close_coclass_key:
+ RegCloseKey(coclass_key);
+error_return:
+ return res != ERROR_SUCCESS ? HRESULT_FROM_WIN32(res) : S_OK;
+}
+
+/***********************************************************************
+ * regsvr_key_guid
+ */
+static LONG register_key_guid(HKEY base, WCHAR const *name, GUID const *guid)
+{
+ WCHAR buf[39];
+
+ StringFromGUID2(guid, buf, 39);
+ return register_key_defvalueW(base, name, buf);
+}
+
+/***********************************************************************
+ * regsvr_key_defvalueW
+ */
+static LONG register_key_defvalueW(
+ HKEY base,
+ WCHAR const *name,
+ WCHAR const *value)
+{
+ LONG res;
+ HKEY key;
+
+ res = RegCreateKeyExW(base, name, 0, NULL, 0,
+ KEY_READ | KEY_WRITE, NULL, &key, NULL);
+ if (res != ERROR_SUCCESS) return res;
+ res = RegSetValueExW(key, NULL, 0, REG_SZ, (CONST BYTE*)value,
+ (lstrlenW(value) + 1) * sizeof(WCHAR));
+ RegCloseKey(key);
+ return res;
+}
+
+/***********************************************************************
+ * regsvr_key_defvalueA
+ */
+static LONG register_key_defvalueA(
+ HKEY base,
+ WCHAR const *name,
+ char const *value)
+{
+ LONG res;
+ HKEY key;
+
+ res = RegCreateKeyExW(base, name, 0, NULL, 0,
+ KEY_READ | KEY_WRITE, NULL, &key, NULL);
+ if (res != ERROR_SUCCESS) return res;
+ res = RegSetValueExA(key, NULL, 0, REG_SZ, (CONST BYTE*)value,
+ lstrlenA(value) + 1);
+ RegCloseKey(key);
+ return res;
+}
+
+/***********************************************************************
+ * regsvr_progid
+ */
+static LONG register_progid(
+ WCHAR const *clsid,
+ char const *progid,
+ char const *curver_progid,
+ char const *name,
+ char const *extra)
+{
+ LONG res;
+ HKEY progid_key;
+
+ res = RegCreateKeyExA(HKEY_CLASSES_ROOT, progid, 0,
+ NULL, 0, KEY_READ | KEY_WRITE, NULL,
+ &progid_key, NULL);
+ if (res != ERROR_SUCCESS) return res;
+
+ if (name) {
+ res = RegSetValueExA(progid_key, NULL, 0, REG_SZ,
+ (CONST BYTE*)name, strlen(name) + 1);
+ if (res != ERROR_SUCCESS) goto error_close_progid_key;
+ }
+
+ if (clsid) {
+ res = register_key_defvalueW(progid_key, clsid_keyname, clsid);
+ if (res != ERROR_SUCCESS) goto error_close_progid_key;
+ }
+
+ if (curver_progid) {
+ res = register_key_defvalueA(progid_key, curver_keyname,
+ curver_progid);
+ if (res != ERROR_SUCCESS) goto error_close_progid_key;
+ }
+
+ if (extra) {
+ HKEY extra_key;
+
+ res = RegCreateKeyExA(progid_key, extra, 0,
+ NULL, 0, KEY_READ | KEY_WRITE, NULL,
+ &extra_key, NULL);
+ if (res == ERROR_SUCCESS)
+ RegCloseKey(extra_key);
+ }
+
+error_close_progid_key:
+ RegCloseKey(progid_key);
+ return res;
+}
+
+/***********************************************************************
+ * recursive_delete_key
+ */
+static LONG recursive_delete_key(HKEY key)
+{
+ LONG res;
+ WCHAR subkey_name[MAX_PATH];
+ DWORD cName;
+ HKEY subkey;
+
+ for (;;) {
+ cName = sizeof(subkey_name) / sizeof(WCHAR);
+ res = RegEnumKeyExW(key, 0, subkey_name, &cName,
+ NULL, NULL, NULL, NULL);
+ if (res != ERROR_SUCCESS && res != ERROR_MORE_DATA) {
+ res = ERROR_SUCCESS; /* presumably we're done enumerating */
+ break;
+ }
+ res = RegOpenKeyExW(key, subkey_name, 0,
+ KEY_READ | KEY_WRITE, &subkey);
+ if (res == ERROR_FILE_NOT_FOUND) continue;
+ if (res != ERROR_SUCCESS) break;
+
+ res = recursive_delete_key(subkey);
+ RegCloseKey(subkey);
+ if (res != ERROR_SUCCESS) break;
+ }
+
+ if (res == ERROR_SUCCESS) res = RegDeleteKeyW(key, 0);
+ return res;
+}
+
+/***********************************************************************
+ * recursive_delete_keyA
+ */
+static LONG recursive_delete_keyA(HKEY base, char const *name)
+{
+ LONG res;
+ HKEY key;
+
+ res = RegOpenKeyExA(base, name, 0, KEY_READ | KEY_WRITE, &key);
+ if (res == ERROR_FILE_NOT_FOUND) return ERROR_SUCCESS;
+ if (res != ERROR_SUCCESS) return res;
+ res = recursive_delete_key(key);
+ RegCloseKey(key);
+ return res;
+}
+
+/***********************************************************************
+ * recursive_delete_keyW
+ */
+static LONG recursive_delete_keyW(HKEY base, WCHAR const *name)
+{
+ LONG res;
+ HKEY key;
+
+ res = RegOpenKeyExW(base, name, 0, KEY_READ | KEY_WRITE, &key);
+ if (res == ERROR_FILE_NOT_FOUND) return ERROR_SUCCESS;
+ if (res != ERROR_SUCCESS) return res;
+ res = recursive_delete_key(key);
+ RegCloseKey(key);
+ return res;
+}
+
+/***********************************************************************
+ * coclass list
+ */
+static struct regsvr_coclass const coclass_list[] = {
+ {
+ &CLSID_DirectInput,
+ "DirectInput Object",
+ NULL,
+ "dinput.dll",
+ "Both"
+ },
+ {
+ &CLSID_DirectInputDevice,
+ "DirectInputDevice Object",
+ NULL,
+ "dinput.dll",
+ "Both"
+ },
+ { NULL } /* list terminator */
+};
+
+/***********************************************************************
+ * interface list
+ */
+
+static struct regsvr_interface const interface_list[] = {
+ { NULL } /* list terminator */
+};
+
+/***********************************************************************
+ * DllRegisterServer (DINPUT.@)
+ */
+HRESULT WINAPI DINPUT_DllRegisterServer(void)
+{
+ HRESULT hr;
+
+ TRACE("\n");
+
+ hr = register_coclasses(coclass_list);
+ if (SUCCEEDED(hr))
+ hr = register_interfaces(interface_list);
+ return hr;
+}
+
+/***********************************************************************
+ * DllUnregisterServer (DINPUT.@)
+ */
+HRESULT WINAPI DINPUT_DllUnregisterServer(void)
+{
+ HRESULT hr;
+
+ TRACE("\n");
+
+ hr = unregister_coclasses(coclass_list);
+ if (SUCCEEDED(hr))
+ hr = unregister_interfaces(interface_list);
+ return hr;
+}
reactos/lib/dinput
diff -N version.rc
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ version.rc 29 Nov 2004 00:13:49 -0000 1.1
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2001 Ove Kaaven
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#define WINE_FILEDESCRIPTION_STR "Wine DirectInput"
+#define WINE_FILENAME_STR "dinput.dll"
+#define WINE_FILEVERSION 5,1,2600,881
+#define WINE_FILEVERSION_STR "5.1.2600.881"
+#define WINE_PRODUCTVERSION 5,1,2600,881
+#define WINE_PRODUCTVERSION_STR "5.1"
+
+#include "wine/wine_common_ver.rc"
CVSspam 0.2.8