mouse.c 20 KB

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