main.c 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. /*
  2. * Copyright 2024 NXP
  3. * NXP Proprietary. This software is owned or controlled by NXP and may only be used strictly in
  4. * accordance with the applicable license terms. By expressly accepting such terms or by downloading, installing,
  5. * activating and/or otherwise using the software, you are agreeing that you have read, and that you agree to
  6. * comply with and are bound by, such license terms. If you do not agree to be bound by the applicable license
  7. * terms, then you may not retain, install, activate or otherwise use the software.
  8. */
  9. /*********************
  10. * INCLUDES
  11. *********************/
  12. #define _DEFAULT_SOURCE /* needed for usleep() */
  13. #include <stdlib.h>
  14. #include <unistd.h>
  15. #define SDL_MAIN_HANDLED /*To fix SDL's "undefined reference to WinMain" issue*/
  16. #include <SDL2/SDL.h>
  17. #include "lvgl/lvgl.h"
  18. #include "gui_guider.h"
  19. #include "custom.h"
  20. #include "widgets_init.h"
  21. #include <pthread.h>
  22. #include <stdio.h>
  23. #include <string.h>
  24. #if LV_USE_FREEMASTER
  25. #include "external_data_init.h"
  26. #endif
  27. #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
  28. /*********************
  29. * DEFINES
  30. *********************/
  31. #ifndef USE_KEYBOARD
  32. #define USE_KEYBOARD 0
  33. #endif
  34. #ifndef LV_GUIDER_SIMULATOR_WINDOW_ZOOM
  35. #define LV_GUIDER_SIMULATOR_WINDOW_ZOOM 1
  36. #endif
  37. /**********************
  38. * TYPEDEFS
  39. **********************/
  40. /**********************
  41. * STATIC PROTOTYPES
  42. **********************/
  43. static lv_display_t * hal_init(int32_t w, int32_t h);
  44. volatile int keep_running = 0;
  45. /**********************
  46. * STATIC VARIABLES
  47. **********************/
  48. /**********************
  49. * MACROS
  50. **********************/
  51. /**********************
  52. * GLOBAL FUNCTIONS
  53. **********************/
  54. /*********************
  55. * DEFINES
  56. *********************/
  57. /**********************
  58. * TYPEDEFS
  59. **********************/
  60. /**********************
  61. * VARIABLES
  62. **********************/
  63. extern uint16_t simulator_icon[];
  64. lv_ui guider_ui;
  65. #if LV_USE_FREEMASTER
  66. pthread_t thread[2];
  67. pthread_mutex_t jsonrpc_mutex;
  68. pthread_mutex_t lvgl_mutex;
  69. pthread_mutex_t gg_edata_ll_mutex;
  70. pthread_cond_t gg_edata_ll_cond;
  71. #endif
  72. /**********************
  73. * STATIC PROTOTYPES
  74. **********************/
  75. /**********************
  76. * GLOBAL FUNCTIONS
  77. **********************/
  78. int main(int argc, char **argv)
  79. {
  80. #if LV_USE_FREEMASTER
  81. if(argc > 1)
  82. {
  83. int sim_conf(int argc, char *argv[]);
  84. sim_conf(argc, argv);
  85. }
  86. #endif
  87. /* local threads will run */
  88. keep_running = 1;
  89. /*Initialize LVGL*/
  90. lv_init();
  91. /*Initialize the HAL (display, input devices, tick) for LVGL*/
  92. hal_init(LV_HOR_RES_MAX, LV_VER_RES_MAX);
  93. #if LV_USE_FREEMASTER
  94. pthread_mutex_init(&gg_edata_ll_mutex, NULL);
  95. pthread_cond_init(&gg_edata_ll_cond, NULL);
  96. /*Initialize the external data */
  97. external_task_init(&guider_ui);
  98. #endif
  99. setup_ui(&guider_ui);
  100. custom_init(&guider_ui);
  101. #if LV_USE_FREEMASTER
  102. pthread_mutex_init(&jsonrpc_mutex, NULL);
  103. pthread_mutex_init(&lvgl_mutex, NULL);
  104. memset(&thread, 0, sizeof(thread));
  105. /*Create a separate thread to loop the linked list*/
  106. pthread_create(&thread[0], NULL, gg_edata_task_exec, &jsonrpc_mutex);
  107. #endif
  108. while(keep_running) {
  109. #if LV_USE_FREEMASTER
  110. pthread_mutex_lock(&lvgl_mutex);
  111. #endif
  112. /* Periodically call the lv_task handler.
  113. * It could be done in a timer interrupt or an OS task too.*/
  114. lv_timer_handler();
  115. #if LV_USE_VIDEO
  116. video_play(&guider_ui);
  117. #endif
  118. #if LV_USE_FREEMASTER
  119. pthread_mutex_unlock(&lvgl_mutex);
  120. #endif
  121. usleep(5 * 1000);
  122. }
  123. #if LV_USE_FREEMASTER
  124. /* wakeup gg_edata_task_exec thread if it sleeps, let it finish */
  125. pthread_cond_signal(&gg_edata_ll_cond);
  126. /* wait for the gg_edata_task_exec thread*/
  127. pthread_join(thread[0], NULL);
  128. freemaster_disconnect();
  129. #endif
  130. SDL_Quit();
  131. return 0;
  132. }
  133. /**********************
  134. * STATIC FUNCTIONS
  135. **********************/
  136. /**
  137. * Initialize the Hardware Abstraction Layer (HAL) for the LVGL graphics
  138. * library
  139. */
  140. static lv_display_t * hal_init(int32_t w, int32_t h)
  141. {
  142. lv_group_set_default(lv_group_create());
  143. lv_display_t * disp = lv_sdl_window_create(w, h);
  144. lv_sdl_window_set_title(disp, "Simulator (C/C++)");
  145. lv_sdl_window_set_icon(disp, simulator_icon);
  146. lv_sdl_window_set_resizeable(disp, false);
  147. lv_sdl_window_set_zoom(disp, LV_GUIDER_SIMULATOR_WINDOW_ZOOM);
  148. lv_indev_t * mouse = lv_sdl_mouse_create();
  149. lv_indev_set_group(mouse, lv_group_get_default());
  150. lv_indev_set_display(mouse, disp);
  151. lv_display_set_default(disp);
  152. #if USE_KEYBOARD
  153. lv_indev_t * keyboard = lv_sdl_keyboard_create();
  154. lv_indev_set_display(keyboard, disp);
  155. lv_indev_set_group(keyboard, lv_group_get_default());
  156. #endif
  157. return disp;
  158. }
  159. #if LV_USE_FREEMASTER
  160. /**
  161. * Enable simulator to be linked and used as DLL. This function is invoked by
  162. * FreeMASTER from its background thread. This function must finish when
  163. * sim_exit() is called asynchronously.
  164. */
  165. __declspec(dllexport)
  166. int sim_main(int argc, char *argv[])
  167. {
  168. int ret = main(argc, argv);
  169. return ret;
  170. }
  171. /**
  172. * Finish all running threads and terminate the application running as sim_main().
  173. */
  174. __declspec(dllexport)
  175. int sim_exit(void)
  176. {
  177. keep_running = 0;
  178. return 0;
  179. }
  180. /**
  181. * Enable FreeMASTER to configure the simulator before starting it.
  182. * This function is the first one called by the FreeMASTER from its GUI thread.
  183. */
  184. __declspec(dllexport)
  185. int sim_conf(int argc, char *argv[])
  186. {
  187. /* Process the arguments */
  188. if(argc > 0 && argv != NULL)
  189. {
  190. for(int i=0; i<argc; i++)
  191. {
  192. /* --rpcs is used to specify FreeMASTER JSON-RPC server address. */
  193. if(strcmp(argv[i], "--rpcs") == 0)
  194. {
  195. i++;
  196. if(i<argc && strncmp(argv[i], "ws://", 5) == 0)
  197. {
  198. freemaster_server = strdup(argv[i]);
  199. }
  200. }
  201. }
  202. }
  203. return 0;
  204. }
  205. /**
  206. * Enable host application to retrieve DLL information
  207. */
  208. __declspec(dllexport)
  209. const void * sim_info(void)
  210. {
  211. #define SIM_F_RESIZE_UP 0x0001 /* Enable growing size within parent view */
  212. #define SIM_F_RESIZE_DOWN 0x0002 /* Enable shrinking size within parent view */
  213. #define SIM_F_KEEP_ASPECT 0x0004 /* When RESIZE used, preserve aspect ratio */
  214. #define SIM_F_CENTER_H 0x0008 /* Center horizontally */
  215. #define SIM_F_CENTER_V 0x0010 /* Center vertically */
  216. #define SIM_F_CENTER_FORCE 0x0020 /* Keep centered even if parent is smaller (move beyond top/left border) */
  217. #define SIM_F_AUTO_BACKCOLOR 0x0040 /* Determine background color automatically */
  218. typedef struct
  219. {
  220. uint32_t sz;
  221. const char* name;
  222. const char* desc;
  223. const char* copyright;
  224. const char* server;
  225. uint32_t width;
  226. uint32_t height;
  227. uint32_t flags;
  228. uint32_t background;
  229. uint32_t reserved;
  230. } sim_info_t;
  231. /* Constant options: */
  232. static sim_info_t info =
  233. {
  234. .sz = sizeof(sim_info_t),
  235. .name = "NXP GUI-Guider Project",
  236. .desc = "Designed to enable GUI designs created in GG to be hosted in FreeMASTER",
  237. .copyright = "Copyright 2024 NXP",
  238. .server = "",
  239. .width = LV_HOR_RES_MAX,
  240. .height = LV_VER_RES_MAX,
  241. .flags = SIM_F_CENTER_H,
  242. .background = 0,
  243. };
  244. /* Runtime-defined options: */
  245. info.server = freemaster_server;
  246. return &info;
  247. }
  248. #endif