| /* DirectInput Keyboard 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 |
| */ |
| |
| #include "config.h" |
| #include <string.h> |
| #ifdef HAVE_SYS_ERRNO_H |
| # include <sys/errno.h> |
| #endif |
| |
| #include "winbase.h" |
| #include "winuser.h" |
| #include "winerror.h" |
| #include "dinput.h" |
| |
| #include "dinput_private.h" |
| #include "device_private.h" |
| #include "wine/debug.h" |
| |
| WINE_DEFAULT_DEBUG_CHANNEL(dinput); |
| |
| static ICOM_VTABLE(IDirectInputDevice2A) SysKeyboardAvt; |
| static ICOM_VTABLE(IDirectInputDevice7A) SysKeyboard7Avt; |
| |
| typedef struct SysKeyboardAImpl SysKeyboardAImpl; |
| struct SysKeyboardAImpl |
| { |
| /* IDirectInputDevice2AImpl */ |
| ICOM_VFIELD(IDirectInputDevice2A); |
| DWORD ref; |
| GUID guid; |
| |
| IDirectInputAImpl *dinput; |
| |
| /* SysKeyboardAImpl */ |
| BYTE keystate[256]; |
| int acquired; |
| }; |
| |
| static GUID DInput_Wine_Keyboard_GUID = { /* 0ab8648a-7735-11d2-8c73-71df54a96441 */ |
| 0x0ab8648a, |
| 0x7735, |
| 0x11d2, |
| {0x8c, 0x73, 0x71, 0xdf, 0x54, 0xa9, 0x64, 0x41} |
| }; |
| |
| static BOOL keyboarddev_enum_device(DWORD dwDevType, DWORD dwFlags, LPCDIDEVICEINSTANCEA lpddi) |
| { |
| if ((dwDevType == 0) || (dwDevType == DIDEVTYPE_KEYBOARD)) { |
| TRACE("Enumerating the Keyboard device\n"); |
| |
| lpddi->guidInstance = GUID_SysKeyboard;/* DInput's GUID */ |
| lpddi->guidProduct = DInput_Wine_Keyboard_GUID; /* Vendor's GUID */ |
| lpddi->dwDevType = DIDEVTYPE_KEYBOARD | (DIDEVTYPEKEYBOARD_UNKNOWN << 8); |
| strcpy(lpddi->tszInstanceName, "Keyboard"); |
| strcpy(lpddi->tszProductName, "Wine Keyboard"); |
| |
| return TRUE; |
| } |
| |
| return FALSE; |
| } |
| |
| static SysKeyboardAImpl *alloc_device(REFGUID rguid, ICOM_VTABLE(IDirectInputDevice2A) *kvt, IDirectInputAImpl *dinput) |
| { |
| SysKeyboardAImpl* newDevice; |
| newDevice = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(SysKeyboardAImpl)); |
| newDevice->ref = 1; |
| ICOM_VTBL(newDevice) = kvt; |
| memcpy(&(newDevice->guid),rguid,sizeof(*rguid)); |
| memset(newDevice->keystate,0,256); |
| newDevice->dinput = dinput; |
| |
| return newDevice; |
| } |
| |
| |
| static HRESULT keyboarddev_create_device(IDirectInputAImpl *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_IDirectInputDevice2A,riid)) || (IsEqualGUID(&IID_IDirectInputDevice2A,riid))) { |
| *pdev=(IDirectInputDeviceA*) alloc_device(rguid, &SysKeyboardAvt, dinput); |
| |
| TRACE("Creating a Keyboard device (%p)\n", *pdev); |
| return DI_OK; |
| } else if (IsEqualGUID(&IID_IDirectInputDevice7A,riid)) { |
| *pdev=(IDirectInputDeviceA*) alloc_device(rguid, (ICOM_VTABLE(IDirectInputDevice2A) *) &SysKeyboard7Avt, dinput); |
| |
| TRACE("Creating a Keyboard DInput7A device (%p)\n", *pdev); |
| return DI_OK; |
| } else |
| return DIERR_NOINTERFACE; |
| } |
| |
| return DIERR_DEVICENOTREG; |
| } |
| |
| static dinput_device keyboarddev = { |
| 100, |
| keyboarddev_enum_device, |
| keyboarddev_create_device |
| }; |
| |
| DECL_GLOBAL_CONSTRUCTOR(keyboarddev_register) { dinput_register_device(&keyboarddev); } |
| |
| static HRESULT WINAPI SysKeyboardAImpl_SetProperty( |
| LPDIRECTINPUTDEVICE2A iface,REFGUID rguid,LPCDIPROPHEADER ph |
| ) |
| { |
| ICOM_THIS(SysKeyboardAImpl,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); |
| break; |
| } |
| default: |
| WARN("Unknown type %ld\n",(DWORD)rguid); |
| break; |
| } |
| } |
| return 0; |
| } |
| |
| static HRESULT WINAPI SysKeyboardAImpl_GetDeviceState( |
| LPDIRECTINPUTDEVICE2A iface,DWORD len,LPVOID ptr |
| ) |
| { |
| DWORD i; |
| |
| memset( ptr, 0, len ); |
| if (len != 256) |
| { |
| WARN("whoops, got len %ld?\n", len); |
| return DI_OK; |
| } |
| for (i = 0; i < 0x80; i++) |
| { |
| WORD vkey = MapVirtualKeyA( i, 1 ); |
| if (vkey && (GetAsyncKeyState( vkey ) & 0x8000)) |
| { |
| ((LPBYTE)ptr)[i] = 0x80; |
| ((LPBYTE)ptr)[i | 0x80] = 0x80; |
| } |
| } |
| return DI_OK; |
| } |
| |
| static HRESULT WINAPI SysKeyboardAImpl_GetDeviceData( |
| LPDIRECTINPUTDEVICE2A iface,DWORD dodsize,LPDIDEVICEOBJECTDATA dod, |
| LPDWORD entries,DWORD flags |
| ) |
| { |
| ICOM_THIS(SysKeyboardAImpl,iface); |
| int i, n; |
| |
| TRACE("(this=%p,%ld,%p,%p(%ld)),0x%08lx)\n", |
| This,dodsize,dod,entries,entries?*entries:0,flags); |
| |
| |
| for (i = n = 0; (i < 0x80) && (n < *entries); i++) |
| { |
| WORD state, vkey = MapVirtualKeyA( i, 1 ); |
| if (!vkey) continue; |
| state = (GetAsyncKeyState( vkey ) >> 8) & 0x80; |
| if (state != This->keystate[vkey]) |
| { |
| if (dod) |
| { |
| /* add an entry */ |
| dod[n].dwOfs = i; /* scancode */ |
| dod[n].dwData = state; |
| dod[n].dwTimeStamp = GetCurrentTime(); /* umm */ |
| dod[n].dwSequence = This->dinput->evsequence++; |
| n++; |
| } |
| if (!(flags & DIGDD_PEEK)) This->keystate[vkey] = state; |
| } |
| } |
| if (n) TRACE_(dinput)("%d entries\n",n); |
| *entries = n; |
| return DI_OK; |
| } |
| |
| static HRESULT WINAPI SysKeyboardAImpl_Acquire(LPDIRECTINPUTDEVICE2A iface) |
| { |
| ICOM_THIS(SysKeyboardAImpl,iface); |
| |
| TRACE("(this=%p)\n",This); |
| |
| if (This->acquired == 0) { |
| This->acquired = 1; |
| } |
| |
| return DI_OK; |
| } |
| |
| static HRESULT WINAPI SysKeyboardAImpl_Unacquire(LPDIRECTINPUTDEVICE2A iface) |
| { |
| ICOM_THIS(SysKeyboardAImpl,iface); |
| TRACE("(this=%p)\n",This); |
| |
| if (This->acquired == 1) { |
| This->acquired = 0; |
| } else { |
| ERR("Unacquiring a not-acquired device !!!\n"); |
| } |
| |
| return DI_OK; |
| } |
| |
| /****************************************************************************** |
| * GetCapabilities : get the device capablitites |
| */ |
| static HRESULT WINAPI SysKeyboardAImpl_GetCapabilities( |
| LPDIRECTINPUTDEVICE2A iface, |
| LPDIDEVCAPS lpDIDevCaps) |
| { |
| ICOM_THIS(SysKeyboardAImpl,iface); |
| |
| TRACE("(this=%p,%p)\n",This,lpDIDevCaps); |
| |
| if (lpDIDevCaps->dwSize == sizeof(DIDEVCAPS)) { |
| lpDIDevCaps->dwFlags = DIDC_ATTACHED; |
| lpDIDevCaps->dwDevType = DIDEVTYPE_KEYBOARD; |
| lpDIDevCaps->dwAxes = 0; |
| lpDIDevCaps->dwButtons = 0; |
| lpDIDevCaps->dwPOVs = 0; |
| lpDIDevCaps->dwFFSamplePeriod = 0; |
| lpDIDevCaps->dwFFMinTimeResolution = 0; |
| lpDIDevCaps->dwFirmwareRevision = 100; |
| lpDIDevCaps->dwHardwareRevision = 100; |
| lpDIDevCaps->dwFFDriverVersion = 0; |
| } else { |
| /* DirectX 3.0 */ |
| FIXME("DirectX 3.0 not supported....\n"); |
| } |
| |
| return DI_OK; |
| } |
| |
| static ICOM_VTABLE(IDirectInputDevice2A) SysKeyboardAvt = |
| { |
| ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE |
| IDirectInputDevice2AImpl_QueryInterface, |
| IDirectInputDevice2AImpl_AddRef, |
| IDirectInputDevice2AImpl_Release, |
| SysKeyboardAImpl_GetCapabilities, |
| IDirectInputDevice2AImpl_EnumObjects, |
| IDirectInputDevice2AImpl_GetProperty, |
| SysKeyboardAImpl_SetProperty, |
| SysKeyboardAImpl_Acquire, |
| SysKeyboardAImpl_Unacquire, |
| SysKeyboardAImpl_GetDeviceState, |
| SysKeyboardAImpl_GetDeviceData, |
| IDirectInputDevice2AImpl_SetDataFormat, |
| IDirectInputDevice2AImpl_SetEventNotification, |
| IDirectInputDevice2AImpl_SetCooperativeLevel, |
| IDirectInputDevice2AImpl_GetObjectInfo, |
| IDirectInputDevice2AImpl_GetDeviceInfo, |
| IDirectInputDevice2AImpl_RunControlPanel, |
| IDirectInputDevice2AImpl_Initialize, |
| IDirectInputDevice2AImpl_CreateEffect, |
| IDirectInputDevice2AImpl_EnumEffects, |
| IDirectInputDevice2AImpl_GetEffectInfo, |
| IDirectInputDevice2AImpl_GetForceFeedbackState, |
| IDirectInputDevice2AImpl_SendForceFeedbackCommand, |
| IDirectInputDevice2AImpl_EnumCreatedEffectObjects, |
| IDirectInputDevice2AImpl_Escape, |
| IDirectInputDevice2AImpl_Poll, |
| IDirectInputDevice2AImpl_SendDeviceData |
| }; |
| |
| #if !defined(__STRICT_ANSI__) && defined(__GNUC__) |
| # define XCAST(fun) (typeof(SysKeyboard7Avt.fun)) |
| #else |
| # define XCAST(fun) (void*) |
| #endif |
| |
| static ICOM_VTABLE(IDirectInputDevice7A) SysKeyboard7Avt = |
| { |
| ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE |
| XCAST(QueryInterface)IDirectInputDevice2AImpl_QueryInterface, |
| XCAST(AddRef)IDirectInputDevice2AImpl_AddRef, |
| XCAST(Release)IDirectInputDevice2AImpl_Release, |
| XCAST(GetCapabilities)SysKeyboardAImpl_GetCapabilities, |
| XCAST(EnumObjects)IDirectInputDevice2AImpl_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)IDirectInputDevice2AImpl_SetEventNotification, |
| XCAST(SetCooperativeLevel)IDirectInputDevice2AImpl_SetCooperativeLevel, |
| XCAST(GetObjectInfo)IDirectInputDevice2AImpl_GetObjectInfo, |
| XCAST(GetDeviceInfo)IDirectInputDevice2AImpl_GetDeviceInfo, |
| XCAST(RunControlPanel)IDirectInputDevice2AImpl_RunControlPanel, |
| XCAST(Initialize)IDirectInputDevice2AImpl_Initialize, |
| XCAST(CreateEffect)IDirectInputDevice2AImpl_CreateEffect, |
| XCAST(EnumEffects)IDirectInputDevice2AImpl_EnumEffects, |
| XCAST(GetEffectInfo)IDirectInputDevice2AImpl_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, |
| IDirectInputDevice7AImpl_EnumEffectsInFile, |
| IDirectInputDevice7AImpl_WriteEffectToFile |
| }; |
| |
| #undef XCAST |