Embedded SDK
Embedded SDK
ux_bagl.h
Go to the documentation of this file.
1 
2 /*******************************************************************************
3  * Ledger Nano S - Secure firmware
4  * (c) 2022 Ledger
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  ********************************************************************************/
18 
19 #pragma once
20 
21 #if defined(HAVE_BOLOS)
22 #include "bolos_privileged_ux.h"
23 #endif // HAVE_BOLOS
24 
25 #include "bolos_target.h"
26 #include "lcx_ecfp.h"
27 #include "os_math.h"
28 #include "os_ux.h"
29 #include "os_task.h"
30 #include "os_screen.h"
31 
32 #ifndef HAVE_BOLOS_UX
33 #ifndef HAVE_UX_FLOW
34 #define COMPLIANCE_UX_160
35 #define HAVE_UX_LEGACY
36 #endif // HAVE_UX_FLOW
37 #endif // HAVE_BOLOS_UX
38 
39 #include "ux_layouts.h"
40 #include "ux_flow_engine.h"
41 #if defined(HAVE_INDEXED_STRINGS)
42 #include "ux_loc.h"
43 #include "bolos_ux_loc_strings.h"
44 #include "ux_loc_layouts.h"
45 #include "ux_loc_flow_engine.h"
46 #endif // defined(HAVE_INDEXED_STRINGS)
47 
48 #include "bagl.h"
49 #include <string.h>
50 
51 typedef struct bagl_element_e bagl_element_t;
52 
53 // callback returns NULL when element must not be redrawn (with a changing color or what so ever)
54 typedef const bagl_element_t *(*bagl_element_callback_t)(const bagl_element_t *element);
55 
56 // a graphic element is an element with defined text and actions depending on user touches
58  bagl_component_t component;
59 
60 #if defined(HAVE_INDEXED_STRINGS)
61  // Nameless union, to be able to access one member of the union or the other.
62  // No space won when using index with bagl_element_e, but headaches are avoided :)
63  union {
64  const char *text;
66  };
67 #else // defined(HAVE_INDEXED_STRINGS)
68  const char *text;
69 #endif // defined(HAVE_INDEXED_STRINGS)
70 };
71 
72 // When not using indexed strings, some functions can be inlined, to save space
73 #if !defined(HAVE_INDEXED_STRINGS)
74 #define STATIC_IF_NOT_INDEXED static
75 #else
76 #define STATIC_IF_NOT_INDEXED
77 #endif
78 
79 // touch management helper function (callback the call with the element for the given position,
80 // taking into account touch release)
81 void io_seproxyhal_touch(const bagl_element_t *elements,
82  unsigned short element_count,
83  unsigned short x,
84  unsigned short y,
85  unsigned char event_kind);
87  unsigned short element_count,
88  unsigned short x,
89  unsigned short y,
90  unsigned char event_kind,
91  bagl_element_callback_t before_display);
92 // callback to be implemented by the se
93 void io_seproxyhal_touch_callback(const bagl_element_t *element, unsigned char event);
94 
99 
100 // meta type to share amongst all multiline layouts
102  const char *lines[5];
104 
105 // meta type to share amongst all icon + multiline layouts
107  const bagl_icon_details_t *icon;
108  const char *lines[5];
110 
111 #if defined(HAVE_INDEXED_STRINGS)
112 const bagl_element_t *ux_loc_layout_strings_prepro(const bagl_element_t *element);
113 
114 // Prototypes related to localization
115 const bagl_icon_details_t *get_glyphs_icon(unsigned char id);
116 const char *get_string_buffer(unsigned char id);
117 const char *get_ux_loc_string(UX_LOC_STRINGS_INDEX index);
118 #endif // defined(HAVE_INDEXED_STRINGS)
119 #if defined(HAVE_LANGUAGE_PACK)
120 void bolos_ux_select_language(uint16_t language);
121 void bolos_ux_refresh_language(void);
122 
123 typedef struct ux_loc_language_pack_infos {
124  unsigned char available;
125 
126 } UX_LOC_LANGUAGE_PACK_INFO;
127 
128 // To populate infos about language packs
129 SYSCALL PERMISSION(APPLICATION_FLAG_BOLOS_UX) void list_language_packs(
130  UX_LOC_LANGUAGE_PACK_INFO *packs PLENGTH(NB_LANG * sizeof(UX_LOC_LANGUAGE_PACK_INFO)));
131 SYSCALL PERMISSION(APPLICATION_FLAG_BOLOS_UX) const LANGUAGE_PACK *get_language_pack(
132  unsigned int language);
133 #endif // defined(HAVE_LANGUAGE_PACK)
134 
135 #ifndef BUTTON_FAST_THRESHOLD_CS
136 #define BUTTON_FAST_THRESHOLD_CS 8 // x100MS
137 #endif // BUTTON_FAST_THRESHOLD_CS
138 #ifndef BUTTON_FAST_ACTION_CS
139 #define BUTTON_FAST_ACTION_CS 3 // x100MS
140 #endif // BUTTON_FAST_ACTION_CS
141 
142 typedef unsigned int (*button_push_callback_t)(unsigned int button_mask,
143  unsigned int button_mask_counter);
144 #define BUTTON_LEFT 1
145 #define BUTTON_RIGHT 2
146 // flag set when fast threshold is reached and above
147 #define BUTTON_EVT_FAST 0x40000000UL
148 #define BUTTON_EVT_RELEASED 0x80000000UL
150  unsigned int new_button_mask);
151 
152 // hal point (if application has to reprocess elements)
154 
155 // Helper function that give a realistic timing of scrolling for label with text larger than screen
157  unsigned int average_char_width);
159  const char *str,
160  unsigned int average_char_width);
161 
162 // default version to be called by ::io_seproxyhal_display if nothing to be done by the application
164 
165 #ifndef UX_STACK_SLOT_COUNT
166 #define UX_STACK_SLOT_COUNT 1
167 #endif // UX_STACK_SLOT_COUNT
168 
169 #ifndef UX_STACK_SLOT_ARRAY_COUNT
170 #define UX_STACK_SLOT_ARRAY_COUNT 1
171 #endif // UX_STACK_SLOT_ARRAY_COUNT
172 
173 typedef unsigned int (*callback_int_t)(unsigned int);
174 typedef void (*asynchmodal_end_callback_t)(unsigned int ux_status);
175 
176 typedef struct ux_stack_slot_s ux_stack_slot_t;
177 
181 typedef struct ux_state_s ux_state_t;
182 
183 // returns 0 if the element_array is not found, else stack_index + 1 if the element_array is found
184 unsigned int ux_stack_is_element_array_present(const bagl_element_t *element_array);
185 
186 // push if a slot exists and returns the new slot, otherwise returns the top spot
187 unsigned int ux_stack_push(void);
188 
189 // pops the top slot exists and returns the new slot, then returns the new top slot
190 unsigned int ux_stack_pop(void);
191 
192 // inserts a new slot at the stack_slot
193 void ux_stack_insert(unsigned int stack_slot); // insert slot space as given index
194 
195 // removes the slot at the stack_slot
196 void ux_stack_remove(unsigned int stack_slot);
197 
198 void ux_stack_init(unsigned int stack_slot);
199 
200 // display the slot at index stack_slot
201 void ux_stack_display(unsigned int stack_slot);
202 
206 void ux_stack_al_display_next_element(unsigned int stack_slot);
207 
208 // redisplay the top stacked slot.
209 void ux_stack_redisplay(void);
210 
212 #ifdef HAVE_SE_SCREEN
213 void ux_stack_display_elements(ux_stack_slot_t *slot);
214 #endif // HAVE_SE_SCREEN
215 
216 #ifdef HAVE_UX_LEGACY
217 // a menu callback is called with a given userid provided within the menu entry to allow for fast
218 // switch of the action to be taken
219 typedef void (*ux_menu_callback_t)(unsigned int userid);
220 
221 typedef struct ux_menu_entry_s ux_menu_entry_t;
222 
227  // other menu shown when validated
229  // callback called when entered (not executed when a menu entry is present)
231  // user identifier to allow for indirection in a separated table and mutualise even more menu
232  // handling, passed to the given callback is any
233  unsigned int userid;
234  const bagl_icon_details_t *icon;
235  const char *line1;
236  const char *line2;
237  char text_x;
238  char icon_x;
239 };
240 
241 typedef const bagl_element_t *(*ux_menu_preprocessor_t)(const ux_menu_entry_t *,
242  bagl_element_t *element);
243 typedef const ux_menu_entry_t *(*ux_menu_iterator_t)(unsigned int entry_idx);
244 typedef struct ux_menu_state_s {
246  unsigned int menu_entries_count;
247  unsigned int current_entry;
251 
252 // a menu callback is called with a given userid provided within the menu entry to allow for fast
253 // switch of the action to be taken
254 typedef void (*ux_turner_callback_t)(void);
255 
256 typedef struct ux_turner_step_s {
257  const bagl_icon_details_t *icon;
258  unsigned short fontid1;
259  const char *line1;
260  unsigned short fontid2;
261  const char *line2;
262  char text_x;
263  char icon_x;
264  unsigned int next_step_ms;
266 
267 typedef struct ux_turner_state_s {
269  unsigned int steps_count;
270  unsigned int current_step;
272  unsigned int elapsed_ms;
274 #endif // HAVE_UX_LEGACY
275 
277  // arrays of element to be displayed (to automate when dealing with static and dynamic elements)
279  unsigned char element_arrays_count;
280  unsigned short element_index;
281  // unsigned char displayed;
282  struct {
284  unsigned char element_array_count;
286 
287 #if defined(HAVE_UX_FLOW)
288  callback_int_t displayed_callback;
289 #endif // defined(HAVE_UX_FLOW)
290  // callback called before the screen callback to change the keyboard face
293 
295  unsigned int ticker_value;
296  unsigned int ticker_interval;
297 };
298 
299 struct ux_state_s {
300  unsigned char stack_count; // initialized @0 by the bolos ux initialize
301  bolos_task_status_t exit_code;
302 
303 #ifdef HAVE_BLE
305 #endif // HAVE_BLE
306 
307 #ifdef HAVE_UX_FLOW
308  // global context, therefore, don't allow for multiple paging overlaid in a graphic stack
309  ux_layout_paging_state_t layout_paging;
310 
311  // the flow for each stack slot
313 
314 #endif // HAVE_UX_FLOW
315 
316 #if defined(HAVE_UX_FLOW)
317  // after an int to make sure it's aligned
318  char string_buffer[MAX(128, sizeof(bagl_icon_details_t) - 1)];
319 #endif // defined(HAVE_UX_FLOW)
320 
322 
323  // unified arrays
324  // maxstack: [onboarding/dashboard/settings] | pairing | pin | batterylow | batterycrit |
325  // screensaver
327 
328 #ifdef HAVE_UX_FLOW
329  // for menulist display
330  unsigned int menulist_current;
331  ux_layout_strings_params_t menulist_params;
332  list_item_value_t menulist_getter;
333  list_item_select_t menulist_selector;
334 #endif // HAVE_UX_FLOW
335 
336 #ifdef COMPLIANCE_UX_160
337  bolos_ux_params_t params;
338 #endif // COMPLIANCE_UX_160
339 
341 };
342 
343 #ifdef COMPLIANCE_UX_160
344 
345 #define G_ux ux
346 #define G_ux_params ux.params
347 #define callback_interval_ms stack[0].ticker_interval
348 #define UX_INIT() \
349  memset(&G_ux, 0, sizeof(G_ux)); \
350  ux_stack_push();
351 extern ux_state_t G_ux;
352 
353 #else // COMPLIANCE_UX_160
354 
355 extern ux_state_t G_ux;
356 #if !defined(APP_UX)
357 extern bolos_ux_params_t G_ux_params;
358 #endif // !defined(APP_UX)
359 
363 #define UX_INIT() memset(&G_ux, 0, sizeof(G_ux));
364 
365 #endif // COMPLIANCE_UX_160
366 
373 #ifdef HAVE_SE_SCREEN
374 #define UX_DISPLAY_NEXT_ELEMENT() \
375  if (G_ux.stack[0].element_arrays[0].element_array \
376  && G_ux.stack[0].element_index < G_ux.stack[0].element_arrays[0].element_array_count \
377  && (os_perso_isonboarded() != BOLOS_UX_OK \
378  || os_global_pin_is_validated() == BOLOS_UX_OK)) { \
379  while (G_ux.stack[0].element_index \
380  < G_ux.stack[0].element_arrays[0].element_array_count) { \
381  const bagl_element_t *element \
382  = &G_ux.stack[0].element_arrays[0].element_array[G_ux.stack[0].element_index]; \
383  if (!G_ux.stack[0].screen_before_element_display_callback \
384  || (element = G_ux.stack[0].screen_before_element_display_callback(element))) { \
385  if ((unsigned int) element \
386  == 1) { /*backward compat with coding to avoid smashing everything*/ \
387  element = &G_ux.stack[0] \
388  .element_arrays[0] \
389  .element_array[G_ux.stack[0].element_index]; \
390  } \
391  io_seproxyhal_display(element); \
392  } \
393  G_ux.stack[0].element_index++; \
394  } \
395  if (G_ux.stack[0].element_index == G_ux.stack[0].element_arrays[0].element_array_count) { \
396  screen_update(); \
397  } \
398  }
399 #else // HAVE_SE_SCREEN
400 #define UX_DISPLAY_NEXT_ELEMENT() \
401  while (G_ux.stack[0].element_arrays[0].element_array \
402  && G_ux.stack[0].element_index < G_ux.stack[0].element_arrays[0].element_array_count \
403  && !io_seproxyhal_spi_is_status_sent() \
404  && (os_perso_isonboarded() != BOLOS_UX_OK \
405  || os_global_pin_is_validated() == BOLOS_UX_OK)) { \
406  const bagl_element_t *element \
407  = &G_ux.stack[0].element_arrays[0].element_array[G_ux.stack[0].element_index]; \
408  if (!G_ux.stack[0].screen_before_element_display_callback \
409  || (element = G_ux.stack[0].screen_before_element_display_callback(element))) { \
410  if ((unsigned int) element \
411  == 1) { /*backward compat with coding to avoid smashing everything*/ \
412  element \
413  = &G_ux.stack[0].element_arrays[0].element_array[G_ux.stack[0].element_index]; \
414  } \
415  io_seproxyhal_display(element); \
416  } \
417  G_ux.stack[0].element_index++; \
418  }
419 #endif // HAVE_SE_SCREEN
420 
421 #ifdef HAVE_BLE
426 #define UX_FORWARD_EVENT_REDRAWCB(bypasspincheck, \
427  G_ux_params, \
428  G_ux, \
429  os_ux, \
430  os_sched_last_status, \
431  callback, \
432  redraw_cb, \
433  ignoring_app_if_ux_busy) \
434  G_ux_params.ux_id = BOLOS_UX_EVENT; \
435  G_ux_params.len = 0; \
436  os_ux(&G_ux_params); \
437  G_ux_params.len = os_sched_last_status(TASK_BOLOS_UX); \
438  if (G_ux.asynchmodal_end_callback \
439  && os_ux_get_status(BOLOS_UX_ASYNCHMODAL_PAIRING_REQUEST) != 0) { \
440  asynchmodal_end_callback_t cb = G_ux.asynchmodal_end_callback; \
441  G_ux.asynchmodal_end_callback = NULL; \
442  cb(os_ux_get_status(BOLOS_UX_ASYNCHMODAL_PAIRING_REQUEST)); \
443  G_ux_params.len = BOLOS_UX_REDRAW; \
444  } \
445  if (G_ux_params.len == BOLOS_UX_REDRAW) { \
446  redraw_cb; \
447  } \
448  else if (!ignoring_app_if_ux_busy \
449  || (G_ux_params.len != BOLOS_UX_IGNORE && G_ux_params.len != BOLOS_UX_CONTINUE)) { \
450  callback; \
451  }
452 
453 #else // HAVE_BLE
454 
459 #define UX_FORWARD_EVENT_REDRAWCB(bypasspincheck, \
460  G_ux_params, \
461  G_ux, \
462  os_ux, \
463  os_sched_last_status, \
464  callback, \
465  redraw_cb, \
466  ignoring_app_if_ux_busy) \
467  G_ux_params.ux_id = BOLOS_UX_EVENT; \
468  G_ux_params.len = 0; \
469  os_ux(&G_ux_params); \
470  G_ux_params.len = os_sched_last_status(TASK_BOLOS_UX); \
471  if (G_ux_params.len == BOLOS_UX_REDRAW) { \
472  redraw_cb; \
473  } \
474  else if (!ignoring_app_if_ux_busy \
475  || (G_ux_params.len != BOLOS_UX_IGNORE && G_ux_params.len != BOLOS_UX_CONTINUE)) { \
476  callback; \
477  }
478 #endif // HAVE_BLE
479 
485 #define UX_WAKE_UP() \
486  G_ux_params.ux_id = BOLOS_UX_WAKE_UP; \
487  G_ux_params.len = 0; \
488  os_ux(&G_ux_params); \
489  G_ux_params.len = os_sched_last_status(TASK_BOLOS_UX);
490 
494 #define UX_REDISPLAY_REQUEST() \
495  io_seproxyhal_init_ux(); \
496  io_seproxyhal_init_button(); \
497  G_ux.stack[0].element_index = 0;
498 
502 #define UX_REDISPLAY_IDX(index) \
503  io_seproxyhal_init_ux(); \
504  io_seproxyhal_init_button(); /*ensure to avoid release of a button from a nother screen to \
505  mess up with the redisplayed screen */ \
506  G_ux.stack[0].element_index = index; \
507  /* REDRAW is redisplay already, use os_ux return value to check */ \
508  G_ux_params.len = os_sched_last_status(TASK_BOLOS_UX); \
509  if (G_ux_params.len != BOLOS_UX_IGNORE && G_ux_params.len != BOLOS_UX_CONTINUE) { \
510  UX_DISPLAY_NEXT_ELEMENT(); \
511  }
512 
516 #define UX_REDISPLAY() UX_REDISPLAY_IDX(0)
517 
518 #define UX_DISPLAY(elements_array, preprocessor) \
519  G_ux.stack[0].element_arrays[0].element_array = elements_array; \
520  G_ux.stack[0].element_arrays[0].element_array_count \
521  = sizeof(elements_array) / sizeof(elements_array[0]); \
522  G_ux.stack[0].button_push_callback = elements_array##_button; \
523  G_ux.stack[0].screen_before_element_display_callback = preprocessor; \
524  UX_WAKE_UP(); \
525  UX_REDISPLAY();
526 
531 #define UX_DISPLAY_REQUEST(elements_array, preprocessor) \
532  G_ux.stack[0].element_arrays[0].element_array = elements_array; \
533  G_ux.stack[0].element_arrays[0].element_array_count \
534  = sizeof(elements_array) / sizeof(elements_array[0]); \
535  G_ux.stack[0].button_push_callback = elements_array##_button; \
536  G_ux.stack[0].screen_before_element_display_callback = preprocessor; \
537  UX_WAKE_UP();
538 
543 #define UX_CALLBACK_SET_INTERVAL(ms) G_ux.stack[0].ticker_value = ms;
544 
549 #define UX_FORWARD_EVENT(callback, ignoring_app_if_ux_busy) \
550  UX_FORWARD_EVENT_REDRAWCB(0, \
551  G_ux_params, \
552  G_io_asynch_ux_callback, \
553  os_ux, \
554  os_sched_last_status, \
555  callback, \
556  UX_REDISPLAY(), \
557  ignoring_app_if_ux_busy);
558 
559 #define UX_CONTINUE_DISPLAY_APP(displayed_callback) \
560  UX_DISPLAY_NEXT_ELEMENT(); \
561  /* all items have been displayed */ \
562  if (G_ux.stack[0].element_index >= G_ux.stack[0].element_arrays[0].element_array_count \
563  && !io_seproxyhal_spi_is_status_sent()) { \
564  displayed_callback \
565  }
566 
570 #define UX_DISPLAYED_EVENT(displayed_callback) \
571  UX_FORWARD_EVENT({ UX_CONTINUE_DISPLAY_APP(displayed_callback); }, 1)
572 
576 #define UX_DISPLAYED() \
577  (G_ux.stack[0].element_index >= G_ux.stack[0].element_arrays[0].element_array_count)
578 
583 #ifdef HAVE_SE_SCREEN
584 #define UX_WAIT_DISPLAYED() \
585  while (!UX_DISPLAYED()) { \
586  UX_DISPLAY_NEXT_ELEMENT(); \
587  }
588 #else
589 #define UX_WAIT_DISPLAYED() \
590  while (!UX_DISPLAYED()) { \
591  /* We wait for the MCU event (should indicate display processed for a bagl element) */ \
592  io_seproxyhal_spi_recv(G_io_seproxyhal_spi_buffer, sizeof(G_io_seproxyhal_spi_buffer), 0); \
593  io_seproxyhal_handle_event(); \
594  UX_DISPLAY_NEXT_ELEMENT(); \
595  } \
596  io_seproxyhal_spi_recv(G_io_seproxyhal_spi_buffer, sizeof(G_io_seproxyhal_spi_buffer), 0); \
597  io_seproxyhal_handle_event(); \
598  /* We send a general status which indicates to the MCU that he can process any pending action \
599  * (i.e. here, display the whole screen) */ \
600  io_seproxyhal_general_status(); \
601  /* We wait for an ack of the MCU. */ \
602  io_seproxyhal_spi_recv(G_io_seproxyhal_spi_buffer, sizeof(G_io_seproxyhal_spi_buffer), 0);
603 #endif
604 
609 #define UX_BUTTON_PUSH_EVENT(seph_packet) \
610  UX_FORWARD_EVENT( \
611  { \
612  if (G_ux.stack[0].button_push_callback) { \
613  io_seproxyhal_button_push(G_ux.stack[0].button_push_callback, \
614  seph_packet[3] >> 1); \
615  } \
616  UX_CONTINUE_DISPLAY_APP({}); \
617  }, \
618  1);
619 
620 #define UX_FINGER_EVENT(seph_packet)
625 #define UX_TICKER_EVENT(seph_packet, callback) \
626  UX_FORWARD_EVENT( \
627  { \
628  unsigned int UX_ALLOWED \
629  = (G_ux_params.len != BOLOS_UX_IGNORE && G_ux_params.len != BOLOS_UX_CONTINUE); \
630  if (G_ux.stack[0].ticker_value) { \
631  G_ux.stack[0].ticker_value -= MIN(G_ux.stack[0].ticker_value, 100); \
632  if (!G_ux.stack[0].ticker_value) { \
633  if (!G_ux.stack[0].ticker_callback) { \
634  callback \
635  } \
636  else { \
637  G_ux.stack[0].ticker_value = G_ux.stack[0].ticker_interval; \
638  G_ux.stack[0].ticker_callback(0); \
639  } \
640  } \
641  } \
642  if (UX_ALLOWED) { \
643  UX_CONTINUE_DISPLAY_APP({}); \
644  } \
645  }, \
646  0);
647 
652 #define UX_DEFAULT_EVENT() UX_FORWARD_EVENT({ UX_CONTINUE_DISPLAY_APP({}); }, 0);
653 
658 #define UX_DISPLAY_KEYBOARD(callback) \
659  G_ux_params.ux_id = BOLOS_UX_KEYBOARD; \
660  G_ux_params.len = 0; \
661  os_ux(&G_ux_params); \
662  G_ux_params.len = os_sched_last_status(TASK_BOLOS_UX);
663 
668 void io_seproxyhal_setup_ticker(unsigned int interval_ms);
669 
671 
677  int y,
678  unsigned int w,
679  unsigned int h,
680  unsigned int *color_index,
681  unsigned int bit_per_pixel,
682  unsigned char *bitmap);
683 
684 void io_seproxyhal_power_off(bool criticalBattery);
685 
687 
689 
690 void io_seproxyhal_backlight(unsigned int flags, unsigned int backlight_percentage);
691 
696 void io_seproxyhal_display_icon(const bagl_component_t *icon_component,
697  const bagl_icon_details_t *icon_details);
698 
702 unsigned int io_seproxyhal_display_icon_header_and_colors(const bagl_component_t *icon_component,
703  const bagl_icon_details_t *icon_details,
704  unsigned int *icon_len);
705 
706 // discriminated from io to allow for different memory placement
707 typedef struct ux_seph_s {
708  unsigned int button_mask;
709  unsigned int button_same_mask_counter;
710 #ifdef HAVE_BOLOS
711  unsigned int ux_id;
712  unsigned int ux_status;
713 #endif // HAVE_BOLOS
715 
717 
718 #ifdef HAVE_UX_LEGACY
719 #define UX_MENU_END \
720  { \
721  NULL, NULL, 0, NULL, NULL, NULL, 0, 0 \
722  }
723 
724 #define UX_MENU_INIT() memset(&ux_menu, 0, sizeof(ux_menu));
725 
726 #define UX_MENU_DISPLAY(current_entry, menu_entries, menu_entry_preprocessor) \
727  ux_menu_display(current_entry, menu_entries, menu_entry_preprocessor);
728 
729 // if current_entry == -1UL, then don't change the current entry
730 #define UX_MENU_UNCHANGED_ENTRY (-1UL)
731 void ux_menu_display(unsigned int current_entry,
732  const ux_menu_entry_t *menu_entries,
733  ux_menu_preprocessor_t menu_entry_preprocessor);
735 unsigned int ux_menu_elements_button(unsigned int button_mask, unsigned int button_mask_counter);
737 
738 #define UX_TURNER_INIT() memset(&ux_turner, 0, sizeof(ux_turner));
739 
740 #define UX_TURNER_DISPLAY(current_step, steps, steps_count, button_push_callback) \
741  ux_turner_display(current_step, steps, steps_count, button_push_callback);
742 
743 // if current_entry == -1UL, then don't change the current entry
744 #define UX_TURNER_UNCHANGED_ENTRY (-1UL)
745 void ux_turner_display(unsigned int current_step,
746  const ux_turner_step_t *steps,
747  unsigned int steps_count,
748  button_push_callback_t button_callback);
749 // function to be called to advance to the next turner step when the programmed delay is expired
750 void ux_turner_ticker(unsigned int elpased_ms);
751 
753 #endif // HAVE_UX_LEGACY
754 
755 #ifdef HAVE_UX_LEGACY
756 // current ux_menu context (could be pluralised if multiple nested levels of menu are required
757 // within bolos_ux for example)
758 #ifdef BOLOS_RELEASE
759 #ifdef TARGET_NANOX
760 #error HAVE_UX_LEGACY must be removed in the release
761 #else
762 #warning Refactor UX plz
763 #endif // TARGET_NANOX
764 #endif // BOLOS_RELEASE
765 #endif // HAVE_UX_LEGACY
766 
767 #include "glyphs.h"
Key pair generation based on elliptic curves.
#define LANGUAGE_PACK
Definition: nbgl_fonts.h:29
const char * get_ux_loc_string(uint32_t index)
#define MAX(x, y)
Definition: nbgl_types.h:82
const char * text
Definition: ux_bagl.h:68
bagl_component_t component
Definition: ux_bagl.h:58
const bagl_icon_details_t * icon
Definition: ux_bagl.h:107
const char * lines[5]
Definition: ux_bagl.h:102
Definition: ux_bagl.h:226
unsigned int userid
Definition: ux_bagl.h:233
char icon_x
Definition: ux_bagl.h:238
char text_x
Definition: ux_bagl.h:237
const char * line1
Definition: ux_bagl.h:235
const char * line2
Definition: ux_bagl.h:236
const bagl_icon_details_t * icon
Definition: ux_bagl.h:234
ux_menu_callback_t callback
Definition: ux_bagl.h:230
const ux_menu_entry_t * menu
Definition: ux_bagl.h:228
ux_menu_preprocessor_t menu_entry_preprocessor
Definition: ux_bagl.h:248
const ux_menu_entry_t * menu_entries
Definition: ux_bagl.h:245
ux_menu_iterator_t menu_iterator
Definition: ux_bagl.h:249
unsigned int current_entry
Definition: ux_bagl.h:247
unsigned int menu_entries_count
Definition: ux_bagl.h:246
unsigned int button_mask
Definition: ux_bagl.h:706
unsigned int button_same_mask_counter
Definition: ux_bagl.h:707
unsigned char element_arrays_count
Definition: ux_bagl.h:279
button_push_callback_t button_push_callback
Definition: ux_bagl.h:292
unsigned int ticker_interval
Definition: ux_bagl.h:296
bolos_task_status_t exit_code_after_elements_displayed
Definition: ux_bagl.h:278
unsigned short element_index
Definition: ux_bagl.h:280
struct ux_stack_slot_s::@44 element_arrays[UX_STACK_SLOT_ARRAY_COUNT]
callback_int_t ticker_callback
Definition: ux_bagl.h:294
bagl_element_callback_t screen_before_element_display_callback
Definition: ux_bagl.h:291
unsigned int ticker_value
Definition: ux_bagl.h:295
const bagl_element_t * element_array
Definition: ux_bagl.h:283
unsigned char element_array_count
Definition: ux_bagl.h:284
unsigned char stack_count
Definition: ux_bagl.h:300
bolos_ux_params_t params
Definition: ux_bagl.h:337
ux_stack_slot_t stack[UX_STACK_SLOT_COUNT]
Definition: ux_bagl.h:326
asynchmodal_end_callback_t asynchmodal_end_callback
Definition: ux_nbgl.h:48
bagl_element_t tmp_element
Definition: ux_bagl.h:321
char * externalText
Definition: ux_bagl.h:340
bolos_task_status_t exit_code
Definition: ux_bagl.h:301
char string_buffer[128]
Definition: ux_nbgl.h:50
unsigned int current_step
Definition: ux_bagl.h:270
const ux_turner_step_t * steps
Definition: ux_bagl.h:268
button_push_callback_t button_callback
Definition: ux_bagl.h:271
unsigned int elapsed_ms
Definition: ux_bagl.h:272
unsigned int steps_count
Definition: ux_bagl.h:269
unsigned short fontid2
Definition: ux_bagl.h:260
unsigned short fontid1
Definition: ux_bagl.h:258
const bagl_icon_details_t * icon
Definition: ux_bagl.h:257
const char * line1
Definition: ux_bagl.h:259
const char * line2
Definition: ux_bagl.h:261
unsigned int next_step_ms
Definition: ux_bagl.h:264
unsigned short uint16_t
Definition: usbd_conf.h:54
void io_seproxyhal_button_push(button_push_callback_t button_push_callback, unsigned int new_button_mask)
void(* ux_menu_callback_t)(unsigned int userid)
Definition: ux_bagl.h:219
unsigned int ux_stack_push(void)
Definition: ux_stack.c:45
const bagl_element_t *(* ux_menu_preprocessor_t)(const ux_menu_entry_t *, bagl_element_t *element)
Definition: ux_bagl.h:241
void io_seproxyhal_setup_ticker(unsigned int interval_ms)
const ux_menu_entry_t *(* ux_menu_iterator_t)(unsigned int entry_idx)
Definition: ux_bagl.h:243
const bagl_element_t * ux_stack_display_element_callback(const bagl_element_t *element)
Definition: ux_stack.c:206
unsigned int ux_stack_is_element_array_present(const bagl_element_t *element_array)
Definition: ux_stack.c:29
const bagl_element_t * ux_layout_strings_prepro(const bagl_element_t *element)
void io_seproxyhal_touch_callback(const bagl_element_t *element, unsigned char event)
void(* asynchmodal_end_callback_t)(unsigned int ux_status)
Definition: ux_bagl.h:174
void io_seproxyhal_display_bitmap(int x, int y, unsigned int w, unsigned int h, unsigned int *color_index, unsigned int bit_per_pixel, unsigned char *bitmap)
struct ux_turner_state_s ux_turner_state_t
struct ux_seph_s ux_seph_os_and_app_t
struct ux_menu_state_s ux_menu_state_t
const bagl_element_t * ux_menu_element_preprocessor(const bagl_element_t *element)
#define UX_STACK_SLOT_COUNT
Definition: ux_bagl.h:166
void ux_turner_display(unsigned int current_step, const ux_turner_step_t *steps, unsigned int steps_count, button_push_callback_t button_callback)
void io_seproxyhal_disable_io(void)
void io_seproxyhal_backlight(unsigned int flags, unsigned int backlight_percentage)
const bagl_element_t *(* bagl_element_callback_t)(const bagl_element_t *element)
Definition: ux_bagl.h:54
void io_seproxyhal_power_off(bool criticalBattery)
ux_menu_state_t ux_menu
void ux_turner_ticker(unsigned int elpased_ms)
#define G_ux
Definition: ux_bagl.h:345
struct ux_layout_icon_strings_params_s ux_layout_icon_strings_params_t
void ux_stack_display(unsigned int stack_slot)
Definition: ux_stack.c:331
void(* ux_turner_callback_t)(void)
Definition: ux_bagl.h:254
void io_seproxyhal_se_reset(void)
void io_seproxyhal_display(const bagl_element_t *element)
void io_seproxyhal_touch_element_callback(const bagl_element_t *elements, unsigned short element_count, unsigned short x, unsigned short y, unsigned char event_kind, bagl_element_callback_t before_display)
void ux_stack_remove(unsigned int stack_slot)
Definition: ux_stack.c:140
void io_seproxyhal_display_default(const bagl_element_t *element)
struct ux_turner_step_s ux_turner_step_t
void ux_stack_al_display_next_element(unsigned int stack_slot)
Definition: ux_stack.c:297
void ux_stack_insert(unsigned int stack_slot)
Definition: ux_stack.c:111
void io_seproxyhal_touch(const bagl_element_t *elements, unsigned short element_count, unsigned short x, unsigned short y, unsigned char event_kind)
ux_turner_state_t ux_turner
ux_seph_os_and_app_t G_ux_os
void ux_stack_init(unsigned int stack_slot)
Definition: ux_stack.c:171
#define G_ux_params
Definition: ux_bagl.h:346
void io_seproxyhal_display_icon(const bagl_component_t *icon_component, const bagl_icon_details_t *icon_details)
unsigned int(* button_push_callback_t)(unsigned int button_mask, unsigned int button_mask_counter)
Definition: ux_bagl.h:142
unsigned int io_seproxyhal_display_icon_header_and_colors(const bagl_component_t *icon_component, const bagl_icon_details_t *icon_details, unsigned int *icon_len)
#define UX_STACK_SLOT_ARRAY_COUNT
Definition: ux_bagl.h:170
void ux_menu_display(unsigned int current_entry, const ux_menu_entry_t *menu_entries, ux_menu_preprocessor_t menu_entry_preprocessor)
struct ux_layout_strings_params_s ux_layout_strings_params_t
void ux_stack_redisplay(void)
Definition: ux_stack.c:89
unsigned int bagl_label_roundtrip_duration_ms(const bagl_element_t *e, unsigned int average_char_width)
unsigned int bagl_label_roundtrip_duration_ms_buf(const bagl_element_t *e, const char *str, unsigned int average_char_width)
unsigned int ux_menu_elements_button(unsigned int button_mask, unsigned int button_mask_counter)
void io_seproxyhal_request_mcu_status(void)
unsigned int(* callback_int_t)(unsigned int)
Definition: ux_bagl.h:173
unsigned int ux_stack_pop(void)
Definition: ux_stack.c:59
BOLOS_UX_LOC_STRINGS UX_LOC_STRINGS_INDEX