瀏覽代碼

add on_idle call back function.

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

+ 35 - 0
components/rtgui/common/rtgui_system.c

@@ -285,6 +285,7 @@ rtgui_thread_t* rtgui_thread_register(rt_thread_t tid, rt_mq_t mq)
 		thread->tid			= tid;
 		thread->mq			= mq;
 		thread->widget		= RT_NULL;
+		thread->on_idle     = RT_NULL;
 
 		/* set user thread */
 		tid->user_data = (rt_uint32_t)thread;
@@ -323,6 +324,26 @@ rtgui_thread_t* rtgui_thread_self()
 	return thread;
 }
 
+void rtgui_thread_set_onidle(rtgui_idle_func onidle)
+{
+	struct rtgui_thread* thread;
+
+	thread = rtgui_thread_self();
+	RT_ASSERT(thread != RT_NULL);
+
+	thread->on_idle = onidle;
+}
+
+rtgui_idle_func rtgui_thread_get_onidle()
+{
+	struct rtgui_thread* thread;
+
+	thread = rtgui_thread_self();
+	RT_ASSERT(thread != RT_NULL);
+
+	return thread->on_idle;
+}
+
 extern rt_thread_t rt_thread_find(char* name);
 rt_thread_t rtgui_thread_get_server()
 {
@@ -455,6 +476,20 @@ rt_err_t rtgui_thread_recv(rtgui_event_t* event, rt_size_t event_size)
 	return r;
 }
 
+rt_err_t rtgui_thread_recv_nosuspend(rtgui_event_t* event, rt_size_t event_size)
+{
+	struct rtgui_thread* thread;
+	rt_err_t r;
+
+	/* find rtgui_thread */
+	thread = (struct rtgui_thread*) (rt_thread_self()->user_data);
+	if (thread == RT_NULL) return -RT_ERROR;
+
+	r = rt_mq_recv(thread->mq, event, event_size, 0);
+
+	return r;
+}
+
 rt_err_t rtgui_thread_recv_filter(rt_uint32_t type, rtgui_event_t* event, rt_size_t event_size)
 {
 	struct rtgui_thread* thread;

+ 7 - 0
components/rtgui/include/rtgui/rtgui_system.h

@@ -39,10 +39,14 @@ struct rtgui_thread
 	struct rtgui_widget* widget;
 	/* event buffer */
 	rt_uint8_t event_buffer[RTGUI_EVENT_BUFFER_SIZE];
+
+	/* on idle event handler */
+	void (*on_idle)(struct rtgui_widget* widget, struct rtgui_event *event);
 };
 typedef struct rtgui_thread rtgui_thread_t;
 struct rtgui_timer;
 typedef void (*rtgui_timeout_func)(struct rtgui_timer* timer, void* parameter);
