/* DirectInput Keyboard device * * Copyright 1998 Marcus Meissner * Copyright 1998,1999 Lionel Ulmer * */ #include "config.h" #include #ifdef HAVE_SYS_ERRNO_H # include #endif #include "debugtools.h" #include "user.h" #include "winerror.h" #include "windef.h" #include "dinput.h" #include "dinput_private.h" #include "device_private.h" DEFAULT_DEBUG_CHANNEL(dinput); extern BYTE InputKeyStateTable[256]; extern int min_keycode, max_keycode; extern WORD keyc2vkey[256]; 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]; KEYBOARD_CONFIG initial_config; 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 ) { return USER_Driver.pGetDIState(len, ptr)?DI_OK:E_FAIL; } static HRESULT WINAPI SysKeyboardAImpl_GetDeviceData( LPDIRECTINPUTDEVICE2A iface,DWORD dodsize,LPDIDEVICEOBJECTDATA dod, LPDWORD entries,DWORD flags ) { ICOM_THIS(SysKeyboardAImpl,iface); HRESULT ret; int i; TRACE("(this=%p,%ld,%p,%p(%ld)),0x%08lx)\n", This,dodsize,dod,entries,entries?*entries:0,flags); ret=USER_Driver.pGetDIData( This->keystate, dodsize, dod, entries, flags)?DI_OK:E_FAIL; for (i=0;i<*entries;i++) { dod[i].dwTimeStamp = GetTickCount(); dod[i].dwSequence = (This->dinput->evsequence)++; } return ret; } static HRESULT WINAPI SysKeyboardAImpl_Acquire(LPDIRECTINPUTDEVICE2A iface) { ICOM_THIS(SysKeyboardAImpl,iface); TRACE("(this=%p)\n",This); if (This->acquired == 0) { KEYBOARD_CONFIG no_auto; /* Save the original config */ USER_Driver.pGetKeyboardConfig(&(This->initial_config)); /* Now, remove auto-repeat */ no_auto.auto_repeat = FALSE; USER_Driver.pSetKeyboardConfig(&no_auto, WINE_KEYBOARD_CONFIG_AUTO_REPEAT); 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) { /* Restore the original configuration */ USER_Driver.pSetKeyboardConfig(&(This->initial_config), 0xFFFFFFFF); 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.fn##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