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*/