diff options
Diffstat (limited to 'components/rtgui_win/common/rtgui_system.c')
| -rw-r--r-- | components/rtgui_win/common/rtgui_system.c | 750 |
1 files changed, 750 insertions, 0 deletions
diff --git a/components/rtgui_win/common/rtgui_system.c b/components/rtgui_win/common/rtgui_system.c new file mode 100644 index 0000000000..b25848956e --- /dev/null +++ b/components/rtgui_win/common/rtgui_system.c @@ -0,0 +1,750 @@ +/*
+ * File : rtgui_system.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 <rtgui/image.h>
+#include <rtgui/font.h>
+#include <rtgui/event.h>
+#include <rtgui/rtgui_server.h>
+#include <rtgui/rtgui_system.h>
+#include <rtgui/widgets/window.h>
+#include <rtgui/rtgui_theme.h>
+
+
+#ifdef __WIN32__ +#define RTGUI_EVENT_DEBUG +#define RTGUI_MEM_TRACE +#endif
+
+void rtgui_system_server_init()
+{
+ /* init image */
+ rtgui_system_image_init();
+ /* init font */
+ rtgui_font_system_init();
+
+ /* init rtgui server */
+ rtgui_win_init();
+ rtgui_server_init();
+
+ /* init theme */
+ rtgui_system_theme_init();
+}
+
+/************************************************************************/ +/* RTGUI Thread Wrapper */ +/************************************************************************/ +#ifdef RTGUI_EVENT_DEBUG +const char *event_string[] = +{ + /* panel event */ + "PANEL_ATTACH", /* attach to a panel */ + "PANEL_DETACH", /* detach from a panel */ + "PANEL_SHOW", /* show in a panel */ + "PANEL_HIDE", /* hide from a panel */ + "PANEL_INFO", /* panel information */ + "PANEL_RESIZE", /* resize panel */ + "PANEL_FULLSCREEN", /* to full screen */ + "PANEL_NORMAL", /* to normal screen */ + + /* window event */ + "WIN_CREATE", /* create a window */ + "WIN_DESTROY", /* destroy a window */ + "WIN_SHOW", /* show a window */ + "WIN_HIDE", /* hide a window */ + "WIN_ACTIVATE", /* activate a window */ + "WIN_DEACTIVATE", /* deactivate a window */ + "WIN_CLOSE", /* close a window */ + "WIN_MOVE", /* move a window */ + "WIN_RESIZE", /* resize a window */ + + "SET_WM", /* set window manager */ + + "UPDATE_BEGIN", /* begin of update rect */ + "UPDATE_END", /* end of update rect */ + "MONITOR_ADD", /* add a monitor rect */ + "MONITOR_REMOVE", /* remove a monitor rect*/ + "PAINT", /* paint on screen */ + "TIMER", /* timer */ + + /* clip rect information */ + "CLIP_INFO", /* clip rect info */ + + /* mouse and keyboard event */ + "MOUSE_MOTION", /* mouse motion */ + "MOUSE_BUTTON", /* mouse button info */ + "KBD", /* keyboard info */ + + /* user command event */ + "COMMAND", /* user command */ + + /* request's status event */ + "STATUS", /* request result */ + "SCROLLED", /* scroll bar scrolled */ + "RESIZE", /* widget resize */ +}; + +#define DBG_MSG(x) rt_kprintf x + +static void rtgui_event_dump(rt_thread_t tid, rtgui_event_t* event) +{ + char* sender = "(unknown)"; + + if (event->sender != RT_NULL) sender = event->sender->name; + + if ((event->type == RTGUI_EVENT_TIMER) || + (event->type == RTGUI_EVENT_UPDATE_BEGIN) || + (event->type == RTGUI_EVENT_UPDATE_END)) + { + /* don't dump timer event */ + return ; + } + + rt_kprintf("%s -- %s --> %s ", sender, event_string[event->type], tid->name); + switch (event->type) + { + case RTGUI_EVENT_PAINT: + { + struct rtgui_event_paint *paint = (struct rtgui_event_paint *)event; + + if(paint->wid != RT_NULL) + rt_kprintf("win: %s", paint->wid->title); + } + break; + + case RTGUI_EVENT_KBD: + { + struct rtgui_event_kbd *ekbd = (struct rtgui_event_kbd*) event; + if (ekbd->wid != RT_NULL) + rt_kprintf("win: %s", ekbd->wid->title); + if (RTGUI_KBD_IS_UP(ekbd)) rt_kprintf(", up"); + else rt_kprintf(", down"); + } + break; + + case RTGUI_EVENT_CLIP_INFO: + { + struct rtgui_event_clip_info *info = (struct rtgui_event_clip_info *)event; + + if(info->wid != RT_NULL) + rt_kprintf("win: %s", info->wid->title); +#ifdef RTGUI_USING_SMALL_SIZE + rt_kprintf(" clip no. %d", info->num_rect); +#else + { + rtgui_rect_t *rect; + rt_uint32_t index; + + rect = (rtgui_rect_t*)(info + 1); + for (index = 0; index < info->num_rect; index ++) + { + rt_kprintf(" (x1:%d, y1:%d, x2:%d, y2:%d)", rect->x1, rect->y1, rect->x2, rect->y2); + rect ++; + } + } +#endif + } + break; + + case RTGUI_EVENT_WIN_CREATE: + { + struct rtgui_event_win_create *create = (struct rtgui_event_win_create*)event; + + rt_kprintf(" win: %s at (x1:%d, y1:%d, x2:%d, y2:%d)", +#ifdef RTGUI_USING_SMALL_SIZE + create->wid->title, + RTGUI_WIDGET(create->wid)->extent.x1, + RTGUI_WIDGET(create->wid)->extent.y1, + RTGUI_WIDGET(create->wid)->extent.x2, + RTGUI_WIDGET(create->wid)->extent.y2); +#else + create->title, + create->extent.x1, + create->extent.y1, + create->extent.x2, + create->extent.y2); +#endif + } + break; + + case RTGUI_EVENT_UPDATE_END: + { + struct rtgui_event_update_end* update_end = (struct rtgui_event_update_end*)event; + rt_kprintf("(x:%d, y1:%d, x2:%d, y2:%d)", update_end->rect.x1, + update_end->rect.y1, + update_end->rect.x2, + update_end->rect.y2); + } + break; + + case RTGUI_EVENT_WIN_ACTIVATE: + case RTGUI_EVENT_WIN_DEACTIVATE: + case RTGUI_EVENT_WIN_SHOW: + { + struct rtgui_event_win *win = (struct rtgui_event_win *)event; + + if(win->wid != RT_NULL) + rt_kprintf("win: %s", win->wid->title); + } + break; + + case RTGUI_EVENT_WIN_MOVE: + { + struct rtgui_event_win_move *win = (struct rtgui_event_win_move *)event; + + if(win->wid != RT_NULL) + { + rt_kprintf("win: %s", win->wid->title); + rt_kprintf(" to (x:%d, y:%d)", win->x, win->y); + } + } + break; + + case RTGUI_EVENT_WIN_RESIZE: + { + struct rtgui_event_win_resize* win = (struct rtgui_event_win_resize *)event; + + if (win->wid != RT_NULL) + { + rt_kprintf("win: %s, rect(x1:%d, y1:%d, x2:%d, y2:%d)", win->wid->title, + RTGUI_WIDGET(win->wid)->extent.x1, + RTGUI_WIDGET(win->wid)->extent.y1, + RTGUI_WIDGET(win->wid)->extent.x2, + RTGUI_WIDGET(win->wid)->extent.y2); + } + } + break; + + case RTGUI_EVENT_MOUSE_BUTTON: + case RTGUI_EVENT_MOUSE_MOTION: + { + struct rtgui_event_mouse *mouse = (struct rtgui_event_mouse*)event; + + if (mouse->button & RTGUI_MOUSE_BUTTON_LEFT) rt_kprintf("left "); + else rt_kprintf("right "); + + if (mouse->button & RTGUI_MOUSE_BUTTON_DOWN) rt_kprintf("down "); + else rt_kprintf("up "); + + if (mouse->wid != RT_NULL) + rt_kprintf("win: %s at (%d, %d)", mouse->wid->title, + mouse->x, mouse->y); + else + rt_kprintf("(%d, %d)", mouse->x, mouse->y); + } + break; + + case RTGUI_EVENT_MONITOR_ADD: + { + struct rtgui_event_monitor *monitor = (struct rtgui_event_monitor*)event; + if (monitor->panel != RT_NULL) + { +#if 0 + rt_kprintf("panel: %s, the rect is:(%d, %d) - (%d, %d)", monitor->panel->name, + monitor->rect.x1, monitor->rect.y1, + monitor->rect.x2, monitor->rect.y2); +#endif + rt_kprintf("the rect is:(%d, %d) - (%d, %d)", + monitor->rect.x1, monitor->rect.y1, + monitor->rect.x2, monitor->rect.y2); + } + else if (monitor->wid != RT_NULL) + { + rt_kprintf("win: %s, the rect is:(%d, %d) - (%d, %d)", monitor->wid->title, + monitor->rect.x1, monitor->rect.y1, + monitor->rect.x2, monitor->rect.y2); + } + } + break; + } + + rt_kprintf("\n"); +} +#else +#define DBG_MSG(x) +#define rtgui_event_dump(tid, event) +#endif
+void rtgui_thread_register(struct rt_thread* tid, struct rt_messagequeue* mq)
+{
+ rtgui_thread_t* thread = (rtgui_thread_t*)rt_malloc(sizeof(rtgui_thread_t));
+
+ if(thread != RT_NULL)
+ {
+ /* set tid and 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;
+ }
+}
+
+void rtgui_thread_deregister(struct rt_thread* tid)
+{
+ rtgui_thread_t* thread;
+
+ /* find rtgui_thread_t */
+ thread = (rtgui_thread_t*) (tid->user_data);
+
+ if(thread != RT_NULL)
+ {
+ /* remove rtgui_thread_t */
+ tid->user_data = 0;
+ /* free rtgui_thread_t */
+ rt_free(thread);
+ }
+}
+
+/* get current gui thread */
+rtgui_thread_t* rtgui_thread_self()
+{
+ rtgui_thread_t* thread;
+ struct rt_thread* self;
+
+ /* get current thread */
+ self = rt_thread_self();
+ thread = (rtgui_thread_t*)(self->user_data);
+
+ return thread;
+}
+
+void rtgui_thread_set_onidle(rtgui_idle_func onidle) +{ + rtgui_thread_t* thread; + + thread = rtgui_thread_self(); + RT_ASSERT(thread != RT_NULL); + + thread->on_idle = onidle; +} + +rtgui_idle_func rtgui_thread_get_onidle() +{ + rtgui_thread_t* thread; + + thread = rtgui_thread_self(); + RT_ASSERT(thread != RT_NULL); + + return thread->on_idle; +}
+
+extern struct rt_thread* rt_thread_find(char* name);
+struct rt_thread* rtgui_thread_get_server()
+{
+ return rt_thread_find("rtgui");
+}
+
+void rtgui_thread_set_widget(PVOID widget)
+{
+ rtgui_thread_t* thread;
+
+ /* get thread */
+ thread = (rtgui_thread_t*) (rt_thread_self()->user_data);
+
+ if(thread != RT_NULL) thread->widget = widget;//?���ܶ��win����һ��thread!!
+}
+
+PVOID rtgui_thread_get_widget(void)
+{
+ rtgui_thread_t* thread;
+
+ /* get rtgui_thread_t */
+ thread = (rtgui_thread_t*) (rt_thread_self()->user_data);
+
+ return thread == RT_NULL? RT_NULL : thread->widget;
+}
+
+rt_err_t rtgui_thread_send(struct rt_thread* tid, rtgui_event_t* event, rt_size_t event_size)
+{
+ rt_err_t result;
+ rtgui_thread_t* thread;
+
+ /* find rtgui_thread_t */
+ thread = (rtgui_thread_t*) (tid->user_data);
+ if(thread == RT_NULL) return -RT_ERROR;
+
+ result = rt_mq_send(thread->mq, event, event_size);
+ if(result != RT_EOK)
+ {
+ if(event->type != RTGUI_EVENT_TIMER)
+ rt_kprintf("send event to %s failed\n", thread->tid->name);
+ }
+
+ return result;
+}
+
+rt_err_t rtgui_thread_send_urgent(struct rt_thread* tid, rtgui_event_t* event, rt_size_t event_size)
+{
+ rt_err_t result;
+ rtgui_thread_t* thread;
+
+ /* find rtgui_thread_t */
+ thread = (rtgui_thread_t*) (tid->user_data);
+ if(thread == RT_NULL) return -RT_ERROR;
+
+ result = rt_mq_urgent(thread->mq, event, event_size);
+ if(result != RT_EOK)
+ rt_kprintf("send ergent event failed\n");
+
+ return result;
+}
+
+rt_err_t rtgui_thread_send_sync(struct rt_thread* tid, rtgui_event_t* event, rt_size_t event_size)
+{
+ rt_err_t r;
+ rtgui_thread_t* thread;
+ rt_int32_t ack_buffer, ack_status;
+ struct rt_mailbox ack_mb;
+
+ /* init ack mailbox */
+ r = rt_mb_init(&ack_mb, "ack", &ack_buffer, 1, 0);
+ if( r!= RT_EOK) goto __return;
+
+ /* find rtgui_thread_t */
+ thread = (rtgui_thread_t*) (tid->user_data);
+ if(thread == RT_NULL){ r = RT_ERROR; goto __return; }
+
+ event->ack = &ack_mb;
+ r = rt_mq_send(thread->mq, event, event_size);
+ if(r != RT_EOK)
+ {
+ rt_kprintf("send sync event failed\n");
+ goto __return;
+ }
+
+ r = rt_mb_recv(&ack_mb, (rt_uint32_t*)&ack_status, RT_WAITING_FOREVER);
+ if( r!= RT_EOK) goto __return;
+
+ if(ack_status != RT_EOK) r = -RT_ERROR;
+ else r = RT_EOK;
+
+ /* fini ack mailbox */
+ rt_mb_detach(&ack_mb);
+
+__return:
+ return r;
+}
+
+rt_err_t rtgui_thread_ack(rtgui_event_t* event, rt_err_t errcode)
+{
+ if(event != RT_NULL &&
+ event->ack != RT_NULL)
+ {
+ rt_mb_send(event->ack, errcode);
+ }
+
+ return RT_EOK;
+}
+
+rt_err_t rtgui_thread_recv(rtgui_event_t* event, rt_size_t event_size)
+{
+ rtgui_thread_t* thread;
+ rt_err_t r;
+
+ /* find rtgui_thread_t */
+ thread = (rtgui_thread_t*) (rt_thread_self()->user_data);
+ if(thread == RT_NULL) return -RT_ERROR;
+
+ r = rt_mq_recv(thread->mq, event, event_size, RT_WAITING_FOREVER);
+
+ return r;
+}
+ +rt_err_t rtgui_thread_recv_nosuspend(rtgui_event_t* event, rt_size_t event_size) +{ + rtgui_thread_t* thread; + rt_err_t r; + + /* find rtgui_thread */ + thread = (rtgui_thread_t*) (rt_thread_self()->user_data); + if (thread == RT_NULL) return -RT_ERROR; + + r = rt_mq_recv(thread->mq, event, event_size, 1); + + return r; +}
+ +rt_err_t rtgui_thread_recv_filter(rt_uint32_t type, rtgui_event_t* event, rt_size_t event_size)
+{
+ rtgui_thread_t* thread;
+
+ /* find rtgui_thread_t */
+ thread = (rtgui_thread_t*) (rt_thread_self()->user_data);
+ if(thread == RT_NULL) return -RT_ERROR;
+
+ while(rt_mq_recv(thread->mq, event, event_size, RT_WAITING_FOREVER) == RT_EOK)
+ {
+ if(event->type == type)
+ {
+ return RT_EOK;
+ }
+ else
+ {
+ /* let widget to handle event */
+ if(thread->widget != RT_NULL && RTGUI_WIDGET_EVENT_HANDLE(thread->widget) != RT_NULL)
+ {
+ RTGUI_WIDGET_EVENT_CALL(thread->widget, event);
+ }
+ }
+ }
+
+ return -RT_ERROR;
+}
+
+/************************************************************************/
+/* RTGUI Timer */
+/************************************************************************/
+static void rtgui_time_out(void* parameter)
+{
+ rtgui_timer_t* timer;
+ rtgui_event_timer_t event;
+ timer = (rtgui_timer_t*)parameter;
+
+ /*
+ * Note: event_timer can not use RTGUI_EVENT_TIMER_INIT to init, for there is no
+ * thread context
+ */
+ RTGUI_EVENT_TIMER_INIT(&event);
+ //event.parent.type = RTGUI_EVENT_TIMER;
+ //event.parent.sender = RT_NULL;
+
+ event.timer = timer;
+
+ rtgui_thread_send(timer->tid, &(event.parent), sizeof(rtgui_event_timer_t));
+}
+
+rtgui_timer_t* rtgui_timer_create(rt_int32_t time, rt_int32_t flag, rtgui_timeout_func timeout, void* parameter)
+{
+ rtgui_timer_t* timer;
+
+ timer = (rtgui_timer_t*) rt_malloc(sizeof(rtgui_timer_t));
+ timer->tid = rt_thread_self();
+ timer->timeout = timeout;
+ timer->user_data = parameter;
+
+ /* init rt-thread timer */
+ rt_timer_init(&(timer->timer), "rtgui", rtgui_time_out, timer, time, (rt_uint8_t)flag);
+
+ return timer;
+}
+
+void rtgui_timer_destory(rtgui_timer_t* timer)
+{
+ RT_ASSERT(timer != RT_NULL);
+
+ /* stop timer firstly */
+ rtgui_timer_stop(timer);
+
+ /* detach rt-thread timer */
+ rt_timer_detach(&(timer->timer));
+
+ rt_free(timer);
+}
+
+void rtgui_timer_start(rtgui_timer_t* timer)
+{
+ RT_ASSERT(timer != RT_NULL);
+
+ /* start rt-thread timer */
+ rt_timer_start(&(timer->timer));
+}
+
+void rtgui_timer_stop (rtgui_timer_t* timer)
+{
+ RT_ASSERT(timer != RT_NULL);
+
+ /* stop rt-thread timer */
+ rt_timer_stop(&(timer->timer));
+}
+
+/************************************************************************/ +/* RTGUI Memory Management */ +/************************************************************************/ +#ifdef RTGUI_MEM_TRACE +struct rtgui_mem_info +{ + rt_uint32_t allocated_size; + rt_uint32_t max_allocated; +}; +struct rtgui_mem_info mem_info; + +#define MEMTRACE_MAX 4096 +#define MEMTRACE_HASH_SIZE 256 + +struct rti_memtrace_item +{ + void* mb_ptr; /* memory block pointer */ + rt_uint32_t mb_len; /* memory block length */ + + struct rti_memtrace_item* next; +}; +struct rti_memtrace_item trace_list[MEMTRACE_MAX]; +struct rti_memtrace_item *item_hash[MEMTRACE_HASH_SIZE]; +struct rti_memtrace_item *item_free; + +rt_bool_t rti_memtrace_inited = 0; +void rti_memtrace_init() +{ + struct rti_memtrace_item *item; + rt_uint32_t index; + + rt_memset(trace_list, 0, sizeof(trace_list)); + rt_memset(item_hash, 0, sizeof(item_hash)); + + item_free = &trace_list[0]; + item = &trace_list[0]; + + for (index = 1; index < MEMTRACE_HASH_SIZE; index ++) + { + item->next = &trace_list[index]; + item = item->next; + } + + item->next = RT_NULL; +} + +void rti_malloc_hook(void* ptr, rt_uint32_t len) +{ + rt_uint32_t index; + struct rti_memtrace_item* item; + + if (item_free == RT_NULL) return; + + mem_info.allocated_size += len; + if (mem_info.max_allocated < mem_info.allocated_size) + mem_info.max_allocated = mem_info.allocated_size; + + /* lock context */ + item = item_free; + item_free = item->next; + + item->mb_ptr = ptr; + item->mb_len = len; + item->next = RT_NULL; + + /* get hash item index */ + index = ((rt_uint32_t)ptr) % MEMTRACE_HASH_SIZE; + if (item_hash[index] != RT_NULL) + { + /* add to list */ + item->next = item_hash[index]; + item_hash[index] = item; + } + else + { + /* set list header */ + item_hash[index] = item; + } + /* unlock context */ +} + +void rti_free_hook(void* ptr) +{ + rt_uint32_t index; + struct rti_memtrace_item *item; + + /* get hash item index */ + index = ((rt_uint32_t)ptr) % MEMTRACE_HASH_SIZE; + if (item_hash[index] != RT_NULL) + { + item = item_hash[index]; + if (item->mb_ptr == ptr) + { + /* delete item from list */ + item_hash[index] = item->next; + } + else + { + /* find ptr in list */ + while (item->next != RT_NULL && item->next->mb_ptr != ptr) + item = item->next; + + /* delete item from list */ + if (item->next != RT_NULL) + { + struct rti_memtrace_item* i; + + i = item->next; + item->next = item->next->next; + + item = i; + } + else + { + /* not found */ + return; + } + } + + /* reduce allocated size */ + mem_info.allocated_size -= item->mb_len; + + /* clear item */ + rt_memset(item, 0, sizeof(struct rti_memtrace_item)); + + /* add item to the free list */ + item->next = item_free; + item_free = item; + } +} +#endif + +void* rtgui_malloc(rt_size_t size) +{ + void* ptr; + + ptr = rt_malloc(size); +#ifdef RTGUI_MEM_TRACE + if (rti_memtrace_inited == 0) + { + rti_memtrace_init(); + rti_memtrace_inited = 1; + } + + if (ptr != RT_NULL) + rti_malloc_hook(ptr, size); +#endif + + return ptr; +} + +void* rtgui_realloc(void* ptr, rt_size_t size) +{ + void* new_ptr; + +#ifdef RTGUI_MEM_TRACE + new_ptr = rtgui_malloc(size); + if ((new_ptr != RT_NULL) && (ptr != RT_NULL)) + { + rt_memcpy(new_ptr, ptr, size); + rtgui_free(ptr); + } +#else + new_ptr = rt_realloc(ptr, size); +#endif + + return new_ptr; +} + +void rtgui_free(void* ptr) +{ +#ifdef RTGUI_MEM_TRACE + if (ptr != RT_NULL) + rti_free_hook(ptr); +#endif + + rt_free(ptr); +} |
