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