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