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