OMOUSEFR.cpp 45 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618
  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(FRENCH))
  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. if( mouseMsg->dwData & 0x80)
  783. {
  784. // mouse button pressed
  785. //ev.state = left_press = LEFT_BUTTON_MASK;
  786. left_press = LEFT_BUTTON_MASK;
  787. ev.event_type = LEFT_BUTTON;
  788. ev.x = cur_x;
  789. ev.y = cur_y;
  790. ev.time = mouseMsg->dwTimeStamp;
  791. ev.scan_code = 0;
  792. ev.skey_state = skey_state;
  793. add_event(&ev);
  794. }
  795. else
  796. {
  797. // mouse button released
  798. left_press = 0;
  799. ev.event_type = LEFT_BUTTON_RELEASE;
  800. ev.x = cur_x;
  801. ev.y = cur_y;
  802. ev.time = mouseMsg->dwTimeStamp;
  803. ev.scan_code = 0;
  804. ev.skey_state = skey_state;
  805. add_event(&ev);
  806. reset_boundary(); // reset_boundary whenever left button is released
  807. }
  808. }
  809. else if (mouseMsg->dwOfs == DIMOFS_BUTTON1)
  810. {
  811. if( mouseMsg->dwData & 0x80)
  812. {
  813. // mouse button pressed
  814. right_press = RIGHT_BUTTON_MASK;
  815. ev.event_type = RIGHT_BUTTON;
  816. ev.x = cur_x;
  817. ev.y = cur_y;
  818. ev.time = mouseMsg->dwTimeStamp;
  819. ev.scan_code = 0;
  820. ev.skey_state = skey_state;
  821. add_event(&ev);
  822. }
  823. else
  824. {
  825. // mouse button released
  826. right_press = 0;
  827. ev.event_type = RIGHT_BUTTON_RELEASE;
  828. ev.x = cur_x;
  829. ev.y = cur_y;
  830. ev.time = mouseMsg->dwTimeStamp;
  831. ev.scan_code = 0;
  832. ev.skey_state = skey_state;
  833. add_event(&ev);
  834. }
  835. }
  836. else if (mouseMsg->dwOfs == DIMOFS_BUTTON2)
  837. {
  838. // not interested
  839. }
  840. else if (mouseMsg->dwOfs == DIMOFS_BUTTON3) {
  841. // not interested
  842. }
  843. else if (mouseMsg->dwOfs == DIMOFS_X)
  844. {
  845. cur_x += micky_to_displacement(mouseMsg->dwData);
  846. if(cur_x < bound_x1)
  847. cur_x = bound_x1;
  848. if(cur_x > bound_x2)
  849. cur_x = bound_x2;
  850. moveFlag = 1;
  851. }
  852. else if (mouseMsg->dwOfs == DIMOFS_Y)
  853. {
  854. cur_y += micky_to_displacement(mouseMsg->dwData);
  855. if(cur_y < bound_y1)
  856. cur_y = bound_y1;
  857. if(cur_y > bound_y2)
  858. cur_y = bound_y2;
  859. moveFlag = 1;
  860. }
  861. else if (mouseMsg->dwOfs == DIMOFS_Z)
  862. {
  863. // not interested
  864. }
  865. --mouseLen;
  866. ++mouseMsg;
  867. }
  868. else if( earlyDevice == 2 )
  869. {
  870. // trap keys, such as shift, ctrl, alt, numlock, caplock and scrolllock
  871. // add to event if the key is none of the above
  872. switch( keybMsg->dwOfs )
  873. {
  874. case DIK_LSHIFT:
  875. if( keybMsg->dwData & 0x80 )
  876. skey_state |= LEFT_SHIFT_KEY_MASK;
  877. else
  878. skey_state &= ~LEFT_SHIFT_KEY_MASK;
  879. break;
  880. case DIK_RSHIFT:
  881. if( keybMsg->dwData & 0x80 )
  882. skey_state |= RIGHT_SHIFT_KEY_MASK;
  883. else
  884. skey_state &= ~RIGHT_SHIFT_KEY_MASK;
  885. break;
  886. case DIK_LCONTROL:
  887. if( keybMsg->dwData & 0x80 )
  888. skey_state |= LEFT_CONTROL_KEY_MASK;
  889. else
  890. skey_state &= ~LEFT_CONTROL_KEY_MASK;
  891. break;
  892. case DIK_RCONTROL:
  893. if( keybMsg->dwData & 0x80 )
  894. skey_state |= RIGHT_CONTROL_KEY_MASK;
  895. else
  896. skey_state &= ~RIGHT_CONTROL_KEY_MASK;
  897. break;
  898. case DIK_LMENU:
  899. if( keybMsg->dwData & 0x80 )
  900. skey_state |= LEFT_ALT_KEY_MASK;
  901. else
  902. skey_state &= ~LEFT_ALT_KEY_MASK;
  903. break;
  904. case DIK_RMENU:
  905. if( keybMsg->dwData & 0x80 )
  906. skey_state |= GRAPH_KEY_MASK;
  907. else
  908. skey_state &= ~GRAPH_KEY_MASK;
  909. break;
  910. case DIK_CAPITAL:
  911. if(keybMsg->dwData & 0x80)
  912. skey_state ^= CAP_LOCK_STATE_MASK;
  913. break;
  914. case DIK_NUMLOCK:
  915. if(keybMsg->dwData & 0x80)
  916. skey_state ^= NUM_LOCK_STATE_MASK;
  917. break;
  918. case DIK_SCROLL:
  919. if(keybMsg->dwData & 0x80)
  920. skey_state ^= SCROLL_LOCK_STATE_MASK;
  921. break;
  922. case DIK_INSERT:
  923. if(keybMsg->dwData & 0x80)
  924. {
  925. // insert is a special case, it toggle skey_state and
  926. // append event queue
  927. skey_state ^= INSERT_STATE_MASK;
  928. add_key_event(keybMsg->dwOfs, keybMsg->dwTimeStamp);
  929. }
  930. break;
  931. default:
  932. if( keybMsg->dwData & 0x80 )
  933. {
  934. add_key_event(keybMsg->dwOfs, keybMsg->dwTimeStamp);
  935. // ####### begin Gilbert 29/8 ######//
  936. // capture screen
  937. if(keybMsg->dwOfs == DIK_F11 && (skey_state & CONTROL_KEY_MASK))
  938. {
  939. sys.capture_screen();
  940. }
  941. // ####### end Gilbert 29/8 ######//
  942. }
  943. }
  944. --keybLen;
  945. ++keybMsg;
  946. }
  947. }
  948. }
  949. // ####### begin Gilbert 12/4 ########//
  950. if(moveFlag)
  951. {
  952. mouse_cursor.process(cur_x, cur_y); // repaint mouse cursor
  953. power.mouse_handler();
  954. }
  955. // ####### end Gilbert 12/4 ########//
  956. }
  957. //--------- End of Mouse::poll_event --------------//
  958. // ####### begin Gilbert 31/10 #########//
  959. //--------- Begin of Mouse::update_skey_state ----------//
  960. // called after task switch to get the lastest state of ctrl/alt/shift key
  961. void Mouse::update_skey_state()
  962. {
  963. // ------- get initial keyboard state ----------//
  964. skey_state = 0;
  965. if(GetKeyState(VK_LSHIFT) < 0)
  966. skey_state |= LEFT_SHIFT_KEY_MASK;
  967. if(GetKeyState(VK_RSHIFT) < 0)
  968. skey_state |= RIGHT_SHIFT_KEY_MASK;
  969. if(GetKeyState(VK_LCONTROL) < 0)
  970. skey_state |= LEFT_CONTROL_KEY_MASK;
  971. if(GetKeyState(VK_RCONTROL) < 0)
  972. skey_state |= RIGHT_CONTROL_KEY_MASK;
  973. if(GetKeyState(VK_LMENU) < 0)
  974. skey_state |= LEFT_ALT_KEY_MASK;
  975. if(GetKeyState(VK_RMENU) < 0)
  976. skey_state |= GRAPH_KEY_MASK;
  977. if(GetKeyState(VK_NUMLOCK) & 1)
  978. skey_state |= NUM_LOCK_STATE_MASK;
  979. if(GetKeyState(VK_CAPITAL) & 1)
  980. skey_state |= CAP_LOCK_STATE_MASK;
  981. if(GetKeyState(VK_SCROLL) & 1)
  982. skey_state |= SCROLL_LOCK_STATE_MASK;
  983. skey_state |= INSERT_STATE_MASK; // enable insert mode by default
  984. }
  985. //--------- End of Mouse::update_skey_state ----------//
  986. // ####### end Gilbert 31/10 #########//
  987. //--------- Begin of Mouse::wait_press ----------//
  988. //
  989. // Wait until one of the mouse buttons is pressed.
  990. //
  991. // [int] timeOutSecond - no. of seconds to time out. If not
  992. // given, there will be no time out.
  993. //
  994. // return: <int> 1-left mouse button
  995. // 2-right mouse button
  996. //
  997. int Mouse::wait_press(int timeOutSecond)
  998. {
  999. while( mouse.left_press || mouse.any_click() || mouse.key_code ) // avoid repeat clicking
  1000. {
  1001. sys.yield();
  1002. mouse.get_event();
  1003. }
  1004. int rc=0;
  1005. unsigned int timeOutTime = m.get_time() + timeOutSecond*1000;
  1006. while(1)
  1007. {
  1008. sys.yield();
  1009. mouse.get_event();
  1010. if( sys.debug_session )
  1011. sys.blt_virtual_buf();
  1012. if( right_press || mouse.key_code==KEY_ESC )
  1013. {
  1014. rc = 2;
  1015. break;
  1016. }
  1017. if( left_press || mouse.key_code )
  1018. {
  1019. rc = 1;
  1020. break;
  1021. }
  1022. if( timeOutSecond && m.get_time() > timeOutTime )
  1023. break;
  1024. }
  1025. while( mouse.left_press || mouse.any_click() || mouse.key_code ) // avoid repeat clicking
  1026. {
  1027. sys.yield();
  1028. mouse.get_event();
  1029. }
  1030. return rc;
  1031. }
  1032. //--------- End of Mouse::wait_press --------------//
  1033. //--------- Begin of Mouse::reset_click ----------//
  1034. //
  1035. // Reset queued mouse clicks.
  1036. //
  1037. void Mouse::reset_click()
  1038. {
  1039. click_buffer[0].count=0;
  1040. click_buffer[1].count=0;
  1041. }
  1042. //--------- End of Mouse::reset_click --------------//
  1043. // ------ Begin of Mouse::mickey_to_displacment -------//
  1044. long Mouse::micky_to_displacement(DWORD w)
  1045. {
  1046. long d = (long)w ;
  1047. // long a = abs(d);
  1048. // return a >= double_speed_threshold ? (a >= triple_speed_threshold ? 3 * d : 2 * d) : d;
  1049. return abs(d) >= double_speed_threshold ? d+d : d;
  1050. }
  1051. // ------ End of Mouse::mickey_to_displacment -------//
  1052. // ------ Begin of Mouse::is_key -------//
  1053. // compare key with key code
  1054. // e.g. to test a key is alt-a,
  1055. // call mouse.is_key(mouse.scan_code, mouse.event_skey_state, 'a', K_CHAR_KEY | K_IS_ALT)
  1056. //
  1057. // pass 0 as charValue to disable checking in charValue
  1058. // e.g pressed key is 'a'
  1059. // mouse.is_key(mouse.scan_code, mouse.event_skey_state, (WORD) 0, K_CHAR_KEY) returns 'a'
  1060. // but if key pressed is alt-a
  1061. // the same function call returns 0
  1062. // use mouse.is_key(mouse.scan_code, mouse.event_skey_state, (WORD) 0, K_CHAR_KEY | K_IS_ALT ) instead
  1063. //
  1064. int Mouse::is_key(unsigned scanCode, unsigned short skeyState, unsigned short charValue, unsigned flags)
  1065. {
  1066. unsigned short priChar = 0, shiftChar = 0, capitalChar = 0, altChar = 0;
  1067. unsigned onNumPad = 0;
  1068. switch(scanCode)
  1069. {
  1070. case DIK_ESCAPE: priChar = shiftChar = capitalChar = KEY_ESC; break;
  1071. case DIK_1: priChar = capitalChar = '1'; shiftChar = '!'; break;
  1072. case DIK_2: priChar = capitalChar = '2'; shiftChar = '\"'; altChar = '@'; break;
  1073. case DIK_3: priChar = capitalChar = '3'; shiftChar = '/'; altChar = (UCHAR)'£'; break;
  1074. case DIK_4: priChar = capitalChar = '4'; shiftChar = '$'; break;
  1075. case DIK_5: priChar = capitalChar = '5'; shiftChar = '%'; break;
  1076. case DIK_6: priChar = capitalChar = '6'; shiftChar = '?'; altChar = (UCHAR)'¬';break;
  1077. case DIK_7: priChar = capitalChar = '7'; shiftChar = '&'; break;
  1078. case DIK_8: priChar = capitalChar = '8'; shiftChar = '*'; break;
  1079. case DIK_9: priChar = capitalChar = '9'; shiftChar = '('; break;
  1080. case DIK_0: priChar = capitalChar = '0'; shiftChar = ')'; break;
  1081. case DIK_MINUS: priChar = capitalChar = '-'; shiftChar = '_'; break;
  1082. case DIK_EQUALS: priChar = capitalChar = '='; shiftChar = '+'; break;
  1083. case DIK_BACK: priChar = capitalChar = shiftChar = KEY_BACK_SPACE; break; // backspace
  1084. case DIK_TAB: priChar = capitalChar = shiftChar = KEY_TAB; break;
  1085. case DIK_Q: priChar = 'q'; capitalChar = shiftChar = 'Q'; break;
  1086. case DIK_W: priChar = 'w'; capitalChar = shiftChar = 'W'; break;
  1087. case DIK_E: priChar = 'e'; capitalChar = shiftChar = 'E'; break;
  1088. case DIK_R: priChar = 'r'; capitalChar = shiftChar = 'R'; break;
  1089. case DIK_T: priChar = 't'; capitalChar = shiftChar = 'T'; break;
  1090. case DIK_Y: priChar = 'y'; capitalChar = shiftChar = 'Y'; break;
  1091. case DIK_U: priChar = 'u'; capitalChar = shiftChar = 'U'; break;
  1092. case DIK_I: priChar = 'i'; capitalChar = shiftChar = 'I'; break;
  1093. case DIK_O: priChar = 'o'; capitalChar = shiftChar = 'O'; break;
  1094. case DIK_P: priChar = 'p'; capitalChar = shiftChar = 'P'; break;
  1095. // case DIK_LBRACKET: priChar = capitalChar = '['; shiftChar = '{'; break;
  1096. case 0x1a: priChar = capitalChar = shiftChar = '^'; altChar = '['; break;
  1097. // case DIK_RBRACKET: priChar = capitalChar = ']'; shiftChar = '}'; break;
  1098. case 0x1b: priChar = capitalChar = (UCHAR)'¸';shiftChar = (UCHAR)'¨'; altChar = ']'; break;
  1099. case DIK_NUMPADENTER: // Enter on numeric keypad
  1100. onNumPad = 1; // fall through
  1101. case DIK_RETURN: priChar = capitalChar = shiftChar = KEY_RETURN; break;
  1102. case DIK_A: priChar = 'a'; capitalChar = shiftChar = 'A'; break;
  1103. case DIK_S: priChar = 's'; capitalChar = shiftChar = 'S'; break;
  1104. case DIK_D: priChar = 'd'; capitalChar = shiftChar = 'D'; break;
  1105. case DIK_F: priChar = 'f'; capitalChar = shiftChar = 'F'; break;
  1106. case DIK_G: priChar = 'g'; capitalChar = shiftChar = 'G'; break;
  1107. case DIK_H: priChar = 'h'; capitalChar = shiftChar = 'H'; break;
  1108. case DIK_J: priChar = 'j'; capitalChar = shiftChar = 'J'; break;
  1109. case DIK_K: priChar = 'k'; capitalChar = shiftChar = 'K'; break;
  1110. case DIK_L: priChar = 'l'; capitalChar = shiftChar = 'L'; break;
  1111. case DIK_SEMICOLON: priChar = capitalChar = ';'; shiftChar = ':'; altChar = '~'; break;
  1112. //case DIK_APOSTROPHE: priChar = capitalChar = '\''; shiftChar = '\"'; break;
  1113. case 0x28: priChar = capitalChar = shiftChar = '`'; altChar = '{'; break;
  1114. //case DIK_GRAVE: priChar = capitalChar = '~'; shiftChar = '`'; break;
  1115. case 0x29: priChar = capitalChar = '#'; shiftChar = '|'; altChar = '\\'; break;
  1116. // case DIK_BACKSLASH: priChar = capitalChar = '\\'; shiftChar = '|'; break;
  1117. case 0x2b: priChar = capitalChar = '<'; shiftChar = '>'; altChar = '}'; break;
  1118. case DIK_Z: priChar = 'z'; capitalChar = shiftChar = 'Z'; break;
  1119. case DIK_X: priChar = 'x'; capitalChar = shiftChar = 'X'; break;
  1120. case DIK_C: priChar = 'c'; capitalChar = shiftChar = 'C'; break;
  1121. case DIK_V: priChar = 'v'; capitalChar = shiftChar = 'V'; break;
  1122. case DIK_B: priChar = 'b'; capitalChar = shiftChar = 'B'; break;
  1123. case DIK_N: priChar = 'n'; capitalChar = shiftChar = 'N'; break;
  1124. case DIK_M: priChar = 'm'; capitalChar = shiftChar = 'M'; break;
  1125. case DIK_COMMA: priChar = capitalChar = ','; shiftChar = '\''; altChar = (UCHAR)'¯'; break;
  1126. case DIK_PERIOD: priChar = capitalChar = '.'; shiftChar = '\"'; altChar = (UCHAR)'­'; break;
  1127. // case DIK_SLASH: priChar = capitalChar = '/'; shiftChar = '\?'; break;
  1128. case 0x35: priChar = (UCHAR)'é'; capitalChar = shiftChar = (UCHAR)'É'; altChar = (UCHAR)'´'; break;
  1129. case DIK_MULTIPLY: priChar = capitalChar = shiftChar = '*'; onNumPad = 1; break; // * on numeric keypad
  1130. case DIK_SPACE: priChar = capitalChar = shiftChar = ' '; break;
  1131. case DIK_ADD: priChar = capitalChar = shiftChar = '+'; onNumPad = 1; break; // + on numeric keypad
  1132. case DIK_DIVIDE: priChar = capitalChar = shiftChar = '/'; onNumPad = 1; break; // / on numeric keypad
  1133. case DIK_SUBTRACT: priChar = capitalChar = shiftChar = '-'; onNumPad = 1; break; // - on numeric keypad
  1134. case DIK_NUMPAD7: priChar = shiftChar = capitalChar = '7'; onNumPad = 1; break;
  1135. case DIK_NUMPAD8: priChar = shiftChar = capitalChar = '8'; onNumPad = 1; break;
  1136. case DIK_NUMPAD9: priChar = shiftChar = capitalChar = '9'; onNumPad = 1; break;
  1137. case DIK_NUMPAD4: priChar = shiftChar = capitalChar = '4'; onNumPad = 1; break;
  1138. case DIK_NUMPAD5: priChar = shiftChar = capitalChar = '5'; onNumPad = 1; break;
  1139. case DIK_NUMPAD6: priChar = shiftChar = capitalChar = '6'; onNumPad = 1; break;
  1140. case DIK_NUMPAD1: priChar = shiftChar = capitalChar = '1'; onNumPad = 1; break;
  1141. case DIK_NUMPAD2: priChar = shiftChar = capitalChar = '2'; onNumPad = 1; break;
  1142. case DIK_NUMPAD3: priChar = shiftChar = capitalChar = '3'; onNumPad = 1; break;
  1143. case DIK_NUMPAD0: priChar = shiftChar = capitalChar = '0'; onNumPad = 1; break;
  1144. case DIK_DECIMAL: priChar = shiftChar = capitalChar = '.'; onNumPad = 1; break;
  1145. // function keys
  1146. case DIK_F1: priChar = shiftChar = capitalChar = KEY_F1; break;
  1147. case DIK_F2: priChar = shiftChar = capitalChar = KEY_F2; break;
  1148. case DIK_F3: priChar = shiftChar = capitalChar = KEY_F3; break;
  1149. case DIK_F4: priChar = shiftChar = capitalChar = KEY_F4; break;
  1150. case DIK_F5: priChar = shiftChar = capitalChar = KEY_F5; break;
  1151. case DIK_F6: priChar = shiftChar = capitalChar = KEY_F6; break;
  1152. case DIK_F7: priChar = shiftChar = capitalChar = KEY_F7; break;
  1153. case DIK_F8: priChar = shiftChar = capitalChar = KEY_F8; break;
  1154. case DIK_F9: priChar = shiftChar = capitalChar = KEY_F9; break;
  1155. case DIK_F10: priChar = shiftChar = capitalChar = KEY_F10; break;
  1156. case DIK_F11: priChar = shiftChar = capitalChar = KEY_F11; break;
  1157. case DIK_F12: priChar = shiftChar = capitalChar = KEY_F12; break;
  1158. // arrow keys
  1159. case DIK_HOME: priChar = shiftChar = capitalChar = KEY_HOME; break;
  1160. case DIK_UP: priChar = shiftChar = capitalChar = KEY_UP; break;
  1161. case DIK_PRIOR: priChar = shiftChar = capitalChar = KEY_PGUP; break;
  1162. case DIK_LEFT: priChar = shiftChar = capitalChar = KEY_LEFT; break;
  1163. case DIK_RIGHT: priChar = shiftChar = capitalChar = KEY_RIGHT; break;
  1164. case DIK_END: priChar = shiftChar = capitalChar = KEY_END; break;
  1165. case DIK_DOWN: priChar = shiftChar = capitalChar = KEY_DOWN; break;
  1166. case DIK_NEXT: priChar = shiftChar = capitalChar = KEY_PGDN; break;
  1167. case DIK_INSERT: priChar = shiftChar = capitalChar = KEY_INS; break;
  1168. case DIK_DELETE: priChar = shiftChar = capitalChar = KEY_DEL; break;
  1169. // other keys found in Japanese keyboard
  1170. case DIK_NUMPADCOMMA: priChar = shiftChar = capitalChar = ','; break;
  1171. case DIK_NUMPADEQUALS: priChar = shiftChar = capitalChar = '='; break;
  1172. case DIK_AT: priChar = shiftChar = capitalChar = '@'; break;
  1173. case DIK_COLON: priChar = shiftChar = capitalChar = ':'; break;
  1174. case DIK_UNDERLINE: priChar = shiftChar = capitalChar = '_'; break;
  1175. }
  1176. // BUGHERE : numpad key is not translated when numlock is off
  1177. // check flags
  1178. int retFlag = 1;
  1179. // check shift key state
  1180. if( !(flags & K_IGNORE_SHIFT) )
  1181. {
  1182. if( flags & K_IS_SHIFT )
  1183. {
  1184. if( !(skeyState & SHIFT_KEY_MASK) )
  1185. retFlag = 0;
  1186. }
  1187. else
  1188. {
  1189. if( skeyState & SHIFT_KEY_MASK )
  1190. retFlag = 0;
  1191. }
  1192. }
  1193. // check contrl key state
  1194. if( !(flags & K_IGNORE_CTRL) )
  1195. {
  1196. if( flags & K_IS_CTRL )
  1197. {
  1198. if( !(skeyState & CONTROL_KEY_MASK) )
  1199. retFlag = 0;
  1200. }
  1201. else
  1202. {
  1203. if( skeyState & CONTROL_KEY_MASK )
  1204. retFlag = 0;
  1205. }
  1206. }
  1207. // check alt key state
  1208. if( !(flags & K_IGNORE_ALT) )
  1209. {
  1210. if( flags & K_IS_ALT )
  1211. {
  1212. if( !(skeyState & ALT_KEY_MASK) )
  1213. retFlag = 0;
  1214. }
  1215. else
  1216. {
  1217. if( skeyState & ALT_KEY_MASK )
  1218. retFlag = 0;
  1219. }
  1220. }
  1221. // check numpad state
  1222. if( !(flags & K_IGNORE_NUMPAD) )
  1223. {
  1224. if( flags & K_ON_NUMPAD )
  1225. {
  1226. if( !onNumPad )
  1227. retFlag = 0;
  1228. }
  1229. else
  1230. {
  1231. if( onNumPad )
  1232. retFlag = 0;
  1233. }
  1234. }
  1235. unsigned outChar = priChar;
  1236. if( flags & K_TRANSLATE_KEY )
  1237. {
  1238. if( (skeyState & GRAPH_KEY_MASK) && altChar )
  1239. {
  1240. outChar = altChar;
  1241. }
  1242. else
  1243. {
  1244. if( priChar == capitalChar )
  1245. {
  1246. // non-letter
  1247. outChar = skeyState & SHIFT_KEY_MASK ? shiftChar : priChar;
  1248. }
  1249. else
  1250. {
  1251. // letter
  1252. outChar = skeyState & CAP_LOCK_STATE_MASK ?
  1253. (skeyState & SHIFT_KEY_MASK ? priChar : capitalChar) :
  1254. (skeyState & SHIFT_KEY_MASK ? shiftChar : priChar) ;
  1255. }
  1256. }
  1257. }
  1258. if(!retFlag)
  1259. return 0;
  1260. int retFlag2 = (charValue == 0) || outChar == charValue
  1261. || ((flags & K_IGNORE_SHIFT) && shiftChar == charValue)
  1262. || ((flags & K_IGNORE_CAP_LOCK) && capitalChar == charValue)
  1263. #ifdef WIN32
  1264. || ((flags & K_CASE_INSENSITIVE) && outChar == (unsigned short) std::tolower(charValue));
  1265. #else
  1266. || ((flags & K_CASE_INSENSITIVE) && outChar == (unsigned short) tolower(charValue));
  1267. #endif
  1268. if(retFlag2)
  1269. return outChar;
  1270. else
  1271. return 0;
  1272. }
  1273. // ------ End of Mouse::is_key -------//
  1274. // ------ Begin of Mouse::is_key -------//
  1275. int Mouse::is_key(unsigned scanCode, unsigned short skeyState, char *keyStr, unsigned flags)
  1276. {
  1277. int len = strlen(keyStr);
  1278. if( len == 0)
  1279. return 0;
  1280. if( len == 1)
  1281. return is_key(scanCode, skeyState, keyStr[0], flags);
  1282. char *priChar = NULL;
  1283. char *numLockChar = NULL;
  1284. int onNumPad = 0;
  1285. switch(scanCode)
  1286. {
  1287. case DIK_F1: numLockChar = priChar = "F1"; break;
  1288. case DIK_F2: numLockChar = priChar = "F2"; break;
  1289. case DIK_F3: numLockChar = priChar = "F3"; break;
  1290. case DIK_F4: numLockChar = priChar = "F4"; break;
  1291. case DIK_F5: numLockChar = priChar = "F5"; break;
  1292. case DIK_F6: numLockChar = priChar = "F6"; break;
  1293. case DIK_F7: numLockChar = priChar = "F7"; break;
  1294. case DIK_F8: numLockChar = priChar = "F8"; break;
  1295. case DIK_F9: numLockChar = priChar = "F9"; break;
  1296. case DIK_F10: numLockChar = priChar = "F10"; break;
  1297. case DIK_F11: numLockChar = priChar = "F11"; break;
  1298. case DIK_F12: numLockChar = priChar = "F12"; break;
  1299. case DIK_NUMPAD7: priChar = "HOME"; numLockChar = "7"; onNumPad = 1; break;
  1300. case DIK_NUMPAD8: priChar = "UP"; numLockChar = "8"; onNumPad = 1; break;
  1301. case DIK_NUMPAD9: priChar = "PAGE UP"; numLockChar = "9"; onNumPad = 1; break;
  1302. case DIK_NUMPAD4: priChar = "LEFT"; numLockChar = "4"; onNumPad = 1; break;
  1303. case DIK_NUMPAD5: priChar = "CENTER"; numLockChar = "5"; onNumPad = 1; break;
  1304. case DIK_NUMPAD6: priChar = "RIGHT"; numLockChar = "6"; onNumPad = 1; break;
  1305. case DIK_NUMPAD1: priChar = "END"; numLockChar = "1"; onNumPad = 1; break;
  1306. case DIK_NUMPAD2: priChar = "DOWN"; numLockChar = "2"; onNumPad = 1; break;
  1307. case DIK_NUMPAD3: priChar = "PAGE DOWN"; numLockChar = "3"; onNumPad = 1; break;
  1308. case DIK_NUMPAD0: priChar = "INSERT"; numLockChar = "0"; onNumPad = 1; break;
  1309. case DIK_DECIMAL: priChar = "DELETE"; numLockChar = "."; onNumPad = 1; break;
  1310. // keys above arrow keys
  1311. case DIK_HOME: priChar = numLockChar = "HOME"; break;
  1312. case DIK_UP: priChar = numLockChar = "UP"; break;
  1313. case DIK_PRIOR: priChar = numLockChar = "PAGE UP"; break;
  1314. case DIK_LEFT: priChar = numLockChar = "LEFT"; break;
  1315. case DIK_RIGHT: priChar = numLockChar = "RIGHT"; break;
  1316. case DIK_END: priChar = numLockChar = "END"; break;
  1317. case DIK_DOWN: priChar = numLockChar = "DOWN"; break;
  1318. case DIK_NEXT: priChar = numLockChar = "PAGE DOWN"; break;
  1319. case DIK_INSERT: priChar = numLockChar = "INSERT"; break;
  1320. case DIK_DELETE: priChar = numLockChar = "DELETE"; break;
  1321. // 104-key only
  1322. case DIK_LWIN: priChar = numLockChar = "LEFT WINDOW"; break;
  1323. case DIK_RWIN: priChar = numLockChar = "RIGHT WINDOW"; break;
  1324. case DIK_APPS: priChar = numLockChar = "APP MENU"; break;
  1325. }
  1326. // check flags
  1327. int retFlag = 1;
  1328. // check shift key state
  1329. if( !(flags & K_IGNORE_SHIFT) )
  1330. {
  1331. if( flags & K_IS_SHIFT )
  1332. {
  1333. if( !(skeyState & SHIFT_KEY_MASK) )
  1334. retFlag = 0;
  1335. }
  1336. else
  1337. {
  1338. if( skeyState & SHIFT_KEY_MASK )
  1339. retFlag = 0;
  1340. }
  1341. }
  1342. // check contrl key state
  1343. if( !(flags & K_IGNORE_CTRL) )
  1344. {
  1345. if( flags & K_IS_CTRL )
  1346. {
  1347. if( !(skeyState & CONTROL_KEY_MASK) )
  1348. retFlag = 0;
  1349. }
  1350. else
  1351. {
  1352. if( skeyState & CONTROL_KEY_MASK )
  1353. retFlag = 0;
  1354. }
  1355. }
  1356. // check alt key state
  1357. if( !(flags & K_IGNORE_ALT) )
  1358. {
  1359. if( flags & K_IS_ALT )
  1360. {
  1361. if( !(skeyState & ALT_KEY_MASK) )
  1362. retFlag = 0;
  1363. }
  1364. else
  1365. {
  1366. if( skeyState & ALT_KEY_MASK )
  1367. retFlag = 0;
  1368. }
  1369. }
  1370. // check numpad state
  1371. if( !(flags & K_IGNORE_NUMPAD) )
  1372. {
  1373. if( flags & K_ON_NUMPAD )
  1374. {
  1375. if( !onNumPad )
  1376. retFlag = 0;
  1377. }
  1378. else
  1379. {
  1380. if( onNumPad )
  1381. retFlag = 0;
  1382. }
  1383. }
  1384. char *outChar = skeyState & NUM_LOCK_STATE_MASK ? numLockChar : priChar;
  1385. int retFlag2 = outChar ? !strcmp(outChar, keyStr) : 0;
  1386. return retFlag && retFlag2;
  1387. }
  1388. // ------ End of Mouse::is_key -------//
  1389. #endif