winInput.cc 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949
  1. //-----------------------------------------------------------------------------
  2. // Copyright (c) 2013 GarageGames, LLC
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to
  6. // deal in the Software without restriction, including without limitation the
  7. // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
  8. // sell copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  19. // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  20. // IN THE SOFTWARE.
  21. //-----------------------------------------------------------------------------
  22. #include "platformWin32/platformWin32.h"
  23. #include "platform/platformInput.h"
  24. #include "platform/platformVideo.h"
  25. #include "platformWin32/winDirectInput.h"
  26. #include "platform/event.h"
  27. #include "console/console.h"
  28. #include "platform/platformInput_ScriptBinding.h"
  29. #include "winInput_ScriptBinding.h"
  30. // Static class variables:
  31. InputManager* Input::smManager;
  32. bool Input::smActive;
  33. CursorManager* Input::smCursorManager = 0; //*** DAW: Added
  34. U8 Input::smModifierKeys; //*** DAW: Added
  35. bool Input::smLastKeyboardActivated;
  36. bool Input::smLastMouseActivated;
  37. bool Input::smLastJoystickActivated;
  38. static void fillAsciiTable();
  39. //------------------------------------------------------------------------------
  40. //
  41. // This function gets the standard ASCII code corresponding to our key code
  42. // and the existing modifier key state.
  43. //
  44. //------------------------------------------------------------------------------
  45. struct AsciiData
  46. {
  47. struct KeyData
  48. {
  49. U16 ascii;
  50. bool isDeadChar;
  51. };
  52. KeyData upper;
  53. KeyData lower;
  54. KeyData goofy;
  55. };
  56. #define NUM_KEYS ( KEY_OEM_102 + 1 )
  57. #define KEY_FIRST KEY_ESCAPE
  58. static AsciiData AsciiTable[NUM_KEYS];
  59. //------------------------------------------------------------------------------
  60. void Input::init()
  61. {
  62. Con::printSeparator();
  63. Con::printf( "Input Initialization:" );
  64. destroy();
  65. smActive = false;
  66. smLastKeyboardActivated = true;
  67. smLastMouseActivated = true;
  68. smLastJoystickActivated = true;
  69. OSVERSIONINFO OSVersionInfo;
  70. dMemset( &OSVersionInfo, 0, sizeof( OSVERSIONINFO ) );
  71. OSVersionInfo.dwOSVersionInfoSize = sizeof( OSVERSIONINFO );
  72. if ( GetVersionEx( &OSVersionInfo ) )
  73. {
  74. if ( !( OSVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_NT && OSVersionInfo.dwMajorVersion < 5 ) )
  75. {
  76. smManager = new DInputManager;
  77. if ( !smManager->enable() )
  78. {
  79. Con::printf( " DirectInput not enabled." );
  80. delete smManager;
  81. smManager = NULL;
  82. }
  83. else
  84. {
  85. DInputManager::init();
  86. Con::printf( " DirectInput enabled." );
  87. }
  88. }
  89. else
  90. Con::printf( " WinNT detected -- DirectInput not enabled." );
  91. }
  92. // Startup the Cursor Manager
  93. if(!smCursorManager)
  94. {
  95. smCursorManager = new CursorManager();
  96. if(smCursorManager)
  97. {
  98. // Add the arrow cursor to the stack
  99. smCursorManager->pushCursor(CursorManager::curArrow);
  100. }
  101. else
  102. {
  103. Con::printf(" Cursor Manager not enabled.");
  104. }
  105. }
  106. // Init the current modifier keys
  107. setModifierKeys(0);
  108. fillAsciiTable();
  109. Con::printf( "" );
  110. }
  111. //------------------------------------------------------------------------------
  112. static void fillAsciiTable()
  113. {
  114. //HKL layout = GetKeyboardLayout( 0 );
  115. U8 state[256];
  116. U16 ascii[2];
  117. U32 dikCode, vKeyCode, keyCode;
  118. S32 result;
  119. dMemset( &AsciiTable, 0, sizeof( AsciiTable ) );
  120. dMemset( &state, 0, sizeof( state ) );
  121. for ( keyCode = KEY_FIRST; keyCode < NUM_KEYS; keyCode++ )
  122. {
  123. ascii[0] = ascii[1] = 0;
  124. dikCode = Key_to_DIK( keyCode );
  125. if ( dikCode )
  126. {
  127. //vKeyCode = MapVirtualKeyEx( dikCode, 1, layout );
  128. vKeyCode = MapVirtualKey( dikCode, 1 );
  129. // Lower case:
  130. ascii[0] = ascii[1] = 0;
  131. //result = ToAsciiEx( vKeyCode, dikCode, state, ascii, 0, layout );
  132. result = ToAscii( vKeyCode, dikCode, state, ascii, 0 );
  133. if ( result == 2 )
  134. AsciiTable[keyCode].lower.ascii = ascii[1] ? ascii[1] : ( ascii[0] >> 8 );
  135. else if ( result == 1 )
  136. AsciiTable[keyCode].lower.ascii = ascii[0];
  137. else if ( result < 0 )
  138. {
  139. AsciiTable[keyCode].lower.ascii = ascii[0];
  140. AsciiTable[keyCode].lower.isDeadChar = true;
  141. // Need to clear the dead character from the keyboard layout:
  142. //ToAsciiEx( vKeyCode, dikCode, state, ascii, 0, layout );
  143. ToAscii( vKeyCode, dikCode, state, ascii, 0 );
  144. }
  145. // Upper case:
  146. ascii[0] = ascii[1] = 0;
  147. state[VK_SHIFT] = 0x80;
  148. //result = ToAsciiEx( vKeyCode, dikCode, state, ascii, 0, layout );
  149. result = ToAscii( vKeyCode, dikCode, state, ascii, 0 );
  150. if ( result == 2 )
  151. AsciiTable[keyCode].upper.ascii = ascii[1] ? ascii[1] : ( ascii[0] >> 8 );
  152. else if ( result == 1 )
  153. AsciiTable[keyCode].upper.ascii = ascii[0];
  154. else if ( result < 0 )
  155. {
  156. AsciiTable[keyCode].upper.ascii = ascii[0];
  157. AsciiTable[keyCode].upper.isDeadChar = true;
  158. // Need to clear the dead character from the keyboard layout:
  159. //ToAsciiEx( vKeyCode, dikCode, state, ascii, 0, layout );
  160. ToAscii( vKeyCode, dikCode, state, ascii, 0 );
  161. }
  162. state[VK_SHIFT] = 0;
  163. // Foreign mod case:
  164. ascii[0] = ascii[1] = 0;
  165. state[VK_CONTROL] = 0x80;
  166. state[VK_MENU] = 0x80;
  167. //result = ToAsciiEx( vKeyCode, dikCode, state, ascii, 0, layout );
  168. result = ToAscii( vKeyCode, dikCode, state, ascii, 0 );
  169. if ( result == 2 )
  170. AsciiTable[keyCode].goofy.ascii = ascii[1] ? ascii[1] : ( ascii[0] >> 8 );
  171. else if ( result == 1 )
  172. AsciiTable[keyCode].goofy.ascii = ascii[0];
  173. else if ( result < 0 )
  174. {
  175. AsciiTable[keyCode].goofy.ascii = ascii[0];
  176. AsciiTable[keyCode].goofy.isDeadChar = true;
  177. // Need to clear the dead character from the keyboard layout:
  178. //ToAsciiEx( vKeyCode, dikCode, state, ascii, 0, layout );
  179. ToAscii( vKeyCode, dikCode, state, ascii, 0 );
  180. }
  181. state[VK_CONTROL] = 0;
  182. state[VK_MENU] = 0;
  183. }
  184. }
  185. }
  186. //------------------------------------------------------------------------------
  187. U16 Input::getKeyCode( U16 asciiCode )
  188. {
  189. U16 keyCode = 0;
  190. U16 i;
  191. // This is done three times so the lowerkey will always
  192. // be found first. Some foreign keyboards have duplicate
  193. // chars on some keys.
  194. for ( i = KEY_FIRST; i < NUM_KEYS && !keyCode; i++ )
  195. {
  196. if ( AsciiTable[i].lower.ascii == asciiCode )
  197. {
  198. keyCode = i;
  199. break;
  200. };
  201. }
  202. for ( i = KEY_FIRST; i < NUM_KEYS && !keyCode; i++ )
  203. {
  204. if ( AsciiTable[i].upper.ascii == asciiCode )
  205. {
  206. keyCode = i;
  207. break;
  208. };
  209. }
  210. for ( i = KEY_FIRST; i < NUM_KEYS && !keyCode; i++ )
  211. {
  212. if ( AsciiTable[i].goofy.ascii == asciiCode )
  213. {
  214. keyCode = i;
  215. break;
  216. };
  217. }
  218. return( keyCode );
  219. }
  220. //------------------------------------------------------------------------------
  221. U16 Input::getAscii( U16 keyCode, KEY_STATE keyState )
  222. {
  223. if ( keyCode >= NUM_KEYS )
  224. return 0;
  225. switch ( keyState )
  226. {
  227. case STATE_LOWER:
  228. return AsciiTable[keyCode].lower.ascii;
  229. case STATE_UPPER:
  230. return AsciiTable[keyCode].upper.ascii;
  231. case STATE_GOOFY:
  232. return AsciiTable[keyCode].goofy.ascii;
  233. default:
  234. return(0);
  235. }
  236. }
  237. //------------------------------------------------------------------------------
  238. void Input::destroy()
  239. {
  240. if ( smManager && smManager->isEnabled() )
  241. {
  242. smManager->disable();
  243. delete smManager;
  244. smManager = NULL;
  245. }
  246. }
  247. //------------------------------------------------------------------------------
  248. bool Input::enable()
  249. {
  250. if ( smManager && !smManager->isEnabled() )
  251. return( smManager->enable() );
  252. return( false );
  253. }
  254. //------------------------------------------------------------------------------
  255. void Input::disable()
  256. {
  257. if ( smManager && smManager->isEnabled() )
  258. smManager->disable();
  259. }
  260. //------------------------------------------------------------------------------
  261. void Input::activate()
  262. {
  263. #ifdef UNICODE
  264. winState.imeHandle = ImmGetContext( winState.appWindow );
  265. ImmReleaseContext( winState.appWindow, winState.imeHandle );
  266. #endif
  267. DInputDevice::resetModifierKeys();
  268. if ( !Con::getBoolVariable( "$enableDirectInput" ) )
  269. return;
  270. if ( smManager && smManager->isEnabled() && !smActive )
  271. {
  272. Con::printf( "Activating DirectInput..." );
  273. smActive = true;
  274. DInputManager* dInputManager = dynamic_cast<DInputManager*>( smManager );
  275. if ( dInputManager )
  276. {
  277. if ( dInputManager->isKeyboardEnabled() && smLastKeyboardActivated )
  278. dInputManager->activateKeyboard();
  279. if ( Video::isFullScreen() )
  280. {
  281. // DirectInput Mouse Hook-Up:
  282. if ( dInputManager->isMouseEnabled() && smLastMouseActivated )
  283. dInputManager->activateMouse();
  284. }
  285. else
  286. dInputManager->deactivateMouse();
  287. if ( dInputManager->isJoystickEnabled() && smLastJoystickActivated )
  288. dInputManager->activateJoystick();
  289. }
  290. }
  291. }
  292. //------------------------------------------------------------------------------
  293. void Input::deactivate()
  294. {
  295. if ( smManager && smManager->isEnabled() && smActive )
  296. {
  297. DInputManager* dInputManager = dynamic_cast<DInputManager*>( smManager );
  298. if ( dInputManager )
  299. {
  300. smLastKeyboardActivated = dInputManager->isKeyboardActive();
  301. smLastMouseActivated = dInputManager->isMouseActive();
  302. smLastJoystickActivated = dInputManager->isJoystickActive();
  303. dInputManager->deactivateKeyboard();
  304. dInputManager->deactivateMouse();
  305. dInputManager->deactivateJoystick();
  306. }
  307. smActive = false;
  308. Con::printf( "DirectInput deactivated." );
  309. }
  310. }
  311. //------------------------------------------------------------------------------
  312. void Input::reactivate()
  313. {
  314. // This is soo hacky...
  315. SetForegroundWindow( winState.appWindow );
  316. PostMessage( winState.appWindow, WM_ACTIVATE, WA_ACTIVE, NULL );
  317. }
  318. //------------------------------------------------------------------------------
  319. bool Input::isEnabled()
  320. {
  321. if ( smManager )
  322. return smManager->isEnabled();
  323. return false;
  324. }
  325. //------------------------------------------------------------------------------
  326. bool Input::isActive()
  327. {
  328. return smActive;
  329. }
  330. //------------------------------------------------------------------------------
  331. void Input::process()
  332. {
  333. if ( smManager && smManager->isEnabled() && smActive )
  334. smManager->process();
  335. }
  336. //------------------------------------------------------------------------------
  337. // Accesses the global input manager to see if its mouse is enabled
  338. bool Input::isMouseEnabled()
  339. {
  340. DInputManager* dInputManager = dynamic_cast<DInputManager*>( smManager );
  341. if ( !dInputManager || !dInputManager->isEnabled() )
  342. return( false );
  343. if (dInputManager->isMouseEnabled() && dInputManager->isMouseActive() )
  344. return( true );
  345. return false;
  346. }
  347. //------------------------------------------------------------------------------
  348. // Accesses the global input manager to see if its keyboard is enabled
  349. bool Input::isKeyboardEnabled()
  350. {
  351. DInputManager* dInputManager = dynamic_cast<DInputManager*>( smManager );
  352. if ( !dInputManager || !dInputManager->isEnabled() )
  353. return( false );
  354. if ( dInputManager->isKeyboardEnabled() && dInputManager->isKeyboardActive() )
  355. return( true );
  356. return false;
  357. }
  358. //------------------------------------------------------------------------------
  359. // Access the global input manager and enables its mouse
  360. void Input::enableMouse()
  361. {
  362. DInputManager::enableMouse();
  363. }
  364. //------------------------------------------------------------------------------
  365. // Access the global input manager and disables its mouse
  366. void Input::disableMouse()
  367. {
  368. DInputManager::disableMouse();
  369. }
  370. //------------------------------------------------------------------------------
  371. // Access the global input manager and enables its keyboard
  372. void Input::enableKeyboard()
  373. {
  374. DInputManager::enableKeyboard();
  375. }
  376. //------------------------------------------------------------------------------
  377. // Access the global input manager and enables its keyboard
  378. void Input::disableKeyboard()
  379. {
  380. DInputManager::disableKeyboard();
  381. }
  382. //------------------------------------------------------------------------------
  383. bool Input::activateKeyboard()
  384. {
  385. DInputManager* mgr = dynamic_cast<DInputManager*>( Input::getManager() );
  386. if ( mgr )
  387. return( mgr->activateKeyboard() );
  388. return( false );
  389. }
  390. //------------------------------------------------------------------------------
  391. void Input::deactivateKeyboard()
  392. {
  393. DInputManager* mgr = dynamic_cast<DInputManager*>( Input::getManager() );
  394. if ( mgr )
  395. mgr->deactivateKeyboard();
  396. }
  397. //------------------------------------------------------------------------------
  398. bool Input::enableJoystick()
  399. {
  400. return( DInputManager::enableJoystick() );
  401. }
  402. //------------------------------------------------------------------------------
  403. void Input::disableJoystick()
  404. {
  405. DInputManager::disableJoystick();
  406. }
  407. //------------------------------------------------------------------------------
  408. void Input::echoInputState()
  409. {
  410. DInputManager* mgr = dynamic_cast<DInputManager*>( Input::getManager() );
  411. if ( mgr && mgr->isEnabled() )
  412. {
  413. Con::printf( "DirectInput is enabled %s.", Input::isActive() ? "and active" : "but inactive" );
  414. Con::printf( "- Keyboard is %sabled and %sactive.",
  415. mgr->isKeyboardEnabled() ? "en" : "dis",
  416. mgr->isKeyboardActive() ? "" : "in" );
  417. Con::printf( "- Mouse is %sabled and %sactive.",
  418. mgr->isMouseEnabled() ? "en" : "dis",
  419. mgr->isMouseActive() ? "" : "in" );
  420. Con::printf( "- Joystick is %sabled and %sactive.",
  421. mgr->isJoystickEnabled() ? "en" : "dis",
  422. mgr->isJoystickActive() ? "" : "in" );
  423. Con::printf( "- Xinput is %sabled and %sactive.",
  424. mgr->isXInputEnabled() ? "en" : "dis",
  425. mgr->isXInputActive() ? "" : "in" );
  426. }
  427. else
  428. {
  429. Con::printf( "DirectInput is not enabled." );
  430. }
  431. }
  432. //------------------------------------------------------------------------------
  433. void Input::setCursorPos(S32 x, S32 y)
  434. {
  435. POINT pt;
  436. pt.x = x;
  437. pt.y = y;
  438. ClientToScreen(winState.appWindow, &pt);
  439. SetCursorPos(pt.x, pt.y);
  440. }
  441. //------------------------------------------------------------------------------
  442. // Set the cursor to draw (true) or not (false)
  443. void Input::setCursorState(bool on)
  444. {
  445. ShowCursor(on);
  446. }
  447. //------------------------------------------------------------------------------
  448. static struct { U32 id; LPTSTR resourceID; } sgCursorShapeMap[]=
  449. {
  450. { CursorManager::curArrow, IDC_ARROW },
  451. { CursorManager::curWait, IDC_WAIT },
  452. { CursorManager::curPlus, IDC_CROSS },
  453. { CursorManager::curResizeVert, IDC_SIZEWE },
  454. { CursorManager::curResizeHorz, IDC_SIZENS },
  455. { CursorManager::curResizeAll, IDC_SIZEALL },
  456. { CursorManager::curIBeam, IDC_IBEAM },
  457. { CursorManager::curResizeNESW, IDC_SIZENESW },
  458. { CursorManager::curResizeNWSE, IDC_SIZENWSE },
  459. { 0, 0 },
  460. };
  461. void Input::setCursorShape(U32 cursorID)
  462. {
  463. LPTSTR resourceID = NULL;
  464. for(S32 i = 0;sgCursorShapeMap[i].resourceID != NULL;++i)
  465. {
  466. if(cursorID == sgCursorShapeMap[i].id)
  467. {
  468. resourceID = sgCursorShapeMap[i].resourceID;
  469. break;
  470. }
  471. }
  472. if(resourceID == NULL)
  473. return;
  474. HCURSOR cur = LoadCursor(NULL, resourceID);
  475. if(cur)
  476. SetCursor(cur);
  477. }
  478. //------------------------------------------------------------------------------
  479. // Functions to change the cursor shape using the Input class.
  480. void Input::pushCursor(S32 cursorID)
  481. {
  482. CursorManager* cm = getCursorManager();
  483. if(cm)
  484. cm->pushCursor(cursorID);
  485. }
  486. void Input::popCursor()
  487. {
  488. CursorManager* cm = getCursorManager();
  489. if(cm)
  490. cm->popCursor();
  491. }
  492. void Input::refreshCursor()
  493. {
  494. CursorManager* cm = getCursorManager();
  495. if(cm)
  496. cm->refreshCursor();
  497. }
  498. //------------------------------------------------------------------------------
  499. U32 Input::getDoubleClickTime()
  500. {
  501. return GetDoubleClickTime();
  502. }
  503. S32 Input::getDoubleClickWidth()
  504. {
  505. return GetSystemMetrics(SM_CXDOUBLECLK);
  506. }
  507. S32 Input::getDoubleClickHeight()
  508. {
  509. return GetSystemMetrics(SM_CYDOUBLECLK);
  510. }
  511. //------------------------------------------------------------------------------
  512. InputManager* Input::getManager()
  513. {
  514. return( smManager );
  515. }
  516. //------------------------------------------------------------------------------
  517. //------------------------------------------------------------------------------
  518. static U8 VcodeRemap[256] =
  519. {
  520. 0, // 0x00
  521. 0, // 0x01 VK_LBUTTON
  522. 0, // 0x02 VK_RBUTTON
  523. 0, // 0x03 VK_CANCEL
  524. 0, // 0x04 VK_MBUTTON
  525. 0, // 0x05
  526. 0, // 0x06
  527. 0, // 0x07
  528. KEY_BACKSPACE, // 0x08 VK_BACK
  529. KEY_TAB, // 0x09 VK_TAB
  530. 0, // 0x0A
  531. 0, // 0x0B
  532. 0, // 0x0C VK_CLEAR
  533. KEY_RETURN, // 0x0D VK_RETURN
  534. 0, // 0x0E
  535. 0, // 0x0F
  536. KEY_SHIFT, // 0x10 VK_SHIFT
  537. KEY_CONTROL, // 0x11 VK_CONTROL
  538. KEY_ALT, // 0x12 VK_MENU
  539. KEY_PAUSE, // 0x13 VK_PAUSE
  540. KEY_CAPSLOCK, // 0x14 VK_CAPITAL
  541. 0, // 0x15 VK_KANA, VK_HANGEUL, VK_HANGUL
  542. 0, // 0x16
  543. 0, // 0x17 VK_JUNJA
  544. 0, // 0x18 VK_FINAL
  545. 0, // 0x19 VK_HANJA, VK_KANJI
  546. 0, // 0x1A
  547. KEY_ESCAPE, // 0x1B VK_ESCAPE
  548. 0, // 0x1C VK_CONVERT
  549. 0, // 0x1D VK_NONCONVERT
  550. 0, // 0x1E VK_ACCEPT
  551. 0, // 0x1F VK_MODECHANGE
  552. KEY_SPACE, // 0x20 VK_SPACE
  553. KEY_PAGE_UP, // 0x21 VK_PRIOR
  554. KEY_PAGE_DOWN, // 0x22 VK_NEXT
  555. KEY_END, // 0x23 VK_END
  556. KEY_HOME, // 0x24 VK_HOME
  557. KEY_LEFT, // 0x25 VK_LEFT
  558. KEY_UP, // 0x26 VK_UP
  559. KEY_RIGHT, // 0x27 VK_RIGHT
  560. KEY_DOWN, // 0x28 VK_DOWN
  561. 0, // 0x29 VK_SELECT
  562. KEY_PRINT, // 0x2A VK_PRINT
  563. 0, // 0x2B VK_EXECUTE
  564. 0, // 0x2C VK_SNAPSHOT
  565. KEY_INSERT, // 0x2D VK_INSERT
  566. KEY_DELETE, // 0x2E VK_DELETE
  567. KEY_HELP, // 0x2F VK_HELP
  568. KEY_0, // 0x30 VK_0 VK_0 thru VK_9 are the same as ASCII '0' thru '9' (// 0x30 - // 0x39)
  569. KEY_1, // 0x31 VK_1
  570. KEY_2, // 0x32 VK_2
  571. KEY_3, // 0x33 VK_3
  572. KEY_4, // 0x34 VK_4
  573. KEY_5, // 0x35 VK_5
  574. KEY_6, // 0x36 VK_6
  575. KEY_7, // 0x37 VK_7
  576. KEY_8, // 0x38 VK_8
  577. KEY_9, // 0x39 VK_9
  578. 0, // 0x3A
  579. 0, // 0x3B
  580. 0, // 0x3C
  581. 0, // 0x3D
  582. 0, // 0x3E
  583. 0, // 0x3F
  584. 0, // 0x40
  585. KEY_A, // 0x41 VK_A VK_A thru VK_Z are the same as ASCII 'A' thru 'Z' (// 0x41 - // 0x5A)
  586. KEY_B, // 0x42 VK_B
  587. KEY_C, // 0x43 VK_C
  588. KEY_D, // 0x44 VK_D
  589. KEY_E, // 0x45 VK_E
  590. KEY_F, // 0x46 VK_F
  591. KEY_G, // 0x47 VK_G
  592. KEY_H, // 0x48 VK_H
  593. KEY_I, // 0x49 VK_I
  594. KEY_J, // 0x4A VK_J
  595. KEY_K, // 0x4B VK_K
  596. KEY_L, // 0x4C VK_L
  597. KEY_M, // 0x4D VK_M
  598. KEY_N, // 0x4E VK_N
  599. KEY_O, // 0x4F VK_O
  600. KEY_P, // 0x50 VK_P
  601. KEY_Q, // 0x51 VK_Q
  602. KEY_R, // 0x52 VK_R
  603. KEY_S, // 0x53 VK_S
  604. KEY_T, // 0x54 VK_T
  605. KEY_U, // 0x55 VK_U
  606. KEY_V, // 0x56 VK_V
  607. KEY_W, // 0x57 VK_W
  608. KEY_X, // 0x58 VK_X
  609. KEY_Y, // 0x59 VK_Y
  610. KEY_Z, // 0x5A VK_Z
  611. KEY_WIN_LWINDOW, // 0x5B VK_LWIN
  612. KEY_WIN_RWINDOW, // 0x5C VK_RWIN
  613. KEY_WIN_APPS, // 0x5D VK_APPS
  614. 0, // 0x5E
  615. 0, // 0x5F
  616. KEY_NUMPAD0, // 0x60 VK_NUMPAD0
  617. KEY_NUMPAD1, // 0x61 VK_NUMPAD1
  618. KEY_NUMPAD2, // 0x62 VK_NUMPAD2
  619. KEY_NUMPAD3, // 0x63 VK_NUMPAD3
  620. KEY_NUMPAD4, // 0x64 VK_NUMPAD4
  621. KEY_NUMPAD5, // 0x65 VK_NUMPAD5
  622. KEY_NUMPAD6, // 0x66 VK_NUMPAD6
  623. KEY_NUMPAD7, // 0x67 VK_NUMPAD7
  624. KEY_NUMPAD8, // 0x68 VK_NUMPAD8
  625. KEY_NUMPAD9, // 0x69 VK_NUMPAD9
  626. KEY_MULTIPLY, // 0x6A VK_MULTIPLY
  627. KEY_ADD, // 0x6B VK_ADD
  628. KEY_SEPARATOR, // 0x6C VK_SEPARATOR
  629. KEY_SUBTRACT, // 0x6D VK_SUBTRACT
  630. KEY_DECIMAL, // 0x6E VK_DECIMAL
  631. KEY_DIVIDE, // 0x6F VK_DIVIDE
  632. KEY_F1, // 0x70 VK_F1
  633. KEY_F2, // 0x71 VK_F2
  634. KEY_F3, // 0x72 VK_F3
  635. KEY_F4, // 0x73 VK_F4
  636. KEY_F5, // 0x74 VK_F5
  637. KEY_F6, // 0x75 VK_F6
  638. KEY_F7, // 0x76 VK_F7
  639. KEY_F8, // 0x77 VK_F8
  640. KEY_F9, // 0x78 VK_F9
  641. KEY_F10, // 0x79 VK_F10
  642. KEY_F11, // 0x7A VK_F11
  643. KEY_F12, // 0x7B VK_F12
  644. KEY_F13, // 0x7C VK_F13
  645. KEY_F14, // 0x7D VK_F14
  646. KEY_F15, // 0x7E VK_F15
  647. KEY_F16, // 0x7F VK_F16
  648. KEY_F17, // 0x80 VK_F17
  649. KEY_F18, // 0x81 VK_F18
  650. KEY_F19, // 0x82 VK_F19
  651. KEY_F20, // 0x83 VK_F20
  652. KEY_F21, // 0x84 VK_F21
  653. KEY_F22, // 0x85 VK_F22
  654. KEY_F23, // 0x86 VK_F23
  655. KEY_F24, // 0x87 VK_F24
  656. 0, // 0x88
  657. 0, // 0x89
  658. 0, // 0x8A
  659. 0, // 0x8B
  660. 0, // 0x8C
  661. 0, // 0x8D
  662. 0, // 0x8E
  663. 0, // 0x8F
  664. KEY_NUMLOCK, // 0x90 VK_NUMLOCK
  665. KEY_SCROLLLOCK, // 0x91 VK_OEM_SCROLL
  666. 0, // 0x92
  667. 0, // 0x93
  668. 0, // 0x94
  669. 0, // 0x95
  670. 0, // 0x96
  671. 0, // 0x97
  672. 0, // 0x98
  673. 0, // 0x99
  674. 0, // 0x9A
  675. 0, // 0x9B
  676. 0, // 0x9C
  677. 0, // 0x9D
  678. 0, // 0x9E
  679. 0, // 0x9F
  680. KEY_LSHIFT, // 0xA0 VK_LSHIFT
  681. KEY_RSHIFT, // 0xA1 VK_RSHIFT
  682. KEY_LCONTROL, // 0xA2 VK_LCONTROL
  683. KEY_RCONTROL, // 0xA3 VK_RCONTROL
  684. KEY_LALT, // 0xA4 VK_LMENU
  685. KEY_RALT, // 0xA5 VK_RMENU
  686. 0, // 0xA6
  687. 0, // 0xA7
  688. 0, // 0xA8
  689. 0, // 0xA9
  690. 0, // 0xAA
  691. 0, // 0xAB
  692. 0, // 0xAC
  693. 0, // 0xAD
  694. 0, // 0xAE
  695. 0, // 0xAF
  696. 0, // 0xB0
  697. 0, // 0xB1
  698. 0, // 0xB2
  699. 0, // 0xB3
  700. 0, // 0xB4
  701. 0, // 0xB5
  702. 0, // 0xB6
  703. 0, // 0xB7
  704. 0, // 0xB8
  705. 0, // 0xB9
  706. KEY_SEMICOLON, // 0xBA VK_OEM_1
  707. KEY_EQUALS, // 0xBB VK_OEM_PLUS
  708. KEY_COMMA, // 0xBC VK_OEM_COMMA
  709. KEY_MINUS, // 0xBD VK_OEM_MINUS
  710. KEY_PERIOD, // 0xBE VK_OEM_PERIOD
  711. KEY_SLASH, // 0xBF VK_OEM_2
  712. KEY_TILDE, // 0xC0 VK_OEM_3
  713. 0, // 0xC1
  714. 0, // 0xC2
  715. 0, // 0xC3
  716. 0, // 0xC4
  717. 0, // 0xC5
  718. 0, // 0xC6
  719. 0, // 0xC7
  720. 0, // 0xC8
  721. 0, // 0xC9
  722. 0, // 0xCA
  723. 0, // 0xCB
  724. 0, // 0xCC
  725. 0, // 0xCD
  726. 0, // 0xCE
  727. 0, // 0xCF
  728. 0, // 0xD0
  729. 0, // 0xD1
  730. 0, // 0xD2
  731. 0, // 0xD3
  732. 0, // 0xD4
  733. 0, // 0xD5
  734. 0, // 0xD6
  735. 0, // 0xD7
  736. 0, // 0xD8
  737. 0, // 0xD9
  738. 0, // 0xDA
  739. KEY_LBRACKET, // 0xDB VK_OEM_4
  740. KEY_BACKSLASH, // 0xDC VK_OEM_5
  741. KEY_RBRACKET, // 0xDD VK_OEM_6
  742. KEY_APOSTROPHE, // 0xDE VK_OEM_7
  743. 0, // 0xDF VK_OEM_8
  744. 0, // 0xE0
  745. 0, // 0xE1 VK_OEM_AX AX key on Japanese AX keyboard
  746. KEY_OEM_102, // 0xE2 VK_OEM_102
  747. 0, // 0xE3
  748. 0, // 0xE4
  749. 0, // 0xE5 VK_PROCESSKEY
  750. 0, // 0xE6
  751. 0, // 0xE7
  752. 0, // 0xE8
  753. 0, // 0xE9
  754. 0, // 0xEA
  755. 0, // 0xEB
  756. 0, // 0xEC
  757. 0, // 0xED
  758. 0, // 0xEE
  759. 0, // 0xEF
  760. 0, // 0xF0
  761. 0, // 0xF1
  762. 0, // 0xF2
  763. 0, // 0xF3
  764. 0, // 0xF4
  765. 0, // 0xF5
  766. 0, // 0xF6 VK_ATTN
  767. 0, // 0xF7 VK_CRSEL
  768. 0, // 0xF8 VK_EXSEL
  769. 0, // 0xF9 VK_EREOF
  770. 0, // 0xFA VK_PLAY
  771. 0, // 0xFB VK_ZOOM
  772. 0, // 0xFC VK_NONAME
  773. 0, // 0xFD VK_PA1
  774. 0, // 0xFE VK_OEM_CLEAR
  775. 0 // 0xFF
  776. };
  777. //------------------------------------------------------------------------------
  778. //
  779. // This function translates a virtual key code to our corresponding internal
  780. // key code using the preceding table.
  781. //
  782. //------------------------------------------------------------------------------
  783. U8 TranslateOSKeyCode(U8 vcode)
  784. {
  785. return VcodeRemap[vcode];
  786. }
  787. //-----------------------------------------------------------------------------
  788. // Clipboard functions
  789. const char* Platform::getClipboard()
  790. {
  791. HGLOBAL hGlobal;
  792. LPVOID pGlobal;
  793. //make sure we can access the clipboard
  794. if (!IsClipboardFormatAvailable(CF_TEXT))
  795. return "";
  796. if (!OpenClipboard(NULL))
  797. return "";
  798. hGlobal = GetClipboardData(CF_TEXT);
  799. pGlobal = GlobalLock(hGlobal);
  800. S32 cbLength = strlen((char *)pGlobal);
  801. char *returnBuf = Con::getReturnBuffer(cbLength + 1);
  802. strcpy(returnBuf, (char *)pGlobal);
  803. returnBuf[cbLength] = '\0';
  804. GlobalUnlock(hGlobal);
  805. CloseClipboard();
  806. //note - this function never returns NULL
  807. return returnBuf;
  808. }
  809. //-----------------------------------------------------------------------------
  810. bool Platform::setClipboard(const char *text)
  811. {
  812. if (!text)
  813. return false;
  814. //make sure we can access the clipboard
  815. if (!OpenClipboard(NULL))
  816. return false;
  817. S32 cbLength = strlen(text);
  818. HGLOBAL hGlobal;
  819. LPVOID pGlobal;
  820. hGlobal = GlobalAlloc(GHND, cbLength + 1);
  821. pGlobal = GlobalLock (hGlobal);
  822. strcpy((char *)pGlobal, text);
  823. GlobalUnlock(hGlobal);
  824. EmptyClipboard();
  825. SetClipboardData(CF_TEXT, hGlobal);
  826. CloseClipboard();
  827. return true;
  828. }