diff options
Diffstat (limited to 'source/blender/windowmanager/intern')
-rw-r--r-- | source/blender/windowmanager/intern/wm_draw.c | 83 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_event_system.c | 19 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_files.c | 116 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_init_exit.c | 29 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_operators.c | 188 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_subwindow.c | 14 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_window.c | 226 |
7 files changed, 488 insertions, 187 deletions
diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c index a92ed65392c..11cf1088280 100644 --- a/source/blender/windowmanager/intern/wm_draw.c +++ b/source/blender/windowmanager/intern/wm_draw.c @@ -49,6 +49,7 @@ #include "BKE_context.h" #include "BKE_global.h" +#include "BKE_screen.h" #include "GHOST_C-api.h" @@ -431,22 +432,22 @@ static int wm_triple_gen_textures(wmWindow *win, wmDrawTriple *triple) triple->target = GL_TEXTURE_RECTANGLE_ARB; triple->nx = 1; triple->ny = 1; - triple->x[0] = win->sizex; - triple->y[0] = win->sizey; + triple->x[0] = WM_window_pixels_x(win); + triple->y[0] = WM_window_pixels_y(win); } else if (GPU_non_power_of_two_support()) { triple->target = GL_TEXTURE_2D; triple->nx = 1; triple->ny = 1; - triple->x[0] = win->sizex; - triple->y[0] = win->sizey; + triple->x[0] = WM_window_pixels_x(win); + triple->y[0] = WM_window_pixels_y(win); } else { triple->target = GL_TEXTURE_2D; triple->nx = 0; triple->ny = 0; - split_width(win->sizex, MAX_N_TEX, triple->x, &triple->nx); - split_width(win->sizey, MAX_N_TEX, triple->y, &triple->ny); + split_width(WM_window_pixels_x(win), MAX_N_TEX, triple->x, &triple->nx); + split_width(WM_window_pixels_y(win), MAX_N_TEX, triple->y, &triple->ny); } /* generate texture names */ @@ -491,7 +492,7 @@ static int wm_triple_gen_textures(wmWindow *win, wmDrawTriple *triple) return 1; } -static void wm_triple_draw_textures(wmWindow *win, wmDrawTriple *triple) +static void wm_triple_draw_textures(wmWindow *win, wmDrawTriple *triple, float alpha) { float halfx, halfy, ratiox, ratioy; int x, y, sizex, sizey, offx, offy; @@ -500,8 +501,8 @@ static void wm_triple_draw_textures(wmWindow *win, wmDrawTriple *triple) for (y = 0, offy = 0; y < triple->ny; offy += triple->y[y], y++) { for (x = 0, offx = 0; x < triple->nx; offx += triple->x[x], x++) { - sizex = (x == triple->nx - 1) ? win->sizex - offx : triple->x[x]; - sizey = (y == triple->ny - 1) ? win->sizey - offy : triple->y[y]; + sizex = (x == triple->nx - 1) ? WM_window_pixels_x(win) - offx : triple->x[x]; + sizey = (y == triple->ny - 1) ? WM_window_pixels_y(win) - offy : triple->y[y]; /* wmOrtho for the screen has this same offset */ ratiox = sizex; @@ -519,7 +520,7 @@ static void wm_triple_draw_textures(wmWindow *win, wmDrawTriple *triple) glBindTexture(triple->target, triple->bind[x + y * triple->nx]); - glColor3f(1.0f, 1.0f, 1.0f); + glColor4f(1.0f, 1.0f, 1.0f, alpha); glBegin(GL_QUADS); glTexCoord2f(halfx, halfy); glVertex2f(offx, offy); @@ -546,8 +547,8 @@ static void wm_triple_copy_textures(wmWindow *win, wmDrawTriple *triple) for (y = 0, offy = 0; y < triple->ny; offy += triple->y[y], y++) { for (x = 0, offx = 0; x < triple->nx; offx += triple->x[x], x++) { - sizex = (x == triple->nx - 1) ? win->sizex - offx : triple->x[x]; - sizey = (y == triple->ny - 1) ? win->sizey - offy : triple->y[y]; + sizex = (x == triple->nx - 1) ? WM_window_pixels_x(win) - offx : triple->x[x]; + sizey = (y == triple->ny - 1) ? WM_window_pixels_y(win) - offy : triple->y[y]; glBindTexture(triple->target, triple->bind[x + y * triple->nx]); glCopyTexSubImage2D(triple->target, 0, 0, 0, offx, offy, sizex, sizey); @@ -557,6 +558,20 @@ static void wm_triple_copy_textures(wmWindow *win, wmDrawTriple *triple) glBindTexture(triple->target, 0); } +static void wm_draw_region_blend(wmWindow *win, ARegion *ar) +{ + float fac = ED_region_blend_factor(ar); + + /* region blend always is 1, except when blend timer is running */ + if (fac < 1.0f) { + wmSubWindowScissorSet(win, win->screen->mainwin, &ar->winrct); + + glEnable(GL_BLEND); + wm_triple_draw_textures(win, win->drawdata, 1.0f - fac); + glDisable(GL_BLEND); + } +} + static void wm_method_draw_triple(bContext *C, wmWindow *win) { wmWindowManager *wm = CTX_wm_manager(C); @@ -572,7 +587,7 @@ static void wm_method_draw_triple(bContext *C, wmWindow *win) wmSubWindowSet(win, screen->mainwin); - wm_triple_draw_textures(win, win->drawdata); + wm_triple_draw_textures(win, win->drawdata, 1.0f); } else { win->drawdata = MEM_callocN(sizeof(wmDrawTriple), "wmDrawTriple"); @@ -591,11 +606,13 @@ static void wm_method_draw_triple(bContext *C, wmWindow *win) for (ar = sa->regionbase.first; ar; ar = ar->next) { if (ar->swinid && ar->do_draw) { - CTX_wm_region_set(C, ar); - ED_region_do_draw(C, ar); - ED_area_overdraw_flush(sa, ar); - CTX_wm_region_set(C, NULL); - copytex = 1; + if (ar->overlap == 0) { + CTX_wm_region_set(C, ar); + ED_region_do_draw(C, ar); + ED_area_overdraw_flush(sa, ar); + CTX_wm_region_set(C, NULL); + copytex = 1; + } } } @@ -610,10 +627,28 @@ static void wm_method_draw_triple(bContext *C, wmWindow *win) wm_triple_copy_textures(win, triple); } + /* 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); + ED_area_overdraw_flush(sa, 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 overlapping regions */ + /* draw floating regions (menus) */ for (ar = screen->regionbase.first; ar; ar = ar->next) { if (ar->swinid) { CTX_wm_menu_set(C, ar); @@ -652,9 +687,9 @@ static void wm_method_draw_triple(bContext *C, wmWindow *win) if (wm->drags.first) { wm_drags_draw(C, win, NULL); } - } + /****************** main update call **********************/ /* quick test to prevent changing window drawable */ @@ -734,6 +769,14 @@ static int wm_automatic_draw_method(wmWindow *win) return win->drawmethod; } +int WM_is_draw_triple(wmWindow *win) +{ + /* function can get called before this variable is set in drawing code below */ + if (win->drawmethod != U.wmdrawmethod) + win->drawmethod = U.wmdrawmethod; + return USER_DRAW_TRIPLE == wm_automatic_draw_method(win); +} + void wm_tag_redraw_overlay(wmWindow *win, ARegion *ar) { /* for draw triple gestures, paint cursors don't need region redraw */ diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index c0e3b19c716..d8dd0ac04c4 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -1640,9 +1640,9 @@ static int wm_action_not_handled(int action) static int wm_handlers_do_intern(bContext *C, wmEvent *event, ListBase *handlers) { #ifndef NDEBUG - const int do_debug_handler = (G.debug & G_DEBUG_HANDLERS) + const int do_debug_handler = (G.debug & G_DEBUG_HANDLERS) && /* comment this out to flood the console! (if you really want to test) */ - && !ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE) + !ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE) ; #endif wmWindowManager *wm = CTX_wm_manager(C); @@ -2738,11 +2738,9 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U { GHOST_TEventCursorData *cd = customdata; wmEvent *lastevent = win->queue.last; - int cx, cy; - GHOST_ScreenToClient(win->ghostwin, cd->x, cd->y, &cx, &cy); - evt->x = cx; - evt->y = (win->sizey - 1) - cy; + evt->x = cd->x; + evt->y = cd->y; event.x = evt->x; event.y = evt->y; @@ -2790,13 +2788,8 @@ void wm_event_add_ghostevent(wmWindowManager *wm, wmWindow *win, int type, int U break; } - { - int cx, cy; - GHOST_ScreenToClient(win->ghostwin, pd->x, pd->y, &cx, &cy); - event.x = evt->x = cx; - event.y = evt->y = (win->sizey - 1) - cy; - } - + event.x = evt->x = pd->x; + event.y = evt->y = pd->y; event.val = 0; /* Use prevx/prevy so we can calculate the delta later */ diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 1c168bc5ac5..20b205a642a 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -285,7 +285,9 @@ static void wm_window_match_do(bContext *C, ListBase *oldwmlist) /* in case UserDef was read, we re-initialize all, and do versioning */ static void wm_init_userdef(bContext *C) { + /* versioning is here */ UI_init_userdef(); + MEM_CacheLimiter_set_maximum(((size_t)U.memcachelimit) * 1024 * 1024); sound_init(CTX_data_main(C)); @@ -302,6 +304,13 @@ static void wm_init_userdef(bContext *C) /* update tempdir from user preferences */ BLI_init_temporary_dir(U.tempdir); + + /* displays with larger native pixels, like Macbook. Used to scale dpi with */ + if (G.background == FALSE) + U.pixelsize = GHOST_GetNativePixelSize(); + if (U.pixelsize == 0) U.pixelsize = 1; + + BKE_userdef_state(); } @@ -390,6 +399,8 @@ void WM_file_read(bContext *C, const char *filepath, ReportList *reports) /* also exit screens and editors */ wm_window_match_init(C, &wmbase); + /* confusing this global... */ + G.relbase_valid = 1; retval = BKE_read_file(C, filepath, reports); G.save_over = 1; @@ -410,7 +421,6 @@ void WM_file_read(bContext *C, const char *filepath, ReportList *reports) } if (retval != BKE_READ_FILE_FAIL) { - G.relbase_valid = 1; if (do_history) { write_history(); } @@ -488,11 +498,12 @@ void WM_file_read(bContext *C, const char *filepath, ReportList *reports) /* called on startup, (context entirely filled with NULLs) */ /* or called for 'New File' */ -/* op can be NULL */ -int WM_homefile_read(bContext *C, ReportList *UNUSED(reports), short from_memory) +/* both startup.blend and userpref.blend are checked */ +int wm_homefile_read(bContext *C, ReportList *UNUSED(reports), short from_memory) { ListBase wmbase; - char tstr[FILE_MAX]; + char startstr[FILE_MAX]; + char prefstr[FILE_MAX]; int success = 0; BLI_callback_exec(CTX_data_main(C), NULL, BLI_CB_EVT_LOAD_PRE); @@ -501,10 +512,12 @@ int WM_homefile_read(bContext *C, ReportList *UNUSED(reports), short from_memory if (!from_memory) { char *cfgdir = BLI_get_folder(BLENDER_USER_CONFIG, NULL); if (cfgdir) { - BLI_make_file_string(G.main->name, tstr, cfgdir, BLENDER_STARTUP_FILE); + BLI_make_file_string(G.main->name, startstr, cfgdir, BLENDER_STARTUP_FILE); + BLI_make_file_string(G.main->name, prefstr, cfgdir, BLENDER_USERPREF_FILE); } else { - tstr[0] = '\0'; + startstr[0] = '\0'; + prefstr[0] = '\0'; from_memory = 1; } } @@ -515,14 +528,16 @@ int WM_homefile_read(bContext *C, ReportList *UNUSED(reports), short from_memory /* put aside screens to match with persistent windows later */ wm_window_match_init(C, &wmbase); - if (!from_memory && BLI_exists(tstr)) { - success = (BKE_read_file(C, tstr, NULL) != BKE_READ_FILE_FAIL); + if (!from_memory && BLI_exists(startstr)) { + success = (BKE_read_file(C, startstr, NULL) != BKE_READ_FILE_FAIL); - if (U.themes.first == NULL) { - printf("\nError: No valid "STRINGIFY (BLENDER_STARTUP_FILE)", fall back to built-in default.\n\n"); - success = 0; - } } + + if (U.themes.first == NULL) { + printf("\nError: No valid "STRINGIFY (BLENDER_STARTUP_FILE)", fall back to built-in default.\n\n"); + success = 0; + } + if (success == 0) { success = BKE_read_file_from_memory(C, datatoc_startup_blend, datatoc_startup_blend_size, NULL); if (wmbase.first == NULL) wm_clear_default_size(C); @@ -534,6 +549,12 @@ int WM_homefile_read(bContext *C, ReportList *UNUSED(reports), short from_memory #endif } + /* check new prefs only after startup.blend was finished */ + if (!from_memory && BLI_exists(prefstr)) { + int done = BKE_read_file_userdef(prefstr, NULL); + if (done) printf("read new prefs: %s\n", prefstr); + } + /* prevent buggy files that had G_FILE_RELATIVE_REMAP written out by mistake. Screws up autosaves otherwise * can remove this eventually, only in a 2.53 and older, now its not written */ G.fileflags &= ~G_FILE_RELATIVE_REMAP; @@ -587,13 +608,13 @@ int WM_homefile_read(bContext *C, ReportList *UNUSED(reports), short from_memory return TRUE; } -int WM_homefile_read_exec(bContext *C, wmOperator *op) +int wm_homefile_read_exec(bContext *C, wmOperator *op) { int from_memory = strcmp(op->type->idname, "WM_OT_read_factory_settings") == 0; - return WM_homefile_read(C, op->reports, from_memory) ? OPERATOR_FINISHED : OPERATOR_CANCELLED; + return wm_homefile_read(C, op->reports, from_memory) ? OPERATOR_FINISHED : OPERATOR_CANCELLED; } -void WM_read_history(void) +void wm_read_history(void) { char name[FILE_MAX]; LinkNode *l, *lines; @@ -633,6 +654,10 @@ static void write_history(void) FILE *fp; int i; + /* no write history for recovered startup files */ + if (G.main->name[0] == 0) + return; + /* will be NULL in background mode */ user_config_dir = BLI_get_folder_create(BLENDER_USER_CONFIG, NULL); if (!user_config_dir) @@ -711,7 +736,7 @@ static ImBuf *blend_file_thumb(Scene *scene, bScreen *screen, int **thumb_pt) if (scene->camera) { ibuf = ED_view3d_draw_offscreen_imbuf_simple(scene, scene->camera, BLEN_THUMB_SIZE * 2, BLEN_THUMB_SIZE * 2, - IB_rect, OB_SOLID, FALSE, FALSE, err_out); + IB_rect, OB_SOLID, FALSE, FALSE, FALSE, err_out); } else { ibuf = ED_view3d_draw_offscreen_imbuf(scene, v3d, ar, BLEN_THUMB_SIZE * 2, BLEN_THUMB_SIZE * 2, @@ -765,12 +790,11 @@ int write_crash_blend(void) } } -int WM_file_write(bContext *C, const char *target, int fileflags, ReportList *reports) +int wm_file_write(bContext *C, const char *target, int fileflags, ReportList *reports) { Library *li; int len; char filepath[FILE_MAX]; - int *thumb = NULL; ImBuf *ibuf_thumb = NULL; @@ -820,6 +844,14 @@ int WM_file_write(bContext *C, const char *target, int fileflags, ReportList *re fileflags |= G_FILE_HISTORY; /* write file history */ + /* first time saving */ + /* XXX temp solution to solve bug, real fix coming (ton) */ + if (G.main->name[0] == 0) + BLI_strncpy(G.main->name, filepath, sizeof(G.main->name)); + + /* XXX temp solution to solve bug, real fix coming (ton) */ + G.main->recovered = 0; + if (BLO_write_file(CTX_data_main(C), filepath, fileflags, reports, thumb)) { if (!(fileflags & G_FILE_SAVE_COPY)) { G.relbase_valid = 1; @@ -864,7 +896,7 @@ int WM_file_write(bContext *C, const char *target, int fileflags, ReportList *re } /* operator entry */ -int WM_homefile_write_exec(bContext *C, wmOperator *op) +int wm_homefile_write_exec(bContext *C, wmOperator *op) { wmWindowManager *wm = CTX_wm_manager(C); wmWindow *win = CTX_wm_window(C); @@ -884,7 +916,7 @@ int WM_homefile_write_exec(bContext *C, wmOperator *op) /* force save as regular blend file */ fileflags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_AUTOPLAY | G_FILE_LOCK | G_FILE_SIGN | G_FILE_HISTORY); - if (BLO_write_file(CTX_data_main(C), filepath, fileflags, op->reports, NULL) == 0) { + if (BLO_write_file(CTX_data_main(C), filepath, fileflags | G_FILE_USERPREFS, op->reports, NULL) == 0) { printf("fail\n"); return OPERATOR_CANCELLED; } @@ -896,6 +928,28 @@ int WM_homefile_write_exec(bContext *C, wmOperator *op) return OPERATOR_FINISHED; } +/* Only save the prefs block. operator entry */ +int wm_userpref_write_exec(bContext *C, wmOperator *op) +{ + wmWindowManager *wm = CTX_wm_manager(C); + char filepath[FILE_MAX]; + + /* update keymaps in user preferences */ + WM_keyconfig_update(wm); + + BLI_make_file_string("/", filepath, BLI_get_folder_create(BLENDER_USER_CONFIG, NULL), BLENDER_USERPREF_FILE); + printf("trying to save userpref at %s ", filepath); + + if (BKE_write_file_userdef(filepath, op->reports) == 0) { + printf("fail\n"); + return OPERATOR_CANCELLED; + } + + printf("ok\n"); + + return OPERATOR_FINISHED; +} + /************************ autosave ****************************/ void wm_autosave_location(char *filepath) @@ -939,7 +993,7 @@ void wm_autosave_timer(const bContext *C, wmWindowManager *wm, wmTimer *UNUSED(w wmWindow *win; wmEventHandler *handler; char filepath[FILE_MAX]; - int fileflags; + Scene *scene = CTX_data_scene(C); WM_event_remove_timer(wm, NULL, wm->autosavetimer); @@ -963,12 +1017,17 @@ void wm_autosave_timer(const bContext *C, wmWindowManager *wm, wmTimer *UNUSED(w wm_autosave_location(filepath); - /* force save as regular blend file */ - fileflags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_AUTOPLAY | G_FILE_LOCK | G_FILE_SIGN | G_FILE_HISTORY); - - /* no error reporting to console */ - BLO_write_file(CTX_data_main(C), filepath, fileflags, NULL, NULL); + if (U.uiflag & USER_GLOBALUNDO) { + /* fast save of last undobuffer, now with UI */ + BKE_undo_save_file(filepath); + } + else { + /* save as regular blend file */ + int fileflags = G.fileflags & ~(G_FILE_COMPRESS | G_FILE_AUTOPLAY | G_FILE_LOCK | G_FILE_SIGN | G_FILE_HISTORY); + /* no error reporting to console */ + BLO_write_file(CTX_data_main(C), filepath, fileflags, NULL, NULL); + } /* 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); } @@ -989,7 +1048,7 @@ void wm_autosave_delete(void) if (BLI_exists(filename)) { char str[FILE_MAX]; - BLI_make_file_string("/", str, BLI_temporary_dir(), "quit.blend"); + BLI_make_file_string("/", str, BLI_temporary_dir(), BLENDER_QUIT_FILE); /* if global undo; remove tempsave, otherwise rename */ if (U.uiflag & USER_GLOBALUNDO) BLI_delete(filename, 0, 0); @@ -1005,3 +1064,6 @@ void wm_autosave_read(bContext *C, ReportList *reports) WM_file_read(C, filename, reports); } + + + diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index c9f0bbffc63..3cffa143ebc 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -48,6 +48,7 @@ #include "DNA_windowmanager_types.h" #include "BLI_listbase.h" +#include "BLI_path_util.h" #include "BLI_string.h" #include "BLI_utildefines.h" @@ -128,6 +129,7 @@ int wm_start_with_console = 0; /* used in creator.c */ /* only called once, for startup */ void WM_init(bContext *C, int argc, const char **argv) { + if (!G.background) { wm_ghost_init(C); /* note: it assigns C to ghost! */ wm_init_cursor_data(); @@ -149,8 +151,8 @@ void WM_init(bContext *C, int argc, const char **argv) BLF_lang_init(); /* get the default database, plus a wm */ - WM_homefile_read(C, NULL, G.factory_startup); - + wm_homefile_read(C, NULL, G.factory_startup); + BLF_lang_set(NULL); /* note: there is a bug where python needs initializing before loading the @@ -158,7 +160,7 @@ void WM_init(bContext *C, int argc, const char **argv) * initializing space types and other internal data. * * However cant redo this at the moment. Solution is to load python - * before WM_homefile_read() or make py-drivers check if python is running. + * before wm_homefile_read() or make py-drivers check if python is running. * Will try fix when the crash can be repeated. - campbell. */ #ifdef WITH_PYTHON @@ -195,7 +197,7 @@ void WM_init(bContext *C, int argc, const char **argv) ED_preview_init_dbase(); - WM_read_history(); + wm_read_history(); /* allow a path of "", this is what happens when making a new file */ #if 0 @@ -211,6 +213,10 @@ void WM_init(bContext *C, int argc, const char **argv) COM_linker_hack = COM_execute; } #endif + + /* load last session, uses regular file reading so it has to be in end (after init py etc) */ + if (U.uiflag2 & USER_KEEP_SESSION) + wm_recover_last_session(C, NULL); } void WM_init_splash(bContext *C) @@ -372,6 +378,18 @@ void WM_exit_ext(bContext *C, const short do_python) if (C && wm) { wmWindow *win; + if (!G.background) { + if ((U.uiflag2 & USER_KEEP_SESSION) || BKE_undo_valid(NULL)) { + /* save the undo state as quit.blend */ + char filename[FILE_MAX]; + + BLI_make_file_string("/", filename, BLI_temporary_dir(), BLENDER_QUIT_FILE); + + if (BKE_undo_save_file(filename)) + printf("Saved session recovery to '%s'\n", filename); + } + } + WM_jobs_kill_all(wm); for (win = wm->windows.first; win; win = win->next) { @@ -454,9 +472,6 @@ void WM_exit_ext(bContext *C, const short do_python) GPU_free_unused_buffers(); GPU_extensions_exit(); - if (!G.background) { - BKE_undo_save_quit(); /* saves quit.blend if global undo is on */ - } BKE_reset_undo(); ED_file_exit(); /* for fsmenu */ diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 8a0701b1063..cd3d5c97f99 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -103,6 +103,7 @@ #include "wm_draw.h" #include "wm_event_system.h" #include "wm_event_types.h" +#include "wm_files.h" #include "wm_subwindow.h" #include "wm_window.h" @@ -559,6 +560,106 @@ char *WM_operator_pystring(bContext *C, wmOperatorType *ot, PointerRNA *opptr, i return cstring; } +/* return NULL if no match is found */ +static char *wm_prop_pystring_from_context(bContext *C, PointerRNA *ptr, PropertyRNA *prop, int index) +{ + + /* loop over all context items and do 2 checks + * + * - see if the pointer is in the context. + * - see if the pointers ID is in the context. + */ + + ListBase lb = CTX_data_dir_get(C); + LinkData *link; + + const char *member_found = NULL; + const char *member_id = NULL; + + char *prop_str = NULL; + char *ret = NULL; + + + for (link = lb.first; link; link = link->next) { + const char *identifier = link->data; + PointerRNA ctx_ptr = CTX_data_pointer_get(C, identifier); + + if (ctx_ptr.type == NULL) { + continue; + } + + if (ptr->id.data == ctx_ptr.id.data) { + if ((ptr->data == ctx_ptr.data) && + (ptr->type == ctx_ptr.type)) + { + /* found! */ + member_found = identifier; + break; + } + else if (RNA_struct_is_ID(ctx_ptr.type)) { + /* we found a reference to this ID, + * so fallback to it if there is no direct reference */ + member_id = identifier; + } + } + } + + /* grr, CTX_data_dir_get skips scene */ + if ((member_id == NULL) && + (ptr->id.data != NULL) && + (GS(((ID *)ptr->id.data)->name) == ID_SCE) && + (CTX_data_scene(C) == ptr->id.data)) + { + member_id = "scene"; + } + + if (member_found) { + prop_str = RNA_path_property_py(ptr, prop, index); + if (prop_str) { + ret = BLI_sprintfN("bpy.context.%s.%s", member_found, prop_str); + MEM_freeN(prop_str); + } + } + else if (member_id) { + prop_str = RNA_path_struct_property_py(ptr, prop, index); + if (prop_str) { + ret = BLI_sprintfN("bpy.context.%s.%s", member_id, prop_str); + MEM_freeN(prop_str); + } + } + + BLI_freelistN(&lb); + + return ret; +} + +char *WM_prop_pystring_assign(bContext *C, PointerRNA *ptr, PropertyRNA *prop, int index) +{ + char *lhs, *rhs, *ret; + + lhs = C ? wm_prop_pystring_from_context(C, ptr, prop, index) : NULL; + + if (lhs == NULL) { + /* fallback to bpy.data.foo[id] if we dont find in the context */ + lhs = RNA_path_full_property_py(ptr, prop, index); + } + + if (!lhs) { + return NULL; + } + + rhs = RNA_property_as_string(C, ptr, prop, index); + if (!rhs) { + MEM_freeN(lhs); + return NULL; + } + + ret = BLI_sprintfN("%s = %s", lhs, rhs); + MEM_freeN(lhs); + MEM_freeN(rhs); + return ret; +} + void WM_operator_properties_create_ptr(PointerRNA *ptr, wmOperatorType *ot) { RNA_pointer_create(NULL, ot->srna, NULL, ptr); @@ -1078,7 +1179,7 @@ static uiBlock *wm_block_create_redo(bContext *C, ARegion *ar, void *arg_op) uiBlock *block; uiLayout *layout; uiStyle *style = UI_GetStyle(); - int width = 300; + int width = 15 * UI_UNIT_X; block = uiBeginBlock(C, ar, __func__, UI_EMBOSS); uiBlockClearFlag(block, UI_BLOCK_LOOP); @@ -1262,7 +1363,7 @@ static int wm_operator_props_popup_ex(bContext *C, wmOperator *op, const int do_ /* if we don't have global undo, we can't do undo push for automatic redo, * so we require manual OK clicking in this popup */ if (!(U.uiflag & USER_GLOBALUNDO)) - return WM_operator_props_dialog_popup(C, op, 300, UI_UNIT_Y); + return WM_operator_props_dialog_popup(C, op, 15 * UI_UNIT_X, UI_UNIT_Y); uiPupBlock(C, wm_block_create_redo, op); @@ -1429,7 +1530,7 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar int i; MenuType *mt = WM_menutype_find("USERPREF_MT_splash", TRUE); char url[96]; - char file [FILE_MAX]; + char file[FILE_MAX]; #ifndef WITH_HEADLESS extern char datatoc_splash_png[]; @@ -1452,9 +1553,9 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar "%d.%02d.%d", BLENDER_VERSION / 100, BLENDER_VERSION % 100, BLENDER_SUBVERSION); BLI_snprintf(revision_buf, sizeof(revision_buf), "r%s", build_rev); - BLF_size(style->widgetlabel.uifont_id, style->widgetlabel.points, U.dpi); - ver_width = (int)BLF_width(style->widgetlabel.uifont_id, version_buf) + 5; - rev_width = (int)BLF_width(style->widgetlabel.uifont_id, revision_buf) + 5; + BLF_size(style->widgetlabel.uifont_id, style->widgetlabel.points, U.pixelsize * U.dpi); + ver_width = (int)BLF_width(style->widgetlabel.uifont_id, version_buf) + 0.5f * U.widget_unit; + rev_width = (int)BLF_width(style->widgetlabel.uifont_id, revision_buf) + 0.5f * U.widget_unit; #endif /* WITH_BUILDINFO */ block = uiBeginBlock(C, ar, "_popup", UI_EMBOSS); @@ -1464,16 +1565,17 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar * ugly results and clipping the splash isn't useful anyway, just disable it [#32938] */ uiBlockSetFlag(block, UI_BLOCK_KEEP_OPEN | UI_BLOCK_NO_WIN_CLIP); - but = uiDefBut(block, BUT_IMAGE, 0, "", 0, 10, 501, 282, ibuf, 0.0, 0.0, 0, 0, ""); /* button owns the imbuf now */ + /* XXX splash scales with pixelsize, should become widget-units */ + but = uiDefBut(block, BUT_IMAGE, 0, "", 0, 0.5f * U.widget_unit, U.pixelsize * 501, U.pixelsize *282, ibuf, 0.0, 0.0, 0, 0, ""); /* button owns the imbuf now */ uiButSetFunc(but, wm_block_splash_close, block, NULL); uiBlockSetFunc(block, wm_block_splash_refreshmenu, block, NULL); #ifdef WITH_BUILDINFO - uiDefBut(block, LABEL, 0, version_buf, 494 - ver_width, 282 - 24, ver_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL); - uiDefBut(block, LABEL, 0, revision_buf, 494 - rev_width, 282 - 36, rev_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL); + uiDefBut(block, LABEL, 0, version_buf, U.pixelsize * 494 - ver_width, U.pixelsize * 258, ver_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL); + uiDefBut(block, LABEL, 0, revision_buf, U.pixelsize * 494 - rev_width, U.pixelsize * 246, rev_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL); #endif /* WITH_BUILDINFO */ - layout = uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 10, 2, 480, 110, style); + layout = uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 10, 2, U.pixelsize * 480, U.pixelsize * 110, style); uiBlockSetEmboss(block, UI_EMBOSS); /* show the splash menu (containing interaction presets), using python */ @@ -1675,12 +1777,23 @@ static void WM_OT_window_duplicate(wmOperatorType *ot) static void WM_OT_save_homefile(wmOperatorType *ot) { - ot->name = "Save User Settings"; + ot->name = "Save Startup File"; ot->idname = "WM_OT_save_homefile"; - ot->description = "Make the current file the default .blend file"; + ot->description = "Make the current file the default .blend file, includes preferences"; ot->invoke = WM_operator_confirm; - ot->exec = WM_homefile_write_exec; + ot->exec = wm_homefile_write_exec; + ot->poll = WM_operator_winactive; +} + +static void WM_OT_save_userpref(wmOperatorType *ot) +{ + ot->name = "Save User Settings"; + ot->idname = "WM_OT_save_userpref"; + ot->description = "Save user preferences separately, overrides startup file preferences"; + + ot->invoke = WM_operator_confirm; + ot->exec = wm_userpref_write_exec; ot->poll = WM_operator_winactive; } @@ -1691,7 +1804,7 @@ static void WM_OT_read_homefile(wmOperatorType *ot) ot->description = "Open the default file (doesn't save the current file)"; ot->invoke = WM_operator_confirm; - ot->exec = WM_homefile_read_exec; + ot->exec = wm_homefile_read_exec; /* ommit poll to run in background mode */ } @@ -1702,7 +1815,7 @@ static void WM_OT_read_factory_settings(wmOperatorType *ot) ot->description = "Load default file and user preferences"; ot->invoke = WM_operator_confirm; - ot->exec = WM_homefile_read_exec; + ot->exec = wm_homefile_read_exec; /* ommit poll to run in background mode */ } @@ -2003,21 +2116,35 @@ static void WM_OT_link_append(wmOperatorType *ot) /* *************** recover last session **************** */ -static int wm_recover_last_session_exec(bContext *C, wmOperator *op) +void wm_recover_last_session(bContext *C, ReportList *reports) { char filename[FILE_MAX]; + + BLI_make_file_string("/", filename, BLI_temporary_dir(), BLENDER_QUIT_FILE); + /* if reports==NULL, it's called directly without operator, we add a quick check here */ + if (reports || BLI_exists(filename)) { + G.fileflags |= G_FILE_RECOVER; + + /* XXX wm in context is not set correctly after WM_file_read -> crash */ + /* do it before for now, but is this correct with multiple windows? */ + WM_event_add_notifier(C, NC_WINDOW, NULL); + + /* load file */ + WM_file_read(C, filename, reports); + + G.fileflags &= ~G_FILE_RECOVER; + + /* XXX bad global... fixme */ + if (G.main->name[0]) + G.file_loaded = 1; /* prevents splash to show */ + else + G.relbase_valid = 0; + } +} - G.fileflags |= G_FILE_RECOVER; - - /* XXX wm in context is not set correctly after WM_file_read -> crash */ - /* do it before for now, but is this correct with multiple windows? */ - WM_event_add_notifier(C, NC_WINDOW, NULL); - - /* load file */ - BLI_make_file_string("/", filename, BLI_temporary_dir(), "quit.blend"); - WM_file_read(C, filename, op->reports); - - G.fileflags &= ~G_FILE_RECOVER; +static int wm_recover_last_session_exec(bContext *C, wmOperator *op) +{ + wm_recover_last_session(C, op->reports); return OPERATOR_FINISHED; } @@ -2025,7 +2152,7 @@ static void WM_OT_recover_last_session(wmOperatorType *ot) { ot->name = "Recover Last Session"; ot->idname = "WM_OT_recover_last_session"; - ot->description = "Open the last closed file (\"quit.blend\")"; + ot->description = "Open the last closed file (\"" BLENDER_QUIT_FILE "\")"; ot->exec = wm_recover_last_session_exec; ot->poll = WM_operator_winactive; @@ -2139,7 +2266,7 @@ static int wm_save_as_mainfile_exec(bContext *C, wmOperator *op) untitled(path); } - fileflags = G.fileflags; + fileflags = G.fileflags & ~G_FILE_USERPREFS; /* set compression flag */ BKE_BIT_TEST_SET(fileflags, RNA_boolean_get(op->ptr, "compress"), @@ -2158,7 +2285,7 @@ static int wm_save_as_mainfile_exec(bContext *C, wmOperator *op) G_FILE_MESH_COMPAT); #endif - if (WM_file_write(C, path, fileflags, op->reports) != 0) + if (wm_file_write(C, path, fileflags, op->reports) != 0) return OPERATOR_CANCELLED; WM_event_add_notifier(C, NC_WM | ND_FILESAVE, NULL); @@ -3787,6 +3914,7 @@ void wm_operatortype_init(void) WM_operatortype_append(WM_OT_read_homefile); WM_operatortype_append(WM_OT_read_factory_settings); WM_operatortype_append(WM_OT_save_homefile); + WM_operatortype_append(WM_OT_save_userpref); WM_operatortype_append(WM_OT_window_fullscreen_toggle); WM_operatortype_append(WM_OT_quit_blender); WM_operatortype_append(WM_OT_open_mainfile); diff --git a/source/blender/windowmanager/intern/wm_subwindow.c b/source/blender/windowmanager/intern/wm_subwindow.c index 8533494ae96..1ed9ffb3b6c 100644 --- a/source/blender/windowmanager/intern/wm_subwindow.c +++ b/source/blender/windowmanager/intern/wm_subwindow.c @@ -131,7 +131,7 @@ void wm_subwindow_getorigin(wmWindow *win, int swinid, int *x, int *y) } } -void wm_subwindow_getmatrix(wmWindow *win, int swinid, float mat[][4]) +void wm_subwindow_getmatrix(wmWindow *win, int swinid, float mat[4][4]) { wmSubWindow *swin = swin_from_swinid(win, swinid); @@ -217,10 +217,10 @@ void wm_subwindow_position(wmWindow *win, int swinid, rcti *winrct) * fixed it). - zr (2001!) */ - if (swin->winrct.xmax > win->sizex) - swin->winrct.xmax = win->sizex; - if (swin->winrct.ymax > win->sizey) - swin->winrct.ymax = win->sizey; + if (swin->winrct.xmax > WM_window_pixels_x(win)) + swin->winrct.xmax = WM_window_pixels_x(win); + if (swin->winrct.ymax > WM_window_pixels_y(win)) + swin->winrct.ymax = WM_window_pixels_y(win); /* extra service */ wmSubWindowSet(win, swinid); @@ -257,8 +257,8 @@ void wmSubWindowScissorSet(wmWindow *win, int swinid, rcti *srct) glViewport(_curswin->winrct.xmin, _curswin->winrct.ymin, width, height); if (srct) { - width = BLI_rcti_size_x(srct) + 1; - height = BLI_rcti_size_y(srct) + 1; + int width = BLI_rcti_size_x(srct) + 1; /* only here */ + int height = BLI_rcti_size_y(srct) + 1; glScissor(srct->xmin, srct->ymin, width, height); } else diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index 09f7e1692d9..be202a23d33 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -91,7 +91,9 @@ static struct WMInitStruct { int windowstate; WinOverrideFlag override_flag; -} wm_init_state = {0, 0, 0, 0, GHOST_kWindowStateNormal, 0}; + + int native_pixels; +} wm_init_state = {0, 0, 0, 0, GHOST_kWindowStateNormal, 0, 1}; /* ******** win open & close ************ */ @@ -241,7 +243,7 @@ wmWindow *wm_window_copy(bContext *C, wmWindow *winorig) win->screen->do_refresh = TRUE; win->screen->do_draw = TRUE; - win->drawmethod = -1; + win->drawmethod = U.wmdrawmethod; win->drawdata = NULL; return win; @@ -251,51 +253,50 @@ wmWindow *wm_window_copy(bContext *C, wmWindow *winorig) void wm_window_close(bContext *C, wmWindowManager *wm, wmWindow *win) { wmWindow *tmpwin; - bScreen *screen = win->screen; + int do_exit = 0; + + /* first check if we have to quit (there are non-temp remaining windows) */ + for (tmpwin = wm->windows.first; tmpwin; tmpwin = tmpwin->next) { + if (tmpwin == win) + continue; + if (tmpwin->screen->temp == 0) + break; + } + + if (tmpwin == NULL) + do_exit = 1; - /* first check if we have any non-temp remaining windows */ if ((U.uiflag & USER_QUIT_PROMPT) && !wm->file_saved) { - if (wm->windows.first) { - for (tmpwin = wm->windows.first; tmpwin; tmpwin = tmpwin->next) { - if (tmpwin == win) - continue; - if (tmpwin->screen->temp == 0) - break; - } - if (tmpwin == NULL) { - if (!GHOST_confirmQuit(win->ghostwin)) - return; - } + if (do_exit) { + if (!GHOST_confirmQuit(win->ghostwin)) + return; } } - BLI_remlink(&wm->windows, win); - - wm_draw_window_clear(win); - CTX_wm_window_set(C, win); /* needed by handlers */ - WM_event_remove_handlers(C, &win->handlers); - WM_event_remove_handlers(C, &win->modalhandlers); - ED_screen_exit(C, win, win->screen); - - wm_window_free(C, wm, win); - - /* if temp screen, delete it after window free (it stops jobs that can access it) */ - if (screen->temp) { - Main *bmain = CTX_data_main(C); - BKE_libblock_free(&bmain->screen, screen); + /* let WM_exit do all freeing, for correct quit.blend save */ + if (do_exit) { + WM_exit(C); } + else { + bScreen *screen = win->screen; + + BLI_remlink(&wm->windows, win); + + wm_draw_window_clear(win); + + CTX_wm_window_set(C, win); /* needed by handlers */ + WM_event_remove_handlers(C, &win->handlers); + WM_event_remove_handlers(C, &win->modalhandlers); + ED_screen_exit(C, win, win->screen); + + wm_window_free(C, wm, win); - /* check remaining windows */ - if (wm->windows.first) { - for (win = wm->windows.first; win; win = win->next) - if (win->screen->temp == 0) - break; - /* in this case we close all */ - if (win == NULL) - WM_exit(C); - } - else - WM_exit(C); + /* if temp screen, delete it after window free (it stops jobs that can access it) */ + if (screen->temp) { + Main *bmain = CTX_data_main(C); + BKE_libblock_free(&bmain->screen, screen); + } + } } void wm_window_title(wmWindowManager *wm, wmWindow *win) @@ -308,8 +309,9 @@ void wm_window_title(wmWindowManager *wm, wmWindow *win) /* this is set to 1 if you don't have startup.blend open */ if (G.save_over && G.main->name[0]) { - char str[sizeof(G.main->name) + 12]; - BLI_snprintf(str, sizeof(str), "Blender%s [%s]", wm->file_saved ? "" : "*", G.main->name); + char str[sizeof(G.main->name) + 24]; + BLI_snprintf(str, sizeof(str), "Blender%s [%s%s]", wm->file_saved ? "" : "*", G.main->name, + G.main->recovered ? " (Recovered)" : ""); GHOST_SetTitle(win->ghostwin, str); } else @@ -344,8 +346,6 @@ static void wm_window_add_ghostwindow(const char *title, wmWindow *win) wm_get_screensize(&scr_w, &scr_h); posy = (scr_h - win->posy - win->sizey); - /* Disable AA for now, as GL_SELECT (used for border, lasso, ... select) - * doesn't work well when AA is initialized, even if not used. */ ghostwin = GHOST_CreateWindow(g_system, title, win->posx, posy, win->sizex, win->sizey, (GHOST_TWindowState)win->windowstate, @@ -354,6 +354,8 @@ static void wm_window_add_ghostwindow(const char *title, wmWindow *win) multisamples /* AA */); if (ghostwin) { + GHOST_RectangleHandle bounds; + /* needed so we can detect the graphics card below */ GPU_extensions_init(); @@ -372,7 +374,19 @@ static void wm_window_add_ghostwindow(const char *title, wmWindow *win) if (!GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_UNIX, GPU_DRIVER_OPENSOURCE)) { glClear(GL_COLOR_BUFFER_BIT); } + + /* displays with larger native pixels, like Macbook. Used to scale dpi with */ + /* needed here, because it's used before it reads userdef */ + U.pixelsize = GHOST_GetNativePixelSize(); + BKE_userdef_state(); + + /* store actual window size in blender window */ + bounds = GHOST_GetClientBounds(win->ghostwin); + win->sizex = GHOST_GetWidthRectangle(bounds); + win->sizey = GHOST_GetHeightRectangle(bounds); + GHOST_DisposeRectangle(bounds); + wm_window_swap_buffers(win); //GHOST_SetWindowState(ghostwin, GHOST_kWindowStateModified); @@ -468,7 +482,7 @@ wmWindow *WM_window_open(bContext *C, rcti *rect) win->sizex = BLI_rcti_size_x(rect); win->sizey = BLI_rcti_size_y(rect); - win->drawmethod = -1; + win->drawmethod = U.wmdrawmethod; win->drawdata = NULL; WM_check(C); @@ -578,6 +592,23 @@ int wm_window_fullscreen_toggle_exec(bContext *C, wmOperator *UNUSED(op)) /* ************ events *************** */ +static void wm_convert_cursor_position(wmWindow *win, int *x, int *y) +{ + + GHOST_ScreenToClient(win->ghostwin, *x, *y, x, y); + *x *= GHOST_GetNativePixelSize(); + + *y = (win->sizey - 1) - *y; + *y *= GHOST_GetNativePixelSize(); +} + + +void wm_get_cursor_position(wmWindow *win, int *x, int *y) +{ + GHOST_GetCursorPosition(g_system, x, y); + wm_convert_cursor_position(win, x, y); +} + typedef enum { SHIFT = 's', CONTROL = 'c', @@ -633,6 +664,7 @@ void wm_window_make_drawable(bContext *C, wmWindow *win) } /* called by ghost, here we handle events for windows themselves or send to event system */ +/* mouse coordinate converversion happens here */ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr) { bContext *C = C_void_ptr; @@ -673,7 +705,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr { GHOST_TEventKeyData kdata; wmEvent event; - int cx, cy, wx, wy; + int wx, wy; wm->winactive = win; /* no context change! c->wm->windrawable is drawable, or for area queues */ @@ -703,11 +735,10 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr win->eventstate->keymodifier = 0; /* entering window, update mouse pos. but no event */ - GHOST_GetCursorPosition(g_system, &wx, &wy); - - GHOST_ScreenToClient(win->ghostwin, wx, wy, &cx, &cy); - win->eventstate->x = cx; - win->eventstate->y = (win->sizey - 1) - cy; + wm_get_cursor_position(win, &wx, &wy); + + win->eventstate->x = wx; + win->eventstate->y = wy; win->addmousemove = 1; /* enables highlighted buttons */ @@ -857,14 +888,12 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr { wmEvent event; GHOST_TEventDragnDropData *ddd = GHOST_GetEventData(evt); - int cx, cy, wx, wy; + int wx, wy; /* entering window, update mouse pos */ - GHOST_GetCursorPosition(g_system, &wx, &wy); - - GHOST_ScreenToClient(win->ghostwin, wx, wy, &cx, &cy); - win->eventstate->x = cx; - win->eventstate->y = (win->sizey - 1) - cy; + wm_get_cursor_position(win, &wx, &wy); + win->eventstate->x = wx; + win->eventstate->y = wy; event = *(win->eventstate); /* copy last state, like mouse coords */ @@ -907,11 +936,24 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr } } + break; + } + case GHOST_kEventTrackpad: + { + GHOST_TEventTrackpadData *pd = data; + wm_convert_cursor_position(win, &pd->x, &pd->y); + wm_event_add_ghostevent(wm, win, type, time, data); + break; + } + case GHOST_kEventCursorMove: + { + GHOST_TEventCursorData *cd = data; + wm_convert_cursor_position(win, &cd->x, &cd->y); + wm_event_add_ghostevent(wm, win, type, time, data); break; } - default: wm_event_add_ghostevent(wm, win, type, time, data); break; @@ -1017,6 +1059,10 @@ void wm_ghost_init(bContext *C) g_system = GHOST_CreateSystem(); GHOST_AddEventConsumer(g_system, consumer); + + if (wm_init_state.native_pixels) { + GHOST_UseNativePixels(); + } } } @@ -1068,6 +1114,8 @@ void WM_event_remove_timer(wmWindowManager *wm, wmWindow *UNUSED(win), wmTimer * if (wt == timer) break; if (wt) { + wmWindow *win; + if (wm->reports.reporttimer == wt) wm->reports.reporttimer = NULL; @@ -1075,6 +1123,17 @@ void WM_event_remove_timer(wmWindowManager *wm, wmWindow *UNUSED(win), wmTimer * if (wt->customdata) MEM_freeN(wt->customdata); MEM_freeN(wt); + + /* there might be events in queue with this timer as customdata */ + for (win = wm->windows.first; win; win = win->next) { + wmEvent *event; + for (event = win->queue.first; event; event = event->next) { + if (event->customdata == wt) { + event->customdata = NULL; + event->type = EVENT_NONE; /* timer users customdata, dont want NULL == NULL */ + } + } + } } } @@ -1158,23 +1217,6 @@ void wm_window_get_position(wmWindow *win, int *posx_r, int *posy_r) *posy_r = win->posy; } -void wm_window_get_size(wmWindow *win, int *width_r, int *height_r) -{ - *width_r = win->sizex; - *height_r = win->sizey; -} - -/* exceptional case: - splash is called before events are processed - * this means we don't actually know the window size so get this from GHOST */ -void wm_window_get_size_ghost(wmWindow *win, int *width_r, int *height_r) -{ - GHOST_RectangleHandle bounds = GHOST_GetClientBounds(win->ghostwin); - *width_r = GHOST_GetWidthRectangle(bounds); - *height_r = GHOST_GetHeightRectangle(bounds); - - GHOST_DisposeRectangle(bounds); -} - void wm_window_set_size(wmWindow *win, int width, int height) { GHOST_SetClientSize(win->ghostwin, width, height); @@ -1202,12 +1244,6 @@ void wm_window_swap_buffers(wmWindow *win) #endif } -void wm_get_cursor_position(wmWindow *win, int *x, int *y) -{ - GHOST_GetCursorPosition(g_system, x, y); - GHOST_ScreenToClient(win->ghostwin, *x, *y, x, y); - *y = (win->sizey - 1) - *y; -} /* ******************* exported api ***************** */ @@ -1217,8 +1253,8 @@ void WM_init_state_size_set(int stax, int stay, int sizx, int sizy) { wm_init_state.start_x = stax; /* left hand pos */ wm_init_state.start_y = stay; /* bottom pos */ - wm_init_state.size_x = sizx; - wm_init_state.size_y = sizy; + wm_init_state.size_x = sizx < 640 ? 640 : sizx; + wm_init_state.size_y = sizy < 480 ? 480 : sizy; wm_init_state.override_flag |= WIN_OVERRIDE_GEOM; } @@ -1235,12 +1271,20 @@ void WM_init_state_normal_set(void) wm_init_state.override_flag |= WIN_OVERRIDE_WINSTATE; } +void WM_init_native_pixels(int do_it) +{ + wm_init_state.native_pixels = do_it; +} + /* This function requires access to the GHOST_SystemHandle (g_system) */ void WM_cursor_warp(wmWindow *win, int x, int y) { if (win && win->ghostwin) { + float f = GHOST_GetNativePixelSize(); int oldx = x, oldy = y; + x = x / f; + y = y / f; y = win->sizey - y - 1; GHOST_ClientToScreen(win->ghostwin, x, y, &x, &y); @@ -1251,3 +1295,19 @@ void WM_cursor_warp(wmWindow *win, int x, int y) } } +/* support for native pixel size */ +/* mac retina opens window in size X, but it has up to 2 x more pixels */ +int WM_window_pixels_x(wmWindow *win) +{ + float f = GHOST_GetNativePixelSize(); + + return (int)(f * (float)win->sizex); +} + +int WM_window_pixels_y(wmWindow *win) +{ + float f = GHOST_GetNativePixelSize(); + + return (int)(f * (float)win->sizey); + +} |