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_event.c (14827B)

      1 /**
      2  * @file lv_event.c
      3  *
      4  */
      5 
      6 /*********************
      7  *      INCLUDES
      8  *********************/
      9 #include "lv_obj.h"
     10 #include "lv_indev.h"
     11 
     12 /*********************
     13  *      DEFINES
     14  *********************/
     15 #define MY_CLASS &lv_obj_class
     16 
     17 /**********************
     18  *      TYPEDEFS
     19  **********************/
     20 typedef struct _lv_event_dsc_t {
     21     lv_event_cb_t cb;
     22     void * user_data;
     23     lv_event_code_t filter : 8;
     24 } lv_event_dsc_t;
     25 
     26 /**********************
     27  *  STATIC PROTOTYPES
     28  **********************/
     29 static lv_event_dsc_t * lv_obj_get_event_dsc(const lv_obj_t * obj, uint32_t id);
     30 static lv_res_t event_send_core(lv_event_t * e);
     31 static bool event_is_bubbled(lv_event_t * e);
     32 
     33 
     34 /**********************
     35  *  STATIC VARIABLES
     36  **********************/
     37 static lv_event_t * event_head;
     38 
     39 /**********************
     40  *      MACROS
     41  **********************/
     42 #if LV_LOG_TRACE_EVENT
     43     #define EVENT_TRACE(...) LV_LOG_TRACE(__VA_ARGS__)
     44 #else
     45     #define EVENT_TRACE(...)
     46 #endif
     47 
     48 /**********************
     49  *   GLOBAL FUNCTIONS
     50  **********************/
     51 
     52 lv_res_t lv_event_send(lv_obj_t * obj, lv_event_code_t event_code, void * param)
     53 {
     54     if(obj == NULL) return LV_RES_OK;
     55 
     56     LV_ASSERT_OBJ(obj, MY_CLASS);
     57 
     58     lv_event_t e;
     59     e.target = obj;
     60     e.current_target = obj;
     61     e.code = event_code;
     62     e.user_data = NULL;
     63     e.param = param;
     64     e.deleted = 0;
     65     e.stop_bubbling = 0;
     66     e.stop_processing = 0;
     67 
     68     /*Build a simple linked list from the objects used in the events
     69      *It's important to know if this object was deleted by a nested event
     70      *called from this `event_cb`.*/
     71     e.prev = event_head;
     72     event_head = &e;
     73 
     74     /*Send the event*/
     75     lv_res_t res = event_send_core(&e);
     76 
     77     /*Remove this element from the list*/
     78     event_head = e.prev;
     79 
     80     return res;
     81 }
     82 
     83 
     84 lv_res_t lv_obj_event_base(const lv_obj_class_t * class_p, lv_event_t * e)
     85 {
     86     const lv_obj_class_t * base;
     87     if(class_p == NULL) base = e->current_target->class_p;
     88     else base = class_p->base_class;
     89 
     90     /*Find a base in which call the ancestor's event handler_cb if set*/
     91     while(base && base->event_cb == NULL) base = base->base_class;
     92 
     93     if(base == NULL) return LV_RES_OK;
     94     if(base->event_cb == NULL) return LV_RES_OK;
     95 
     96     /*Call the actual event callback*/
     97     e->user_data = NULL;
     98     base->event_cb(base, e);
     99 
    100     lv_res_t res = LV_RES_OK;
    101     /*Stop if the object is deleted*/
    102     if(e->deleted) res = LV_RES_INV;
    103 
    104     return res;
    105 }
    106 
    107 
    108 lv_obj_t * lv_event_get_target(lv_event_t * e)
    109 {
    110     return e->target;
    111 }
    112 
    113 lv_obj_t * lv_event_get_current_target(lv_event_t * e)
    114 {
    115     return e->current_target;
    116 }
    117 
    118 lv_event_code_t lv_event_get_code(lv_event_t * e)
    119 {
    120     return e->code & ~LV_EVENT_PREPROCESS;
    121 }
    122 
    123 void * lv_event_get_param(lv_event_t * e)
    124 {
    125     return e->param;
    126 }
    127 
    128 void * lv_event_get_user_data(lv_event_t * e)
    129 {
    130     return e->user_data;
    131 }
    132 
    133 void lv_event_stop_bubbling(lv_event_t * e)
    134 {
    135     e->stop_bubbling = 1;
    136 }
    137 
    138 void lv_event_stop_processing(lv_event_t * e)
    139 {
    140     e->stop_processing = 1;
    141 }
    142 
    143 
    144 uint32_t lv_event_register_id(void)
    145 {
    146     static uint32_t last_id = _LV_EVENT_LAST;
    147     last_id ++;
    148     return last_id;
    149 }
    150 
    151 void _lv_event_mark_deleted(lv_obj_t * obj)
    152 {
    153     lv_event_t * e = event_head;
    154 
    155     while(e) {
    156         if(e->current_target == obj || e->target == obj) e->deleted = 1;
    157         e = e->prev;
    158     }
    159 }
    160 
    161 
    162 struct _lv_event_dsc_t * lv_obj_add_event_cb(lv_obj_t * obj, lv_event_cb_t event_cb, lv_event_code_t filter,
    163                                              void * user_data)
    164 {
    165     LV_ASSERT_OBJ(obj, MY_CLASS);
    166     lv_obj_allocate_spec_attr(obj);
    167 
    168     obj->spec_attr->event_dsc_cnt++;
    169     obj->spec_attr->event_dsc = lv_mem_realloc(obj->spec_attr->event_dsc,
    170                                                obj->spec_attr->event_dsc_cnt * sizeof(lv_event_dsc_t));
    171     LV_ASSERT_MALLOC(obj->spec_attr->event_dsc);
    172 
    173     obj->spec_attr->event_dsc[obj->spec_attr->event_dsc_cnt - 1].cb = event_cb;
    174     obj->spec_attr->event_dsc[obj->spec_attr->event_dsc_cnt - 1].filter = filter;
    175     obj->spec_attr->event_dsc[obj->spec_attr->event_dsc_cnt - 1].user_data = user_data;
    176 
    177     return &obj->spec_attr->event_dsc[obj->spec_attr->event_dsc_cnt - 1];
    178 }
    179 
    180 bool lv_obj_remove_event_cb(lv_obj_t * obj, lv_event_cb_t event_cb)
    181 {
    182     LV_ASSERT_OBJ(obj, MY_CLASS);
    183     if(obj->spec_attr == NULL) return false;
    184 
    185     int32_t i = 0;
    186     for(i = 0; i < obj->spec_attr->event_dsc_cnt; i++) {
    187         if(event_cb == NULL || obj->spec_attr->event_dsc[i].cb == event_cb) {
    188             /*Shift the remaining event handlers forward*/
    189             for(; i < (obj->spec_attr->event_dsc_cnt - 1); i++) {
    190                 obj->spec_attr->event_dsc[i] = obj->spec_attr->event_dsc[i + 1];
    191             }
    192             obj->spec_attr->event_dsc_cnt--;
    193             obj->spec_attr->event_dsc = lv_mem_realloc(obj->spec_attr->event_dsc,
    194                                                        obj->spec_attr->event_dsc_cnt * sizeof(lv_event_dsc_t));
    195             LV_ASSERT_MALLOC(obj->spec_attr->event_dsc);
    196             return true;
    197         }
    198     }
    199 
    200     /*No event handler found*/
    201     return false;
    202 }
    203 
    204 bool lv_obj_remove_event_cb_with_user_data(lv_obj_t * obj, lv_event_cb_t event_cb, const void * user_data)
    205 {
    206     LV_ASSERT_OBJ(obj, MY_CLASS);
    207     if(obj->spec_attr == NULL) return false;
    208 
    209     int32_t i = 0;
    210     for(i = 0; i < obj->spec_attr->event_dsc_cnt; i++) {
    211         if((event_cb == NULL || obj->spec_attr->event_dsc[i].cb == event_cb) &&
    212            obj->spec_attr->event_dsc[i].user_data == user_data) {
    213             /*Shift the remaining event handlers forward*/
    214             for(; i < (obj->spec_attr->event_dsc_cnt - 1); i++) {
    215                 obj->spec_attr->event_dsc[i] = obj->spec_attr->event_dsc[i + 1];
    216             }
    217             obj->spec_attr->event_dsc_cnt--;
    218             obj->spec_attr->event_dsc = lv_mem_realloc(obj->spec_attr->event_dsc,
    219                                                        obj->spec_attr->event_dsc_cnt * sizeof(lv_event_dsc_t));
    220             LV_ASSERT_MALLOC(obj->spec_attr->event_dsc);
    221             return true;
    222         }
    223     }
    224 
    225     /*No event handler found*/
    226     return false;
    227 }
    228 
    229 
    230 bool lv_obj_remove_event_dsc(lv_obj_t * obj, struct _lv_event_dsc_t * event_dsc)
    231 {
    232     LV_ASSERT_OBJ(obj, MY_CLASS);
    233     if(obj->spec_attr == NULL) return false;
    234 
    235     int32_t i = 0;
    236     for(i = 0; i < obj->spec_attr->event_dsc_cnt; i++) {
    237         if(&obj->spec_attr->event_dsc[i] == event_dsc) {
    238             /*Shift the remaining event handlers forward*/
    239             for(; i < (obj->spec_attr->event_dsc_cnt - 1); i++) {
    240                 obj->spec_attr->event_dsc[i] = obj->spec_attr->event_dsc[i + 1];
    241             }
    242             obj->spec_attr->event_dsc_cnt--;
    243             obj->spec_attr->event_dsc = lv_mem_realloc(obj->spec_attr->event_dsc,
    244                                                        obj->spec_attr->event_dsc_cnt * sizeof(lv_event_dsc_t));
    245             LV_ASSERT_MALLOC(obj->spec_attr->event_dsc);
    246             return true;
    247         }
    248     }
    249 
    250     /*No event handler found*/
    251     return false;
    252 }
    253 
    254 void * lv_obj_get_event_user_data(struct _lv_obj_t * obj, lv_event_cb_t event_cb)
    255 {
    256     LV_ASSERT_OBJ(obj, MY_CLASS);
    257     if(obj->spec_attr == NULL) return NULL;
    258 
    259     int32_t i = 0;
    260     for(i = 0; i < obj->spec_attr->event_dsc_cnt; i++) {
    261         if(event_cb == obj->spec_attr->event_dsc[i].cb) return obj->spec_attr->event_dsc[i].user_data;
    262     }
    263     return NULL;
    264 }
    265 
    266 lv_indev_t * lv_event_get_indev(lv_event_t * e)
    267 {
    268 
    269     if(e->code == LV_EVENT_PRESSED ||
    270        e->code == LV_EVENT_PRESSING ||
    271        e->code == LV_EVENT_PRESS_LOST ||
    272        e->code == LV_EVENT_SHORT_CLICKED ||
    273        e->code == LV_EVENT_LONG_PRESSED ||
    274        e->code == LV_EVENT_LONG_PRESSED_REPEAT ||
    275        e->code == LV_EVENT_CLICKED ||
    276        e->code == LV_EVENT_RELEASED ||
    277        e->code == LV_EVENT_SCROLL_BEGIN ||
    278        e->code == LV_EVENT_SCROLL_END ||
    279        e->code == LV_EVENT_SCROLL ||
    280        e->code == LV_EVENT_GESTURE ||
    281        e->code == LV_EVENT_KEY ||
    282        e->code == LV_EVENT_FOCUSED ||
    283        e->code == LV_EVENT_DEFOCUSED ||
    284        e->code == LV_EVENT_LEAVE) {
    285         return lv_event_get_param(e);
    286     }
    287     else {
    288         LV_LOG_WARN("Not interpreted with this event code");
    289         return NULL;
    290     }
    291 }
    292 
    293 lv_obj_draw_part_dsc_t * lv_event_get_draw_part_dsc(lv_event_t * e)
    294 {
    295     if(e->code == LV_EVENT_DRAW_PART_BEGIN ||
    296        e->code == LV_EVENT_DRAW_PART_END) {
    297         return lv_event_get_param(e);
    298     }
    299     else {
    300         LV_LOG_WARN("Not interpreted with this event code");
    301         return NULL;
    302     }
    303 }
    304 
    305 lv_draw_ctx_t * lv_event_get_draw_ctx(lv_event_t * e)
    306 {
    307     if(e->code == LV_EVENT_DRAW_MAIN ||
    308        e->code == LV_EVENT_DRAW_MAIN_BEGIN ||
    309        e->code == LV_EVENT_DRAW_MAIN_END ||
    310        e->code == LV_EVENT_DRAW_POST ||
    311        e->code == LV_EVENT_DRAW_POST_BEGIN ||
    312        e->code == LV_EVENT_DRAW_POST_END) {
    313         return lv_event_get_param(e);
    314     }
    315     else {
    316         LV_LOG_WARN("Not interpreted with this event code");
    317         return NULL;
    318     }
    319 }
    320 
    321 const lv_area_t * lv_event_get_old_size(lv_event_t * e)
    322 {
    323     if(e->code == LV_EVENT_SIZE_CHANGED) {
    324         return lv_event_get_param(e);
    325     }
    326     else {
    327         LV_LOG_WARN("Not interpreted with this event code");
    328         return NULL;
    329     }
    330 }
    331 
    332 uint32_t lv_event_get_key(lv_event_t * e)
    333 {
    334     if(e->code == LV_EVENT_KEY) {
    335         uint32_t * k = lv_event_get_param(e);
    336         if(k) return *k;
    337         else return 0;
    338     }
    339     else {
    340         LV_LOG_WARN("Not interpreted with this event code");
    341         return 0;
    342     }
    343 }
    344 
    345 lv_anim_t * lv_event_get_scroll_anim(lv_event_t * e)
    346 {
    347     if(e->code == LV_EVENT_SCROLL_BEGIN) {
    348         return lv_event_get_param(e);
    349     }
    350     else {
    351         LV_LOG_WARN("Not interpreted with this event code");
    352         return 0;
    353     }
    354 }
    355 
    356 void lv_event_set_ext_draw_size(lv_event_t * e, lv_coord_t size)
    357 {
    358     if(e->code == LV_EVENT_REFR_EXT_DRAW_SIZE) {
    359         lv_coord_t * cur_size = lv_event_get_param(e);
    360         *cur_size = LV_MAX(*cur_size, size);
    361     }
    362     else {
    363         LV_LOG_WARN("Not interpreted with this event code");
    364     }
    365 }
    366 
    367 lv_point_t * lv_event_get_self_size_info(lv_event_t * e)
    368 {
    369     if(e->code == LV_EVENT_GET_SELF_SIZE) {
    370         return lv_event_get_param(e);
    371     }
    372     else {
    373         LV_LOG_WARN("Not interpreted with this event code");
    374         return 0;
    375     }
    376 }
    377 
    378 lv_hit_test_info_t * lv_event_get_hit_test_info(lv_event_t * e)
    379 {
    380     if(e->code == LV_EVENT_HIT_TEST) {
    381         return lv_event_get_param(e);
    382     }
    383     else {
    384         LV_LOG_WARN("Not interpreted with this event code");
    385         return 0;
    386     }
    387 }
    388 
    389 const lv_area_t * lv_event_get_cover_area(lv_event_t * e)
    390 {
    391     if(e->code == LV_EVENT_COVER_CHECK) {
    392         lv_cover_check_info_t * p = lv_event_get_param(e);
    393         return p->area;
    394     }
    395     else {
    396         LV_LOG_WARN("Not interpreted with this event code");
    397         return NULL;
    398     }
    399 }
    400 
    401 void lv_event_set_cover_res(lv_event_t * e, lv_cover_res_t res)
    402 {
    403     if(e->code == LV_EVENT_COVER_CHECK) {
    404         lv_cover_check_info_t * p = lv_event_get_param(e);
    405         if(res > p->res) p->res = res;  /*Save only "stronger" results*/
    406     }
    407     else {
    408         LV_LOG_WARN("Not interpreted with this event code");
    409     }
    410 }
    411 
    412 /**********************
    413  *   STATIC FUNCTIONS
    414  **********************/
    415 
    416 static lv_event_dsc_t * lv_obj_get_event_dsc(const lv_obj_t * obj, uint32_t id)
    417 {
    418     LV_ASSERT_OBJ(obj, MY_CLASS);
    419 
    420     if(!obj->spec_attr) return NULL;
    421     if(id >= obj->spec_attr->event_dsc_cnt) return NULL;
    422 
    423     return &obj->spec_attr->event_dsc[id];
    424 }
    425 
    426 static lv_res_t event_send_core(lv_event_t * e)
    427 {
    428     EVENT_TRACE("Sending event %d to %p with %p param", e->code, (void *)e->current_target, e->param);
    429 
    430     /*Call the input device's feedback callback if set*/
    431     lv_indev_t * indev_act = lv_indev_get_act();
    432     if(indev_act) {
    433         if(indev_act->driver->feedback_cb) indev_act->driver->feedback_cb(indev_act->driver, e->code);
    434         if(e->stop_processing) return LV_RES_OK;
    435         if(e->deleted) return LV_RES_INV;
    436     }
    437 
    438     lv_res_t res = LV_RES_OK;
    439     lv_event_dsc_t * event_dsc = lv_obj_get_event_dsc(e->current_target, 0);
    440 
    441     uint32_t i = 0;
    442     while(event_dsc && res == LV_RES_OK) {
    443         if(event_dsc->cb  && ((event_dsc->filter & LV_EVENT_PREPROCESS) == LV_EVENT_PREPROCESS)
    444            && (event_dsc->filter == (LV_EVENT_ALL | LV_EVENT_PREPROCESS) ||
    445                (event_dsc->filter & ~LV_EVENT_PREPROCESS) == e->code)) {
    446             e->user_data = event_dsc->user_data;
    447             event_dsc->cb(e);
    448 
    449             if(e->stop_processing) return LV_RES_OK;
    450             /*Stop if the object is deleted*/
    451             if(e->deleted) return LV_RES_INV;
    452         }
    453 
    454         i++;
    455         event_dsc = lv_obj_get_event_dsc(e->current_target, i);
    456     }
    457 
    458     res = lv_obj_event_base(NULL, e);
    459 
    460     event_dsc = res == LV_RES_INV ? NULL : lv_obj_get_event_dsc(e->current_target, 0);
    461 
    462     i = 0;
    463     while(event_dsc && res == LV_RES_OK) {
    464         if(event_dsc->cb && ((event_dsc->filter & LV_EVENT_PREPROCESS) == 0)
    465            && (event_dsc->filter == LV_EVENT_ALL || event_dsc->filter == e->code)) {
    466             e->user_data = event_dsc->user_data;
    467             event_dsc->cb(e);
    468 
    469             if(e->stop_processing) return LV_RES_OK;
    470             /*Stop if the object is deleted*/
    471             if(e->deleted) return LV_RES_INV;
    472         }
    473 
    474         i++;
    475         event_dsc = lv_obj_get_event_dsc(e->current_target, i);
    476     }
    477 
    478     if(res == LV_RES_OK && e->current_target->parent && event_is_bubbled(e)) {
    479         e->current_target = e->current_target->parent;
    480         res = event_send_core(e);
    481         if(res != LV_RES_OK) return LV_RES_INV;
    482     }
    483 
    484     return res;
    485 }
    486 
    487 static bool event_is_bubbled(lv_event_t * e)
    488 {
    489     if(e->stop_bubbling) return false;
    490 
    491     /*Event codes that always bubble*/
    492     switch(e->code) {
    493         case LV_EVENT_CHILD_CREATED:
    494         case LV_EVENT_CHILD_DELETED:
    495             return true;
    496         default:
    497             break;
    498     }
    499 
    500     /*Check other codes only if bubbling is enabled*/
    501     if(lv_obj_has_flag(e->current_target, LV_OBJ_FLAG_EVENT_BUBBLE) == false) return false;
    502 
    503     switch(e->code) {
    504         case LV_EVENT_HIT_TEST:
    505         case LV_EVENT_COVER_CHECK:
    506         case LV_EVENT_REFR_EXT_DRAW_SIZE:
    507         case LV_EVENT_DRAW_MAIN_BEGIN:
    508         case LV_EVENT_DRAW_MAIN:
    509         case LV_EVENT_DRAW_MAIN_END:
    510         case LV_EVENT_DRAW_POST_BEGIN:
    511         case LV_EVENT_DRAW_POST:
    512         case LV_EVENT_DRAW_POST_END:
    513         case LV_EVENT_DRAW_PART_BEGIN:
    514         case LV_EVENT_DRAW_PART_END:
    515         case LV_EVENT_REFRESH:
    516         case LV_EVENT_DELETE:
    517         case LV_EVENT_CHILD_CREATED:
    518         case LV_EVENT_CHILD_DELETED:
    519         case LV_EVENT_CHILD_CHANGED:
    520         case LV_EVENT_SIZE_CHANGED:
    521         case LV_EVENT_STYLE_CHANGED:
    522         case LV_EVENT_GET_SELF_SIZE:
    523             return false;
    524         default:
    525             return true;
    526     }
    527 }