/** * \brief get the ID from the screen. * */ static void datadropper_id_sample_pt(bContext *C, DataDropper *ddr, int mx, int my, ID **r_id) { /* we could use some clever */ wmWindow *win = CTX_wm_window(C); ScrArea *sa; ScrArea *area_prev = CTX_wm_area(C); ARegion *ar_prev = CTX_wm_region(C); ddr->name[0] = '\0'; for (sa = win->screen->areabase.first; sa; sa = sa->next) { if (BLI_rcti_isect_pt(&sa->totrct, mx, my)) { if (sa->spacetype == SPACE_VIEW3D) { ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW); if (ar && BLI_rcti_isect_pt(&ar->winrct, mx, my)) { int mval[2] = {mx - ar->winrct.xmin, my - ar->winrct.ymin}; Base *base; CTX_wm_area_set(C, sa); CTX_wm_region_set(C, ar); /* grr, always draw else we leave stale text */ ED_region_tag_redraw(ar); base = ED_view3d_give_base_under_cursor(C, mval); if (base) { Object *ob = base->object; ID *id = NULL; if (ddr->idcode == ID_OB) { id = (ID *)ob; } else if (ob->data) { if (GS(((ID *)ob->data)->name) == ddr->idcode) { id = (ID *)ob->data; } else { BLI_snprintf(ddr->name, sizeof(ddr->name), "Incompatible, expected a %s", ddr->idcode_name); } } if (id) { BLI_snprintf(ddr->name, sizeof(ddr->name), "%s: %s", ddr->idcode_name, id->name + 2); *r_id = id; } break; } } } } } CTX_wm_area_set(C, area_prev); CTX_wm_region_set(C, ar_prev); }
static void rna_Area_type_update(bContext *C, PointerRNA *ptr) { wmWindowManager *wm = CTX_wm_manager(C); wmWindow *win; bScreen *sc = (bScreen *)ptr->id.data; ScrArea *sa = (ScrArea *)ptr->data; /* XXX this call still use context, so we trick it to work in the right context */ for (win = wm->windows.first; win; win = win->next) { if (sc == win->screen) { wmWindow *prevwin = CTX_wm_window(C); ScrArea *prevsa = CTX_wm_area(C); ARegion *prevar = CTX_wm_region(C); CTX_wm_window_set(C, win); CTX_wm_area_set(C, sa); CTX_wm_region_set(C, NULL); ED_area_newspace(C, sa, sa->butspacetype); ED_area_tag_redraw(sa); CTX_wm_window_set(C, prevwin); CTX_wm_area_set(C, prevsa); CTX_wm_region_set(C, prevar); break; } } }
static int ui_button_press_invoke(bContext *C, wmOperator *op, const wmEvent *event) { const bool skip_depressed = RNA_boolean_get(op->ptr, "skip_depressed"); ARegion *ar_prev = CTX_wm_region(C); ARegion *ar = region_event_inside_for_screen(C, &event->x); if (ar == NULL) { ar = ar_prev; } CTX_wm_region_set(C, ar); uiBut *but = UI_context_active_but_get(C); CTX_wm_region_set(C, ar_prev); if (but == NULL) { return OPERATOR_PASS_THROUGH; } if (skip_depressed && (but->flag & (UI_SELECT | UI_SELECT_DRAW))) { return OPERATOR_PASS_THROUGH; } /* Weak, this is a workaround for 'UI_but_is_tool', which checks the operator type, * having this avoids a minor drawing glitch. */ void *but_optype = but->optype; UI_but_execute(C, but); but->optype = but_optype; WM_event_add_mousemove(C); return OPERATOR_FINISHED; }
/** * \brief get the ID from the screen. */ static void depthdropper_depth_sample_pt( bContext *C, DepthDropper *ddr, int mx, int my, float *r_depth) { /* we could use some clever */ bScreen *screen = CTX_wm_screen(C); ScrArea *sa = BKE_screen_find_area_xy(screen, SPACE_TYPE_ANY, mx, my); Scene *scene = CTX_data_scene(C); ScrArea *area_prev = CTX_wm_area(C); ARegion *ar_prev = CTX_wm_region(C); ddr->name[0] = '\0'; if (sa) { if (sa->spacetype == SPACE_VIEW3D) { ARegion *ar = BKE_area_find_region_xy(sa, RGN_TYPE_WINDOW, mx, my); if (ar) { struct Depsgraph *depsgraph = CTX_data_depsgraph(C); View3D *v3d = sa->spacedata.first; RegionView3D *rv3d = ar->regiondata; /* weak, we could pass in some reference point */ const float *view_co = v3d->camera ? v3d->camera->obmat[3] : rv3d->viewinv[3]; const int mval[2] = {mx - ar->winrct.xmin, my - ar->winrct.ymin}; float co[3]; CTX_wm_area_set(C, sa); CTX_wm_region_set(C, ar); /* grr, always draw else we leave stale text */ ED_region_tag_redraw(ar); view3d_operator_needs_opengl(C); if (ED_view3d_autodist(depsgraph, ar, v3d, mval, co, true, NULL)) { const float mval_center_fl[2] = {(float)ar->winx / 2, (float)ar->winy / 2}; float co_align[3]; /* quick way to get view-center aligned point */ ED_view3d_win_to_3d(v3d, ar, co, mval_center_fl, co_align); *r_depth = len_v3v3(view_co, co_align); bUnit_AsString2(ddr->name, sizeof(ddr->name), (double)*r_depth, 4, B_UNIT_LENGTH, &scene->unit, false); } else { BLI_strncpy(ddr->name, "Nothing under cursor", sizeof(ddr->name)); } } } } CTX_wm_area_set(C, area_prev); CTX_wm_region_set(C, ar_prev); }
static void rna_Area_type_update(bContext *C, PointerRNA *ptr) { wmWindowManager *wm = CTX_wm_manager(C); wmWindow *win; bScreen *sc = (bScreen *)ptr->id.data; ScrArea *sa = (ScrArea *)ptr->data; /* XXX this call still use context, so we trick it to work in the right context */ for (win = wm->windows.first; win; win = win->next) { if (sc == win->screen) { wmWindow *prevwin = CTX_wm_window(C); ScrArea *prevsa = CTX_wm_area(C); ARegion *prevar = CTX_wm_region(C); CTX_wm_window_set(C, win); CTX_wm_area_set(C, sa); CTX_wm_region_set(C, NULL); ED_area_newspace(C, sa, sa->butspacetype, true); ED_area_tag_redraw(sa); /* It is possible that new layers becomes visible. */ if (sa->spacetype == SPACE_VIEW3D) { DAG_on_visible_update(CTX_data_main(C), false); } CTX_wm_window_set(C, prevwin); CTX_wm_area_set(C, prevsa); CTX_wm_region_set(C, prevar); break; } } }
/* TODO de-duplicate redo panel functions - campbell */ static void view3d_panel_operator_redo(const bContext *C, Panel *pa) { wmOperator *op = WM_operator_last_redo(C); ARegion *ar; ARegion *ar1; if (op == NULL) { return; } /* keep in sync with logic in ED_undo_operator_repeat() */ ar = CTX_wm_region(C); ar1 = BKE_area_find_region_active_win(CTX_wm_area(C)); if (ar1) CTX_wm_region_set((bContext *)C, ar1); if (WM_operator_poll((bContext *)C, op->type)) { uiBlock *block = uiLayoutGetBlock(pa->layout); if (!WM_operator_check_ui_enabled(C, op->type->name)) uiLayoutSetEnabled(pa->layout, false); /* note, blockfunc is a default but->func, use Handle func to allow button callbacks too */ UI_block_func_handle_set(block, ED_undo_operator_repeat_cb_evt, op); view3d_panel_operator_redo_operator(C, pa, op); } /* set region back */ CTX_wm_region_set((bContext *)C, ar); }
/** * \brief get the ID from the screen. */ static void datadropper_id_sample_pt(bContext *C, DataDropper *ddr, int mx, int my, ID **r_id) { /* we could use some clever */ bScreen *screen = CTX_wm_screen(C); ScrArea *sa = BKE_screen_find_area_xy(screen, -1, mx, my); ScrArea *area_prev = CTX_wm_area(C); ARegion *ar_prev = CTX_wm_region(C); ddr->name[0] = '\0'; if (sa) { if (sa->spacetype == SPACE_VIEW3D) { ARegion *ar = BKE_area_find_region_xy(sa, RGN_TYPE_WINDOW, mx, my); if (ar) { const int mval[2] = {mx - ar->winrct.xmin, my - ar->winrct.ymin}; Base *base; CTX_wm_area_set(C, sa); CTX_wm_region_set(C, ar); /* grr, always draw else we leave stale text */ ED_region_tag_redraw(ar); base = ED_view3d_give_base_under_cursor(C, mval); if (base) { Object *ob = base->object; ID *id = NULL; if (ddr->idcode == ID_OB) { id = (ID *)ob; } else if (ob->data) { if (GS(((ID *)ob->data)->name) == ddr->idcode) { id = (ID *)ob->data; } else { BLI_snprintf( ddr->name, sizeof(ddr->name), "Incompatible, expected a %s", ddr->idcode_name); } } PointerRNA idptr; RNA_id_pointer_create(id, &idptr); if (id && RNA_property_pointer_poll(&ddr->ptr, ddr->prop, &idptr)) { BLI_snprintf(ddr->name, sizeof(ddr->name), "%s: %s", ddr->idcode_name, id->name + 2); *r_id = id; } } } } } CTX_wm_area_set(C, area_prev); CTX_wm_region_set(C, ar_prev); }
static void screen_opengl_render_end(bContext *C, OGLRender *oglrender) { Main *bmain = CTX_data_main(C); Scene *scene = oglrender->scene; if (oglrender->mh) { if (BKE_imtype_is_movie(scene->r.im_format.imtype)) oglrender->mh->end_movie(); } if (oglrender->timer) { /* exec will not have a timer */ scene->r.cfra = oglrender->cfrao; BKE_scene_update_for_newframe(bmain, scene, screen_opengl_layers(oglrender)); WM_event_remove_timer(oglrender->wm, oglrender->win, oglrender->timer); } WM_cursor_modal_restore(oglrender->win); WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, oglrender->scene); U.obcenter_dia = oglrender->obcenter_dia_back; GPU_offscreen_free(oglrender->ofs); oglrender->scene->customdata_mask_modal = 0; CTX_wm_area_set(C, oglrender->prevsa); CTX_wm_region_set(C, oglrender->prevar); MEM_freeN(oglrender); }
bool ED_view3d_context_activate(bContext *C) { bScreen *sc = CTX_wm_screen(C); ScrArea *sa = CTX_wm_area(C); ARegion *ar; /* sa can be NULL when called from python */ if (sa == NULL || sa->spacetype != SPACE_VIEW3D) for (sa = sc->areabase.first; sa; sa = sa->next) if (sa->spacetype == SPACE_VIEW3D) break; if (!sa) return false; for (ar = sa->regionbase.first; ar; ar = ar->next) if (ar->regiontype == RGN_TYPE_WINDOW) break; if (!ar) return false; /* bad context switch .. */ CTX_wm_area_set(C, sa); CTX_wm_region_set(C, ar); return true; }
bool ED_view3d_context_activate(bContext *C) { bScreen *sc = CTX_wm_screen(C); ScrArea *sa = CTX_wm_area(C); ARegion *ar; /* sa can be NULL when called from python */ if (sa == NULL || sa->spacetype != SPACE_VIEW3D) { sa = BKE_screen_find_big_area(sc, SPACE_VIEW3D, 0); } if (sa == NULL) { return false; } ar = BKE_area_find_region_active_win(sa); if (ar == NULL) { return false; } /* bad context switch .. */ CTX_wm_area_set(C, sa); CTX_wm_region_set(C, ar); return true; }
void WM_redraw_windows(bContext *C) { wmWindow *win_prev = CTX_wm_window(C); ScrArea *area_prev = CTX_wm_area(C); ARegion *ar_prev = CTX_wm_region(C); wm_draw_update(C); CTX_wm_window_set(C, win_prev); CTX_wm_area_set(C, area_prev); CTX_wm_region_set(C, ar_prev); }
static void wm_method_draw_full(bContext *C, wmWindow *win) { bScreen *screen = win->screen; ScrArea *sa; ARegion *ar; /* draw area regions */ for (sa = screen->areabase.first; sa; sa = sa->next) { CTX_wm_area_set(C, sa); for (ar = sa->regionbase.first; ar; ar = ar->next) { if (ar->swinid) { CTX_wm_region_set(C, ar); ED_region_do_draw(C, ar); ar->do_draw = false; wm_paintcursor_draw(C, ar); CTX_wm_region_set(C, NULL); } } wm_area_mark_invalid_backbuf(sa); CTX_wm_area_set(C, NULL); } ED_screen_draw(win); win->screen->do_draw = false; /* draw overlapping regions */ for (ar = screen->regionbase.first; ar; ar = ar->next) { if (ar->swinid) { CTX_wm_menu_set(C, ar); ED_region_do_draw(C, ar); ar->do_draw = false; CTX_wm_menu_set(C, NULL); } } if (screen->do_draw_gesture) wm_gesture_draw(win); }
static void ui_block_region_refresh(const bContext *C, ARegion *ar) { ScrArea *ctx_area = CTX_wm_area(C); ARegion *ctx_region = CTX_wm_region(C); uiBlock *block; if (ar->do_draw & RGN_DRAW_REFRESH_UI) { ScrArea *handle_ctx_area; ARegion *handle_ctx_region; uiBlock *block_next; ar->do_draw &= ~RGN_DRAW_REFRESH_UI; for (block = ar->uiblocks.first; block; block = block_next) { block_next = block->next; uiPopupBlockHandle *handle = block->handle; if (handle->can_refresh) { handle_ctx_area = handle->ctx_area; handle_ctx_region = handle->ctx_region; if (handle_ctx_area) { CTX_wm_area_set((bContext *)C, handle_ctx_area); } if (handle_ctx_region) { CTX_wm_region_set((bContext *)C, handle_ctx_region); } uiBut *but = handle->popup_create_vars.but; ARegion *butregion = handle->popup_create_vars.butregion; ui_popup_block_refresh((bContext *)C, handle, butregion, but); } } } CTX_wm_area_set((bContext *)C, ctx_area); CTX_wm_region_set((bContext *)C, ctx_region); }
void ED_render_scene_update(Main *bmain, Scene *scene, int updated) { /* viewport rendering update on data changes, happens after depsgraph * updates if there was any change. context is set to the 3d view */ bContext *C; bScreen *sc; ScrArea *sa; ARegion *ar; /* don't do this render engine update if we're updating the scene from * other threads doing e.g. rendering or baking jobs */ if (!BLI_thread_is_main()) return; C = CTX_create(); CTX_data_main_set(C, bmain); CTX_data_scene_set(C, scene); CTX_wm_manager_set(C, bmain->wm.first); for (sc = bmain->screen.first; sc; sc = sc->id.next) { for (sa = sc->areabase.first; sa; sa = sa->next) { if (sa->spacetype != SPACE_VIEW3D) continue; for (ar = sa->regionbase.first; ar; ar = ar->next) { RegionView3D *rv3d; RenderEngine *engine; if (ar->regiontype != RGN_TYPE_WINDOW) continue; rv3d = ar->regiondata; engine = rv3d->render_engine; if (engine && (updated || (engine->flag & RE_ENGINE_DO_UPDATE))) { CTX_wm_screen_set(C, sc); CTX_wm_area_set(C, sa); CTX_wm_region_set(C, ar); engine->flag &= ~RE_ENGINE_DO_UPDATE; engine->type->view_update(engine, C); } } } } CTX_free(C); }
static void screen_opengl_render_end(bContext *C, OGLRender *oglrender) { Main *bmain = CTX_data_main(C); Scene *scene = oglrender->scene; size_t i; if (oglrender->mh) { if (BKE_imtype_is_movie(scene->r.im_format.imtype)) { for (i = 0; i < oglrender->totvideos; i++) { oglrender->mh->end_movie(oglrender->movie_ctx_arr[i]); oglrender->mh->context_free(oglrender->movie_ctx_arr[i]); } } if (oglrender->movie_ctx_arr) { MEM_freeN(oglrender->movie_ctx_arr); } } if (oglrender->timer) { /* exec will not have a timer */ scene->r.cfra = oglrender->cfrao; BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene, screen_opengl_layers(oglrender)); WM_event_remove_timer(oglrender->wm, oglrender->win, oglrender->timer); } WM_cursor_modal_restore(oglrender->win); WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, oglrender->scene); if (oglrender->fx) GPU_fx_compositor_destroy(oglrender->fx); GPU_offscreen_free(oglrender->ofs); oglrender->scene->customdata_mask_modal = 0; CTX_wm_area_set(C, oglrender->prevsa); CTX_wm_region_set(C, oglrender->prevar); MEM_freeN(oglrender); }
static void wm_method_draw_triple_multiview(bContext *C, wmWindow *win, StereoViews sview) { wmWindowManager *wm = CTX_wm_manager(C); wmDrawData *drawdata; wmDrawTriple *triple_data, *triple_all; bScreen *screen = win->screen; ScrArea *sa; ARegion *ar; int copytex = false; int id; /* we store the triple_data in sequence to triple_all */ for (id = 0; id < 2; id++) { drawdata = BLI_findlink(&win->drawdata, (sview * 2) + id); if (drawdata && drawdata->triple) { if (id == 0) { glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); wmSubWindowSet(win, screen->mainwin); wm_triple_draw_textures(win, drawdata->triple, 1.0f); } } else { /* we run it when we start OR when we turn stereo on */ if (drawdata == NULL) { drawdata = MEM_callocN(sizeof(wmDrawData), "wmDrawData"); BLI_addtail(&win->drawdata, drawdata); } drawdata->triple = MEM_callocN(sizeof(wmDrawTriple), "wmDrawTriple"); if (!wm_triple_gen_textures(win, drawdata->triple)) { wm_draw_triple_fail(C, win); return; } } } triple_data = ((wmDrawData *) BLI_findlink(&win->drawdata, sview * 2))->triple; triple_all = ((wmDrawData *) BLI_findlink(&win->drawdata, (sview * 2) + 1))->triple; /* draw marked area regions */ for (sa = screen->areabase.first; sa; sa = sa->next) { CTX_wm_area_set(C, sa); switch (sa->spacetype) { case SPACE_IMAGE: { SpaceImage *sima = sa->spacedata.first; sima->iuser.multiview_eye = sview; break; } case SPACE_VIEW3D: { View3D *v3d = sa->spacedata.first; BGpic *bgpic = v3d->bgpicbase.first; v3d->multiview_eye = sview; if (bgpic) bgpic->iuser.multiview_eye = sview; break; } case SPACE_NODE: { SpaceNode *snode = sa->spacedata.first; if ((snode->flag & SNODE_BACKDRAW) && ED_node_is_compositor(snode)) { Image *ima = BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node"); ima->eye = sview; } break; } case SPACE_SEQ: { SpaceSeq *sseq = sa->spacedata.first; sseq->multiview_eye = sview; break; } } /* draw marked area regions */ for (ar = sa->regionbase.first; ar; ar = ar->next) { if (ar->swinid && ar->do_draw) { if (ar->overlap == false) { CTX_wm_region_set(C, ar); ED_region_do_draw(C, ar); if (sview == STEREO_RIGHT_ID) ar->do_draw = false; CTX_wm_region_set(C, NULL); copytex = true; } } } wm_area_mark_invalid_backbuf(sa); CTX_wm_area_set(C, NULL); } if (copytex) { wmSubWindowSet(win, screen->mainwin); wm_triple_copy_textures(win, triple_data); } if (wm->paintcursors.first) { for (sa = screen->areabase.first; sa; sa = sa->next) { for (ar = sa->regionbase.first; ar; ar = ar->next) { if (ar->swinid && ar->swinid == screen->subwinactive) { CTX_wm_area_set(C, sa); CTX_wm_region_set(C, ar); /* make region ready for draw, scissor, pixelspace */ ED_region_set(C, ar); wm_paintcursor_draw(C, ar); CTX_wm_region_set(C, NULL); CTX_wm_area_set(C, NULL); } } } wmSubWindowSet(win, screen->mainwin); } /* draw overlapping area regions (always like popups) */ for (sa = screen->areabase.first; sa; sa = sa->next) { CTX_wm_area_set(C, sa); for (ar = sa->regionbase.first; ar; ar = ar->next) { if (ar->swinid && ar->overlap) { CTX_wm_region_set(C, ar); ED_region_do_draw(C, ar); if (sview == STEREO_RIGHT_ID) ar->do_draw = false; CTX_wm_region_set(C, NULL); wm_draw_region_blend(win, ar, triple_data); } } CTX_wm_area_set(C, NULL); } /* after area regions so we can do area 'overlay' drawing */ ED_screen_draw(win); if (sview == STEREO_RIGHT_ID) win->screen->do_draw = false; /* draw floating regions (menus) */ for (ar = screen->regionbase.first; ar; ar = ar->next) { if (ar->swinid) { CTX_wm_menu_set(C, ar); ED_region_do_draw(C, ar); if (sview == STEREO_RIGHT_ID) ar->do_draw = false; CTX_wm_menu_set(C, NULL); } } /* always draw, not only when screen tagged */ if (win->gesture.first) wm_gesture_draw(win); /* needs pixel coords in screen */ if (wm->drags.first) { wm_drags_draw(C, win, NULL); } /* copy the ui + overlays */ wmSubWindowSet(win, screen->mainwin); wm_triple_copy_textures(win, triple_all); }
static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath) { bScreen *curscreen = NULL; Scene *curscene = NULL; int recover; enum { LOAD_UI = 1, LOAD_UI_OFF, LOAD_UNDO, } mode; if (BLI_listbase_is_empty(&bfd->main->screen)) { mode = LOAD_UNDO; } else if (G.fileflags & G_FILE_NO_UI) { mode = LOAD_UI_OFF; } else { mode = LOAD_UI; } recover = (G.fileflags & G_FILE_RECOVER); /* Free all render results, without this stale data gets displayed after loading files */ if (mode != LOAD_UNDO) { RE_FreeAllRenderResults(); } /* Only make filepaths compatible when loading for real (not undo) */ if (mode != LOAD_UNDO) { clean_paths(bfd->main); } /* XXX here the complex windowmanager matching */ /* no load screens? */ if (mode != LOAD_UI) { /* Logic for 'track_undo_scene' is to keep using the scene which the active screen has, * as long as the scene associated with the undo operation is visible in one of the open windows. * * - 'curscreen->scene' - scene the user is currently looking at. * - 'bfd->curscene' - scene undo-step was created in. * * This means users can have 2+ windows open and undo in both without screens switching. * But if they close one of the screens, * undo will ensure that the scene being operated on will be activated * (otherwise we'd be undoing on an off-screen scene which isn't acceptable). * see: T43424 */ bool track_undo_scene; /* comes from readfile.c */ SWAP(ListBase, G.main->wm, bfd->main->wm); SWAP(ListBase, G.main->screen, bfd->main->screen); SWAP(ListBase, G.main->script, bfd->main->script); /* we re-use current screen */ curscreen = CTX_wm_screen(C); /* but use new Scene pointer */ curscene = bfd->curscene; track_undo_scene = (mode == LOAD_UNDO && curscreen && bfd->main->wm.first); if (curscene == NULL) curscene = bfd->main->scene.first; /* empty file, we add a scene to make Blender work */ if (curscene == NULL) curscene = BKE_scene_add(bfd->main, "Empty"); if (track_undo_scene) { /* keep the old (free'd) scene, let 'blo_lib_link_screen_restore' * replace it with 'curscene' if its needed */ } else { /* and we enforce curscene to be in current screen */ if (curscreen) { /* can run in bgmode */ curscreen->scene = curscene; } } /* clear_global will free G.main, here we can still restore pointers */ blo_lib_link_screen_restore(bfd->main, curscreen, curscene); curscene = curscreen->scene; if (track_undo_scene) { wmWindowManager *wm = bfd->main->wm.first; if (wm_scene_is_visible(wm, bfd->curscene) == false) { curscene = bfd->curscene; curscreen->scene = curscene; } } } /* free G.main Main database */ // CTX_wm_manager_set(C, NULL); clear_global(); /* clear old property update cache, in case some old references are left dangling */ RNA_property_update_cache_free(); G.main = bfd->main; CTX_data_main_set(C, G.main); sound_init_main(G.main); if (bfd->user) { /* only here free userdef themes... */ BKE_userdef_free(); U = *bfd->user; /* Security issue: any blend file could include a USER block. * * Currently we load prefs from BLENDER_STARTUP_FILE and later on load BLENDER_USERPREF_FILE, * to load the preferences defined in the users home dir. * * This means we will never accidentally (or maliciously) * enable scripts auto-execution by loading a '.blend' file. */ U.flag |= USER_SCRIPT_AUTOEXEC_DISABLE; MEM_freeN(bfd->user); } /* case G_FILE_NO_UI or no screens in file */ if (mode != LOAD_UI) { /* leave entire context further unaltered? */ CTX_data_scene_set(C, curscene); } else { G.fileflags = bfd->fileflags; CTX_wm_manager_set(C, G.main->wm.first); CTX_wm_screen_set(C, bfd->curscreen); CTX_data_scene_set(C, bfd->curscene); CTX_wm_area_set(C, NULL); CTX_wm_region_set(C, NULL); CTX_wm_menu_set(C, NULL); curscene = bfd->curscene; } /* this can happen when active scene was lib-linked, and doesn't exist anymore */ if (CTX_data_scene(C) == NULL) { /* in case we don't even have a local scene, add one */ if (!G.main->scene.first) BKE_scene_add(G.main, "Scene"); CTX_data_scene_set(C, G.main->scene.first); CTX_wm_screen(C)->scene = CTX_data_scene(C); curscene = CTX_data_scene(C); } BLI_assert(curscene == CTX_data_scene(C)); /* special cases, override loaded flags: */ if (G.f != bfd->globalf) { const int flags_keep = (G_SWAP_EXCHANGE | G_SCRIPT_AUTOEXEC | G_SCRIPT_OVERRIDE_PREF); bfd->globalf = (bfd->globalf & ~flags_keep) | (G.f & flags_keep); } G.f = bfd->globalf; #ifdef WITH_PYTHON /* let python know about new main */ BPY_context_update(C); #endif if (!G.background) { //setscreen(G.curscreen); } /* FIXME: this version patching should really be part of the file-reading code, * but we still get too many unrelated data-corruption crashes otherwise... */ if (G.main->versionfile < 250) do_versions_ipos_to_animato(G.main); G.main->recovered = 0; /* startup.blend or recovered startup */ if (bfd->filename[0] == 0) { G.main->name[0] = 0; } else if (recover && G.relbase_valid) { /* in case of autosave or quit.blend, use original filename instead * use relbase_valid to make sure the file is saved, else we get <memory2> in the filename */ filepath = bfd->filename; G.main->recovered = 1; /* these are the same at times, should never copy to the same location */ if (G.main->name != filepath) BLI_strncpy(G.main->name, filepath, FILE_MAX); } /* baseflags, groups, make depsgraph, etc */ /* first handle case if other windows have different scenes visible */ if (mode == LOAD_UI) { wmWindowManager *wm = G.main->wm.first; if (wm) { wmWindow *win; for (win = wm->windows.first; win; win = win->next) { if (win->screen && win->screen->scene) /* zealous check... */ if (win->screen->scene != curscene) BKE_scene_set_background(G.main, win->screen->scene); } } } BKE_scene_set_background(G.main, curscene); if (mode != LOAD_UNDO) { IMB_colormanagement_check_file_config(G.main); } MEM_freeN(bfd); }
/* only meant for timer usage */ static int file_smoothscroll_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event) { ScrArea *sa = CTX_wm_area(C); SpaceFile *sfile = CTX_wm_space_file(C); ARegion *ar, *oldar = CTX_wm_region(C); int offset; int numfiles, numfiles_layout; int edit_idx = 0; int i; /* escape if not our timer */ if (sfile->smoothscroll_timer == NULL || sfile->smoothscroll_timer != event->customdata) return OPERATOR_PASS_THROUGH; numfiles = filelist_numfiles(sfile->files); /* check if we are editing a name */ for (i = 0; i < numfiles; ++i) { if (filelist_is_selected(sfile->files, i, CHECK_ALL) ) { edit_idx = i; break; } } /* if we are not editing, we are done */ if (0 == edit_idx) { WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), sfile->smoothscroll_timer); sfile->smoothscroll_timer = NULL; return OPERATOR_PASS_THROUGH; } /* we need the correct area for scrolling */ ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW); if (!ar || ar->regiontype != RGN_TYPE_WINDOW) { WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), sfile->smoothscroll_timer); sfile->smoothscroll_timer = NULL; return OPERATOR_PASS_THROUGH; } offset = ED_fileselect_layout_offset(sfile->layout, (int)ar->v2d.cur.xmin, (int)-ar->v2d.cur.ymax); if (offset < 0) offset = 0; /* scroll offset is the first file in the row/column we are editing in */ if (sfile->scroll_offset == 0) { if (sfile->layout->flag & FILE_LAYOUT_HOR) { sfile->scroll_offset = (edit_idx / sfile->layout->rows) * sfile->layout->rows; if (sfile->scroll_offset <= offset) sfile->scroll_offset -= sfile->layout->rows; } else { sfile->scroll_offset = (edit_idx / sfile->layout->columns) * sfile->layout->columns; if (sfile->scroll_offset <= offset) sfile->scroll_offset -= sfile->layout->columns; } } numfiles_layout = ED_fileselect_layout_numfiles(sfile->layout, ar); /* check if we have reached our final scroll position */ if ( (sfile->scroll_offset >= offset) && (sfile->scroll_offset < offset + numfiles_layout) ) { WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), sfile->smoothscroll_timer); sfile->smoothscroll_timer = NULL; return OPERATOR_FINISHED; } /* temporarily set context to the main window region, * so the scroll operators work */ CTX_wm_region_set(C, ar); /* scroll one step in the desired direction */ if (sfile->scroll_offset < offset) { if (sfile->layout->flag & FILE_LAYOUT_HOR) { WM_operator_name_call(C, "VIEW2D_OT_scroll_left", 0, NULL); } else { WM_operator_name_call(C, "VIEW2D_OT_scroll_up", 0, NULL); } } else { if (sfile->layout->flag & FILE_LAYOUT_HOR) { WM_operator_name_call(C, "VIEW2D_OT_scroll_right", 0, NULL); } else { WM_operator_name_call(C, "VIEW2D_OT_scroll_down", 0, NULL); } } ED_region_tag_redraw(ar); /* and restore context */ CTX_wm_region_set(C, oldar); return OPERATOR_FINISHED; }
static int game_engine_exec(bContext *C, wmOperator *op) { #ifdef WITH_GAMEENGINE Scene *startscene = CTX_data_scene(C); Main *bmain = CTX_data_main(C); ScrArea /* *sa, */ /* UNUSED */ *prevsa = CTX_wm_area(C); ARegion *ar, *prevar = CTX_wm_region(C); wmWindow *prevwin = CTX_wm_window(C); RegionView3D *rv3d; rcti cam_frame; (void)op; /* unused */ /* bad context switch .. */ if (!ED_view3d_context_activate(C)) return OPERATOR_CANCELLED; /* redraw to hide any menus/popups, we don't go back to * the window manager until after this operator exits */ WM_redraw_windows(C); BLI_callback_exec(bmain, &startscene->id, BLI_CB_EVT_GAME_PRE); rv3d = CTX_wm_region_view3d(C); /* sa = CTX_wm_area(C); */ /* UNUSED */ ar = CTX_wm_region(C); view3d_operator_needs_opengl(C); game_set_commmandline_options(&startscene->gm); if ((rv3d->persp == RV3D_CAMOB) && (startscene->gm.framing.type == SCE_GAMEFRAMING_BARS) && (startscene->gm.stereoflag != STEREO_DOME)) { /* Letterbox */ rctf cam_framef; ED_view3d_calc_camera_border(startscene, ar, CTX_wm_view3d(C), rv3d, &cam_framef, false); cam_frame.xmin = cam_framef.xmin + ar->winrct.xmin; cam_frame.xmax = cam_framef.xmax + ar->winrct.xmin; cam_frame.ymin = cam_framef.ymin + ar->winrct.ymin; cam_frame.ymax = cam_framef.ymax + ar->winrct.ymin; BLI_rcti_isect(&ar->winrct, &cam_frame, &cam_frame); } else { cam_frame.xmin = ar->winrct.xmin; cam_frame.xmax = ar->winrct.xmax; cam_frame.ymin = ar->winrct.ymin; cam_frame.ymax = ar->winrct.ymax; } SaveState(C, prevwin); StartKetsjiShell(C, ar, &cam_frame, 1); /* window wasnt closed while the BGE was running */ if (BLI_findindex(&CTX_wm_manager(C)->windows, prevwin) == -1) { prevwin = NULL; CTX_wm_window_set(C, NULL); } ED_area_tag_redraw(CTX_wm_area(C)); if (prevwin) { /* restore context, in case it changed in the meantime, for * example by working in another window or closing it */ CTX_wm_region_set(C, prevar); CTX_wm_window_set(C, prevwin); CTX_wm_area_set(C, prevsa); } RestoreState(C, prevwin); //XXX restore_all_scene_cfra(scene_cfra_store); BKE_scene_set_background(CTX_data_main(C), startscene); //XXX BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene, scene->lay); BLI_callback_exec(bmain, &startscene->id, BLI_CB_EVT_GAME_POST); return OPERATOR_FINISHED; #else (void)C; /* unused */ BKE_report(op->reports, RPT_ERROR, "Game engine is disabled in this build"); return OPERATOR_CANCELLED; #endif }
static void screen_opengl_render_end(bContext *C, OGLRender *oglrender) { Main *bmain = CTX_data_main(C); Scene *scene = oglrender->scene; int i; if (oglrender->is_animation) { BLI_task_pool_work_and_wait(oglrender->task_pool); BLI_task_pool_free(oglrender->task_pool); /* Depending on various things we might or might not use global scheduler. */ if (oglrender->task_scheduler != NULL) { BLI_task_scheduler_free(oglrender->task_scheduler); } BLI_spin_end(&oglrender->reports_lock); } BLI_mutex_end(&oglrender->task_mutex); BLI_condition_end(&oglrender->task_condition); #ifdef DEBUG_TIME printf("Total render time: %f\n", PIL_check_seconds_timer() - oglrender->time_start); #endif if (oglrender->mh) { if (BKE_imtype_is_movie(scene->r.im_format.imtype)) { for (i = 0; i < oglrender->totvideos; i++) { oglrender->mh->end_movie(oglrender->movie_ctx_arr[i]); oglrender->mh->context_free(oglrender->movie_ctx_arr[i]); } } if (oglrender->movie_ctx_arr) { MEM_freeN(oglrender->movie_ctx_arr); } } if (oglrender->timer) { /* exec will not have a timer */ scene->r.cfra = oglrender->cfrao; BKE_scene_update_for_newframe(bmain->eval_ctx, bmain, scene, screen_opengl_layers(oglrender)); WM_event_remove_timer(oglrender->wm, oglrender->win, oglrender->timer); } WM_cursor_modal_restore(oglrender->win); WM_event_add_notifier(C, NC_SCENE | ND_RENDER_RESULT, oglrender->scene); if (oglrender->fx) GPU_fx_compositor_destroy(oglrender->fx); GPU_offscreen_free(oglrender->ofs); if (oglrender->is_sequencer) { MEM_freeN(oglrender->seq_data.ibufs_arr); } oglrender->scene->customdata_mask_modal = 0; CTX_wm_area_set(C, oglrender->prevsa); CTX_wm_region_set(C, oglrender->prevar); MEM_freeN(oglrender); }
static int game_engine_exec(bContext *C, wmOperator *op) { #ifdef WITH_GAMEENGINE Scene *startscene = CTX_data_scene(C); ScrArea *sa, *prevsa= CTX_wm_area(C); ARegion *ar, *prevar= CTX_wm_region(C); wmWindow *prevwin= CTX_wm_window(C); RegionView3D *rv3d; rcti cam_frame; (void)op; /* unused */ // bad context switch .. if(!ED_view3d_context_activate(C)) return OPERATOR_CANCELLED; rv3d= CTX_wm_region_view3d(C); sa= CTX_wm_area(C); ar= CTX_wm_region(C); view3d_operator_needs_opengl(C); game_set_commmandline_options(&startscene->gm); if(rv3d->persp==RV3D_CAMOB && startscene->gm.framing.type == SCE_GAMEFRAMING_BARS && startscene->gm.stereoflag != STEREO_DOME) { /* Letterbox */ rctf cam_framef; ED_view3d_calc_camera_border(startscene, ar, CTX_wm_view3d(C), rv3d, &cam_framef, FALSE); cam_frame.xmin = cam_framef.xmin + ar->winrct.xmin; cam_frame.xmax = cam_framef.xmax + ar->winrct.xmin; cam_frame.ymin = cam_framef.ymin + ar->winrct.ymin; cam_frame.ymax = cam_framef.ymax + ar->winrct.ymin; BLI_isect_rcti(&ar->winrct, &cam_frame, &cam_frame); } else { cam_frame.xmin = ar->winrct.xmin; cam_frame.xmax = ar->winrct.xmax; cam_frame.ymin = ar->winrct.ymin; cam_frame.ymax = ar->winrct.ymax; } SaveState(C, prevwin); StartKetsjiShell(C, ar, &cam_frame, 1); /* window wasnt closed while the BGE was running */ if(BLI_findindex(&CTX_wm_manager(C)->windows, prevwin) == -1) { prevwin= NULL; CTX_wm_window_set(C, NULL); } if(prevwin) { /* restore context, in case it changed in the meantime, for example by working in another window or closing it */ CTX_wm_region_set(C, prevar); CTX_wm_window_set(C, prevwin); CTX_wm_area_set(C, prevsa); } RestoreState(C, prevwin); //XXX restore_all_scene_cfra(scene_cfra_store); set_scene_bg(CTX_data_main(C), startscene); //XXX scene_update_for_newframe(bmain, scene, scene->lay); ED_area_tag_redraw(CTX_wm_area(C)); return OPERATOR_FINISHED; #else (void)C; /* unused */ BKE_report(op->reports, RPT_ERROR, "Game engine is disabled in this build."); return OPERATOR_CANCELLED; #endif }
static void wm_method_draw_overlap_all(bContext *C, wmWindow *win, int exchange) { wmWindowManager *wm = CTX_wm_manager(C); bScreen *screen = win->screen; ScrArea *sa; ARegion *ar; static rcti rect = {0, 0, 0, 0}; /* after backbuffer selection draw, we need to redraw */ for (sa = screen->areabase.first; sa; sa = sa->next) for (ar = sa->regionbase.first; ar; ar = ar->next) if (ar->swinid && !wm_area_test_invalid_backbuf(sa)) ED_region_tag_redraw(ar); /* flush overlapping regions */ if (screen->regionbase.first) { /* flush redraws of area regions up to overlapping regions */ for (sa = screen->areabase.first; sa; sa = sa->next) for (ar = sa->regionbase.first; ar; ar = ar->next) if (ar->swinid && ar->do_draw) wm_flush_regions_up(screen, &ar->winrct); /* flush between overlapping regions */ for (ar = screen->regionbase.last; ar; ar = ar->prev) if (ar->swinid && ar->do_draw) wm_flush_regions_up(screen, &ar->winrct); /* flush redraws of overlapping regions down to area regions */ for (ar = screen->regionbase.last; ar; ar = ar->prev) if (ar->swinid && ar->do_draw) wm_flush_regions_down(screen, &ar->winrct); } /* flush drag item */ if (rect.xmin != rect.xmax) { wm_flush_regions_down(screen, &rect); rect.xmin = rect.xmax = 0; } if (wm->drags.first) { /* doesnt draw, fills rect with boundbox */ wm_drags_draw(C, win, &rect); } /* draw marked area regions */ for (sa = screen->areabase.first; sa; sa = sa->next) { CTX_wm_area_set(C, sa); for (ar = sa->regionbase.first; ar; ar = ar->next) { if (ar->swinid) { if (ar->do_draw) { CTX_wm_region_set(C, ar); ED_region_do_draw(C, ar); wm_paintcursor_draw(C, ar); CTX_wm_region_set(C, NULL); if (exchange) ar->swap = WIN_FRONT_OK; } else if (exchange) { if (ar->swap == WIN_FRONT_OK) { CTX_wm_region_set(C, ar); ED_region_do_draw(C, ar); wm_paintcursor_draw(C, ar); CTX_wm_region_set(C, NULL); ar->swap = WIN_BOTH_OK; } else if (ar->swap == WIN_BACK_OK) ar->swap = WIN_FRONT_OK; else if (ar->swap == WIN_BOTH_OK) ar->swap = WIN_BOTH_OK; } } } wm_area_mark_invalid_backbuf(sa); CTX_wm_area_set(C, NULL); } /* after area regions so we can do area 'overlay' drawing */ if (screen->do_draw) { ED_screen_draw(win); if (exchange) screen->swap = WIN_FRONT_OK; } else if (exchange) { if (screen->swap == WIN_FRONT_OK) { ED_screen_draw(win); screen->swap = WIN_BOTH_OK; } else if (screen->swap == WIN_BACK_OK) screen->swap = WIN_FRONT_OK; else if (screen->swap == WIN_BOTH_OK) screen->swap = WIN_BOTH_OK; } /* draw marked overlapping regions */ for (ar = screen->regionbase.first; ar; ar = ar->next) { if (ar->swinid && ar->do_draw) { CTX_wm_menu_set(C, ar); ED_region_do_draw(C, ar); CTX_wm_menu_set(C, NULL); } } if (screen->do_draw_gesture) wm_gesture_draw(win); /* needs pixel coords in screen */ if (wm->drags.first) { wm_drags_draw(C, win, NULL); } }
void ED_render_scene_update(Main *bmain, Scene *scene, int updated) { /* viewport rendering update on data changes, happens after depsgraph * updates if there was any change. context is set to the 3d view */ bContext *C; wmWindowManager *wm; wmWindow *win; static bool recursive_check = false; /* don't do this render engine update if we're updating the scene from * other threads doing e.g. rendering or baking jobs */ if (!BLI_thread_is_main()) return; /* don't call this recursively for frame updates */ if (recursive_check) return; /* Do not call if no WM available, see T42688. */ if (BLI_listbase_is_empty(&bmain->wm)) return; recursive_check = true; C = CTX_create(); CTX_data_main_set(C, bmain); CTX_data_scene_set(C, scene); CTX_wm_manager_set(C, bmain->wm.first); wm = bmain->wm.first; for (win = wm->windows.first; win; win = win->next) { bScreen *sc = win->screen; ScrArea *sa; ARegion *ar; CTX_wm_window_set(C, win); for (sa = sc->areabase.first; sa; sa = sa->next) { if (sa->spacetype != SPACE_VIEW3D) continue; for (ar = sa->regionbase.first; ar; ar = ar->next) { RegionView3D *rv3d; RenderEngine *engine; if (ar->regiontype != RGN_TYPE_WINDOW) continue; rv3d = ar->regiondata; engine = rv3d->render_engine; /* call update if the scene changed, or if the render engine * tagged itself for update (e.g. because it was busy at the * time of the last update) */ if (engine && (updated || (engine->flag & RE_ENGINE_DO_UPDATE))) { CTX_wm_screen_set(C, sc); CTX_wm_area_set(C, sa); CTX_wm_region_set(C, ar); engine->flag &= ~RE_ENGINE_DO_UPDATE; engine->type->view_update(engine, C); } } } } CTX_free(C); recursive_check = false; }
/* ui callbacks should call this rather than calling WM_operator_repeat() themselves */ int ED_undo_operator_repeat(bContext *C, struct wmOperator *op) { int ret = 0; if (op) { wmWindowManager *wm = CTX_wm_manager(C); struct Scene *scene = CTX_data_scene(C); /* keep in sync with logic in view3d_panel_operator_redo() */ ARegion *ar = CTX_wm_region(C); ARegion *ar1 = BKE_area_find_region_active_win(CTX_wm_area(C)); if (ar1) CTX_wm_region_set(C, ar1); if ((WM_operator_repeat_check(C, op)) && (WM_operator_poll(C, op->type)) && /* note, undo/redo cant run if there are jobs active, * check for screen jobs only so jobs like material/texture/world preview * (which copy their data), wont stop redo, see [#29579]], * * note, - WM_operator_check_ui_enabled() jobs test _must_ stay in sync with this */ (WM_jobs_test(wm, scene, WM_JOB_TYPE_ANY) == 0)) { int retval; ED_viewport_render_kill_jobs(C, true); if (G.debug & G_DEBUG) printf("redo_cb: operator redo %s\n", op->type->name); ED_undo_pop_op(C, op); if (op->type->check) { op->type->check(C, op); /* ignore return value since its running again anyway */ } retval = WM_operator_repeat(C, op); if ((retval & OPERATOR_FINISHED) == 0) { if (G.debug & G_DEBUG) printf("redo_cb: operator redo failed: %s, return %d\n", op->type->name, retval); ED_undo_redo(C); } else { ret = 1; } } else { if (G.debug & G_DEBUG) { printf("redo_cb: WM_operator_repeat_check returned false %s\n", op->type->name); } } /* set region back */ CTX_wm_region_set(C, ar); } else { if (G.debug & G_DEBUG) { printf("redo_cb: ED_undo_operator_repeat called with NULL 'op'\n"); } } return ret; }
static void wm_draw_window_offscreen(bContext *C, wmWindow *win, bool stereo) { Main *bmain = CTX_data_main(C); wmWindowManager *wm = CTX_wm_manager(C); bScreen *screen = WM_window_get_active_screen(win); /* Draw screen areas into own frame buffer. */ ED_screen_areas_iter(win, screen, sa) { CTX_wm_area_set(C, sa); /* Compute UI layouts for dynamically size regions. */ for (ARegion *ar = sa->regionbase.first; ar; ar = ar->next) { if (ar->visible && ar->do_draw && ar->type && ar->type->layout) { CTX_wm_region_set(C, ar); ED_region_do_layout(C, ar); CTX_wm_region_set(C, NULL); } } ED_area_update_region_sizes(wm, win, sa); if (sa->flag & AREA_FLAG_ACTIVE_TOOL_UPDATE) { if ((1 << sa->spacetype) & WM_TOOLSYSTEM_SPACE_MASK) { WM_toolsystem_update_from_context(C, CTX_wm_workspace(C), CTX_data_view_layer(C), sa); } sa->flag &= ~AREA_FLAG_ACTIVE_TOOL_UPDATE; } /* Then do actual drawing of regions. */ for (ARegion *ar = sa->regionbase.first; ar; ar = ar->next) { if (ar->visible && ar->do_draw) { CTX_wm_region_set(C, ar); bool use_viewport = wm_region_use_viewport(sa, ar); if (stereo && wm_draw_region_stereo_set(bmain, sa, ar, STEREO_LEFT_ID)) { wm_draw_region_buffer_create(ar, true, use_viewport); for (int view = 0; view < 2; view++) { eStereoViews sview; if (view == 0) { sview = STEREO_LEFT_ID; } else { sview = STEREO_RIGHT_ID; wm_draw_region_stereo_set(bmain, sa, ar, sview); } wm_draw_region_bind(ar, view); ED_region_do_draw(C, ar); wm_draw_region_unbind(ar, view); } } else { wm_draw_region_buffer_create(ar, false, use_viewport); wm_draw_region_bind(ar, 0); ED_region_do_draw(C, ar); wm_draw_region_unbind(ar, 0); } ar->do_draw = false; CTX_wm_region_set(C, NULL); } } wm_area_mark_invalid_backbuf(sa); CTX_wm_area_set(C, NULL); }
static void wm_method_draw_triple(bContext *C, wmWindow *win) { wmWindowManager *wm = CTX_wm_manager(C); wmDrawTriple *triple; wmDrawData *dd, *dd_next, *drawdata = win->drawdata.first; bScreen *screen = win->screen; ScrArea *sa; ARegion *ar; int copytex = false; if (drawdata && drawdata->triple) { glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); wmSubWindowSet(win, screen->mainwin); wm_triple_draw_textures(win, drawdata->triple, 1.0f); } else { /* we run it when we start OR when we turn stereo on */ if (drawdata == NULL) { drawdata = MEM_callocN(sizeof(wmDrawData), "wmDrawData"); BLI_addhead(&win->drawdata, drawdata); } drawdata->triple = MEM_callocN(sizeof(wmDrawTriple), "wmDrawTriple"); if (!wm_triple_gen_textures(win, drawdata->triple)) { wm_draw_triple_fail(C, win); return; } } /* it means stereo was just turned off */ /* note: we are removing all drawdatas that are not the first */ for (dd = drawdata->next; dd; dd = dd_next) { dd_next = dd->next; BLI_remlink(&win->drawdata, dd); wm_draw_triple_free(dd->triple); MEM_freeN(dd); } triple = drawdata->triple; /* draw marked area regions */ for (sa = screen->areabase.first; sa; sa = sa->next) { CTX_wm_area_set(C, sa); for (ar = sa->regionbase.first; ar; ar = ar->next) { if (ar->swinid && ar->do_draw) { if (ar->overlap == false) { CTX_wm_region_set(C, ar); ED_region_do_draw(C, ar); ar->do_draw = false; CTX_wm_region_set(C, NULL); copytex = true; } } } wm_area_mark_invalid_backbuf(sa); CTX_wm_area_set(C, NULL); } if (copytex) { wmSubWindowSet(win, screen->mainwin); wm_triple_copy_textures(win, triple); } if (wm->paintcursors.first) { for (sa = screen->areabase.first; sa; sa = sa->next) { for (ar = sa->regionbase.first; ar; ar = ar->next) { if (ar->swinid && ar->swinid == screen->subwinactive) { CTX_wm_area_set(C, sa); CTX_wm_region_set(C, ar); /* make region ready for draw, scissor, pixelspace */ ED_region_set(C, ar); wm_paintcursor_draw(C, ar); CTX_wm_region_set(C, NULL); CTX_wm_area_set(C, NULL); } } } wmSubWindowSet(win, screen->mainwin); } /* draw overlapping area regions (always like popups) */ for (sa = screen->areabase.first; sa; sa = sa->next) { CTX_wm_area_set(C, sa); for (ar = sa->regionbase.first; ar; ar = ar->next) { if (ar->swinid && ar->overlap) { CTX_wm_region_set(C, ar); ED_region_do_draw(C, ar); ar->do_draw = false; CTX_wm_region_set(C, NULL); wm_draw_region_blend(win, ar, triple); } } CTX_wm_area_set(C, NULL); } /* after area regions so we can do area 'overlay' drawing */ ED_screen_draw(win); win->screen->do_draw = false; /* draw floating regions (menus) */ for (ar = screen->regionbase.first; ar; ar = ar->next) { if (ar->swinid) { CTX_wm_menu_set(C, ar); ED_region_do_draw(C, ar); ar->do_draw = false; CTX_wm_menu_set(C, NULL); } } /* always draw, not only when screen tagged */ if (win->gesture.first) wm_gesture_draw(win); /* needs pixel coords in screen */ if (wm->drags.first) { wm_drags_draw(C, win, NULL); } }
static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath) { bScreen *curscreen= NULL; Scene *curscene= NULL; int recover; char mode; /* 'u' = undo save, 'n' = no UI load */ if(bfd->main->screen.first==NULL) mode= 'u'; else if(G.fileflags & G_FILE_NO_UI) mode= 'n'; else mode= 0; recover= (G.fileflags & G_FILE_RECOVER); /* Only make filepaths compatible when loading for real (not undo) */ if(mode != 'u') { clean_paths(bfd->main); } /* XXX here the complex windowmanager matching */ /* no load screens? */ if(mode) { /* comes from readfile.c */ extern void lib_link_screen_restore(Main *, bScreen *, Scene *); SWAP(ListBase, G.main->wm, bfd->main->wm); SWAP(ListBase, G.main->screen, bfd->main->screen); SWAP(ListBase, G.main->script, bfd->main->script); /* we re-use current screen */ curscreen= CTX_wm_screen(C); /* but use new Scene pointer */ curscene= bfd->curscene; if(curscene==NULL) curscene= bfd->main->scene.first; /* and we enforce curscene to be in current screen */ if(curscreen) curscreen->scene= curscene; /* can run in bgmode */ /* clear_global will free G.main, here we can still restore pointers */ lib_link_screen_restore(bfd->main, curscreen, curscene); } /* free G.main Main database */ // CTX_wm_manager_set(C, NULL); clear_global(); /* clear old property update cache, in case some old references are left dangling */ RNA_property_update_cache_free(); G.main= bfd->main; CTX_data_main_set(C, G.main); sound_init_main(G.main); if (bfd->user) { /* only here free userdef themes... */ BKE_userdef_free(); U= *bfd->user; MEM_freeN(bfd->user); } /* case G_FILE_NO_UI or no screens in file */ if(mode) { /* leave entire context further unaltered? */ CTX_data_scene_set(C, curscene); } else { G.winpos= bfd->winpos; G.displaymode= bfd->displaymode; G.fileflags= bfd->fileflags; CTX_wm_manager_set(C, bfd->main->wm.first); CTX_wm_screen_set(C, bfd->curscreen); CTX_data_scene_set(C, bfd->curscreen->scene); CTX_wm_area_set(C, NULL); CTX_wm_region_set(C, NULL); CTX_wm_menu_set(C, NULL); } /* this can happen when active scene was lib-linked, and doesnt exist anymore */ if(CTX_data_scene(C)==NULL) { CTX_data_scene_set(C, bfd->main->scene.first); CTX_wm_screen(C)->scene= CTX_data_scene(C); curscene= CTX_data_scene(C); } /* special cases, override loaded flags: */ if(G.f != bfd->globalf) { const int flags_keep= (G_DEBUG | G_SWAP_EXCHANGE | G_SCRIPT_AUTOEXEC | G_SCRIPT_OVERRIDE_PREF); bfd->globalf= (bfd->globalf & ~flags_keep) | (G.f & flags_keep); } G.f= bfd->globalf; if (!G.background) { //setscreen(G.curscreen); } // FIXME: this version patching should really be part of the file-reading code, // but we still get too many unrelated data-corruption crashes otherwise... if (G.main->versionfile < 250) do_versions_ipos_to_animato(G.main); if(recover && bfd->filename[0] && G.relbase_valid) { /* in case of autosave or quit.blend, use original filename instead * use relbase_valid to make sure the file is saved, else we get <memory2> in the filename */ filepath= bfd->filename; } #if 0 else if (!G.relbase_valid) { /* otherwise, use an empty string as filename, rather than <memory2> */ filepath=""; } #endif /* these are the same at times, should never copy to the same location */ if(G.main->name != filepath) BLI_strncpy(G.main->name, filepath, FILE_MAX); /* baseflags, groups, make depsgraph, etc */ set_scene_bg(G.main, CTX_data_scene(C)); MEM_freeN(bfd); (void)curscene; /* quiet warning */ }
bool WM_init_game(bContext *C) { wmWindowManager *wm = CTX_wm_manager(C); wmWindow *win; ScrArea *sa; ARegion *ar = NULL; Scene *scene = CTX_data_scene(C); if (!scene) { /* XXX, this should not be needed. */ Main *bmain = CTX_data_main(C); scene = bmain->scene.first; } win = wm->windows.first; /* first to get a valid window */ if (win) CTX_wm_window_set(C, win); sa = BKE_screen_find_big_area(CTX_wm_screen(C), SPACE_VIEW3D, 0); ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW); /* if we have a valid 3D view */ if (sa && ar) { ARegion *arhide; CTX_wm_area_set(C, sa); CTX_wm_region_set(C, ar); /* disable quad view */ if (ar->alignment == RGN_ALIGN_QSPLIT) WM_operator_name_call(C, "SCREEN_OT_region_quadview", WM_OP_EXEC_DEFAULT, NULL); /* toolbox, properties panel and header are hidden */ for (arhide = sa->regionbase.first; arhide; arhide = arhide->next) { if (arhide->regiontype != RGN_TYPE_WINDOW) { if (!(arhide->flag & RGN_FLAG_HIDDEN)) { ED_region_toggle_hidden(C, arhide); } } } /* full screen the area */ if (!sa->full) { ED_screen_state_toggle(C, win, sa, SCREENMAXIMIZED); } /* Fullscreen */ if ((scene->gm.playerflag & GAME_PLAYER_FULLSCREEN)) { WM_operator_name_call(C, "WM_OT_window_fullscreen_toggle", WM_OP_EXEC_DEFAULT, NULL); wm_get_screensize(&ar->winrct.xmax, &ar->winrct.ymax); ar->winx = ar->winrct.xmax + 1; ar->winy = ar->winrct.ymax + 1; } else { GHOST_RectangleHandle rect = GHOST_GetClientBounds(win->ghostwin); ar->winrct.ymax = GHOST_GetHeightRectangle(rect); ar->winrct.xmax = GHOST_GetWidthRectangle(rect); ar->winx = ar->winrct.xmax + 1; ar->winy = ar->winrct.ymax + 1; GHOST_DisposeRectangle(rect); } WM_operator_name_call(C, "VIEW3D_OT_game_start", WM_OP_EXEC_DEFAULT, NULL); BKE_sound_exit(); return true; } else { ReportTimerInfo *rti; BKE_report(&wm->reports, RPT_ERROR, "No valid 3D View found, game auto start is not possible"); /* After adding the report to the global list, reset the report timer. */ WM_event_remove_timer(wm, NULL, wm->reports.reporttimer); /* Records time since last report was added */ wm->reports.reporttimer = WM_event_add_timer(wm, CTX_wm_window(C), TIMER, 0.02); rti = MEM_callocN(sizeof(ReportTimerInfo), "ReportTimerInfo"); wm->reports.reporttimer->customdata = rti; return false; } }
static void wm_method_draw_triple(bContext *C, wmWindow *win) { wmWindowManager *wm = CTX_wm_manager(C); wmDrawTriple *triple; bScreen *screen = win->screen; ScrArea *sa; ARegion *ar; int copytex = 0, paintcursor = 1; if (win->drawdata) { glClearColor(0, 0, 0, 0); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); wmSubWindowSet(win, screen->mainwin); wm_triple_draw_textures(win, win->drawdata, 1.0f); } else { win->drawdata = MEM_callocN(sizeof(wmDrawTriple), "wmDrawTriple"); if (!wm_triple_gen_textures(win, win->drawdata)) { wm_draw_triple_fail(C, win); return; } } triple = win->drawdata; /* draw marked area regions */ for (sa = screen->areabase.first; sa; sa = sa->next) { CTX_wm_area_set(C, sa); for (ar = sa->regionbase.first; ar; ar = ar->next) { if (ar->swinid && ar->do_draw) { if (ar->overlap == 0) { CTX_wm_region_set(C, ar); ED_region_do_draw(C, ar); CTX_wm_region_set(C, NULL); copytex = 1; } } } wm_area_mark_invalid_backbuf(sa); CTX_wm_area_set(C, NULL); } if (copytex) { wmSubWindowSet(win, screen->mainwin); wm_triple_copy_textures(win, triple); } if (paintcursor && wm->paintcursors.first) { for (sa = screen->areabase.first; sa; sa = sa->next) { for (ar = sa->regionbase.first; ar; ar = ar->next) { if (ar->swinid && ar->swinid == screen->subwinactive) { CTX_wm_area_set(C, sa); CTX_wm_region_set(C, ar); /* make region ready for draw, scissor, pixelspace */ ED_region_set(C, ar); wm_paintcursor_draw(C, ar); CTX_wm_region_set(C, NULL); CTX_wm_area_set(C, NULL); } } } wmSubWindowSet(win, screen->mainwin); } /* draw overlapping area regions (always like popups) */ for (sa = screen->areabase.first; sa; sa = sa->next) { CTX_wm_area_set(C, sa); for (ar = sa->regionbase.first; ar; ar = ar->next) { if (ar->swinid && ar->overlap) { CTX_wm_region_set(C, ar); ED_region_do_draw(C, ar); CTX_wm_region_set(C, NULL); wm_draw_region_blend(win, ar); } } CTX_wm_area_set(C, NULL); } /* after area regions so we can do area 'overlay' drawing */ ED_screen_draw(win); /* draw floating regions (menus) */ for (ar = screen->regionbase.first; ar; ar = ar->next) { if (ar->swinid) { CTX_wm_menu_set(C, ar); ED_region_do_draw(C, ar); CTX_wm_menu_set(C, NULL); /* when a menu is being drawn, don't do the paint cursors */ paintcursor = 0; } } /* always draw, not only when screen tagged */ if (win->gesture.first) wm_gesture_draw(win); /* needs pixel coords in screen */ if (wm->drags.first) { wm_drags_draw(C, win, NULL); } }
static void setup_app_data(bContext *C, BlendFileData *bfd, const char *filepath) { bScreen *curscreen = NULL; Scene *curscene = NULL; int recover; char mode; /* 'u' = undo save, 'n' = no UI load */ if (bfd->main->screen.first == NULL) mode = 'u'; else if (G.fileflags & G_FILE_NO_UI) mode = 'n'; else mode = 0; recover = (G.fileflags & G_FILE_RECOVER); /* Free all render results, without this stale data gets displayed after loading files */ if (mode != 'u') { RE_FreeAllRenderResults(); } /* Only make filepaths compatible when loading for real (not undo) */ if (mode != 'u') { clean_paths(bfd->main); } /* XXX here the complex windowmanager matching */ /* no load screens? */ if (mode) { /* comes from readfile.c */ SWAP(ListBase, G.main->wm, bfd->main->wm); SWAP(ListBase, G.main->screen, bfd->main->screen); SWAP(ListBase, G.main->script, bfd->main->script); /* we re-use current screen */ curscreen = CTX_wm_screen(C); /* but use new Scene pointer */ curscene = bfd->curscene; if (curscene == NULL) curscene = bfd->main->scene.first; /* empty file, we add a scene to make Blender work */ if (curscene == NULL) curscene = BKE_scene_add(bfd->main, "Empty"); /* and we enforce curscene to be in current screen */ if (curscreen) curscreen->scene = curscene; /* can run in bgmode */ /* clear_global will free G.main, here we can still restore pointers */ blo_lib_link_screen_restore(bfd->main, curscreen, curscene); } /* free G.main Main database */ // CTX_wm_manager_set(C, NULL); clear_global(); /* clear old property update cache, in case some old references are left dangling */ RNA_property_update_cache_free(); G.main = bfd->main; CTX_data_main_set(C, G.main); sound_init_main(G.main); if (bfd->user) { /* only here free userdef themes... */ BKE_userdef_free(); U = *bfd->user; MEM_freeN(bfd->user); } /* case G_FILE_NO_UI or no screens in file */ if (mode) { /* leave entire context further unaltered? */ CTX_data_scene_set(C, curscene); } else { G.winpos = bfd->winpos; G.displaymode = bfd->displaymode; G.fileflags = bfd->fileflags; CTX_wm_manager_set(C, G.main->wm.first); CTX_wm_screen_set(C, bfd->curscreen); CTX_data_scene_set(C, bfd->curscene); CTX_wm_area_set(C, NULL); CTX_wm_region_set(C, NULL); CTX_wm_menu_set(C, NULL); } /* this can happen when active scene was lib-linked, and doesn't exist anymore */ if (CTX_data_scene(C) == NULL) { /* in case we don't even have a local scene, add one */ if (!G.main->scene.first) BKE_scene_add(G.main, "Scene"); CTX_data_scene_set(C, G.main->scene.first); CTX_wm_screen(C)->scene = CTX_data_scene(C); curscene = CTX_data_scene(C); } /* special cases, override loaded flags: */ if (G.f != bfd->globalf) { const int flags_keep = (G_SWAP_EXCHANGE | G_SCRIPT_AUTOEXEC | G_SCRIPT_OVERRIDE_PREF); bfd->globalf = (bfd->globalf & ~flags_keep) | (G.f & flags_keep); } G.f = bfd->globalf; #ifdef WITH_PYTHON /* let python know about new main */ BPY_context_update(C); #endif if (!G.background) { //setscreen(G.curscreen); } /* FIXME: this version patching should really be part of the file-reading code, * but we still get too many unrelated data-corruption crashes otherwise... */ if (G.main->versionfile < 250) do_versions_ipos_to_animato(G.main); G.main->recovered = 0; /* startup.blend or recovered startup */ if (bfd->filename[0] == 0) { G.main->name[0] = 0; } else if (recover && G.relbase_valid) { /* in case of autosave or quit.blend, use original filename instead * use relbase_valid to make sure the file is saved, else we get <memory2> in the filename */ filepath = bfd->filename; G.main->recovered = 1; /* these are the same at times, should never copy to the same location */ if (G.main->name != filepath) BLI_strncpy(G.main->name, filepath, FILE_MAX); } /* baseflags, groups, make depsgraph, etc */ /* first handle case if other windows have different scenes visible */ if (mode == 0) { wmWindowManager *wm = G.main->wm.first; if (wm) { wmWindow *win; for (win = wm->windows.first; win; win = win->next) { if (win->screen && win->screen->scene) /* zealous check... */ if (win->screen->scene != CTX_data_scene(C)) BKE_scene_set_background(G.main, win->screen->scene); } } } BKE_scene_set_background(G.main, CTX_data_scene(C)); if (mode != 'u') { IMB_colormanagement_check_file_config(G.main); } MEM_freeN(bfd); }