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