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:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2009-10-20 17:58:53 +0400
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2009-10-20 17:58:53 +0400
commitcb8f7fd385251d22ab97a48466e33ce0e42d5e4d (patch)
treefac9b9510d58bc04ff94dbc658621c3de31ed466 /source/blender/windowmanager
parentb8eec2b8fe123b118aef925ce2f786842764413d (diff)
Auto Save
Auto save is now working again in 2.5. It will also remember now what the location of the original file was when recovering it, so that library links still work and saving the restored file does not save to the temp directory. There is also a new Recover Auto Save operator which will open the filebrowser in the temp directory and show the auto saved .blends. Implemenation Notes: * Timer storage was moved from window to windowmanager, so we can have windowmanager level timers too now, doesn't make sense to have autosave timer attached to a particular window. * FileGlobal now has a filename field storing where the file was saved. Note that this is only used when loading a file through the recover operators, regular file read doesn't use it, so copying the quit.blend manually over the original file will still work as expected. * Jobs timer no longer uses operator now, this seems more like an internal thing, changing keymaps should not make it possible to break the jobs manager. * Autosave is postponed by 10 seconds when a modal operator is running, e.g. transform or file browsing. * Moved setting G.sce in setup_app_data before depsgraph updates, these can use the filename for pointcaches.
Diffstat (limited to 'source/blender/windowmanager')
-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
13 files changed, 251 insertions, 173 deletions
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);