Mercurial > MadButterfly
comparison src/redraw_man.c @ 140:0de8fd11271e
Use macro to simplify the code.
Many code snippets are repeated annoying. Just because we manipulate
a common structure of data. They are move to macros to make it
simple and meaning.
author | Thinker K.F. Li <thinker@branda.to> |
---|---|
date | Tue, 23 Sep 2008 08:28:14 +0800 |
parents | 1695a4b02b14 |
children | e89512d6fa0a |
comparison
equal
deleted
inserted
replaced
139:1695a4b02b14 | 140:0de8fd11271e |
---|---|
30 static void ob_subject_free(ob_factory_t *factory, subject_t *subject); | 30 static void ob_subject_free(ob_factory_t *factory, subject_t *subject); |
31 static observer_t *ob_observer_alloc(ob_factory_t *factory); | 31 static observer_t *ob_observer_alloc(ob_factory_t *factory); |
32 static void ob_observer_free(ob_factory_t *factory, observer_t *observer); | 32 static void ob_observer_free(ob_factory_t *factory, observer_t *observer); |
33 static subject_t *ob_get_parent_subject(ob_factory_t *factory, | 33 static subject_t *ob_get_parent_subject(ob_factory_t *factory, |
34 subject_t *cur_subject); | 34 subject_t *cur_subject); |
35 | 35 /* Functions for children. */ |
36 #define FORCHILDREN(coord, child) \ | |
37 for((child) = STAILQ_HEAD((coord)->children); \ | |
38 (child) != NULL; \ | |
39 (child) = STAILQ_NEXT(coord_t, sibling, (child))) | |
40 #define NEXT_CHILD(child) STAILQ_NEXT(coord_t, sibling, child) | |
41 #define ADD_CHILD(parent, child) \ | |
42 STAILQ_INS_TAIL((parent)->children, coord_t, sibling, (child)) | |
43 #define RM_CHILD(parent, child) \ | |
44 STAILQ_REMOVE((parent)->children, coord_t, sibling, (child)) | |
45 #define FIRST_CHILD(parent) STAILQ_HEAD((parent)->children) | |
46 | |
47 /* Functions for members. */ | |
48 #define FORMEMBERS(coord, member) \ | |
49 for((member) = STAILQ_HEAD((coord)->members); \ | |
50 (member) != NULL; \ | |
51 (member) = STAILQ_NEXT(geo_t, coord_next, (member))) | |
52 #define NEXT_MEMBER(member) STAILQ_NEXT(geo_t, coord_next, (member)) | |
53 #define ADD_MEMBER(coord, member) \ | |
54 STAILQ_INS_TAIL((coord)->members, geo_t, coord_next, (member)) | |
55 #define RM_MEMBER(coord, member) \ | |
56 STAILQ_REMOVE((coord)->members, geo_t, coord_next, (member)) | |
57 #define FIRST_MEMBER(coord) STAILQ_HEAD((coord)->members) | |
36 | 58 |
37 /*! \brief Sort a list of element by a unsigned integer. | 59 /*! \brief Sort a list of element by a unsigned integer. |
38 * | 60 * |
39 * The result is in ascend order. The unsigned integers is | 61 * The result is in ascend order. The unsigned integers is |
40 * at offset specified by 'off' from start address of elemnts. | 62 * at offset specified by 'off' from start address of elemnts. |
135 | 157 |
136 static void free_canvas(cairo_t *canvas) { | 158 static void free_canvas(cairo_t *canvas) { |
137 #ifndef UNITTEST | 159 #ifndef UNITTEST |
138 cairo_destroy(canvas); | 160 cairo_destroy(canvas); |
139 #endif | 161 #endif |
162 } | |
163 | |
164 static int geo_off_in_coord(geo_t *geo, coord_t *coord) { | |
165 int off = 0; | |
166 geo_t *vgeo; | |
167 | |
168 FORMEMBERS(coord, vgeo) { | |
169 if(vgeo == geo) | |
170 return off; | |
171 off++; | |
172 } | |
173 return -1; | |
174 } | |
175 | |
176 static void geo_attach_coord(geo_t *geo, coord_t *coord) { | |
177 ADD_MEMBER(coord, geo); | |
178 coord->num_members++; | |
179 } | |
180 | |
181 static void geo_detach_coord(geo_t *geo, coord_t *coord) { | |
182 int off; | |
183 coord_t *child; | |
184 | |
185 off = geo_off_in_coord(geo, coord); | |
186 if(off < 0) | |
187 return; | |
188 FORCHILDREN(coord, child) { | |
189 if(child->before_pmem >= off) | |
190 child->before_pmem--; | |
191 } | |
192 | |
193 RM_MEMBER(coord, geo); | |
194 coord->num_members--; | |
140 } | 195 } |
141 | 196 |
142 int redraw_man_init(redraw_man_t *rdman, cairo_t *cr, cairo_t *backend) { | 197 int redraw_man_init(redraw_man_t *rdman, cairo_t *cr, cairo_t *backend) { |
143 extern void redraw_man_destroy(redraw_man_t *rdman); | 198 extern void redraw_man_destroy(redraw_man_t *rdman); |
144 | 199 |
258 return ERR; | 313 return ERR; |
259 | 314 |
260 geo_init(geo); | 315 geo_init(geo); |
261 geo->mouse_event = subject_new(&rdman->ob_factory, geo, OBJT_GEO); | 316 geo->mouse_event = subject_new(&rdman->ob_factory, geo, OBJT_GEO); |
262 | 317 |
263 STAILQ_INS_TAIL(coord->members, geo_t, coord_next, geo); | 318 geo_attach_coord(geo, coord); |
264 coord->num_members++; | |
265 | 319 |
266 /* New one should be dirty to recompute it when drawing. */ | 320 /* New one should be dirty to recompute it when drawing. */ |
267 geo->flags |= GEF_DIRTY; | 321 geo->flags |= GEF_DIRTY; |
268 r = add_dirty_geo(rdman, geo); | 322 r = add_dirty_geo(rdman, geo); |
269 if(r != OK) | 323 if(r != OK) |
283 geo_t *geo; | 337 geo_t *geo; |
284 coord_t *coord; | 338 coord_t *coord; |
285 | 339 |
286 geo = shape->geo; | 340 geo = shape->geo; |
287 coord = shape->coord; | 341 coord = shape->coord; |
288 STAILQ_REMOVE(coord->members, geo_t, coord_next, geo); | 342 geo_detach_coord(geo, coord); |
289 subject_free(&rdman->ob_factory, geo->mouse_event); | 343 subject_free(&rdman->ob_factory, geo->mouse_event); |
290 sh_detach_geo(shape); | 344 sh_detach_geo(shape); |
291 elmpool_elm_free(rdman->geo_pool, shape->geo); | 345 elmpool_elm_free(rdman->geo_pool, shape->geo); |
292 sh_detach_coord(shape); | 346 sh_detach_coord(shape); |
293 return OK; | 347 return OK; |
338 | 392 |
339 parent = coord->parent; | 393 parent = coord->parent; |
340 if(parent == NULL) | 394 if(parent == NULL) |
341 return ERR; | 395 return ERR; |
342 | 396 |
343 if(STAILQ_HEAD(coord->members) != NULL) | 397 if(FIRST_MEMBER(coord) != NULL) |
344 return ERR; | 398 return ERR; |
345 | 399 |
346 if(STAILQ_HEAD(coord->children) != NULL) | 400 if(FIRST_CHILD(coord) != NULL) |
347 return ERR; | 401 return ERR; |
348 | 402 |
349 /* Free canvas (\ref redraw) */ | 403 /* Free canvas (\ref redraw) */ |
350 if(coord->flags & COF_OWN_CANVAS) | 404 if(coord->flags & COF_OWN_CANVAS) |
351 free_canvas(coord->canvas); | 405 free_canvas(coord->canvas); |
352 | 406 |
353 STAILQ_REMOVE(parent->children, coord_t, sibling, coord); | 407 RM_CHILD(parent, coord); |
354 subject_free(&rdman->ob_factory, coord->mouse_event); | 408 subject_free(&rdman->ob_factory, coord->mouse_event); |
355 elmpool_elm_free(rdman->coord_pool, coord); | 409 elmpool_elm_free(rdman->coord_pool, coord); |
356 rdman->n_coords--; | 410 rdman->n_coords--; |
357 | 411 |
358 return OK; | 412 return OK; |
508 | 562 |
509 compute_aggr_of_coord(coord); | 563 compute_aggr_of_coord(coord); |
510 | 564 |
511 /* Clean member shapes. */ | 565 /* Clean member shapes. */ |
512 cnt = 0; | 566 cnt = 0; |
513 for(geo = STAILQ_HEAD(coord->members); | 567 FORMEMBERS(coord, geo) { |
514 geo != NULL; | |
515 geo = STAILQ_NEXT(geo_t, coord_next, geo)) { | |
516 SWAP(geo->cur_area, geo->last_area, area_t *); | 568 SWAP(geo->cur_area, geo->last_area, area_t *); |
517 clean_shape(geo->shape); | 569 clean_shape(geo->shape); |
518 cnt++; | 570 cnt++; |
519 } | 571 } |
520 | 572 |
522 poses = (co_aix (*)[2])malloc(sizeof(co_aix [2]) * 2 * cnt); | 574 poses = (co_aix (*)[2])malloc(sizeof(co_aix [2]) * 2 * cnt); |
523 if(poses == NULL) | 575 if(poses == NULL) |
524 return ERR; | 576 return ERR; |
525 | 577 |
526 pos_cnt = 0; | 578 pos_cnt = 0; |
527 for(geo = STAILQ_HEAD(coord->members); | 579 FORMEMBERS(coord, geo) { |
528 geo != NULL; | |
529 geo = STAILQ_NEXT(geo_t, coord_next, geo)) { | |
530 area_to_positions(geo->cur_area, poses + pos_cnt); | 580 area_to_positions(geo->cur_area, poses + pos_cnt); |
531 pos_cnt += 2; | 581 pos_cnt += 2; |
532 } | 582 } |
533 | 583 |
534 SWAP(coord->cur_area, coord->last_area, area_t *); | 584 SWAP(coord->cur_area, coord->last_area, area_t *); |
769 coord_t *child; | 819 coord_t *child; |
770 cairo_t *canvas; | 820 cairo_t *canvas; |
771 int mem_idx; | 821 int mem_idx; |
772 | 822 |
773 canvas = coord->canvas; | 823 canvas = coord->canvas; |
774 member = STAILQ_HEAD(coord->members); | 824 member = FIRST_MEMBER(coord); |
775 mem_idx = 0; | 825 mem_idx = 0; |
776 child = STAILQ_HEAD(coord->children); | 826 child = FIRST_CHILD(coord); |
777 while(child != NULL || member != NULL) { | 827 while(child != NULL || member != NULL) { |
778 if(child && child->before_pmem == mem_idx) { | 828 if(child && child->before_pmem == mem_idx) { |
779 r = draw_coord_shapes_in_areas(rdman, child, n_areas, areas); | 829 r = draw_coord_shapes_in_areas(rdman, child, n_areas, areas); |
780 dirty |= r; | 830 dirty |= r; |
781 child = STAILQ_NEXT(coord_t, sibling, child); | 831 child = NEXT_CHILD(child); |
782 } else { | 832 } else { |
783 ASSERT(member != NULL); | 833 ASSERT(member != NULL); |
784 if(is_geo_in_areas(member, n_areas, areas)) { | 834 if(is_geo_in_areas(member, n_areas, areas)) { |
785 draw_shape(rdman, canvas, member->shape); | 835 draw_shape(rdman, canvas, member->shape); |
786 dirty = 1; | 836 dirty = 1; |
787 } | 837 } |
788 member = STAILQ_NEXT(geo_t, coord_next, member); | 838 member = NEXT_MEMBER(member); |
789 mem_idx++; | 839 mem_idx++; |
790 } | 840 } |
791 } | 841 } |
792 | 842 |
793 if(dirty && coord->flags & COF_OWN_CANVAS) { | 843 if(dirty && coord->flags & COF_OWN_CANVAS) { |
947 geo_t *next; | 997 geo_t *next; |
948 coord_t *coord; | 998 coord_t *coord; |
949 | 999 |
950 if(last == NULL) { | 1000 if(last == NULL) { |
951 coord = rdman->root_coord; | 1001 coord = rdman->root_coord; |
952 while(coord != NULL && STAILQ_HEAD(coord->members) == NULL) | 1002 while(coord != NULL && FIRST_MEMBER(coord) == NULL) |
953 coord = preorder_coord_subtree(rdman->root_coord, coord); | 1003 coord = preorder_coord_subtree(rdman->root_coord, coord); |
954 if(coord == NULL) | 1004 if(coord == NULL) |
955 return NULL; | 1005 return NULL; |
956 return STAILQ_HEAD(coord->members); | 1006 return FIRST_MEMBER(coord); |
957 } | 1007 } |
958 | 1008 |
959 coord = last->shape->coord; | 1009 coord = last->shape->coord; |
960 next = STAILQ_NEXT(geo_t, coord_next, last); | 1010 next = NEXT_MEMBER(last); |
961 while(next == NULL) { | 1011 while(next == NULL) { |
962 coord = preorder_coord_subtree(rdman->root_coord, coord); | 1012 coord = preorder_coord_subtree(rdman->root_coord, coord); |
963 if(coord == NULL) | 1013 if(coord == NULL) |
964 return NULL; | 1014 return NULL; |
965 next = STAILQ_HEAD(coord->members); | 1015 next = FIRST_MEMBER(coord); |
966 } | 1016 } |
967 return next; | 1017 return next; |
968 } | 1018 } |
969 | 1019 |
970 int rdman_force_clean(redraw_man_t *rdman) { | 1020 int rdman_force_clean(redraw_man_t *rdman) { |