Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.
 
 
 
 
 
 

640 строки
21 KiB

  1. /*
  2. * libcaca ASCII-Art library
  3. * Copyright (c) 2002, 2003 Sam Hocevar <sam@zoy.org>
  4. * All Rights Reserved
  5. *
  6. * This library is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2 of the License, or (at your option) any later version.
  10. *
  11. * This library 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 GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with this library; if not, write to the Free Software
  18. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  19. * 02111-1307 USA
  20. */
  21. /** \file io.c
  22. * \version \$Id$
  23. * \author Sam Hocevar <sam@zoy.org>
  24. * \brief Event handling
  25. *
  26. * This file contains event handling functions for keyboard and mouse input.
  27. */
  28. #include "config.h"
  29. #if defined(USE_SLANG)
  30. # if defined(HAVE_SLANG_SLANG_H)
  31. # include <slang/slang.h>
  32. # else
  33. # include <slang.h>
  34. # endif
  35. #endif
  36. #if defined(USE_NCURSES)
  37. # include <curses.h>
  38. #endif
  39. #if defined(USE_CONIO)
  40. # include <conio.h>
  41. #endif
  42. #if defined(USE_X11)
  43. # include <X11/Xlib.h>
  44. # include <X11/Xutil.h>
  45. # include <X11/keysym.h>
  46. #endif
  47. #if defined(USE_WIN32)
  48. # include <windows.h>
  49. #endif
  50. #include "caca.h"
  51. #include "caca_internals.h"
  52. static unsigned int _get_next_event(void);
  53. static unsigned int _lowlevel_event(void);
  54. #if defined(USE_SLANG) || defined(USE_NCURSES) || defined(USE_CONIO)
  55. static void _push_event(unsigned int);
  56. static unsigned int _pop_event(void);
  57. #endif
  58. #if !defined(_DOXYGEN_SKIP_ME)
  59. #define EVENTBUF_LEN 10
  60. #endif
  61. #if defined(USE_SLANG) || defined(USE_NCURSES) || defined(USE_CONIO)
  62. static unsigned int eventbuf[EVENTBUF_LEN];
  63. static int events = 0;
  64. #endif
  65. #if !defined(_DOXYGEN_SKIP_ME)
  66. /* If no new key was pressed after AUTOREPEAT_THRESHOLD usec, assume the
  67. * key was released */
  68. #define AUTOREPEAT_THRESHOLD 200000
  69. /* Start repeating key after AUTOREPEAT_TRIGGER usec and send keypress
  70. * events every AUTOREPEAT_RATE usec. */
  71. #define AUTOREPEAT_TRIGGER 300000
  72. #define AUTOREPEAT_RATE 100000
  73. #endif
  74. /** \brief Get the next mouse or keyboard input event.
  75. *
  76. * This function polls the event queue for mouse or keyboard events matching
  77. * the event mask and returns the first matching event. Non-matching events
  78. * are discarded. \c event_mask must have a non-zero value. This function is
  79. * non-blocking and returns zero if no more events are pending in the queue.
  80. * See also caca_wait_event() for a blocking version of this function.
  81. *
  82. * \param event_mask Bitmask of requested events.
  83. * \return The next matching event in the queue, or 0 if no event is pending.
  84. */
  85. unsigned int caca_get_event(unsigned int event_mask)
  86. {
  87. if(!event_mask)
  88. return CACA_EVENT_NONE;
  89. for( ; ; )
  90. {
  91. unsigned int event = _get_next_event();
  92. if(!event || event & event_mask)
  93. return event;
  94. }
  95. }
  96. /** \brief Wait for the next mouse or keyboard input event.
  97. *
  98. * This function returns the first mouse or keyboard event in the queue
  99. * that matches the event mask. If no event is pending, it blocks until a
  100. * matching event is received. \c event_mask must have a non-zero value.
  101. * See also caca_get_event() for a non-blocking version of this function.
  102. *
  103. * \param event_mask Bitmask of requested events.
  104. * \return The next event in the queue.
  105. */
  106. unsigned int caca_wait_event(unsigned int event_mask)
  107. {
  108. if(!event_mask)
  109. return CACA_EVENT_NONE;
  110. for( ; ; )
  111. {
  112. unsigned int event = _get_next_event();
  113. if(event & event_mask)
  114. return event;
  115. _caca_sleep(10000);
  116. }
  117. }
  118. /*
  119. * XXX: The following functions are local.
  120. */
  121. static unsigned int _get_next_event(void)
  122. {
  123. #if defined(USE_SLANG) || defined(USE_NCURSES)
  124. static struct caca_timer key_timer = CACA_TIMER_INITIALIZER;
  125. static unsigned int last_key_ticks = 0;
  126. static unsigned int autorepeat_ticks = 0;
  127. static unsigned int last_key = 0;
  128. unsigned int ticks;
  129. #endif
  130. unsigned int event = _lowlevel_event();
  131. #if defined(USE_SLANG)
  132. if(_caca_driver != CACA_DRIVER_SLANG)
  133. #endif
  134. #if defined(USE_NCURSES)
  135. if(_caca_driver != CACA_DRIVER_NCURSES)
  136. #endif
  137. return event;
  138. #if defined(USE_SLANG) || defined(USE_NCURSES)
  139. /* Simulate long keypresses using autorepeat features */
  140. ticks = _caca_getticks(&key_timer);
  141. last_key_ticks += ticks;
  142. autorepeat_ticks += ticks;
  143. /* Handle autorepeat */
  144. if(last_key && autorepeat_ticks > AUTOREPEAT_TRIGGER
  145. && autorepeat_ticks > AUTOREPEAT_THRESHOLD
  146. && autorepeat_ticks > AUTOREPEAT_RATE)
  147. {
  148. _push_event(event);
  149. autorepeat_ticks -= AUTOREPEAT_RATE;
  150. return CACA_EVENT_KEY_PRESS | last_key;
  151. }
  152. /* We are in autorepeat mode and the same key was just pressed, ignore
  153. * this event and return the next one by calling ourselves. */
  154. if(event == (CACA_EVENT_KEY_PRESS | last_key))
  155. {
  156. last_key_ticks = 0;
  157. return _get_next_event();
  158. }
  159. /* We are in autorepeat mode, but key has expired or a new key was
  160. * pressed - store our event and return a key release event first */
  161. if(last_key && (last_key_ticks > AUTOREPEAT_THRESHOLD
  162. || (event & CACA_EVENT_KEY_PRESS)))
  163. {
  164. _push_event(event);
  165. event = CACA_EVENT_KEY_RELEASE | last_key;
  166. last_key = 0;
  167. return event;
  168. }
  169. /* A new key was pressed, enter autorepeat mode */
  170. if(event & CACA_EVENT_KEY_PRESS)
  171. {
  172. last_key_ticks = 0;
  173. autorepeat_ticks = 0;
  174. last_key = event & 0x00ffffff;
  175. }
  176. return event;
  177. #endif
  178. }
  179. static unsigned int _lowlevel_event(void)
  180. {
  181. unsigned int event;
  182. #if defined(USE_SLANG) || defined(USE_NCURSES) || defined(USE_CONIO)
  183. event = _pop_event();
  184. if(event)
  185. return event;
  186. #endif
  187. #if defined(USE_X11)
  188. /* The X11 event check routine */
  189. if(_caca_driver == CACA_DRIVER_X11)
  190. {
  191. XEvent xevent;
  192. static unsigned int x11_x = 0, x11_y = 0;
  193. long int xevent_mask = KeyPressMask | KeyReleaseMask | ButtonPressMask
  194. | ButtonReleaseMask | PointerMotionMask;
  195. char key;
  196. while(XCheckWindowEvent(x11_dpy, x11_window, xevent_mask, &xevent)
  197. == True)
  198. {
  199. KeySym keysym;
  200. /* Check for mouse motion events */
  201. if(xevent.type == MotionNotify)
  202. {
  203. unsigned int newx = xevent.xmotion.x / x11_font_width;
  204. unsigned int newy = xevent.xmotion.y / x11_font_height;
  205. if(newx >= _caca_width)
  206. newx = _caca_width - 1;
  207. if(newy >= _caca_height)
  208. newy = _caca_height - 1;
  209. if(x11_x == newx && x11_y == newy)
  210. continue;
  211. x11_x = newx & 0xfff;
  212. x11_y = newy & 0xfff;
  213. return CACA_EVENT_MOUSE_MOTION | (newx << 12) | (newy << 0);
  214. }
  215. /* Check for mouse press and release events */
  216. if(xevent.type == ButtonPress)
  217. return CACA_EVENT_MOUSE_PRESS
  218. | ((XButtonEvent *)&xevent)->button;
  219. if(xevent.type == ButtonRelease)
  220. return CACA_EVENT_MOUSE_RELEASE
  221. | ((XButtonEvent *)&xevent)->button;
  222. /* Check for key press and release events */
  223. if(xevent.type == KeyPress)
  224. event |= CACA_EVENT_KEY_PRESS;
  225. else if(xevent.type == KeyRelease)
  226. event |= CACA_EVENT_KEY_RELEASE;
  227. else
  228. continue;
  229. if(XLookupString(&xevent.xkey, &key, 1, NULL, NULL))
  230. return event | key;
  231. keysym = XKeycodeToKeysym(x11_dpy, xevent.xkey.keycode, 0);
  232. switch(keysym)
  233. {
  234. case XK_F1: return event | CACA_KEY_F1;
  235. case XK_F2: return event | CACA_KEY_F2;
  236. case XK_F3: return event | CACA_KEY_F3;
  237. case XK_F4: return event | CACA_KEY_F4;
  238. case XK_F5: return event | CACA_KEY_F5;
  239. case XK_F6: return event | CACA_KEY_F6;
  240. case XK_F7: return event | CACA_KEY_F7;
  241. case XK_F8: return event | CACA_KEY_F8;
  242. case XK_F9: return event | CACA_KEY_F9;
  243. case XK_F10: return event | CACA_KEY_F10;
  244. case XK_F11: return event | CACA_KEY_F11;
  245. case XK_F12: return event | CACA_KEY_F12;
  246. case XK_F13: return event | CACA_KEY_F13;
  247. case XK_F14: return event | CACA_KEY_F14;
  248. case XK_F15: return event | CACA_KEY_F15;
  249. case XK_Left: return event | CACA_KEY_LEFT;
  250. case XK_Right: return event | CACA_KEY_RIGHT;
  251. case XK_Up: return event | CACA_KEY_UP;
  252. case XK_Down: return event | CACA_KEY_DOWN;
  253. default: return CACA_EVENT_NONE;
  254. }
  255. }
  256. return CACA_EVENT_NONE;
  257. }
  258. else
  259. #endif
  260. #if defined(USE_NCURSES)
  261. if(_caca_driver == CACA_DRIVER_NCURSES)
  262. {
  263. int intkey = getch();
  264. if(intkey == ERR)
  265. return CACA_EVENT_NONE;
  266. if(intkey < 0x100)
  267. {
  268. return CACA_EVENT_KEY_PRESS | intkey;
  269. }
  270. if(intkey == KEY_MOUSE)
  271. {
  272. MEVENT mevent;
  273. getmouse(&mevent);
  274. switch(mevent.bstate)
  275. {
  276. case BUTTON1_PRESSED:
  277. _push_event(CACA_EVENT_MOUSE_PRESS | 1);
  278. break;
  279. case BUTTON1_RELEASED:
  280. _push_event(CACA_EVENT_MOUSE_RELEASE | 1);
  281. break;
  282. case BUTTON1_CLICKED:
  283. _push_event(CACA_EVENT_MOUSE_PRESS | 1);
  284. _push_event(CACA_EVENT_MOUSE_RELEASE | 1);
  285. break;
  286. case BUTTON1_DOUBLE_CLICKED:
  287. _push_event(CACA_EVENT_MOUSE_PRESS | 1);
  288. _push_event(CACA_EVENT_MOUSE_RELEASE | 1);
  289. _push_event(CACA_EVENT_MOUSE_PRESS | 1);
  290. _push_event(CACA_EVENT_MOUSE_RELEASE | 1);
  291. break;
  292. case BUTTON1_TRIPLE_CLICKED:
  293. _push_event(CACA_EVENT_MOUSE_PRESS | 1);
  294. _push_event(CACA_EVENT_MOUSE_RELEASE | 1);
  295. _push_event(CACA_EVENT_MOUSE_PRESS | 1);
  296. _push_event(CACA_EVENT_MOUSE_RELEASE | 1);
  297. _push_event(CACA_EVENT_MOUSE_PRESS | 1);
  298. _push_event(CACA_EVENT_MOUSE_RELEASE | 1);
  299. break;
  300. case BUTTON1_RESERVED_EVENT:
  301. break;
  302. case BUTTON2_PRESSED:
  303. _push_event(CACA_EVENT_MOUSE_PRESS | 2);
  304. break;
  305. case BUTTON2_RELEASED:
  306. _push_event(CACA_EVENT_MOUSE_RELEASE | 2);
  307. break;
  308. case BUTTON2_CLICKED:
  309. _push_event(CACA_EVENT_MOUSE_PRESS | 2);
  310. _push_event(CACA_EVENT_MOUSE_RELEASE | 2);
  311. break;
  312. case BUTTON2_DOUBLE_CLICKED:
  313. _push_event(CACA_EVENT_MOUSE_PRESS | 2);
  314. _push_event(CACA_EVENT_MOUSE_RELEASE | 2);
  315. _push_event(CACA_EVENT_MOUSE_PRESS | 2);
  316. _push_event(CACA_EVENT_MOUSE_RELEASE | 2);
  317. break;
  318. case BUTTON2_TRIPLE_CLICKED:
  319. _push_event(CACA_EVENT_MOUSE_PRESS | 2);
  320. _push_event(CACA_EVENT_MOUSE_RELEASE | 2);
  321. _push_event(CACA_EVENT_MOUSE_PRESS | 2);
  322. _push_event(CACA_EVENT_MOUSE_RELEASE | 2);
  323. _push_event(CACA_EVENT_MOUSE_PRESS | 2);
  324. _push_event(CACA_EVENT_MOUSE_RELEASE | 2);
  325. break;
  326. case BUTTON2_RESERVED_EVENT:
  327. break;
  328. case BUTTON3_PRESSED:
  329. _push_event(CACA_EVENT_MOUSE_PRESS | 3);
  330. break;
  331. case BUTTON3_RELEASED:
  332. _push_event(CACA_EVENT_MOUSE_RELEASE | 3);
  333. break;
  334. case BUTTON3_CLICKED:
  335. _push_event(CACA_EVENT_MOUSE_PRESS | 3);
  336. _push_event(CACA_EVENT_MOUSE_RELEASE | 3);
  337. break;
  338. case BUTTON3_DOUBLE_CLICKED:
  339. _push_event(CACA_EVENT_MOUSE_PRESS | 3);
  340. _push_event(CACA_EVENT_MOUSE_RELEASE | 3);
  341. _push_event(CACA_EVENT_MOUSE_PRESS | 3);
  342. _push_event(CACA_EVENT_MOUSE_RELEASE | 3);
  343. break;
  344. case BUTTON3_TRIPLE_CLICKED:
  345. _push_event(CACA_EVENT_MOUSE_PRESS | 3);
  346. _push_event(CACA_EVENT_MOUSE_RELEASE | 3);
  347. _push_event(CACA_EVENT_MOUSE_PRESS | 3);
  348. _push_event(CACA_EVENT_MOUSE_RELEASE | 3);
  349. _push_event(CACA_EVENT_MOUSE_PRESS | 3);
  350. _push_event(CACA_EVENT_MOUSE_RELEASE | 3);
  351. break;
  352. case BUTTON3_RESERVED_EVENT:
  353. break;
  354. case BUTTON4_PRESSED:
  355. _push_event(CACA_EVENT_MOUSE_PRESS | 4);
  356. break;
  357. case BUTTON4_RELEASED:
  358. _push_event(CACA_EVENT_MOUSE_RELEASE | 4);
  359. break;
  360. case BUTTON4_CLICKED:
  361. _push_event(CACA_EVENT_MOUSE_PRESS | 4);
  362. _push_event(CACA_EVENT_MOUSE_RELEASE | 4);
  363. break;
  364. case BUTTON4_DOUBLE_CLICKED:
  365. _push_event(CACA_EVENT_MOUSE_PRESS | 4);
  366. _push_event(CACA_EVENT_MOUSE_RELEASE | 4);
  367. _push_event(CACA_EVENT_MOUSE_PRESS | 4);
  368. _push_event(CACA_EVENT_MOUSE_RELEASE | 4);
  369. break;
  370. case BUTTON4_TRIPLE_CLICKED:
  371. _push_event(CACA_EVENT_MOUSE_PRESS | 4);
  372. _push_event(CACA_EVENT_MOUSE_RELEASE | 4);
  373. _push_event(CACA_EVENT_MOUSE_PRESS | 4);
  374. _push_event(CACA_EVENT_MOUSE_RELEASE | 4);
  375. _push_event(CACA_EVENT_MOUSE_PRESS | 4);
  376. _push_event(CACA_EVENT_MOUSE_RELEASE | 4);
  377. break;
  378. case BUTTON4_RESERVED_EVENT:
  379. break;
  380. default:
  381. break;
  382. }
  383. return CACA_EVENT_MOUSE_MOTION | (mevent.x << 12) | mevent.y;
  384. }
  385. event = CACA_EVENT_KEY_PRESS;
  386. switch(intkey)
  387. {
  388. case KEY_UP: return event | CACA_KEY_UP;
  389. case KEY_DOWN: return event | CACA_KEY_DOWN;
  390. case KEY_LEFT: return event | CACA_KEY_LEFT;
  391. case KEY_RIGHT: return event | CACA_KEY_RIGHT;
  392. case KEY_IC: return event | CACA_KEY_INSERT;
  393. case KEY_DC: return event | CACA_KEY_DELETE;
  394. case KEY_HOME: return event | CACA_KEY_HOME;
  395. case KEY_END: return event | CACA_KEY_END;
  396. case KEY_PPAGE: return event | CACA_KEY_PAGEUP;
  397. case KEY_NPAGE: return event | CACA_KEY_PAGEDOWN;
  398. case KEY_F(1): return event | CACA_KEY_F1;
  399. case KEY_F(2): return event | CACA_KEY_F2;
  400. case KEY_F(3): return event | CACA_KEY_F3;
  401. case KEY_F(4): return event | CACA_KEY_F4;
  402. case KEY_F(5): return event | CACA_KEY_F5;
  403. case KEY_F(6): return event | CACA_KEY_F6;
  404. case KEY_F(7): return event | CACA_KEY_F7;
  405. case KEY_F(8): return event | CACA_KEY_F8;
  406. case KEY_F(9): return event | CACA_KEY_F9;
  407. case KEY_F(10): return event | CACA_KEY_F10;
  408. case KEY_F(11): return event | CACA_KEY_F11;
  409. case KEY_F(12): return event | CACA_KEY_F12;
  410. }
  411. return CACA_EVENT_NONE;
  412. }
  413. else
  414. #endif
  415. #if defined(USE_SLANG)
  416. if(_caca_driver == CACA_DRIVER_SLANG)
  417. {
  418. int intkey;
  419. if(!SLang_input_pending(0))
  420. return CACA_EVENT_NONE;
  421. /* We first use SLang_getkey() to see whether Esc was pressed
  422. * alone, then (if it wasn't) we unget the key and use SLkp_getkey()
  423. * instead, so that escape sequences are interpreted. */
  424. intkey = SLang_getkey();
  425. if(intkey != 0x1b /* Esc */ || SLang_input_pending(0))
  426. {
  427. SLang_ungetkey(intkey);
  428. intkey = SLkp_getkey();
  429. }
  430. /* If the key was ASCII, return it immediately */
  431. if(intkey < 0x100)
  432. {
  433. return CACA_EVENT_KEY_PRESS | intkey;
  434. }
  435. if(intkey == 0x3e9)
  436. {
  437. int button = (SLang_getkey() - ' ' + 1) & 0xf;
  438. int x = SLang_getkey() - '!';
  439. int y = SLang_getkey() - '!';
  440. _push_event(CACA_EVENT_MOUSE_PRESS | button);
  441. _push_event(CACA_EVENT_MOUSE_RELEASE | button);
  442. return CACA_EVENT_MOUSE_MOTION | (x << 12) | (y << 0);
  443. }
  444. event = CACA_EVENT_KEY_PRESS;
  445. switch(intkey)
  446. {
  447. case SL_KEY_UP: return event | CACA_KEY_UP;
  448. case SL_KEY_DOWN: return event | CACA_KEY_DOWN;
  449. case SL_KEY_LEFT: return event | CACA_KEY_LEFT;
  450. case SL_KEY_RIGHT: return event | CACA_KEY_RIGHT;
  451. case SL_KEY_IC: return event | CACA_KEY_INSERT;
  452. case SL_KEY_DELETE: return event | CACA_KEY_DELETE;
  453. case SL_KEY_HOME: return event | CACA_KEY_HOME;
  454. case SL_KEY_END: return event | CACA_KEY_END;
  455. case SL_KEY_PPAGE: return event | CACA_KEY_PAGEUP;
  456. case SL_KEY_NPAGE: return event | CACA_KEY_PAGEDOWN;
  457. case SL_KEY_F(1): return event | CACA_KEY_F1;
  458. case SL_KEY_F(2): return event | CACA_KEY_F2;
  459. case SL_KEY_F(3): return event | CACA_KEY_F3;
  460. case SL_KEY_F(4): return event | CACA_KEY_F4;
  461. case SL_KEY_F(5): return event | CACA_KEY_F5;
  462. case SL_KEY_F(6): return event | CACA_KEY_F6;
  463. case SL_KEY_F(7): return event | CACA_KEY_F7;
  464. case SL_KEY_F(8): return event | CACA_KEY_F8;
  465. case SL_KEY_F(9): return event | CACA_KEY_F9;
  466. case SL_KEY_F(10): return event | CACA_KEY_F10;
  467. case SL_KEY_F(11): return event | CACA_KEY_F11;
  468. case SL_KEY_F(12): return event | CACA_KEY_F12;
  469. }
  470. return CACA_EVENT_NONE;
  471. }
  472. else
  473. #endif
  474. #if defined(USE_CONIO)
  475. if(_caca_driver == CACA_DRIVER_CONIO)
  476. {
  477. if(!_conio_kbhit())
  478. return CACA_EVENT_NONE;
  479. event = getch();
  480. _push_event(CACA_EVENT_KEY_RELEASE | event);
  481. return CACA_EVENT_KEY_PRESS | event;
  482. }
  483. else
  484. #endif
  485. #if defined(USE_WIN32)
  486. if(_caca_driver == CACA_DRIVER_WIN32)
  487. {
  488. INPUT_RECORD rec;
  489. DWORD num;
  490. GetNumberOfConsoleInputEvents(win32_hin, &num);
  491. if(num == 0)
  492. return CACA_EVENT_NONE;
  493. ReadConsoleInput(win32_hin, &rec, 1, &num);
  494. if(rec.EventType == KEY_EVENT)
  495. {
  496. if(rec.Event.KeyEvent.bKeyDown)
  497. event = CACA_EVENT_KEY_PRESS;
  498. else
  499. event = CACA_EVENT_KEY_RELEASE;
  500. if(rec.Event.KeyEvent.uChar.AsciiChar)
  501. return event | rec.Event.KeyEvent.uChar.AsciiChar;
  502. }
  503. else if(rec.EventType == MOUSE_EVENT)
  504. {
  505. if(rec.Event.MouseEvent.dwEventFlags == 0)
  506. {
  507. if(rec.Event.MouseEvent.dwButtonState & 0x01)
  508. return CACA_EVENT_MOUSE_PRESS | 0x000001;
  509. if(rec.Event.MouseEvent.dwButtonState & 0x02)
  510. return CACA_EVENT_MOUSE_PRESS | 0x000002;
  511. }
  512. else if(rec.Event.MouseEvent.dwEventFlags == MOUSE_MOVED)
  513. {
  514. return CACA_EVENT_MOUSE_MOTION
  515. | (rec.Event.MouseEvent.dwMousePosition.X << 12)
  516. | (rec.Event.MouseEvent.dwMousePosition.Y);
  517. }
  518. #if 0
  519. else if(rec.Event.MouseEvent.dwEventFlags == DOUBLE_CLICK)
  520. {
  521. cout << rec.Event.MouseEvent.dwMousePosition.X << "," <<
  522. rec.Event.MouseEvent.dwMousePosition.Y << " " << flush;
  523. }
  524. else if(rec.Event.MouseEvent.dwEventFlags == MOUSE_WHEELED)
  525. {
  526. SetConsoleCursorPosition(hOut,
  527. WheelWhere);
  528. if(rec.Event.MouseEvent.dwButtonState & 0xFF000000)
  529. cout << "Down" << flush;
  530. else
  531. cout << "Up " << flush;
  532. }
  533. #endif
  534. }
  535. return CACA_EVENT_NONE;
  536. }
  537. else
  538. #endif
  539. {
  540. /* Dummy */
  541. }
  542. return CACA_EVENT_NONE;
  543. }
  544. #if defined(USE_SLANG) || defined(USE_NCURSES) || defined(USE_CONIO)
  545. static void _push_event(unsigned int event)
  546. {
  547. if(events == EVENTBUF_LEN)
  548. return;
  549. eventbuf[events] = event;
  550. events++;
  551. }
  552. static unsigned int _pop_event(void)
  553. {
  554. int i;
  555. unsigned int event;
  556. if(events == 0)
  557. return CACA_EVENT_NONE;
  558. event = eventbuf[0];
  559. for(i = 1; i < events; i++)
  560. eventbuf[i - 1] = eventbuf[i];
  561. events--;
  562. return event;
  563. }
  564. #endif