668 lines
20 KiB
C
668 lines
20 KiB
C
/*
|
|
* 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 */
|
|
struct rtgui_topwin *topwin;
|
|
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
|
|
};
|
|
|
|
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(void)
|
|
{
|
|
const struct rtgui_graphic_driver *gd = rtgui_graphic_driver_get_default();
|
|
|
|
if (_rtgui_cursor != RT_NULL) rtgui_mouse_fini();
|
|
|
|
_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->bits_per_pixel / 8;
|
|
_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 = _rtgui_cursor->rect.y1 = 0;
|
|
_rtgui_cursor->rect.x2 = _rtgui_cursor->cursor_image->w;
|
|
_rtgui_cursor->rect.y2 = _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_fini(void)
|
|
{
|
|
if (_rtgui_cursor != RT_NULL)
|
|
{
|
|
#ifdef RTGUI_USING_WINMOVE
|
|
rtgui_free(_rtgui_cursor->win_left);
|
|
rtgui_free(_rtgui_cursor->win_right);
|
|
rtgui_free(_rtgui_cursor->win_top);
|
|
rtgui_free(_rtgui_cursor->win_bottom);
|
|
#endif
|
|
#ifdef RTGUI_USING_MOUSE_CURSOR
|
|
rt_mutex_detach(&cursor_mutex);
|
|
rtgui_image_destroy(_rtgui_cursor->cursor_image);
|
|
rtgui_free(_rtgui_cursor->cursor_saved);
|
|
#endif
|
|
rtgui_free(_rtgui_cursor);
|
|
|
|
_rtgui_cursor = RT_NULL;
|
|
}
|
|
}
|
|
|
|
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_graphic_driver_get_default_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_graphic_driver_get_default_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()
|
|
{
|
|
// FIXME: the prototype of set_pixel is using int so we have to use int
|
|
// as well. Might be uniformed with others in the future
|
|
int x, y;
|
|
rtgui_color_t *ptr;
|
|
rtgui_rect_t rect;
|
|
void (*set_pixel)(rtgui_color_t * c, int x, int y);
|
|
|
|
ptr = (rtgui_color_t *) _rtgui_cursor->cursor_image->data;
|
|
set_pixel = rtgui_graphic_driver_get_default()->ops->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_screen_update(rtgui_graphic_driver_get_default(), &rect);
|
|
}
|
|
#endif
|
|
|
|
#ifdef RTGUI_USING_WINMOVE
|
|
void rtgui_winrect_set(struct rtgui_topwin *topwin)
|
|
{
|
|
/* set win rect show */
|
|
_rtgui_cursor->win_rect_show = RT_TRUE;
|
|
|
|
/* set win rect */
|
|
_rtgui_cursor->win_rect = topwin->title == RT_NULL ? topwin->extent : RTGUI_WIDGET(topwin->title)->extent;
|
|
_rtgui_cursor->topwin = topwin;
|
|
}
|
|
|
|
rt_bool_t rtgui_winrect_moved_done(rtgui_rect_t *winrect, struct rtgui_topwin **topwin)
|
|
{
|
|
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;
|
|
*topwin = _rtgui_cursor->topwin;
|
|
|
|
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, int x, int y);
|
|
|
|
c = black;
|
|
set_pixel = rtgui_graphic_driver_get_default()->ops->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_screen_update(rtgui_graphic_driver_get_default(), &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, *driver_fb;
|
|
int winrect_pitch, idx;
|
|
rtgui_rect_t screen_rect, win_rect;
|
|
|
|
driver_fb = rtgui_graphic_driver_get_default_framebuffer();
|
|
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 = driver_fb + 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 = driver_fb + 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 = driver_fb + 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 = driver_fb + (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, *driver_fb;
|
|
int winrect_pitch, idx;
|
|
rtgui_rect_t screen_rect, win_rect;
|
|
|
|
driver_fb = rtgui_graphic_driver_get_default_framebuffer();
|
|
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 = driver_fb + 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 = driver_fb + 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 = driver_fb + 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 = driver_fb + (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)
|
|
{
|
|
struct rtgui_list_node *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)
|
|
{
|
|
struct rtgui_list_node *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;
|
|
}
|