summaryrefslogtreecommitdiff
path: root/components/rtgui_win/server/mouse.c
diff options
context:
space:
mode:
Diffstat (limited to 'components/rtgui_win/server/mouse.c')
-rw-r--r--components/rtgui_win/server/mouse.c647
1 files changed, 647 insertions, 0 deletions
diff --git a/components/rtgui_win/server/mouse.c b/components/rtgui_win/server/mouse.c
new file mode 100644
index 0000000000..c7244f7d64
--- /dev/null
+++ b/components/rtgui_win/server/mouse.c
@@ -0,0 +1,647 @@
+/*
+ * File : mouse.c
+ * This file is part of RT-Thread RTOS
+ * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
+ *
+ * The license and distribution terms for this file may be
+ * found in the file LICENSE in this distribution or at
+ * http://www.rt-thread.org/license/LICENSE
+ *
+ * Change Logs:
+ * Date Author Notes
+ * 2009-10-16 Bernard first version
+ */
+
+#include "mouse.h"
+#include <rtgui/region.h>
+#include <rtgui/driver.h>
+#include <rtgui/rtgui_system.h>
+
+struct rtgui_cursor
+{
+ /* screen byte per pixel */
+ rt_uint16_t bpp;
+
+ /* screen pitch */
+ rt_uint16_t screen_pitch;
+
+ /* current cursor x and y */
+ rt_uint16_t cx, cy;
+
+#ifdef RTGUI_USING_MOUSE_CURSOR
+ /* cursor pitch */
+ rt_uint16_t cursor_pitch;
+
+ /* show cursor and show cursor count */
+ rt_bool_t show_cursor;
+ rt_base_t show_cursor_count;
+
+ /* cursor rect info */
+ rtgui_rect_t rect;
+
+ /* cursor image and saved cursor */
+ rtgui_image_t *cursor_image;
+ rt_uint8_t *cursor_saved;
+#endif
+
+#ifdef RTGUI_USING_WINMOVE
+ /* move window rect and border */
+ rtgui_win_t *win;
+ rtgui_rect_t win_rect;
+ rt_uint8_t *win_left, *win_right;
+ rt_uint8_t *win_top, *win_bottom;
+ rt_bool_t win_rect_show, win_rect_has_saved;
+#endif
+
+ /* screen framebuffer */
+ rt_uint8_t* framebuffer;
+};
+
+struct rtgui_cursor* _rtgui_cursor;
+
+#ifdef RTGUI_USING_MOUSE_CURSOR
+struct rt_mutex cursor_mutex;
+static const rt_uint8_t *cursor_xpm[] = {
+ "16 16 35 1",
+ " c None",
+ ". c #A0B8D0",
+ "+ c #F0F0F0",
+ "@ c #FFFFFF",
+ "# c #F0F8F0",
+ "$ c #A0B0D0",
+ "% c #90A8C0",
+ "& c #A0B0C0",
+ "* c #E0E8F0",
+ "= c #8090B0",
+ "- c #D0D8E0",
+ "; c #7080A0",
+ "> c #90A0B0",
+ ", c #FFF8FF",
+ "' c #F0F8FF",
+ ") c #607090",
+ "! c #8098B0",
+ "~ c #405060",
+ "{ c #405070",
+ "] c #506070",
+ "^ c #607080",
+ "/ c #708090",
+ "( c #7088A0",
+ "_ c #D0D0E0",
+ ": c #607890",
+ "< c #C0D0E0",
+ "[ c #C0C8D0",
+ "} c #506880",
+ "| c #5F778F",
+ "1 c #D0D8F0",
+ "2 c #506080",
+ "3 c #C0C8E0",
+ "4 c #A0A8C0",
+ "5 c #405870",
+ "6 c #5F6F8F",
+ " . ",
+ " .. ",
+ " .+. ",
+ " .@#$ ",
+ " $@@+% ",
+ " &@@@*= ",
+ " %@@@@-; ",
+ " >@@,''-) ",
+ " !,''+)~{] ",
+ " ='-^*/ ",
+ " (_{:<[^ ",
+ " ;} |:12 ",
+ " / )345 ",
+ " 6}${ ",
+ " 5{ ",
+ " "};
+
+static void rtgui_cursor_restore (void);
+static void rtgui_cursor_save (void);
+static void rtgui_cursor_show (void);
+#endif
+
+#ifdef RTGUI_USING_WINMOVE
+static void rtgui_winrect_restore (void);
+static void rtgui_winrect_save (void);
+static void rtgui_winrect_show (void);
+#endif
+
+#define WIN_MOVE_BORDER 4
+void rtgui_mouse_init()
+{
+ const struct rtgui_graphic_driver* gd = rtgui_graphic_driver_get_default();
+
+ _rtgui_cursor = (struct rtgui_cursor*) rtgui_malloc(sizeof(struct rtgui_cursor));
+ rt_memset(_rtgui_cursor, 0, sizeof(struct rtgui_cursor));
+
+#ifdef RTGUI_USING_MOUSE_CURSOR
+ rt_mutex_init(&cursor_mutex, "cursor", RT_IPC_FLAG_FIFO);
+#endif
+
+ /* init cursor */
+ _rtgui_cursor->bpp = gd->byte_per_pixel;
+ _rtgui_cursor->framebuffer = gd->get_framebuffer();
+ _rtgui_cursor->screen_pitch = _rtgui_cursor->bpp * gd->width;
+
+#ifdef RTGUI_USING_MOUSE_CURSOR
+ /* init cursor image */
+ _rtgui_cursor->cursor_image = rtgui_image_create_from_mem("xpm", (rt_uint8_t*)cursor_xpm, sizeof(cursor_xpm),RT_TRUE);
+ if (_rtgui_cursor->cursor_image == RT_NULL)
+ {
+ rtgui_free(_rtgui_cursor);
+ _rtgui_cursor = RT_NULL;
+
+ return;
+ }
+
+ /* init rect */
+ _rtgui_cursor->rect.x1 = gd->width/2;
+ _rtgui_cursor->rect.y1 = gd->height/2;
+ _rtgui_cursor->rect.x2 = _rtgui_cursor->rect.x1 + _rtgui_cursor->cursor_image->w;
+ _rtgui_cursor->rect.y2 = _rtgui_cursor->rect.y1 + _rtgui_cursor->cursor_image->h;
+
+ _rtgui_cursor->cursor_pitch = _rtgui_cursor->cursor_image->w * _rtgui_cursor->bpp;
+
+ _rtgui_cursor->show_cursor = RT_TRUE;
+ _rtgui_cursor->show_cursor_count = 0;
+ _rtgui_cursor->cursor_saved = rtgui_malloc(_rtgui_cursor->cursor_image->w *
+ _rtgui_cursor->cursor_image->h * _rtgui_cursor->bpp);
+#endif
+
+
+#ifdef RTGUI_USING_WINMOVE
+ /* init window move save image */
+ _rtgui_cursor->win_rect_has_saved = RT_FALSE;
+ _rtgui_cursor->win_rect_show = RT_FALSE;
+
+ _rtgui_cursor->win_left = rtgui_malloc(_rtgui_cursor->bpp * gd->height * WIN_MOVE_BORDER);
+ _rtgui_cursor->win_right = rtgui_malloc(_rtgui_cursor->bpp * gd->height * WIN_MOVE_BORDER);
+ _rtgui_cursor->win_top = rtgui_malloc(_rtgui_cursor->bpp * gd->width * WIN_MOVE_BORDER);
+ _rtgui_cursor->win_bottom = rtgui_malloc(_rtgui_cursor->bpp * gd->width * WIN_MOVE_BORDER);
+#endif
+}
+
+void rtgui_mouse_moveto(int x, int y)
+{
+#ifdef RTGUI_USING_MOUSE_CURSOR
+ rt_mutex_take(&cursor_mutex, RT_WAITING_FOREVER);
+#endif
+
+ if (x != _rtgui_cursor->cx || y != _rtgui_cursor->cy)
+ {
+#ifdef RTGUI_USING_WINMOVE
+ if (_rtgui_cursor->win_rect_show)
+ {
+ if (_rtgui_cursor->win_rect_has_saved == RT_TRUE)
+ {
+ rtgui_winrect_restore();
+ }
+
+#ifdef RTGUI_USING_MOUSE_CURSOR
+ rtgui_mouse_hide_cursor();
+#endif
+
+ /* move winrect */
+ rtgui_rect_moveto(&(_rtgui_cursor->win_rect), x - _rtgui_cursor->cx,
+ y - _rtgui_cursor->cy);
+ rtgui_winrect_save();
+
+ /* move current cursor */
+ _rtgui_cursor->cx = x;
+ _rtgui_cursor->cy = y;
+
+#ifdef RTGUI_USING_MOUSE_CURSOR
+ /* show cursor */
+ rtgui_mouse_show_cursor();
+#endif
+ /* show winrect */
+ rtgui_winrect_show();
+ }
+ else
+#endif
+ {
+#ifdef RTGUI_USING_MOUSE_CURSOR
+ rtgui_mouse_hide_cursor();
+#endif
+ /* move current cursor */
+ _rtgui_cursor->cx = x;
+ _rtgui_cursor->cy = y;
+
+#ifdef RTGUI_USING_MOUSE_CURSOR
+ /* show cursor */
+ rtgui_mouse_show_cursor();
+#endif
+ }
+ }
+
+#ifdef RTGUI_USING_MOUSE_CURSOR
+ rt_mutex_release(&cursor_mutex);
+#endif
+}
+
+#ifdef RTGUI_USING_MOUSE_CURSOR
+void rtgui_mouse_set_cursor_enable(rt_bool_t enable)
+{
+ _rtgui_cursor->show_cursor = enable;
+}
+
+/* set current cursor image */
+void rtgui_mouse_set_cursor(rtgui_image_t* cursor)
+{
+}
+
+void rtgui_mouse_get_cursor_rect(rtgui_rect_t* rect)
+{
+ if (rect != RT_NULL)
+ {
+ *rect = _rtgui_cursor->rect;
+ }
+}
+
+void rtgui_mouse_show_cursor()
+{
+ if (_rtgui_cursor->show_cursor == RT_FALSE)
+ return;
+
+ _rtgui_cursor->show_cursor_count ++;
+ if (_rtgui_cursor->show_cursor_count == 1)
+ {
+ /* save show mouse area */
+ rtgui_cursor_save();
+
+ /* show mouse cursor */
+ rtgui_cursor_show();
+ }
+}
+
+void rtgui_mouse_hide_cursor()
+{
+ if (_rtgui_cursor->show_cursor == RT_FALSE)
+ return;
+
+ if (_rtgui_cursor->show_cursor_count == 1)
+ {
+ /* display the cursor coverage area */
+ rtgui_cursor_restore();
+ }
+ _rtgui_cursor->show_cursor_count --;
+}
+
+rt_bool_t rtgui_mouse_is_intersect(rtgui_rect_t* r)
+{
+ return rtgui_rect_is_intersect(&(_rtgui_cursor->rect), r) == RT_EOK? RT_TRUE : RT_FALSE;
+}
+
+/* display the saved cursor area to screen */
+static void rtgui_cursor_restore()
+{
+ rt_base_t idx, height, cursor_pitch;
+ rt_uint8_t *cursor_ptr, *fb_ptr;
+
+ fb_ptr = _rtgui_cursor->framebuffer + _rtgui_cursor->cy * _rtgui_cursor->screen_pitch
+ + _rtgui_cursor->cx * _rtgui_cursor->bpp;
+ cursor_ptr = _rtgui_cursor->cursor_saved;
+
+ height = (_rtgui_cursor->cy + _rtgui_cursor->cursor_image->h <
+ rtgui_graphic_driver_get_default()->height)? _rtgui_cursor->cursor_image->h :
+ rtgui_graphic_driver_get_default()->height - _rtgui_cursor->cy;
+
+ cursor_pitch = (_rtgui_cursor->cx + _rtgui_cursor->cursor_image->w <
+ rtgui_graphic_driver_get_default()->width)? _rtgui_cursor->cursor_pitch :
+ (rtgui_graphic_driver_get_default()->width - _rtgui_cursor->cx) * _rtgui_cursor->bpp;
+
+ for (idx = 0; idx < height; idx ++)
+ {
+ rt_memcpy(fb_ptr, cursor_ptr, cursor_pitch);
+
+ fb_ptr += _rtgui_cursor->screen_pitch;
+ cursor_ptr += _rtgui_cursor->cursor_pitch;
+ }
+}
+
+/* save the cursor coverage area from screen */
+static void rtgui_cursor_save()
+{
+ rt_base_t idx, height, cursor_pitch;
+ rt_uint8_t *cursor_ptr, *fb_ptr;
+
+ fb_ptr = _rtgui_cursor->framebuffer + _rtgui_cursor->cy * _rtgui_cursor->screen_pitch +
+ _rtgui_cursor->cx * _rtgui_cursor->bpp;
+ cursor_ptr = _rtgui_cursor->cursor_saved;
+
+ height = (_rtgui_cursor->cy + _rtgui_cursor->cursor_image->h <
+ rtgui_graphic_driver_get_default()->height)? _rtgui_cursor->cursor_image->h :
+ rtgui_graphic_driver_get_default()->height - _rtgui_cursor->cy;
+
+ cursor_pitch = (_rtgui_cursor->cx + _rtgui_cursor->cursor_image->w <
+ rtgui_graphic_driver_get_default()->width)? _rtgui_cursor->cursor_pitch :
+ (rtgui_graphic_driver_get_default()->width - _rtgui_cursor->cx) * _rtgui_cursor->bpp;
+
+ for (idx = 0; idx < height; idx ++)
+ {
+ rt_memcpy(cursor_ptr, fb_ptr, cursor_pitch);
+
+ fb_ptr += _rtgui_cursor->screen_pitch;
+ cursor_ptr += _rtgui_cursor->cursor_pitch;
+ }
+}
+
+static void rtgui_cursor_show()
+{
+ rt_uint16_t x, y;
+ rtgui_color_t* ptr;
+ rtgui_rect_t rect;
+ void (*set_pixel) (rtgui_color_t *c, rt_base_t x, rt_base_t y);
+
+ ptr = (rtgui_color_t*) _rtgui_cursor->cursor_image->data;
+ set_pixel = rtgui_graphic_driver_get_default()->set_pixel;
+
+ rtgui_mouse_get_cursor_rect(&rect);
+ rtgui_rect_moveto(&rect, _rtgui_cursor->cx, _rtgui_cursor->cy);
+
+ /* draw each point */
+ for (y = rect.y1; y < rect.y2; y ++)
+ {
+ for (x = rect.x1; x < rect.x2; x++)
+ {
+ /* not alpha */
+ if ((*ptr >> 24) != 255)
+ {
+ set_pixel(ptr, x, y);
+ }
+
+ /* move to next color buffer */
+ ptr ++;
+ }
+ }
+
+ /* update rect */
+ rtgui_graphic_driver_get_default()->screen_update(&rect);
+}
+#endif
+
+#ifdef RTGUI_USING_WINMOVE
+void rtgui_winrect_set(rtgui_win_t* win)
+{
+ /* set win rect show */
+ _rtgui_cursor->win_rect_show = RT_TRUE;
+
+ /* set win rect */
+ _rtgui_cursor->win_rect = RTGUI_WIDGET_EXTENT(win);
+ _rtgui_cursor->win = win;
+}
+
+void rtgui_cursor_set_location(int x, int y)
+{
+ _rtgui_cursor->cx = x;
+ _rtgui_cursor->cy = y;
+}
+
+rt_bool_t rtgui_winrect_moved_done(rtgui_rect_t* winrect, rtgui_win_t** win)
+{
+ rt_bool_t moved = RT_FALSE;
+
+ /* no win rect */
+ if (winrect == RT_NULL) return RT_FALSE;
+
+ /* restore winrect */
+ if (_rtgui_cursor->win_rect_has_saved)
+ {
+ rtgui_winrect_restore();
+
+ moved = RT_TRUE;
+ }
+
+ /* clear win rect show */
+ _rtgui_cursor->win_rect_show = RT_FALSE;
+ _rtgui_cursor->win_rect_has_saved = RT_FALSE;
+
+ /* return win rect */
+ *winrect = _rtgui_cursor->win_rect;
+ *win = _rtgui_cursor->win;
+
+ return moved;
+}
+
+rt_bool_t rtgui_winrect_is_moved()
+{
+ return _rtgui_cursor->win_rect_show;
+}
+
+/* show winrect */
+static void rtgui_winrect_show()
+{
+ rt_uint16_t x, y;
+ rtgui_color_t c;
+ rtgui_rect_t screen_rect, win_rect, win_rect_inner;
+ void (*set_pixel) (rtgui_color_t *c, rt_base_t x, rt_base_t y);
+
+ c = black;
+ set_pixel = rtgui_graphic_driver_get_default()->set_pixel;
+
+ win_rect = _rtgui_cursor->win_rect;
+
+ win_rect_inner = win_rect;
+ rtgui_rect_inflate(&win_rect_inner, -WIN_MOVE_BORDER);
+
+ rtgui_graphic_driver_get_rect(rtgui_graphic_driver_get_default(),
+ &screen_rect);
+ rtgui_rect_intersect(&screen_rect, &win_rect);
+ rtgui_rect_intersect(&screen_rect, &win_rect_inner);
+
+ /* draw left */
+ for (y = win_rect.y1; y < win_rect.y2; y ++)
+ {
+ for (x = win_rect.x1; x < win_rect_inner.x1; x++)
+ if ((x + y) & 0x01) set_pixel(&c, x, y);
+ }
+
+ /* draw right */
+ for (y = win_rect.y1; y < win_rect.y2; y ++)
+ {
+ for (x = win_rect_inner.x2; x < win_rect.x2; x++)
+ if ((x + y) & 0x01) set_pixel(&c, x, y);
+ }
+
+ /* draw top border */
+ for (y = win_rect.y1; y < win_rect_inner.y1; y ++)
+ {
+ for (x = win_rect_inner.x1; x < win_rect_inner.x2; x++)
+ if ((x + y) & 0x01) set_pixel(&c, x, y);
+ }
+
+ /* draw bottom border */
+ for (y = win_rect_inner.y2; y < win_rect.y2; y ++)
+ {
+ for (x = win_rect_inner.x1; x < win_rect_inner.x2; x++)
+ if ((x + y) & 0x01) set_pixel(&c, x, y);
+ }
+
+ /* update rect */
+ rtgui_graphic_driver_get_default()->screen_update(&win_rect);
+}
+
+#define display_direct_memcpy(src, dest, src_pitch, dest_pitch, height, len) \
+ for (idx = 0; idx < height; idx ++) \
+ { \
+ rt_memcpy(dest, src, len); \
+ src += src_pitch; \
+ dest += dest_pitch; \
+ }
+
+static void rtgui_winrect_restore()
+{
+ rt_uint8_t *winrect_ptr, *fb_ptr;
+ int winrect_pitch, idx;
+ rtgui_rect_t screen_rect, win_rect;
+
+ win_rect = _rtgui_cursor->win_rect;
+
+ rtgui_graphic_driver_get_rect(rtgui_graphic_driver_get_default(),
+ &screen_rect);
+ rtgui_rect_intersect(&screen_rect, &win_rect);
+
+ /* restore winrect left */
+ fb_ptr = _rtgui_cursor->framebuffer + win_rect.y1 * _rtgui_cursor->screen_pitch +
+ win_rect.x1 * _rtgui_cursor->bpp;
+ winrect_ptr = _rtgui_cursor->win_left;
+ winrect_pitch = WIN_MOVE_BORDER * _rtgui_cursor->bpp;
+ display_direct_memcpy(winrect_ptr, fb_ptr, winrect_pitch, _rtgui_cursor->screen_pitch,
+ (win_rect.y2 - win_rect.y1), winrect_pitch);
+
+ /* restore winrect right */
+ fb_ptr = _rtgui_cursor->framebuffer + win_rect.y1 * _rtgui_cursor->screen_pitch +
+ (win_rect.x2 - WIN_MOVE_BORDER) * _rtgui_cursor->bpp;
+ winrect_ptr = _rtgui_cursor->win_right;
+ winrect_pitch = WIN_MOVE_BORDER * _rtgui_cursor->bpp;
+ display_direct_memcpy(winrect_ptr, fb_ptr, winrect_pitch, _rtgui_cursor->screen_pitch,
+ (win_rect.y2 - win_rect.y1), winrect_pitch);
+
+ /* restore winrect top */
+ fb_ptr = _rtgui_cursor->framebuffer + win_rect.y1 * _rtgui_cursor->screen_pitch +
+ (win_rect.x1 + WIN_MOVE_BORDER)* _rtgui_cursor->bpp;
+ winrect_ptr = _rtgui_cursor->win_top;
+ winrect_pitch = (win_rect.x2 - win_rect.x1 - 2 * WIN_MOVE_BORDER) * _rtgui_cursor->bpp;
+ display_direct_memcpy(winrect_ptr, fb_ptr, winrect_pitch, _rtgui_cursor->screen_pitch,
+ WIN_MOVE_BORDER, winrect_pitch);
+
+ /* restore winrect bottom */
+ fb_ptr = _rtgui_cursor->framebuffer + (win_rect.y2 - WIN_MOVE_BORDER) * _rtgui_cursor->screen_pitch +
+ (win_rect.x1 + WIN_MOVE_BORDER) * _rtgui_cursor->bpp;
+ winrect_ptr = _rtgui_cursor->win_bottom;
+ display_direct_memcpy(winrect_ptr, fb_ptr, winrect_pitch, _rtgui_cursor->screen_pitch,
+ WIN_MOVE_BORDER, winrect_pitch);
+}
+
+static void rtgui_winrect_save()
+{
+ rt_uint8_t *winrect_ptr, *fb_ptr;
+ int winrect_pitch, idx;
+ rtgui_rect_t screen_rect, win_rect;
+
+ win_rect = _rtgui_cursor->win_rect;
+
+ rtgui_graphic_driver_get_rect(rtgui_graphic_driver_get_default(),
+ &screen_rect);
+ rtgui_rect_intersect(&screen_rect, &win_rect);
+
+ /* set winrect has saved */
+ _rtgui_cursor->win_rect_has_saved = RT_TRUE;
+
+ /* save winrect left */
+ fb_ptr = _rtgui_cursor->framebuffer + win_rect.y1 * _rtgui_cursor->screen_pitch +
+ win_rect.x1 * _rtgui_cursor->bpp;
+ winrect_ptr = _rtgui_cursor->win_left;
+ winrect_pitch = WIN_MOVE_BORDER * _rtgui_cursor->bpp;
+ display_direct_memcpy(fb_ptr, winrect_ptr, _rtgui_cursor->screen_pitch, winrect_pitch,
+ (win_rect.y2 - win_rect.y1), winrect_pitch);
+
+ /* save winrect right */
+ fb_ptr = _rtgui_cursor->framebuffer + win_rect.y1 * _rtgui_cursor->screen_pitch +
+ (win_rect.x2 - WIN_MOVE_BORDER) * _rtgui_cursor->bpp;
+ winrect_ptr = _rtgui_cursor->win_right;
+ winrect_pitch = WIN_MOVE_BORDER * _rtgui_cursor->bpp;
+ display_direct_memcpy(fb_ptr, winrect_ptr, _rtgui_cursor->screen_pitch, winrect_pitch,
+ (win_rect.y2 - win_rect.y1), winrect_pitch);
+
+ /* save winrect top */
+ fb_ptr = _rtgui_cursor->framebuffer + win_rect.y1 * _rtgui_cursor->screen_pitch +
+ (win_rect.x1 + WIN_MOVE_BORDER)* _rtgui_cursor->bpp;
+ winrect_ptr = _rtgui_cursor->win_top;
+ winrect_pitch = (win_rect.x2 - win_rect.x1 - 2 * WIN_MOVE_BORDER) * _rtgui_cursor->bpp;
+ display_direct_memcpy(fb_ptr, winrect_ptr, _rtgui_cursor->screen_pitch, winrect_pitch,
+ WIN_MOVE_BORDER, winrect_pitch);
+
+ /* save winrect bottom */
+ fb_ptr = _rtgui_cursor->framebuffer + (win_rect.y2 - WIN_MOVE_BORDER) * _rtgui_cursor->screen_pitch +
+ (win_rect.x1 + WIN_MOVE_BORDER) * _rtgui_cursor->bpp;
+ winrect_ptr = _rtgui_cursor->win_bottom;
+ display_direct_memcpy(fb_ptr, winrect_ptr, _rtgui_cursor->screen_pitch, winrect_pitch,
+ WIN_MOVE_BORDER, winrect_pitch);
+}
+#endif
+
+void rtgui_mouse_monitor_append(rtgui_list_t* head, rtgui_rect_t* rect)
+{
+ struct rtgui_mouse_monitor* mmonitor;
+
+ /* check parameters */
+ if (head == RT_NULL || rect == RT_NULL) return;
+
+ /* create a mouse monitor node */
+ mmonitor = (struct rtgui_mouse_monitor*) rtgui_malloc (sizeof(struct rtgui_mouse_monitor));
+ if (mmonitor == RT_NULL) return; /* no memory */
+
+ /* set mouse monitor node */
+ mmonitor->rect = *rect;
+ rtgui_list_init(&(mmonitor->list));
+
+ /* append to list */
+ rtgui_list_append(head, &(mmonitor->list));
+}
+
+void rtgui_mouse_monitor_remove(rtgui_list_t* head, rtgui_rect_t* rect)
+{
+ rtgui_list_t* node;
+ struct rtgui_mouse_monitor* mmonitor;
+
+ /* check parameters */
+ if (head == RT_NULL || rect == RT_NULL) return;
+
+ for (node = head->next; node != RT_NULL; node = node->next)
+ {
+ mmonitor = rtgui_list_entry(node, struct rtgui_mouse_monitor, list);
+ if (mmonitor->rect.x1 == rect->x1 &&
+ mmonitor->rect.x2 == rect->x2 &&
+ mmonitor->rect.y1 == rect->y1 &&
+ mmonitor->rect.y2 == rect->y2)
+ {
+ /* found node */
+ rtgui_list_remove(head, node);
+ rtgui_free(mmonitor);
+
+ return ;
+ }
+ }
+}
+
+rt_bool_t rtgui_mouse_monitor_contains_point(rtgui_list_t* head, int x, int y)
+{
+ rtgui_list_t* node;
+
+ /* check parameter */
+ if (head == RT_NULL) return RT_FALSE;
+
+ rtgui_list_foreach(node, head)
+ {
+ struct rtgui_mouse_monitor* monitor = rtgui_list_entry(node,
+ struct rtgui_mouse_monitor, list);
+
+ if (rtgui_rect_contains_point(&(monitor->rect), x, y) == RT_EOK)
+ {
+ return RT_TRUE;
+ }
+ }
+
+ return RT_FALSE;
+}