mouse.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639
  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_topwin *topwin;
  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. /* screen framebuffer */
  47. rt_uint8_t* framebuffer;
  48. };
  49. struct rtgui_cursor* _rtgui_cursor;
  50. #ifdef RTGUI_USING_MOUSE_CURSOR
  51. struct rt_mutex cursor_mutex;
  52. static const rt_uint8_t * cursor_xpm[] = {
  53. "16 16 35 1",
  54. " c None",
  55. ". c #A0B8D0",
  56. "+ c #F0F0F0",
  57. "@ c #FFFFFF",
  58. "# c #F0F8F0",
  59. "$ c #A0B0D0",
  60. "% c #90A8C0",
  61. "& c #A0B0C0",
  62. "* c #E0E8F0",
  63. "= c #8090B0",
  64. "- c #D0D8E0",
  65. "; c #7080A0",
  66. "> c #90A0B0",
  67. ", c #FFF8FF",
  68. "' c #F0F8FF",
  69. ") c #607090",
  70. "! c #8098B0",
  71. "~ c #405060",
  72. "{ c #405070",
  73. "] c #506070",
  74. "^ c #607080",
  75. "/ c #708090",
  76. "( c #7088A0",
  77. "_ c #D0D0E0",
  78. ": c #607890",
  79. "< c #C0D0E0",
  80. "[ c #C0C8D0",
  81. "} c #506880",
  82. "| c #5F778F",
  83. "1 c #D0D8F0",
  84. "2 c #506080",
  85. "3 c #C0C8E0",
  86. "4 c #A0A8C0",
  87. "5 c #405870",
  88. "6 c #5F6F8F",
  89. " . ",
  90. " .. ",
  91. " .+. ",
  92. " .@#$ ",
  93. " $@@+% ",
  94. " &@@@*= ",
  95. " %@@@@-; ",
  96. " >@@,''-) ",
  97. " !,''+)~{] ",
  98. " ='-^*/ ",
  99. " (_{:<[^ ",
  100. " ;} |:12 ",
  101. " / )345 ",
  102. " 6}${ ",
  103. " 5{ ",
  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()
  116. {
  117. const struct rtgui_graphic_driver* gd = rtgui_graphic_driver_get_default();
  118. _rtgui_cursor = (struct rtgui_cursor*) rtgui_malloc(sizeof(struct rtgui_cursor));
  119. rt_memset(_rtgui_cursor, 0, sizeof(struct rtgui_cursor));
  120. #ifdef RTGUI_USING_MOUSE_CURSOR
  121. rt_mutex_init(&cursor_mutex, "cursor", RT_IPC_FLAG_FIFO);
  122. #endif
  123. /* init cursor */
  124. _rtgui_cursor->bpp = gd->byte_per_pixel;
  125. _rtgui_cursor->framebuffer = gd->get_framebuffer();
  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", cursor_xpm, sizeof(cursor_xpm));
  130. if (_rtgui_cursor->cursor_image == RT_NULL)
  131. {
  132. rtgui_free(_rtgui_cursor);
  133. _rtgui_cursor = RT_NULL;
  134. return;
  135. }
  136. /* init rect */
  137. _rtgui_cursor->rect.x1 = _rtgui_cursor->rect.y1 = 0;
  138. _rtgui_cursor->rect.x2 = _rtgui_cursor->cursor_image->w;
  139. _rtgui_cursor->rect.y2 = _rtgui_cursor->cursor_image->h;
  140. _rtgui_cursor->cursor_pitch = _rtgui_cursor->cursor_image->w * _rtgui_cursor->bpp;
  141. _rtgui_cursor->show_cursor = RT_TRUE;
  142. _rtgui_cursor->show_cursor_count = 0;
  143. _rtgui_cursor->cursor_saved = rtgui_malloc(_rtgui_cursor->cursor_image->w *
  144. _rtgui_cursor->cursor_image->h * _rtgui_cursor->bpp);
  145. #endif
  146. #ifdef RTGUI_USING_WINMOVE
  147. /* init window move save image */
  148. _rtgui_cursor->win_rect_has_saved = RT_FALSE;
  149. _rtgui_cursor->win_rect_show = RT_FALSE;
  150. _rtgui_cursor->win_left = rtgui_malloc(_rtgui_cursor->bpp * gd->height * WIN_MOVE_BORDER);
  151. _rtgui_cursor->win_right = rtgui_malloc(_rtgui_cursor->bpp * gd->height * WIN_MOVE_BORDER);
  152. _rtgui_cursor->win_top = rtgui_malloc(_rtgui_cursor->bpp * gd->width * WIN_MOVE_BORDER);
  153. _rtgui_cursor->win_bottom = rtgui_malloc(_rtgui_cursor->bpp * gd->width * WIN_MOVE_BORDER);
  154. #endif
  155. }
  156. void rtgui_mouse_moveto(int x, int y)
  157. {
  158. #ifdef RTGUI_USING_MOUSE_CURSOR
  159. rt_mutex_take(&cursor_mutex, RT_WAITING_FOREVER);
  160. #endif
  161. if (x != _rtgui_cursor->cx ||
  162. y != _rtgui_cursor->cy)
  163. {
  164. #ifdef RTGUI_USING_WINMOVE
  165. if (_rtgui_cursor->win_rect_show)
  166. {
  167. if (_rtgui_cursor->win_rect_has_saved == RT_TRUE)
  168. {
  169. rtgui_winrect_restore();
  170. }
  171. #ifdef RTGUI_USING_MOUSE_CURSOR
  172. rtgui_mouse_hide_cursor();
  173. #endif
  174. /* move winrect */
  175. rtgui_rect_moveto(&(_rtgui_cursor->win_rect), x - _rtgui_cursor->cx,
  176. y - _rtgui_cursor->cy);
  177. rtgui_winrect_save();
  178. /* move current cursor */
  179. _rtgui_cursor->cx = x;
  180. _rtgui_cursor->cy = y;
  181. #ifdef RTGUI_USING_MOUSE_CURSOR
  182. /* show cursor */
  183. rtgui_mouse_show_cursor();
  184. #endif
  185. /* show winrect */
  186. rtgui_winrect_show();
  187. }
  188. else
  189. #endif
  190. {
  191. #ifdef RTGUI_USING_MOUSE_CURSOR
  192. rtgui_mouse_hide_cursor();
  193. #endif
  194. /* move current cursor */
  195. _rtgui_cursor->cx = x;
  196. _rtgui_cursor->cy = y;
  197. #ifdef RTGUI_USING_MOUSE_CURSOR
  198. /* show cursor */
  199. rtgui_mouse_show_cursor();
  200. #endif
  201. }
  202. }
  203. #ifdef RTGUI_USING_MOUSE_CURSOR
  204. rt_mutex_release(&cursor_mutex);
  205. #endif
  206. }
  207. #ifdef RTGUI_USING_MOUSE_CURSOR
  208. void rtgui_mouse_set_cursor_enable(rt_bool_t enable)
  209. {
  210. _rtgui_cursor->show_cursor = enable;
  211. }
  212. /* set current cursor image */
  213. void rtgui_mouse_set_cursor(rtgui_image_t* cursor)
  214. {
  215. }
  216. void rtgui_mouse_get_cursor_rect(rtgui_rect_t* rect)
  217. {
  218. if (rect != RT_NULL)
  219. {
  220. *rect = _rtgui_cursor->rect;
  221. }
  222. }
  223. void rtgui_mouse_show_cursor()
  224. {
  225. if (_rtgui_cursor->show_cursor == RT_FALSE)
  226. return;
  227. _rtgui_cursor->show_cursor_count ++;
  228. if (_rtgui_cursor->show_cursor_count == 1)
  229. {
  230. /* save show mouse area */
  231. rtgui_cursor_save();
  232. /* show mouse cursor */
  233. rtgui_cursor_show();
  234. }
  235. }
  236. void rtgui_mouse_hide_cursor()
  237. {
  238. if (_rtgui_cursor->show_cursor == RT_FALSE)
  239. return;
  240. if (_rtgui_cursor->show_cursor_count == 1)
  241. {
  242. /* display the cursor coverage area */
  243. rtgui_cursor_restore();
  244. }
  245. _rtgui_cursor->show_cursor_count --;
  246. }
  247. rt_bool_t rtgui_mouse_is_intersect(rtgui_rect_t* r)
  248. {
  249. return rtgui_rect_is_intersect(&(_rtgui_cursor->rect), r) == RT_EOK? RT_TRUE : RT_FALSE;
  250. }
  251. /* display the saved cursor area to screen */
  252. static void rtgui_cursor_restore()
  253. {
  254. rt_base_t idx, height, cursor_pitch;
  255. rt_uint8_t *cursor_ptr, *fb_ptr;
  256. fb_ptr = _rtgui_cursor->framebuffer + _rtgui_cursor->cy * _rtgui_cursor->screen_pitch
  257. + _rtgui_cursor->cx * _rtgui_cursor->bpp;
  258. cursor_ptr = _rtgui_cursor->cursor_saved;
  259. height = (_rtgui_cursor->cy + _rtgui_cursor->cursor_image->h <
  260. rtgui_graphic_driver_get_default()->height)? _rtgui_cursor->cursor_image->h :
  261. rtgui_graphic_driver_get_default()->height - _rtgui_cursor->cy;
  262. cursor_pitch = (_rtgui_cursor->cx + _rtgui_cursor->cursor_image->w <
  263. rtgui_graphic_driver_get_default()->width)? _rtgui_cursor->cursor_pitch :
  264. (rtgui_graphic_driver_get_default()->width - _rtgui_cursor->cx) * _rtgui_cursor->bpp;
  265. for (idx = 0; idx < height; idx ++)
  266. {
  267. rt_memcpy(fb_ptr, cursor_ptr, cursor_pitch);
  268. fb_ptr += _rtgui_cursor->screen_pitch;
  269. cursor_ptr += _rtgui_cursor->cursor_pitch;
  270. }
  271. }
  272. /* save the cursor coverage area from screen */
  273. static void rtgui_cursor_save()
  274. {
  275. rt_base_t idx, height, cursor_pitch;
  276. rt_uint8_t *cursor_ptr, *fb_ptr;
  277. fb_ptr = _rtgui_cursor->framebuffer + _rtgui_cursor->cy * _rtgui_cursor->screen_pitch +
  278. _rtgui_cursor->cx * _rtgui_cursor->bpp;
  279. cursor_ptr = _rtgui_cursor->cursor_saved;
  280. height = (_rtgui_cursor->cy + _rtgui_cursor->cursor_image->h <
  281. rtgui_graphic_driver_get_default()->height)? _rtgui_cursor->cursor_image->h :
  282. rtgui_graphic_driver_get_default()->height - _rtgui_cursor->cy;
  283. cursor_pitch = (_rtgui_cursor->cx + _rtgui_cursor->cursor_image->w <
  284. rtgui_graphic_driver_get_default()->width)? _rtgui_cursor->cursor_pitch :
  285. (rtgui_graphic_driver_get_default()->width - _rtgui_cursor->cx) * _rtgui_cursor->bpp;
  286. for (idx = 0; idx < height; idx ++)
  287. {
  288. rt_memcpy(cursor_ptr, fb_ptr, cursor_pitch);
  289. fb_ptr += _rtgui_cursor->screen_pitch;
  290. cursor_ptr += _rtgui_cursor->cursor_pitch;
  291. }
  292. }
  293. static void rtgui_cursor_show()
  294. {
  295. rt_uint16_t x, y;
  296. rtgui_color_t* ptr;
  297. rtgui_rect_t rect;
  298. void (*set_pixel) (rtgui_color_t *c, rt_uint16_t x, rt_uint16_t y);
  299. ptr = (rtgui_color_t*) _rtgui_cursor->cursor_image->data;
  300. set_pixel = rtgui_graphic_driver_get_default()->set_pixel;
  301. rtgui_mouse_get_cursor_rect(&rect);
  302. rtgui_rect_moveto(&rect, _rtgui_cursor->cx, _rtgui_cursor->cy);
  303. /* draw each point */
  304. for (y = rect.y1; y < rect.y2; y ++)
  305. {
  306. for (x = rect.x1; x < rect.x2; x++)
  307. {
  308. /* not alpha */
  309. if ((*ptr >> 24) != 255)
  310. {
  311. set_pixel(ptr, x, y);
  312. }
  313. /* move to next color buffer */
  314. ptr ++;
  315. }
  316. }
  317. /* update rect */
  318. rtgui_graphic_driver_get_default()->screen_update(&rect);
  319. }
  320. #endif
  321. #ifdef RTGUI_USING_WINMOVE
  322. void rtgui_winrect_set(struct rtgui_topwin* topwin)
  323. {
  324. /* set win rect show */
  325. _rtgui_cursor->win_rect_show = RT_TRUE;
  326. /* set win rect */
  327. _rtgui_cursor->win_rect = topwin->title == RT_NULL? topwin->extent : RTGUI_WIDGET(topwin->title)->extent;
  328. _rtgui_cursor->topwin = topwin;
  329. }
  330. rt_bool_t rtgui_winrect_moved_done(rtgui_rect_t* winrect, struct rtgui_topwin** topwin)
  331. {
  332. rt_bool_t moved = RT_FALSE;
  333. /* no win rect */
  334. if (winrect == RT_NULL) return RT_FALSE;
  335. /* restore winrect */
  336. if (_rtgui_cursor->win_rect_has_saved)
  337. {
  338. rtgui_winrect_restore();
  339. moved = RT_TRUE;
  340. }
  341. /* clear win rect show */
  342. _rtgui_cursor->win_rect_show = RT_FALSE;
  343. _rtgui_cursor->win_rect_has_saved = RT_FALSE;
  344. /* return win rect */
  345. *winrect = _rtgui_cursor->win_rect;
  346. *topwin = _rtgui_cursor->topwin;
  347. return moved;
  348. }
  349. rt_bool_t rtgui_winrect_is_moved()
  350. {
  351. return _rtgui_cursor->win_rect_show;
  352. }
  353. /* show winrect */
  354. static void rtgui_winrect_show()
  355. {
  356. rt_uint16_t x, y;
  357. rtgui_color_t c;
  358. rtgui_rect_t screen_rect, win_rect, win_rect_inner;
  359. void (*set_pixel) (rtgui_color_t *c, rt_base_t x, rt_base_t y);
  360. c = black;
  361. set_pixel = rtgui_graphic_driver_get_default()->set_pixel;
  362. win_rect = _rtgui_cursor->win_rect;
  363. win_rect_inner = win_rect;
  364. rtgui_rect_inflate(&win_rect_inner, -WIN_MOVE_BORDER);
  365. rtgui_graphic_driver_get_rect(rtgui_graphic_driver_get_default(),
  366. &screen_rect);
  367. rtgui_rect_intersect(&screen_rect, &win_rect);
  368. rtgui_rect_intersect(&screen_rect, &win_rect_inner);
  369. /* draw left */
  370. for (y = win_rect.y1; y < win_rect.y2; y ++)
  371. {
  372. for (x = win_rect.x1; x < win_rect_inner.x1; x++)
  373. if ((x + y) & 0x01) set_pixel(&c, x, y);
  374. }
  375. /* draw right */
  376. for (y = win_rect.y1; y < win_rect.y2; y ++)
  377. {
  378. for (x = win_rect_inner.x2; x < win_rect.x2; x++)
  379. if ((x + y) & 0x01) set_pixel(&c, x, y);
  380. }
  381. /* draw top border */
  382. for (y = win_rect.y1; y < win_rect_inner.y1; y ++)
  383. {
  384. for (x = win_rect_inner.x1; x < win_rect_inner.x2; x++)
  385. if ((x + y) & 0x01) set_pixel(&c, x, y);
  386. }
  387. /* draw bottom border */
  388. for (y = win_rect_inner.y2; y < win_rect.y2; y ++)
  389. {
  390. for (x = win_rect_inner.x1; x < win_rect_inner.x2; x++)
  391. if ((x + y) & 0x01) set_pixel(&c, x, y);
  392. }
  393. /* update rect */
  394. rtgui_graphic_driver_get_default()->screen_update(&win_rect);
  395. }
  396. #define display_direct_memcpy(src, dest, src_pitch, dest_pitch, height, len) \
  397. for (idx = 0; idx < height; idx ++) \
  398. { \
  399. rt_memcpy(dest, src, len); \
  400. src += src_pitch; \
  401. dest += dest_pitch; \
  402. }
  403. static void rtgui_winrect_restore()
  404. {
  405. rt_uint8_t *winrect_ptr, *fb_ptr;
  406. int winrect_pitch, idx;
  407. rtgui_rect_t screen_rect, win_rect;
  408. win_rect = _rtgui_cursor->win_rect;
  409. rtgui_graphic_driver_get_rect(rtgui_graphic_driver_get_default(),
  410. &screen_rect);
  411. rtgui_rect_intersect(&screen_rect, &win_rect);
  412. /* restore winrect left */
  413. fb_ptr = _rtgui_cursor->framebuffer + win_rect.y1 * _rtgui_cursor->screen_pitch +
  414. win_rect.x1 * _rtgui_cursor->bpp;
  415. winrect_ptr = _rtgui_cursor->win_left;
  416. winrect_pitch = WIN_MOVE_BORDER * _rtgui_cursor->bpp;
  417. display_direct_memcpy(winrect_ptr, fb_ptr, winrect_pitch, _rtgui_cursor->screen_pitch,
  418. (win_rect.y2 - win_rect.y1), winrect_pitch);
  419. /* restore winrect right */
  420. fb_ptr = _rtgui_cursor->framebuffer + win_rect.y1 * _rtgui_cursor->screen_pitch +
  421. (win_rect.x2 - WIN_MOVE_BORDER) * _rtgui_cursor->bpp;
  422. winrect_ptr = _rtgui_cursor->win_right;
  423. winrect_pitch = WIN_MOVE_BORDER * _rtgui_cursor->bpp;
  424. display_direct_memcpy(winrect_ptr, fb_ptr, winrect_pitch, _rtgui_cursor->screen_pitch,
  425. (win_rect.y2 - win_rect.y1), winrect_pitch);
  426. /* restore winrect top */
  427. fb_ptr = _rtgui_cursor->framebuffer + win_rect.y1 * _rtgui_cursor->screen_pitch +
  428. (win_rect.x1 + WIN_MOVE_BORDER)* _rtgui_cursor->bpp;
  429. winrect_ptr = _rtgui_cursor->win_top;
  430. winrect_pitch = (win_rect.x2 - win_rect.x1 - 2 * WIN_MOVE_BORDER) * _rtgui_cursor->bpp;
  431. display_direct_memcpy(winrect_ptr, fb_ptr, winrect_pitch, _rtgui_cursor->screen_pitch,
  432. WIN_MOVE_BORDER, winrect_pitch);
  433. /* restore winrect bottom */
  434. fb_ptr = _rtgui_cursor->framebuffer + (win_rect.y2 - WIN_MOVE_BORDER) * _rtgui_cursor->screen_pitch +
  435. (win_rect.x1 + WIN_MOVE_BORDER) * _rtgui_cursor->bpp;
  436. winrect_ptr = _rtgui_cursor->win_bottom;
  437. display_direct_memcpy(winrect_ptr, fb_ptr, winrect_pitch, _rtgui_cursor->screen_pitch,
  438. WIN_MOVE_BORDER, winrect_pitch);
  439. }
  440. static void rtgui_winrect_save()
  441. {
  442. rt_uint8_t *winrect_ptr, *fb_ptr;
  443. int winrect_pitch, idx;
  444. rtgui_rect_t screen_rect, win_rect;
  445. win_rect = _rtgui_cursor->win_rect;
  446. rtgui_graphic_driver_get_rect(rtgui_graphic_driver_get_default(),
  447. &screen_rect);
  448. rtgui_rect_intersect(&screen_rect, &win_rect);
  449. /* set winrect has saved */
  450. _rtgui_cursor->win_rect_has_saved = RT_TRUE;
  451. /* save winrect left */
  452. fb_ptr = _rtgui_cursor->framebuffer + win_rect.y1 * _rtgui_cursor->screen_pitch +
  453. win_rect.x1 * _rtgui_cursor->bpp;
  454. winrect_ptr = _rtgui_cursor->win_left;
  455. winrect_pitch = WIN_MOVE_BORDER * _rtgui_cursor->bpp;
  456. display_direct_memcpy(fb_ptr, winrect_ptr, _rtgui_cursor->screen_pitch, winrect_pitch,
  457. (win_rect.y2 - win_rect.y1), winrect_pitch);
  458. /* save winrect right */
  459. fb_ptr = _rtgui_cursor->framebuffer + win_rect.y1 * _rtgui_cursor->screen_pitch +
  460. (win_rect.x2 - WIN_MOVE_BORDER) * _rtgui_cursor->bpp;
  461. winrect_ptr = _rtgui_cursor->win_right;
  462. winrect_pitch = WIN_MOVE_BORDER * _rtgui_cursor->bpp;
  463. display_direct_memcpy(fb_ptr, winrect_ptr, _rtgui_cursor->screen_pitch, winrect_pitch,
  464. (win_rect.y2 - win_rect.y1), winrect_pitch);
  465. /* save winrect top */
  466. fb_ptr = _rtgui_cursor->framebuffer + win_rect.y1 * _rtgui_cursor->screen_pitch +
  467. (win_rect.x1 + WIN_MOVE_BORDER)* _rtgui_cursor->bpp;
  468. winrect_ptr = _rtgui_cursor->win_top;
  469. winrect_pitch = (win_rect.x2 - win_rect.x1 - 2 * WIN_MOVE_BORDER) * _rtgui_cursor->bpp;
  470. display_direct_memcpy(fb_ptr, winrect_ptr, _rtgui_cursor->screen_pitch, winrect_pitch,
  471. WIN_MOVE_BORDER, winrect_pitch);
  472. /* save winrect bottom */
  473. fb_ptr = _rtgui_cursor->framebuffer + (win_rect.y2 - WIN_MOVE_BORDER) * _rtgui_cursor->screen_pitch +
  474. (win_rect.x1 + WIN_MOVE_BORDER) * _rtgui_cursor->bpp;
  475. winrect_ptr = _rtgui_cursor->win_bottom;
  476. display_direct_memcpy(fb_ptr, winrect_ptr, _rtgui_cursor->screen_pitch, winrect_pitch,
  477. WIN_MOVE_BORDER, winrect_pitch);
  478. }
  479. #endif
  480. void rtgui_mouse_monitor_append(rtgui_list_t* head, rtgui_rect_t* rect)
  481. {
  482. struct rtgui_mouse_monitor* mmonitor;
  483. /* check parameters */
  484. if (head == RT_NULL || rect == RT_NULL) return;
  485. /* create a mouse monitor node */
  486. mmonitor = (struct rtgui_mouse_monitor*) rtgui_malloc (sizeof(struct rtgui_mouse_monitor));
  487. if (mmonitor == RT_NULL) return; /* no memory */
  488. /* set mouse monitor node */
  489. mmonitor->rect = *rect;
  490. rtgui_list_init(&(mmonitor->list));
  491. /* append to list */
  492. rtgui_list_append(head, &(mmonitor->list));
  493. }
  494. void rtgui_mouse_monitor_remove(rtgui_list_t* head, rtgui_rect_t* rect)
  495. {
  496. struct rtgui_list_node* node;
  497. struct rtgui_mouse_monitor* mmonitor;
  498. /* check parameters */
  499. if (head == RT_NULL || rect == RT_NULL) return;
  500. for (node = head->next; node != RT_NULL; node = node->next)
  501. {
  502. mmonitor = rtgui_list_entry(node, struct rtgui_mouse_monitor, list);
  503. if (mmonitor->rect.x1 == rect->x1 &&
  504. mmonitor->rect.x2 == rect->x2 &&
  505. mmonitor->rect.y1 == rect->y1 &&
  506. mmonitor->rect.y2 == rect->y2)
  507. {
  508. /* found node */
  509. rtgui_list_remove(head, node);
  510. rtgui_free(mmonitor);
  511. return ;
  512. }
  513. }
  514. }
  515. rt_bool_t rtgui_mouse_monitor_contains_point(rtgui_list_t* head, int x, int y)
  516. {
  517. struct rtgui_list_node* node;
  518. /* check parameter */
  519. if (head == RT_NULL) return RT_FALSE;
  520. rtgui_list_foreach(node, head)
  521. {
  522. struct rtgui_mouse_monitor* monitor = rtgui_list_entry(node,
  523. struct rtgui_mouse_monitor, list);
  524. if (rtgui_rect_contains_point(&(monitor->rect), x, y) == RT_EOK)
  525. {
  526. return RT_TRUE;
  527. }
  528. }
  529. return RT_FALSE;
  530. }