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); }
/* To be able to read files without windows closing, opening, moving * we try to prepare for worst case: * - active window gets active screen from file * - restoring the screens from non-active windows * Best case is all screens match, in that case they get assigned to proper window */ static void wm_window_match_init(bContext *C, ListBase *wmlist) { wmWindowManager *wm; wmWindow *win, *active_win; *wmlist = G.main->wm; BLI_listbase_clear(&G.main->wm); active_win = CTX_wm_window(C); /* first wrap up running stuff */ /* code copied from wm_init_exit.c */ for (wm = wmlist->first; wm; wm = wm->id.next) { WM_jobs_kill_all(wm); for (win = wm->windows.first; win; win = win->next) { CTX_wm_window_set(C, win); /* needed by operator close callbacks */ WM_event_remove_handlers(C, &win->handlers); WM_event_remove_handlers(C, &win->modalhandlers); ED_screen_exit(C, win, win->screen); } } /* reset active window */ CTX_wm_window_set(C, active_win); /* XXX Hack! We have to clear context menu here, because removing all modalhandlers above frees the active menu * (at least, in the 'startup splash' case), causing use-after-free error in later handling of the button * callbacks in UI code (see ui_apply_but_funcs_after()). * Tried solving this by always NULL-ing context's menu when setting wm/win/etc., but it broke popups refreshing * (see T47632), so for now just handling this specific case here. */ CTX_wm_menu_set(C, NULL); ED_editors_exit(C); /* just had return; here from r12991, this code could just get removed?*/ #if 0 if (wm == NULL) return; if (G.fileflags & G_FILE_NO_UI) return; /* we take apart the used screens from non-active window */ for (win = wm->windows.first; win; win = win->next) { BLI_strncpy(win->screenname, win->screen->id.name, MAX_ID_NAME); if (win != wm->winactive) { BLI_remlink(&G.main->screen, win->screen); //BLI_addtail(screenbase, win->screen); } } #endif }
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); }
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 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); } }
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); }
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 */ }
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 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); } }