+typedef void (*rtgui_idle_func)(struct rtgui_widget* widget, struct rtgui_event *event);
 
 struct rtgui_timer
 {
@@ -65,6 +69,8 @@ void rtgui_timer_stop (rtgui_timer_t* timer);
 
 rtgui_thread_t* rtgui_thread_register(rt_thread_t tid, rt_mq_t mq);
 void rtgui_thread_deregister(rt_thread_t tid);
+void rtgui_thread_set_onidle(rtgui_idle_func onidle);
+rtgui_idle_func rtgui_thread_get_onidle();
 rtgui_thread_t* rtgui_thread_self(void);
 
 rt_thread_t rtgui_thread_get_server(void);
@@ -76,6 +82,7 @@ rt_err_t rtgui_thread_send(rt_thread_t tid, struct rtgui_event* event, rt_size_t
 rt_err_t rtgui_thread_send_urgent(rt_thread_t tid, struct rtgui_event* event, rt_size_t event_size);
 rt_err_t rtgui_thread_send_sync(rt_thread_t tid, struct rtgui_event* event, rt_size_t event_size);
 rt_err_t rtgui_thread_recv(struct rtgui_event* event, rt_size_t event_size);
+rt_err_t rtgui_thread_recv_nosuspend(struct rtgui_event* event, rt_size_t event_size);
 rt_err_t rtgui_thread_recv_filter(rt_uint32_t type, struct rtgui_event* event, rt_size_t event_size);
 rt_err_t rtgui_thread_ack(struct rtgui_event* event, rt_int32_t status);
 

+ 41 - 6
components/rtgui/widgets/window.c

@@ -522,6 +522,7 @@ rt_bool_t rtgui_win_event_handler(struct rtgui_widget* widget, struct rtgui_even
 /* windows event loop */
 void rtgui_win_event_loop(rtgui_win_t* wnd)
 {
+	rt_err_t result;
 	rtgui_thread_t* tid;
 	struct rtgui_event* event;
 
@@ -535,10 +536,27 @@ void rtgui_win_event_loop(rtgui_win_t* wnd)
 	{
 		while (wnd->style & RTGUI_WIN_STYLE_UNDER_MODAL)
 		{
-			if (rtgui_thread_recv(event, RTGUI_EVENT_BUFFER_SIZE) == RT_EOK)
+			if (tid->on_idle != RT_NULL)
 			{
-				/* perform event handler */
-				RTGUI_WIDGET(wnd)->event_handler(RTGUI_WIDGET(wnd), event);
+				result = rtgui_thread_recv_nosuspend(event, RTGUI_EVENT_BUFFER_SIZE);
+				if (result == RT_EOK)
+				{
+					/* perform event handler */
+					RTGUI_WIDGET(wnd)->event_handler(RTGUI_WIDGET(wnd), event);
+				}
+				else if (result == -RT_ETIMEOUT)
+				{
+					tid->on_idle(RTGUI_WIDGET(wnd), RT_NULL);
+				}
+			}
+			else
+			{
+				result = rtgui_thread_recv(event, RTGUI_EVENT_BUFFER_SIZE);
+				if (result == RT_EOK)
+				{
+					/* perform event handler */
+					RTGUI_WIDGET(wnd)->event_handler(RTGUI_WIDGET(wnd), event);
+				}
 			}
 		}
 	}
@@ -546,10 +564,27 @@ void rtgui_win_event_loop(rtgui_win_t* wnd)
 	{
 		while (!(wnd->style & RTGUI_WIN_STYLE_CLOSED))
 		{
-			if (rtgui_thread_recv(event, RTGUI_EVENT_BUFFER_SIZE) == RT_EOK)
+			if (tid->on_idle != RT_NULL)
+			{
+				result = rtgui_thread_recv_nosuspend(event, RTGUI_EVENT_BUFFER_SIZE);
+				if (result == RT_EOK)
+				{
+					/* perform event handler */
+					RTGUI_WIDGET(wnd)->event_handler(RTGUI_WIDGET(wnd), event);
+				}
+				else if (result == -RT_ETIMEOUT)
+				{
+					tid->on_idle(RTGUI_WIDGET(wnd), RT_NULL);
+				}
+			}
+			else
 			{
-				/* perform event handler */
-				RTGUI_WIDGET(wnd)->event_handler(RTGUI_WIDGET(wnd), event);
+				result = rtgui_thread_recv(event, RTGUI_EVENT_BUFFER_SIZE);
+				if (result == RT_EOK)
+				{
+					/* perform event handler */
+					RTGUI_WIDGET(wnd)->event_handler(RTGUI_WIDGET(wnd), event);
+				}
 			}
 		}
 	}

+ 26 - 5
components/rtgui/widgets/workbench.c

@@ -162,6 +162,7 @@ void rtgui_workbench_set_flag(rtgui_workbench_t* workbench, rt_uint8_t flag)
 
 rt_bool_t rtgui_workbench_event_loop(rtgui_workbench_t* workbench)
 {
+	rt_err_t result;
 	rtgui_thread_t* tid;
 	struct rtgui_event* event;
 
@@ -176,9 +177,19 @@ rt_bool_t rtgui_workbench_event_loop(rtgui_workbench_t* workbench)
 		/* event loop for modal mode shown view */
 		while (workbench->flag & RTGUI_WORKBENCH_FLAG_MODAL_MODE)
 		{
-			if (rtgui_thread_recv(event, RTGUI_EVENT_BUFFER_SIZE) == RT_EOK)
+			if (tid->on_idle != RT_NULL)
 			{
-				RTGUI_WIDGET(workbench)->event_handler(RTGUI_WIDGET(workbench), event);
+				result = rtgui_thread_recv_nosuspend(event, RTGUI_EVENT_BUFFER_SIZE);
+				if (result == RT_EOK)
+					RTGUI_WIDGET(workbench)->event_handler(RTGUI_WIDGET(workbench), event);
+				else if (result == -RT_ETIMEOUT)
+					tid->on_idle(RTGUI_WIDGET(workbench), RT_NULL);
+			}
+			else
+			{
+				result = rtgui_thread_recv(event, RTGUI_EVENT_BUFFER_SIZE);
+				if (result == RT_EOK)
+					RTGUI_WIDGET(workbench)->event_handler(RTGUI_WIDGET(workbench), event);
 			}
 		}
 	}
@@ -186,12 +197,22 @@ rt_bool_t rtgui_workbench_event_loop(rtgui_workbench_t* workbench)
 	{
 		/* show workbench firstly */
 		rtgui_workbench_show(workbench);
-		
+
 		while (!(workbench->flag & RTGUI_WORKBENCH_FLAG_CLOSED))
 		{
-			if (rtgui_thread_recv(event, RTGUI_EVENT_BUFFER_SIZE) == RT_EOK)
+			if (tid->on_idle != RT_NULL)
+			{
+				result = rtgui_thread_recv_nosuspend(event, RTGUI_EVENT_BUFFER_SIZE);
+				if (result == RT_EOK)
+					RTGUI_WIDGET(workbench)->event_handler(RTGUI_WIDGET(workbench), event);
+				else if (result == -RT_ETIMEOUT)
+					tid->on_idle(RTGUI_WIDGET(workbench), RT_NULL);
+			}
+			else 
 			{
-				RTGUI_WIDGET(workbench)->event_handler(RTGUI_WIDGET(workbench), event);
+				result = rtgui_thread_recv(event, RTGUI_EVENT_BUFFER_SIZE);
+				if (result == RT_EOK)
+					RTGUI_WIDGET(workbench)->event_handler(RTGUI_WIDGET(workbench), event);
 			}
 		}
 	}