acid-drop- Hacking the planet from a LilyGo T-Deck using custom firmware |
git clone git://git.acid.vegas/acid-drop.git |
Log | Files | Refs | Archive | README | LICENSE |
lv_msg.c (3683B)
1 /** 2 * @file lv_msg.c 3 * 4 */ 5 6 /********************* 7 * INCLUDES 8 *********************/ 9 #include "lv_msg.h" 10 #if LV_USE_MSG 11 12 #include "../../../misc/lv_assert.h" 13 #include "../../../misc/lv_ll.h" 14 15 /********************* 16 * DEFINES 17 *********************/ 18 19 /********************** 20 * TYPEDEFS 21 **********************/ 22 23 typedef struct { 24 uint32_t msg_id; 25 lv_msg_subscribe_cb_t callback; 26 void * user_data; 27 void * _priv_data; /*Internal: used only store 'obj' in lv_obj_subscribe*/ 28 } sub_dsc_t; 29 30 /********************** 31 * STATIC PROTOTYPES 32 **********************/ 33 34 static void notify(lv_msg_t * m); 35 static void obj_notify_cb(void * s, lv_msg_t * m); 36 static void obj_delete_event_cb(lv_event_t * e); 37 38 /********************** 39 * STATIC VARIABLES 40 **********************/ 41 static lv_ll_t subs_ll; 42 43 /********************** 44 * GLOBAL VARIABLES 45 **********************/ 46 lv_event_code_t LV_EVENT_MSG_RECEIVED; 47 48 /********************** 49 * MACROS 50 **********************/ 51 52 /********************** 53 * GLOBAL FUNCTIONS 54 **********************/ 55 56 void lv_msg_init(void) 57 { 58 LV_EVENT_MSG_RECEIVED = lv_event_register_id(); 59 _lv_ll_init(&subs_ll, sizeof(sub_dsc_t)); 60 } 61 62 void * lv_msg_subsribe(uint32_t msg_id, lv_msg_subscribe_cb_t cb, void * user_data) 63 { 64 sub_dsc_t * s = _lv_ll_ins_tail(&subs_ll); 65 LV_ASSERT_MALLOC(s); 66 if(s == NULL) return NULL; 67 68 lv_memset_00(s, sizeof(*s)); 69 70 s->msg_id = msg_id; 71 s->callback = cb; 72 s->user_data = user_data; 73 return s; 74 } 75 76 void * lv_msg_subsribe_obj(uint32_t msg_id, lv_obj_t * obj, void * user_data) 77 { 78 sub_dsc_t * s = lv_msg_subsribe(msg_id, obj_notify_cb, user_data); 79 if(s == NULL) return NULL; 80 s->_priv_data = obj; 81 82 /*If not added yet, add a delete event cb which automatically unsubcribes the object*/ 83 sub_dsc_t * s_first = lv_obj_get_event_user_data(obj, obj_delete_event_cb); 84 if(s_first == NULL) { 85 lv_obj_add_event_cb(obj, obj_delete_event_cb, LV_EVENT_DELETE, s); 86 } 87 return s; 88 } 89 90 void lv_msg_unsubscribe(void * s) 91 { 92 LV_ASSERT_NULL(s); 93 _lv_ll_remove(&subs_ll, s); 94 lv_mem_free(s); 95 } 96 97 void lv_msg_send(uint32_t msg_id, const void * payload) 98 { 99 lv_msg_t m; 100 lv_memset_00(&m, sizeof(m)); 101 m.id = msg_id; 102 m.payload = payload; 103 notify(&m); 104 } 105 106 uint32_t lv_msg_get_id(lv_msg_t * m) 107 { 108 return m->id; 109 } 110 111 const void * lv_msg_get_payload(lv_msg_t * m) 112 { 113 return m->payload; 114 } 115 116 void * lv_msg_get_user_data(lv_msg_t * m) 117 { 118 return m->user_data; 119 } 120 121 lv_msg_t * lv_event_get_msg(lv_event_t * e) 122 { 123 if(e->code == LV_EVENT_MSG_RECEIVED) { 124 return lv_event_get_param(e); 125 } 126 else { 127 LV_LOG_WARN("Not interpreted with this event code"); 128 return NULL; 129 } 130 } 131 132 133 134 /********************** 135 * STATIC FUNCTIONS 136 **********************/ 137 138 static void notify(lv_msg_t * m) 139 { 140 sub_dsc_t * s; 141 _LV_LL_READ(&subs_ll, s) { 142 if(s->msg_id == m->id && s->callback) { 143 m->user_data = s->user_data; 144 m->_priv_data = s->_priv_data; 145 s->callback(s, m); 146 } 147 } 148 } 149 150 static void obj_notify_cb(void * s, lv_msg_t * m) 151 { 152 LV_UNUSED(s); 153 lv_event_send(m->_priv_data, LV_EVENT_MSG_RECEIVED, m); 154 } 155 156 static void obj_delete_event_cb(lv_event_t * e) 157 { 158 lv_obj_t * obj = lv_event_get_target(e); 159 160 sub_dsc_t * s = _lv_ll_get_head(&subs_ll); 161 sub_dsc_t * s_next; 162 while(s) { 163 /*On unsubscribe the list changes s becomes invalid so get next item while it's surely valid*/ 164 s_next = _lv_ll_get_next(&subs_ll, s); 165 if(s->_priv_data == obj) { 166 lv_msg_unsubscribe(s); 167 } 168 s = s_next; 169 } 170 } 171 172 #endif /*LV_USE_MSG*/