OMOUSE.cpp 44 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607
  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(GERMAN) && !defined(FRENCH) && !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 |= RIGHT_ALT_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 |= RIGHT_ALT_KEY_MASK;
  909. else
  910. skey_state &= ~RIGHT_ALT_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 |= RIGHT_ALT_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;
  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 = '!'; break;
  1074. case DIK_2: priChar = capitalChar = '2'; shiftChar = '@'; break;
  1075. case DIK_3: priChar = capitalChar = '3'; shiftChar = '#'; 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 DIK_EQUALS: priChar = capitalChar = '='; shiftChar = '+'; break;
  1085. case DIK_BACK: priChar = capitalChar = shiftChar = KEY_BACK_SPACE; break; // backspace
  1086. case DIK_TAB: priChar = capitalChar = shiftChar = KEY_TAB; break;
  1087. case DIK_Q: priChar = 'q'; capitalChar = shiftChar = 'Q'; break;
  1088. case DIK_W: priChar = 'w'; capitalChar = shiftChar = 'W'; break;
  1089. case DIK_E: priChar = 'e'; capitalChar = shiftChar = 'E'; break;
  1090. case DIK_R: priChar = 'r'; capitalChar = shiftChar = 'R'; break;
  1091. case DIK_T: priChar = 't'; capitalChar = shiftChar = 'T'; break;
  1092. case DIK_Y: priChar = 'y'; capitalChar = shiftChar = 'Y'; break;
  1093. case DIK_U: priChar = 'u'; capitalChar = shiftChar = 'U'; break;
  1094. case DIK_I: priChar = 'i'; capitalChar = shiftChar = 'I'; break;
  1095. case DIK_O: priChar = 'o'; capitalChar = shiftChar = 'O'; break;
  1096. case DIK_P: priChar = 'p'; capitalChar = shiftChar = 'P'; break;
  1097. case DIK_LBRACKET: priChar = capitalChar = '['; shiftChar = '{'; break;
  1098. case DIK_RBRACKET: priChar = capitalChar = ']'; shiftChar = '}'; 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 = ':'; break;
  1112. case DIK_APOSTROPHE: priChar = capitalChar = '\''; shiftChar = '\"'; break;
  1113. case DIK_GRAVE: priChar = capitalChar = '~'; shiftChar = '`'; break;
  1114. case DIK_BACKSLASH: priChar = capitalChar = '\\'; shiftChar = '|'; break;
  1115. case DIK_Z: priChar = 'z'; capitalChar = shiftChar = 'Z'; break;
  1116. case DIK_X: priChar = 'x'; capitalChar = shiftChar = 'X'; break;
  1117. case DIK_C: priChar = 'c'; capitalChar = shiftChar = 'C'; break;
  1118. case DIK_V: priChar = 'v'; capitalChar = shiftChar = 'V'; break;
  1119. case DIK_B: priChar = 'b'; capitalChar = shiftChar = 'B'; break;
  1120. case DIK_N: priChar = 'n'; capitalChar = shiftChar = 'N'; break;
  1121. case DIK_M: priChar = 'm'; capitalChar = shiftChar = 'M'; break;
  1122. case DIK_COMMA: priChar = capitalChar = ','; shiftChar = '<'; break;
  1123. case DIK_PERIOD: priChar = capitalChar = '.'; shiftChar = '>'; break;
  1124. case DIK_SLASH: priChar = capitalChar = '/'; shiftChar = '\?'; break;
  1125. case DIK_MULTIPLY: priChar = capitalChar = shiftChar = '*'; onNumPad = 1; break; // * on numeric keypad
  1126. case DIK_SPACE: priChar = capitalChar = shiftChar = ' '; break;
  1127. case DIK_ADD: priChar = capitalChar = shiftChar = '+'; onNumPad = 1; break; // + on numeric keypad
  1128. case DIK_DIVIDE: priChar = capitalChar = shiftChar = '/'; onNumPad = 1; break; // / on numeric keypad
  1129. case DIK_SUBTRACT: priChar = capitalChar = shiftChar = '-'; onNumPad = 1; break; // - on numeric keypad
  1130. case DIK_NUMPAD7: priChar = shiftChar = capitalChar = '7'; onNumPad = 1; break;
  1131. case DIK_NUMPAD8: priChar = shiftChar = capitalChar = '8'; onNumPad = 1; break;
  1132. case DIK_NUMPAD9: priChar = shiftChar = capitalChar = '9'; onNumPad = 1; break;
  1133. case DIK_NUMPAD4: priChar = shiftChar = capitalChar = '4'; onNumPad = 1; break;
  1134. case DIK_NUMPAD5: priChar = shiftChar = capitalChar = '5'; onNumPad = 1; break;
  1135. case DIK_NUMPAD6: priChar = shiftChar = capitalChar = '6'; onNumPad = 1; break;
  1136. case DIK_NUMPAD1: priChar = shiftChar = capitalChar = '1'; onNumPad = 1; break;
  1137. case DIK_NUMPAD2: priChar = shiftChar = capitalChar = '2'; onNumPad = 1; break;
  1138. case DIK_NUMPAD3: priChar = shiftChar = capitalChar = '3'; onNumPad = 1; break;
  1139. case DIK_NUMPAD0: priChar = shiftChar = capitalChar = '0'; onNumPad = 1; break;
  1140. case DIK_DECIMAL: priChar = shiftChar = capitalChar = '.'; onNumPad = 1; break;
  1141. // function keys
  1142. case DIK_F1: priChar = shiftChar = capitalChar = KEY_F1; break;
  1143. case DIK_F2: priChar = shiftChar = capitalChar = KEY_F2; break;
  1144. case DIK_F3: priChar = shiftChar = capitalChar = KEY_F3; break;
  1145. case DIK_F4: priChar = shiftChar = capitalChar = KEY_F4; break;
  1146. case DIK_F5: priChar = shiftChar = capitalChar = KEY_F5; break;
  1147. case DIK_F6: priChar = shiftChar = capitalChar = KEY_F6; break;
  1148. case DIK_F7: priChar = shiftChar = capitalChar = KEY_F7; break;
  1149. case DIK_F8: priChar = shiftChar = capitalChar = KEY_F8; break;
  1150. case DIK_F9: priChar = shiftChar = capitalChar = KEY_F9; break;
  1151. case DIK_F10: priChar = shiftChar = capitalChar = KEY_F10; break;
  1152. case DIK_F11: priChar = shiftChar = capitalChar = KEY_F11; break;
  1153. case DIK_F12: priChar = shiftChar = capitalChar = KEY_F12; break;
  1154. // arrow keys
  1155. case DIK_HOME: priChar = shiftChar = capitalChar = KEY_HOME; break;
  1156. case DIK_UP: priChar = shiftChar = capitalChar = KEY_UP; break;
  1157. case DIK_PRIOR: priChar = shiftChar = capitalChar = KEY_PGUP; break;
  1158. case DIK_LEFT: priChar = shiftChar = capitalChar = KEY_LEFT; break;
  1159. case DIK_RIGHT: priChar = shiftChar = capitalChar = KEY_RIGHT; break;
  1160. case DIK_END: priChar = shiftChar = capitalChar = KEY_END; break;
  1161. case DIK_DOWN: priChar = shiftChar = capitalChar = KEY_DOWN; break;
  1162. case DIK_NEXT: priChar = shiftChar = capitalChar = KEY_PGDN; break;
  1163. case DIK_INSERT: priChar = shiftChar = capitalChar = KEY_INS; break;
  1164. case DIK_DELETE: priChar = shiftChar = capitalChar = KEY_DEL; break;
  1165. // other keys found in Japanese keyboard
  1166. case DIK_NUMPADCOMMA: priChar = shiftChar = capitalChar = ','; break;
  1167. case DIK_NUMPADEQUALS: priChar = shiftChar = capitalChar = '='; break;
  1168. case DIK_AT: priChar = shiftChar = capitalChar = '@'; break;
  1169. case DIK_COLON: priChar = shiftChar = capitalChar = ':'; break;
  1170. case DIK_UNDERLINE: priChar = shiftChar = capitalChar = '_'; break;
  1171. }
  1172. // BUGHERE : numpad key is not translated when numlock is off
  1173. // check flags
  1174. int retFlag = 1;
  1175. // check shift key state
  1176. if( !(flags & K_IGNORE_SHIFT) )
  1177. {
  1178. if( flags & K_IS_SHIFT )
  1179. {
  1180. if( !(skeyState & SHIFT_KEY_MASK) )
  1181. retFlag = 0;
  1182. }
  1183. else
  1184. {
  1185. if( skeyState & SHIFT_KEY_MASK )
  1186. retFlag = 0;
  1187. }
  1188. }
  1189. // check contrl key state
  1190. if( !(flags & K_IGNORE_CTRL) )
  1191. {
  1192. if( flags & K_IS_CTRL )
  1193. {
  1194. if( !(skeyState & CONTROL_KEY_MASK) )
  1195. retFlag = 0;
  1196. }
  1197. else
  1198. {
  1199. if( skeyState & CONTROL_KEY_MASK )
  1200. retFlag = 0;
  1201. }
  1202. }
  1203. // check alt key state
  1204. if( !(flags & K_IGNORE_ALT) )
  1205. {
  1206. if( flags & K_IS_ALT )
  1207. {
  1208. if( !(skeyState & ALT_KEY_MASK) )
  1209. retFlag = 0;
  1210. }
  1211. else
  1212. {
  1213. if( skeyState & ALT_KEY_MASK )
  1214. retFlag = 0;
  1215. }
  1216. }
  1217. // check numpad state
  1218. if( !(flags & K_IGNORE_NUMPAD) )
  1219. {
  1220. if( flags & K_ON_NUMPAD )
  1221. {
  1222. if( !onNumPad )
  1223. retFlag = 0;
  1224. }
  1225. else
  1226. {
  1227. if( onNumPad )
  1228. retFlag = 0;
  1229. }
  1230. }
  1231. unsigned outChar = priChar;
  1232. if( flags & K_TRANSLATE_KEY )
  1233. {
  1234. if( priChar == capitalChar )
  1235. {
  1236. // non-letter
  1237. outChar = skeyState & SHIFT_KEY_MASK ? shiftChar : priChar;
  1238. }
  1239. else
  1240. {
  1241. // letter
  1242. outChar = skeyState & CAP_LOCK_STATE_MASK ?
  1243. (skeyState & SHIFT_KEY_MASK ? priChar : capitalChar) :
  1244. (skeyState & SHIFT_KEY_MASK ? shiftChar : priChar) ;
  1245. }
  1246. }
  1247. if(!retFlag)
  1248. return 0;
  1249. int retFlag2 = (charValue == 0) || outChar == charValue
  1250. || ((flags & K_IGNORE_SHIFT) && shiftChar == charValue)
  1251. || ((flags & K_IGNORE_CAP_LOCK) && capitalChar == charValue)
  1252. #ifdef WIN32
  1253. || ((flags & K_CASE_INSENSITIVE) && outChar == (unsigned short) std::tolower(charValue));
  1254. #else
  1255. || ((flags & K_CASE_INSENSITIVE) && outChar == (unsigned short) tolower(charValue));
  1256. #endif
  1257. if(retFlag2)
  1258. return outChar;
  1259. else
  1260. return 0;
  1261. }
  1262. // ------ End of Mouse::is_key -------//
  1263. // ------ Begin of Mouse::is_key -------//
  1264. int Mouse::is_key(unsigned scanCode, unsigned short skeyState, char *keyStr, unsigned flags)
  1265. {
  1266. int len = strlen(keyStr);
  1267. if( len == 0)
  1268. return 0;
  1269. if( len == 1)
  1270. return is_key(scanCode, skeyState, keyStr[0], flags);
  1271. char *priChar = NULL;
  1272. char *numLockChar = NULL;
  1273. int onNumPad = 0;
  1274. switch(scanCode)
  1275. {
  1276. case DIK_F1: numLockChar = priChar = "F1"; break;
  1277. case DIK_F2: numLockChar = priChar = "F2"; break;
  1278. case DIK_F3: numLockChar = priChar = "F3"; break;
  1279. case DIK_F4: numLockChar = priChar = "F4"; break;
  1280. case DIK_F5: numLockChar = priChar = "F5"; break;
  1281. case DIK_F6: numLockChar = priChar = "F6"; break;
  1282. case DIK_F7: numLockChar = priChar = "F7"; break;
  1283. case DIK_F8: numLockChar = priChar = "F8"; break;
  1284. case DIK_F9: numLockChar = priChar = "F9"; break;
  1285. case DIK_F10: numLockChar = priChar = "F10"; break;
  1286. case DIK_F11: numLockChar = priChar = "F11"; break;
  1287. case DIK_F12: numLockChar = priChar = "F12"; break;
  1288. case DIK_NUMPAD7: priChar = "HOME"; numLockChar = "7"; onNumPad = 1; break;
  1289. case DIK_NUMPAD8: priChar = "UP"; numLockChar = "8"; onNumPad = 1; break;
  1290. case DIK_NUMPAD9: priChar = "PAGE UP"; numLockChar = "9"; onNumPad = 1; break;
  1291. case DIK_NUMPAD4: priChar = "LEFT"; numLockChar = "4"; onNumPad = 1; break;
  1292. case DIK_NUMPAD5: priChar = "CENTER"; numLockChar = "5"; onNumPad = 1; break;
  1293. case DIK_NUMPAD6: priChar = "RIGHT"; numLockChar = "6"; onNumPad = 1; break;
  1294. case DIK_NUMPAD1: priChar = "END"; numLockChar = "1"; onNumPad = 1; break;
  1295. case DIK_NUMPAD2: priChar = "DOWN"; numLockChar = "2"; onNumPad = 1; break;
  1296. case DIK_NUMPAD3: priChar = "PAGE DOWN"; numLockChar = "3"; onNumPad = 1; break;
  1297. case DIK_NUMPAD0: priChar = "INSERT"; numLockChar = "0"; onNumPad = 1; break;
  1298. case DIK_DECIMAL: priChar = "DELETE"; numLockChar = "."; onNumPad = 1; break;
  1299. // keys above arrow keys
  1300. case DIK_HOME: priChar = numLockChar = "HOME"; break;
  1301. case DIK_UP: priChar = numLockChar = "UP"; break;
  1302. case DIK_PRIOR: priChar = numLockChar = "PAGE UP"; break;
  1303. case DIK_LEFT: priChar = numLockChar = "LEFT"; break;
  1304. case DIK_RIGHT: priChar = numLockChar = "RIGHT"; break;
  1305. case DIK_END: priChar = numLockChar = "END"; break;
  1306. case DIK_DOWN: priChar = numLockChar = "DOWN"; break;
  1307. case DIK_NEXT: priChar = numLockChar = "PAGE DOWN"; break;
  1308. case DIK_INSERT: priChar = numLockChar = "INSERT"; break;
  1309. case DIK_DELETE: priChar = numLockChar = "DELETE"; break;
  1310. // 104-key only
  1311. case DIK_LWIN: priChar = numLockChar = "LEFT WINDOW"; break;
  1312. case DIK_RWIN: priChar = numLockChar = "RIGHT WINDOW"; break;
  1313. case DIK_APPS: priChar = numLockChar = "APP MENU"; break;
  1314. }
  1315. // check flags
  1316. int retFlag = 1;
  1317. // check shift key state
  1318. if( !(flags & K_IGNORE_SHIFT) )
  1319. {
  1320. if( flags & K_IS_SHIFT )
  1321. {
  1322. if( !(skeyState & SHIFT_KEY_MASK) )
  1323. retFlag = 0;
  1324. }
  1325. else
  1326. {
  1327. if( skeyState & SHIFT_KEY_MASK )
  1328. retFlag = 0;
  1329. }
  1330. }
  1331. // check contrl key state
  1332. if( !(flags & K_IGNORE_CTRL) )
  1333. {
  1334. if( flags & K_IS_CTRL )
  1335. {
  1336. if( !(skeyState & CONTROL_KEY_MASK) )
  1337. retFlag = 0;
  1338. }
  1339. else
  1340. {
  1341. if( skeyState & CONTROL_KEY_MASK )
  1342. retFlag = 0;
  1343. }
  1344. }
  1345. // check alt key state
  1346. if( !(flags & K_IGNORE_ALT) )
  1347. {
  1348. if( flags & K_IS_ALT )
  1349. {
  1350. if( !(skeyState & ALT_KEY_MASK) )
  1351. retFlag = 0;
  1352. }
  1353. else
  1354. {
  1355. if( skeyState & ALT_KEY_MASK )
  1356. retFlag = 0;
  1357. }
  1358. }
  1359. // check numpad state
  1360. if( !(flags & K_IGNORE_NUMPAD) )
  1361. {
  1362. if( flags & K_ON_NUMPAD )
  1363. {
  1364. if( !onNumPad )
  1365. retFlag = 0;
  1366. }
  1367. else
  1368. {
  1369. if( onNumPad )
  1370. retFlag = 0;
  1371. }
  1372. }
  1373. char *outChar = skeyState & NUM_LOCK_STATE_MASK ? numLockChar : priChar;
  1374. int retFlag2 = outChar ? !strcmp(outChar, keyStr) : 0;
  1375. return retFlag && retFlag2;
  1376. }
  1377. // ------ End of Mouse::is_key -------//
  1378. #endif