winInput.cc 31 KB

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