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