Embedded SDK
Embedded SDK
ux_menulist.c
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 #include "ux.h"
20 #include "os_helpers.h"
21 
22 #ifdef HAVE_UX_FLOW
23 
24 void ux_menulist_refresh(unsigned int stack_slot);
25 
26 unsigned int ux_menulist_button(unsigned int button_mask, unsigned int button_mask_counter)
27 {
28  UNUSED(button_mask_counter);
29 
30  switch (button_mask) {
32  if (G_ux.menulist_getter(G_ux.menulist_current - 1UL)) {
33  G_ux.menulist_current--;
34  ux_menulist_refresh(G_ux.stack_count - 1);
35  }
36  break;
38  if (G_ux.menulist_getter(G_ux.menulist_current + 1UL)) {
39  G_ux.menulist_current++;
40  ux_menulist_refresh(G_ux.stack_count - 1);
41  }
42  break;
44  G_ux.menulist_selector(G_ux.menulist_current);
45  break;
46  }
47  return 0;
48 }
49 
50 void ux_menulist_refresh(unsigned int stack_slot)
51 {
52  // set values
53  int i;
54  for (i = 0; i < 5; i++) {
55  G_ux.menulist_params.lines[i] = G_ux.menulist_getter(G_ux.menulist_current + i - 2);
56  }
57  // display (strings are localized before being displayed)
58  ux_layout_nnbnn_init(stack_slot);
59  // change callback to the menulist one
60  G_ux.stack[stack_slot].button_push_callback = ux_menulist_button;
61 }
62 
63 const ux_flow_step_t ux_menulist_conststep
64  = {ux_menulist_refresh, &G_ux.menulist_params, NULL, NULL};
65 UX_FLOW(ux_menulist_constflow, &ux_menulist_conststep);
66 
67 void ux_menulist_init_select(unsigned int stack_slot,
68  list_item_value_t getter,
69  list_item_select_t selector,
70  unsigned int selected_item_idx)
71 {
72  G_ux.menulist_current = selected_item_idx;
73  G_ux.menulist_getter = getter;
74  G_ux.menulist_selector = selector;
75 
76  // ensure the current flow step reference the G_ux.menulist_params to ensure strings displayed
77  // correctly. if not, then use the forged step (and display it if top of ux stack)
78  if (ux_stack_get_step_params(stack_slot) != (void *) &G_ux.menulist_params) {
79  ux_flow_init(stack_slot, ux_menulist_constflow, NULL);
80  }
81  else {
82  ux_menulist_refresh(stack_slot);
83  }
84 }
85 
86 // based on a nnbnn layout
87 void ux_menulist_init(unsigned int stack_slot,
88  list_item_value_t getter,
89  list_item_select_t selector)
90 {
91  ux_menulist_init_select(stack_slot, getter, selector, 0);
92 }
93 
94 #endif // HAVE_UX_FLOW
#define BUTTON_RIGHT
Definition: ux_bagl.h:145
#define BUTTON_EVT_RELEASED
Definition: ux_bagl.h:148
#define G_ux
Definition: ux_bagl.h:345
#define BUTTON_LEFT
Definition: ux_bagl.h:144
void ux_flow_init(unsigned int stack_slot, const ux_flow_step_t *const *steps, const ux_flow_step_t *const start_step)
const void * ux_stack_get_step_params(unsigned int stack_slot)
#define UX_FLOW(flow_name,...)