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 }