From 898ad75a7afec41a8d91c9dbe7f6ff5c9a47a572 Mon Sep 17 00:00:00 2001 From: "bernard.xiong@gmail.com" Date: Wed, 4 Aug 2010 23:39:01 +0000 Subject: [PATCH] add on_idle call back function. git-svn-id: https://rt-thread.googlecode.com/svn/trunk@829 bbd45198-f89e-11dd-88c7-29a3b14d5316 --- components/rtgui/common/rtgui_system.c | 35 ++++++++++++++ components/rtgui/include/rtgui/rtgui_system.h | 7 +++ components/rtgui/widgets/window.c | 47 ++++++++++++++++--- components/rtgui/widgets/workbench.c | 31 ++++++++++-- 4 files changed, 109 insertions(+), 11 deletions(-) diff --git a/components/rtgui/common/rtgui_system.c b/components/rtgui/common/rtgui_system.c index df438ab5ee..cb04189266 100644 --- a/components/rtgui/common/rtgui_system.c +++ b/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; diff --git a/components/rtgui/include/rtgui/rtgui_system.h b/components/rtgui/include/rtgui/rtgui_system.h index 4afc65e4e0..ef2bd5da84 100644 --- a/components/rtgui/include/rtgui/rtgui_system.h +++ b/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); diff --git a/components/rtgui/widgets/window.c b/components/rtgui/widgets/window.c index 0997d769ba..13982395ef 100644 --- a/components/rtgui/widgets/window.c +++ b/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) { - /* 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); + } } } } diff --git a/components/rtgui/widgets/workbench.c b/components/rtgui/widgets/workbench.c index 28224d1eb9..1cfc98eedc 100644 --- a/components/rtgui/widgets/workbench.c +++ b/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) { - 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); } } }