7f2872c0797fc5b8294893687c897f0fdc2d0db6
[blender-staging.git] / source / blender / blenkernel / intern / context.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
21  * All rights reserved.
22  *
23  * Contributor(s): Blender Foundation (2008).
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 #include "MEM_guardedalloc.h"
29
30 #include "DNA_ID.h"
31 #include "DNA_listBase.h"
32 #include "DNA_scene_types.h"
33 #include "DNA_screen_types.h"
34 #include "DNA_space_types.h"
35 #include "DNA_view3d_types.h"
36 #include "DNA_windowmanager_types.h"
37 #include "DNA_object_types.h"
38
39 #include "RNA_access.h"
40
41 #include "BLI_listbase.h"
42 #include "BLI_string.h"
43
44 #include "BKE_context.h"
45 #include "BKE_main.h"
46 #include "BKE_screen.h"
47 #include "BKE_global.h"
48
49 #include <string.h>
50
51 /* struct */
52
53 struct bContext {
54         int thread;
55
56         /* windowmanager context */
57         struct {
58                 struct wmWindowManager *manager;
59                 struct wmWindow *window;
60                 struct bScreen *screen;
61                 struct ScrArea *area;
62                 struct ARegion *region;
63                 struct ARegion *menu;
64                 struct bContextStore *store;
65         } wm;
66         
67         /* data context */
68         struct {
69                 struct Main *main;
70                 struct Scene *scene;
71
72                 int recursion;
73                 int py_init; /* true if python is initialized */
74                 void *py_context;
75         } data;
76         
77         /* data evaluation */
78         struct {
79                 int render;
80         } eval;
81 };
82
83 /* context */
84
85 bContext *CTX_create()
86 {
87         bContext *C;
88         
89         C= MEM_callocN(sizeof(bContext), "bContext");
90
91         return C;
92 }
93
94 bContext *CTX_copy(const bContext *C)
95 {
96         bContext *newC= MEM_dupallocN((void*)C);
97
98         return newC;
99 }
100
101 void CTX_free(bContext *C)
102 {
103         MEM_freeN(C);
104 }
105
106 /* store */
107
108 bContextStore *CTX_store_add(ListBase *contexts, char *name, PointerRNA *ptr)
109 {
110         bContextStoreEntry *entry;
111         bContextStore *ctx, *lastctx;
112
113         /* ensure we have a context to put the entry in, if it was already used
114          * we have to copy the context to ensure */
115         ctx= contexts->last;
116
117         if(!ctx || ctx->used) {
118                 if(ctx) {
119                         lastctx= ctx;
120                         ctx= MEM_dupallocN(lastctx);
121                         BLI_duplicatelist(&ctx->entries, &lastctx->entries);
122                 }
123                 else
124                         ctx= MEM_callocN(sizeof(bContextStore), "bContextStore");
125
126                 BLI_addtail(contexts, ctx);
127         }
128
129         entry= MEM_callocN(sizeof(bContextStoreEntry), "bContextStoreEntry");
130         BLI_strncpy(entry->name, name, sizeof(entry->name));
131         entry->ptr= *ptr;
132
133         BLI_addtail(&ctx->entries, entry);
134
135         return ctx;
136 }
137
138 void CTX_store_set(bContext *C, bContextStore *store)
139 {
140         C->wm.store= store;
141 }
142
143 bContextStore *CTX_store_copy(bContextStore *store)
144 {
145         bContextStore *ctx;
146
147         ctx= MEM_dupallocN(store);
148         BLI_duplicatelist(&ctx->entries, &store->entries);
149
150         return ctx;
151 }
152
153 void CTX_store_free(bContextStore *store)
154 {
155         BLI_freelistN(&store->entries);
156         MEM_freeN(store);
157 }
158
159 void CTX_store_free_list(ListBase *contexts)
160 {
161         bContextStore *ctx;
162
163         while((ctx= contexts->first)) {
164                 BLI_remlink(contexts, ctx);
165                 CTX_store_free(ctx);
166         }
167 }
168
169 /* is python initialied? */
170 int CTX_py_init_get(bContext *C)
171 {
172         return C->data.py_init;
173 }
174 void CTX_py_init_set(bContext *C, int value)
175 {
176         C->data.py_init= value;
177 }
178
179 void *CTX_py_dict_get(bContext *C)
180 {
181         return C->data.py_context;
182 }
183 void CTX_py_dict_set(bContext *C, void *value)
184 {
185         C->data.py_context= value;
186 }
187
188 /* window manager context */
189
190 wmWindowManager *CTX_wm_manager(const bContext *C)
191 {
192         return C->wm.manager;
193 }
194
195 wmWindow *CTX_wm_window(const bContext *C)
196 {
197         return C->wm.window;
198 }
199
200 bScreen *CTX_wm_screen(const bContext *C)
201 {
202         return C->wm.screen;
203 }
204
205 ScrArea *CTX_wm_area(const bContext *C)
206 {
207         return C->wm.area;
208 }
209
210 SpaceLink *CTX_wm_space_data(const bContext *C)
211 {
212         return (C->wm.area)? C->wm.area->spacedata.first: NULL;
213 }
214
215 ARegion *CTX_wm_region(const bContext *C)
216 {
217         return C->wm.region;
218 }
219
220 void *CTX_wm_region_data(const bContext *C)
221 {
222         return (C->wm.region)? C->wm.region->regiondata: NULL;
223 }
224
225 struct ARegion *CTX_wm_menu(const bContext *C)
226 {
227         return C->wm.menu;
228 }
229
230 struct ReportList *CTX_wm_reports(const bContext *C)
231 {
232         if (C->wm.manager)
233                 return &(C->wm.manager->reports);
234
235         return NULL;
236 }
237
238 View3D *CTX_wm_view3d(const bContext *C)
239 {
240         if(C->wm.area && C->wm.area->spacetype==SPACE_VIEW3D)
241                 return C->wm.area->spacedata.first;
242         return NULL;
243 }
244
245 RegionView3D *CTX_wm_region_view3d(const bContext *C)
246 {
247         if(C->wm.area && C->wm.area->spacetype==SPACE_VIEW3D)
248                 if(C->wm.region)
249                         return C->wm.region->regiondata;
250         return NULL;
251 }
252
253 struct SpaceText *CTX_wm_space_text(const bContext *C)
254 {
255         if(C->wm.area && C->wm.area->spacetype==SPACE_TEXT)
256                 return C->wm.area->spacedata.first;
257         return NULL;
258 }
259
260 struct SpaceConsole *CTX_wm_space_console(const bContext *C)
261 {
262         if(C->wm.area && C->wm.area->spacetype==SPACE_CONSOLE)
263                 return C->wm.area->spacedata.first;
264         return NULL;
265 }
266
267 struct SpaceImage *CTX_wm_space_image(const bContext *C)
268 {
269         if(C->wm.area && C->wm.area->spacetype==SPACE_IMAGE)
270                 return C->wm.area->spacedata.first;
271         return NULL;
272 }
273
274 struct SpaceButs *CTX_wm_space_buts(const bContext *C)
275 {
276         if(C->wm.area && C->wm.area->spacetype==SPACE_BUTS)
277                 return C->wm.area->spacedata.first;
278         return NULL;
279 }
280
281 struct SpaceFile *CTX_wm_space_file(const bContext *C)
282 {
283         if(C->wm.area && C->wm.area->spacetype==SPACE_FILE)
284                 return C->wm.area->spacedata.first;
285         return NULL;
286 }
287
288 struct SpaceSeq *CTX_wm_space_seq(const bContext *C)
289 {
290         if(C->wm.area && C->wm.area->spacetype==SPACE_SEQ)
291                 return C->wm.area->spacedata.first;
292         return NULL;
293 }
294
295 struct SpaceOops *CTX_wm_space_outliner(const bContext *C)
296 {
297         if(C->wm.area && C->wm.area->spacetype==SPACE_OUTLINER)
298                 return C->wm.area->spacedata.first;
299         return NULL;
300 }
301
302 struct SpaceNla *CTX_wm_space_nla(const bContext *C)
303 {
304         if(C->wm.area && C->wm.area->spacetype==SPACE_NLA)
305                 return C->wm.area->spacedata.first;
306         return NULL;
307 }
308
309 struct SpaceTime *CTX_wm_space_time(const bContext *C)
310 {
311         if(C->wm.area && C->wm.area->spacetype==SPACE_TIME)
312                 return C->wm.area->spacedata.first;
313         return NULL;
314 }
315
316 struct SpaceNode *CTX_wm_space_node(const bContext *C)
317 {
318         if(C->wm.area && C->wm.area->spacetype==SPACE_NODE)
319                 return C->wm.area->spacedata.first;
320         return NULL;
321 }
322
323 struct SpaceLogic *CTX_wm_space_logic(const bContext *C)
324 {
325         if(C->wm.area && C->wm.area->spacetype==SPACE_LOGIC)
326                 return C->wm.area->spacedata.first;
327         return NULL;
328 }
329
330 struct SpaceIpo *CTX_wm_space_graph(const bContext *C)
331 {
332         if(C->wm.area && C->wm.area->spacetype==SPACE_IPO)
333                 return C->wm.area->spacedata.first;
334         return NULL;
335 }
336
337 struct SpaceAction *CTX_wm_space_action(const bContext *C)
338 {
339         if(C->wm.area && C->wm.area->spacetype==SPACE_ACTION)
340                 return C->wm.area->spacedata.first;
341         return NULL;
342 }
343
344 struct SpaceInfo *CTX_wm_space_info(const bContext *C)
345 {
346         if(C->wm.area && C->wm.area->spacetype==SPACE_INFO)
347                 return C->wm.area->spacedata.first;
348         return NULL;
349 }
350
351 struct SpaceUserPref *CTX_wm_space_userpref(const bContext *C)
352 {
353         if(C->wm.area && C->wm.area->spacetype==SPACE_USERPREF)
354                 return C->wm.area->spacedata.first;
355         return NULL;
356 }
357
358 void CTX_wm_manager_set(bContext *C, wmWindowManager *wm)
359 {
360         C->wm.manager= wm;
361         C->wm.window= NULL;
362         C->wm.screen= NULL;
363         C->wm.area= NULL;
364         C->wm.region= NULL;
365 }
366
367 void CTX_wm_window_set(bContext *C, wmWindow *win)
368 {
369         C->wm.window= win;
370         C->wm.screen= (win)? win->screen: NULL;
371         C->data.scene= (C->wm.screen)? C->wm.screen->scene: NULL;
372         C->wm.area= NULL;
373         C->wm.region= NULL;
374 }
375
376 void CTX_wm_screen_set(bContext *C, bScreen *screen)
377 {
378         C->wm.screen= screen;
379         C->data.scene= (C->wm.screen)? C->wm.screen->scene: NULL;
380         C->wm.area= NULL;
381         C->wm.region= NULL;
382 }
383
384 void CTX_wm_area_set(bContext *C, ScrArea *area)
385 {
386         C->wm.area= area;
387         C->wm.region= NULL;
388 }
389
390 void CTX_wm_region_set(bContext *C, ARegion *region)
391 {
392         C->wm.region= region;
393 }
394
395 void CTX_wm_menu_set(bContext *C, ARegion *menu)
396 {
397         C->wm.menu= menu;
398 }
399
400 /* data context utility functions */
401
402 struct bContextDataResult {
403         PointerRNA ptr;
404         ListBase list;
405         const char **dir;
406 };
407
408 static int ctx_data_get(bContext *C, const char *member, bContextDataResult *result)
409 {
410         int done= 0, recursion= C->data.recursion;
411
412         memset(result, 0, sizeof(bContextDataResult));
413
414         if(CTX_py_dict_get(C)) {
415                 return bpy_context_get(C, member, result);
416         }
417
418         /* we check recursion to ensure that we do not get infinite
419          * loops requesting data from ourselfs in a context callback */
420         if(!done && recursion < 1 && C->wm.store) {
421                 bContextStoreEntry *entry;
422
423                 C->data.recursion= 1;
424
425                 for(entry=C->wm.store->entries.first; entry; entry=entry->next) {
426                         if(strcmp(entry->name, member) == 0) {
427                                 result->ptr= entry->ptr;
428                                 done= 1;
429                         }
430                 }
431         }
432         if(!done && recursion < 2 && C->wm.region) {
433                 C->data.recursion= 2;
434                 if(C->wm.region->type && C->wm.region->type->context)
435                         done= C->wm.region->type->context(C, member, result);
436         }
437         if(!done && recursion < 3 && C->wm.area) {
438                 C->data.recursion= 3;
439                 if(C->wm.area->type && C->wm.area->type->context)
440                         done= C->wm.area->type->context(C, member, result);
441         }
442         if(!done && recursion < 4 && C->wm.screen) {
443                 bContextDataCallback cb= C->wm.screen->context;
444                 C->data.recursion= 4;
445                 if(cb)
446                         done= cb(C, member, result);
447         }
448
449         C->data.recursion= recursion;
450
451         return done;
452 }
453
454 static void *ctx_data_pointer_get(const bContext *C, const char *member)
455 {
456         bContextDataResult result;
457
458         if(C && ctx_data_get((bContext*)C, member, &result))
459                 return result.ptr.data;
460
461         return NULL;
462 }
463
464 static int ctx_data_pointer_verify(const bContext *C, const char *member, void **pointer)
465 {
466         bContextDataResult result;
467
468         if(ctx_data_get((bContext*)C, member, &result)) {
469                 *pointer= result.ptr.data;
470                 return 1;
471         }
472         else {
473                 *pointer= NULL;
474                 return 0;
475         }
476 }
477
478 static int ctx_data_collection_get(const bContext *C, const char *member, ListBase *list)
479 {
480         bContextDataResult result;
481
482         if(ctx_data_get((bContext*)C, member, &result)) {
483                 *list= result.list;
484                 return 1;
485         }
486
487         list->first= NULL;
488         list->last= NULL;
489
490         return 0;
491 }
492
493 PointerRNA CTX_data_pointer_get(const bContext *C, const char *member)
494 {
495         bContextDataResult result;
496
497         if(ctx_data_get((bContext*)C, member, &result))
498                 return result.ptr;
499         else
500                 return PointerRNA_NULL;
501 }
502
503 PointerRNA CTX_data_pointer_get_type(const bContext *C, const char *member, StructRNA *type)
504 {
505         PointerRNA ptr = CTX_data_pointer_get(C, member);
506
507         if(ptr.data && RNA_struct_is_a(ptr.type, type))
508                 return ptr;
509         
510         return PointerRNA_NULL;
511 }
512
513 ListBase CTX_data_collection_get(const bContext *C, const char *member)
514 {
515         bContextDataResult result;
516
517         if(ctx_data_get((bContext*)C, member, &result)) {
518                 return result.list;
519         }
520         else {
521                 ListBase list;
522                 memset(&list, 0, sizeof(list));
523                 return list;
524         }
525 }
526
527 void CTX_data_get(const bContext *C, const char *member, PointerRNA *r_ptr, ListBase *r_lb)
528 {
529         bContextDataResult result;
530
531         if(ctx_data_get((bContext*)C, member, &result)) {
532                 *r_ptr= result.ptr;
533                 *r_lb= result.list;
534         }
535         else {
536                 memset(r_ptr, 0, sizeof(*r_ptr));
537                 memset(r_lb, 0, sizeof(*r_lb));
538         }
539 }
540
541 static void data_dir_add(ListBase *lb, const char *member)
542 {
543         LinkData *link;
544
545         if(strcmp(member, "scene") == 0) /* exception */
546                 return;
547
548         for(link=lb->first; link; link=link->next)
549                 if(strcmp(link->data, member) == 0)
550                         return;
551         
552         link= MEM_callocN(sizeof(LinkData), "LinkData");
553         link->data= (void*)member;
554         BLI_addtail(lb, link);
555 }
556
557 ListBase CTX_data_dir_get(const bContext *C)
558 {
559         bContextDataResult result;
560         ListBase lb;
561         int a;
562
563         memset(&lb, 0, sizeof(lb));
564
565         if(C->wm.store) {
566                 bContextStoreEntry *entry;
567
568                 for(entry=C->wm.store->entries.first; entry; entry=entry->next)
569                         data_dir_add(&lb, entry->name);
570         }
571         if(C->wm.region && C->wm.region->type && C->wm.region->type->context) {
572                 memset(&result, 0, sizeof(result));
573                 C->wm.region->type->context(C, "", &result);
574
575                 if(result.dir)
576                         for(a=0; result.dir[a]; a++)
577                                 data_dir_add(&lb, result.dir[a]);
578         }
579         if(C->wm.area && C->wm.area->type && C->wm.area->type->context) {
580                 memset(&result, 0, sizeof(result));
581                 C->wm.area->type->context(C, "", &result);
582
583                 if(result.dir)
584                         for(a=0; result.dir[a]; a++)
585                                 data_dir_add(&lb, result.dir[a]);
586         }
587         if(C->wm.screen && C->wm.screen->context) {
588                 bContextDataCallback cb= C->wm.screen->context;
589                 memset(&result, 0, sizeof(result));
590                 cb(C, "", &result);
591
592                 if(result.dir)
593                         for(a=0; result.dir[a]; a++)
594                                 data_dir_add(&lb, result.dir[a]);
595         }
596
597         return lb;
598 }
599
600 int CTX_data_equals(const char *member, const char *str)
601 {
602         return (strcmp(member, str) == 0);
603 }
604
605 int CTX_data_dir(const char *member)
606 {
607         return (strcmp(member, "") == 0);
608 }
609
610 void CTX_data_id_pointer_set(bContextDataResult *result, ID *id)
611 {
612         RNA_id_pointer_create(id, &result->ptr);
613 }
614
615 void CTX_data_pointer_set(bContextDataResult *result, ID *id, StructRNA *type, void *data)
616 {
617         RNA_pointer_create(id, type, data, &result->ptr);
618 }
619
620 void CTX_data_id_list_add(bContextDataResult *result, ID *id)
621 {
622         CollectionPointerLink *link;
623
624         link= MEM_callocN(sizeof(CollectionPointerLink), "CTX_data_id_list_add");
625         RNA_id_pointer_create(id, &link->ptr);
626
627         BLI_addtail(&result->list, link);
628 }
629
630 void CTX_data_list_add(bContextDataResult *result, ID *id, StructRNA *type, void *data)
631 {
632         CollectionPointerLink *link;
633
634         link= MEM_callocN(sizeof(CollectionPointerLink), "CTX_data_list_add");
635         RNA_pointer_create(id, type, data, &link->ptr);
636
637         BLI_addtail(&result->list, link);
638 }
639
640 int ctx_data_list_count(const bContext *C, int (*func)(const bContext*, ListBase*))
641 {
642         ListBase list;
643
644         if(func(C, &list)) {
645                 int tot= BLI_countlist(&list);
646                 BLI_freelistN(&list);
647                 return tot;
648         }
649         else
650                 return 0;
651 }
652
653 void CTX_data_dir_set(bContextDataResult *result, const char **dir)
654 {
655         result->dir= dir;
656 }
657
658 /* data context */
659
660 Main *CTX_data_main(const bContext *C)
661 {
662         Main *bmain;
663
664         if(ctx_data_pointer_verify(C, "main", (void*)&bmain))
665                 return bmain;
666         else
667                 return C->data.main;
668 }
669
670 void CTX_data_main_set(bContext *C, Main *bmain)
671 {
672         C->data.main= bmain;
673 }
674
675 Scene *CTX_data_scene(const bContext *C)
676 {
677         Scene *scene;
678
679         if(ctx_data_pointer_verify(C, "scene", (void*)&scene))
680                 return scene;
681         else
682                 return C->data.scene;
683 }
684
685 int CTX_data_mode_enum(const bContext *C)
686 {
687         Object *obedit= CTX_data_edit_object(C);
688
689         if(obedit) {
690                 switch(obedit->type) {
691                         case OB_MESH:
692                                 return CTX_MODE_EDIT_MESH;
693                         case OB_CURVE:
694                                 return CTX_MODE_EDIT_CURVE;
695                         case OB_SURF:
696                                 return CTX_MODE_EDIT_SURFACE;
697                         case OB_FONT:
698                                 return CTX_MODE_EDIT_TEXT;
699                         case OB_ARMATURE:
700                                 return CTX_MODE_EDIT_ARMATURE;
701                         case OB_MBALL:
702                                 return CTX_MODE_EDIT_METABALL;
703                         case OB_LATTICE:
704                                 return CTX_MODE_EDIT_LATTICE;
705                 }
706         }
707         else {
708                 Object *ob = CTX_data_active_object(C);
709
710                 if(ob) {
711                         if(ob->mode & OB_MODE_POSE) return CTX_MODE_POSE;
712                         else if(ob->mode & OB_MODE_SCULPT)  return CTX_MODE_SCULPT;
713                         else if(ob->mode & OB_MODE_WEIGHT_PAINT) return CTX_MODE_PAINT_WEIGHT;
714                         else if(ob->mode & OB_MODE_VERTEX_PAINT) return CTX_MODE_PAINT_VERTEX;
715                         else if(ob->mode & OB_MODE_TEXTURE_PAINT) return CTX_MODE_PAINT_TEXTURE;
716                         else if(ob->mode & OB_MODE_PARTICLE_EDIT) return CTX_MODE_PARTICLE;
717                 }
718         }
719
720         return CTX_MODE_OBJECT;
721 }
722
723
724 /* would prefer if we can use the enum version below over this one - Campbell */
725 /* must be aligned with above enum  */
726 static char *data_mode_strings[] = {
727         "mesh_edit",
728         "curve_edit",
729         "surface_edit",
730         "text_edit",
731         "armature_edit",
732         "mball_edit",
733         "lattice_edit",
734         "posemode",
735         "sculpt_mode",
736         "weightpaint",
737         "vertexpaint",
738         "texturepaint",
739         "particlemode",
740         "objectmode",
741         0
742 };
743 char *CTX_data_mode_string(const bContext *C)
744 {
745         return data_mode_strings[CTX_data_mode_enum(C)];
746 }
747
748 void CTX_data_scene_set(bContext *C, Scene *scene)
749 {
750         C->data.scene= scene;
751 }
752
753 ToolSettings *CTX_data_tool_settings(const bContext *C)
754 {
755         Scene *scene = CTX_data_scene(C);
756
757         if(scene)
758                 return scene->toolsettings;
759         else
760                 return NULL;
761 }
762
763 int CTX_data_selected_nodes(const bContext *C, ListBase *list)
764 {
765         return ctx_data_collection_get(C, "selected_nodes", list);
766 }
767
768 int CTX_data_selected_editable_objects(const bContext *C, ListBase *list)
769 {
770         return ctx_data_collection_get(C, "selected_editable_objects", list);
771 }
772
773 int CTX_data_selected_editable_bases(const bContext *C, ListBase *list)
774 {
775         return ctx_data_collection_get(C, "selected_editable_bases", list);
776 }
777
778 int CTX_data_selected_objects(const bContext *C, ListBase *list)
779 {
780         return ctx_data_collection_get(C, "selected_objects", list);
781 }
782
783 int CTX_data_selected_bases(const bContext *C, ListBase *list)
784 {
785         return ctx_data_collection_get(C, "selected_bases", list);
786 }
787
788 int CTX_data_visible_objects(const bContext *C, ListBase *list)
789 {
790         return ctx_data_collection_get(C, "visible_objects", list);
791 }
792
793 int CTX_data_visible_bases(const bContext *C, ListBase *list)
794 {
795         return ctx_data_collection_get(C, "visible_bases", list);
796 }
797
798 int CTX_data_selectable_objects(const bContext *C, ListBase *list)
799 {
800         return ctx_data_collection_get(C, "selectable_objects", list);
801 }
802
803 int CTX_data_selectable_bases(const bContext *C, ListBase *list)
804 {
805         return ctx_data_collection_get(C, "selectable_bases", list);
806 }
807
808 struct Object *CTX_data_active_object(const bContext *C)
809 {
810         return ctx_data_pointer_get(C, "active_object");
811 }
812
813 struct Base *CTX_data_active_base(const bContext *C)
814 {
815         return ctx_data_pointer_get(C, "active_base");
816 }
817
818 struct Object *CTX_data_edit_object(const bContext *C)
819 {
820         return ctx_data_pointer_get(C, "edit_object");
821 }
822
823 struct Image *CTX_data_edit_image(const bContext *C)
824 {
825         return ctx_data_pointer_get(C, "edit_image");
826 }
827
828 struct Text *CTX_data_edit_text(const bContext *C)
829 {
830         return ctx_data_pointer_get(C, "edit_text");
831 }
832
833 struct EditBone *CTX_data_active_bone(const bContext *C)
834 {
835         return ctx_data_pointer_get(C, "active_bone");
836 }
837
838 int CTX_data_selected_bones(const bContext *C, ListBase *list)
839 {
840         return ctx_data_collection_get(C, "selected_bones", list);
841 }
842
843 int CTX_data_selected_editable_bones(const bContext *C, ListBase *list)
844 {
845         return ctx_data_collection_get(C, "selected_editable_bones", list);
846 }
847
848 int CTX_data_visible_bones(const bContext *C, ListBase *list)
849 {
850         return ctx_data_collection_get(C, "visible_bones", list);
851 }
852
853 int CTX_data_editable_bones(const bContext *C, ListBase *list)
854 {
855         return ctx_data_collection_get(C, "editable_bones", list);
856 }
857
858 struct bPoseChannel *CTX_data_active_pchan(const bContext *C)
859 {
860         return ctx_data_pointer_get(C, "active_pchan");
861 }
862
863 int CTX_data_selected_pchans(const bContext *C, ListBase *list)
864 {
865         return ctx_data_collection_get(C, "selected_pchans", list);
866 }
867
868 int CTX_data_visible_pchans(const bContext *C, ListBase *list)
869 {
870         return ctx_data_collection_get(C, "visible_pchans", list);
871 }
872