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) {