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