Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--intern/ghost/intern/GHOST_WindowX11.cpp4
-rw-r--r--release/scripts/ui/space_info.py1
-rw-r--r--source/blender/blenkernel/BKE_global.h1
-rw-r--r--source/blender/blenkernel/intern/blender.c20
-rw-r--r--source/blender/blenloader/BLO_readfile.h1
-rw-r--r--source/blender/blenloader/intern/readfile.c3
-rw-r--r--source/blender/blenloader/intern/writefile.c7
-rw-r--r--source/blender/editors/interface/interface_handlers.c22
-rw-r--r--source/blender/editors/interface/interface_panel.c4
-rw-r--r--source/blender/editors/screen/screen_edit.c13
-rw-r--r--source/blender/editors/sculpt_paint/paint_image.c4
-rw-r--r--source/blender/editors/sculpt_paint/paint_stroke.c4
-rw-r--r--source/blender/editors/space_file/file_draw.c2
-rw-r--r--source/blender/editors/space_image/image_ops.c4
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c10
-rw-r--r--source/blender/editors/uvedit/uvedit_unwrap_ops.c4
-rw-r--r--source/blender/makesdna/DNA_fileglobal_types.h3
-rw-r--r--source/blender/makesdna/DNA_windowmanager_types.h5
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c8
-rw-r--r--source/blender/makesrna/intern/rna_wm.c2
-rw-r--r--source/blender/windowmanager/WM_api.h10
-rw-r--r--source/blender/windowmanager/WM_types.h3
-rw-r--r--source/blender/windowmanager/intern/wm.c11
-rw-r--r--source/blender/windowmanager/intern/wm_draw.c2
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c2
-rw-r--r--source/blender/windowmanager/intern/wm_files.c171
-rw-r--r--source/blender/windowmanager/intern/wm_init_exit.c2
-rw-r--r--source/blender/windowmanager/intern/wm_jobs.c27
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c79
-rw-r--r--source/blender/windowmanager/intern/wm_window.c98
-rw-r--r--source/blender/windowmanager/wm.h12
-rw-r--r--source/blender/windowmanager/wm_event_types.h3
-rw-r--r--source/blender/windowmanager/wm_window.h4
33 files changed, 325 insertions, 221 deletions
diff --git a/intern/ghost/intern/GHOST_WindowX11.cpp b/intern/ghost/intern/GHOST_WindowX11.cpp
index d40ce4145f5..5e6bb93d9ba 100644
--- a/intern/ghost/intern/GHOST_WindowX11.cpp
+++ b/intern/ghost/intern/GHOST_WindowX11.cpp
@@ -1412,7 +1412,7 @@ setWindowCursorGrab(
setWindowCursorVisibility(false);
}
- XGrabPointer(m_display, m_window, True, ButtonPressMask| ButtonReleaseMask|PointerMotionMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
+ //XGrabPointer(m_display, m_window, True, ButtonPressMask| ButtonReleaseMask|PointerMotionMask, GrabModeAsync, GrabModeAsync, None, None, CurrentTime);
}
else {
if (m_cursorGrab==GHOST_kGrabHide) {
@@ -1430,7 +1430,7 @@ setWindowCursorGrab(
/* Almost works without but important otherwise the mouse GHOST location can be incorrect on exit */
setCursorGrabAccum(0, 0);
m_cursorGrabBounds.m_l= m_cursorGrabBounds.m_r= -1; /* disable */
- XUngrabPointer(m_display, CurrentTime);
+ //XUngrabPointer(m_display, CurrentTime);
}
XFlush(m_display);
diff --git a/release/scripts/ui/space_info.py b/release/scripts/ui/space_info.py
index f9feef6f023..d1e4ac13ab7 100644
--- a/release/scripts/ui/space_info.py
+++ b/release/scripts/ui/space_info.py
@@ -54,6 +54,7 @@ class INFO_MT_file(bpy.types.Menu):
layout.itemO("wm.open_mainfile", text="Open...", icon='ICON_FILE_FOLDER')
layout.item_menu_enumO("wm.open_recentfile", "file", text="Open Recent")
layout.itemO("wm.recover_last_session")
+ layout.itemO("wm.recover_auto_save", text="Recover Auto Save...")
layout.itemS()
diff --git a/source/blender/blenkernel/BKE_global.h b/source/blender/blenkernel/BKE_global.h
index 5d0b89220d5..ccd21603c49 100644
--- a/source/blender/blenkernel/BKE_global.h
+++ b/source/blender/blenkernel/BKE_global.h
@@ -145,6 +145,7 @@ typedef struct Global {
#define G_FILE_GLSL_NO_NODES (1 << 20) /* deprecated */
#define G_FILE_GLSL_NO_EXTRA_TEX (1 << 21) /* deprecated */
#define G_FILE_IGNORE_DEPRECATION_WARNINGS (1 << 22) /* deprecated */
+#define G_FILE_RECOVER (1 << 23)
/* G.windowstate */
#define G_WINDOWSTATE_USERDEF 0
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index 2df5b7c173c..7570369827b 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -281,12 +281,15 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, char *filename)
Object *ob;
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);
clean_paths(bfd->main);
@@ -371,6 +374,16 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, char *filename)
if(G.main->versionfile < 250)
do_versions_ipos_to_animato(G.main); // XXX fixme... complicated versionpatching
+ /* in case of autosave or quit.blend, use original filename instead */
+ if(recover && bfd->filename[0])
+ filename= bfd->filename;
+
+ /* these are the same at times, should never copy to the same location */
+ if(G.sce != filename)
+ BLI_strncpy(G.sce, filename, FILE_MAX);
+
+ BLI_strncpy(G.main->name, filename, FILE_MAX); /* is guaranteed current file */
+
/* baseflags, groups, make depsgraph, etc */
set_scene_bg(CTX_data_scene(C));
@@ -383,11 +396,6 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, char *filename)
/* now tag update flags, to ensure deformers get calculated on redraw */
DAG_scene_update_flags(CTX_data_scene(C), CTX_data_scene(C)->lay);
- if (G.sce != filename) /* these are the same at times, should never copy to the same location */
- strcpy(G.sce, filename);
-
- BLI_strncpy(G.main->name, filename, FILE_MAX); /* is guaranteed current file */
-
MEM_freeN(bfd);
}
diff --git a/source/blender/blenloader/BLO_readfile.h b/source/blender/blenloader/BLO_readfile.h
index 52295dc3092..408d07b965c 100644
--- a/source/blender/blenloader/BLO_readfile.h
+++ b/source/blender/blenloader/BLO_readfile.h
@@ -62,6 +62,7 @@ typedef struct BlendFileData {
int fileflags;
int displaymode;
int globalf;
+ char filename[240]; /* 240 = FILE_MAX */
struct bScreen* curscreen;
struct Scene* curscene;
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 761fc8b079a..ca2e5f4de75 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -4432,7 +4432,6 @@ static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm)
win->curswin= NULL;
win->tweak= NULL;
- win->timers.first= win->timers.last= NULL;
win->queue.first= win->queue.last= NULL;
win->handlers.first= win->handlers.last= NULL;
win->modalhandlers.first= win->modalhandlers.last= NULL;
@@ -4444,6 +4443,7 @@ static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm)
win->drawfail= 0;
}
+ wm->timers.first= wm->timers.last= NULL;
wm->operators.first= wm->operators.last= NULL;
wm->paintcursors.first= wm->paintcursors.last= NULL;
wm->queue.first= wm->queue.last= NULL;
@@ -5468,6 +5468,7 @@ static BHead *read_global(BlendFileData *bfd, FileData *fd, BHead *bhead)
bfd->fileflags= fg->fileflags;
bfd->displaymode= fg->displaymode;
bfd->globalf= fg->globalf;
+ BLI_strncpy(bfd->filename, fg->filename, sizeof(bfd->filename));
bfd->curscreen= fg->curscreen;
bfd->curscene= fg->curscene;
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index e3d061d8e4b..f0c584b6267 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -2308,7 +2308,7 @@ static void write_scripts(WriteData *wd, ListBase *idbase)
/* context is usually defined by WM, two cases where no WM is available:
* - for forward compatibility, curscreen has to be saved
* - for undofile, curscene needs to be saved */
-static void write_global(WriteData *wd, Main *mainvar)
+static void write_global(WriteData *wd, int fileflags, Main *mainvar)
{
FileGlobal fg;
bScreen *screen;
@@ -2321,8 +2321,9 @@ static void write_global(WriteData *wd, Main *mainvar)
fg.curscene= screen->scene;
fg.displaymode= G.displaymode;
fg.winpos= G.winpos;
- fg.fileflags= (G.fileflags & ~G_FILE_NO_UI); // prevent to save this, is not good convention, and feature with concerns...
+ fg.fileflags= (fileflags & ~G_FILE_NO_UI); // prevent to save this, is not good convention, and feature with concerns...
fg.globalf= G.f;
+ BLI_strncpy(fg.filename, mainvar->name, sizeof(fg.filename));
sprintf(subvstr, "%4d", BLENDER_SUBVERSION);
memcpy(fg.subvstr, subvstr, 4);
@@ -2351,7 +2352,7 @@ static int write_file_handle(Main *mainvar, int handle, MemFile *compare, MemFil
mywrite(wd, buf, 12);
write_renderinfo(wd, mainvar);
- write_global(wd, mainvar);
+ write_global(wd, write_flags, mainvar);
/* no UI save in undo */
if(current==NULL) {
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 29d84076533..554e729e0e2 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -92,6 +92,7 @@ typedef enum uiHandleButtonState {
} uiHandleButtonState;
typedef struct uiHandleButtonData {
+ wmWindowManager *wm;
wmWindow *window;
ARegion *region;
@@ -3677,7 +3678,7 @@ static void button_timers_tooltip_remove(bContext *C, uiBut *but)
data= but->active;
if(data->tooltiptimer) {
- WM_event_remove_window_timer(data->window, data->tooltiptimer);
+ WM_event_remove_timer(data->wm, data->window, data->tooltiptimer);
data->tooltiptimer= NULL;
}
if(data->tooltip) {
@@ -3686,7 +3687,7 @@ static void button_timers_tooltip_remove(bContext *C, uiBut *but)
}
if(data->autoopentimer) {
- WM_event_remove_window_timer(data->window, data->autoopentimer);
+ WM_event_remove_timer(data->wm, data->window, data->autoopentimer);
data->autoopentimer= NULL;
}
}
@@ -3698,13 +3699,13 @@ static void button_tooltip_timer_reset(uiBut *but)
data= but->active;
if(data->tooltiptimer) {
- WM_event_remove_window_timer(data->window, data->tooltiptimer);
+ WM_event_remove_timer(data->wm, data->window, data->tooltiptimer);
data->tooltiptimer= NULL;
}
if(U.flag & USER_TOOLTIPS)
if(!but->block->tooltipdisabled)
- data->tooltiptimer= WM_event_add_window_timer(data->window, TIMER, BUTTON_TOOLTIP_DELAY);
+ data->tooltiptimer= WM_event_add_timer(data->wm, data->window, TIMER, BUTTON_TOOLTIP_DELAY);
}
static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState state)
@@ -3732,7 +3733,7 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s
else time= -1;
if(time >= 0)
- data->autoopentimer= WM_event_add_window_timer(data->window, TIMER, 0.02*(double)time);
+ data->autoopentimer= WM_event_add_timer(data->wm, data->window, TIMER, 0.02*(double)time);
}
}
}
@@ -3765,10 +3766,10 @@ static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState s
/* add a short delay before exiting, to ensure there is some feedback */
if(state == BUTTON_STATE_WAIT_FLASH) {
- data->flashtimer= WM_event_add_window_timer(data->window, TIMER, BUTTON_FLASH_DELAY);
+ data->flashtimer= WM_event_add_timer(data->wm, data->window, TIMER, BUTTON_FLASH_DELAY);
}
else if(data->flashtimer) {
- WM_event_remove_window_timer(data->window, data->flashtimer);
+ WM_event_remove_timer(data->wm, data->window, data->flashtimer);
data->flashtimer= NULL;
}
@@ -3799,6 +3800,7 @@ static void button_activate_init(bContext *C, ARegion *ar, uiBut *but, uiButtonA
/* setup struct */
data= MEM_callocN(sizeof(uiHandleButtonData), "uiHandleButtonData");
+ data->wm= CTX_wm_manager(C);
data->window= CTX_wm_window(C);
data->region= ar;
if( ELEM(but->type, BUT_CURVE, SEARCH_MENU) ); // XXX curve is temp
@@ -4036,7 +4038,7 @@ static int ui_handle_button_event(bContext *C, wmEvent *event, uiBut *but)
case TIMER: {
/* handle tooltip timer */
if(event->customdata == data->tooltiptimer) {
- WM_event_remove_window_timer(data->window, data->tooltiptimer);
+ WM_event_remove_timer(data->wm, data->window, data->tooltiptimer);
data->tooltiptimer= NULL;
if(!data->tooltip)
@@ -4044,7 +4046,7 @@ static int ui_handle_button_event(bContext *C, wmEvent *event, uiBut *but)
}
/* handle menu auto open timer */
else if(event->customdata == data->autoopentimer) {
- WM_event_remove_window_timer(data->window, data->autoopentimer);
+ WM_event_remove_timer(data->wm, data->window, data->autoopentimer);
data->autoopentimer= NULL;
if(ui_mouse_inside_button(ar, but, event->x, event->y))
@@ -4058,7 +4060,7 @@ static int ui_handle_button_event(bContext *C, wmEvent *event, uiBut *but)
case MIDDLEMOUSE:
/* XXX hardcoded keymap check... but anyway, while view changes, tooltips should be removed */
if(data->tooltiptimer) {
- WM_event_remove_window_timer(data->window, data->tooltiptimer);
+ WM_event_remove_timer(data->wm, data->window, data->tooltiptimer);
data->tooltiptimer= NULL;
}
/* pass on purposedly */
diff --git a/source/blender/editors/interface/interface_panel.c b/source/blender/editors/interface/interface_panel.c
index 2123b412d61..20cd6ebf971 100644
--- a/source/blender/editors/interface/interface_panel.c
+++ b/source/blender/editors/interface/interface_panel.c
@@ -1189,7 +1189,7 @@ static void panel_activate_state(const bContext *C, Panel *pa, uiHandlePanelStat
pa->flag |= PNL_SELECT;
if(data && data->animtimer) {
- WM_event_remove_window_timer(win, data->animtimer);
+ WM_event_remove_timer(CTX_wm_manager(C), win, data->animtimer);
data->animtimer= NULL;
}
@@ -1208,7 +1208,7 @@ static void panel_activate_state(const bContext *C, Panel *pa, uiHandlePanelStat
}
if(ELEM(state, PANEL_STATE_ANIMATION, PANEL_STATE_DRAG))
- data->animtimer= WM_event_add_window_timer(win, TIMER, ANIMATION_INTERVAL);
+ data->animtimer= WM_event_add_timer(CTX_wm_manager(C), win, TIMER, ANIMATION_INTERVAL);
data->state= state;
data->startx= win->eventstate->x;
diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c
index 2cc5500c3ef..6b71ccaba10 100644
--- a/source/blender/editors/screen/screen_edit.c
+++ b/source/blender/editors/screen/screen_edit.c
@@ -1040,7 +1040,7 @@ void ED_screen_refresh(wmWindowManager *wm, wmWindow *win)
/* wake up animtimer */
if(win->screen->animtimer)
- WM_event_window_timer_sleep(win, win->screen->animtimer, 0);
+ WM_event_timer_sleep(wm, win, win->screen->animtimer, 0);
if(G.f & G_DEBUG) printf("set screen\n");
win->screen->do_refresh= 0;
@@ -1097,6 +1097,7 @@ void ED_area_exit(bContext *C, ScrArea *sa)
void ED_screen_exit(bContext *C, wmWindow *window, bScreen *screen)
{
+ wmWindowManager *wm= CTX_wm_manager(C);
wmWindow *prevwin= CTX_wm_window(C);
ScrArea *sa;
ARegion *ar;
@@ -1104,7 +1105,7 @@ void ED_screen_exit(bContext *C, wmWindow *window, bScreen *screen)
CTX_wm_window_set(C, window);
if(screen->animtimer)
- WM_event_remove_window_timer(window, screen->animtimer);
+ WM_event_remove_timer(wm, window, screen->animtimer);
screen->animtimer= NULL;
if(screen->mainwin)
@@ -1232,6 +1233,7 @@ int ED_screen_area_active(const bContext *C)
/* Do NOT call in area/region queues! */
void ED_screen_set(bContext *C, bScreen *sc)
{
+ wmWindowManager *wm= CTX_wm_manager(C);
wmWindow *win= CTX_wm_window(C);
bScreen *oldscreen= CTX_wm_screen(C);
ID *id;
@@ -1264,7 +1266,7 @@ void ED_screen_set(bContext *C, bScreen *sc)
/* we put timer to sleep, so screen_exit has to think there's no timer */
oldscreen->animtimer= NULL;
if(wt)
- WM_event_window_timer_sleep(win, wt, 1);
+ WM_event_timer_sleep(wm, win, wt, 1);
ED_screen_exit(C, win, oldscreen);
oldscreen->animtimer= wt;
@@ -1519,17 +1521,18 @@ void ED_screen_full_prevspace(bContext *C)
void ED_screen_animation_timer(bContext *C, int redraws, int sync, int enable)
{
bScreen *screen= CTX_wm_screen(C);
+ wmWindowManager *wm= CTX_wm_manager(C);
wmWindow *win= CTX_wm_window(C);
Scene *scene= CTX_data_scene(C);
if(screen->animtimer)
- WM_event_remove_window_timer(win, screen->animtimer);
+ WM_event_remove_timer(wm, win, screen->animtimer);
screen->animtimer= NULL;
if(enable) {
struct ScreenAnimData *sad= MEM_callocN(sizeof(ScreenAnimData), "ScreenAnimData");
- screen->animtimer= WM_event_add_window_timer(win, TIMER0, (1.0/FPS));
+ screen->animtimer= WM_event_add_timer(wm, win, TIMER0, (1.0/FPS));
sad->ar= CTX_wm_region(C);
sad->redraws= redraws;
sad->flag |= (enable < 0)? ANIMPLAY_FLAG_REVERSE: 0;
diff --git a/source/blender/editors/sculpt_paint/paint_image.c b/source/blender/editors/sculpt_paint/paint_image.c
index 7596191e781..21651afe417 100644
--- a/source/blender/editors/sculpt_paint/paint_image.c
+++ b/source/blender/editors/sculpt_paint/paint_image.c
@@ -4645,7 +4645,7 @@ static void paint_exit(bContext *C, wmOperator *op)
PaintOperation *pop= op->customdata;
if(pop->timer)
- WM_event_remove_window_timer(CTX_wm_window(C), pop->timer);
+ WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), pop->timer);
settings->imapaint.flag &= ~IMAGEPAINT_DRAWING;
imapaint_canvas_free(&pop->s);
@@ -4757,7 +4757,7 @@ static int paint_invoke(bContext *C, wmOperator *op, wmEvent *event)
WM_event_add_modal_handler(C, op);
if(pop->s.brush->flag & BRUSH_AIRBRUSH)
- pop->timer= WM_event_add_window_timer(CTX_wm_window(C), TIMER, 0.01f);
+ pop->timer= WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER, 0.01f);
return OPERATOR_RUNNING_MODAL;
}
diff --git a/source/blender/editors/sculpt_paint/paint_stroke.c b/source/blender/editors/sculpt_paint/paint_stroke.c
index b83352ae70c..6e256bee7f2 100644
--- a/source/blender/editors/sculpt_paint/paint_stroke.c
+++ b/source/blender/editors/sculpt_paint/paint_stroke.c
@@ -243,7 +243,7 @@ int paint_stroke_modal(bContext *C, wmOperator *op, wmEvent *event)
WM_paint_cursor_activate(CTX_wm_manager(C), paint_poll, paint_draw_smooth_stroke, stroke);
if(stroke->brush->flag & BRUSH_AIRBRUSH)
- stroke->timer = WM_event_add_window_timer(CTX_wm_window(C), TIMER, stroke->brush->rate);
+ stroke->timer = WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER, stroke->brush->rate);
}
ED_region_tag_redraw(ar);
@@ -270,7 +270,7 @@ int paint_stroke_modal(bContext *C, wmOperator *op, wmEvent *event)
WM_paint_cursor_end(CTX_wm_manager(C), stroke->smooth_stroke_cursor);
if(stroke->timer)
- WM_event_remove_window_timer(CTX_wm_window(C), stroke->timer);
+ WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), stroke->timer);
stroke->done(C, stroke);
MEM_freeN(stroke);
diff --git a/source/blender/editors/space_file/file_draw.c b/source/blender/editors/space_file/file_draw.c
index 77a1b671054..2a1bb8b4add 100644
--- a/source/blender/editors/space_file/file_draw.c
+++ b/source/blender/editors/space_file/file_draw.c
@@ -610,7 +610,7 @@ void file_draw_list(const bContext *C, ARegion *ar)
}
if (!sfile->loadimage_timer)
- sfile->loadimage_timer= WM_event_add_window_timer(CTX_wm_window(C), TIMER1, 1.0/30.0); /* max 30 frames/sec. */
+ sfile->loadimage_timer= WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER1, 1.0/30.0); /* max 30 frames/sec. */
}
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index 482750e5b2e..ffc737eb9af 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -1680,7 +1680,7 @@ static void record_composite_exit(bContext *C, wmOperator *op)
WM_cursor_restore(CTX_wm_window(C));
if(rcd->timer)
- WM_event_remove_window_timer(CTX_wm_window(C), rcd->timer);
+ WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), rcd->timer);
WM_event_add_notifier(C, NC_IMAGE|NA_EDITED, sima->image);
@@ -1711,7 +1711,7 @@ static int record_composite_invoke(bContext *C, wmOperator *op, wmEvent *event)
return OPERATOR_CANCELLED;
rcd= op->customdata;
- rcd->timer= WM_event_add_window_timer(CTX_wm_window(C), TIMER, 0.0f);
+ rcd->timer= WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER, 0.0f);
WM_event_add_modal_handler(C, op);
if(!record_composite_apply(C, op))
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index ae496158a46..12654bdac14 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -292,9 +292,9 @@ void smooth_view(bContext *C, Object *oldcamera, Object *camera, float *ofs, flo
rv3d->sms= MEM_mallocN(sizeof(struct SmoothViewStore), "smoothview v3d");
*rv3d->sms= sms;
if(rv3d->smooth_timer)
- WM_event_remove_window_timer(CTX_wm_window(C), rv3d->smooth_timer);
+ WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), rv3d->smooth_timer);
/* TIMER1 is hardcoded in keymap */
- rv3d->smooth_timer= WM_event_add_window_timer(CTX_wm_window(C), TIMER1, 1.0/30.0); /* max 30 frs/sec */
+ rv3d->smooth_timer= WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER1, 1.0/30.0); /* max 30 frs/sec */
return;
}
@@ -346,7 +346,7 @@ static int view3d_smoothview_invoke(bContext *C, wmOperator *op, wmEvent *event)
MEM_freeN(rv3d->sms);
rv3d->sms= NULL;
- WM_event_remove_window_timer(CTX_wm_window(C), rv3d->smooth_timer);
+ WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), rv3d->smooth_timer);
rv3d->smooth_timer= NULL;
}
else {
@@ -1798,7 +1798,7 @@ int initFlyInfo (bContext *C, FlyInfo *fly, wmOperator *op, wmEvent *event)
fly->dvec_prev[0]= fly->dvec_prev[1]= fly->dvec_prev[2]= 0.0f;
- fly->timer= WM_event_add_window_timer(CTX_wm_window(C), TIMER, 0.01f);
+ fly->timer= WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER, 0.01f);
/* we have to rely on events to give proper mousecoords after a warp_pointer */
@@ -1867,7 +1867,7 @@ static int flyEnd(bContext *C, FlyInfo *fly)
if(fly->state == FLY_RUNNING)
return OPERATOR_RUNNING_MODAL;
- WM_event_remove_window_timer(CTX_wm_window(C), fly->timer);
+ WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), fly->timer);
rv3d->dist= fly->dist_backup;
diff --git a/source/blender/editors/uvedit/uvedit_unwrap_ops.c b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
index c7258e616fa..019ac33dfd0 100644
--- a/source/blender/editors/uvedit/uvedit_unwrap_ops.c
+++ b/source/blender/editors/uvedit/uvedit_unwrap_ops.c
@@ -303,7 +303,7 @@ static void minimize_stretch_exit(bContext *C, wmOperator *op, int cancel)
if(sa)
ED_area_headerprint(sa, NULL);
if(ms->timer)
- WM_event_remove_window_timer(CTX_wm_window(C), ms->timer);
+ WM_event_remove_timer(CTX_wm_manager(C), CTX_wm_window(C), ms->timer);
if(cancel)
param_flush_restore(ms->handle);
@@ -343,7 +343,7 @@ static int minimize_stretch_invoke(bContext *C, wmOperator *op, wmEvent *event)
ms= op->customdata;
WM_event_add_modal_handler(C, op);
- ms->timer= WM_event_add_window_timer(CTX_wm_window(C), TIMER, 0.01f);
+ ms->timer= WM_event_add_timer(CTX_wm_manager(C), CTX_wm_window(C), TIMER, 0.01f);
return OPERATOR_RUNNING_MODAL;
}
diff --git a/source/blender/makesdna/DNA_fileglobal_types.h b/source/blender/makesdna/DNA_fileglobal_types.h
index 43ab895b398..271c8d2a33e 100644
--- a/source/blender/makesdna/DNA_fileglobal_types.h
+++ b/source/blender/makesdna/DNA_fileglobal_types.h
@@ -47,6 +47,9 @@ typedef struct FileGlobal {
struct Scene *curscene;
int fileflags;
int globalf;
+
+ /* file path where this was saved, for recover */
+ char filename[240]; /* 240 = FILE_MAX */
} FileGlobal;
diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h
index 7a024e35ff0..5cdd74c8262 100644
--- a/source/blender/makesdna/DNA_windowmanager_types.h
+++ b/source/blender/makesdna/DNA_windowmanager_types.h
@@ -124,6 +124,9 @@ typedef struct wmWindowManager {
ListBase keyconfigs; /* known key configurations */
struct wmKeyConfig *defaultconf; /* default configuration, not saved */
int defaultactmap, pad2; /* active keymap from default for editing */
+
+ ListBase timers; /* active timers */
+ struct wmTimer *autosavetimer; /* timer for auto save */
} wmWindowManager;
/* wmWindowManager.initialized */
@@ -160,8 +163,6 @@ typedef struct wmWindow {
int drawmethod, drawfail; /* internal for wm_draw.c only */
void *drawdata; /* internal for wm_draw.c only */
- ListBase timers;
-
ListBase queue; /* all events (ghost level events were handled) */
ListBase handlers; /* window+screen handlers, handled last */
ListBase modalhandlers; /* priority handlers, handled first */
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index 1acf3c8effa..f9192a9473e 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -146,7 +146,11 @@ static void rna_UserDef_weight_color_update(bContext *C, PointerRNA *ptr)
rna_userdef_update(C, ptr);
}
-
+static void rna_userdef_autosave_update(bContext *C, PointerRNA *ptr)
+{
+ WM_autosave_init(C);
+ rna_userdef_update(C, ptr);
+}
#else
@@ -2344,11 +2348,13 @@ static void rna_def_userdef_filepaths(BlenderRNA *brna)
prop= RNA_def_property(srna, "auto_save_temporary_files", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", USER_AUTOSAVE);
RNA_def_property_ui_text(prop, "Auto Save Temporary Files", "Automatic saving of temporary files.");
+ RNA_def_property_update(prop, 0, "rna_userdef_autosave_update");
prop= RNA_def_property(srna, "auto_save_time", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "savetime");
RNA_def_property_range(prop, 1, 60);
RNA_def_property_ui_text(prop, "Auto Save Time", "The time (in minutes) to wait between automatic temporary saves.");
+ RNA_def_property_update(prop, 0, "rna_userdef_autosave_update");
prop= RNA_def_property(srna, "recent_files", PROP_INT, PROP_NONE);
RNA_def_property_range(prop, 0, 30);
diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c
index 2189412783a..e2e50b695fd 100644
--- a/source/blender/makesrna/intern/rna_wm.c
+++ b/source/blender/makesrna/intern/rna_wm.c
@@ -93,7 +93,6 @@ EnumPropertyItem event_timer_type_items[]= {
{TIMER0, "TIMER0", 0, "Timer 0", ""},
{TIMER1, "TIMER1", 0, "Timer 1", ""},
{TIMER2, "TIMER2", 0, "Timer 2", ""},
- {TIMERJOBS, "JOBS_TIMER", 0, "Jobs Timer", ""},
{0, NULL, 0, NULL, NULL}};
/* not returned: CAPSLOCKKEY, UNKNOWNKEY, GRLESSKEY */
@@ -229,7 +228,6 @@ EnumPropertyItem event_type_items[] = {
{TIMER0, "TIMER0", 0, "Timer 0", ""},
{TIMER1, "TIMER1", 0, "Timer 1", ""},
{TIMER2, "TIMER2", 0, "Timer 2", ""},
- {TIMERJOBS, "JOBS_TIMER", 0, "Jobs Timer", ""},
{0, NULL, 0, NULL, NULL}};
#define KMI_TYPE_KEYBOARD 0
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index 59f3bcd4edc..224338e557a 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -67,9 +67,9 @@ void WM_window_open_temp (struct bContext *C, struct rcti *position, int type);
int WM_read_homefile (struct bContext *C, struct wmOperator *op);
int WM_write_homefile (struct bContext *C, struct wmOperator *op);
void WM_read_file (struct bContext *C, char *name, struct ReportList *reports);
-void WM_write_file (struct bContext *C, char *target, int compress, struct ReportList *reports);
+void WM_write_file (struct bContext *C, char *target, int fileflags, struct ReportList *reports);
void WM_read_autosavefile(struct bContext *C);
-void WM_write_autosave (struct bContext *C);
+void WM_autosave_init (struct bContext *C);
/* mouse cursors */
void WM_cursor_set (struct wmWindow *win, int curs);
@@ -141,9 +141,9 @@ void WM_main_add_notifier(unsigned int type, void *reference);
void wm_event_add (struct wmWindow *win, struct wmEvent *event_to_add); /* XXX only for warning */
/* at maximum, every timestep seconds it triggers event_type events */
-struct wmTimer *WM_event_add_window_timer(struct wmWindow *win, int event_type, double timestep);
-void WM_event_remove_window_timer(struct wmWindow *win, struct wmTimer *timer);
-void WM_event_window_timer_sleep(struct wmWindow *win, struct wmTimer *timer, int dosleep);
+struct wmTimer *WM_event_add_timer(struct wmWindowManager *wm, struct wmWindow *win, int event_type, double timestep);
+void WM_event_remove_timer(struct wmWindowManager *wm, struct wmWindow *win, struct wmTimer *timer);
+void WM_event_timer_sleep(struct wmWindowManager *wm, struct wmWindow *win, struct wmTimer *timer, int dosleep);
/* operator api, default callbacks */
/* invoke callback, uses enum property named "type" */
diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h
index 31cb5ee0832..0ef7e9670dc 100644
--- a/source/blender/windowmanager/WM_types.h
+++ b/source/blender/windowmanager/WM_types.h
@@ -289,6 +289,9 @@ typedef struct wmTabletData {
typedef struct wmTimer {
struct wmTimer *next, *prev;
+
+ struct wmWindow *win; /* window this timer is attached to (optional) */
+
double timestep; /* set by timer user */
int event_type; /* set by timer user, goes to event system */
void *customdata; /* set by timer user, to allow custom values */
diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c
index f4baa42515c..1d173005d85 100644
--- a/source/blender/windowmanager/intern/wm.c
+++ b/source/blender/windowmanager/intern/wm.c
@@ -209,8 +209,10 @@ void wm_check(bContext *C)
if(wm->windows.first==NULL) return;
/* case: fileread */
- if((wm->initialized & WM_INIT_WINDOW) == 0)
+ if((wm->initialized & WM_INIT_WINDOW) == 0) {
WM_keymap_init(C);
+ WM_autosave_init(C);
+ }
/* case: no open windows at all, for old file reads */
wm_window_add_ghostwindows(wm);
@@ -269,12 +271,15 @@ void wm_close_and_free(bContext *C, wmWindowManager *wm)
wmWindow *win;
wmOperator *op;
wmKeyConfig *keyconf;
-
+
+ if(wm->autosavetimer)
+ wm_autosave_timer_ended(wm);
+
while((win= wm->windows.first)) {
BLI_remlink(&wm->windows, win);
win->screen= NULL; /* prevent draw clear to use screen */
wm_draw_window_clear(win);
- wm_window_free(C, win);
+ wm_window_free(C, wm, win);
}
while((op= wm->operators.first)) {
diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c
index 93ecd4076a3..e7c04141ad3 100644
--- a/source/blender/windowmanager/intern/wm_draw.c
+++ b/source/blender/windowmanager/intern/wm_draw.c
@@ -44,6 +44,8 @@
#include "ED_screen.h"
+#include "GPU_extensions.h"
+
#include "WM_api.h"
#include "WM_types.h"
#include "wm.h"
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index 8eca0a1b416..f301a20a7c1 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -791,7 +791,7 @@ static int wm_eventmatch(wmEvent *winevent, wmKeyMapItem *kmi)
static int wm_event_always_pass(wmEvent *event)
{
/* some events we always pass on, to ensure proper communication */
- return ELEM5(event->type, TIMER, TIMER0, TIMER1, TIMER2, TIMERJOBS);
+ return ELEM4(event->type, TIMER, TIMER0, TIMER1, TIMER2);
}
/* operator exists */
diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c
index ff0e69b74d4..b2e55c8532e 100644
--- a/source/blender/windowmanager/intern/wm_files.c
+++ b/source/blender/windowmanager/intern/wm_files.c
@@ -95,6 +95,7 @@
#include "WM_types.h"
#include "wm.h"
#include "wm_window.h"
+#include "wm_event_system.h"
static void writeBlog(void);
@@ -348,49 +349,6 @@ int WM_read_homefile(bContext *C, wmOperator *op)
}
-static void get_autosave_location(char buf[FILE_MAXDIR+FILE_MAXFILE])
-{
- char pidstr[32];
-#ifdef WIN32
- char subdir[9];
- char savedir[FILE_MAXDIR];
-#endif
-
- sprintf(pidstr, "%d.blend", abs(getpid()));
-
-#ifdef WIN32
- if (!BLI_exists(U.tempdir)) {
- BLI_strncpy(subdir, "autosave", sizeof(subdir));
- BLI_make_file_string("/", savedir, BLI_gethome(), subdir);
-
- /* create a new autosave dir
- * function already checks for existence or not */
- BLI_recurdir_fileops(savedir);
-
- BLI_make_file_string("/", buf, savedir, pidstr);
- return;
- }
-#endif
-
- BLI_make_file_string("/", buf, U.tempdir, pidstr);
-}
-
-void WM_read_autosavefile(bContext *C)
-{
- char tstr[FILE_MAX], scestr[FILE_MAX];
- int save_over;
-
- BLI_strncpy(scestr, G.sce, FILE_MAX); /* temporal store */
-
- get_autosave_location(tstr);
-
- save_over = G.save_over;
- BKE_read_file(C, tstr, NULL, NULL);
- G.save_over = save_over;
- BLI_strncpy(G.sce, scestr, FILE_MAX);
-}
-
-
void read_Blog(void)
{
char name[FILE_MAX];
@@ -496,10 +454,10 @@ static void do_history(char *name, ReportList *reports)
BKE_report(reports, RPT_ERROR, "Unable to make version backup");
}
-void WM_write_file(bContext *C, char *target, int compress, ReportList *reports)
+void WM_write_file(bContext *C, char *target, int fileflags, ReportList *reports)
{
Library *li;
- int writeflags, len;
+ int len;
char di[FILE_MAX];
len = strlen(target);
@@ -537,20 +495,14 @@ void WM_write_file(bContext *C, char *target, int compress, ReportList *reports)
do_history(di, reports);
- writeflags= G.fileflags;
-
- /* set compression flag */
- if(compress) writeflags |= G_FILE_COMPRESS;
- else writeflags &= ~G_FILE_COMPRESS;
-
- if (BLO_write_file(CTX_data_main(C), di, writeflags, reports)) {
+ if (BLO_write_file(CTX_data_main(C), di, fileflags, reports)) {
strcpy(G.sce, di);
G.relbase_valid = 1;
strcpy(G.main->name, di); /* is guaranteed current file */
G.save_over = 1; /* disable untitled.blend convention */
- if(compress) G.fileflags |= G_FILE_COMPRESS;
+ if(fileflags & G_FILE_COMPRESS) G.fileflags |= G_FILE_COMPRESS;
else G.fileflags &= ~G_FILE_COMPRESS;
writeBlog();
@@ -562,56 +514,125 @@ void WM_write_file(bContext *C, char *target, int compress, ReportList *reports)
/* operator entry */
int WM_write_homefile(bContext *C, wmOperator *op)
{
+ wmWindowManager *wm= CTX_wm_manager(C);
wmWindow *win= CTX_wm_window(C);
char tstr[FILE_MAXDIR+FILE_MAXFILE];
- int write_flags;
+ int fileflags;
/* check current window and close it if temp */
- if(win->screen->full == SCREENTEMP) {
- wm_window_close(C, win);
- }
+ if(win->screen->full == SCREENTEMP)
+ wm_window_close(C, wm, win);
BLI_make_file_string("/", tstr, BLI_gethome(), ".B25.blend");
/* force save as regular blend file */
- write_flags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_LOCK | G_FILE_SIGN);
+ fileflags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_LOCK | G_FILE_SIGN);
- BLO_write_file(CTX_data_main(C), tstr, write_flags, op->reports);
+ BLO_write_file(CTX_data_main(C), tstr, fileflags, op->reports);
G.save_over= 0;
return OPERATOR_FINISHED;
}
-void WM_write_autosave(bContext *C)
+/************************ autosave ****************************/
+
+void wm_autosave_location(char *filename)
{
- char tstr[FILE_MAXDIR+FILE_MAXFILE];
- int write_flags;
+ char pidstr[32];
+#ifdef WIN32
+ char subdir[9];
+ char savedir[FILE_MAXDIR];
+#endif
+
+ sprintf(pidstr, "%d.blend", abs(getpid()));
+
+#ifdef WIN32
+ if (!BLI_exists(U.tempdir)) {
+ BLI_strncpy(subdir, "autosave", sizeof(subdir));
+ BLI_make_file_string("/", savedir, BLI_gethome(), subdir);
+
+ /* create a new autosave dir
+ * function already checks for existence or not */
+ BLI_recurdir_fileops(savedir);
+
+ BLI_make_file_string("/", filename, savedir, pidstr);
+ return;
+ }
+#endif
- get_autosave_location(tstr);
+ BLI_make_file_string("/", filename, U.tempdir, pidstr);
+}
- /* force save as regular blend file */
- write_flags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_LOCK | G_FILE_SIGN);
+void WM_autosave_init(bContext *C)
+{
+ wmWindowManager *wm= CTX_wm_manager(C);
+ wm_autosave_timer_ended(wm);
- /* error reporting to console */
- BLO_write_file(CTX_data_main(C), tstr, write_flags, NULL);
+ if(U.flag & USER_AUTOSAVE)
+ wm->autosavetimer= WM_event_add_timer(wm, NULL, TIMERAUTOSAVE, U.savetime*60.0);
}
-/* if global undo; remove tempsave, otherwise rename */
-void delete_autosave(void)
+void wm_autosave_timer(const bContext *C, wmWindowManager *wm, wmTimer *wt)
{
- char tstr[FILE_MAXDIR+FILE_MAXFILE];
+ wmWindow *win;
+ wmEventHandler *handler;
+ char filename[FILE_MAX];
+ int fileflags;
+
+ WM_event_remove_timer(wm, NULL, wm->autosavetimer);
+
+ /* if a modal operator is running, don't autosave, but try again in 10 seconds */
+ for(win=wm->windows.first; win; win=win->next) {
+ for(handler=win->modalhandlers.first; handler; handler=handler->next) {
+ if(handler->op) {
+ wm->autosavetimer= WM_event_add_timer(wm, NULL, TIMERAUTOSAVE, 10.0);
+ return;
+ }
+ }
+ }
- get_autosave_location(tstr);
+ wm_autosave_location(filename);
+
+ /* force save as regular blend file */
+ fileflags = G.fileflags & ~(G_FILE_COMPRESS|G_FILE_LOCK|G_FILE_SIGN);
+
+ /* no error reporting to console */
+ BLO_write_file(CTX_data_main(C), filename, fileflags, NULL);
- if (BLI_exists(tstr)) {
+ /* do timer after file write, just in case file write takes a long time */
+ wm->autosavetimer= WM_event_add_timer(wm, NULL, TIMERAUTOSAVE, U.savetime*60.0);
+}
+
+void wm_autosave_timer_ended(wmWindowManager *wm)
+{
+ if(wm->autosavetimer) {
+ WM_event_remove_timer(wm, NULL, wm->autosavetimer);
+ wm->autosavetimer= NULL;
+ }
+}
+
+void wm_autosave_delete(void)
+{
+ char filename[FILE_MAX];
+
+ wm_autosave_location(filename);
+
+ if(BLI_exists(filename)) {
char str[FILE_MAXDIR+FILE_MAXFILE];
BLI_make_file_string("/", str, U.tempdir, "quit.blend");
- if(U.uiflag & USER_GLOBALUNDO) BLI_delete(tstr, 0, 0);
- else BLI_rename(tstr, str);
+ /* if global undo; remove tempsave, otherwise rename */
+ if(U.uiflag & USER_GLOBALUNDO) BLI_delete(filename, 0, 0);
+ else BLI_rename(filename, str);
}
}
-/***/
+void wm_autosave_read(bContext *C, ReportList *reports)
+{
+ char filename[FILE_MAX];
+
+ wm_autosave_location(filename);
+ WM_read_file(C, filename, reports);
+}
diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c
index 2e456669cb1..8097822acbc 100644
--- a/source/blender/windowmanager/intern/wm_init_exit.c
+++ b/source/blender/windowmanager/intern/wm_init_exit.c
@@ -283,7 +283,7 @@ void WM_exit(bContext *C)
printf("Error Totblock: %d\n", MEM_get_memory_blocks_in_use());
MEM_printmemlist();
}
-// delete_autosave();
+ wm_autosave_delete();
printf("\nBlender quit\n");
diff --git a/source/blender/windowmanager/intern/wm_jobs.c b/source/blender/windowmanager/intern/wm_jobs.c
index 498306484e9..c2ecf0c59e7 100644
--- a/source/blender/windowmanager/intern/wm_jobs.c
+++ b/source/blender/windowmanager/intern/wm_jobs.c
@@ -255,7 +255,7 @@ void WM_jobs_start(wmWindowManager *wm, wmJob *steve)
/* restarted job has timer already */
if(steve->wt==NULL)
- steve->wt= WM_event_add_window_timer(steve->win, TIMERJOBS, steve->timestep);
+ steve->wt= WM_event_add_timer(wm, steve->win, TIMERJOBS, steve->timestep);
}
else printf("job fails, not initialized\n");
}
@@ -271,7 +271,7 @@ static void wm_jobs_kill_job(wmWindowManager *wm, wmJob *steve)
}
if(steve->wt)
- WM_event_remove_window_timer(steve->win, steve->wt);
+ WM_event_remove_timer(wm, steve->win, steve->wt);
if(steve->customdata)
steve->free(steve->customdata);
if(steve->run_customdata)
@@ -317,14 +317,13 @@ void wm_jobs_timer_ended(wmWindowManager *wm, wmTimer *wt)
}
/* hardcoded to event TIMERJOBS */
-static int wm_jobs_timer(bContext *C, wmOperator *op, wmEvent *evt)
+void wm_jobs_timer(const bContext *C, wmWindowManager *wm, wmTimer *wt)
{
- wmWindowManager *wm= CTX_wm_manager(C);
wmJob *steve= wm->jobs.first;
for(; steve; steve= steve->next) {
- if(evt->customdata==steve->wt) {
+ if(steve->wt==wt) {
/* running threads */
if(steve->threads.first) {
@@ -358,7 +357,7 @@ static int wm_jobs_timer(bContext *C, wmOperator *op, wmEvent *evt)
WM_jobs_start(wm, steve);
}
else {
- WM_event_remove_window_timer(steve->win, steve->wt);
+ WM_event_remove_timer(wm, steve->win, steve->wt);
steve->wt= NULL;
/* remove steve */
@@ -370,23 +369,7 @@ static int wm_jobs_timer(bContext *C, wmOperator *op, wmEvent *evt)
else if(steve->suspended) {
WM_jobs_start(wm, steve);
}
-
- return OPERATOR_FINISHED;
}
}
- return OPERATOR_PASS_THROUGH;
}
-void WM_OT_jobs_timer(wmOperatorType *ot)
-{
- /* identifiers */
- ot->name= "Jobs timer";
- ot->idname= "WM_OT_jobs_timer";
- ot->description="Jobs timer operator.";
-
- /* api callbacks */
- ot->invoke= wm_jobs_timer;
-
- ot->poll= ED_operator_screenactive;
-
-}
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index cc5967ab23a..7a97ebf0de7 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -972,7 +972,7 @@ static int wm_open_mainfile_exec(bContext *C, wmOperator *op)
WM_read_file(C, path, op->reports);
- return 0;
+ return OPERATOR_FINISHED;
}
static void WM_OT_open_mainfile(wmOperatorType *ot)
@@ -1154,12 +1154,9 @@ static void WM_OT_link_append(wmOperatorType *ot)
static int wm_recover_last_session_exec(bContext *C, wmOperator *op)
{
- char scestr[FILE_MAX], filename[FILE_MAX];
- int save_over;
+ char filename[FILE_MAX];
- /* back up some values */
- BLI_strncpy(scestr, G.sce, sizeof(scestr));
- save_over = G.save_over;
+ G.fileflags |= G_FILE_RECOVER;
// XXX wm in context is not set correctly after WM_read_file -> crash
// do it before for now, but is this correct with multiple windows?
@@ -1169,11 +1166,9 @@ static int wm_recover_last_session_exec(bContext *C, wmOperator *op)
BLI_make_file_string("/", filename, btempdir, "quit.blend");
WM_read_file(C, filename, op->reports);
- /* restore */
- G.save_over = save_over;
- BLI_strncpy(G.sce, scestr, sizeof(G.sce));
+ G.fileflags &= ~G_FILE_RECOVER;
- return 0;
+ return OPERATOR_FINISHED;
}
static void WM_OT_recover_last_session(wmOperatorType *ot)
@@ -1186,6 +1181,52 @@ static void WM_OT_recover_last_session(wmOperatorType *ot)
ot->poll= WM_operator_winactive;
}
+/* *************** recover auto save **************** */
+
+static int wm_recover_auto_save_exec(bContext *C, wmOperator *op)
+{
+ char path[FILE_MAX];
+
+ RNA_string_get(op->ptr, "path", path);
+
+ G.fileflags |= G_FILE_RECOVER;
+
+ // XXX wm in context is not set correctly after WM_read_file -> crash
+ // do it before for now, but is this correct with multiple windows?
+ WM_event_add_notifier(C, NC_WINDOW, NULL);
+
+ /* load file */
+ WM_read_file(C, path, op->reports);
+
+ G.fileflags &= ~G_FILE_RECOVER;
+
+ return OPERATOR_FINISHED;
+}
+
+static int wm_recover_auto_save_invoke(bContext *C, wmOperator *op, wmEvent *event)
+{
+ char filename[FILE_MAX];
+
+ wm_autosave_location(filename);
+ RNA_string_set(op->ptr, "path", filename);
+ WM_event_add_fileselect(C, op);
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+static void WM_OT_recover_auto_save(wmOperatorType *ot)
+{
+ ot->name= "Recover Auto Save";
+ ot->idname= "WM_OT_recover_auto_save";
+ ot->description="Open an automatically saved file to recover it.";
+
+ ot->exec= wm_recover_auto_save_exec;
+ ot->invoke= wm_recover_auto_save_invoke;
+ ot->poll= WM_operator_winactive;
+
+ WM_operator_properties_filesel(ot, BLENDERFILE, FILE_BLENDER);
+}
+
/* *************** save file as **************** */
static void untitled(char *name)
@@ -1229,10 +1270,9 @@ static int wm_save_as_mainfile_invoke(bContext *C, wmOperator *op, wmEvent *even
static int wm_save_as_mainfile_exec(bContext *C, wmOperator *op)
{
char path[FILE_MAX];
- int compress;
+ int fileflags;
save_set_compress(op);
- compress= RNA_boolean_get(op->ptr, "compress");
if(RNA_property_is_set(op->ptr, "path"))
RNA_string_get(op->ptr, "path", path);
@@ -1241,7 +1281,15 @@ static int wm_save_as_mainfile_exec(bContext *C, wmOperator *op)
untitled(path);
}
- WM_write_file(C, path, compress, op->reports);
+ fileflags= G.fileflags;
+
+ /* set compression flag */
+ if(RNA_boolean_get(op->ptr, "compress"))
+ fileflags |= G_FILE_COMPRESS;
+ else
+ fileflags &= ~G_FILE_COMPRESS;
+
+ WM_write_file(C, path, fileflags, op->reports);
WM_event_add_notifier(C, NC_WM|ND_FILESAVE, NULL);
@@ -2173,7 +2221,7 @@ void wm_operatortype_init(void)
WM_operatortype_append(WM_OT_open_mainfile);
WM_operatortype_append(WM_OT_link_append);
WM_operatortype_append(WM_OT_recover_last_session);
- WM_operatortype_append(WM_OT_jobs_timer);
+ WM_operatortype_append(WM_OT_recover_auto_save);
WM_operatortype_append(WM_OT_save_as_mainfile);
WM_operatortype_append(WM_OT_save_mainfile);
WM_operatortype_append(WM_OT_redraw_timer);
@@ -2188,9 +2236,6 @@ void wm_window_keymap(wmKeyConfig *keyconf)
wmKeyMap *keymap= WM_keymap_find(keyconf, "Window", 0, 0);
wmKeyMapItem *km;
- /* items to make WM work */
- WM_keymap_verify_item(keymap, "WM_OT_jobs_timer", TIMERJOBS, KM_ANY, KM_ANY, 0);
-
/* note, this doesn't replace existing keymap items */
WM_keymap_verify_item(keymap, "WM_OT_window_duplicate", WKEY, KM_PRESS, KM_CTRL|KM_ALT, 0);
#ifdef __APPLE__
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index f7116a2bd1f..70d40df4532 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -130,37 +130,39 @@ static void wm_ghostwindow_destroy(wmWindow *win)
/* including window itself, C can be NULL.
ED_screen_exit should have been called */
-void wm_window_free(bContext *C, wmWindow *win)
+void wm_window_free(bContext *C, wmWindowManager *wm, wmWindow *win)
{
wmTimer *wt, *wtnext;
/* update context */
if(C) {
- wmWindowManager *wm= CTX_wm_manager(C);
-
- if(wm->windrawable==win)
- wm->windrawable= NULL;
- if(wm->winactive==win)
- wm->winactive= NULL;
- if(CTX_wm_window(C)==win)
- CTX_wm_window_set(C, NULL);
-
WM_event_remove_handlers(C, &win->handlers);
WM_event_remove_handlers(C, &win->modalhandlers);
- /* end running jobs, a job end also removes its timer */
- for(wt= win->timers.first; wt; wt= wtnext) {
- wtnext= wt->next;
- if(wt->event_type==TIMERJOBS)
- wm_jobs_timer_ended(wm, wt);
- }
+ if(CTX_wm_window(C)==win)
+ CTX_wm_window_set(C, NULL);
}
-
- if(win->eventstate) MEM_freeN(win->eventstate);
+
+ if(wm->windrawable==win)
+ wm->windrawable= NULL;
+ if(wm->winactive==win)
+ wm->winactive= NULL;
+
+ /* end running jobs, a job end also removes its timer */
+ for(wt= wm->timers.first; wt; wt= wtnext) {
+ wtnext= wt->next;
+ if(wt->win==win && wt->event_type==TIMERJOBS)
+ wm_jobs_timer_ended(wm, wt);
+ }
/* timer removing, need to call this api function */
- while((wt= win->timers.first))
- WM_event_remove_window_timer(win, wt);
+ for(wt= wm->timers.first; wt; wt=wtnext) {
+ wtnext= wt->next;
+ if(wt->win==win)
+ WM_event_remove_timer(wm, win, wt);
+ }
+
+ if(win->eventstate) MEM_freeN(win->eventstate);
wm_event_free_all(win);
wm_subwindows_free(win);
@@ -223,14 +225,13 @@ wmWindow *wm_window_copy(bContext *C, wmWindow *winorig)
}
/* this is event from ghost, or exit-blender op */
-void wm_window_close(bContext *C, wmWindow *win)
+void wm_window_close(bContext *C, wmWindowManager *wm, wmWindow *win)
{
- wmWindowManager *wm= CTX_wm_manager(C);
BLI_remlink(&wm->windows, win);
wm_draw_window_clear(win);
ED_screen_exit(C, win, win->screen);
- wm_window_free(C, win);
+ wm_window_free(C, wm, win);
/* check remaining windows */
if(wm->windows.first) {
@@ -544,6 +545,7 @@ void wm_window_make_drawable(bContext *C, wmWindow *win)
static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr private)
{
bContext *C= private;
+ wmWindowManager *wm= CTX_wm_manager(C);
GHOST_TEventType type= GHOST_GetEventType(evt);
if (type == GHOST_kEventQuit) {
@@ -576,7 +578,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr private)
GHOST_TEventKeyData kdata;
int cx, cy, wx, wy;
- CTX_wm_manager(C)->winactive= win; /* no context change! c->wm->windrawable is drawable, or for area queues */
+ wm->winactive= win; /* no context change! c->wm->windrawable is drawable, or for area queues */
win->active= 1;
// window_handle(win, INPUTCHANGE, win->active);
@@ -619,7 +621,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr private)
break;
}
case GHOST_kEventWindowClose: {
- wm_window_close(C, win);
+ wm_window_close(C, wm, win);
break;
}
case GHOST_kEventWindowUpdate: {
@@ -719,22 +721,29 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr private)
static int wm_window_timer(const bContext *C)
{
wmWindowManager *wm= CTX_wm_manager(C);
+ wmTimer *wt, *wtnext;
wmWindow *win;
double time= PIL_check_seconds_timer();
int retval= 0;
- for(win= wm->windows.first; win; win= win->next) {
- wmTimer *wt;
- for(wt= win->timers.first; wt; wt= wt->next) {
- if(wt->sleep==0) {
- if(time > wt->ntime) {
+ for(wt= wm->timers.first; wt; wt= wtnext) {
+ wtnext= wt->next; /* in case timer gets removed */
+ win= wt->win;
+
+ if(wt->sleep==0) {
+ if(time > wt->ntime) {
+ wt->delta= time - wt->ltime;
+ wt->duration += wt->delta;
+ wt->ltime= time;
+ wt->ntime= wt->stime + wt->timestep*ceil(wt->duration/wt->timestep);
+
+ if(wt->event_type == TIMERJOBS)
+ wm_jobs_timer(C, wm, wt);
+ else if(wt->event_type == TIMERAUTOSAVE)
+ wm_autosave_timer(C, wm, wt);
+ else if(win) {
wmEvent event= *(win->eventstate);
- wt->delta= time - wt->ltime;
- wt->duration += wt->delta;
- wt->ltime= time;
- wt->ntime= wt->stime + wt->timestep*ceil(wt->duration/wt->timestep);
-
event.type= wt->event_type;
event.custom= EVT_DATA_TIMER;
event.customdata= wt;
@@ -810,19 +819,19 @@ void wm_ghost_exit(void)
/* **************** timer ********************** */
/* to (de)activate running timers temporary */
-void WM_event_window_timer_sleep(wmWindow *win, wmTimer *timer, int dosleep)
+void WM_event_timer_sleep(wmWindowManager *wm, wmWindow *win, wmTimer *timer, int dosleep)
{
wmTimer *wt;
- for(wt= win->timers.first; wt; wt= wt->next)
+ for(wt= wm->timers.first; wt; wt= wt->next)
if(wt==timer)
break;
- if(wt) {
+
+ if(wt)
wt->sleep= dosleep;
- }
}
-wmTimer *WM_event_add_window_timer(wmWindow *win, int event_type, double timestep)
+wmTimer *WM_event_add_timer(wmWindowManager *wm, wmWindow *win, int event_type, double timestep)
{
wmTimer *wt= MEM_callocN(sizeof(wmTimer), "window timer");
@@ -831,23 +840,24 @@ wmTimer *WM_event_add_window_timer(wmWindow *win, int event_type, double timeste
wt->ntime= wt->ltime + timestep;
wt->stime= wt->ltime;
wt->timestep= timestep;
+ wt->win= win;
- BLI_addtail(&win->timers, wt);
+ BLI_addtail(&wm->timers, wt);
return wt;
}
-void WM_event_remove_window_timer(wmWindow *win, wmTimer *timer)
+void WM_event_remove_timer(wmWindowManager *wm, wmWindow *win, wmTimer *timer)
{
wmTimer *wt;
/* extra security check */
- for(wt= win->timers.first; wt; wt= wt->next)
+ for(wt= wm->timers.first; wt; wt= wt->next)
if(wt==timer)
break;
if(wt) {
- BLI_remlink(&win->timers, wt);
+ BLI_remlink(&wm->timers, wt);
if(wt->customdata)
MEM_freeN(wt->customdata);
MEM_freeN(wt);
diff --git a/source/blender/windowmanager/wm.h b/source/blender/windowmanager/wm.h
index 832558b961f..609b6142640 100644
--- a/source/blender/windowmanager/wm.h
+++ b/source/blender/windowmanager/wm.h
@@ -29,6 +29,7 @@
#define WM_H
struct wmWindow;
+struct ReportList;
typedef struct wmPaintCursor {
struct wmPaintCursor *next, *prev;
@@ -64,9 +65,16 @@ void wm_gesture_draw(struct wmWindow *win);
int wm_gesture_evaluate(bContext *C, wmGesture *gesture);
void wm_gesture_tag_redraw(bContext *C);
-/* wm_jobs.h */
-void WM_OT_jobs_timer(struct wmOperatorType *ot);
+/* wm_jobs.c */
+void wm_jobs_timer(const bContext *C, wmWindowManager *wm, wmTimer *wt);
void wm_jobs_timer_ended(wmWindowManager *wm, wmTimer *wt);
+/* wm_files.c */
+void wm_autosave_timer(const bContext *C, wmWindowManager *wm, wmTimer *wt);
+void wm_autosave_timer_ended(wmWindowManager *wm);
+void wm_autosave_delete(void);
+void wm_autosave_read(bContext *C, struct ReportList *reports);
+void wm_autosave_location(char *filename);
+
#endif /* WM_H */
diff --git a/source/blender/windowmanager/wm_event_types.h b/source/blender/windowmanager/wm_event_types.h
index b33c4bd14e8..c7588795a15 100644
--- a/source/blender/windowmanager/wm_event_types.h
+++ b/source/blender/windowmanager/wm_event_types.h
@@ -75,6 +75,7 @@
#define TIMER1 0x0112 /* timer event, slot for internal use */
#define TIMER2 0x0113 /* timer event, slot for internal use */
#define TIMERJOBS 0x0114 /* timer event, internal use */
+#define TIMERAUTOSAVE 0x0115 /* timer event, internal use */
/* standard keyboard */
#define AKEY 'a'
@@ -203,7 +204,7 @@
#define ISMOUSE(event) (event >= LEFTMOUSE && event <= WHEELOUTMOUSE)
/* test wether the event is timer event */
-#define ISTIMER(event) (event >= TIMER && event <= TIMERJOBS)
+#define ISTIMER(event) (event >= TIMER && event <= TIMERAUTOSAVE)
/* test wether the event is tweak event */
#define ISTWEAK(event) (event >= EVT_TWEAK_L && event <= EVT_GESTURE)
diff --git a/source/blender/windowmanager/wm_window.h b/source/blender/windowmanager/wm_window.h
index 44c31e7cb69..f0a2c0ec9a9 100644
--- a/source/blender/windowmanager/wm_window.h
+++ b/source/blender/windowmanager/wm_window.h
@@ -36,8 +36,8 @@ void wm_ghost_init (bContext *C);
void wm_ghost_exit(void);
wmWindow *wm_window_new (bContext *C);
-void wm_window_free (bContext *C, wmWindow *win);
-void wm_window_close (bContext *C, wmWindow *win);
+void wm_window_free (bContext *C, wmWindowManager *wm, wmWindow *win);
+void wm_window_close (bContext *C, wmWindowManager *wm, wmWindow *win);
void wm_window_title (wmWindowManager *wm, wmWindow *win);
void wm_window_add_ghostwindows (wmWindowManager *wm);