mouse.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695
  1. /*
  2. * File : mouse.c
  3. * This file is part of RT-Thread GUI Engine
  4. * COPYRIGHT (C) 2006 - 2017, RT-Thread Development Team
  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 along
  17. * with this program; if not, write to the Free Software Foundation, Inc.,
  18. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  19. *
  20. * Change Logs:
  21. * Date Author Notes
  22. * 2009-10-16 Bernard first version
  23. */
  24. #include "mouse.h"
  25. #include <rtgui/region.h>
  26. #include <rtgui/driver.h>
  27. #include <rtgui/rtgui_system.h>
  28. struct rtgui_cursor
  29. {
  30. /* screen byte per pixel */
  31. rt_uint16_t bpp;
  32. /* screen pitch */
  33. rt_uint16_t screen_pitch;
  34. /* current cursor x and y */
  35. rt_uint16_t cx, cy;
  36. #ifdef RTGUI_USING_MOUSE_CURSOR
  37. /* cursor pitch */
  38. rt_uint16_t cursor_pitch;
  39. /* show cursor and show cursor count */
  40. rt_bool_t show_cursor;
  41. rt_base_t show_cursor_count;
  42. /* cursor rect info */
  43. rtgui_rect_t rect;
  44. /* cursor image and saved cursor */
  45. rtgui_image_t *cursor_image;
  46. rt_uint8_t *cursor_saved;
  47. #endif
  48. #ifdef RTGUI_USING_WINMOVE
  49. /* move window rect and border */
  50. struct rtgui_win *win;
  51. rtgui_rect_t win_rect;
  52. rt_uint8_t *win_left, *win_right;
  53. rt_uint8_t *win_top, *win_bottom;
  54. rt_bool_t win_rect_show, win_rect_has_saved;
  55. #endif
  56. };
  57. struct rtgui_cursor *_rtgui_cursor;
  58. #ifdef RTGUI_USING_MOUSE_CURSOR
  59. struct rt_mutex cursor_mutex;
  60. static const rt_uint8_t *cursor_xpm[] =
  61. {
  62. "16 16 35 1",
  63. " c None",
  64. ". c #A0B8D0",
  65. "+ c #F0F0F0",
  66. "@ c #FFFFFF",
  67. "# c #F0F8F0",
  68. "$ c #A0B0D0",
  69. "% c #90A8C0",
  70. "& c #A0B0C0",
  71. "* c #E0E8F0",
  72. "= c #8090B0",
  73. "- c #D0D8E0",
  74. "; c #7080A0",
  75. "> c #90A0B0",
  76. ", c #FFF8FF",
  77. "' c #F0F8FF",
  78. ") c #607090",
  79. "! c #8098B0",
  80. "~ c #405060",
  81. "{ c #405070",
  82. "] c #506070",
  83. "^ c #607080",
  84. "/ c #708090",
  85. "( c #7088A0",
  86. "_ c #D0D0E0",
  87. ": c #607890",
  88. "< c #C0D0E0",
  89. "[ c #C0C8D0",
  90. "} c #506880",
  91. "| c #5F778F",
  92. "1 c #D0D8F0",
  93. "2 c #506080",
  94. "3 c #C0C8E0",
  95. "4 c #A0A8C0",
  96. "5 c #405870",
  97. "6 c #5F6F8F",
  98. " . ",
  99. " .. ",
  100. " .+. ",
  101. " .@#$ ",
  102. " $@@+% ",
  103. " &@@@*= ",
  104. " %@@@@-; ",
  105. " >@@,''-) ",
  106. " !,''+)~{] ",
  107. " ='-^*/ ",
  108. " (_{:<[^ ",
  109. " ;} |:12 ",
  110. " / )345 ",
  111. " 6}${ ",
  112. " 5{ ",
  113. " "
  114. };
  115. static void rtgui_cursor_restore(void);
  116. static void rtgui_cursor_save(void);
  117. static void rtgui_cursor_show(void);
  118. #endif
  119. #ifdef RTGUI_USING_WINMOVE
  120. static void rtgui_winrect_restore(void);
  121. static void rtgui_winrect_save(void);
  122. static void rtgui_winrect_show(void);
  123. #endif
  124. #define WIN_MOVE_BORDER 4
  125. void rtgui_mouse_init(void)
  126. {
  127. const struct rtgui_graphic_driver *gd = rtgui_graphic_driver_get_default();
  128. if (_rtgui_cursor != RT_NULL) rtgui_mouse_fini();
  129. _rtgui_cursor = (struct rtgui_cursor *) rtgui_malloc(sizeof(struct rtgui_cursor));
  130. rt_memset(_rtgui_cursor, 0, sizeof(struct rtgui_cursor));
  131. #ifdef RTGUI_USING_MOUSE_CURSOR
  132. rt_mutex_init(&cursor_mutex, "cursor", RT_IPC_FLAG_FIFO);
  133. #endif
  134. /* init cursor */
  135. _rtgui_cursor->bpp = _UI_BITBYTES(gd->bits_per_pixel);
  136. _rtgui_cursor->screen_pitch = _rtgui_cursor->bpp * gd->width;
  137. #ifdef RTGUI_USING_MOUSE_CURSOR
  138. /* init cursor image */
  139. _rtgui_cursor->cursor_image = rtgui_image_create_from_mem("xpm",
  140. (rt_uint8_t *)cursor_xpm,
  141. sizeof(cursor_xpm),
  142. RT_TRUE);
  143. if (_rtgui_cursor->cursor_image == RT_NULL)
  144. {
  145. rtgui_free(_rtgui_cursor);
  146. _rtgui_cursor = RT_NULL;
  147. return;
  148. }
  149. /* init rect */
  150. _rtgui_cursor->rect.x1 = _rtgui_cursor->rect.y1 = 0;
  151. _rtgui_cursor->rect.x2 = _rtgui_cursor->cursor_image->w;
  152. _rtgui_cursor->rect.y2 = _rtgui_cursor->cursor_image->h;
  153. _rtgui_cursor->cursor_pitch = _rtgui_cursor->cursor_image->w * _rtgui_cursor->bpp;
  154. _rtgui_cursor->show_cursor = RT_TRUE;
  155. _rtgui_cursor->show_cursor_count = 0;
  156. _rtgui_cursor->cursor_saved = rtgui_malloc(_rtgui_cursor->cursor_image->w *
  157. _rtgui_cursor->cursor_image->h * _rtgui_cursor->bpp);
  158. #endif
  159. #ifdef RTGUI_USING_WINMOVE
  160. /* init window move save image */
  161. _rtgui_cursor->win_rect_has_saved = RT_FALSE;
  162. _rtgui_cursor->win_rect_show = RT_FALSE;
  163. _rtgui_cursor->win_left = rtgui_malloc(_rtgui_cursor->bpp * gd->height * WIN_MOVE_BORDER);
  164. _rtgui_cursor->win_right = rtgui_malloc(_rtgui_cursor->bpp * gd->height * WIN_MOVE_BORDER);
  165. _rtgui_cursor->win_top = rtgui_malloc(_rtgui_cursor->bpp * gd->width * WIN_MOVE_BORDER);
  166. _rtgui_cursor->win_bottom = rtgui_malloc(_rtgui_cursor->bpp * gd->width * WIN_MOVE_BORDER);
  167. #endif
  168. }
  169. void rtgui_mouse_fini(void)
  170. {
  171. if (_rtgui_cursor != RT_NULL)
  172. {
  173. #ifdef RTGUI_USING_WINMOVE
  174. rtgui_free(_rtgui_cursor->win_left);
  175. rtgui_free(_rtgui_cursor->win_right);
  176. rtgui_free(_rtgui_cursor->win_top);
  177. rtgui_free(_rtgui_cursor->win_bottom);
  178. #endif
  179. #ifdef RTGUI_USING_MOUSE_CURSOR
  180. rt_mutex_detach(&cursor_mutex);
  181. rtgui_image_destroy(_rtgui_cursor->cursor_image);
  182. rtgui_free(_rtgui_cursor->cursor_saved);
  183. #endif
  184. rtgui_free(_rtgui_cursor);
  185. _rtgui_cursor = RT_NULL;
  186. }
  187. }
  188. void rtgui_mouse_moveto(int x, int y)
  189. {
  190. #ifdef RTGUI_USING_MOUSE_CURSOR
  191. rt_mutex_take(&cursor_mutex, RT_WAITING_FOREVER);
  192. #endif
  193. if (x != _rtgui_cursor->cx ||
  194. y != _rtgui_cursor->cy)
  195. {
  196. #ifdef RTGUI_USING_WINMOVE
  197. if (_rtgui_cursor->win_rect_show)
  198. {
  199. if (_rtgui_cursor->win_rect_has_saved == RT_TRUE)
  200. {
  201. rtgui_winrect_restore();
  202. }
  203. #ifdef RTGUI_USING_MOUSE_CURSOR
  204. rtgui_mouse_hide_cursor();
  205. #endif
  206. /* move winrect */
  207. rtgui_rect_move(&(_rtgui_cursor->win_rect), x - _rtgui_cursor->cx,
  208. y - _rtgui_cursor->cy);
  209. rtgui_winrect_save();
  210. /* move current cursor */
  211. _rtgui_cursor->cx = x;
  212. _rtgui_cursor->cy = y;
  213. #ifdef RTGUI_USING_MOUSE_CURSOR
  214. /* show cursor */
  215. rtgui_mouse_show_cursor();
  216. #endif
  217. /* show winrect */
  218. rtgui_winrect_show();
  219. }
  220. else
  221. #endif
  222. {
  223. #ifdef RTGUI_USING_MOUSE_CURSOR
  224. rtgui_mouse_hide_cursor();
  225. #endif
  226. /* move current cursor */
  227. _rtgui_cursor->cx = x;
  228. _rtgui_cursor->cy = y;
  229. #ifdef RTGUI_USING_MOUSE_CURSOR
  230. /* show cursor */
  231. rtgui_mouse_show_cursor();
  232. #endif
  233. }
  234. #ifdef RTGUI_USING_HW_CURSOR
  235. rtgui_cursor_set_position(_rtgui_cursor->cx, _rtgui_cursor->cy);
  236. #endif
  237. }
  238. #ifdef RTGUI_USING_MOUSE_CURSOR
  239. rt_mutex_release(&cursor_mutex);
  240. #endif
  241. }
  242. void rtgui_mouse_set_position(int x, int y)
  243. {
  244. /* move current cursor */
  245. _rtgui_cursor->cx = x;
  246. _rtgui_cursor->cy = y;
  247. #ifdef RTGUI_USING_HW_CURSOR
  248. rtgui_cursor_set_position(_rtgui_cursor->cx, _rtgui_cursor->cy);
  249. #endif
  250. }
  251. #ifdef RTGUI_USING_MOUSE_CURSOR
  252. void rtgui_mouse_set_cursor_enable(rt_bool_t enable)
  253. {
  254. _rtgui_cursor->show_cursor = enable;
  255. }
  256. /* set current cursor image */
  257. void rtgui_mouse_set_cursor(rtgui_image_t *cursor)
  258. {
  259. }
  260. void rtgui_mouse_get_cursor_rect(rtgui_rect_t *rect)
  261. {
  262. if (rect != RT_NULL)
  263. {
  264. *rect = _rtgui_cursor->rect;
  265. }
  266. }
  267. void rtgui_mouse_show_cursor()
  268. {
  269. if (_rtgui_cursor->show_cursor == RT_FALSE)
  270. return;
  271. _rtgui_cursor->show_cursor_count ++;
  272. if (_rtgui_cursor->show_cursor_count == 1)
  273. {
  274. /* save show mouse area */
  275. rtgui_cursor_save();
  276. /* show mouse cursor */
  277. rtgui_cursor_show();
  278. }
  279. }
  280. void rtgui_mouse_hide_cursor()
  281. {
  282. if (_rtgui_cursor->show_cursor == RT_FALSE)
  283. return;
  284. if (_rtgui_cursor->show_cursor_count == 1)
  285. {
  286. /* display the cursor coverage area */
  287. rtgui_cursor_restore();
  288. }
  289. _rtgui_cursor->show_cursor_count --;
  290. }
  291. rt_bool_t rtgui_mouse_is_intersect(rtgui_rect_t *r)
  292. {
  293. return rtgui_rect_is_intersect(&(_rtgui_cursor->rect), r) == RT_EOK ? RT_TRUE : RT_FALSE;
  294. }
  295. /* display the saved cursor area to screen */
  296. static void rtgui_cursor_restore()
  297. {
  298. rt_base_t idx, height, cursor_pitch;
  299. rt_uint8_t *cursor_ptr, *fb_ptr;
  300. fb_ptr = rtgui_graphic_driver_get_framebuffer(RT_NULL) + _rtgui_cursor->cy * _rtgui_cursor->screen_pitch
  301. + _rtgui_cursor->cx * _rtgui_cursor->bpp;
  302. cursor_ptr = _rtgui_cursor->cursor_saved;
  303. height = (_rtgui_cursor->cy + _rtgui_cursor->cursor_image->h <
  304. rtgui_graphic_driver_get_default()->height) ? _rtgui_cursor->cursor_image->h :
  305. rtgui_graphic_driver_get_default()->height - _rtgui_cursor->cy;
  306. cursor_pitch = (_rtgui_cursor->cx + _rtgui_cursor->cursor_image->w <
  307. rtgui_graphic_driver_get_default()->width) ? _rtgui_cursor->cursor_pitch :
  308. (rtgui_graphic_driver_get_default()->width - _rtgui_cursor->cx) * _rtgui_cursor->bpp;
  309. for (idx = 0; idx < height; idx ++)
  310. {
  311. memcpy(fb_ptr, cursor_ptr, cursor_pitch);
  312. fb_ptr += _rtgui_cursor->screen_pitch;
  313. cursor_ptr += _rtgui_cursor->cursor_pitch;
  314. }
  315. }
  316. /* save the cursor coverage area from screen */
  317. static void rtgui_cursor_save()
  318. {
  319. rt_base_t idx, height, cursor_pitch;
  320. rt_uint8_t *cursor_ptr, *fb_ptr;
  321. fb_ptr = rtgui_graphic_driver_get_framebuffer(RT_NULL) + _rtgui_cursor->cy * _rtgui_cursor->screen_pitch +
  322. _rtgui_cursor->cx * _rtgui_cursor->bpp;
  323. cursor_ptr = _rtgui_cursor->cursor_saved;
  324. height = (_rtgui_cursor->cy + _rtgui_cursor->cursor_image->h <
  325. rtgui_graphic_driver_get_default()->height) ? _rtgui_cursor->cursor_image->h :
  326. rtgui_graphic_driver_get_default()->height - _rtgui_cursor->cy;
  327. cursor_pitch = (_rtgui_cursor->cx + _rtgui_cursor->cursor_image->w <
  328. rtgui_graphic_driver_get_default()->width) ? _rtgui_cursor->cursor_pitch :
  329. (rtgui_graphic_driver_get_default()->width - _rtgui_cursor->cx) * _rtgui_cursor->bpp;
  330. for (idx = 0; idx < height; idx ++)
  331. {
  332. memcpy(cursor_ptr, fb_ptr, cursor_pitch);
  333. fb_ptr += _rtgui_cursor->screen_pitch;
  334. cursor_ptr += _rtgui_cursor->cursor_pitch;
  335. }
  336. }
  337. static void rtgui_cursor_show()
  338. {
  339. // FIXME: the prototype of set_pixel is using int so we have to use int
  340. // as well. Might be uniformed with others in the future
  341. int x, y;
  342. rtgui_color_t *ptr;
  343. rtgui_rect_t rect;
  344. void (*set_pixel)(rtgui_color_t * c, int x, int y);
  345. ptr = (rtgui_color_t *) _rtgui_cursor->cursor_image->data;
  346. set_pixel = rtgui_graphic_driver_get_default()->ops->set_pixel;
  347. rtgui_mouse_get_cursor_rect(&rect);
  348. rtgui_rect_move(&rect, _rtgui_cursor->cx, _rtgui_cursor->cy);
  349. /* draw each point */
  350. for (y = rect.y1; y < rect.y2; y ++)
  351. {
  352. for (x = rect.x1; x < rect.x2; x++)
  353. {
  354. /* not alpha */
  355. if ((*ptr >> 24) != 255)
  356. {
  357. set_pixel(ptr, x, y);
  358. }
  359. /* move to next color buffer */
  360. ptr ++;
  361. }
  362. }
  363. /* update rect */
  364. rtgui_graphic_driver_screen_update(rtgui_graphic_driver_get_default(), &rect);
  365. }
  366. #endif
  367. #ifdef RTGUI_USING_WINMOVE
  368. void rtgui_winrect_set(struct rtgui_win *win)
  369. {
  370. /* set win rect show */
  371. _rtgui_cursor->win_rect_show = RT_TRUE;
  372. /* set win rect */
  373. _rtgui_cursor->win_rect =
  374. win->_title_wgt == RT_NULL ?
  375. RTGUI_WIDGET(win)->extent :
  376. RTGUI_WIDGET(win->_title_wgt)->extent;
  377. _rtgui_cursor->win = win;
  378. }
  379. rt_bool_t rtgui_winrect_moved_done(rtgui_rect_t *winrect, struct rtgui_win **win)
  380. {
  381. rt_bool_t moved = RT_FALSE;
  382. /* restore winrect */
  383. if (_rtgui_cursor->win_rect_has_saved)
  384. {
  385. rtgui_winrect_restore();
  386. moved = RT_TRUE;
  387. }
  388. /* clear win rect show */
  389. _rtgui_cursor->win_rect_show = RT_FALSE;
  390. _rtgui_cursor->win_rect_has_saved = RT_FALSE;
  391. /* return win rect */
  392. if (winrect)
  393. *winrect = _rtgui_cursor->win_rect;
  394. if (win)
  395. *win = _rtgui_cursor->win;
  396. return moved;
  397. }
  398. rt_bool_t rtgui_winrect_is_moved()
  399. {
  400. return _rtgui_cursor->win_rect_show;
  401. }
  402. /* show winrect */
  403. static void rtgui_winrect_show()
  404. {
  405. rt_uint16_t x, y;
  406. rtgui_color_t c;
  407. rtgui_rect_t screen_rect, win_rect, win_rect_inner;
  408. void (*set_pixel)(rtgui_color_t * c, int x, int y);
  409. c = black;
  410. set_pixel = rtgui_graphic_driver_get_default()->ops->set_pixel;
  411. win_rect = _rtgui_cursor->win_rect;
  412. win_rect_inner = win_rect;
  413. rtgui_rect_inflate(&win_rect_inner, -WIN_MOVE_BORDER);
  414. rtgui_graphic_driver_get_rect(rtgui_graphic_driver_get_default(),
  415. &screen_rect);
  416. rtgui_rect_intersect(&screen_rect, &win_rect);
  417. rtgui_rect_intersect(&screen_rect, &win_rect_inner);
  418. /* draw left */
  419. for (y = win_rect.y1; y < win_rect.y2; y ++)
  420. {
  421. for (x = win_rect.x1; x < win_rect_inner.x1; x++)
  422. if ((x + y) & 0x01) set_pixel(&c, x, y);
  423. }
  424. /* draw right */
  425. for (y = win_rect.y1; y < win_rect.y2; y ++)
  426. {
  427. for (x = win_rect_inner.x2; x < win_rect.x2; x++)
  428. if ((x + y) & 0x01) set_pixel(&c, x, y);
  429. }
  430. /* draw top border */
  431. for (y = win_rect.y1; y < win_rect_inner.y1; y ++)
  432. {
  433. for (x = win_rect_inner.x1; x < win_rect_inner.x2; x++)
  434. if ((x + y) & 0x01) set_pixel(&c, x, y);
  435. }
  436. /* draw bottom border */
  437. for (y = win_rect_inner.y2; y < win_rect.y2; y ++)
  438. {
  439. for (x = win_rect_inner.x1; x < win_rect_inner.x2; x++)
  440. if ((x + y) & 0x01) set_pixel(&c, x, y);
  441. }
  442. /* update rect */
  443. rtgui_graphic_driver_screen_update(rtgui_graphic_driver_get_default(), &win_rect);
  444. }
  445. #define display_direct_memcpy(src, dest, src_pitch, dest_pitch, height, len) \
  446. for (idx = 0; idx < height; idx ++) \
  447. { \
  448. memcpy(dest, src, len); \
  449. src += src_pitch; \
  450. dest += dest_pitch; \
  451. }
  452. static void rtgui_winrect_restore()
  453. {
  454. rt_uint8_t *winrect_ptr, *fb_ptr, *driver_fb;
  455. int winrect_pitch, idx;
  456. rtgui_rect_t screen_rect, win_rect;
  457. driver_fb = rtgui_graphic_driver_get_framebuffer(RT_NULL);
  458. win_rect = _rtgui_cursor->win_rect;
  459. rtgui_graphic_driver_get_rect(rtgui_graphic_driver_get_default(),
  460. &screen_rect);
  461. rtgui_rect_intersect(&screen_rect, &win_rect);
  462. /* restore winrect left */
  463. fb_ptr = driver_fb + win_rect.y1 * _rtgui_cursor->screen_pitch +
  464. win_rect.x1 * _rtgui_cursor->bpp;
  465. winrect_ptr = _rtgui_cursor->win_left;
  466. winrect_pitch = WIN_MOVE_BORDER * _rtgui_cursor->bpp;
  467. display_direct_memcpy(winrect_ptr, fb_ptr, winrect_pitch, _rtgui_cursor->screen_pitch,
  468. (win_rect.y2 - win_rect.y1), winrect_pitch);
  469. /* restore winrect right */
  470. fb_ptr = driver_fb + win_rect.y1 * _rtgui_cursor->screen_pitch +
  471. (win_rect.x2 - WIN_MOVE_BORDER) * _rtgui_cursor->bpp;
  472. winrect_ptr = _rtgui_cursor->win_right;
  473. winrect_pitch = WIN_MOVE_BORDER * _rtgui_cursor->bpp;
  474. display_direct_memcpy(winrect_ptr, fb_ptr, winrect_pitch, _rtgui_cursor->screen_pitch,
  475. (win_rect.y2 - win_rect.y1), winrect_pitch);
  476. /* restore winrect top */
  477. fb_ptr = driver_fb + win_rect.y1 * _rtgui_cursor->screen_pitch +
  478. (win_rect.x1 + WIN_MOVE_BORDER) * _rtgui_cursor->bpp;
  479. winrect_ptr = _rtgui_cursor->win_top;
  480. winrect_pitch = (win_rect.x2 - win_rect.x1 - 2 * WIN_MOVE_BORDER) * _rtgui_cursor->bpp;
  481. display_direct_memcpy(winrect_ptr, fb_ptr, winrect_pitch, _rtgui_cursor->screen_pitch,
  482. WIN_MOVE_BORDER, winrect_pitch);
  483. /* restore winrect bottom */
  484. fb_ptr = driver_fb + (win_rect.y2 - WIN_MOVE_BORDER) * _rtgui_cursor->screen_pitch +
  485. (win_rect.x1 + WIN_MOVE_BORDER) * _rtgui_cursor->bpp;
  486. winrect_ptr = _rtgui_cursor->win_bottom;
  487. display_direct_memcpy(winrect_ptr, fb_ptr, winrect_pitch, _rtgui_cursor->screen_pitch,
  488. WIN_MOVE_BORDER, winrect_pitch);
  489. }
  490. static void rtgui_winrect_save()
  491. {
  492. rt_uint8_t *winrect_ptr, *fb_ptr, *driver_fb;
  493. int winrect_pitch, idx;
  494. rtgui_rect_t screen_rect, win_rect;
  495. driver_fb = rtgui_graphic_driver_get_framebuffer(RT_NULL);
  496. win_rect = _rtgui_cursor->win_rect;
  497. rtgui_graphic_driver_get_rect(rtgui_graphic_driver_get_default(),
  498. &screen_rect);
  499. rtgui_rect_intersect(&screen_rect, &win_rect);
  500. /* set winrect has saved */
  501. _rtgui_cursor->win_rect_has_saved = RT_TRUE;
  502. /* save winrect left */
  503. fb_ptr = driver_fb + win_rect.y1 * _rtgui_cursor->screen_pitch +
  504. win_rect.x1 * _rtgui_cursor->bpp;
  505. winrect_ptr = _rtgui_cursor->win_left;
  506. winrect_pitch = WIN_MOVE_BORDER * _rtgui_cursor->bpp;
  507. display_direct_memcpy(fb_ptr, winrect_ptr, _rtgui_cursor->screen_pitch, winrect_pitch,
  508. (win_rect.y2 - win_rect.y1), winrect_pitch);
  509. /* save winrect right */
  510. fb_ptr = driver_fb + win_rect.y1 * _rtgui_cursor->screen_pitch +
  511. (win_rect.x2 - WIN_MOVE_BORDER) * _rtgui_cursor->bpp;
  512. winrect_ptr = _rtgui_cursor->win_right;
  513. winrect_pitch = WIN_MOVE_BORDER * _rtgui_cursor->bpp;
  514. display_direct_memcpy(fb_ptr, winrect_ptr, _rtgui_cursor->screen_pitch, winrect_pitch,
  515. (win_rect.y2 - win_rect.y1), winrect_pitch);
  516. /* save winrect top */
  517. fb_ptr = driver_fb + win_rect.y1 * _rtgui_cursor->screen_pitch +
  518. (win_rect.x1 + WIN_MOVE_BORDER) * _rtgui_cursor->bpp;
  519. winrect_ptr = _rtgui_cursor->win_top;
  520. winrect_pitch = (win_rect.x2 - win_rect.x1 - 2 * WIN_MOVE_BORDER) * _rtgui_cursor->bpp;
  521. display_direct_memcpy(fb_ptr, winrect_ptr, _rtgui_cursor->screen_pitch, winrect_pitch,
  522. WIN_MOVE_BORDER, winrect_pitch);
  523. /* save winrect bottom */
  524. fb_ptr = driver_fb + (win_rect.y2 - WIN_MOVE_BORDER) * _rtgui_cursor->screen_pitch +
  525. (win_rect.x1 + WIN_MOVE_BORDER) * _rtgui_cursor->bpp;
  526. winrect_ptr = _rtgui_cursor->win_bottom;
  527. display_direct_memcpy(fb_ptr, winrect_ptr, _rtgui_cursor->screen_pitch, winrect_pitch,
  528. WIN_MOVE_BORDER, winrect_pitch);
  529. }
  530. #endif
  531. void rtgui_mouse_monitor_append(rtgui_list_t *head, rtgui_rect_t *rect)
  532. {
  533. struct rtgui_mouse_monitor *mmonitor;
  534. /* check parameters */
  535. if (head == RT_NULL || rect == RT_NULL) return;
  536. /* create a mouse monitor node */
  537. mmonitor = (struct rtgui_mouse_monitor *) rtgui_malloc(sizeof(struct rtgui_mouse_monitor));
  538. if (mmonitor == RT_NULL) return; /* no memory */
  539. /* set mouse monitor node */
  540. mmonitor->rect = *rect;
  541. rtgui_list_init(&(mmonitor->list));
  542. /* append to list */
  543. rtgui_list_append(head, &(mmonitor->list));
  544. }
  545. void rtgui_mouse_monitor_remove(rtgui_list_t *head, rtgui_rect_t *rect)
  546. {
  547. struct rtgui_list_node *node;
  548. struct rtgui_mouse_monitor *mmonitor;
  549. /* check parameters */
  550. if (head == RT_NULL || rect == RT_NULL) return;
  551. for (node = head->next; node != RT_NULL; node = node->next)
  552. {
  553. mmonitor = rtgui_list_entry(node, struct rtgui_mouse_monitor, list);
  554. if (mmonitor->rect.x1 == rect->x1 &&
  555. mmonitor->rect.x2 == rect->x2 &&
  556. mmonitor->rect.y1 == rect->y1 &&
  557. mmonitor->rect.y2 == rect->y2)
  558. {
  559. /* found node */
  560. rtgui_list_remove(head, node);
  561. rtgui_free(mmonitor);
  562. return ;
  563. }
  564. }
  565. }
  566. rt_bool_t rtgui_mouse_monitor_contains_point(rtgui_list_t *head, int x, int y)
  567. {
  568. struct rtgui_list_node *node;
  569. /* check parameter */
  570. if (head == RT_NULL) return RT_FALSE;
  571. rtgui_list_foreach(node, head)
  572. {
  573. struct rtgui_mouse_monitor *monitor = rtgui_list_entry(node,
  574. struct rtgui_mouse_monitor, list);
  575. if (rtgui_rect_contains_point(&(monitor->rect), x, y) == RT_EOK)
  576. {
  577. return RT_TRUE;
  578. }
  579. }
  580. return RT_FALSE;
  581. }