OMOUSESP.cpp 45 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626
  1. /*
  2. * Seven Kingdoms: Ancient Adversaries
  3. *
  4. * Copyright 1997,1998 Enlight Software Ltd.
  5. *
  6. * This program is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 2 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  18. *
  19. */
  20. //Filename : OMOUSE.CPP
  21. //Description : Mouse handling Object
  22. #if(defined(SPANISH))
  23. #include <ALL.h>
  24. #include <OSYS.h>
  25. #include <OVGA.h>
  26. #include <OPOWER.h>
  27. #include <OMOUSE.h>
  28. #include <OMOUSECR.h>
  29. #include <OMOUSE2.h>
  30. #include <KEY.h>
  31. #include <OVGALOCK.h>
  32. #ifdef WIN32
  33. #include <cctype>
  34. #endif
  35. //--- define the size of a buffer for real-time vga screen updating ---//
  36. #define VGA_UPDATE_BUF_SIZE (100*100) // 100 x 100
  37. //--------- Define Click Threshold -----------//
  38. //
  39. // Clock tick is incremented 1000 times per second or once per millisecond.
  40. //
  41. // The minimum time interval between consequent mouse click is set to
  42. // = 0.3 seconds
  43. //
  44. //--------------------------------------------//
  45. static DWORD click_threshold = (LONG)(0.3 * 1000);
  46. //------- Define static functions -----------//
  47. LRESULT CALLBACK key_hook_proc(int nCode, WORD wParam, LONG lParam);
  48. // static unsigned translate_key(unsigned scanCode, unsigned short skeyState);
  49. //------- define constant --------//
  50. #define MOUSE_BUFFER_SIZE 100
  51. #define KEYB_BUFFER_SIZE 16
  52. #define DOUBLE_SPEED_THREHOLD 8
  53. //------- define static storage -----------//
  54. static DIDEVICEOBJECTDATA mouse_data[MOUSE_BUFFER_SIZE];
  55. static DIDEVICEOBJECTDATA keyb_data[KEYB_BUFFER_SIZE];
  56. static int update_x1, update_y1, update_x2, update_y2; // coordination of the last double-buffer update area
  57. //--------- Start of Mouse::Mouse ---------//
  58. //
  59. Mouse::Mouse()
  60. {
  61. memset( this, 0, sizeof(Mouse) );
  62. double_speed_threshold = DEFAULT_DOUBLE_SPEED_THRESHOLD;
  63. triple_speed_threshold = DEFAULT_TRIPLE_SPEED_THRESHOLD;
  64. }
  65. //---------- End of Mouse::Mouse ---------//
  66. //---------- Begin of Mouse::~Mouse --------//
  67. //
  68. // Deinitialize the mouse driver, reset event handler
  69. //
  70. Mouse::~Mouse()
  71. {
  72. deinit();
  73. }
  74. //------------ End of Mouse::~Mouse --------//
  75. //------------ Start of Mouse::init ------------//
  76. //
  77. void Mouse::init(HINSTANCE hinst, HWND hwnd, LPDIRECTINPUT createdDirectInput)
  78. {
  79. //-------- set starting position ---------//
  80. POINT pt;
  81. GetCursorPos(&pt);
  82. cur_x = pt.x;
  83. cur_y = pt.y;
  84. /*
  85. //------ install keyboard hook ---------//
  86. key_hook_handle = SetWindowsHookEx(WH_KEYBOARD, (HOOKPROC) key_hook_proc, sys.app_hinstance, NULL);
  87. if( !key_hook_handle )
  88. err.run( "Failed installing keyboard hook." );
  89. */
  90. //-------- initialize DirectInput Mouse device--------//
  91. /*
  92. direct_mouse_handle = DMouseOpen();
  93. if( !direct_mouse_handle )
  94. err.run( "Failed installing direct mouse." );
  95. */
  96. HRESULT hr;
  97. if( createdDirectInput )
  98. {
  99. direct_input = createdDirectInput;
  100. hr = direct_input->AddRef();
  101. }
  102. else
  103. {
  104. hr = DirectInputCreate(hinst, DIRECTINPUT_VERSION, &direct_input, NULL);
  105. }
  106. if(hr)
  107. err.run( "Failed creating DirectInput");
  108. // ####### begin Gilbert 12/9 #######//
  109. {
  110. VgaFrontLock vgaLock;
  111. hr = direct_input->CreateDevice(GUID_SysMouse,&di_mouse_device,NULL);
  112. }
  113. // ####### end Gilbert 12/9 #######//
  114. if(hr)
  115. err.run( "Failed creating mouse interface from DirectInput");
  116. // ------- set cooperative level --------//
  117. hr = di_mouse_device->SetCooperativeLevel(hwnd, DISCL_FOREGROUND | DISCL_EXCLUSIVE);
  118. // ------- set data format ---------//
  119. if(!hr)
  120. hr = di_mouse_device->SetDataFormat(&c_dfDIMouse);
  121. // ------- set relative coordinate mode --------//
  122. // DirectInput default is relative
  123. if(!hr)
  124. {
  125. DIPROPDWORD propDword;
  126. propDword.diph.dwSize = sizeof(DIPROPDWORD);
  127. propDword.diph.dwHeaderSize = sizeof(DIPROPHEADER);
  128. propDword.diph.dwHow = DIPH_DEVICE; // Entire device
  129. propDword.diph.dwObj = 0; // Entire device, so zero
  130. propDword.dwData = DIPROPAXISMODE_REL;
  131. hr = di_mouse_device->SetProperty(DIPROP_AXISMODE, &propDword.diph);
  132. }
  133. // ------- set buffer size --------//
  134. if(!hr)
  135. {
  136. DIPROPDWORD propDword;
  137. propDword.diph.dwSize = sizeof(DIPROPDWORD);
  138. propDword.diph.dwHeaderSize = sizeof(DIPROPHEADER);
  139. propDword.diph.dwHow = DIPH_DEVICE; // Entire device
  140. propDword.diph.dwObj = 0; // Entire device, so zero
  141. propDword.dwData = MOUSE_BUFFER_SIZE * sizeof(DIDEVICEOBJECTDATA);
  142. hr = di_mouse_device->SetProperty(DIPROP_BUFFERSIZE, &propDword.diph);
  143. }
  144. if(hr)
  145. err.run( "Failed initializing mouse interface");
  146. // ------- create direct input keyboard interface --------- //
  147. // ####### begin Gilbert 12/9 #######//
  148. {
  149. VgaFrontLock vgaLock;
  150. hr = direct_input->CreateDevice(GUID_SysKeyboard,&di_keyb_device,NULL);
  151. }
  152. // ####### end Gilbert 12/9 #######//
  153. if(hr)
  154. err.run( "Failed creating keyboard interface from DirectInput");
  155. // ------- set cooperative level --------//
  156. hr = di_keyb_device->SetCooperativeLevel(hwnd, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE);
  157. // ------- set data format ---------//
  158. if(!hr)
  159. hr = di_keyb_device->SetDataFormat(&c_dfDIKeyboard);
  160. // ------- set buffer size --------//
  161. if(!hr)
  162. {
  163. DIPROPDWORD propDword;
  164. propDword.diph.dwSize = sizeof(DIPROPDWORD);
  165. propDword.diph.dwHeaderSize = sizeof(DIPROPHEADER);
  166. propDword.diph.dwHow = DIPH_DEVICE; // Entire device
  167. propDword.diph.dwObj = 0; // Entire device, so zero
  168. propDword.dwData = KEYB_BUFFER_SIZE * sizeof(DIDEVICEOBJECTDATA);
  169. hr = di_keyb_device->SetProperty(DIPROP_BUFFERSIZE, &propDword.diph);
  170. }
  171. if(hr)
  172. err.run( "Failed initializing keyboard interface");
  173. // ------- get initial keyboard state ----------//
  174. skey_state = 0;
  175. if(GetKeyState(VK_LSHIFT) < 0)
  176. skey_state |= LEFT_SHIFT_KEY_MASK;
  177. if(GetKeyState(VK_RSHIFT) < 0)
  178. skey_state |= RIGHT_SHIFT_KEY_MASK;
  179. if(GetKeyState(VK_LCONTROL) < 0)
  180. skey_state |= LEFT_CONTROL_KEY_MASK;
  181. if(GetKeyState(VK_RCONTROL) < 0)
  182. skey_state |= RIGHT_CONTROL_KEY_MASK;
  183. if(GetKeyState(VK_LMENU) < 0)
  184. skey_state |= LEFT_ALT_KEY_MASK;
  185. if(GetKeyState(VK_RMENU) < 0)
  186. skey_state |= GRAPH_KEY_MASK;
  187. if(GetKeyState(VK_NUMLOCK) & 1)
  188. skey_state |= NUM_LOCK_STATE_MASK;
  189. if(GetKeyState(VK_CAPITAL) & 1)
  190. skey_state |= CAP_LOCK_STATE_MASK;
  191. if(GetKeyState(VK_SCROLL) & 1)
  192. skey_state |= SCROLL_LOCK_STATE_MASK;
  193. skey_state |= INSERT_STATE_MASK; // enable insert mode by default
  194. //------- initialize VGA update buffer -------//
  195. vga_update_buf = mem_add( VGA_UPDATE_BUF_SIZE );
  196. // ------ initialize mouse boundary ---------//
  197. reset_boundary();
  198. // ------- initialize event queue ---------//
  199. head_ptr = tail_ptr = 0;
  200. //--------------------------------------------//
  201. init_flag = 1;
  202. }
  203. //------------- End of Mouse::init -------------//
  204. //------------ Start of Mouse::deinit ------------//
  205. //
  206. void Mouse::deinit()
  207. {
  208. if( init_flag )
  209. {
  210. // UnhookWindowsHookEx(key_hook_handle);
  211. // DMouseClose(direct_mouse_handle);
  212. init_flag = 0;
  213. }
  214. if( vga_update_buf )
  215. {
  216. mem_del(vga_update_buf);
  217. vga_update_buf = NULL;
  218. }
  219. if( di_keyb_device )
  220. {
  221. di_keyb_device->Unacquire();
  222. di_keyb_device->Release();
  223. di_keyb_device = NULL;
  224. }
  225. if( di_mouse_device )
  226. {
  227. di_mouse_device->Unacquire();
  228. di_mouse_device->Release();
  229. di_mouse_device = NULL;
  230. }
  231. if( direct_input )
  232. {
  233. direct_input->Release();
  234. direct_input = NULL;
  235. }
  236. }
  237. //------------- End of Mouse::deinit -------------//
  238. //--------- Start of Mouse::hide -------//
  239. //
  240. // Suspend the mouse function, use resume() to resume to function
  241. //
  242. void Mouse::hide()
  243. {
  244. mouse_cursor.hide_all_flag=1;
  245. mouse_cursor.process(cur_x, cur_y);
  246. }
  247. //---------- End of Mouse::hide --------//
  248. //--------- Start of Mouse::show -------//
  249. //
  250. // Resume the mouse function which is previously hideed by hide()
  251. //
  252. void Mouse::show()
  253. {
  254. mouse_cursor.hide_all_flag=0;
  255. mouse_cursor.process(cur_x, cur_y);
  256. }
  257. //---------- End of Mouse::show --------//
  258. //--------- Begin of Mouse::hide_area ----------//
  259. //
  260. void Mouse::hide_area(int x1, int y1, int x2, int y2)
  261. {
  262. mouse_cursor.hide_area_flag++;
  263. if( mouse_cursor.hide_area_flag!=1 ) // only process for the first call of hide_area()
  264. return;
  265. mouse_cursor.hide_x1 = x1;
  266. mouse_cursor.hide_y1 = y1;
  267. mouse_cursor.hide_x2 = x2;
  268. mouse_cursor.hide_y2 = y2;
  269. int curX = cur_x - mouse_cursor.hot_spot_x;
  270. int curY = cur_y - mouse_cursor.hot_spot_y;
  271. if( m.is_touch( x1, y1, x2, y2, curX, curY,
  272. curX+mouse_cursor.icon_width-1,
  273. curY+mouse_cursor.icon_height-1 ) )
  274. {
  275. if( handle_flicking )
  276. {
  277. update_x1 = min(x1, curX);
  278. update_y1 = min(y1, curY);
  279. update_x2 = max(x2, curX+mouse_cursor.icon_width-1);
  280. update_y2 = max(y2, curY+mouse_cursor.icon_height-1);
  281. update_x1 = max(0, update_x1);
  282. update_y1 = max(0, update_y1);
  283. update_x2 = min(VGA_WIDTH-1 , update_x2);
  284. update_y2 = min(VGA_HEIGHT-1, update_y2);
  285. err_when( (update_x2-update_x1+1) * (update_y2-update_y1+1) > VGA_UPDATE_BUF_SIZE );
  286. //---- save the update area of the back buf to a temp buffer ----//
  287. vga_back.read_bitmap( update_x1, update_y1, update_x2, update_y2, vga_update_buf );
  288. //--- copy the update area from the front buf to the back buf ---//
  289. IMGcopy( vga_back.buf_ptr(), vga_back.buf_pitch(), vga_front.buf_ptr(), vga_front.buf_pitch(),
  290. update_x1, update_y1, update_x2, update_y2 );
  291. //-- redirect the front VGA buffer pointer to the back VGA buffer --//
  292. vga_front.set_buf_ptr( vga_back.buf_ptr() );
  293. }
  294. //------ hide up the mouse cursor --------//
  295. mouse_cursor.process(cur_x, cur_y);
  296. }
  297. }
  298. //--------- End of Mouse::hide_area --------------//
  299. //--------- Begin of Mouse::show_area ----------//
  300. //
  301. void Mouse::show_area()
  302. {
  303. mouse_cursor.hide_area_flag--;
  304. if( mouse_cursor.hide_area_flag!=0 ) // only process for the first call of hide_area()
  305. return;
  306. int curX = cur_x - mouse_cursor.hot_spot_x;
  307. int curY = cur_y - mouse_cursor.hot_spot_y;
  308. if( m.is_touch( mouse_cursor.hide_x1, mouse_cursor.hide_y1,
  309. mouse_cursor.hide_x2, mouse_cursor.hide_y2,
  310. curX, curY, curX+mouse_cursor.icon_width-1,
  311. curY+mouse_cursor.icon_height-1 ) )
  312. {
  313. //----- redisplay the mouse cursor ------//
  314. mouse_cursor.process(cur_x, cur_y);
  315. if( handle_flicking )
  316. {
  317. //--- copy the update area from the back buf to the front buf ---//
  318. IMGcopy( vga_front.buf_ptr(), vga_front.buf_pitch(), vga_back.buf_ptr(), vga_back.buf_pitch(),
  319. update_x1, update_y1, update_x2, update_y2 );
  320. //--- restore the update area of the back buf with the temp buffer ---//
  321. vga_back.fast_put_bitmap( update_x1, update_y1, vga_update_buf );
  322. //--- restore the VGA front buffer's buf ptr ---//
  323. vga_front.set_default_buf_ptr();
  324. }
  325. }
  326. }
  327. //--------- End of Mouse::show_area --------------//
  328. //--------- Start of Mouse::add_event ---------//
  329. //
  330. // Called by handler interrupt to procss the state
  331. //
  332. void Mouse::add_event(MouseEvent *mouseEvent)
  333. {
  334. //---- call the game object to see if the mouse cursor icon needs to be changed, or if the nation selection square needs to be activated ----//
  335. power.mouse_handler();
  336. //--------- update the mouse cursor ----------//
  337. mouse_cursor.process(cur_x, cur_y); // repaint mouse cursor
  338. //-------- save state into the event queue --------//
  339. if((head_ptr == tail_ptr-1) || // see if the buffer is full
  340. (head_ptr == EVENT_BUFFER_SIZE-1 && tail_ptr == 0))
  341. {
  342. return;
  343. }
  344. event_buffer[head_ptr] = *mouseEvent;
  345. if(++head_ptr >= EVENT_BUFFER_SIZE) // increment the head ptr
  346. head_ptr = 0;
  347. }
  348. //----------- End of Mouse::add_event ----------//
  349. //--------- Start of Mouse::add_key_event ---------//
  350. //
  351. // Called by key handler to save the key pressed
  352. //
  353. void Mouse::add_key_event(unsigned scanCode, DWORD timeStamp)
  354. {
  355. if((head_ptr == tail_ptr-1) || // see if the buffer is full
  356. (head_ptr == EVENT_BUFFER_SIZE-1 && tail_ptr == 0))
  357. {
  358. return;
  359. }
  360. MouseEvent *ev = event_buffer + head_ptr;
  361. ev->event_type = KEY_PRESS;
  362. ev->scan_code = scanCode;
  363. ev->skey_state = skey_state;
  364. ev->time = timeStamp;
  365. // put mouse state
  366. // ev->state = 0; //ev->state = left_press | right_press;
  367. ev->x = cur_x;
  368. ev->y = cur_y;
  369. if(++head_ptr >= EVENT_BUFFER_SIZE) // increment the head ptr
  370. head_ptr = 0;
  371. }
  372. //----------- End of Mouse::add_key_event ----------//
  373. //--------- Start of Mouse::get_event ---------//
  374. //
  375. // Get next event from the event buffer
  376. //
  377. // return : <int> 1 - event fetched from the event queue
  378. // 0 - not event remained in the buffer
  379. //
  380. // to know what type of event :
  381. // 1. check is_mouse_event() or is_key_event()
  382. // 2. if is_mouse_event(), check mouse_event_type
  383. // if( LEFT_BUTTON or LEFT_BUTTON_RELEASE, read click_buffer[LEFT_BUTTON]
  384. // if( RIGHT_BUTTON or RIGHT_BUTTON_RELEASE, read click_buffer[RIGHT_BUTTON]
  385. // 3. if is_key_event(), check event_skey_state, scan_code and key_code
  386. //
  387. int Mouse::get_event()
  388. {
  389. if(head_ptr == tail_ptr) // no event queue left in the buffer
  390. {
  391. scan_code =0; // no keyboard event
  392. key_code =0;
  393. has_mouse_event=0; // no mouse event
  394. return 0;
  395. }
  396. //--------- get event from queue ---------//
  397. MouseEvent* eptr = event_buffer + tail_ptr;
  398. MouseClick* cptr;
  399. event_skey_state = eptr->skey_state;
  400. mouse_event_type = eptr->event_type;
  401. switch( eptr->event_type )
  402. {
  403. case LEFT_BUTTON:
  404. case RIGHT_BUTTON:
  405. // set count of other button to zero
  406. click_buffer[LEFT_BUTTON+RIGHT_BUTTON-eptr->event_type].count = 0;
  407. cptr = click_buffer + eptr->event_type;
  408. if( //eptr->event_type == LEFT_BUTTON && // left button has double click
  409. eptr->time - cptr->time < click_threshold )
  410. cptr->count++;
  411. else
  412. cptr->count = 1;
  413. cptr->time = eptr->time;
  414. cptr->x = eptr->x;
  415. cptr->y = eptr->y;
  416. scan_code = 0;
  417. key_code = 0;
  418. has_mouse_event = 1;
  419. break;
  420. case KEY_PRESS:
  421. scan_code = eptr->scan_code;
  422. key_code = mouse.is_key(mouse.scan_code, mouse.event_skey_state, (WORD) 0, K_CHAR_KEY);
  423. has_mouse_event = 0;
  424. break;
  425. case LEFT_BUTTON_RELEASE:
  426. case RIGHT_BUTTON_RELEASE:
  427. cptr = click_buffer + eptr->event_type - LEFT_BUTTON_RELEASE;
  428. cptr->release_time = eptr->time;
  429. cptr->release_x = eptr->x;
  430. cptr->release_y = eptr->y;
  431. scan_code = 0;
  432. key_code = 0;
  433. has_mouse_event = 1;
  434. break;
  435. case KEY_RELEASE:
  436. // no action
  437. break;
  438. default:
  439. err_here();
  440. }
  441. if(++tail_ptr >= EVENT_BUFFER_SIZE)
  442. tail_ptr = 0;
  443. return 1;
  444. }
  445. //----------- End of Mouse::get_event ----------//
  446. //--------- Begin of Mouse::in_area ----------//
  447. //
  448. // <Real-time access>
  449. //
  450. // Detect whether mouse cursor is in the specified area
  451. //
  452. // <int> x1,y1,x2,y2 = the coordinations of the area
  453. //
  454. // Return : 1 - if the mouse cursor is in the area
  455. // 0 - if not
  456. //
  457. int Mouse::in_area(int x1, int y1, int x2, int y2)
  458. {
  459. return( cur_x >= x1 && cur_y >= y1 && cur_x <= x2 && cur_y <= y2 );
  460. }
  461. //--------- End of Mouse::in_area --------------//
  462. //--------- Begin of Mouse::press_area ----------//
  463. //
  464. // <Real-time access>
  465. //
  466. // Detect whether the specified area has been pressed by mouse
  467. //
  468. // <int> x1,y1,x2,y2 = the coordinations of the area
  469. // <int> buttonId = which button ( 0=left, 1-right, 2-left or right )
  470. //
  471. // Return : 1 - if the area has been pressed (left button)
  472. // 1 - if the area has been pressed (right button)
  473. // 0 - if not
  474. //
  475. int Mouse::press_area(int x1, int y1, int x2, int y2, int buttonId)
  476. {
  477. if( cur_x >= x1 && cur_y >= y1 && cur_x <= x2 && cur_y <= y2 )
  478. {
  479. if( left_press && (buttonId==0 || buttonId==2) ) // Left button
  480. return 1;
  481. if( right_press && (buttonId==1 || buttonId==2) ) // Right button
  482. return 2;
  483. }
  484. return 0;
  485. }
  486. //--------- End of Mouse::press_area --------------//
  487. //--------- Begin of Mouse::set_boundary ----------//
  488. //
  489. // for each parameter, put -1 to mean unchange
  490. //
  491. void Mouse::set_boundary(int x1, int y1, int x2, int y2)
  492. {
  493. if( x1 >= 0)
  494. bound_x1 = x1;
  495. if( y1 >= 0)
  496. bound_y1 = y1;
  497. if( x2 >= 0)
  498. bound_x2 = x2 > MOUSE_X_UPPER_LIMIT ? MOUSE_X_UPPER_LIMIT : x2;
  499. if( y2 >= 0)
  500. bound_y2 = y2 > MOUSE_Y_UPPER_LIMIT ? MOUSE_Y_UPPER_LIMIT : y2;
  501. }
  502. //--------- End of Mouse::set_boundary ----------//
  503. //--------- Begin of Mouse::reset_boundary ----------//
  504. void Mouse::reset_boundary()
  505. {
  506. bound_x1 = 0;
  507. bound_y1 = 0;
  508. bound_x2 = MOUSE_X_UPPER_LIMIT;
  509. bound_y2 = MOUSE_Y_UPPER_LIMIT;
  510. }
  511. //--------- End of Mouse::set_boundary ----------//
  512. //--------- Begin of Mouse::single_click ----------//
  513. //
  514. // <Event queue access>
  515. //
  516. // Detect whether the specified area has been single clicked by mouse
  517. //
  518. // <int> x1,y1,x2,y2 = the coordinations of the area
  519. // [int] buttonId = which button ( 0=left, 1-right, 2-both)
  520. // (default:0)
  521. //
  522. // Return : 1 - if the area has been clicked (left click)
  523. // 2 - if the area has been clicked (right click)
  524. // 0 - if not
  525. //
  526. int Mouse::single_click(int x1, int y1, int x2, int y2,int buttonId)
  527. {
  528. if( !has_mouse_event )
  529. return 0;
  530. MouseClick* cptr;
  531. if( buttonId==0 || buttonId==2 ) // left button
  532. {
  533. cptr = click_buffer+LEFT_BUTTON;
  534. if( mouse_event_type == LEFT_BUTTON
  535. && cptr->count == 1
  536. && cptr->x >= x1 && cptr->y >= y1
  537. && cptr->x <= x2 && cptr->y <= y2 )
  538. {
  539. return 1;
  540. }
  541. }
  542. if( buttonId==1 || buttonId==2 ) // right button
  543. {
  544. cptr = click_buffer+RIGHT_BUTTON;
  545. if( mouse_event_type == RIGHT_BUTTON
  546. && cptr->count == 1
  547. && cptr->x >= x1 && cptr->y >= y1
  548. && cptr->x <= x2 && cptr->y <= y2 )
  549. {
  550. return 2;
  551. }
  552. }
  553. return 0;
  554. }
  555. //--------- End of Mouse::single_click --------------//
  556. //--------- Begin of Mouse::double_click ----------//
  557. //
  558. // <Event queue access>
  559. //
  560. // Detect whether the specified area has been double clicked by mouse
  561. //
  562. // Note : when a mouse double click, it will FIRST generate a SINGLE
  563. // click signal and then a DOUBLE click signal.
  564. // Because a double click is consisted of two single click
  565. //
  566. // <int> x1,y1,x2,y2 = the coordinations of the area
  567. // [int] buttonId = which button ( 0=left, 1-right, 2-left or right)
  568. // (default:0)
  569. //
  570. // Return : 1 - if the area has been clicked
  571. // 0 - if not
  572. //
  573. int Mouse::double_click(int x1, int y1, int x2, int y2,int buttonId)
  574. {
  575. if( !has_mouse_event )
  576. return 0;
  577. MouseClick* cptr;
  578. if( buttonId==0 || buttonId==2 ) // left button
  579. {
  580. cptr = click_buffer+LEFT_BUTTON;
  581. if( mouse_event_type == LEFT_BUTTON
  582. && cptr->count == 2
  583. && cptr->x >= x1 && cptr->y >= y1
  584. && cptr->x <= x2 && cptr->y <= y2 )
  585. {
  586. return 1;
  587. }
  588. }
  589. if( buttonId==1 || buttonId==2 ) // right button
  590. {
  591. cptr = click_buffer+RIGHT_BUTTON;
  592. if( mouse_event_type == RIGHT_BUTTON
  593. && cptr->count == 2
  594. && cptr->x >= x1 && cptr->y >= y1
  595. && cptr->x <= x2 && cptr->y <= y2 )
  596. {
  597. return 1;
  598. }
  599. }
  600. return 0;
  601. }
  602. //--------- End of Mouse::double_click --------------//
  603. //--------- Begin of Mouse::any_click ----------//
  604. //
  605. // <Event queue access>
  606. //
  607. // Detect whether the specified area has been single or double clicked by mouse
  608. //
  609. // <int> x1,y1,x2,y2 = the coordinations of the area
  610. // [int] buttonId = which button ( 0=left, 1-right, 2-left or right)
  611. // (default:0)
  612. //
  613. // Return : >0 - the no. of click if the area has been clicked
  614. // 0 - if not
  615. //
  616. int Mouse::any_click(int x1, int y1, int x2, int y2,int buttonId)
  617. {
  618. if( !has_mouse_event )
  619. return 0;
  620. MouseClick* cptr;
  621. if( buttonId==0 || buttonId==2 ) // left button
  622. {
  623. cptr = click_buffer+LEFT_BUTTON;
  624. if( mouse_event_type == LEFT_BUTTON
  625. && cptr->count >= 1
  626. && cptr->x >= x1 && cptr->y >= y1
  627. && cptr->x <= x2 && cptr->y <= y2 )
  628. {
  629. return cptr->count;
  630. }
  631. }
  632. if( buttonId==1 || buttonId==2 ) // right button
  633. {
  634. cptr = click_buffer+RIGHT_BUTTON;
  635. if( mouse_event_type == RIGHT_BUTTON
  636. && cptr->count >= 1
  637. && cptr->x >= x1 && cptr->y >= y1
  638. && cptr->x <= x2 && cptr->y <= y2 )
  639. {
  640. return cptr->count;
  641. }
  642. }
  643. return 0;
  644. }
  645. //--------- End of Mouse::any_click --------------//
  646. //--------- Begin of Mouse::any_click ----------//
  647. //
  648. // <Event queue access>
  649. //
  650. // Detect whether the specified area has been single or double clicked by mouse
  651. // Only check button, don't check mouse coordination
  652. //
  653. // [int] buttonId = which button ( 0=left, 1-right, 2-left or right)
  654. // (default:0)
  655. //
  656. // Return : >0 - the no. of click if the area has been clicked
  657. // 0 - if not
  658. //
  659. int Mouse::any_click(int buttonId)
  660. {
  661. if( !has_mouse_event )
  662. return 0;
  663. MouseClick* cptr;
  664. if( buttonId==0 || buttonId==2 ) // left button
  665. {
  666. cptr = click_buffer+LEFT_BUTTON;
  667. if( mouse_event_type == LEFT_BUTTON && cptr->count >= 1 )
  668. return cptr->count;
  669. }
  670. if( buttonId==1 || buttonId==2 ) // right button
  671. {
  672. cptr = click_buffer+RIGHT_BUTTON;
  673. if( mouse_event_type == RIGHT_BUTTON && cptr->count >= 1 )
  674. return cptr->count;
  675. }
  676. return 0;
  677. }
  678. //--------- End of Mouse::any_click --------------//
  679. //--------- Begin of Mouse::release_click ----------//
  680. //
  681. // <Event queue access>
  682. //
  683. // Detect whether the specified area has been released button by mouse
  684. //
  685. // <int> x1,y1,x2,y2 = the coordinations of the area
  686. // [int] buttonId = which button ( 0=left, 1-right, 2-both)
  687. // (default:0)
  688. //
  689. // Return : 1 - if the area has been clicked (left click)
  690. // 2 - if the area has been clicked (right click)
  691. // 0 - if not
  692. //
  693. int Mouse::release_click(int x1, int y1, int x2, int y2,int buttonId)
  694. {
  695. if( !has_mouse_event )
  696. return 0;
  697. MouseClick* cptr;
  698. if( buttonId==0 || buttonId==2 ) // left button
  699. {
  700. cptr = click_buffer+LEFT_BUTTON;
  701. if( mouse_event_type == LEFT_BUTTON_RELEASE
  702. && cptr->release_x >= x1 && cptr->release_y >= y1
  703. && cptr->release_x <= x2 && cptr->release_y <= y2 )
  704. {
  705. return 1;
  706. }
  707. }
  708. if( buttonId==1 || buttonId==2 ) // right button
  709. {
  710. cptr = click_buffer+RIGHT_BUTTON;
  711. if( mouse_event_type == RIGHT_BUTTON_RELEASE
  712. && cptr->release_x >= x1 && cptr->release_y >= y1
  713. && cptr->release_x <= x2 && cptr->release_y <= y2 )
  714. {
  715. return 2;
  716. }
  717. }
  718. return 0;
  719. }
  720. //--------- End of Mouse::release_click --------------//
  721. //------- Begin of function key_hook_proc --------//
  722. LRESULT CALLBACK key_hook_proc(int nCode, WORD wParam, LONG lParam)
  723. {
  724. if (nCode >= 0)
  725. mouse.add_key_event(wParam, m.get_time());
  726. return CallNextHookEx(mouse.key_hook_handle, nCode, wParam, lParam);
  727. }
  728. //-------- End of function key_hook_proc --------//
  729. //--------- Begin of Mouse::poll_event ----------//
  730. //
  731. // Poll mouse events from the direct mouse VXD.
  732. //
  733. void Mouse::poll_event()
  734. {
  735. if(!init_flag)
  736. return;
  737. // ---- acquire mouse device and count the message queued ----//
  738. HRESULT hr;
  739. if( (hr = di_mouse_device->Acquire()) != DI_OK && hr != S_FALSE)
  740. return;
  741. if( (hr = di_keyb_device->Acquire()) != DI_OK && hr != S_FALSE)
  742. return;
  743. // HRESULT hr;
  744. DWORD mouseLen, keybLen;
  745. int moveFlag = 0;
  746. while( 1 )
  747. {
  748. mouseLen = MOUSE_BUFFER_SIZE;
  749. keybLen = KEYB_BUFFER_SIZE;
  750. if( (hr = di_mouse_device->GetDeviceData( sizeof(DIDEVICEOBJECTDATA),
  751. mouse_data, &mouseLen, 0)) != DI_OK && hr != S_FALSE )
  752. mouseLen = 0;
  753. if( (hr = di_keyb_device->GetDeviceData( sizeof(DIDEVICEOBJECTDATA),
  754. keyb_data, &keybLen, 0)) != DI_OK && hr != S_FALSE)
  755. keybLen = 0;
  756. if( !mouseLen && !keybLen )
  757. break;
  758. DIDEVICEOBJECTDATA *mouseMsg = mouse_data, *keybMsg = keyb_data;
  759. while( mouseLen > 0 || keybLen > 0)
  760. {
  761. // merge mouse event and keyboard event
  762. MouseEvent ev;
  763. int earlyDevice = 0; // 1 = mouse, 2 = keyboard
  764. if( mouseLen > 0 && keybLen > 0 )
  765. {
  766. if( DISEQUENCE_COMPARE(mouseMsg->dwSequence, <=, keybMsg->dwSequence) )
  767. earlyDevice = 1;
  768. else
  769. earlyDevice = 2;
  770. }
  771. else if( mouseLen > 0)
  772. {
  773. earlyDevice = 1;
  774. }
  775. else if( keybLen > 0)
  776. {
  777. earlyDevice = 2;
  778. }
  779. if( earlyDevice == 1 )
  780. {
  781. if (mouseMsg->dwOfs == DIMOFS_BUTTON0)
  782. {
  783. if( mouseMsg->dwData & 0x80)
  784. {
  785. // mouse button pressed
  786. //ev.state = left_press = LEFT_BUTTON_MASK;
  787. left_press = LEFT_BUTTON_MASK;
  788. ev.event_type = LEFT_BUTTON;
  789. ev.x = cur_x;
  790. ev.y = cur_y;
  791. ev.time = mouseMsg->dwTimeStamp;
  792. ev.scan_code = 0;
  793. ev.skey_state = skey_state;
  794. add_event(&ev);
  795. }
  796. else
  797. {
  798. // mouse button released
  799. left_press = 0;
  800. ev.event_type = LEFT_BUTTON_RELEASE;
  801. ev.x = cur_x;
  802. ev.y = cur_y;
  803. ev.time = mouseMsg->dwTimeStamp;
  804. ev.scan_code = 0;
  805. ev.skey_state = skey_state;
  806. add_event(&ev);
  807. reset_boundary(); // reset_boundary whenever left button is released
  808. }
  809. }
  810. else if (mouseMsg->dwOfs == DIMOFS_BUTTON1)
  811. {
  812. if( mouseMsg->dwData & 0x80)
  813. {
  814. // mouse button pressed
  815. right_press = RIGHT_BUTTON_MASK;
  816. ev.event_type = RIGHT_BUTTON;
  817. ev.x = cur_x;
  818. ev.y = cur_y;
  819. ev.time = mouseMsg->dwTimeStamp;
  820. ev.scan_code = 0;
  821. ev.skey_state = skey_state;
  822. add_event(&ev);
  823. }
  824. else
  825. {
  826. // mouse button released
  827. right_press = 0;
  828. ev.event_type = RIGHT_BUTTON_RELEASE;
  829. ev.x = cur_x;
  830. ev.y = cur_y;
  831. ev.time = mouseMsg->dwTimeStamp;
  832. ev.scan_code = 0;
  833. ev.skey_state = skey_state;
  834. add_event(&ev);
  835. }
  836. }
  837. else if (mouseMsg->dwOfs == DIMOFS_BUTTON2)
  838. {
  839. // not interested
  840. }
  841. else if (mouseMsg->dwOfs == DIMOFS_BUTTON3)
  842. {
  843. // not interested
  844. }
  845. else if (mouseMsg->dwOfs == DIMOFS_X)
  846. {
  847. cur_x += micky_to_displacement(mouseMsg->dwData);
  848. if(cur_x < bound_x1)
  849. cur_x = bound_x1;
  850. if(cur_x > bound_x2)
  851. cur_x = bound_x2;
  852. moveFlag = 1;
  853. }
  854. else if (mouseMsg->dwOfs == DIMOFS_Y)
  855. {
  856. cur_y += micky_to_displacement(mouseMsg->dwData);
  857. if(cur_y < bound_y1)
  858. cur_y = bound_y1;
  859. if(cur_y > bound_y2)
  860. cur_y = bound_y2;
  861. moveFlag = 1;
  862. }
  863. else if (mouseMsg->dwOfs == DIMOFS_Z)
  864. {
  865. // not interested
  866. }
  867. --mouseLen;
  868. ++mouseMsg;
  869. }
  870. else if( earlyDevice == 2 )
  871. {
  872. // trap keys, such as shift, ctrl, alt, numlock, caplock and scrolllock
  873. // add to event if the key is none of the above
  874. switch( keybMsg->dwOfs )
  875. {
  876. case DIK_LSHIFT:
  877. if( keybMsg->dwData & 0x80 )
  878. skey_state |= LEFT_SHIFT_KEY_MASK;
  879. else
  880. skey_state &= ~LEFT_SHIFT_KEY_MASK;
  881. break;
  882. case DIK_RSHIFT:
  883. if( keybMsg->dwData & 0x80 )
  884. skey_state |= RIGHT_SHIFT_KEY_MASK;
  885. else
  886. skey_state &= ~RIGHT_SHIFT_KEY_MASK;
  887. break;
  888. case DIK_LCONTROL:
  889. if( keybMsg->dwData & 0x80 )
  890. skey_state |= LEFT_CONTROL_KEY_MASK;
  891. else
  892. skey_state &= ~LEFT_CONTROL_KEY_MASK;
  893. break;
  894. case DIK_RCONTROL:
  895. if( keybMsg->dwData & 0x80 )
  896. skey_state |= RIGHT_CONTROL_KEY_MASK;
  897. else
  898. skey_state &= ~RIGHT_CONTROL_KEY_MASK;
  899. break;
  900. case DIK_LMENU:
  901. if( keybMsg->dwData & 0x80 )
  902. skey_state |= LEFT_ALT_KEY_MASK;
  903. else
  904. skey_state &= ~LEFT_ALT_KEY_MASK;
  905. break;
  906. case DIK_RMENU:
  907. if( keybMsg->dwData & 0x80 )
  908. skey_state |= GRAPH_KEY_MASK;
  909. else
  910. skey_state &= ~GRAPH_KEY_MASK;
  911. break;
  912. case DIK_CAPITAL:
  913. if(keybMsg->dwData & 0x80)
  914. skey_state ^= CAP_LOCK_STATE_MASK;
  915. break;
  916. case DIK_NUMLOCK:
  917. if(keybMsg->dwData & 0x80)
  918. skey_state ^= NUM_LOCK_STATE_MASK;
  919. break;
  920. case DIK_SCROLL:
  921. if(keybMsg->dwData & 0x80)
  922. skey_state ^= SCROLL_LOCK_STATE_MASK;
  923. break;
  924. case DIK_INSERT:
  925. if(keybMsg->dwData & 0x80)
  926. {
  927. // insert is a special case, it toggle skey_state and
  928. // append event queue
  929. skey_state ^= INSERT_STATE_MASK;
  930. add_key_event(keybMsg->dwOfs, keybMsg->dwTimeStamp);
  931. }
  932. break;
  933. default:
  934. if( keybMsg->dwData & 0x80 )
  935. {
  936. add_key_event(keybMsg->dwOfs, keybMsg->dwTimeStamp);
  937. // ####### begin Gilbert 29/8 ######//
  938. // capture screen
  939. if(keybMsg->dwOfs == DIK_F11 && (skey_state & CONTROL_KEY_MASK))
  940. {
  941. sys.capture_screen();
  942. }
  943. // ####### end Gilbert 29/8 ######//
  944. }
  945. }
  946. --keybLen;
  947. ++keybMsg;
  948. }
  949. }
  950. }
  951. // ####### begin Gilbert 12/4 ########//
  952. if(moveFlag)
  953. {
  954. mouse_cursor.process(cur_x, cur_y); // repaint mouse cursor
  955. power.mouse_handler();
  956. }
  957. // ####### end Gilbert 12/4 ########//
  958. }
  959. //--------- End of Mouse::poll_event --------------//
  960. // ####### begin Gilbert 31/10 #########//
  961. //--------- Begin of Mouse::update_skey_state ----------//
  962. // called after task switch to get the lastest state of ctrl/alt/shift key
  963. void Mouse::update_skey_state()
  964. {
  965. // ------- get initial keyboard state ----------//
  966. skey_state = 0;
  967. if(GetKeyState(VK_LSHIFT) < 0)
  968. skey_state |= LEFT_SHIFT_KEY_MASK;
  969. if(GetKeyState(VK_RSHIFT) < 0)
  970. skey_state |= RIGHT_SHIFT_KEY_MASK;
  971. if(GetKeyState(VK_LCONTROL) < 0)
  972. skey_state |= LEFT_CONTROL_KEY_MASK;
  973. if(GetKeyState(VK_RCONTROL) < 0)
  974. skey_state |= RIGHT_CONTROL_KEY_MASK;
  975. if(GetKeyState(VK_LMENU) < 0)
  976. skey_state |= LEFT_ALT_KEY_MASK;
  977. if(GetKeyState(VK_RMENU) < 0)
  978. skey_state |= GRAPH_KEY_MASK;
  979. if(GetKeyState(VK_NUMLOCK) & 1)
  980. skey_state |= NUM_LOCK_STATE_MASK;
  981. if(GetKeyState(VK_CAPITAL) & 1)
  982. skey_state |= CAP_LOCK_STATE_MASK;
  983. if(GetKeyState(VK_SCROLL) & 1)
  984. skey_state |= SCROLL_LOCK_STATE_MASK;
  985. skey_state |= INSERT_STATE_MASK; // enable insert mode by default
  986. }
  987. //--------- End of Mouse::update_skey_state ----------//
  988. // ####### end Gilbert 31/10 #########//
  989. //--------- Begin of Mouse::wait_press ----------//
  990. //
  991. // Wait until one of the mouse buttons is pressed.
  992. //
  993. // [int] timeOutSecond - no. of seconds to time out. If not
  994. // given, there will be no time out.
  995. //
  996. // return: <int> 1-left mouse button
  997. // 2-right mouse button
  998. //
  999. int Mouse::wait_press(int timeOutSecond)
  1000. {
  1001. while( mouse.left_press || mouse.any_click() || mouse.key_code ) // avoid repeat clicking
  1002. {
  1003. sys.yield();
  1004. mouse.get_event();
  1005. }
  1006. int rc=0;
  1007. unsigned int timeOutTime = m.get_time() + timeOutSecond*1000;
  1008. while(1)
  1009. {
  1010. sys.yield();
  1011. mouse.get_event();
  1012. if( sys.debug_session )
  1013. sys.blt_virtual_buf();
  1014. if( right_press || mouse.key_code==KEY_ESC )
  1015. {
  1016. rc = 2;
  1017. break;
  1018. }
  1019. if( left_press || mouse.key_code )
  1020. {
  1021. rc = 1;
  1022. break;
  1023. }
  1024. if( timeOutSecond && m.get_time() > timeOutTime )
  1025. break;
  1026. }
  1027. while( mouse.left_press || mouse.any_click() || mouse.key_code ) // avoid repeat clicking
  1028. {
  1029. sys.yield();
  1030. mouse.get_event();
  1031. }
  1032. return rc;
  1033. }
  1034. //--------- End of Mouse::wait_press --------------//
  1035. //--------- Begin of Mouse::reset_click ----------//
  1036. //
  1037. // Reset queued mouse clicks.
  1038. //
  1039. void Mouse::reset_click()
  1040. {
  1041. click_buffer[0].count=0;
  1042. click_buffer[1].count=0;
  1043. }
  1044. //--------- End of Mouse::reset_click --------------//
  1045. // ------ Begin of Mouse::mickey_to_displacment -------//
  1046. long Mouse::micky_to_displacement(DWORD w)
  1047. {
  1048. long d = (long)w ;
  1049. // long a = abs(d);
  1050. // return a >= double_speed_threshold ? (a >= triple_speed_threshold ? 3 * d : 2 * d) : d;
  1051. return abs(d) >= double_speed_threshold ? d+d : d;
  1052. }
  1053. // ------ End of Mouse::mickey_to_displacment -------//
  1054. // ------ Begin of Mouse::is_key -------//
  1055. // compare key with key code
  1056. // e.g. to test a key is alt-a,
  1057. // call mouse.is_key(mouse.scan_code, mouse.event_skey_state, 'a', K_CHAR_KEY | K_IS_ALT)
  1058. //
  1059. // pass 0 as charValue to disable checking in charValue
  1060. // e.g pressed key is 'a'
  1061. // mouse.is_key(mouse.scan_code, mouse.event_skey_state, (WORD) 0, K_CHAR_KEY) returns 'a'
  1062. // but if key pressed is alt-a
  1063. // the same function call returns 0
  1064. // use mouse.is_key(mouse.scan_code, mouse.event_skey_state, (WORD) 0, K_CHAR_KEY | K_IS_ALT ) instead
  1065. //
  1066. int Mouse::is_key(unsigned scanCode, unsigned short skeyState, unsigned short charValue, unsigned flags)
  1067. {
  1068. unsigned short priChar = 0, shiftChar = 0, capitalChar = 0, altChar = 0;
  1069. unsigned onNumPad = 0;
  1070. switch(scanCode)
  1071. {
  1072. case DIK_ESCAPE: priChar = shiftChar = capitalChar = KEY_ESC; break;
  1073. case DIK_1: priChar = capitalChar = '1'; shiftChar = '!'; altChar = '|'; break;
  1074. case DIK_2: priChar = capitalChar = '2'; shiftChar = '\"'; altChar = '@'; break;
  1075. case DIK_3: priChar = capitalChar = '3'; shiftChar = (UCHAR)'·'; altChar = '#'; break;
  1076. case DIK_4: priChar = capitalChar = '4'; shiftChar = '$'; break;
  1077. case DIK_5: priChar = capitalChar = '5'; shiftChar = '%'; break;
  1078. case DIK_6: priChar = capitalChar = '6'; shiftChar = '&'; break;
  1079. case DIK_7: priChar = capitalChar = '7'; shiftChar = '/'; break;
  1080. case DIK_8: priChar = capitalChar = '8'; shiftChar = '('; break;
  1081. case DIK_9: priChar = capitalChar = '9'; shiftChar = ')'; break;
  1082. case DIK_0: priChar = capitalChar = '0'; shiftChar = '='; break;
  1083. //case DIK_MINUS: priChar = capitalChar = '-'; shiftChar = '_'; break;
  1084. case 0x0c: priChar = capitalChar = '\''; shiftChar = '?'; break;
  1085. //case DIK_EQUALS: priChar = capitalChar = '='; shiftChar = '+'; break;
  1086. case 0x0d: priChar = capitalChar = (UCHAR)'¡'; shiftChar = (UCHAR)'¿'; break;
  1087. case DIK_BACK: priChar = capitalChar = shiftChar = KEY_BACK_SPACE; break; // backspace
  1088. case DIK_TAB: priChar = capitalChar = shiftChar = KEY_TAB; break;
  1089. case DIK_Q: priChar = 'q'; capitalChar = shiftChar = 'Q'; break;
  1090. case DIK_W: priChar = 'w'; capitalChar = shiftChar = 'W'; break;
  1091. case DIK_E: priChar = 'e'; capitalChar = shiftChar = 'E'; break;
  1092. case DIK_R: priChar = 'r'; capitalChar = shiftChar = 'R'; break;
  1093. case DIK_T: priChar = 't'; capitalChar = shiftChar = 'T'; break;
  1094. case DIK_Y: priChar = 'y'; capitalChar = shiftChar = 'Y'; break;
  1095. case DIK_U: priChar = 'u'; capitalChar = shiftChar = 'U'; break;
  1096. case DIK_I: priChar = 'i'; capitalChar = shiftChar = 'I'; break;
  1097. case DIK_O: priChar = 'o'; capitalChar = shiftChar = 'O'; break;
  1098. case DIK_P: priChar = 'p'; capitalChar = shiftChar = 'P'; break;
  1099. // case DIK_LBRACKET: priChar = capitalChar = '['; shiftChar = '{'; break;
  1100. case 0x1a: priChar = capitalChar = '`'; shiftChar = '^'; altChar = '['; break;
  1101. // case DIK_RBRACKET: priChar = capitalChar = ']'; shiftChar = '}'; break;
  1102. case 0x1b: priChar = capitalChar = '+';shiftChar = '*'; altChar = ']'; break;
  1103. case DIK_NUMPADENTER: // Enter on numeric keypad
  1104. onNumPad = 1; // fall through
  1105. case DIK_RETURN: priChar = capitalChar = shiftChar = KEY_RETURN; break;
  1106. case DIK_A: priChar = 'a'; capitalChar = shiftChar = 'A'; break;
  1107. case DIK_S: priChar = 's'; capitalChar = shiftChar = 'S'; break;
  1108. case DIK_D: priChar = 'd'; capitalChar = shiftChar = 'D'; break;
  1109. case DIK_F: priChar = 'f'; capitalChar = shiftChar = 'F'; break;
  1110. case DIK_G: priChar = 'g'; capitalChar = shiftChar = 'G'; break;
  1111. case DIK_H: priChar = 'h'; capitalChar = shiftChar = 'H'; break;
  1112. case DIK_J: priChar = 'j'; capitalChar = shiftChar = 'J'; break;
  1113. case DIK_K: priChar = 'k'; capitalChar = shiftChar = 'K'; break;
  1114. case DIK_L: priChar = 'l'; capitalChar = shiftChar = 'L'; break;
  1115. //case DIK_SEMICOLON: priChar = capitalChar = ';'; shiftChar = ':'; altChar = '~'; break;
  1116. case 0x27: priChar = (UCHAR)'ñ'; capitalChar = shiftChar = (UCHAR)'Ñ'; break;
  1117. //case DIK_APOSTROPHE: priChar = capitalChar = '\''; shiftChar = '\"'; break;
  1118. case 0x28: priChar = capitalChar = (UCHAR)'´'; shiftChar = (UCHAR)'¨'; altChar = '{'; break;
  1119. //case DIK_GRAVE: priChar = capitalChar = '~'; shiftChar = '`'; break;
  1120. case 0x29: priChar = capitalChar = (UCHAR)'º'; shiftChar = (UCHAR)'ª'; altChar = '\\'; break;
  1121. // case DIK_BACKSLASH: priChar = capitalChar = '\\'; shiftChar = '|'; break;
  1122. case 0x2b: priChar = (UCHAR)'ç'; capitalChar = shiftChar = (UCHAR)'Ç'; altChar = '}'; break;
  1123. case DIK_Z: priChar = 'z'; capitalChar = shiftChar = 'Z'; break;
  1124. case DIK_X: priChar = 'x'; capitalChar = shiftChar = 'X'; break;
  1125. case DIK_C: priChar = 'c'; capitalChar = shiftChar = 'C'; break;
  1126. case DIK_V: priChar = 'v'; capitalChar = shiftChar = 'V'; break;
  1127. case DIK_B: priChar = 'b'; capitalChar = shiftChar = 'B'; break;
  1128. case DIK_N: priChar = 'n'; capitalChar = shiftChar = 'N'; break;
  1129. case DIK_M: priChar = 'm'; capitalChar = shiftChar = 'M'; break;
  1130. case DIK_COMMA: priChar = capitalChar = ','; shiftChar = ';'; break;
  1131. case DIK_PERIOD: priChar = capitalChar = '.'; shiftChar = ':'; break;
  1132. // case DIK_SLASH: priChar = capitalChar = '/'; shiftChar = '\?'; break;
  1133. case 0x35: priChar = capitalChar = '-'; shiftChar = '_'; break;
  1134. case DIK_MULTIPLY: priChar = capitalChar = shiftChar = '*'; onNumPad = 1; break; // * on numeric keypad
  1135. case DIK_SPACE: priChar = capitalChar = shiftChar = ' '; break;
  1136. case DIK_ADD: priChar = capitalChar = shiftChar = '+'; onNumPad = 1; break; // + on numeric keypad
  1137. case DIK_DIVIDE: priChar = capitalChar = shiftChar = '/'; onNumPad = 1; break; // / on numeric keypad
  1138. case DIK_SUBTRACT: priChar = capitalChar = shiftChar = '-'; onNumPad = 1; break; // - on numeric keypad
  1139. case DIK_NUMPAD7: priChar = shiftChar = capitalChar = '7'; onNumPad = 1; break;
  1140. case DIK_NUMPAD8: priChar = shiftChar = capitalChar = '8'; onNumPad = 1; break;
  1141. case DIK_NUMPAD9: priChar = shiftChar = capitalChar = '9'; onNumPad = 1; break;
  1142. case DIK_NUMPAD4: priChar = shiftChar = capitalChar = '4'; onNumPad = 1; break;
  1143. case DIK_NUMPAD5: priChar = shiftChar = capitalChar = '5'; onNumPad = 1; break;
  1144. case DIK_NUMPAD6: priChar = shiftChar = capitalChar = '6'; onNumPad = 1; break;
  1145. case DIK_NUMPAD1: priChar = shiftChar = capitalChar = '1'; onNumPad = 1; break;
  1146. case DIK_NUMPAD2: priChar = shiftChar = capitalChar = '2'; onNumPad = 1; break;
  1147. case DIK_NUMPAD3: priChar = shiftChar = capitalChar = '3'; onNumPad = 1; break;
  1148. case DIK_NUMPAD0: priChar = shiftChar = capitalChar = '0'; onNumPad = 1; break;
  1149. case DIK_DECIMAL: priChar = shiftChar = capitalChar = '.'; onNumPad = 1; break;
  1150. // function keys
  1151. case DIK_F1: priChar = shiftChar = capitalChar = KEY_F1; break;
  1152. case DIK_F2: priChar = shiftChar = capitalChar = KEY_F2; break;
  1153. case DIK_F3: priChar = shiftChar = capitalChar = KEY_F3; break;
  1154. case DIK_F4: priChar = shiftChar = capitalChar = KEY_F4; break;
  1155. case DIK_F5: priChar = shiftChar = capitalChar = KEY_F5; break;
  1156. case DIK_F6: priChar = shiftChar = capitalChar = KEY_F6; break;
  1157. case DIK_F7: priChar = shiftChar = capitalChar = KEY_F7; break;
  1158. case DIK_F8: priChar = shiftChar = capitalChar = KEY_F8; break;
  1159. case DIK_F9: priChar = shiftChar = capitalChar = KEY_F9; break;
  1160. case DIK_F10: priChar = shiftChar = capitalChar = KEY_F10; break;
  1161. case DIK_F11: priChar = shiftChar = capitalChar = KEY_F11; break;
  1162. case DIK_F12: priChar = shiftChar = capitalChar = KEY_F12; break;
  1163. // arrow keys
  1164. case DIK_HOME: priChar = shiftChar = capitalChar = KEY_HOME; break;
  1165. case DIK_UP: priChar = shiftChar = capitalChar = KEY_UP; break;
  1166. case DIK_PRIOR: priChar = shiftChar = capitalChar = KEY_PGUP; break;
  1167. case DIK_LEFT: priChar = shiftChar = capitalChar = KEY_LEFT; break;
  1168. case DIK_RIGHT: priChar = shiftChar = capitalChar = KEY_RIGHT; break;
  1169. case DIK_END: priChar = shiftChar = capitalChar = KEY_END; break;
  1170. case DIK_DOWN: priChar = shiftChar = capitalChar = KEY_DOWN; break;
  1171. case DIK_NEXT: priChar = shiftChar = capitalChar = KEY_PGDN; break;
  1172. case DIK_INSERT: priChar = shiftChar = capitalChar = KEY_INS; break;
  1173. case DIK_DELETE: priChar = shiftChar = capitalChar = KEY_DEL; break;
  1174. // other keys
  1175. case 0x56: priChar = capitalChar = '<'; shiftChar = '>'; break;
  1176. // other keys found in Japanese keyboard
  1177. case DIK_NUMPADCOMMA: priChar = shiftChar = capitalChar = ','; break;
  1178. case DIK_NUMPADEQUALS: priChar = shiftChar = capitalChar = '='; break;
  1179. case DIK_AT: priChar = shiftChar = capitalChar = '@'; break;
  1180. case DIK_COLON: priChar = shiftChar = capitalChar = ':'; break;
  1181. case DIK_UNDERLINE: priChar = shiftChar = capitalChar = '_'; break;
  1182. }
  1183. // BUGHERE : numpad key is not translated when numlock is off
  1184. // check flags
  1185. int retFlag = 1;
  1186. // check shift key state
  1187. if( !(flags & K_IGNORE_SHIFT) )
  1188. {
  1189. if( flags & K_IS_SHIFT )
  1190. {
  1191. if( !(skeyState & SHIFT_KEY_MASK) )
  1192. retFlag = 0;
  1193. }
  1194. else
  1195. {
  1196. if( skeyState & SHIFT_KEY_MASK )
  1197. retFlag = 0;
  1198. }
  1199. }
  1200. // check contrl key state
  1201. if( !(flags & K_IGNORE_CTRL) )
  1202. {
  1203. if( flags & K_IS_CTRL )
  1204. {
  1205. if( !(skeyState & CONTROL_KEY_MASK) )
  1206. retFlag = 0;
  1207. }
  1208. else
  1209. {
  1210. if( skeyState & CONTROL_KEY_MASK )
  1211. retFlag = 0;
  1212. }
  1213. }
  1214. // check alt key state
  1215. if( !(flags & K_IGNORE_ALT) )
  1216. {
  1217. if( flags & K_IS_ALT )
  1218. {
  1219. if( !(skeyState & ALT_KEY_MASK) )
  1220. retFlag = 0;
  1221. }
  1222. else
  1223. {
  1224. if( skeyState & ALT_KEY_MASK )
  1225. retFlag = 0;
  1226. }
  1227. }
  1228. // check numpad state
  1229. if( !(flags & K_IGNORE_NUMPAD) )
  1230. {
  1231. if( flags & K_ON_NUMPAD )
  1232. {
  1233. if( !onNumPad )
  1234. retFlag = 0;
  1235. }
  1236. else
  1237. {
  1238. if( onNumPad )
  1239. retFlag = 0;
  1240. }
  1241. }
  1242. unsigned outChar = priChar;
  1243. if( flags & K_TRANSLATE_KEY )
  1244. {
  1245. if( (skeyState & GRAPH_KEY_MASK) && altChar )
  1246. {
  1247. outChar = altChar;
  1248. }
  1249. else
  1250. {
  1251. if( priChar == capitalChar )
  1252. {
  1253. // non-letter
  1254. outChar = skeyState & SHIFT_KEY_MASK ? shiftChar : priChar;
  1255. }
  1256. else
  1257. {
  1258. // letter
  1259. outChar = skeyState & CAP_LOCK_STATE_MASK ?
  1260. (skeyState & SHIFT_KEY_MASK ? priChar : capitalChar) :
  1261. (skeyState & SHIFT_KEY_MASK ? shiftChar : priChar) ;
  1262. }
  1263. }
  1264. }
  1265. if(!retFlag)
  1266. return 0;
  1267. int retFlag2 = (charValue == 0) || outChar == charValue
  1268. || ((flags & K_IGNORE_SHIFT) && shiftChar == charValue)
  1269. || ((flags & K_IGNORE_CAP_LOCK) && capitalChar == charValue)
  1270. #ifdef WIN32
  1271. || ((flags & K_CASE_INSENSITIVE) && outChar == (unsigned short) std::tolower(charValue));
  1272. #else
  1273. || ((flags & K_CASE_INSENSITIVE) && outChar == (unsigned short) tolower(charValue));
  1274. #endif
  1275. if(retFlag2)
  1276. return outChar;
  1277. else
  1278. return 0;
  1279. }
  1280. // ------ End of Mouse::is_key -------//
  1281. // ------ Begin of Mouse::is_key -------//
  1282. int Mouse::is_key(unsigned scanCode, unsigned short skeyState, char *keyStr, unsigned flags)
  1283. {
  1284. int len = strlen(keyStr);
  1285. if( len == 0)
  1286. return 0;
  1287. if( len == 1)
  1288. return is_key(scanCode, skeyState, keyStr[0], flags);
  1289. char *priChar = NULL;
  1290. char *numLockChar = NULL;
  1291. int onNumPad = 0;
  1292. switch(scanCode)
  1293. {
  1294. case DIK_F1: numLockChar = priChar = "F1"; break;
  1295. case DIK_F2: numLockChar = priChar = "F2"; break;
  1296. case DIK_F3: numLockChar = priChar = "F3"; break;
  1297. case DIK_F4: numLockChar = priChar = "F4"; break;
  1298. case DIK_F5: numLockChar = priChar = "F5"; break;
  1299. case DIK_F6: numLockChar = priChar = "F6"; break;
  1300. case DIK_F7: numLockChar = priChar = "F7"; break;
  1301. case DIK_F8: numLockChar = priChar = "F8"; break;
  1302. case DIK_F9: numLockChar = priChar = "F9"; break;
  1303. case DIK_F10: numLockChar = priChar = "F10"; break;
  1304. case DIK_F11: numLockChar = priChar = "F11"; break;
  1305. case DIK_F12: numLockChar = priChar = "F12"; break;
  1306. case DIK_NUMPAD7: priChar = "HOME"; numLockChar = "7"; onNumPad = 1; break;
  1307. case DIK_NUMPAD8: priChar = "UP"; numLockChar = "8"; onNumPad = 1; break;
  1308. case DIK_NUMPAD9: priChar = "PAGE UP"; numLockChar = "9"; onNumPad = 1; break;
  1309. case DIK_NUMPAD4: priChar = "LEFT"; numLockChar = "4"; onNumPad = 1; break;
  1310. case DIK_NUMPAD5: priChar = "CENTER"; numLockChar = "5"; onNumPad = 1; break;
  1311. case DIK_NUMPAD6: priChar = "RIGHT"; numLockChar = "6"; onNumPad = 1; break;
  1312. case DIK_NUMPAD1: priChar = "END"; numLockChar = "1"; onNumPad = 1; break;
  1313. case DIK_NUMPAD2: priChar = "DOWN"; numLockChar = "2"; onNumPad = 1; break;
  1314. case DIK_NUMPAD3: priChar = "PAGE DOWN"; numLockChar = "3"; onNumPad = 1; break;
  1315. case DIK_NUMPAD0: priChar = "INSERT"; numLockChar = "0"; onNumPad = 1; break;
  1316. case DIK_DECIMAL: priChar = "DELETE"; numLockChar = "."; onNumPad = 1; break;
  1317. // keys above arrow keys
  1318. case DIK_HOME: priChar = numLockChar = "HOME"; break;
  1319. case DIK_UP: priChar = numLockChar = "UP"; break;
  1320. case DIK_PRIOR: priChar = numLockChar = "PAGE UP"; break;
  1321. case DIK_LEFT: priChar = numLockChar = "LEFT"; break;
  1322. case DIK_RIGHT: priChar = numLockChar = "RIGHT"; break;
  1323. case DIK_END: priChar = numLockChar = "END"; break;
  1324. case DIK_DOWN: priChar = numLockChar = "DOWN"; break;
  1325. case DIK_NEXT: priChar = numLockChar = "PAGE DOWN"; break;
  1326. case DIK_INSERT: priChar = numLockChar = "INSERT"; break;
  1327. case DIK_DELETE: priChar = numLockChar = "DELETE"; break;
  1328. // 104-key only
  1329. case DIK_LWIN: priChar = numLockChar = "LEFT WINDOW"; break;
  1330. case DIK_RWIN: priChar = numLockChar = "RIGHT WINDOW"; break;
  1331. case DIK_APPS: priChar = numLockChar = "APP MENU"; break;
  1332. }
  1333. // check flags
  1334. int retFlag = 1;
  1335. // check shift key state
  1336. if( !(flags & K_IGNORE_SHIFT) )
  1337. {
  1338. if( flags & K_IS_SHIFT )
  1339. {
  1340. if( !(skeyState & SHIFT_KEY_MASK) )
  1341. retFlag = 0;
  1342. }
  1343. else
  1344. {
  1345. if( skeyState & SHIFT_KEY_MASK )
  1346. retFlag = 0;
  1347. }
  1348. }
  1349. // check contrl key state
  1350. if( !(flags & K_IGNORE_CTRL) )
  1351. {
  1352. if( flags & K_IS_CTRL )
  1353. {
  1354. if( !(skeyState & CONTROL_KEY_MASK) )
  1355. retFlag = 0;
  1356. }
  1357. else
  1358. {
  1359. if( skeyState & CONTROL_KEY_MASK )
  1360. retFlag = 0;
  1361. }
  1362. }
  1363. // check alt key state
  1364. if( !(flags & K_IGNORE_ALT) )
  1365. {
  1366. if( flags & K_IS_ALT )
  1367. {
  1368. if( !(skeyState & ALT_KEY_MASK) )
  1369. retFlag = 0;
  1370. }
  1371. else
  1372. {
  1373. if( skeyState & ALT_KEY_MASK )
  1374. retFlag = 0;
  1375. }
  1376. }
  1377. // check numpad state
  1378. if( !(flags & K_IGNORE_NUMPAD) )
  1379. {
  1380. if( flags & K_ON_NUMPAD )
  1381. {
  1382. if( !onNumPad )
  1383. retFlag = 0;
  1384. }
  1385. else
  1386. {
  1387. if( onNumPad )
  1388. retFlag = 0;
  1389. }
  1390. }
  1391. char *outChar = skeyState & NUM_LOCK_STATE_MASK ? numLockChar : priChar;
  1392. int retFlag2 = outChar ? !strcmp(outChar, keyStr) : 0;
  1393. return retFlag && retFlag2;
  1394. }
  1395. // ------ End of Mouse::is_key -------//
  1396. #endif