1 /* DirectInput Keyboard device 2 * 3 * Copyright 1998 Marcus Meissner 4 * Copyright 1998,1999 Lionel Ulmer 5 * Copyright 2000-2001 TransGaming Technologies Inc. 6 * Copyright 2005 Raphael Junqueira 7 * 8 * This library is free software; you can redistribute it and/or 9 * modify it under the terms of the GNU Lesser General Public 10 * License as published by the Free Software Foundation; either 11 * version 2.1 of the License, or (at your option) any later version. 12 * 13 * This library is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16 * Lesser General Public License for more details. 17 * 18 * You should have received a copy of the GNU Lesser General Public 19 * License along with this library; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 21 */ 22 23 #include "config.h" 24 #include "wine/port.h" 25 26 #include <stdarg.h> 27 #include <string.h> 28 #include "windef.h" 29 #include "winbase.h" 30 #include "winuser.h" 31 #include "winerror.h" 32 #include "dinput.h" 33 34 #include "dinput_private.h" 35 #include "device_private.h" 36 #include "wine/debug.h" 37 #include "wine/unicode.h" 38 39 WINE_DEFAULT_DEBUG_CHANNEL(dinput); 40 41 #define WINE_DINPUT_KEYBOARD_MAX_KEYS 256 42 43 static const IDirectInputDevice8AVtbl SysKeyboardAvt; 44 static const IDirectInputDevice8WVtbl SysKeyboardWvt; 45 46 typedef struct SysKeyboardImpl SysKeyboardImpl; 47 struct SysKeyboardImpl 48 { 49 struct IDirectInputDeviceImpl base; 50 BYTE DInputKeyState[WINE_DINPUT_KEYBOARD_MAX_KEYS]; 51 }; 52 53 static inline SysKeyboardImpl *impl_from_IDirectInputDevice8A(IDirectInputDevice8A *iface) 54 { 55 return CONTAINING_RECORD(CONTAINING_RECORD(iface, IDirectInputDeviceImpl, IDirectInputDevice8A_iface), SysKeyboardImpl, base); 56 } 57 static inline SysKeyboardImpl *impl_from_IDirectInputDevice8W(IDirectInputDevice8W *iface) 58 { 59 return CONTAINING_RECORD(CONTAINING_RECORD(iface, IDirectInputDeviceImpl, IDirectInputDevice8W_iface), SysKeyboardImpl, base); 60 } 61 static inline IDirectInputDevice8A *IDirectInputDevice8A_from_impl(SysKeyboardImpl *This) 62 { 63 return &This->base.IDirectInputDevice8A_iface; 64 } 65 static inline IDirectInputDevice8W *IDirectInputDevice8W_from_impl(SysKeyboardImpl *This) 66 { 67 return &This->base.IDirectInputDevice8W_iface; 68 } 69 70 static BYTE map_dik_code(DWORD scanCode, DWORD vkCode) 71 { 72 if (!scanCode) 73 scanCode = MapVirtualKeyW(vkCode, MAPVK_VK_TO_VSC); 74 75 return scanCode; 76 } 77 78 static int KeyboardCallback( LPDIRECTINPUTDEVICE8A iface, WPARAM wparam, LPARAM lparam ) 79 { 80 SysKeyboardImpl *This = impl_from_IDirectInputDevice8A(iface); 81 int dik_code, ret = This->base.dwCoopLevel & DISCL_EXCLUSIVE; 82 KBDLLHOOKSTRUCT *hook = (KBDLLHOOKSTRUCT *)lparam; 83 BYTE new_diks; 84 85 if (wparam != WM_KEYDOWN && wparam != WM_KEYUP && 86 wparam != WM_SYSKEYDOWN && wparam != WM_SYSKEYUP) 87 return 0; 88 89 TRACE("(%p) wp %08lx, lp %08lx, vk %02x, scan %02x\n", 90 iface, wparam, lparam, hook->vkCode, hook->scanCode); 91 92 switch (hook->vkCode) 93 { 94 /* R-Shift is special - it is an extended key with separate scan code */ 95 case VK_RSHIFT : dik_code = DIK_RSHIFT; break; 96 case VK_PAUSE : dik_code = DIK_PAUSE; break; 97 case VK_NUMLOCK : dik_code = DIK_NUMLOCK; break; 98 case VK_SUBTRACT: dik_code = DIK_SUBTRACT; break; 99 default: 100 dik_code = map_dik_code(hook->scanCode & 0xff, hook->vkCode); 101 if (hook->flags & LLKHF_EXTENDED) dik_code |= 0x80; 102 } 103 new_diks = hook->flags & LLKHF_UP ? 0 : 0x80; 104 105 /* returns now if key event already known */ 106 if (new_diks == This->DInputKeyState[dik_code]) 107 return ret; 108 109 This->DInputKeyState[dik_code] = new_diks; 110 TRACE(" setting %02X to %02X\n", dik_code, This->DInputKeyState[dik_code]); 111 112 EnterCriticalSection(&This->base.crit); 113 queue_event(iface, DIDFT_MAKEINSTANCE(dik_code) | DIDFT_PSHBUTTON, 114 new_diks, GetCurrentTime(), This->base.dinput->evsequence++); 115 LeaveCriticalSection(&This->base.crit); 116 117 return ret; 118 } 119 120 const GUID DInput_Wine_Keyboard_GUID = { /* 0ab8648a-7735-11d2-8c73-71df54a96441 */ 121 0x0ab8648a, 0x7735, 0x11d2, {0x8c, 0x73, 0x71, 0xdf, 0x54, 0xa9, 0x64, 0x41} 122 }; 123 124 static void fill_keyboard_dideviceinstanceA(LPDIDEVICEINSTANCEA lpddi, DWORD version) { 125 DWORD dwSize; 126 DIDEVICEINSTANCEA ddi; 127 128 dwSize = lpddi->dwSize; 129 130 TRACE("%d %p\n", dwSize, lpddi); 131 132 memset(lpddi, 0, dwSize); 133 memset(&ddi, 0, sizeof(ddi)); 134 135 ddi.dwSize = dwSize; 136 ddi.guidInstance = GUID_SysKeyboard;/* DInput's GUID */ 137 ddi.guidProduct = DInput_Wine_Keyboard_GUID; /* Vendor's GUID */ 138 if (version >= 0x0800) 139 ddi.dwDevType = DI8DEVTYPE_KEYBOARD | (DI8DEVTYPEKEYBOARD_UNKNOWN << 8); 140 else 141 ddi.dwDevType = DIDEVTYPE_KEYBOARD | (DIDEVTYPEKEYBOARD_UNKNOWN << 8); 142 strcpy(ddi.tszInstanceName, "Keyboard"); 143 strcpy(ddi.tszProductName, "Wine Keyboard"); 144 145 memcpy(lpddi, &ddi, (dwSize < sizeof(ddi) ? dwSize : sizeof(ddi))); 146 } 147 148 static void fill_keyboard_dideviceinstanceW(LPDIDEVICEINSTANCEW lpddi, DWORD version) { 149 DWORD dwSize; 150 DIDEVICEINSTANCEW ddi; 151 152 dwSize = lpddi->dwSize; 153 154 TRACE("%d %p\n", dwSize, lpddi); 155 156 memset(lpddi, 0, dwSize); 157 memset(&ddi, 0, sizeof(ddi)); 158 159 ddi.dwSize = dwSize; 160 ddi.guidInstance = GUID_SysKeyboard;/* DInput's GUID */ 161 ddi.guidProduct = DInput_Wine_Keyboard_GUID; /* Vendor's GUID */ 162 if (version >= 0x0800) 163 ddi.dwDevType = DI8DEVTYPE_KEYBOARD | (DI8DEVTYPEKEYBOARD_UNKNOWN << 8); 164 else 165 ddi.dwDevType = DIDEVTYPE_KEYBOARD | (DIDEVTYPEKEYBOARD_UNKNOWN << 8); 166 MultiByteToWideChar(CP_ACP, 0, "Keyboard", -1, ddi.tszInstanceName, MAX_PATH); 167 MultiByteToWideChar(CP_ACP, 0, "Wine Keyboard", -1, ddi.tszProductName, MAX_PATH); 168 169 memcpy(lpddi, &ddi, (dwSize < sizeof(ddi) ? dwSize : sizeof(ddi))); 170 } 171 172 static HRESULT keyboarddev_enum_deviceA(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEA lpddi, DWORD version, int id) 173 { 174 if (id != 0) 175 return E_FAIL; 176 177 if ((dwDevType == 0) || 178 ((dwDevType == DIDEVTYPE_KEYBOARD) && (version < 0x0800)) || 179 (((dwDevType == DI8DEVCLASS_KEYBOARD) || (dwDevType == DI8DEVTYPE_KEYBOARD)) && (version >= 0x0800))) { 180 TRACE("Enumerating the Keyboard device\n"); 181 182 fill_keyboard_dideviceinstanceA(lpddi, version); 183 184 return S_OK; 185 } 186 187 return S_FALSE; 188 } 189 190 static HRESULT keyboarddev_enum_deviceW(DWORD dwDevType, DWORD dwFlags, LPDIDEVICEINSTANCEW lpddi, DWORD version, int id) 191 { 192 if (id != 0) 193 return E_FAIL; 194 195 if ((dwDevType == 0) || 196 ((dwDevType == DIDEVTYPE_KEYBOARD) && (version < 0x0800)) || 197 (((dwDevType == DI8DEVCLASS_KEYBOARD) || (dwDevType == DI8DEVTYPE_KEYBOARD)) && (version >= 0x0800))) { 198 TRACE("Enumerating the Keyboard device\n"); 199 200 fill_keyboard_dideviceinstanceW(lpddi, version); 201 202 return S_OK; 203 } 204 205 return S_FALSE; 206 } 207 208 static SysKeyboardImpl *alloc_device(REFGUID rguid, IDirectInputImpl *dinput) 209 { 210 SysKeyboardImpl* newDevice; 211 LPDIDATAFORMAT df = NULL; 212 int i, idx = 0; 213 214 newDevice = HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,sizeof(SysKeyboardImpl)); 215 newDevice->base.IDirectInputDevice8A_iface.lpVtbl = &SysKeyboardAvt; 216 newDevice->base.IDirectInputDevice8W_iface.lpVtbl = &SysKeyboardWvt; 217 newDevice->base.ref = 1; 218 memcpy(&newDevice->base.guid, rguid, sizeof(*rguid)); 219 newDevice->base.dinput = dinput; 220 newDevice->base.event_proc = KeyboardCallback; 221 InitializeCriticalSection(&newDevice->base.crit); 222 newDevice->base.crit.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": SysKeyboardImpl*->base.crit"); 223 224 /* Create copy of default data format */ 225 if (!(df = HeapAlloc(GetProcessHeap(), 0, c_dfDIKeyboard.dwSize))) goto failed; 226 memcpy(df, &c_dfDIKeyboard, c_dfDIKeyboard.dwSize); 227 if (!(df->rgodf = HeapAlloc(GetProcessHeap(), 0, df->dwNumObjs * df->dwObjSize))) goto failed; 228 229 for (i = 0; i < df->dwNumObjs; i++) 230 { 231 char buf[MAX_PATH]; 232 233 if (!GetKeyNameTextA(((i & 0x7f) << 16) | ((i & 0x80) << 17), buf, sizeof(buf))) 234 continue; 235 236 memcpy(&df->rgodf[idx], &c_dfDIKeyboard.rgodf[i], df->dwObjSize); 237 df->rgodf[idx++].dwType = DIDFT_MAKEINSTANCE(i) | DIDFT_PSHBUTTON; 238 } 239 df->dwNumObjs = idx; 240 241 newDevice->base.data_format.wine_df = df; 242 IDirectInput_AddRef(&newDevice->base.dinput->IDirectInput7A_iface); 243 244 EnterCriticalSection(&dinput->crit); 245 list_add_tail(&dinput->devices_list, &newDevice->base.entry); 246 LeaveCriticalSection(&dinput->crit); 247 248 return newDevice; 249 250 failed: 251 if (df) HeapFree(GetProcessHeap(), 0, df->rgodf); 252 HeapFree(GetProcessHeap(), 0, df); 253 HeapFree(GetProcessHeap(), 0, newDevice); 254 return NULL; 255 } 256 257 258 static HRESULT keyboarddev_create_device(IDirectInputImpl *dinput, REFGUID rguid, REFIID riid, LPVOID *pdev, int unicode) 259 { 260 TRACE("%p %s %s %p %i\n", dinput, debugstr_guid(rguid), debugstr_guid(riid), pdev, unicode); 261 *pdev = NULL; 262 263 if (IsEqualGUID(&GUID_SysKeyboard, rguid) || /* Generic Keyboard */ 264 IsEqualGUID(&DInput_Wine_Keyboard_GUID, rguid)) /* Wine Keyboard */ 265 { 266 SysKeyboardImpl *This; 267 268 if (riid == NULL) 269 ;/* nothing */ 270 else if (IsEqualGUID(&IID_IDirectInputDeviceA, riid) || 271 IsEqualGUID(&IID_IDirectInputDevice2A, riid) || 272 IsEqualGUID(&IID_IDirectInputDevice7A, riid) || 273 IsEqualGUID(&IID_IDirectInputDevice8A, riid)) 274 { 275 unicode = 0; 276 } 277 else if (IsEqualGUID(&IID_IDirectInputDeviceW, riid) || 278 IsEqualGUID(&IID_IDirectInputDevice2W, riid) || 279 IsEqualGUID(&IID_IDirectInputDevice7W, riid) || 280 IsEqualGUID(&IID_IDirectInputDevice8W, riid)) 281 { 282 unicode = 1; 283 } 284 else 285 { 286 WARN("no interface\n"); 287 return DIERR_NOINTERFACE; 288 } 289 290 This = alloc_device(rguid, dinput); 291 TRACE("Created a Keyboard device (%p)\n", This); 292 293 if (!This) return DIERR_OUTOFMEMORY; 294 295 if (unicode) 296 *pdev = &This->base.IDirectInputDevice8W_iface; 297 else 298 *pdev = &This->base.IDirectInputDevice8A_iface; 299 300 return DI_OK; 301 } 302 303 return DIERR_DEVICENOTREG; 304 } 305 306 const struct dinput_device keyboard_device = { 307 "Wine keyboard driver", 308 keyboarddev_enum_deviceA, 309 keyboarddev_enum_deviceW, 310 keyboarddev_create_device 311 }; 312 313 static HRESULT WINAPI SysKeyboardWImpl_GetDeviceState(LPDIRECTINPUTDEVICE8W iface, DWORD len, LPVOID ptr) 314 { 315 SysKeyboardImpl *This = impl_from_IDirectInputDevice8W(iface); 316 TRACE("(%p)->(%d,%p)\n", This, len, ptr); 317 318 if (!This->base.acquired) return DIERR_NOTACQUIRED; 319 320 if (len != This->base.data_format.user_df->dwDataSize ) 321 return DIERR_INVALIDPARAM; 322 323 check_dinput_events(); 324 325 EnterCriticalSection(&This->base.crit); 326 327 if (TRACE_ON(dinput)) { 328 int i; 329 for (i = 0; i < WINE_DINPUT_KEYBOARD_MAX_KEYS; i++) { 330 if (This->DInputKeyState[i] != 0x00) 331 TRACE(" - %02X: %02x\n", i, This->DInputKeyState[i]); 332 } 333 } 334 335 fill_DataFormat(ptr, len, This->DInputKeyState, &This->base.data_format); 336 LeaveCriticalSection(&This->base.crit); 337 338 return DI_OK; 339 } 340 341 static HRESULT WINAPI SysKeyboardAImpl_GetDeviceState(LPDIRECTINPUTDEVICE8A iface, DWORD len, LPVOID ptr) 342 { 343 SysKeyboardImpl *This = impl_from_IDirectInputDevice8A(iface); 344 return SysKeyboardWImpl_GetDeviceState(IDirectInputDevice8W_from_impl(This), len, ptr); 345 } 346 347 /****************************************************************************** 348 * GetCapabilities : get the device capabilities 349 */ 350 static HRESULT WINAPI SysKeyboardWImpl_GetCapabilities(LPDIRECTINPUTDEVICE8W iface, LPDIDEVCAPS lpDIDevCaps) 351 { 352 SysKeyboardImpl *This = impl_from_IDirectInputDevice8W(iface); 353 DIDEVCAPS devcaps; 354 355 TRACE("(this=%p,%p)\n",This,lpDIDevCaps); 356 357 if ((lpDIDevCaps->dwSize != sizeof(DIDEVCAPS)) && (lpDIDevCaps->dwSize != sizeof(DIDEVCAPS_DX3))) { 358 WARN("invalid parameter\n"); 359 return DIERR_INVALIDPARAM; 360 } 361 362 devcaps.dwSize = lpDIDevCaps->dwSize; 363 devcaps.dwFlags = DIDC_ATTACHED | DIDC_EMULATED; 364 if (This->base.dinput->dwVersion >= 0x0800) 365 devcaps.dwDevType = DI8DEVTYPE_KEYBOARD | (DI8DEVTYPEKEYBOARD_PCENH << 8); 366 else 367 devcaps.dwDevType = DIDEVTYPE_KEYBOARD | (DIDEVTYPEKEYBOARD_PCENH << 8); 368 devcaps.dwAxes = 0; 369 devcaps.dwButtons = This->base.data_format.wine_df->dwNumObjs; 370 devcaps.dwPOVs = 0; 371 devcaps.dwFFSamplePeriod = 0; 372 devcaps.dwFFMinTimeResolution = 0; 373 devcaps.dwFirmwareRevision = 100; 374 devcaps.dwHardwareRevision = 100; 375 devcaps.dwFFDriverVersion = 0; 376 377 memcpy(lpDIDevCaps, &devcaps, lpDIDevCaps->dwSize); 378 379 return DI_OK; 380 } 381 382 static HRESULT WINAPI SysKeyboardAImpl_GetCapabilities(LPDIRECTINPUTDEVICE8A iface, LPDIDEVCAPS lpDIDevCaps) 383 { 384 SysKeyboardImpl *This = impl_from_IDirectInputDevice8A(iface); 385 return SysKeyboardWImpl_GetCapabilities(IDirectInputDevice8W_from_impl(This), lpDIDevCaps); 386 } 387 388 /****************************************************************************** 389 * GetObjectInfo : get information about a device object such as a button 390 * or axis 391 */ 392 static HRESULT WINAPI 393 SysKeyboardAImpl_GetObjectInfo( 394 LPDIRECTINPUTDEVICE8A iface, 395 LPDIDEVICEOBJECTINSTANCEA pdidoi, 396 DWORD dwObj, 397 DWORD dwHow) 398 { 399 HRESULT res; 400 LONG scan; 401 402 res = IDirectInputDevice2AImpl_GetObjectInfo(iface, pdidoi, dwObj, dwHow); 403 if (res != DI_OK) return res; 404 405 scan = DIDFT_GETINSTANCE(pdidoi->dwType); 406 if (scan == DIK_PAUSE || scan == DIK_NUMLOCK) scan ^= 0x80; 407 if (!GetKeyNameTextA((scan & 0x80) << 17 | (scan & 0x7f) << 16, 408 pdidoi->tszName, sizeof(pdidoi->tszName))) 409 return DIERR_OBJECTNOTFOUND; 410 411 _dump_OBJECTINSTANCEA(pdidoi); 412 return res; 413 } 414 415 static HRESULT WINAPI SysKeyboardWImpl_GetObjectInfo(LPDIRECTINPUTDEVICE8W iface, 416 LPDIDEVICEOBJECTINSTANCEW pdidoi, 417 DWORD dwObj, 418 DWORD dwHow) 419 { 420 HRESULT res; 421 LONG scan; 422 423 res = IDirectInputDevice2WImpl_GetObjectInfo(iface, pdidoi, dwObj, dwHow); 424 if (res != DI_OK) return res; 425 426 scan = DIDFT_GETINSTANCE(pdidoi->dwType); 427 if (scan == DIK_PAUSE || scan == DIK_NUMLOCK) scan ^= 0x80; 428 if (!GetKeyNameTextW((scan & 0x80) << 17 | (scan & 0x7f) << 16, 429 pdidoi->tszName, sizeof(pdidoi->tszName)/sizeof(pdidoi->tszName[0]))) 430 return DIERR_OBJECTNOTFOUND; 431 432 _dump_OBJECTINSTANCEW(pdidoi); 433 return res; 434 } 435 436 /****************************************************************************** 437 * GetDeviceInfo : get information about a device's identity 438 */ 439 static HRESULT WINAPI SysKeyboardAImpl_GetDeviceInfo( 440 LPDIRECTINPUTDEVICE8A iface, 441 LPDIDEVICEINSTANCEA pdidi) 442 { 443 SysKeyboardImpl *This = impl_from_IDirectInputDevice8A(iface); 444 TRACE("(this=%p,%p)\n", This, pdidi); 445 446 if (pdidi->dwSize != sizeof(DIDEVICEINSTANCEA)) { 447 WARN(" dinput3 not supported yet...\n"); 448 return DI_OK; 449 } 450 451 fill_keyboard_dideviceinstanceA(pdidi, This->base.dinput->dwVersion); 452 453 return DI_OK; 454 } 455 456 static HRESULT WINAPI SysKeyboardWImpl_GetDeviceInfo(LPDIRECTINPUTDEVICE8W iface, LPDIDEVICEINSTANCEW pdidi) 457 { 458 SysKeyboardImpl *This = impl_from_IDirectInputDevice8W(iface); 459 TRACE("(this=%p,%p)\n", This, pdidi); 460 461 if (pdidi->dwSize != sizeof(DIDEVICEINSTANCEW)) { 462 WARN(" dinput3 not supported yet...\n"); 463 return DI_OK; 464 } 465 466 fill_keyboard_dideviceinstanceW(pdidi, This->base.dinput->dwVersion); 467 468 return DI_OK; 469 } 470 471 /****************************************************************************** 472 * GetProperty : Retrieves information about the input device. 473 */ 474 static HRESULT WINAPI SysKeyboardWImpl_GetProperty(LPDIRECTINPUTDEVICE8W iface, 475 REFGUID rguid, LPDIPROPHEADER pdiph) 476 { 477 SysKeyboardImpl *This = impl_from_IDirectInputDevice8W(iface); 478 479 TRACE("(%p) %s,%p\n", iface, debugstr_guid(rguid), pdiph); 480 _dump_DIPROPHEADER(pdiph); 481 482 if (!IS_DIPROP(rguid)) return DI_OK; 483 484 switch (LOWORD(rguid)) 485 { 486 case (DWORD_PTR)DIPROP_KEYNAME: 487 { 488 HRESULT hr; 489 LPDIPROPSTRING ps = (LPDIPROPSTRING)pdiph; 490 DIDEVICEOBJECTINSTANCEW didoi; 491 492 if (pdiph->dwSize != sizeof(DIPROPSTRING)) 493 return DIERR_INVALIDPARAM; 494 495 didoi.dwSize = sizeof(DIDEVICEOBJECTINSTANCEW); 496 497 hr = SysKeyboardWImpl_GetObjectInfo(iface, &didoi, ps->diph.dwObj, ps->diph.dwHow); 498 if (hr == DI_OK) 499 memcpy(ps->wsz, didoi.tszName, sizeof(ps->wsz)); 500 return hr; 501 } 502 case (DWORD_PTR) DIPROP_RANGE: 503 return DIERR_UNSUPPORTED; 504 default: 505 return IDirectInputDevice2AImpl_GetProperty( IDirectInputDevice8A_from_impl(This), rguid, pdiph ); 506 } 507 return DI_OK; 508 } 509 510 static HRESULT WINAPI SysKeyboardAImpl_GetProperty(LPDIRECTINPUTDEVICE8A iface, 511 REFGUID rguid, LPDIPROPHEADER pdiph) 512 { 513 SysKeyboardImpl *This = impl_from_IDirectInputDevice8A(iface); 514 return SysKeyboardWImpl_GetProperty(IDirectInputDevice8W_from_impl(This), rguid, pdiph); 515 } 516 517 static HRESULT WINAPI SysKeyboardWImpl_Acquire(LPDIRECTINPUTDEVICE8W iface) 518 { 519 SysKeyboardImpl *This = impl_from_IDirectInputDevice8W(iface); 520 HRESULT res; 521 522 TRACE("(%p)\n", This); 523 524 res = IDirectInputDevice2WImpl_Acquire(iface); 525 if (res == DI_OK) 526 { 527 TRACE("clearing keystate\n"); 528 memset(This->DInputKeyState, 0, sizeof(This->DInputKeyState)); 529 } 530 531 return res; 532 } 533 534 static HRESULT WINAPI SysKeyboardAImpl_Acquire(LPDIRECTINPUTDEVICE8A iface) 535 { 536 SysKeyboardImpl *This = impl_from_IDirectInputDevice8A(iface); 537 return SysKeyboardWImpl_Acquire(IDirectInputDevice8W_from_impl(This)); 538 } 539 540 static HRESULT WINAPI SysKeyboardWImpl_BuildActionMap(LPDIRECTINPUTDEVICE8W iface, 541 LPDIACTIONFORMATW lpdiaf, 542 LPCWSTR lpszUserName, 543 DWORD dwFlags) 544 { 545 FIXME("(%p)->(%p,%s,%08x): semi-stub !\n", iface, lpdiaf, debugstr_w(lpszUserName), dwFlags); 546 547 return _build_action_map(iface, lpdiaf, lpszUserName, dwFlags, DIKEYBOARD_MASK, &c_dfDIKeyboard); 548 } 549 550 static HRESULT WINAPI SysKeyboardAImpl_BuildActionMap(LPDIRECTINPUTDEVICE8A iface, 551 LPDIACTIONFORMATA lpdiaf, 552 LPCSTR lpszUserName, 553 DWORD dwFlags) 554 { 555 SysKeyboardImpl *This = impl_from_IDirectInputDevice8A(iface); 556 DIACTIONFORMATW diafW; 557 HRESULT hr; 558 WCHAR *lpszUserNameW = NULL; 559 int username_size; 560 561 diafW.rgoAction = HeapAlloc(GetProcessHeap(), 0, sizeof(DIACTIONW)*lpdiaf->dwNumActions); 562 _copy_diactionformatAtoW(&diafW, lpdiaf); 563 564 if (lpszUserName != NULL) 565 { 566 username_size = MultiByteToWideChar(CP_ACP, 0, lpszUserName, -1, NULL, 0); 567 lpszUserNameW = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*username_size); 568 MultiByteToWideChar(CP_ACP, 0, lpszUserName, -1, lpszUserNameW, username_size); 569 } 570 571 hr = SysKeyboardWImpl_BuildActionMap(&This->base.IDirectInputDevice8W_iface, &diafW, lpszUserNameW, dwFlags); 572 573 _copy_diactionformatWtoA(lpdiaf, &diafW); 574 HeapFree(GetProcessHeap(), 0, diafW.rgoAction); 575 HeapFree(GetProcessHeap(), 0, lpszUserNameW); 576 577 return hr; 578 } 579 580 static HRESULT WINAPI SysKeyboardWImpl_SetActionMap(LPDIRECTINPUTDEVICE8W iface, 581 LPDIACTIONFORMATW lpdiaf, 582 LPCWSTR lpszUserName, 583 DWORD dwFlags) 584 { 585 FIXME("(%p)->(%p,%s,%08x): semi-stub !\n", iface, lpdiaf, debugstr_w(lpszUserName), dwFlags); 586 587 return _set_action_map(iface, lpdiaf, lpszUserName, dwFlags, &c_dfDIKeyboard); 588 } 589 590 static HRESULT WINAPI SysKeyboardAImpl_SetActionMap(LPDIRECTINPUTDEVICE8A iface, 591 LPDIACTIONFORMATA lpdiaf, 592 LPCSTR lpszUserName, 593 DWORD dwFlags) 594 { 595 SysKeyboardImpl *This = impl_from_IDirectInputDevice8A(iface); 596 DIACTIONFORMATW diafW; 597 HRESULT hr; 598 WCHAR *lpszUserNameW = NULL; 599 int username_size; 600 601 diafW.rgoAction = HeapAlloc(GetProcessHeap(), 0, sizeof(DIACTIONW)*lpdiaf->dwNumActions); 602 _copy_diactionformatAtoW(&diafW, lpdiaf); 603 604 if (lpszUserName != NULL) 605 { 606 username_size = MultiByteToWideChar(CP_ACP, 0, lpszUserName, -1, NULL, 0); 607 lpszUserNameW = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR)*username_size); 608 MultiByteToWideChar(CP_ACP, 0, lpszUserName, -1, lpszUserNameW, username_size); 609 } 610 611 hr = SysKeyboardWImpl_SetActionMap(&This->base.IDirectInputDevice8W_iface, &diafW, lpszUserNameW, dwFlags); 612 613 HeapFree(GetProcessHeap(), 0, diafW.rgoAction); 614 HeapFree(GetProcessHeap(), 0, lpszUserNameW); 615 616 return hr; 617 } 618 619 static const IDirectInputDevice8AVtbl SysKeyboardAvt = 620 { 621 IDirectInputDevice2AImpl_QueryInterface, 622 IDirectInputDevice2AImpl_AddRef, 623 IDirectInputDevice2AImpl_Release, 624 SysKeyboardAImpl_GetCapabilities, 625 IDirectInputDevice2AImpl_EnumObjects, 626 SysKeyboardAImpl_GetProperty, 627 IDirectInputDevice2AImpl_SetProperty, 628 SysKeyboardAImpl_Acquire, 629 IDirectInputDevice2AImpl_Unacquire, 630 SysKeyboardAImpl_GetDeviceState, 631 IDirectInputDevice2AImpl_GetDeviceData, 632 IDirectInputDevice2AImpl_SetDataFormat, 633 IDirectInputDevice2AImpl_SetEventNotification, 634 IDirectInputDevice2AImpl_SetCooperativeLevel, 635 SysKeyboardAImpl_GetObjectInfo, 636 SysKeyboardAImpl_GetDeviceInfo, 637 IDirectInputDevice2AImpl_RunControlPanel, 638 IDirectInputDevice2AImpl_Initialize, 639 IDirectInputDevice2AImpl_CreateEffect, 640 IDirectInputDevice2AImpl_EnumEffects, 641 IDirectInputDevice2AImpl_GetEffectInfo, 642 IDirectInputDevice2AImpl_GetForceFeedbackState, 643 IDirectInputDevice2AImpl_SendForceFeedbackCommand, 644 IDirectInputDevice2AImpl_EnumCreatedEffectObjects, 645 IDirectInputDevice2AImpl_Escape, 646 IDirectInputDevice2AImpl_Poll, 647 IDirectInputDevice2AImpl_SendDeviceData, 648 IDirectInputDevice7AImpl_EnumEffectsInFile, 649 IDirectInputDevice7AImpl_WriteEffectToFile, 650 SysKeyboardAImpl_BuildActionMap, 651 SysKeyboardAImpl_SetActionMap, 652 IDirectInputDevice8AImpl_GetImageInfo 653 }; 654 655 static const IDirectInputDevice8WVtbl SysKeyboardWvt = 656 { 657 IDirectInputDevice2WImpl_QueryInterface, 658 IDirectInputDevice2WImpl_AddRef, 659 IDirectInputDevice2WImpl_Release, 660 SysKeyboardWImpl_GetCapabilities, 661 IDirectInputDevice2WImpl_EnumObjects, 662 SysKeyboardWImpl_GetProperty, 663 IDirectInputDevice2WImpl_SetProperty, 664 SysKeyboardWImpl_Acquire, 665 IDirectInputDevice2WImpl_Unacquire, 666 SysKeyboardWImpl_GetDeviceState, 667 IDirectInputDevice2WImpl_GetDeviceData, 668 IDirectInputDevice2WImpl_SetDataFormat, 669 IDirectInputDevice2WImpl_SetEventNotification, 670 IDirectInputDevice2WImpl_SetCooperativeLevel, 671 SysKeyboardWImpl_GetObjectInfo, 672 SysKeyboardWImpl_GetDeviceInfo, 673 IDirectInputDevice2WImpl_RunControlPanel, 674 IDirectInputDevice2WImpl_Initialize, 675 IDirectInputDevice2WImpl_CreateEffect, 676 IDirectInputDevice2WImpl_EnumEffects, 677 IDirectInputDevice2WImpl_GetEffectInfo, 678 IDirectInputDevice2WImpl_GetForceFeedbackState, 679 IDirectInputDevice2WImpl_SendForceFeedbackCommand, 680 IDirectInputDevice2WImpl_EnumCreatedEffectObjects, 681 IDirectInputDevice2WImpl_Escape, 682 IDirectInputDevice2WImpl_Poll, 683 IDirectInputDevice2WImpl_SendDeviceData, 684 IDirectInputDevice7WImpl_EnumEffectsInFile, 685 IDirectInputDevice7WImpl_WriteEffectToFile, 686 SysKeyboardWImpl_BuildActionMap, 687 SysKeyboardWImpl_SetActionMap, 688 IDirectInputDevice8WImpl_GetImageInfo 689 }; 690