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