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