瀏覽代碼

update according 0.3.1 series and add XML parser.

git-svn-id: https://rt-thread.googlecode.com/svn/trunk@699 bbd45198-f89e-11dd-88c7-29a3b14d5316
bernard.xiong 15 年之前
父節點
當前提交
e7fb7e6c14

+ 8 - 7
components/rtgui/SConscript

@@ -4,25 +4,26 @@ Import('RTT_ROOT')
 Import('projects')
 
 common_src = Split("""
+common/color.c
+common/region.c
 common/rtgui_object.c
 common/rtgui_system.c
 common/rtgui_theme.c
-common/asc12font.c
-common/asc16font.c
-common/color.c
+common/rtgui_xml.c
 common/dc.c
 common/dc_buffer.c
 common/dc_hw.c
-common/font.c
-common/font_hz_file.c
 common/filerw.c
 common/image.c
 common/image_xpm.c
 common/image_hdc.c
-common/region.c
+common/font.c
+common/font_hz_file.c
+common/font_hz_bmp.c
+common/asc12font.c
+common/asc16font.c
 common/hz12font.c
 common/hz16font.c
-common/font_hz_bmp.c
 """)
 
 server_src = Split("""

+ 7 - 10
components/rtgui/common/dc_buffer.c

@@ -29,7 +29,6 @@ struct rtgui_dc_buffer
 	rt_uint16_t pitch;
 
 	/* blit info */
-	rt_uint32_t clip_sync;
 	rtgui_region_t clip;
 
 	/* pixel data */
@@ -87,7 +86,6 @@ struct rtgui_dc* rtgui_dc_buffer_create(int w, int h)
 	dc->height	= h;
 	dc->pitch	= w * sizeof(rtgui_color_t);
 
-	dc->clip_sync = 0;
 	rtgui_region_init(&(dc->clip));
 
 	dc->pixel = rtgui_malloc(h * dc->pitch);
@@ -260,7 +258,7 @@ static void rtgui_dc_buffer_blit(struct rtgui_dc* self, struct rtgui_point* dc_p
 
 	if (dest->type == RTGUI_DC_HW)
 	{
-		rtgui_color_t* pixel;
+		rtgui_color_t* pixel;
 		rt_uint8_t *line_ptr;
 		rt_uint16_t rect_width, rect_height, index;
 		void (*blit_line)(rtgui_color_t* color, rt_uint8_t* dest, int line);
@@ -282,7 +280,6 @@ static void rtgui_dc_buffer_blit(struct rtgui_dc* self, struct rtgui_point* dc_p
 		case 1:
 			blit_line = rtgui_blit_line_1;
 			break;
-
 		case 2:
 			blit_line = rtgui_blit_line_2;
 			break;
@@ -300,17 +297,17 @@ static void rtgui_dc_buffer_blit(struct rtgui_dc* self, struct rtgui_point* dc_p
 		line_ptr = (rt_uint8_t*) rtgui_malloc(rect_width * hw->device->byte_per_pixel);
 
 		/* prepare pixel line */
-		pixel = (rtgui_color_t*)(dc->pixel + dc_point->y * dc->pitch + dc_point->x * sizeof(rtgui_color_t));
+		pixel = (rtgui_color_t*)(dc->pixel + dc_point->y * dc->pitch + dc_point->x * sizeof(rtgui_color_t));
 
 		/* draw each line */
 		for (index = rect->y1; index < rect->y1 + rect_height; index ++)
 		{
 			/* blit on line buffer */
-			blit_line(pixel, line_ptr, rect_width);
-			pixel += dc->width;
-
-			/* draw on hardware dc */
-			rtgui_dc_hw_draw_raw_hline(hw, line_ptr, rect->x1, rect->x1 + rect_width, index);
+			blit_line(pixel, line_ptr, rect_width);
+			pixel += dc->width;
+
+			/* draw on hardware dc */
+			rtgui_dc_hw_draw_raw_hline(hw, line_ptr, rect->x1, rect->x1 + rect_width, index);
 		}
 
 		/* release line buffer */

+ 296 - 0
components/rtgui/common/rtgui_xml.c

@@ -0,0 +1,296 @@
+#include <rtgui/rtgui_xml.h>
+
+/* Internal states that the parser can be in at any given time. */
+enum {
+	STAT_START = 0,         /* starting base state, default state */
+	STAT_TEXT,              /* text state */
+	STAT_START_TAG,         /* start tag state */
+	STAT_START_TAGNAME,     /* start tagname state */
+	STAT_START_TAGNAME_END, /* start tagname ending state */
+	STAT_END_TAG,           /* end tag state */
+	STAT_END_TAGNAME,       /* end tag tagname state */
+	STAT_END_TAGNAME_END,   /* end tag tagname ending */
+	STAT_EMPTY_TAG,         /* empty tag state */
+	STAT_SPACE,             /* linear whitespace state */
+	STAT_ATTR_NAME,         /* attribute name state */
+	STAT_ATTR_NAME_END,     /* attribute name ending state */
+	STAT_ATTR_VAL,          /* attribute value starting state */
+	STAT_ATTR_VAL2,         /* attribute value state */
+	STAT_ERROR              /* error state */
+};
+
+/* character classes that we will match against; This could be expanded if
+   need be, however, we are aiming for simple. */
+enum {
+	CLASS_TYPE_NONE = 0,       /* matches nothing, a base state */
+	CLASS_TYPE_LEFT_ANGLE,     /* matches start tag '<' */
+	CLASS_TYPE_SLASH,          /* matches forward slash */
+	CLASS_TYPE_RIGHT_ANGLE,    /* matches end tag '>' */
+	CLASS_TYPE_EQUALS,         /* matches equals sign */
+	CLASS_TYPE_QUOTE,          /* matches double-quotes */
+	CLASS_TYPE_LETTERS,        /* matches a-zA-Z letters and digits 0-9 */
+	CLASS_TYPE_SPACE,          /* matches whitespace */
+	CLASS_TYPE_ANY             /* matches any ASCII character; will match all
+								above classes */
+};
+
+/* xml state transition table */
+struct rtgui_xml_state
+{
+	rt_uint8_t state;
+	rt_uint8_t class_type;
+	rt_uint8_t next_state;
+	rt_uint8_t event;
+};
+
+/* Note: States must be grouped in match order AND grouped together! */
+static const struct rtgui_xml_state RTGUI_XML_STATES [] = {
+   /* [0-2] starting state, which also serves as the default state in case
+	  of error */
+   { STAT_START,         CLASS_TYPE_SPACE,        STAT_SPACE,             EVENT_NONE },
+   { STAT_START,         CLASS_TYPE_LEFT_ANGLE,   STAT_START_TAG,         EVENT_NONE },
+   { STAT_START,         CLASS_TYPE_ANY,          STAT_TEXT,              EVENT_COPY },
+
+   /* [3-5] space state handles linear white space */
+   { STAT_SPACE,         CLASS_TYPE_SPACE,        STAT_SPACE,             EVENT_NONE },
+   { STAT_SPACE,         CLASS_TYPE_LEFT_ANGLE,   STAT_START_TAG,         EVENT_TEXT },
+   { STAT_SPACE,         CLASS_TYPE_ANY,          STAT_TEXT,              EVENT_COPY },
+
+   /* [6-8] handle start tag */
+   { STAT_START_TAG,     CLASS_TYPE_LETTERS,      STAT_START_TAGNAME,     EVENT_COPY },
+   { STAT_START_TAG,     CLASS_TYPE_SLASH,        STAT_END_TAG,           EVENT_COPY },
+   /* below added since some individuals get a little carried away with
+	  spacing around tag names, e.g. < tag > */
+   { STAT_START_TAG,     CLASS_TYPE_SPACE,        STAT_START_TAG,         EVENT_NONE },
+
+   /* [9-12] handle start tag name */
+   { STAT_START_TAGNAME, CLASS_TYPE_LETTERS,      STAT_START_TAGNAME,     EVENT_NONE },
+   { STAT_START_TAGNAME, CLASS_TYPE_SPACE,        STAT_START_TAGNAME_END, EVENT_START },
+   /* below added for tags without any space between tag and ending
+	  slash, e.g., <br/> */
+   { STAT_START_TAGNAME, CLASS_TYPE_SLASH,        STAT_EMPTY_TAG,         EVENT_END },
+   { STAT_START_TAGNAME, CLASS_TYPE_RIGHT_ANGLE,  STAT_START,             EVENT_START },
+
+   /* [13-16] handle start tag name end */
+   { STAT_START_TAGNAME_END,  CLASS_TYPE_LETTERS, STAT_ATTR_NAME,         EVENT_COPY },
+   /* below added to handle additional space in between attribute value
+	  pairs in start tags, e.g., <tag attr="2" attr2="test" > */
+   { STAT_START_TAGNAME_END,  CLASS_TYPE_SPACE,   STAT_START_TAGNAME_END, EVENT_NONE },
+   { STAT_START_TAGNAME_END,  CLASS_TYPE_RIGHT_ANGLE, STAT_START,         EVENT_START },
+   /* below supports tags that are self-closing, e.g., <br /> */
+   { STAT_START_TAGNAME_END,  CLASS_TYPE_SLASH,   STAT_EMPTY_TAG,         EVENT_COPY },
+
+   /* [17] handle empty tags, e.g., <br /> */
+   { STAT_EMPTY_TAG,     CLASS_TYPE_RIGHT_ANGLE,  STAT_START,             EVENT_END },
+
+   /* [18] handle end tag, e.g., <tag /> */
+   { STAT_END_TAG,       CLASS_TYPE_LETTERS,      STAT_END_TAGNAME,       EVENT_NONE },
+
+   /* [19-21] handle end tag name */
+   { STAT_END_TAGNAME,   CLASS_TYPE_LETTERS,      STAT_END_TAGNAME,       EVENT_NONE },
+   { STAT_END_TAGNAME,   CLASS_TYPE_RIGHT_ANGLE,  STAT_START,             EVENT_END },
+   /* below adds support for spaces at the end of an end tag (before
+	  closing bracket) */
+   { STAT_END_TAGNAME,   CLASS_TYPE_SPACE,        STAT_END_TAGNAME_END,   EVENT_END },
+
+   /* [22] handle ending of end tag name */
+   { STAT_END_TAGNAME_END, CLASS_TYPE_SPACE,      STAT_END_TAGNAME_END,   EVENT_NONE },
+   { STAT_END_TAGNAME_END, CLASS_TYPE_RIGHT_ANGLE,STAT_START,             EVENT_NONE },
+
+   /* [23-25] handle text */
+   { STAT_TEXT,          CLASS_TYPE_SPACE,        STAT_SPACE,             EVENT_NONE },
+   { STAT_TEXT,          CLASS_TYPE_LEFT_ANGLE,   STAT_START_TAG,         EVENT_TEXT },
+   { STAT_TEXT,          CLASS_TYPE_ANY,          STAT_TEXT,              EVENT_NONE },
+
+   /* [26-30] handle attribute names */
+   { STAT_ATTR_NAME,     CLASS_TYPE_LETTERS,      STAT_ATTR_NAME,         EVENT_COPY },
+   /* below add support for space before the equals sign, e.g, <tag
+	  attr ="2"> */
+   { STAT_ATTR_NAME,     CLASS_TYPE_SPACE,        STAT_ATTR_NAME_END,     EVENT_NAME },
+   { STAT_ATTR_NAME,     CLASS_TYPE_EQUALS,       STAT_ATTR_VAL,          EVENT_NAME },
+
+   /* [31-33] attribute name end */
+   { STAT_ATTR_NAME_END, CLASS_TYPE_SPACE,        STAT_ATTR_NAME_END,     EVENT_NONE },
+   { STAT_ATTR_NAME_END, CLASS_TYPE_LETTERS,      STAT_ATTR_NAME,         EVENT_COPY },
+   { STAT_ATTR_NAME_END, CLASS_TYPE_EQUALS,       STAT_ATTR_VAL,          EVENT_NONE },
+
+   /* [34-35] handle attribute values, initial quote and spaces */
+   { STAT_ATTR_VAL,      CLASS_TYPE_QUOTE,        STAT_ATTR_VAL2,         EVENT_NONE },
+   /* below handles initial spaces before quoted attribute value */
+   { STAT_ATTR_VAL,      CLASS_TYPE_SPACE,        STAT_ATTR_VAL,          EVENT_NONE },
+
+   /* [36-37] handle actual attribute values */
+   { STAT_ATTR_VAL2,     CLASS_TYPE_QUOTE,        STAT_START_TAGNAME_END, EVENT_VAL  },
+   { STAT_ATTR_VAL2,     CLASS_TYPE_LETTERS,      STAT_ATTR_VAL2,         EVENT_COPY },
+   { STAT_ATTR_VAL2,     CLASS_TYPE_SLASH,        STAT_ATTR_VAL2,         EVENT_NONE },
+
+   /* End of table marker */
+   { STAT_ERROR,         CLASS_TYPE_NONE,         STAT_ERROR,             EVENT_NONE }
+};
+
+struct rtgui_xml
+{
+	/* event handler */
+	rtgui_xml_event_handler_t event_handler;
+	void* user;
+
+	char* buffer;				/* xml buffer */
+	rt_size_t buffer_size;		/* buffer size */
+	rt_size_t position;			/* current position in buffer */
+	rt_uint16_t state, event;	/* current state and event */
+
+	rt_bool_t copy;             /* copy text into tmp buffer */
+	rt_bool_t halt;				/* halt parsing of document */
+};
+
+rtgui_xml_t* rtgui_xml_create(rt_size_t buffer_size, rtgui_xml_event_handler_t handler,
+	void* user)
+{
+	rtgui_xml_t* xml = (rtgui_xml_t*) rtgui_malloc(sizeof(struct rtgui_xml));
+	rt_memset(xml, 0, sizeof(rtgui_xml_t));
+
+	xml->event_handler = handler;
+	xml->user = user;
+
+	/* create buffer */
+	xml->buffer_size = buffer_size;
+	xml->buffer = (char*)rtgui_malloc(xml->buffer_size);
+	return xml;
+}
+
+void rtgui_xml_destroy(rtgui_xml_t* xml)
+{
+	if(xml)
+	{
+		rtgui_free(xml->buffer);
+		rtgui_free(xml);
+	}
+}
+
+const char* rtgui_xml_event_str(rt_uint8_t event)
+{
+	switch(event)
+	{
+	case EVENT_START:
+		return "start tag";
+		break;
+	case EVENT_END:
+		return "end tag";
+		break;
+	case EVENT_TEXT:
+		return "text";
+		break;
+	case EVENT_NAME:
+		return "attr name";
+		break;
+	case EVENT_VAL:
+		return "attr val";
+		break;
+	case EVENT_END_DOC:
+		return "end document";
+		break;
+	default:
+		break;
+	}
+	return "err";
+}
+
+int rtgui_xml_parse(rtgui_xml_t* xml, const char* buf, rt_size_t len)
+{
+	int i, j, c, match;
+
+#define is_space(ch)	\
+	((rt_uint32_t)(ch - 9) < 5u  ||  ch == ' ')
+#define is_alpha(ch)	\
+	((rt_uint32_t)((ch | 0x20) - 'a') < 26u)
+#define is_digit(ch)	\
+	((rt_uint32_t)(ch - '0') < 10u)
+#define is_letters(ch)	\
+	(is_alpha(ch) || is_digit(ch) || (ch == '.'))
+
+	for(i=0; i<len; i++)
+	{
+		if(xml->halt) break;
+
+		c = buf[i] & 0xff;
+
+		/* search in state table */
+		for(j=0, match = 0; RTGUI_XML_STATES[j].state != STAT_ERROR; j++)
+		{
+			if(RTGUI_XML_STATES[j].state != xml->state)
+				continue;
+
+			switch(RTGUI_XML_STATES[j].class_type)
+			{
+			case CLASS_TYPE_LETTERS:
+				match = is_letters(c);
+				break;
+			case CLASS_TYPE_LEFT_ANGLE:
+				match = (c == '<');
+				break;
+			case CLASS_TYPE_SLASH:
+				match = (c == '/');
+				break;
+			case CLASS_TYPE_RIGHT_ANGLE:
+				match = (c == '>');
+				break;
+			case CLASS_TYPE_EQUALS:
+				match = (c == '=');
+				break;
+			case CLASS_TYPE_QUOTE:
+				match = (c == '"');
+				break;
+			case CLASS_TYPE_SPACE:
+				match = is_space(c);
+				break;
+			case CLASS_TYPE_ANY:
+				match = 1;
+				break;
+			default:
+				break;
+			}
+
+			/* we matched a character class */
+			if(match)
+			{
+				if(RTGUI_XML_STATES[j].event == EVENT_COPY)
+				{
+					xml->copy = RT_TRUE;
+				}
+				else if(RTGUI_XML_STATES[j].event != EVENT_NONE)
+				{
+					if(xml->copy == RT_TRUE)
+					{
+						/* basically we are guaranteed never to have an event of
+						   type EVENT_COPY or EVENT_NONE here. */
+						xml->event = RTGUI_XML_STATES[j].event;
+						xml->buffer[xml->position] = 0; /* make a string */
+
+						if(!xml->event_handler(RTGUI_XML_STATES[j].event,
+											  xml->buffer, xml->position ,
+											  xml->user))
+						{
+							xml->halt = 1; /* stop parsing from here out */
+						}
+						xml->position = 0;
+						xml->copy = RT_FALSE;
+					}
+				}
+				if(xml->copy == RT_TRUE)
+				{
+					/* check to see if we have room; one less for trailing
+					   nul */
+					if(xml->position < xml->buffer_size-1)
+					{
+						xml->buffer[xml->position] = buf[i];
+						xml->position++;
+					}
+				}
+				xml->state = RTGUI_XML_STATES[j].next_state; /* change state */
+				break; /* break out of loop though state search */
+			}
+		}
+	}
+
+	return !xml->halt;
+}

+ 34 - 0
components/rtgui/include/rtgui/rtgui_xml.h

@@ -0,0 +1,34 @@
+#ifndef __RTGUI_XML_H__
+#define __RTGUI_XML_H__
+
+#include <rtgui/rtgui.h>
+
+/* Types of events: start element, end element, text, attr name, attr
+   val and start/end document. Other events can be ignored! */
+enum {
+	EVENT_START = 0, /* Start tag */
+	EVENT_END,       /* End tag */
+	EVENT_TEXT,      /* Text */
+	EVENT_NAME,      /* Attribute name */
+	EVENT_VAL,       /* Attribute value */
+	EVENT_END_DOC,   /* End of document */
+	EVENT_COPY,      /* Internal only; copies to internal buffer */
+	EVENT_NONE       /* Internal only; should never see this event */
+};
+
+/* xml structure typedef */
+typedef struct rtgui_xml rtgui_xml_t;
+typedef int (*rtgui_xml_event_handler_t)(rt_uint8_t event, const char* text, rt_size_t len, void* user);
+
+/* create a xml parser context */
+rtgui_xml_t* rtgui_xml_create(rt_size_t buffer_size, rtgui_xml_event_handler_t handler, void* user);
+/* destroy a xml parser context */
+void rtgui_xml_destroy(rtgui_xml_t* rtgui_xml);
+
+/* parse xml buffer */
+int rtgui_xml_parse(rtgui_xml_t* rtgui_xml, const char* buf, rt_size_t len);
+
+/* event string */
+const char* rtgui_xml_event_str(rt_uint8_t event);
+
+#endif

+ 0 - 1
components/rtgui/include/rtgui/widgets/widget.h

@@ -90,7 +90,6 @@ struct rtgui_widget
 
 	/* the rect clip */
 	rtgui_region_t clip;
-	rt_uint16_t clip_sync;
 
 	/* the event handler */
 	rt_bool_t (*event_handler)	(struct rtgui_widget* widget, struct rtgui_event* event);

+ 2 - 0
components/rtgui/include/rtgui/widgets/window.h

@@ -10,6 +10,7 @@
  * Change Logs:
  * Date           Author       Notes
  * 2009-10-04     Bernard      first version
+ * 2010-05-03     Bernard      add win close function
  */
 #ifndef __RTGUI_WINDOW_H__
 #define __RTGUI_WINDOW_H__
@@ -74,6 +75,7 @@ rtgui_type_t *rtgui_win_type_get(void);
 rtgui_win_t* rtgui_win_create(rtgui_toplevel_t* parent_toplevel, const char* title, 
 	rtgui_rect_t *rect, rt_uint8_t flag);
 void rtgui_win_destroy(rtgui_win_t* win);
+void rtgui_win_close(struct rtgui_win* win);
 
 rtgui_modal_code_t rtgui_win_show(rtgui_win_t* win, rt_bool_t is_modal);
 void rtgui_win_hiden(rtgui_win_t* win);

+ 10 - 0
components/rtgui/server/mouse.c

@@ -44,12 +44,14 @@ struct rtgui_cursor
 	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
 
 	/* screen framebuffer */
 	rt_uint8_t*		framebuffer;
@@ -118,9 +120,11 @@ 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()
@@ -163,6 +167,7 @@ void rtgui_mouse_init()
 		_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;
@@ -171,6 +176,7 @@ void rtgui_mouse_init()
 	_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)
@@ -182,6 +188,7 @@ void rtgui_mouse_moveto(int x, int y)
 	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)
@@ -210,6 +217,7 @@ void rtgui_mouse_moveto(int x, int y)
 			rtgui_winrect_show();
 		}
 		else
+#endif
 		{
 #ifdef RTGUI_USING_MOUSE_CURSOR
 			rtgui_mouse_hide_cursor();
@@ -371,6 +379,7 @@ static void rtgui_cursor_show()
 }
 #endif
 
+#ifdef RTGUI_USING_WINMOVE
 void rtgui_winrect_set(struct rtgui_topwin* topwin)
 {
 	/* set win rect show */
@@ -562,6 +571,7 @@ static void rtgui_winrect_save()
 	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)
 {

+ 2 - 0
components/rtgui/server/mouse.h

@@ -40,9 +40,11 @@ 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(struct rtgui_topwin* topwin);
 rt_bool_t rtgui_winrect_moved_done(rtgui_rect_t* winrect, struct rtgui_topwin** topwin);
+#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);

+ 4 - 2
components/rtgui/server/server.c

@@ -225,6 +225,7 @@ void rtgui_server_handle_mouse_btn(struct rtgui_event_mouse* event)
 	/* 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))
 	{
@@ -259,6 +260,7 @@ void rtgui_server_handle_mouse_btn(struct rtgui_event_mouse* event)
 			return;
 		}
 	}
+#endif
 
 	/* get the wnd which contains the mouse */
 	wnd = rtgui_topwin_get_wnd(event->x, event->y);
@@ -464,9 +466,9 @@ void rtgui_server_handle_kbd(struct rtgui_event_kbd* event)
 		{
 			/* send to focus panel */
 			event->wid = RT_NULL;
-	
+
 			/* send keyboard event to thread */
-				rtgui_thread_send(tid, (struct rtgui_event*)event, sizeof(struct rtgui_event_kbd));
+			rtgui_thread_send(tid, (struct rtgui_event*)event, sizeof(struct rtgui_event_kbd));
 		}
 	}
 }

+ 2 - 0
components/rtgui/server/topwin.c

@@ -946,11 +946,13 @@ void rtgui_topwin_title_onmouse(struct rtgui_topwin* win, struct rtgui_event_mou
 				win->flag |= WINTITLE_CB_PRESSED;
 				rtgui_theme_draw_win(win);
 			}
+#ifdef RTGUI_USING_WINMOVE
 			else
 			{
 				/* maybe move window */
 				rtgui_winrect_set(win);
 			}
+#endif
 		}
 		else if (event->button & RTGUI_MOUSE_BUTTON_UP)
 		{

+ 5 - 1
components/rtgui/widgets/button.c

@@ -22,7 +22,7 @@ static void _rtgui_button_constructor(rtgui_button_t *button)
 	rtgui_widget_set_event_handler(RTGUI_WIDGET(button), rtgui_button_event_handler);
 
 	/* un-press button */
-	button->flag &= ~RTGUI_BUTTON_FLAG_PRESS;
+	button->flag = 0;
 
 	/* set flag and on_button event handler */
 	button->pressed_image = RT_NULL;
@@ -119,9 +119,13 @@ rt_bool_t rtgui_button_event_handler(struct rtgui_widget* widget, struct rtgui_e
 				if (emouse->button & RTGUI_MOUSE_BUTTON_UP)
 				{
 					if (btn->flag & RTGUI_BUTTON_FLAG_PRESS)
+					{
 						btn->flag &= ~RTGUI_BUTTON_FLAG_PRESS;
+					}
 					else
+					{
 						btn->flag |= RTGUI_BUTTON_FLAG_PRESS;
+					}
 
 					/* draw button */
 #ifndef RTGUI_USING_SMALL_SIZE

+ 1 - 1
components/rtgui/widgets/list_view.c

@@ -207,7 +207,7 @@ rt_bool_t rtgui_list_view_event_handler(struct rtgui_widget* widget, struct rtgu
 					old_item = view->current_item;
 
 					/* set selected item */
-					view->current_item = view->current_item/view->page_items + index;
+					view->current_item = (view->current_item/view->page_items) * view->page_items + index;
 					rtgui_list_view_update_current(view, old_item);
 				}
 			}

+ 0 - 1
components/rtgui/widgets/toplevel.c

@@ -167,7 +167,6 @@ void rtgui_toplevel_update_clip(rtgui_toplevel_t* top)
 
 	/* reset toplevel widget clip to extent */
 	rtgui_region_reset(&(RTGUI_WIDGET(top)->clip), &(RTGUI_WIDGET(top)->extent));
-	RTGUI_WIDGET(top)->clip_sync ++;
 
 	/* subtract the screen rect */
 	screen_rect.x1 = screen_rect.y1 = 0;

+ 1 - 6
components/rtgui/widgets/widget.c

@@ -51,9 +51,8 @@ static void _rtgui_widget_constructor(rtgui_widget_t *widget)
 	/* set default event handler */
 	widget->event_handler = rtgui_widget_event_handler;
 
-	/* does not set widget extent and only set clip_sync to zero */
+	/* init clip information */
 	rtgui_region_init(&(widget->clip));
-	widget->clip_sync = 0;
 }
 
 /* Destroys the widget */
@@ -71,7 +70,6 @@ static void _rtgui_widget_destructor(rtgui_widget_t *widget)
 
 	/* fini clip region */
 	rtgui_region_fini(&(widget->clip));
-	widget->clip_sync = 0;
 }
 
 rtgui_type_t *rtgui_widget_type_get(void)
@@ -411,9 +409,6 @@ void rtgui_widget_update_clip(rtgui_widget_t* widget)
 	/* if there is no parent, do not update clip (please use toplevel widget API) */
 	if (parent == RT_NULL) return;
 
-	/* increase clip sync */
-	widget->clip_sync ++;
-
 	/* reset clip to extent */
 	rtgui_region_reset(&(widget->clip), &(widget->extent));