/src/ftk.c

http://ftk.googlecode.com/ · C · 456 lines · 351 code · 76 blank · 29 comment · 66 complexity · c07ceabd07717b491f77e3ee7c2dc69e MD5 · raw file

  1. /*
  2. * File: ftk.c
  3. * Author: Li XianJing <xianjimli@hotmail.com>
  4. * Brief: ftk global init, mainloop and deinit functions.
  5. *
  6. * Copyright (c) 2009 - 2010 Li XianJing <xianjimli@hotmail.com>
  7. *
  8. * Licensed under the Academic Free License version 2.1
  9. *
  10. * This program is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License as published by
  12. * the Free Software Foundation; either version 2 of the License, or
  13. * (at your option) any later version.
  14. *
  15. * This program is distributed in the hope that it will be useful,
  16. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. * GNU General Public License for more details.
  19. *
  20. * You should have received a copy of the GNU General Public License
  21. * along with this program; if not, write to the Free Software
  22. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  23. */
  24. /*
  25. * History:
  26. * ================================================================
  27. * 2009-10-03 Li XianJing <xianjimli@hotmail.com> created
  28. *
  29. */
  30. #include "ftk.h"
  31. #include "ftk_util.h"
  32. #include "ftk_backend.h"
  33. #include "ftk_globals.h"
  34. #include "ftk_main_loop.h"
  35. #include "ftk_status_item.h"
  36. #include "ftk_status_panel.h"
  37. #include "ftk_bitmap_factory.h"
  38. #include "ftk_display_rotate.h"
  39. #include "ftk_allocator_default.h"
  40. #include "ftk_wnd_manager_default.h"
  41. #include "ftk_input_method_preeditor_default.h"
  42. #ifdef FTK_MEMORY_PROFILE
  43. #include "ftk_allocator_profile.h"
  44. #define FTK_ALLOC_PROFILE(a) ftk_allocator_profile_create(a)
  45. #else
  46. #define FTK_ALLOC_PROFILE(a) a
  47. #endif
  48. #define quit_if_fail(p, msg) \
  49. if(!(p))\
  50. {\
  51. ftk_deinit();\
  52. ftk_loge(msg);\
  53. exit(0);\
  54. }
  55. static void ftk_init_panel(void);
  56. static Ret ftk_init_bitmap_factory(void)
  57. {
  58. ftk_set_bitmap_factory(ftk_bitmap_factory_create());
  59. quit_if_fail(ftk_default_bitmap_factory(), "Init bitmap factory failed.\n");
  60. return RET_OK;
  61. }
  62. static Ret ftk_init_theme(const char* theme)
  63. {
  64. char filename[FTK_MAX_PATH + 1] = {0};
  65. ftk_set_theme(ftk_theme_create(theme == NULL));
  66. if(theme != NULL)
  67. {
  68. #if !defined(ANDROID) && !defined(ANDROID_NDK)
  69. ftk_strs_cat(filename, FTK_MAX_PATH,
  70. ftk_config_get_data_dir(ftk_default_config()), "/theme/", theme, "/theme.xml", NULL);
  71. #else
  72. ftk_strs_cat(filename, FTK_MAX_PATH,
  73. ftk_config_get_data_dir(ftk_default_config()), "/theme/", theme, "/theme.wav", NULL);
  74. #endif
  75. ftk_normalize_path(filename);
  76. ftk_theme_parse_file(ftk_default_theme(), filename);
  77. }
  78. quit_if_fail(ftk_default_theme(), "Init theme failed.\n");
  79. ftk_set_animation_trigger(ftk_theme_get_animation_trigger(ftk_default_theme()));
  80. return RET_OK;
  81. }
  82. void ftk_deinit(void)
  83. {
  84. if(ftk_default_input_method_preeditor() != NULL)
  85. {
  86. ftk_input_method_preeditor_destroy(ftk_default_input_method_preeditor());
  87. }
  88. if(ftk_default_wnd_manager() != NULL)
  89. {
  90. ftk_wnd_manager_destroy(ftk_default_wnd_manager());
  91. }
  92. if(ftk_default_main_loop() != NULL)
  93. {
  94. ftk_main_loop_destroy(ftk_default_main_loop());
  95. }
  96. if(ftk_default_sources_manager() != NULL)
  97. {
  98. ftk_sources_manager_destroy(ftk_default_sources_manager());
  99. }
  100. if(ftk_default_bitmap_factory() != NULL)
  101. {
  102. ftk_bitmap_factory_destroy(ftk_default_bitmap_factory());
  103. }
  104. if(ftk_default_text_layout() != NULL)
  105. {
  106. ftk_text_layout_destroy(ftk_default_text_layout());
  107. }
  108. if(ftk_default_display() != NULL)
  109. {
  110. ftk_display_destroy(ftk_default_display());
  111. }
  112. if(ftk_default_theme() != NULL)
  113. {
  114. ftk_theme_destroy(ftk_default_theme());
  115. }
  116. if(ftk_shared_canvas() != NULL)
  117. {
  118. ftk_canvas_destroy(ftk_shared_canvas());
  119. }
  120. if(ftk_default_input_method_manager() != NULL)
  121. {
  122. ftk_input_method_manager_destroy(ftk_default_input_method_manager());
  123. }
  124. if(ftk_default_config() != NULL)
  125. {
  126. ftk_config_destroy(ftk_default_config());
  127. }
  128. ftk_platform_deinit();
  129. #ifndef USE_STD_MALLOC
  130. if(ftk_default_allocator() != NULL)
  131. {
  132. ftk_allocator_destroy(ftk_default_allocator());
  133. }
  134. #endif
  135. ftk_logd("%s: ftk exit.\n", __func__);
  136. ftk_clear_globals();
  137. return;
  138. }
  139. #ifndef USE_LINUX_DFB
  140. static Ret ftk_move_cursor(void* ctx, void* obj)
  141. {
  142. FtkEvent* event = (FtkEvent*)obj;
  143. if(event->type == FTK_EVT_MOUSE_MOVE)
  144. {
  145. ftk_sprite_move((FtkSprite*)ctx, event->u.mouse.x, event->u.mouse.y);
  146. }
  147. else if(event->type == FTK_EVT_DISABLE_CURSOR)
  148. {
  149. ftk_sprite_show((FtkSprite*)ctx, 0);
  150. }
  151. else if(event->type == FTK_EVT_ENABLE_CURSOR)
  152. {
  153. ftk_sprite_show((FtkSprite*)ctx, 1);
  154. }
  155. return RET_OK;
  156. }
  157. static Ret ftk_enable_curosr(void)
  158. {
  159. FtkSprite* sprite = ftk_sprite_create();
  160. FtkBitmap* icon = ftk_theme_load_image(ftk_default_theme(), "cursor"FTK_STOCK_IMG_SUFFIX);
  161. ftk_sprite_set_icon(sprite, icon);
  162. ftk_sprite_show(sprite, 1);
  163. ftk_wnd_manager_add_global_listener(ftk_default_wnd_manager(), ftk_move_cursor, sprite);
  164. return RET_OK;
  165. }
  166. #endif
  167. Ret ftk_init(int argc, char* argv[])
  168. {
  169. FtkColor bg = {0};
  170. FtkConfig* config = NULL;
  171. FtkDisplay* display = NULL;
  172. static int ftk_inited = 0;
  173. if(ftk_inited)
  174. {
  175. return RET_OK;
  176. }
  177. else
  178. {
  179. ftk_inited = 1;
  180. }
  181. ftk_clear_globals();
  182. PROFILE_START();
  183. #ifndef USE_STD_MALLOC
  184. ftk_set_allocator(FTK_ALLOC_PROFILE(ftk_allocator_default_create()));
  185. quit_if_fail(ftk_default_allocator(), "Init allocator failed.\n");
  186. #endif
  187. ftk_platform_init(argc, argv);
  188. config = ftk_config_create();
  189. ftk_set_config(config);
  190. ftk_config_init(config, argc, argv);
  191. quit_if_fail(ftk_default_config(), "Init config failed.\n");
  192. PROFILE_END("config init");
  193. ftk_set_text_layout(ftk_text_layout_create());
  194. PROFILE_START();
  195. ftk_set_sources_manager(ftk_sources_manager_create(64));
  196. ftk_set_main_loop(ftk_main_loop_create(ftk_default_sources_manager()));
  197. ftk_set_wnd_manager(ftk_wnd_manager_default_create(ftk_default_main_loop()));
  198. quit_if_fail(ftk_default_wnd_manager(), "Init windows manager failed.\n");
  199. PROFILE_END("source main loop wnd manager init");
  200. ftk_init_bitmap_factory();
  201. PROFILE_START();
  202. ftk_init_theme(ftk_config_get_theme(config));
  203. ftk_backend_init(argc, argv);
  204. PROFILE_END("theme and backend init");
  205. display = ftk_display_rotate_create(ftk_default_display(), ftk_config_get_rotate(ftk_default_config()));
  206. ftk_set_display(display);
  207. quit_if_fail(ftk_default_display(), "Init display failed.\n");
  208. PROFILE_START();
  209. bg.a = 0xff;
  210. ftk_set_shared_canvas(ftk_canvas_create(ftk_display_width(display), ftk_display_height(display), &bg));
  211. ftk_logd("canvas init: %d %d\n", ftk_display_width(display), ftk_display_height(display));
  212. PROFILE_END("canvas init");
  213. PROFILE_START();
  214. ftk_set_input_method_manager(ftk_input_method_manager_create());
  215. ftk_set_input_method_preeditor(ftk_input_method_preeditor_default_create());
  216. quit_if_fail(ftk_default_input_method_manager(), "Init input method failed.\n");
  217. PROFILE_END("input method init");
  218. PROFILE_START();
  219. if(ftk_config_get_enable_status_bar(config))
  220. {
  221. ftk_init_panel();
  222. }
  223. PROFILE_END("panel init");
  224. if(ftk_config_get_enable_cursor(config))
  225. {
  226. #ifndef USE_LINUX_DFB
  227. ftk_enable_curosr();
  228. #endif
  229. }
  230. return RET_OK;
  231. }
  232. Ret ftk_run(void)
  233. {
  234. Ret ret = ftk_main_loop_run(ftk_default_main_loop());
  235. ftk_deinit();
  236. return ret;
  237. }
  238. void ftk_quit(void)
  239. {
  240. if(ftk_default_main_loop() != NULL)
  241. {
  242. ftk_main_loop_quit(ftk_default_main_loop());
  243. ftk_logd("%s\n", __func__);
  244. }
  245. return;
  246. }
  247. #define IDC_TITLE_ITEM 1000
  248. #define IDC_ICON_ITEM 1001
  249. #define IDC_CLOSE_ITEM 1002
  250. static Ret on_wnd_manager_global_event(void* ctx, void* obj)
  251. {
  252. Ret ret = RET_OK;
  253. FtkEvent* event = (FtkEvent*)obj;
  254. FtkWidget* panel = NULL;
  255. FtkWidget* top_window = NULL;
  256. FtkWidget* close_widget = NULL;
  257. FtkWidget* title_widget = NULL;
  258. if(event->type != FTK_EVT_TOP_WND_CHANGED
  259. && event->type != FTK_EVT_WND_CONFIG_CHANGED)
  260. {
  261. return RET_OK;
  262. }
  263. if(ftk_widget_type((FtkWidget*)event->widget) != FTK_WINDOW)
  264. {
  265. return RET_OK;
  266. }
  267. panel = ftk_default_status_panel();
  268. close_widget = ftk_widget_lookup(panel, IDC_CLOSE_ITEM);
  269. title_widget = ftk_widget_lookup(panel, IDC_TITLE_ITEM);
  270. switch(event->type)
  271. {
  272. case FTK_EVT_TOP_WND_CHANGED:
  273. {
  274. top_window = (FtkWidget*)event->widget;
  275. if(top_window != NULL)
  276. {
  277. ftk_widget_set_text(title_widget, ftk_widget_get_text(top_window));
  278. ftk_logd("top_window changed: %s\n", ftk_widget_get_text(top_window));
  279. }
  280. else
  281. {
  282. ftk_widget_set_text(title_widget, NULL);
  283. }
  284. ftk_widget_set_user_data(title_widget, NULL, top_window);
  285. ret = RET_REMOVE;
  286. break;
  287. }
  288. case FTK_EVT_WND_CONFIG_CHANGED:
  289. {
  290. top_window = (FtkWidget*)ftk_widget_user_data(title_widget);
  291. if(top_window == event->widget)
  292. {
  293. ftk_widget_set_text(title_widget, ftk_widget_get_text(top_window));
  294. }
  295. ftk_logd("%s: config changed: %p %p\n", __func__, top_window, event->widget);
  296. ret = RET_REMOVE;
  297. break;
  298. }
  299. default:break;
  300. }
  301. if(top_window != NULL && close_widget != NULL)
  302. {
  303. ftk_widget_show(close_widget, !ftk_widget_has_attr(top_window, FTK_ATTR_IGNORE_CLOSE));
  304. }
  305. return ret;
  306. }
  307. static Ret button_close_top_clicked(void* ctx, void* obj)
  308. {
  309. FtkWidget* panel = ftk_default_status_panel();
  310. FtkWidget* title_widget = ftk_widget_lookup(panel, IDC_TITLE_ITEM);
  311. FtkWidget* top_window = (FtkWidget*)ftk_widget_user_data(title_widget);
  312. if(top_window != NULL && ftk_widget_type(top_window) == FTK_WINDOW)
  313. {
  314. if(!ftk_widget_has_attr(top_window, FTK_ATTR_IGNORE_CLOSE))
  315. {
  316. ftk_widget_set_user_data(title_widget, NULL, NULL);
  317. ftk_logd("%s: close window %s\n", __func__, ftk_widget_get_text(top_window));
  318. ftk_widget_unref(top_window);
  319. }
  320. else
  321. {
  322. ftk_logd("%s: the top window has attribute FTK_ATTR_IGNORE_CLOSE\n", __func__);
  323. }
  324. }
  325. else
  326. {
  327. ftk_logd("%s: not normal window.\n", __func__);
  328. }
  329. return RET_OK;
  330. }
  331. #define min(a,b) ((a) < (b) ? (a) : (b))
  332. static void ftk_init_panel(void)
  333. {
  334. FtkGc gc;
  335. FtkWidget* item = NULL;
  336. FtkWidget* panel = ftk_status_panel_create(FTK_STATUS_PANEL_HEIGHT);
  337. size_t width = ftk_widget_width(panel);
  338. ftk_set_status_panel(panel);
  339. quit_if_fail(ftk_default_status_panel(), "Init status panel failed.\n");
  340. memset(&gc, 0x00, sizeof(gc));
  341. gc.mask = FTK_GC_BITMAP;
  342. gc.bitmap = ftk_theme_load_image(ftk_default_theme(), "status-bg"FTK_STOCK_IMG_SUFFIX);
  343. ftk_widget_set_gc(panel, FTK_WIDGET_NORMAL, &gc);
  344. ftk_widget_set_gc(panel, FTK_WIDGET_ACTIVE, &gc);
  345. ftk_widget_set_gc(panel, FTK_WIDGET_FOCUSED, &gc);
  346. ftk_gc_reset(&gc);
  347. item = ftk_status_item_create(panel, -100, 32);
  348. ftk_widget_set_id(item, IDC_CLOSE_ITEM);
  349. gc.bitmap = ftk_theme_load_image(ftk_default_theme(), "close-32"FTK_STOCK_IMG_SUFFIX);
  350. if(gc.bitmap != NULL)
  351. {
  352. gc.mask = FTK_GC_BITMAP;
  353. ftk_widget_set_gc(item, FTK_WIDGET_NORMAL, &gc);
  354. ftk_widget_set_gc(item, FTK_WIDGET_FOCUSED, &gc);
  355. ftk_gc_reset(&gc);
  356. gc.mask = FTK_GC_BITMAP;
  357. gc.bitmap = ftk_theme_load_image(ftk_default_theme(), "close-pressed-32"FTK_STOCK_IMG_SUFFIX);
  358. ftk_widget_set_gc(item, FTK_WIDGET_ACTIVE, &gc);
  359. ftk_gc_reset(&gc);
  360. }
  361. ftk_status_item_set_clicked_listener(item, button_close_top_clicked, NULL);
  362. gc.bitmap = ftk_theme_load_image(ftk_default_theme(), "flag-32"FTK_STOCK_IMG_SUFFIX);
  363. item = ftk_status_item_create(panel, 1, gc.bitmap ? min(ftk_bitmap_width(gc.bitmap), 100) : 32);
  364. ftk_widget_set_id(item, IDC_ICON_ITEM);
  365. if(gc.bitmap != NULL)
  366. {
  367. gc.mask = FTK_GC_BITMAP;
  368. ftk_widget_set_gc(item, FTK_WIDGET_NORMAL, &gc);
  369. ftk_widget_set_gc(item, FTK_WIDGET_ACTIVE, &gc);
  370. ftk_widget_set_gc(item, FTK_WIDGET_FOCUSED, &gc);
  371. ftk_gc_reset(&gc);
  372. }
  373. ftk_widget_show(item, 1);
  374. item = ftk_status_item_create(panel, 2, width/2);
  375. ftk_widget_set_id(item, IDC_TITLE_ITEM);
  376. ftk_widget_show(item, 1);
  377. ftk_wnd_manager_add_global_listener(ftk_default_wnd_manager(), on_wnd_manager_global_event, NULL);
  378. ftk_widget_show(panel, 1);
  379. return;
  380. }