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