00001 #ifndef _KERNEL_INTERNAL_H_
00002 #define _KERNEL_INTERNAL_H_
00003
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #include "kernel/kernel.h"
00037 #include "lib/smalloc.h"
00038 #include "kernel/macro.h"
00039 #include "kernel/go_internal.h"
00040
00041 void glt_kernel_init_hanger (struct hanger_info * info);
00042 void glt_kernel_init_anchor (struct anchor_info * info);
00043
00044
00045 #define END_OF_ARGS 255
00046
00047
00048
00049
00050
00051
00052
00053
00054
00058 struct prop_virtual
00059 {
00060 struct prop p;
00061 uns undo_mask;
00062 prop_value (*get)(struct o* o);
00063 void (*set)(struct o* o, prop_value new_value);
00064 void (*set_low)(struct o* o, prop_value new_value);
00065 uns (*get_unit)(struct o* o);
00066 void (*set_unit)(struct o* o, uns unit);
00067 };
00068
00069
00070 void property_init(void);
00071 void property_finish(void);
00072
00073 static inline void prop_init(struct o *o, struct prop_virtual* p)
00074 { o->prop.head.next = &p->p.n; }
00075 void prop_finish(struct o *o);
00076
00077 void prop_name_set_low(struct o* o, string name, struct obj_page *alloc);
00078
00079 void prop_saving_copy(struct o* source, struct o* target);
00080
00081 static inline struct prop_virtual* prop2virt(struct prop* p)
00082 { ASSERT(p->flags & PTF_VIRTUAL); return (struct prop_virtual*)p; }
00083
00084 static inline prop_value prop_value_ref(uns type, prop_value value)
00085 { if(type == PT_STRING) string_ref(value.s); return value; }
00086 static inline prop_value prop_value_unref(uns type, prop_value value)
00087 { if(type == PT_STRING) string_unref(value.s); return value; }
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101 void object_init(void);
00102 void object_finish(void);
00103 void go_finish(struct go *go);
00104
00105 static inline void o_init(struct o *o, uns kind, uns type, uns subtype, struct prop_virtual *pv)
00106 { o->kind = kind; o->type = type; o->subtype = subtype; o->ref_count = 1; prop_init(o, pv); }
00107 static inline void o_finish(struct o *o)
00108 { ASSERT_O(o); prop_finish(o); o->kind = 255; o->type = 255; o->subtype = 255; xfree(o); }
00109
00110 struct go* go_init(struct go *go, uns type, uns subtype, ...);
00111 #ifdef DEBUG_KERNEL
00112 #define go_init(...) go_init(__VA_ARGS__, END_OF_ARGS)
00113 #endif
00114 struct go_group* group_init(struct go_group *group, uns subtype);
00115
00116 static inline void hanger_free(struct hanger *h) { ASSERT_HANGER(h); h->info = NULL; xfree(h); }
00117 static inline void anchor_free(struct anchor *a) { ASSERT_ANCHOR(a); a->info = NULL; xfree(a); }
00118
00119 void go_info_finish(struct go_info *gi, uns count);
00120
00121
00122
00123
00124
00125
00126 void obj_select_low(struct obj* obj);
00127 void obj_unselect_low(struct obj* obj);
00128 void go_select_low(struct go *go);
00129 void go_unselect_low(struct go *go);
00130
00131
00132
00133
00134
00135
00136 static inline struct hanger_smart* tlg_get_first_hanger_smart(struct go_tlg *tlg)
00137 { cnode *n = clist_head(&tlg->mc); return n ? SKIP_BACK(struct hanger_smart, nhanger, n) : NULL; }
00138
00139 #define WALK_GO_DEPENDENT_BEGIN(_go, _walk) do { \
00140 struct anchor *_a; struct hanger *_h; \
00141 WALK_GO_HANGER_BEGIN(_go, _h) \
00142 WALK_HANGER_ANCHOR(_h, _a) { \
00143 _walk = anchor_get_go(_a); \
00144 do {
00145
00146 #define WALK_GO_DEPENDENT_END } while(0); } WALK_GO_HANGER_END } while(0);
00147
00148 #define WALK_HANGER_ANCHOR_DELSAFE(_hanger, _walk, _tmp) for(_walk = hanger_get_first_anchor(_hanger); _walk && (_tmp = hanger_get_next_anchor(_walk), 1); _walk = _tmp)
00149
00150 static inline int go_is_father(struct go *go, struct go *father)
00151 { for(; go; go = &go_get_group(go)->go) if(go == father) return 1; return 0; }
00152
00153
00154
00155
00156
00157
00158 static inline struct go_tlg* go2tlg(struct go *go)
00159 { ASSERT_GROUP(go); return (struct go_tlg*)go; }
00160 static inline struct go_tlg* void2tlg(void *go)
00161 { ASSERT_GROUP(go); return go; }
00162 static inline struct go* tlg2go(struct go_tlg *tlg)
00163 { ASSERT_GROUP(tlg); return &tlg->group.go; }
00164 static inline struct go* group2go(struct go_group *group)
00165 { ASSERT_GROUP(group); return &group->go; }
00166
00167
00168
00169
00170
00171
00172 void go_insert(struct go *go, struct go_group *group, struct go *after);
00173 void go_relink_low(struct go *go, struct go_group *group, struct go *prev);
00174 void obj_relink_low(struct obj *obj, struct obj *father, struct obj *old_father, struct obj *after);
00175 void anchor_rehang_mc_no_recompute(struct anchor* a, struct geom_point *gp);
00176 void anchor_rehang_copy_no_recompute(struct anchor* a, struct hanger *h);
00177
00178
00179
00180
00181
00182 static inline int go_can_work(struct go *go)
00183 { ASSERT_GO(go); struct go_tlg *tlg = go_get_root(go); return trans_present && tlg2go(tlg)->subtype == GOST_GROUP_TLG && tlg->page == trans_page; }
00184 static inline int obj_can_work(struct obj *obj)
00185 { return trans_present && trans_page == page_universum && obj_get_root(obj) == obj_universum; }
00186
00187 void kernel_cache_init(void);
00188 void kernel_cache_finish(void);
00189 void go_altered(struct go* go);
00190 void go_cache_remove(struct go *go);
00191
00192 struct hanger* hanger_new_mc_copy(struct hanger *h);
00193
00194
00195 void clipboard_init(void);
00196 void clipboard_finish(void);
00197
00198 static inline struct hanger* hanger_get_same_hanger(struct go *go1, struct hanger *h, struct go *go2)
00199 { return go_get_hanger(go2, h - go_get_hanger(go1, 0)); }
00200
00201 static inline struct hanger* hanger_copy_clipboard(struct hanger* orig)
00202 {
00203 struct go *orig_go = hanger_get_go(orig), *copy_go = (struct go*)orig_go->temp_data;
00204 return copy_go ? hanger_get_same_hanger(orig_go, orig, copy_go) : hanger_new_mc_copy(orig);
00205 }
00206
00207
00208
00209
00210
00211
00212
00213
00214 void tsort_trans_start(struct obj_page *page);
00215 void tsort_trans_end(void);
00216 void tsort_trans_fail(struct obj_page *page);
00217
00218 void tsort_dirty(struct go *go);
00219 void tsort_dirty_hanger(struct hanger *h);
00220
00221 static inline void tsort_dirty_recompute(struct go *go)
00222 { TSORT_NO_RECOMPUTE_BEGIN tsort_dirty(go); TSORT_NO_RECOMPUTE_END }
00223
00224 static inline void tsort_dirty_hanger_recompute(struct hanger *h)
00225 { TSORT_NO_RECOMPUTE_BEGIN tsort_dirty_hanger(h); TSORT_NO_RECOMPUTE_END }
00226
00227 void tsort_remove(struct go *go, struct go_group *old_group, struct obj_page *page);
00228
00229 static inline int tsort_is_go_flag(struct go *go)
00230 { return go->flags & GOF_TSORT; }
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241 enum trans_undo
00242 {
00243
00244 TRANS_OBJ_SELECT,
00245 TRANS_OBJ_UNSELECT,
00246 TRANS_OBJ_LINK,
00247 TRANS_OBJ_UNLINK,
00248
00249
00250 TRANS_GO_SELECT,
00251 TRANS_GO_UNSELECT,
00252 TRANS_GO_LINK,
00253 TRANS_GO_UNLINK,
00254 TRANS_GO_RELINK,
00255 TRANS_ANCHOR_REHANG,
00256 TRANS_MOUSE_CLICK_MOVE,
00257
00258
00259 TRANS_PROP_CREATE,
00260 TRANS_PROP_CHANGE,
00261 TRANS_PROP_DELETE,
00262 TRANS_PROP_VIRTUAL,
00263 TRANS_PROP_VIRTUAL_START_UNDO,
00264 TRANS_PROP_VIRTUAL_END_UNDO,
00265
00266
00267 TRANS_DOC_SAVED_START,
00268 TRANS_DOC_SAVED_END,
00269
00270
00271 TRANS_UNDO = 0x20,
00272 TRANS_REDO = 0x40,
00273 };
00274
00276 struct trans
00277 {
00278 struct trans *prev;
00279 uns type;
00280 jmp_buf *jb;
00281 char* es;
00282 struct undo_kernel *uk;
00283 clist llog;
00284 struct obj_page *page;
00285 };
00286
00287
00289 struct undo_kernel
00290 {
00291 cnode nk;
00292 uns type;
00293 union undo_kernel_union
00294 {
00295 struct undo_kernel_union_obj_select
00296 {
00297 struct obj *obj;
00298 } obj_select;
00299 struct undo_kernel_union_obj_link
00300 {
00301 struct obj *obj, *father, *after;
00302 } obj_link;
00303 struct undo_kernel_union_go_link
00304 {
00305 struct go *go;
00306 struct go_group *group;
00307 struct go *after;
00308 } go_link;
00309 struct undo_kernel_union_go_select
00310 {
00311 struct go *go;
00312 } go_select;
00313 struct undo_kernel_union_anchor_rehang
00314 {
00315 struct hanger* hanger;
00316 struct anchor* anchor;
00317 } anchor_rehang;
00318 struct undo_kernel_union_mc_move
00319 {
00320 struct hanger_smart *mc;
00321 struct geom_point gp;
00322 } mc_move;
00323 struct undo_kernel_union_prop
00324 {
00325 struct o* o;
00326 struct prop* prop;
00327 prop_value value;
00328 } prop;
00329 struct undo_kernel_union_doc_save
00330 {
00331 struct obj_doc *doc;
00332 } doc_save;
00333 } u;
00334 };
00335
00336 struct trans_log
00337 {
00338 cnode nlog;
00339 uns when;
00340 void (*func)(uintptr_t arg);
00341 uintptr_t arg;
00342 };
00343
00344 void trans_delete_all(struct obj_page *page);
00345 void trans_command_kernel_delete(struct obj_page *page, struct undo_kernel* uk);
00346 struct trans* page_is_in_trans_stack(struct obj_page* page);
00347
00349 struct undo_kernel* trans_new_undo(uns trans_type);
00350 void trans_new_undo_prop_virtual(struct o* o, struct prop_virtual* prop, prop_value value);
00351 #define TRANS_NEW_UNDO(_type, _struct, ...) trans_new_undo(_type)->u._struct = (struct undo_kernel_union_ ## _struct) { __VA_ARGS__ }
00352 void trans_new_undo_start(struct o *o, struct prop_virtual *prop, prop_value value);
00353 void trans_new_undo_end(struct o *o, struct prop_virtual *prop, prop_value value);
00354 struct undo_kernel* trans_new_undo_page_changed(struct obj_doc *doc, struct undo_kernel *after, uns type);
00355
00356 #define WALK_TRANS_STACK(_walk) for(_walk = trans_present; _walk; _walk = _walk->prev)
00357 #define WALK_UNDO_GUI(_page, _walk) for(_walk = trans_get_first_gui(_page); _walk; _walk = trans_get_next_gui(_page, _walk))
00358 #define WALK_UNDO_KERNEL(_ug, _walk) for(_walk = trans_get_first_kernel(_ug); _walk; _walk = trans_get_next_kernel(_ug, _walk))
00359
00360 static inline struct undo_kernel* trans_get_first_kernel(struct undo_gui* u)
00361 { cnode *n = clist_head(&u->lk); return n ? SKIP_BACK(struct undo_kernel, nk, n) : NULL; }
00362 static inline struct undo_kernel* trans_get_next_kernel(struct undo_gui* ug, struct undo_kernel *uk)
00363 { cnode *n = clist_next(&ug->lk, &uk->nk); return n ? SKIP_BACK(struct undo_kernel, nk, n) : NULL; }
00364 static inline struct undo_kernel* trans_get_last_kernel(struct undo_gui* u)
00365 { cnode *n = clist_tail(&u->lk); return n ? SKIP_BACK(struct undo_kernel, nk, n) : NULL; }
00366 static inline struct undo_kernel* trans_get_prev_kernel(struct undo_gui* ug, struct undo_kernel *uk)
00367 { cnode *n = clist_prev(&ug->lk, &uk->nk); return n ? SKIP_BACK(struct undo_kernel, nk, n) : NULL; }
00368
00369 void obj_changed(struct obj *obj);
00370
00371 int trans_is_undo_write_protected(void);
00372 void trans_undo_limit_control(struct obj_page *page);
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382 #define WALK_GO_HOOK(_page, _walk) for(_walk = (struct go_hook*)(_page)->go_hooks.head.next; _walk; _walk = (struct go_hook*)_walk->n.next)
00383 #define WALK_TRANS_HOOK(_page, _walk) for(_walk = (struct trans_hook*)(_page)->trans_hooks.head.next; _walk; _walk = (struct trans_hook*)_walk->n.next)
00384
00385 void hook_call_obj_link(struct obj* obj);
00386 void hook_call_obj_unlink(struct obj* obj, struct obj* father, struct obj* next);
00387 void hook_call_obj_selected(struct obj* obj);
00388 void hook_call_obj_unselected(struct obj* obj);
00389
00390 void hook_call_go_link(struct go* go);
00391 void hook_call_go_unlink(struct go* go, struct go_group* owner, struct go *prev);
00392 void hook_call_go_relink(struct go* go, struct go_group *group, struct go *prev);
00393 void hook_call_go_selected(struct go* go);
00394 void hook_call_go_unselected(struct go* go);
00395
00396
00397 void hook_call_go_changed_generic(struct go* go, const struct changed_data_generic *d);
00398 void hook_call_go_changed(struct go* go, const struct geom_rectangle *old_bbox, const struct geom_rectangle *new_bbox);
00399 void hook_call_go_altered(struct go* go, const struct geom_rectangle *where);
00400 void hook_call_go_transformed(struct go* go, const struct geom_rectangle *old_bbox, const struct geom_rectangle *new_bbox, const struct geom_transform2 *t);
00401
00402 void hook_call_prop_create(struct o* o, struct prop* p);
00403 void hook_call_prop_change(struct o* o);
00404 void hook_call_prop_delete(struct o* o, struct prop* p);
00405
00406
00407 void hook_call_undo_new(struct obj_page* page, struct undo_gui* ug);
00408 void hook_call_undo_delete(struct obj_page* page, struct undo_gui* ug, struct undo_gui* prev_item);
00409 void hook_call_undo_update(struct obj_page* page, struct undo_gui* ug);
00410 void hook_call_undo(struct obj_page* page);
00411 void hook_call_redo(struct obj_page* page);
00412 void hook_call_saved(struct obj * obj);
00413
00414 void hook_call_unit_add(uns slot);
00415 void hook_call_unit_deleted(uns slot);
00416 void hook_call_unit_changed(uns slot);
00417 void hook_call_unit_default(uns def);
00418
00419 void hook_init(void);
00420 void hook_finish(void);
00421
00422
00423
00424
00425
00426
00427 void settings_init(void);
00428 void settings_finish(void);
00429
00430
00431
00432
00433
00434
00435
00436
00437 extern struct prop_virtual o_prop_name, *page_universum_prop_virtual;
00438 extern const uns prop_hash_name_size, go_rtree_bbox_size;
00439
00440 #endif