server.c 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320
  1. /*
  2. * File : server.c
  3. * This file is part of RTGUI in RT-Thread RTOS
  4. * COPYRIGHT (C) 2006 - 2009, RT-Thread Development Team
  5. *
  6. * The license and distribution terms for this file may be
  7. * found in the file LICENSE in this distribution or at
  8. * http://www.rt-thread.org/license/LICENSE
  9. *
  10. * Change Logs:
  11. * Date Author Notes
  12. * 2009-10-04 Bernard first version
  13. */
  14. #include <rtgui/rtgui.h>
  15. #include <topwin.h>
  16. #include <rtgui/event.h>
  17. #include <panel.h>
  18. #include <mouse.h>
  19. #include <rtgui/widgets/widget.h>
  20. #include <rtgui/widgets/window.h>
  21. #include <rtgui/rtgui_theme.h>
  22. static struct rt_messagequeue *rtgui_server_mq;
  23. extern rtgui_win_t* rtgui_server_focus_win;
  24. void rtgui_server_handle_update(rtgui_event_update_t* event)
  25. {
  26. const struct rtgui_graphic_driver* gd = rtgui_graphic_driver_get_default();
  27. gd->screen_update(&(event->rect));
  28. }
  29. void rtgui_server_handle_mouse_btn(rtgui_event_mouse_t* event)
  30. {
  31. rtgui_win_t* win;
  32. rtgui_panel_t* panel=rtgui_panel_get();
  33. /* re-init to server thread */
  34. RTGUI_EVENT_MOUSE_BUTTON_INIT(event);
  35. #ifdef RTGUI_USING_WINMOVE
  36. if (rtgui_winrect_is_moved() &&
  37. event->button & (RTGUI_MOUSE_BUTTON_LEFT | RTGUI_MOUSE_BUTTON_UP))
  38. {/* 释放鼠标按键后,更新窗口位置 */
  39. rtgui_win_t *wid;
  40. rtgui_rect_t rect;
  41. if (rtgui_winrect_moved_done(&rect, &wid) == RT_TRUE)
  42. {
  43. struct rtgui_event_win_move ewin;
  44. /* move window */
  45. RTGUI_EVENT_WIN_MOVE_INIT(&ewin);
  46. ewin.wid = wid;
  47. ewin.x = rect.x1;
  48. ewin.y = rect.y1;
  49. /* send to client thread */
  50. rtgui_thread_send(wid->tid, &(ewin.parent), sizeof(ewin));
  51. return;
  52. }
  53. }
  54. #endif
  55. if(RTGUI_PANEL_IS_MODAL_MODE(panel))
  56. {
  57. if(panel->modal_widget != RT_NULL && RTGUI_IS_WIN(panel->modal_widget))
  58. {
  59. win = RTGUI_WIN(panel->modal_widget);
  60. if(rtgui_rect_contains_point(&(RTGUI_WIDGET_EXTENT(win)), event->x, event->y) != RT_EOK)
  61. {
  62. win->status &= ~RTGUI_WIN_STATUS_ACTIVATE;
  63. rtgui_theme_draw_win_title(win);
  64. win->status |= RTGUI_WIN_STATUS_ACTIVATE;
  65. rtgui_theme_draw_win_title(win);
  66. win->status &= ~RTGUI_WIN_STATUS_ACTIVATE;
  67. rtgui_theme_draw_win_title(win);
  68. win->status |= RTGUI_WIN_STATUS_ACTIVATE;
  69. rtgui_theme_draw_win_title(win);
  70. return;
  71. }
  72. }
  73. }
  74. /* 是否在一个窗口上 */
  75. win = rtgui_topwin_get_wnd(event->x, event->y);
  76. if(win != RT_NULL)
  77. {
  78. rtgui_rect_t rect;
  79. event->wid = win;
  80. if(rtgui_server_focus_win != win)
  81. {//不是焦点窗口,则举升它
  82. rt_kprintf("1.raise win.");
  83. rtgui_topwin_raise(win);
  84. }
  85. rtgui_win_get_title_rect(win, &rect);
  86. rtgui_widget_rect_to_device(win, &rect);
  87. if(rtgui_rect_contains_point(&rect, event->x, event->y) == RT_EOK)
  88. {//鼠标在窗口的标题栏
  89. rtgui_topwin_title_onmouse(win, event);
  90. }
  91. else
  92. {//鼠标在窗口的客户区
  93. /*if(win->style & RTGUI_WIN_CLOSEBOX_PRESSED)
  94. {
  95. win->style &= ~RTGUI_WIN_CLOSEBOX_PRESSED;
  96. rtgui_theme_draw_win_closebox(win);
  97. }*/
  98. /* send mouse event to thread */
  99. rtgui_thread_send(win->tid, (rtgui_event_t*)event, sizeof(rtgui_event_mouse_t));
  100. }
  101. return;
  102. }
  103. //发送消息到panel
  104. /* deactivate old window */
  105. if (rtgui_server_focus_win != RT_NULL)
  106. {
  107. rtgui_topwin_deactivate(rtgui_server_focus_win);
  108. }
  109. rtgui_server_focus_win = RT_NULL;
  110. event->wid = RT_NULL;
  111. rtgui_thread_send(panel->tid,(rtgui_event_t*)event,sizeof(rtgui_event_mouse_t));
  112. }
  113. //static rt_bool_t motion_down=0;
  114. //static rt_int16_t downx,downy;
  115. //鼠标手势处理句柄
  116. void rtgui_server_handle_mouse_motion(rtgui_event_mouse_t* event)
  117. {
  118. rtgui_panel_t* panel;
  119. rtgui_win_t* win=RT_NULL;
  120. panel = rtgui_panel_get();
  121. if(panel != RT_NULL)
  122. {
  123. win = rtgui_topwin_get_wnd(event->x, event->y);
  124. if(win != RT_NULL)
  125. { /* send mouse event to thread */
  126. rtgui_thread_send(win->tid, (rtgui_event_t*)event, sizeof(rtgui_event_mouse_t));
  127. }
  128. else
  129. { //发送消息到panel
  130. rtgui_thread_send(panel->tid,(rtgui_event_t*)event,sizeof(rtgui_event_mouse_t));
  131. }
  132. }
  133. /* move mouse to (x, y) */
  134. rtgui_mouse_moveto(event->x, event->y);
  135. }
  136. void rtgui_server_handle_kbd(rtgui_event_kbd_t* event)
  137. {
  138. rtgui_win_t *win;
  139. rtgui_panel_t *panel;
  140. /* re-init to server thread */
  141. RTGUI_EVENT_KBD_INIT(event);
  142. /* send to focus window or focus panel */
  143. panel = rtgui_panel_get();
  144. if(panel != RT_NULL)
  145. {
  146. win = rtgui_server_focus_win;
  147. if(win != RT_NULL && win->status & RTGUI_WIN_STATUS_ACTIVATE)
  148. {
  149. event->wid = win;
  150. rtgui_thread_send(win->tid, (rtgui_event_t*)event, sizeof(rtgui_event_kbd_t));
  151. }
  152. else
  153. {//发送消息到panel
  154. event->wid = RT_NULL;
  155. rtgui_thread_send(panel->tid,(rtgui_event_t*)event,sizeof(rtgui_event_kbd_t));
  156. }
  157. }
  158. }
  159. void rtgui_server_handle_current_pos(rtgui_event_current_pos_t* event)
  160. {
  161. struct rt_thread *thread = rtgui_panel_get()->tid;
  162. /* re-init to server thread */
  163. RTGUI_EVENT_CURRENT_POS_INIT(event);
  164. /* send to panel */
  165. if(thread != RT_NULL)
  166. {//要用同步方式发送事件,否则会引起触摸屏检测死机
  167. rtgui_thread_send_sync(thread, (rtgui_event_t*)event, sizeof(rtgui_event_current_pos_t));
  168. }
  169. }
  170. /**
  171. * rtgui server thread's entry
  172. */
  173. static void rtgui_server_entry(void* parameter)
  174. {
  175. /* create rtgui server msgq */
  176. rtgui_server_mq = rt_mq_create("rtgui", 256, 8, RT_IPC_FLAG_FIFO);
  177. /* register rtgui server thread */
  178. rtgui_thread_register(rt_thread_self(), rtgui_server_mq);
  179. /* init mouse and show */
  180. rtgui_mouse_init();
  181. #ifdef RTGUI_USING_MOUSE_CURSOR
  182. rtgui_mouse_show_cursor();
  183. #endif
  184. while(1)
  185. {
  186. /* the buffer uses to receive event */
  187. char event_buf[256];
  188. rtgui_event_t* event = (rtgui_event_t*)&(event_buf[0]);
  189. if(rtgui_thread_recv(event, sizeof(event_buf)) == RT_EOK)
  190. {
  191. /* dispatch event */
  192. switch (event->type)
  193. {
  194. case RTGUI_EVENT_WIN_CREATE:
  195. if (rtgui_topwin_add(((rtgui_event_win_t*)event)->wid) == RT_EOK)
  196. rtgui_thread_ack(event, RTGUI_STATUS_OK);
  197. else
  198. rtgui_thread_ack(event, RTGUI_STATUS_ERROR);
  199. break;
  200. case RTGUI_EVENT_WIN_DESTROY:
  201. if (rtgui_topwin_remove(((rtgui_event_win_t*)event)->wid) == RT_EOK)
  202. rtgui_thread_ack(event, RTGUI_STATUS_OK);
  203. else
  204. rtgui_thread_ack(event, RTGUI_STATUS_ERROR);
  205. break;
  206. case RTGUI_EVENT_WIN_SHOW:
  207. if (rtgui_topwin_show(((rtgui_event_win_t*)event)->wid) == RT_EOK)
  208. rtgui_thread_ack(event, RTGUI_STATUS_OK);
  209. else
  210. rtgui_thread_ack(event, RTGUI_STATUS_ERROR);
  211. break;
  212. case RTGUI_EVENT_WIN_HIDE:
  213. if (rtgui_topwin_hide(((rtgui_event_win_t*)event)->wid) == RT_EOK)
  214. rtgui_thread_ack(event, RTGUI_STATUS_OK);
  215. else
  216. rtgui_thread_ack(event, RTGUI_STATUS_ERROR);
  217. break;
  218. case RTGUI_EVENT_WIN_MOVE:
  219. if (rtgui_topwin_move(((rtgui_event_win_move_t*)event)->wid,
  220. ((rtgui_event_win_move_t*)event)->x,
  221. ((rtgui_event_win_move_t*)event)->y))
  222. rtgui_thread_ack(event, RTGUI_STATUS_OK);
  223. else
  224. rtgui_thread_ack(event, RTGUI_STATUS_ERROR);
  225. break;
  226. case RTGUI_EVENT_WIN_RESIZE:
  227. rtgui_topwin_resize(((rtgui_event_win_resize_t*)event)->wid,
  228. &(((rtgui_event_win_resize_t*)event)->rect));
  229. break;
  230. case RTGUI_EVENT_UPDATE:
  231. /* handle screen update */
  232. rtgui_server_handle_update((rtgui_event_update_t*)event);
  233. #ifdef RTGUI_USING_MOUSE_CURSOR
  234. /* show cursor */
  235. rtgui_mouse_show_cursor();
  236. #endif
  237. break;
  238. case RTGUI_EVENT_MOUSE_MOTION:
  239. rtgui_server_handle_mouse_motion((rtgui_event_mouse_t*)event);
  240. break;
  241. case RTGUI_EVENT_MOUSE_BUTTON:
  242. rtgui_server_handle_mouse_btn((rtgui_event_mouse_t*)event);
  243. break;
  244. case RTGUI_EVENT_KBD:
  245. rtgui_server_handle_kbd((rtgui_event_kbd_t*)event);
  246. break;
  247. case RTGUI_EVENT_CURRENT_POS:
  248. rtgui_server_handle_current_pos((rtgui_event_current_pos_t*)event);
  249. break;
  250. case RTGUI_EVENT_COMMAND:
  251. break;
  252. }
  253. }
  254. }
  255. }
  256. void rtgui_server_post_event(rtgui_event_t* event, rt_size_t size)
  257. {
  258. rt_mq_send(rtgui_server_mq, event, size);
  259. }
  260. void rtgui_server_init(void)
  261. {
  262. struct rt_thread* rtgui_server_tid;
  263. rtgui_server_tid = rt_thread_create("rtgui",
  264. rtgui_server_entry, RT_NULL,
  265. RTGUI_SVR_THREAD_STACK_SIZE,
  266. RTGUI_SVR_THREAD_PRIORITY,
  267. RTGUI_SVR_THREAD_TIMESLICE);
  268. /* start rtgui server thread */
  269. if(rtgui_server_tid != RT_NULL)
  270. rt_thread_startup(rtgui_server_tid);
  271. }