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