summaryrefslogtreecommitdiff
path: root/components/rtgui_win/server
diff options
context:
space:
mode:
Diffstat (limited to 'components/rtgui_win/server')
-rw-r--r--components/rtgui_win/server/MOUSE_PS2.c192
-rw-r--r--components/rtgui_win/server/driver.c84
-rw-r--r--components/rtgui_win/server/mouse.c647
-rw-r--r--components/rtgui_win/server/mouse.h54
-rw-r--r--components/rtgui_win/server/panel.c284
-rw-r--r--components/rtgui_win/server/panel.h61
-rw-r--r--components/rtgui_win/server/server.c320
-rw-r--r--components/rtgui_win/server/topwin.c660
-rw-r--r--components/rtgui_win/server/topwin.h43
9 files changed, 2345 insertions, 0 deletions
diff --git a/components/rtgui_win/server/MOUSE_PS2.c b/components/rtgui_win/server/MOUSE_PS2.c
new file mode 100644
index 0000000000..e18f650880
--- /dev/null
+++ b/components/rtgui_win/server/MOUSE_PS2.c
@@ -0,0 +1,192 @@
+/*
+----------------------------------------------------------------------
+File : GUITOUCH.C
+Purpose : Touch screen manager
+----------------------------------------------------------------------
+This module handles the touch screen. It is configured in the file
+GUITouch.conf.h (Should be located in the Config\ directory).
+----------------------------------------------------------------------
+*/
+#include <rtthread.h>
+#include <event.h>
+#include <rtgui_server.h>
+#include <lcd.h>
+
+
+#define MOUSE_CLK (1<<2 ) //GPG2
+#define MOUSE_DATA (1<<11) //GPE11
+
+#define MOUSE_CLK_H() (GPGDAT |= MOUSE_CLK)
+#define MOUSE_CLK_L() (GPGDAT &= ~MOUSE_CLK)
+#define MOUSE_CLK_OUT() (GPGCON = GPGCON &(~(0x03<<4)) | (0x01<<4))
+
+#define MOUSE_DATA_H() (GPEDAT |= MOUSE_DATA)
+#define MOUSE_DATA_L() (GPEDAT &= ~MOUSE_DATA)
+#define MOUSE_DATA_IN() (GPECON = GPECON &(~(0x03<<22)))
+#define MOUSE_DATA_OUT() (GPECON = GPECON &(~(0x03<<22))|(0x01<<22))
+#define MOUSE_DATA_GET() (GPEDAT & MOUSE_DATA)
+
+
+
+static rt_int32_t _ScreenX = 0; /* x-pos */
+static rt_int32_t _ScreenY = 0; /* y-pos */
+static rt_int32_t _NumBytesInBuffer = 0; /* bytes in rx buffer */
+static rt_uint8_t _Buttons = 0; /* button status */
+static rt_uint8_t _abInBuffer[3]; /* mouse rx buffer */
+
+/*********************************************************************
+* PID (Pointer input device ... mouse/touch)
+**********************************************************************
+*/
+typedef struct
+{
+ struct rt_device parent;
+ struct rt_timer* timer;
+ int x,y;
+ rt_uint8_t Pressed;
+} PS2_MOUSE;
+
+static PS2_MOUSE *s_mouse = RT_NULL;
+
+/*********************************************************************
+* _EvaPacket
+**********************************************************************
+�������յ����ݰ�����:
+ | D7 D6 D5 D4 D3 D2 D1 D0
+---------------------------------------------------------
+1st byte | -- -- Y- X- 1 -- LB RB
+2nd byte | X7 X6 X5 X4 X3 X2 X1 X0
+3rd byte | Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0
+*/
+
+static void _EvaPacket(void)
+{
+ char a;
+
+ rtgui_event_mouse_t emouse;
+ emouse.parent.sender = RT_NULL;
+ _Buttons = _abInBuffer[0] & 0x03;
+
+ a = _abInBuffer[1];
+ //����X�ƶ�����
+ if(_abInBuffer[0] & 0x10)
+ {
+ a = -a;
+ _ScreenX -= a;
+ } /* direction is negative, move left */
+ else
+ {
+ _ScreenX += a;
+ }
+
+ a = _abInBuffer[2];
+ //����Y�ƶ�����
+ if(_abInBuffer[0] & 0x20)
+ {
+ a = -a;
+ _ScreenY += a;
+ } /* direction is negative, move down */
+ else
+ {
+ _ScreenY -= a;
+ }
+
+ /* check min/max positions */
+ if(_ScreenX < 0)
+ {
+ _ScreenX = 0;
+ }
+ else if(_ScreenX > LCD_XSIZE-1)
+ {
+ _ScreenX = LCD_XSIZE-1;
+ }
+
+ if(_ScreenY < 0)
+ {
+ _ScreenY = 0;
+ }
+ else if(_ScreenY > LCD_YSIZE-1)
+ {
+ _ScreenY = LCD_YSIZE-1;
+ }
+
+ /* signal new mouse data */
+ emouse.parent.type = RTGUI_EVENT_MOUSE_BUTTON;
+ emouse.x = _ScreenX;
+ emouse.y = _ScreenY;
+ emouse.button = _Buttons;
+ //GUI_MOUSE_StoreState(&emouse);
+ rtgui_server_post_event((&emouse.parent), sizeof(emouse));
+}
+
+
+/*********************************************************************
+ Mouse receive interrupt handler
+ The PS2 mouse interrupt gets in three bytes from the mouse, then wakes
+ up the mouse LSR.
+**********************************************************************/
+
+void GUI_MOUSE_DRIVER_PS2_OnRx(rt_uint8_t Data)
+{
+ if(!_NumBytesInBuffer)
+ {
+ /* check for start frame */
+ if((Data & 0x0c) == 0x08)
+ {
+ _abInBuffer[0] = Data;
+ _NumBytesInBuffer++;
+ }
+ }
+ else
+ {
+ _abInBuffer[_NumBytesInBuffer] = Data;
+ _NumBytesInBuffer++;
+ if(_NumBytesInBuffer >= 3)
+ {
+ _EvaPacket();
+ _NumBytesInBuffer = 0;
+ }
+ }
+}
+
+/*********************************************************************
+*
+* GUI_MOUSE_DRIVER_PS2_Init
+*
+**********************************************************************
+*/
+
+void mouse_PS2_init(void)
+{
+ _NumBytesInBuffer = 0;
+}
+
+static void mouse_timer_fire(void* parameter)
+{
+
+}
+
+void rtgui_PS2_hw_init(void)
+{
+ s_mouse = (PS2_MOUSE*)rt_malloc (sizeof(PS2_MOUSE));
+ if(s_mouse == RT_NULL) return; /* no memory yet */
+
+ /* clear device structure */
+ rt_memset(&(s_mouse->parent), 0, sizeof(struct rt_device));
+
+ /* init device structure */
+ s_mouse->parent.type = RT_Device_Class_Unknown;
+ s_mouse->parent.init = RT_NULL;//rtgui_mouse_init;
+ s_mouse->parent.control = RT_NULL;//rtgui_touch_control;
+ s_mouse->parent.private = RT_NULL;
+
+ /* create 1/8 second timer */
+ s_mouse->timer = rt_timer_create("mouse", mouse_timer_fire, RT_NULL,
+ RT_TICK_PER_SECOND/10, RT_TIMER_FLAG_PERIODIC);
+
+ /* register touch device to RT-Thread */
+ rt_device_register(&(s_mouse->parent), "mouse", RT_DEVICE_FLAG_RDWR);
+
+ s_mouse->parent.init(RT_NULL);
+}
+
diff --git a/components/rtgui_win/server/driver.c b/components/rtgui_win/server/driver.c
new file mode 100644
index 0000000000..e93317dce9
--- /dev/null
+++ b/components/rtgui_win/server/driver.c
@@ -0,0 +1,84 @@
+/*
+ * File : driver.c
+ * This file is part of RTGUI in 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-04 Bernard first version
+ */
+#include <rtgui/driver.h>
+
+#ifdef RTGUI_USING_GRAPHIC_DRIVER_LIST
+rtgui_list_t _rtgui_graphic_driver_list = {RT_NULL};
+
+void rtgui_graphic_driver_add(struct rtgui_graphic_driver* driver)
+{
+ rtgui_list_insert(&_rtgui_graphic_driver_list, &(driver->list));
+}
+
+void rtgui_graphic_driver_remove(struct rtgui_graphic_driver* driver)
+{
+ rtgui_list_remove(&_rtgui_graphic_driver_list, &(driver->list));
+}
+
+struct rtgui_graphic_driver* rtgui_graphic_driver_find(char* name)
+{
+ rtgui_list_t* node;
+ struct rtgui_graphic_driver* driver;
+
+ /* search in list */
+ rtgui_list_foreach(node, &(_rtgui_graphic_driver_list))
+ {
+ driver = rtgui_list_entry(node, struct rtgui_graphic_driver, list);
+
+ /* find it */
+ if (rt_strncmp(driver->name, name, RTGUI_NAME_MAX) == 0)
+ {
+ return driver;
+ }
+ }
+
+ return RT_NULL;
+}
+
+struct rtgui_graphic_driver* rtgui_graphic_driver_get_default()
+{
+ return rtgui_list_entry(_rtgui_graphic_driver_list.next,
+ struct rtgui_graphic_driver, list);
+}
+#else
+static const struct rtgui_graphic_driver* _default_graphic_driver = RT_NULL;
+
+void rtgui_graphic_driver_add(const struct rtgui_graphic_driver* driver)
+{
+ _default_graphic_driver = driver;
+}
+
+const struct rtgui_graphic_driver* rtgui_graphic_driver_get_default()
+{
+ return _default_graphic_driver;
+}
+#endif
+
+
+void rtgui_graphic_driver_get_rect(const struct rtgui_graphic_driver *driver, rtgui_rect_t *rect)
+{
+ RT_ASSERT(rect != RT_NULL);
+ RT_ASSERT(driver != RT_NULL);
+
+ rect->x1 = rect->y1 = 0;
+ rect->x2 = driver->width;
+ rect->y2 = driver->height;
+}
+
+void rtgui_graphic_driver_get_default_rect(rtgui_rect_t *rect)
+{
+ /* return default the extent of default driver */
+ rtgui_graphic_driver_get_rect(rtgui_graphic_driver_get_default(), rect);
+}
+
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;
+}
diff --git a/components/rtgui_win/server/mouse.h b/components/rtgui_win/server/mouse.h
new file mode 100644
index 0000000000..c5fcb7578d
--- /dev/null
+++ b/components/rtgui_win/server/mouse.h
@@ -0,0 +1,54 @@
+/*
+ * File : mouse.h
+ * 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
+ */
+#ifndef __RTGUI_MOUSE_H__
+#define __RTGUI_MOUSE_H__
+
+#include <rtgui/rtgui.h>
+#include <rtgui/image.h>
+#include "topwin.h"
+
+struct rtgui_mouse_monitor
+{
+ /* event rect */
+ rtgui_rect_t rect;
+
+ /* node list */
+ rtgui_list_t list;
+};
+typedef struct rtgui_mouse_monitor rtgui_mouse_monitor_t;
+
+void rtgui_mouse_init(void);
+void rtgui_mouse_moveto(int x, int y);
+
+void rtgui_mouse_set_cursor_enable(rt_bool_t enable);
+void rtgui_mouse_set_cursor(rtgui_image_t* cursor);
+void rtgui_mouse_get_cursor_rect(rtgui_rect_t* rect);
+
+void rtgui_mouse_show_cursor(void);
+void rtgui_mouse_hide_cursor(void);
+
+rt_bool_t rtgui_mouse_is_intersect(rtgui_rect_t* r);
+
+#ifdef RTGUI_USING_WINMOVE
+rt_bool_t rtgui_winrect_is_moved(void);
+void rtgui_winrect_set(rtgui_win_t* win);
+void rtgui_cursor_set_location(int x, int y);
+rt_bool_t rtgui_winrect_moved_done(rtgui_rect_t* winrect, rtgui_win_t** win);
+#endif
+
+void rtgui_mouse_monitor_append(rtgui_list_t* head, rtgui_rect_t* rect);
+void rtgui_mouse_monitor_remove(rtgui_list_t* head, rtgui_rect_t* rect);
+rt_bool_t rtgui_mouse_monitor_contains_point(rtgui_list_t* head, int x, int y);
+
+#endif
diff --git a/components/rtgui_win/server/panel.c b/components/rtgui_win/server/panel.c
new file mode 100644
index 0000000000..ac549d8304
--- /dev/null
+++ b/components/rtgui_win/server/panel.c
@@ -0,0 +1,284 @@
+/*
+ * File : panel.c
+ * This file is part of RTGUI in 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-04 Bernard first version
+ */
+
+#include <panel.h>
+#include <mouse.h>
+#include <rtgui/rtgui_system.h>
+#include <rtgui/widgets/widget.h>
+#include <rtgui/rtgui_theme.h>
+
+/* the global parameter */
+rtgui_panel_t *rtgui_panel = RT_NULL;
+
+//��SVN����,����������������topwin�㶨���,
+//����ȡ����topwin��,�����������Ϊȫ�ֱ���
+rtgui_rect_t *external_clip_rect=RT_NULL;
+rt_uint32_t external_clip_size=0;
+
+static void _rtgui_panel_constructor(rtgui_panel_t *panel)
+{
+ panel->status = 0;
+ RTGUI_WIDGET_FLAG(panel) |= RTGUI_WIDGET_FLAG_FOCUSABLE;
+ panel->image = RT_NULL;
+ rtgui_widget_set_event_handler(panel, rtgui_panel_event_handler);
+ panel->modal_widget = RT_NULL;
+}
+
+static void _rtgui_panel_destructor(rtgui_panel_t *panel)
+{
+ if(external_clip_size > 0)
+ {
+ rt_free(external_clip_rect);
+ external_clip_rect = RT_NULL;
+ external_clip_size = 0;
+ }
+}
+
+rtgui_type_t *rtgui_panel_type_get(void)
+{
+ static rtgui_type_t *panel_type = RT_NULL;
+
+ if(!panel_type)
+ {
+ panel_type = rtgui_type_create("panel", RTGUI_CONTAINER_TYPE,sizeof(rtgui_panel_t),
+ RTGUI_CONSTRUCTOR(_rtgui_panel_constructor),
+ RTGUI_DESTRUCTOR(_rtgui_panel_destructor));
+ }
+
+ return panel_type;
+}
+
+rtgui_panel_t* rtgui_panel_create(int left, int top, int w, int h)
+{
+ rtgui_rect_t rect;
+ rtgui_panel_t *panel;
+ rtgui_thread_t *thread;
+
+ panel = rtgui_widget_create(RTGUI_PANEL_TYPE);
+ if(panel == RT_NULL) return RT_NULL;
+ rtgui_panel_set(panel);
+
+ thread = rtgui_thread_self();
+ panel->tid = thread->tid;
+
+ RTGUI_WIDGET(panel)->toplevel = RTGUI_WIDGET(panel);
+
+ rect.x1 = left;
+ rect.y1 = top;
+ rect.x2 = rect.x1+w;
+ rect.y2 = rect.y1+h;
+
+ rtgui_widget_set_rect(panel,&rect);
+ rtgui_widget_update_clip(panel);
+
+ rtgui_thread_set_widget(panel);
+
+ return panel;
+}
+
+void rtgui_panel_destroy(char* name)
+{
+ //Panel��Ҫ��Զפ���ڴ���
+ //......
+}
+
+void rtgui_panel_set(rtgui_panel_t *panel)
+{
+ rtgui_panel = panel;
+}
+
+rtgui_panel_t* rtgui_panel_get(void)
+{
+ return rtgui_panel;
+}
+
+void rtgui_panel_show(rtgui_panel_t *panel)
+{
+ rtgui_widget_update_clip(panel);
+ rtgui_widget_update(panel);
+}
+
+rt_bool_t rtgui_panel_ondraw(rtgui_panel_t* panel)
+{
+ rtgui_theme_draw_panel(panel);
+ return RT_TRUE;
+}
+
+rt_bool_t rtgui_panel_event_handler(PVOID wdt,rtgui_event_t *event)
+{
+ rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
+ rtgui_panel_t *panel = (rtgui_panel_t*)wdt;
+
+ RT_ASSERT((wdt != RT_NULL) && (event != RT_NULL));
+
+ switch (event->type)
+ {
+ case RTGUI_EVENT_WIN_CLOSE:
+ case RTGUI_EVENT_WIN_ACTIVATE:
+ case RTGUI_EVENT_WIN_DEACTIVATE:
+ {
+ rtgui_event_win_t* wevent = (rtgui_event_win_t*)event;
+ rtgui_win_t* win = wevent->wid;
+ if (win != RT_NULL && RTGUI_WIDGET_EVENT_HANDLE(win) != RT_NULL)
+ {
+ RTGUI_WIDGET_EVENT_CALL(win, event);
+ }
+ break;
+ }
+ case RTGUI_EVENT_WIN_MOVE:
+ {
+ rtgui_event_win_move_t* wevent = (rtgui_event_win_move_t*)event;
+ rtgui_win_t* win = wevent->wid;
+ if (win != RT_NULL && RTGUI_WIDGET_EVENT_HANDLE(win) != RT_NULL)
+ {
+ RTGUI_WIDGET_EVENT_CALL(win, event);
+ }
+ break;
+ }
+ case RTGUI_EVENT_PAINT:
+ if(widget->on_draw != RT_NULL)
+ widget->on_draw(widget, event);
+ else
+ rtgui_panel_ondraw(panel);
+ break;
+
+ case RTGUI_EVENT_MOUSE_BUTTON:
+ {
+ rtgui_event_mouse_t* emouse = (rtgui_event_mouse_t*)event;
+ rtgui_win_t* win = emouse->wid;
+
+ /* check the destination window */
+ if(win != RT_NULL && RTGUI_WIDGET_EVENT_HANDLE(win) != RT_NULL)
+ {
+ RTGUI_WIDGET_EVENT_CALL(win, event);
+ }
+ else
+ {
+ if(RTGUI_PANEL_IS_MODAL_MODE(panel))
+ {
+ /* let modal widget to handle it */
+ if(panel->modal_widget != RT_NULL && RTGUI_WIDGET_EVENT_HANDLE(panel->modal_widget) != RT_NULL)
+ {
+ RTGUI_WIDGET_EVENT_CALL(panel->modal_widget, event);
+ }
+ }
+ else
+ {
+ return rtgui_container_dispatch_mouse_event(RTGUI_CONTAINER(panel),(rtgui_event_mouse_t*)event);
+ }
+ }
+ break;
+ }
+
+ case RTGUI_EVENT_MOUSE_MOTION:
+ return rtgui_container_dispatch_mouse_event(RTGUI_CONTAINER(panel),(rtgui_event_mouse_t*)event);
+
+ case RTGUI_EVENT_KBD:
+ {
+ rtgui_event_kbd_t* kbd = (rtgui_event_kbd_t*)event;
+ rtgui_win_t* win = kbd->wid;
+
+ /* check the destination window */
+ if(win != RT_NULL && RTGUI_WIDGET_EVENT_HANDLE(win) != RT_NULL)
+ {
+ RTGUI_WIDGET_EVENT_CALL(win, event);
+ }
+ else
+ {
+ if(RTGUI_PANEL_IS_MODAL_MODE(panel))
+ {
+ /* let modal widget to handle it */
+ if(panel->modal_widget != RT_NULL && RTGUI_WIDGET_EVENT_HANDLE(panel->modal_widget) != RT_NULL)
+ {
+ RTGUI_WIDGET_EVENT_CALL(panel->modal_widget, event);
+ }
+ }
+ else if(RTGUI_CONTAINER(panel)->focused != RT_NULL)
+ {
+ if(RTGUI_CONTAINER(panel)->focused != widget)
+ {
+ RTGUI_WIDGET_EVENT_CALL(RTGUI_CONTAINER(panel)->focused, event);
+ }
+ }
+ }
+ break;
+ }
+
+ default:
+ return rtgui_container_event_handler(widget, event);
+ }
+ return RT_FALSE;
+}
+
+void rtgui_panel_event_loop(rtgui_panel_t *panel)
+{
+ rt_err_t result;
+ rtgui_thread_t* tid;
+ rtgui_event_t* event;
+
+ tid = rtgui_thread_self();
+ RT_ASSERT(tid != RT_NULL);
+
+ /* point to event buffer */
+ event = (rtgui_event_t*)tid->event_buffer;
+
+ if(RTGUI_PANEL_IS_MODAL_MODE(panel))
+ {
+ /* event loop for modal mode shown view */
+ while(RTGUI_PANEL_IS_MODAL_MODE(panel))
+ {
+ if (tid->on_idle != RT_NULL)
+ {
+ result = rtgui_thread_recv_nosuspend(event, RTGUI_EVENT_BUFFER_SIZE);
+ if (result == RT_EOK)
+ RTGUI_WIDGET_EVENT_CALL(panel, event);
+ else if (result == -RT_ETIMEOUT)
+ tid->on_idle(panel, RT_NULL);
+ }
+ else
+ {
+ result = rtgui_thread_recv(event, RTGUI_EVENT_BUFFER_SIZE);
+ if (result == RT_EOK)
+ RTGUI_WIDGET_EVENT_CALL(panel, event);
+ }
+ }
+ }
+ else
+ {
+ while(1)
+ {
+ if(tid->on_idle != RT_NULL)
+ {
+ result = rtgui_thread_recv_nosuspend(event, RTGUI_EVENT_BUFFER_SIZE);
+ if (result == RT_EOK)
+ RTGUI_WIDGET_EVENT_CALL(panel, event);
+ else if (result == -RT_ETIMEOUT)
+ tid->on_idle(panel, RT_NULL);
+ }
+ else
+ {
+ result = rtgui_thread_recv(event, RTGUI_EVENT_BUFFER_SIZE);
+
+ if (result == RT_EOK)
+ {
+ /* perform event handler */
+ RTGUI_WIDGET_EVENT_CALL(panel, event);
+ }
+ }
+ }
+ }
+}
+
+
+
diff --git a/components/rtgui_win/server/panel.h b/components/rtgui_win/server/panel.h
new file mode 100644
index 0000000000..977af42bd3
--- /dev/null
+++ b/components/rtgui_win/server/panel.h
@@ -0,0 +1,61 @@
+/*
+ * File : panel.h
+ * This file is part of RTGUI in 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-04 Bernard first version
+ */
+
+#ifndef __RT_PANEL_H__
+#define __RT_PANEL_H__
+
+#include <rtgui/rtgui.h>
+#include <rtgui/list.h>
+#include <rtgui/image.h>
+#include <rtgui/widgets/widget.h>
+#include <rtgui/widgets/container.h>
+
+#define RTGUI_PANEL_STATUS_MODAL (1ul << 0) /* panel is modal mode showing */
+
+#define RTGUI_PANEL_IS_MODAL_MODE(panel) (panel->status & RTGUI_PANEL_STATUS_MODAL)
+
+typedef struct rtgui_panel rtgui_panel_t;
+
+#define RTGUI_PANEL_TYPE (rtgui_panel_type_get())
+#define RTGUI_PANEL(obj) (RTGUI_OBJECT_CAST((obj), RTGUI_PANEL_TYPE, rtgui_panel_t))
+#define RTGUI_IS_PANEL(obj) (RTGUI_OBJECT_CHECK_TYPE((obj), RTGUI_PANEL_TYPE))
+
+struct rtgui_panel
+{
+ rtgui_container_t parent;
+ struct rt_thread* tid; //panel�߳�
+
+ PVOID modal_widget;
+ rt_uint32_t status; //panel��״̬
+ rtgui_image_t* image; //����ͼƬ
+};
+
+extern rtgui_rect_t *external_clip_rect;
+extern rt_uint32_t external_clip_size;
+
+rtgui_type_t *rtgui_panel_type_get(void);
+rtgui_panel_t* rtgui_panel_create(int left, int top, int w, int h);
+
+void rtgui_panel_set(rtgui_panel_t *panel);
+rtgui_panel_t* rtgui_panel_get(void);
+struct rt_thread* PanelGetActiveThread(void);
+void PanelSetActiveThread(struct rt_thread* tid);
+
+rt_bool_t rtgui_panel_event_handler(PVOID wdt,rtgui_event_t *event);
+void rtgui_panel_show(rtgui_panel_t *panel);
+void rtgui_panel_event_loop(rtgui_panel_t *panel);
+
+extern rtgui_panel_t *rtgui_panel;
+
+#endif
diff --git a/components/rtgui_win/server/server.c b/components/rtgui_win/server/server.c
new file mode 100644
index 0000000000..c98e51397b
--- /dev/null
+++ b/components/rtgui_win/server/server.c
@@ -0,0 +1,320 @@
+/*
+ * File : server.c
+ * This file is part of RTGUI in 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-04 Bernard first version
+ */
+
+#include <rtgui/rtgui.h>
+#include <topwin.h>
+#include <rtgui/event.h>
+#include <panel.h>
+#include <mouse.h>
+#include <rtgui/widgets/widget.h>
+#include <rtgui/widgets/window.h>
+#include <rtgui/rtgui_theme.h>
+
+static struct rt_messagequeue *rtgui_server_mq;
+
+extern rtgui_win_t* rtgui_server_focus_win;
+
+void rtgui_server_handle_update(rtgui_event_update_t* event)
+{
+ const struct rtgui_graphic_driver* gd = rtgui_graphic_driver_get_default();
+ gd->screen_update(&(event->rect));
+}
+
+void rtgui_server_handle_mouse_btn(rtgui_event_mouse_t* event)
+{
+ rtgui_win_t* win;
+ rtgui_panel_t* panel=rtgui_panel_get();
+
+ /* re-init to server thread */
+ RTGUI_EVENT_MOUSE_BUTTON_INIT(event);
+
+#ifdef RTGUI_USING_WINMOVE
+ if (rtgui_winrect_is_moved() &&
+ event->button & (RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_UP))
+ {/* �ͷ���갴����,���´���λ�� */
+ rtgui_win_t *wid;
+ rtgui_rect_t rect;
+
+ if (rtgui_winrect_moved_done(&rect, &wid) == RT_TRUE)
+ {
+ struct rtgui_event_win_move ewin;
+
+ /* move window */
+ RTGUI_EVENT_WIN_MOVE_INIT(&ewin);
+ ewin.wid = wid;
+
+ ewin.x = rect.x1;
+ ewin.y = rect.y1;
+
+ /* send to client thread */
+ rtgui_thread_send(wid->tid, &(ewin.parent), sizeof(ewin));
+
+ return;
+ }
+ }
+#endif
+
+ if(RTGUI_PANEL_IS_MODAL_MODE(panel))
+ {
+ if(panel->modal_widget != RT_NULL && RTGUI_IS_WIN(panel->modal_widget))
+ {
+ win = RTGUI_WIN(panel->modal_widget);
+
+ if(rtgui_rect_contains_point(&(RTGUI_WIDGET_EXTENT(win)), event->x, event->y) != RT_EOK)
+ {
+ win->status &= ~RTGUI_WIN_STATUS_ACTIVATE;
+ rtgui_theme_draw_win_title(win);
+ win->status |= RTGUI_WIN_STATUS_ACTIVATE;
+ rtgui_theme_draw_win_title(win);
+ win->status &= ~RTGUI_WIN_STATUS_ACTIVATE;
+ rtgui_theme_draw_win_title(win);
+ win->status |= RTGUI_WIN_STATUS_ACTIVATE;
+ rtgui_theme_draw_win_title(win);
+ return;
+ }
+ }
+ }
+ /* �Ƿ���һ�������� */
+ win = rtgui_topwin_get_wnd(event->x, event->y);
+
+ if(win != RT_NULL)
+ {
+ rtgui_rect_t rect;
+
+ event->wid = win;
+ if(rtgui_server_focus_win != win)
+ {//���ǽ��㴰��,�������
+ rt_kprintf("1.raise win.");
+ rtgui_topwin_raise(win);
+ }
+
+ rtgui_win_get_title_rect(win, &rect);
+ rtgui_widget_rect_to_device(win, &rect);
+ if(rtgui_rect_contains_point(&rect, event->x, event->y) == RT_EOK)
+ {//����ڴ��ڵı�����
+ rtgui_topwin_title_onmouse(win, event);
+ }
+ else
+ {//����ڴ��ڵĿͻ���
+ /*if(win->style & RTGUI_WIN_CLOSEBOX_PRESSED)
+ {
+ win->style &= ~RTGUI_WIN_CLOSEBOX_PRESSED;
+ rtgui_theme_draw_win_closebox(win);
+ }*/
+ /* send mouse event to thread */
+ rtgui_thread_send(win->tid, (rtgui_event_t*)event, sizeof(rtgui_event_mouse_t));
+ }
+ return;
+ }
+
+ //������Ϣ��panel
+ /* deactivate old window */
+ if (rtgui_server_focus_win != RT_NULL)
+ {
+ rtgui_topwin_deactivate(rtgui_server_focus_win);
+ }
+ rtgui_server_focus_win = RT_NULL;
+ event->wid = RT_NULL;
+ rtgui_thread_send(panel->tid,(rtgui_event_t*)event,sizeof(rtgui_event_mouse_t));
+}
+
+//static rt_bool_t motion_down=0;
+//static rt_int16_t downx,downy;
+//������ƴ������
+void rtgui_server_handle_mouse_motion(rtgui_event_mouse_t* event)
+{
+ rtgui_panel_t* panel;
+ rtgui_win_t* win=RT_NULL;
+
+ panel = rtgui_panel_get();
+
+ if(panel != RT_NULL)
+ {
+ win = rtgui_topwin_get_wnd(event->x, event->y);
+
+ if(win != RT_NULL)
+ { /* send mouse event to thread */
+ rtgui_thread_send(win->tid, (rtgui_event_t*)event, sizeof(rtgui_event_mouse_t));
+ }
+ else
+ { //������Ϣ��panel
+ rtgui_thread_send(panel->tid,(rtgui_event_t*)event,sizeof(rtgui_event_mouse_t));
+ }
+ }
+ /* move mouse to (x, y) */
+ rtgui_mouse_moveto(event->x, event->y);
+}
+
+void rtgui_server_handle_kbd(rtgui_event_kbd_t* event)
+{
+ rtgui_win_t *win;
+ rtgui_panel_t *panel;
+
+ /* re-init to server thread */
+ RTGUI_EVENT_KBD_INIT(event);
+
+ /* send to focus window or focus panel */
+ panel = rtgui_panel_get();
+
+ if(panel != RT_NULL)
+ {
+ win = rtgui_server_focus_win;
+ if(win != RT_NULL && win->status & RTGUI_WIN_STATUS_ACTIVATE)
+ {
+ event->wid = win;
+ rtgui_thread_send(win->tid, (rtgui_event_t*)event, sizeof(rtgui_event_kbd_t));
+ }
+ else
+ {//������Ϣ��panel
+ event->wid = RT_NULL;
+ rtgui_thread_send(panel->tid,(rtgui_event_t*)event,sizeof(rtgui_event_kbd_t));
+ }
+ }
+}
+
+void rtgui_server_handle_current_pos(rtgui_event_current_pos_t* event)
+{
+ struct rt_thread *thread = rtgui_panel_get()->tid;
+
+ /* re-init to server thread */
+ RTGUI_EVENT_CURRENT_POS_INIT(event);
+
+ /* send to panel */
+ if(thread != RT_NULL)
+ {//Ҫ��ͬ����ʽ�����¼�,��������������������
+ rtgui_thread_send_sync(thread, (rtgui_event_t*)event, sizeof(rtgui_event_current_pos_t));
+ }
+}
+
+/**
+ * rtgui server thread's entry
+ */
+static void rtgui_server_entry(void* parameter)
+{
+ /* create rtgui server msgq */
+ rtgui_server_mq = rt_mq_create("rtgui", 256, 8, RT_IPC_FLAG_FIFO);
+
+
+ /* register rtgui server thread */
+ rtgui_thread_register(rt_thread_self(), rtgui_server_mq);
+
+ /* init mouse and show */
+ rtgui_mouse_init();
+#ifdef RTGUI_USING_MOUSE_CURSOR
+ rtgui_mouse_show_cursor();
+#endif
+
+ while(1)
+ {
+ /* the buffer uses to receive event */
+ char event_buf[256];
+ rtgui_event_t* event = (rtgui_event_t*)&(event_buf[0]);
+
+ if(rtgui_thread_recv(event, sizeof(event_buf)) == RT_EOK)
+ {
+ /* dispatch event */
+ switch (event->type)
+ {
+ case RTGUI_EVENT_WIN_CREATE:
+ if (rtgui_topwin_add(((rtgui_event_win_t*)event)->wid) == RT_EOK)
+ rtgui_thread_ack(event, RTGUI_STATUS_OK);
+ else
+ rtgui_thread_ack(event, RTGUI_STATUS_ERROR);
+ break;
+
+ case RTGUI_EVENT_WIN_DESTROY:
+ if (rtgui_topwin_remove(((rtgui_event_win_t*)event)->wid) == RT_EOK)
+ rtgui_thread_ack(event, RTGUI_STATUS_OK);
+ else
+ rtgui_thread_ack(event, RTGUI_STATUS_ERROR);
+ break;
+
+ case RTGUI_EVENT_WIN_SHOW:
+ if (rtgui_topwin_show(((rtgui_event_win_t*)event)->wid) == RT_EOK)
+ rtgui_thread_ack(event, RTGUI_STATUS_OK);
+ else
+ rtgui_thread_ack(event, RTGUI_STATUS_ERROR);
+ break;
+
+ case RTGUI_EVENT_WIN_HIDE:
+ if (rtgui_topwin_hide(((rtgui_event_win_t*)event)->wid) == RT_EOK)
+ rtgui_thread_ack(event, RTGUI_STATUS_OK);
+ else
+ rtgui_thread_ack(event, RTGUI_STATUS_ERROR);
+ break;
+
+ case RTGUI_EVENT_WIN_MOVE:
+ if (rtgui_topwin_move(((rtgui_event_win_move_t*)event)->wid,
+ ((rtgui_event_win_move_t*)event)->x,
+ ((rtgui_event_win_move_t*)event)->y))
+ rtgui_thread_ack(event, RTGUI_STATUS_OK);
+ else
+ rtgui_thread_ack(event, RTGUI_STATUS_ERROR);
+ break;
+
+ case RTGUI_EVENT_WIN_RESIZE:
+ rtgui_topwin_resize(((rtgui_event_win_resize_t*)event)->wid,
+ &(((rtgui_event_win_resize_t*)event)->rect));
+ break;
+
+ case RTGUI_EVENT_UPDATE:
+ /* handle screen update */
+ rtgui_server_handle_update((rtgui_event_update_t*)event);
+#ifdef RTGUI_USING_MOUSE_CURSOR
+ /* show cursor */
+ rtgui_mouse_show_cursor();
+#endif
+ break;
+
+ case RTGUI_EVENT_MOUSE_MOTION:
+ rtgui_server_handle_mouse_motion((rtgui_event_mouse_t*)event);
+ break;
+
+ case RTGUI_EVENT_MOUSE_BUTTON:
+ rtgui_server_handle_mouse_btn((rtgui_event_mouse_t*)event);
+ break;
+
+ case RTGUI_EVENT_KBD:
+ rtgui_server_handle_kbd((rtgui_event_kbd_t*)event);
+ break;
+
+ case RTGUI_EVENT_CURRENT_POS:
+ rtgui_server_handle_current_pos((rtgui_event_current_pos_t*)event);
+ break;
+
+ case RTGUI_EVENT_COMMAND:
+ break;
+ }
+ }
+ }
+}
+
+void rtgui_server_post_event(rtgui_event_t* event, rt_size_t size)
+{
+ rt_mq_send(rtgui_server_mq, event, size);
+}
+
+void rtgui_server_init(void)
+{
+ struct rt_thread* rtgui_server_tid;
+ rtgui_server_tid = rt_thread_create("rtgui",
+ rtgui_server_entry, RT_NULL,
+ RTGUI_SVR_THREAD_STACK_SIZE,
+ RTGUI_SVR_THREAD_PRIORITY,
+ RTGUI_SVR_THREAD_TIMESLICE);
+
+ /* start rtgui server thread */
+ if(rtgui_server_tid != RT_NULL)
+ rt_thread_startup(rtgui_server_tid);
+}
diff --git a/components/rtgui_win/server/topwin.c b/components/rtgui_win/server/topwin.c
new file mode 100644
index 0000000000..ecc91a3b6c
--- /dev/null
+++ b/components/rtgui_win/server/topwin.c
@@ -0,0 +1,660 @@
+/*
+ * File : win_server.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 "panel.h"
+#include "topwin.h"
+#include "mouse.h"
+#include <rtgui/rtgui_system.h>
+
+#include <rtgui/event.h>
+#include <rtgui/image.h>
+#include <rtgui/rtgui_theme.h>
+#include <rtgui/rtgui_system.h>
+#include <rtgui/widgets/window.h>
+
+rtgui_win_t* rtgui_server_focus_win = RT_NULL;
+
+static rtgui_list_t _rtgui_win_show_list;
+static rtgui_list_t _rtgui_win_hide_list;
+
+void rtgui_panel_redraw(rtgui_rect_t* rect);
+
+void rtgui_win_init(void)
+{
+ //��ʼ�������б�
+ rtgui_list_init(&_rtgui_win_show_list);
+ rtgui_list_init(&_rtgui_win_hide_list);
+}
+
+static rt_bool_t rtgui_win_search_in_list(rtgui_win_t* win, rtgui_list_t *list)
+{
+ rtgui_list_t *node;
+ rtgui_win_t* wid;
+
+ /* search in list */
+ rtgui_list_foreach(node, list)
+ {
+ wid = rtgui_list_entry(node, rtgui_win_t, list);
+ if(wid == win) return RT_TRUE;
+ }
+
+ return RT_FALSE;
+}
+
+//����һ�����ڵ����ش����б�(Ĭ���½��Ĵ��ڴ�������״̬)
+rt_err_t rtgui_topwin_add(rtgui_win_t* win)
+{
+ if(win != RT_NULL)
+ {
+ /* update clip info */
+ rtgui_widget_update_clip(win);
+ list_insert(&(_rtgui_win_hide_list), &(win->list));
+ return RT_EOK;
+ }
+ return RT_ERROR;
+}
+
+/* �Ƴ�һ������ */
+rt_err_t rtgui_topwin_remove(rtgui_win_t* win)
+{
+ RT_ASSERT(win != RT_NULL);
+
+ if(rtgui_win_search_in_list(win,&_rtgui_win_show_list))
+ { /* in show list */
+ rtgui_list_t *node;
+ rtgui_win_t *wid;
+ rtgui_rect_t rect = RTGUI_WIDGET_EXTENT(win);
+ int front_num=0;//����Z���ڵ�ǰ����֮�ϵĴ�������
+
+ /* remove node from list */
+ rtgui_list_remove(&_rtgui_win_show_list, &(win->list));
+
+ rtgui_update_external_clip_info();
+
+ rtgui_list_foreach(node, &_rtgui_win_show_list)
+ {
+ wid = rtgui_list_entry(node, rtgui_win_t, list);
+ /* ����"����ʾ"��������"��ɾ���Ĵ���"�ص������� */
+ rtgui_toplevel_update_clip(wid, &rect, front_num);
+ rtgui_win_ondraw(wid);
+ front_num++;
+ }
+
+ /* ������һ������ */
+ if(_rtgui_win_show_list.next != RT_NULL)
+ {
+ rtgui_win_t* wnd = rtgui_list_entry(_rtgui_win_show_list.next,rtgui_win_t, list);
+
+ rtgui_topwin_raise(wnd);
+ rtgui_server_focus_win = wnd;
+ }
+ else
+ {
+ /* û�п�����ʾ�Ĵ��� */
+ rtgui_server_focus_win = RT_NULL;
+ }
+
+ rtgui_panel_redraw(&rect);
+
+ return RT_EOK;
+ }
+ else if(rtgui_win_search_in_list(win, &_rtgui_win_hide_list))
+ {//��"����"���
+ /* remove node from list */
+ rtgui_list_remove(&_rtgui_win_hide_list, &(win->list));
+ return RT_EOK;
+ }
+
+ return RT_ERROR;
+}
+
+/* activate a win
+ */
+rt_err_t rtgui_topwin_activate(rtgui_win_t* win)
+{
+ if((rtgui_server_focus_win != RT_NULL) && (rtgui_server_focus_win != win))
+ {
+ rtgui_topwin_deactivate(rtgui_server_focus_win);
+ }
+
+ win->status |= RTGUI_WIN_STATUS_ACTIVATE;
+ rtgui_server_focus_win = win;
+
+ rtgui_widget_update_clip(win);
+
+ rtgui_widget_focus(win);
+ rtgui_widget_update(win);
+
+ return RT_EOK;
+}
+
+/*
+ * deactivate a win
+ */
+rt_err_t rtgui_topwin_deactivate(rtgui_win_t* win)
+{
+ win->status &= ~RTGUI_WIN_STATUS_ACTIVATE;
+
+ /* �ô�����֮ǰӦ���ǻ��,���п���ֱ�ӻ�ͼ */
+ rtgui_theme_draw_win_title(win);
+
+ if(rtgui_server_focus_win == win)
+ {
+ rtgui_server_focus_win = RT_NULL;
+ }
+
+ return RT_EOK;
+}
+
+/* raise window to front ��ָ����������Ϊ��ǰ���� */
+rt_err_t rtgui_topwin_raise(rtgui_win_t* win)
+{
+ RT_ASSERT(win != RT_NULL);
+
+ /* find the twin node */
+ if(rtgui_win_search_in_list(win, &_rtgui_win_show_list))
+ {//��������ʾ�б���
+ rtgui_list_t *node;
+ rtgui_win_t *wid;
+ rtgui_rect_t rect = RTGUI_WIDGET_EXTENT(win);
+ int front_num = 0;
+
+ /* the window is already placed in front */
+ if(&(win->list) == _rtgui_win_show_list.next)
+ {/* �ô����Ѿ�����ǰ�� */
+ rtgui_server_focus_win = RT_NULL;
+ rtgui_topwin_activate(win);
+ return RT_EOK;
+ }
+
+ if(rtgui_server_focus_win != RT_NULL && rtgui_server_focus_win != win)
+ {/* �ɴ�����Ϊ�ǻ״̬ */
+ rtgui_topwin_deactivate(rtgui_server_focus_win);
+ }
+
+ rtgui_list_foreach(node, &_rtgui_win_show_list)
+ {/* ���¸����ڵļ����� */
+ wid = rtgui_list_entry(node, rtgui_win_t, list);
+ //����"���뷨"����,��ǰ���ڲ��ᱻ�κδ��ڸ���
+ if(wid == win)
+ {
+ front_num++;
+ continue;
+ }
+ //������������Ҫ���е���ǰ����
+ rtgui_toplevel_update_clip(wid, &rect, front_num);
+ rtgui_win_ondraw(wid); //����ط����������ͼЧ�������
+ front_num++;
+ }
+
+ /* remove node from list */
+ rtgui_list_remove(&_rtgui_win_show_list, &(win->list));
+ /* add to front */
+ list_insert(&_rtgui_win_show_list, &(win->list));
+
+ //�´�����Ϊ�״̬
+ rtgui_topwin_activate(win);
+
+ return RT_EOK;
+ }
+
+ return RT_ERROR;
+}
+
+/* show a window */
+rt_err_t rtgui_topwin_show(rtgui_win_t* win)
+{
+ rtgui_panel_t *panel = rtgui_panel_get();
+
+ /* find it */
+ if(win != RT_NULL)
+ {
+ if(rtgui_win_search_in_list(win, &_rtgui_win_hide_list))
+ {//���������
+ /* remove node from hidden list */
+ rtgui_list_remove(&_rtgui_win_hide_list, &(win->list));
+
+ /* add node to show list */
+ list_insert(&_rtgui_win_show_list, &(win->list));
+ rtgui_update_external_clip_info();
+ rtgui_panel_update_clip(panel);
+
+ RTGUI_WIDGET_UNHIDE(win);
+
+ /* activate this window */
+ rtgui_topwin_activate(win);
+ }
+ else if(rtgui_win_search_in_list(win, &_rtgui_win_show_list))
+ {//����ʾ�б���
+ /* just raise it */
+ rtgui_topwin_raise(win);
+ }
+
+ return RT_EOK;
+ }
+
+ return RT_ERROR;
+}
+
+/* hide a window */
+rt_err_t rtgui_topwin_hide(rtgui_win_t* win)
+{
+ rtgui_panel_t *panel = rtgui_panel_get();
+
+ /* found it */
+ if(win != RT_NULL)
+ {
+ /* remove node from show list */
+ rtgui_list_remove(&_rtgui_win_show_list, &(win->list));
+ rtgui_update_external_clip_info();
+ rtgui_panel_update_clip(panel);
+ /* add node to hidden list */
+ list_insert(&_rtgui_win_hide_list, &(win->list));
+
+ /* redraw the old rect */
+ rtgui_panel_redraw(&(RTGUI_WIDGET_EXTENT(win)));
+
+ if(rtgui_server_focus_win == win)
+ {
+ /* activate the next window */
+ if(_rtgui_win_show_list.next != RT_NULL)
+ {
+ /* get the win */
+ win = rtgui_list_entry(_rtgui_win_show_list.next,rtgui_win_t, list);
+ rtgui_server_focus_win = RT_NULL;
+ rtgui_topwin_activate(win);
+ }
+ else
+ {
+ /* there is no shown window right now */
+ rtgui_server_focus_win = RT_NULL;
+ }
+ }
+
+ return RT_EOK;
+ }
+
+ return RT_ERROR;
+}
+
+/* move top window */
+rt_err_t rtgui_topwin_move(rtgui_win_t* win, int x, int y)
+{
+ rtgui_panel_t *panel = rtgui_panel_get();
+
+ if(win != RT_NULL)
+ {
+ int dx, dy;
+ rtgui_list_t *node;
+ rtgui_win_t *wid;
+ rtgui_rect_t rect = RTGUI_WIDGET_EXTENT(win);
+ int front_num = 0;
+
+ /* get the delta move x, y */
+ dx = x - RTGUI_WIDGET(win)->extent.x1;
+ dy = y - RTGUI_WIDGET(win)->extent.y1;
+
+ /* move window rect */
+ rtgui_widget_move_to_logic(RTGUI_WIDGET(win), dx, dy);
+
+ /* �����ƶ���,��Ҫ����external��Ϣ */
+ rtgui_update_external_clip_info();
+
+ rtgui_list_foreach(node, &_rtgui_win_show_list)
+ {/* ���¸����ڵļ����� */
+ wid = rtgui_list_entry(node, rtgui_win_t, list);
+ if(wid == win)
+ {
+ front_num++;
+ continue;
+ }
+ rtgui_toplevel_update_clip(wid, &rect, front_num);
+ rtgui_win_ondraw(wid);
+ front_num++;
+ }
+
+ /* ��ǰ�����ǻ��,ֱ�Ӹ�������clip */
+ rtgui_widget_update_clip(win);
+ rtgui_widget_update(win);
+
+ /* update old window coverage area */
+ rtgui_panel_redraw(&rect);
+
+ rtgui_topwin_activate(win);
+ return RT_EOK;
+ }
+
+ return RT_ERROR;
+}
+
+/*
+ * resize a top win
+ * Note: currently, only support resize hidden window
+ */
+rt_err_t rtgui_topwin_resize(rtgui_win_t* win, rtgui_rect_t* r)
+{
+ if(win != RT_NULL)
+ {
+ RTGUI_WIDGET_EXTENT(win) = *r;
+
+ /* update title & border clip info */
+ rtgui_widget_update_clip(win);
+
+ return RT_EOK;
+ }
+
+ return RT_ERROR;
+}
+
+rtgui_win_t* rtgui_topwin_get_wnd(int x, int y)
+{
+ rtgui_list_t* node;
+ rtgui_win_t* win;
+
+ /* search in show win list */
+ if(_rtgui_win_show_list.next != RT_NULL)
+ {
+ rtgui_list_foreach(node, &(_rtgui_win_show_list))
+ {
+ win = rtgui_list_entry(node, rtgui_win_t, list);
+
+ /* is this window? */
+ if(rtgui_rect_contains_point(&(RTGUI_WIDGET_EXTENT(win)), x, y) == RT_EOK)
+ {
+ return win;
+ }
+ }
+ }
+ return RT_NULL;
+}
+
+//front_num: ��Ҫ���е���topwin����,ֻ����Z�����Լ�֮�ϵ�
+void rtgui_toplevel_update_clip(PVOID wdt, rtgui_rect_t *rect, int front_num)
+{
+ rtgui_widget_t *widget = (rtgui_widget_t*)wdt;
+ rtgui_widget_t *child;
+ rtgui_list_t *node;
+ rtgui_rect_t new_rect;
+
+ new_rect = widget->extent;
+
+ if(rtgui_rect_is_intersect(rect, &new_rect) == RT_EOK)
+ {//���������ཻ
+ rtgui_rect_intersect(rect, &new_rect);//�����ص�������
+ rtgui_region_reset(&(widget->clip), &new_rect);//���ص�������Ϊ������
+
+ if(front_num > 0)
+ {
+ rt_int32_t i;
+ rtgui_rect_t *ext_rect;
+
+ ext_rect = external_clip_rect;
+ for(i=0;i<front_num;i++)
+ {
+ rtgui_region_subtract_rect(&(widget->clip), &(widget->clip),ext_rect);
+ ext_rect++;
+ }
+ }
+ }
+ else
+ {
+ rtgui_region_reset(&(widget->clip), &rtgui_empty_rect);
+ }
+
+ {/* ���ؼ�clip�޶�����Ļ֮�� */
+ rtgui_rect_t screen_rect;
+ rtgui_graphic_driver_get_rect(rtgui_graphic_driver_get_default(),&screen_rect);
+ rtgui_region_intersect_rect(&(widget->clip), &(widget->clip), &screen_rect);
+ }
+
+ if(RTGUI_IS_CONTAINER(widget))
+ {/* �������ؼ�,�����rect��Χ�ڵ��ӿؼ� */
+ rtgui_list_foreach(node, &(RTGUI_CONTAINER(widget)->children))
+ {
+ child = rtgui_list_entry(node, rtgui_widget_t, sibling);
+ if(RTGUI_WIDGET_IS_HIDE(child))continue;
+ /* ��λ�ӿؼ�Clip */
+ rtgui_region_subtract_rect(&(widget->clip), &(widget->clip),&(child->extent));
+ rtgui_toplevel_update_clip(child, rect, front_num);
+ }
+ }
+}
+
+void rtgui_panel_redraw(rtgui_rect_t* rect)
+{
+ rtgui_panel_t *panel = rtgui_panel_get();
+
+ rtgui_toplevel_update_clip(panel,rect,external_clip_size);
+ rtgui_theme_draw_panel(panel);
+ /* reset panel clip */
+ rtgui_update_external_clip_info();
+ rtgui_panel_update_clip(panel);
+}
+
+void rtgui_topwin_title_onmouse(rtgui_win_t* win, rtgui_event_mouse_t* event)
+{
+ rtgui_rect_t rect;
+
+ if(event->button & RTGUI_MOUSE_BUTTON_LEFT)
+ {
+ if(event->button & RTGUI_MOUSE_BUTTON_DOWN)
+ {//��갴������
+ if(win->style & RTGUI_WIN_CLOSEBOX)
+ {//�ر�
+ rtgui_win_get_closebox_rect(win, &rect);
+ rtgui_widget_rect_to_device(win, &rect);
+ if(rtgui_rect_contains_point(&rect, event->x, event->y) == RT_EOK)
+ {
+ win->style |= RTGUI_WIN_CLOSEBOX_PRESSED;
+ rtgui_theme_draw_win_closebox(win);
+ return;
+ }
+ }
+ if(win->style & RTGUI_WIN_MAXBOX)
+ {//���
+ rtgui_win_get_maxbox_rect(win, &rect);
+ rtgui_widget_rect_to_device(win, &rect);
+ if(rtgui_rect_contains_point(&rect, event->x, event->y) == RT_EOK)
+ {
+ win->style |= RTGUI_WIN_MAXBOX_PRESSED;
+ rtgui_theme_draw_win_maxbox(win);
+ return;
+ }
+ }
+ if(win->style & RTGUI_WIN_MINBOX)
+ {//����
+ rtgui_win_get_minbox_rect(win, &rect);
+ rtgui_widget_rect_to_device(win, &rect);
+ if(rtgui_rect_contains_point(&rect, event->x, event->y) == RT_EOK)
+ {
+ win->style |= RTGUI_WIN_MINBOX_PRESSED;
+ rtgui_theme_draw_win_minbox(win);
+ return;
+ }
+ }
+#ifdef RTGUI_USING_WINMOVE
+ /* maybe move window */
+ rtgui_cursor_set_location(event->x, event->y);
+ rtgui_winrect_set(win);
+#endif
+ }
+ else if(event->button & RTGUI_MOUSE_BUTTON_UP)
+ {//���鰴������
+ if(win->style & RTGUI_WIN_CLOSEBOX)
+ {//�ر�
+ rtgui_win_get_closebox_rect(win, &rect);
+ rtgui_widget_rect_to_device(win, &rect);
+ if(rtgui_rect_contains_point(&rect, event->x, event->y) == RT_EOK)
+ {
+ rtgui_event_win_t event;
+
+ win->style &= ~RTGUI_WIN_CLOSEBOX_PRESSED;
+ rtgui_theme_draw_win_closebox(win);
+
+ /* ����"�رմ���"�¼� */
+ RTGUI_EVENT_WIN_CLOSE_INIT(&event);
+ event.wid = win;
+
+ rtgui_thread_send(win->tid, RTGUI_EVENT(&event), sizeof(rtgui_event_win_t));
+
+ return;
+ }
+ }
+ if(win->style & RTGUI_WIN_MAXBOX)
+ {//���
+ rtgui_win_get_maxbox_rect(win, &rect);
+ rtgui_widget_rect_to_device(win, &rect);
+ if(rtgui_rect_contains_point(&rect, event->x, event->y) == RT_EOK)
+ {
+ rtgui_event_win_t ewin;
+
+ win->style &= ~RTGUI_WIN_MAXBOX_PRESSED;
+ rtgui_theme_draw_win_maxbox(win);
+
+ /* send close event to window */
+ RTGUI_EVENT_WIN_MAX_INIT(&ewin);
+ ewin.wid = win;
+ rtgui_thread_send(win->tid, &(ewin.parent), sizeof(rtgui_event_win_t));
+ return;
+ }
+ }
+ if(win->style & RTGUI_WIN_MINBOX)
+ {//����
+ rtgui_win_get_minbox_rect(win, &rect);
+ rtgui_widget_rect_to_device(win, &rect);
+ if(rtgui_rect_contains_point(&rect, event->x, event->y) == RT_EOK)
+ {
+ rtgui_event_win_t ewin;
+
+ win->style &= ~RTGUI_WIN_MINBOX_PRESSED;
+ rtgui_theme_draw_win_minbox(win);
+
+ /* send close event to window */
+ RTGUI_EVENT_WIN_MIN_INIT(&ewin);
+ ewin.wid = win;
+ rtgui_thread_send(win->tid, &(ewin.parent), sizeof(rtgui_event_win_t));
+ return;
+ }
+ }
+ }
+ }
+}
+
+void rtgui_panel_update_clip(PVOID wdt)
+{
+ rtgui_list_t *node;
+ rtgui_widget_t *child=RT_NULL, *widget;
+
+ widget = (rtgui_widget_t*)wdt;
+
+ rtgui_region_reset(&(widget->clip), &(widget->extent));
+ //�ü�panel Clip
+
+ if(external_clip_size > 0)
+ {
+ rt_int32_t i;
+ rtgui_rect_t *rect;
+ rect = external_clip_rect;
+ for(i=0;i<external_clip_size;i++)
+ {
+ rtgui_region_subtract_rect(&(widget->clip), &(widget->clip),rect);
+ rect++;
+ }
+ }
+
+ if(RTGUI_IS_CONTAINER(widget))
+ {//���ȸ�λpanel�µ��ӿؼ�Clip
+ rtgui_list_foreach(node, &(RTGUI_CONTAINER(widget)->children))
+ {
+ child = rtgui_list_entry(node, rtgui_widget_t, sibling);
+ if(RTGUI_WIDGET_IS_HIDE(child))continue;
+ //if(RTGUI_IS_WIN(child))continue; //���ڲ������ﴦ��
+ //��λ�ӿؼ�Clip
+ rtgui_region_subtract_rect(&(widget->clip), &(widget->clip),&(child->extent));
+ rtgui_panel_update_clip(child);
+ }
+ }
+}
+
+//����Panel Clipʱʹ��
+void rtgui_update_external_clip_info(void)
+{
+ rtgui_rect_t *rect;
+ rtgui_win_t *win;
+ rtgui_list_t *node;
+ rt_uint32_t count=0;
+ rtgui_panel_t *panel=rtgui_panel_get();
+
+ RT_ASSERT(panel != RT_NULL);
+
+ if(external_clip_size > 0)
+ {//���ԭ������
+ rt_free(external_clip_rect);
+ external_clip_rect = RT_NULL;
+ external_clip_size = 0;
+ }
+
+ rtgui_list_foreach(node, &_rtgui_win_show_list)
+ {//���㴰�ڸ���
+ count ++;
+ }
+
+ external_clip_rect = (rtgui_rect_t*)rt_malloc(sizeof(rtgui_rect_t)*count);
+ external_clip_size = count;
+
+ //rt_kprintf("external_clip_size=%d\n",external_clip_size);
+
+ rect = external_clip_rect;
+
+ rtgui_list_foreach(node, &_rtgui_win_show_list)
+ {
+ win = rtgui_list_entry(node, rtgui_win_t, list);
+ *rect = RTGUI_WIDGET_EXTENT(win);
+ rect ++;
+ }
+}
+
+#ifdef RT_USING_FINSH
+#include <finsh.h>
+//��ӡ�����б�
+rt_bool_t list_win(void)
+{
+ rtgui_list_t *node;
+ rtgui_win_t* win;
+
+ rt_kprintf("window'name thread'name modal window'id\n");
+ rt_kprintf("---------------- ---------------- ---------------- ----------\n");
+ /* search in list */
+ rtgui_list_foreach(node, &_rtgui_win_show_list)
+ {
+ win = rtgui_list_entry(node, rtgui_win_t, list);
+
+ if(win != RT_NULL)
+ {
+ rt_kprintf("%-16s %-16s %-16s 0x%08X\n",
+ win->title,win->tid->name,
+ ((RTGUI_WIN_IS_MODAL_MODE(win))?"MODAL_OK":"MODAL_CANCEL"),
+ win);
+ }
+ }
+ if(rtgui_server_focus_win != RT_NULL)
+ {
+ win = rtgui_server_focus_win;
+ rt_kprintf("activate win=%-s,ID=0x%08X, st=%08X\n",
+ win->title,win,win->status);
+ }
+
+ return RT_TRUE;
+}
+FINSH_FUNCTION_EXPORT(list_win, list show window);
+#endif
diff --git a/components/rtgui_win/server/topwin.h b/components/rtgui_win/server/topwin.h
new file mode 100644
index 0000000000..ad911a4d1e
--- /dev/null
+++ b/components/rtgui_win/server/topwin.h
@@ -0,0 +1,43 @@
+/*
+ * File : win_server.h
+ * 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
+ */
+#ifndef __RTGUI_TOPWIN_H__
+#define __RTGUI_TOPWIN_H__
+
+#include <rtgui/rtgui.h>
+#include <rtgui/event.h>
+#include <rtgui/rtgui_server.h>
+
+
+rt_err_t rtgui_topwin_add(rtgui_win_t* win); /* add a top win */
+rt_err_t rtgui_topwin_remove(rtgui_win_t* win); /* remove a top win */
+rt_err_t rtgui_topwin_raise(rtgui_win_t* win); /* raise window to front */
+rt_err_t rtgui_topwin_show(rtgui_win_t* win); /* show a window */
+rt_err_t rtgui_topwin_hide(rtgui_win_t* win); /* hide a window */
+rt_err_t rtgui_topwin_move(rtgui_win_t* win, int x, int y); /* move a window */
+rt_err_t rtgui_topwin_resize(rtgui_win_t* wid, rtgui_rect_t* r); /* resize a window */
+
+rtgui_win_t* rtgui_topwin_get_wnd(int x, int y); /* get window at (x, y) */
+
+rt_err_t rtgui_topwin_activate(rtgui_win_t* win);
+rt_err_t rtgui_topwin_deactivate(rtgui_win_t* win);
+
+void rtgui_toplevel_update_clip(PVOID wdt, rtgui_rect_t *rect, int front_num);
+void rtgui_panel_update_clip(PVOID wdt);
+void rtgui_panel_redraw(rtgui_rect_t* rect);
+/* window title */
+void rtgui_topwin_title_onmouse(rtgui_win_t* win, rtgui_event_mouse_t* event);
+void rtgui_update_external_clip_info(void);
+
+#endif
+