diff options
Diffstat (limited to 'source/blender/windowmanager/intern/wm_window.c')
-rw-r--r-- | source/blender/windowmanager/intern/wm_window.c | 192 |
1 files changed, 120 insertions, 72 deletions
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index 4baad110232..db427ea68d1 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -41,11 +41,14 @@ #include "GHOST_C-api.h" #include "BLI_blenlib.h" +#include "BLI_utildefines.h" #include "BKE_blender.h" #include "BKE_context.h" +#include "BKE_library.h" #include "BKE_global.h" -#include "BKE_utildefines.h" +#include "BKE_main.h" + #include "BIF_gl.h" @@ -58,16 +61,19 @@ #include "wm_event_system.h" #include "ED_screen.h" +#include "ED_fileselect.h" #include "PIL_time.h" #include "GPU_draw.h" +#include "GPU_extensions.h" /* the global to talk to ghost */ GHOST_SystemHandle g_system= NULL; /* set by commandline */ static int prefsizx= 0, prefsizy= 0, prefstax= 0, prefstay= 0, initialstate= GHOST_kWindowStateNormal; +static unsigned short useprefsize= 0; /* ******** win open & close ************ */ @@ -144,10 +150,9 @@ void wm_window_free(bContext *C, wmWindowManager *wm, wmWindow *win) CTX_wm_window_set(C, NULL); } - if(wm->windrawable==win) - wm->windrawable= NULL; - if(wm->winactive==win) - wm->winactive= NULL; + /* always set drawable and active to NULL, prevents non-drawable state of main windows (bugs #22967 and #25071, possibly #22477 too) */ + wm->windrawable= NULL; + wm->winactive= NULL; /* end running jobs, a job end also removes its timer */ for(wt= wm->timers.first; wt; wt= wtnext) { @@ -213,7 +218,7 @@ wmWindow *wm_window_copy(bContext *C, wmWindow *winorig) /* duplicate assigns to window */ win->screen= ED_screen_duplicate(win, winorig->screen); - BLI_strncpy(win->screenname, win->screen->id.name+2, 21); + BLI_strncpy(win->screenname, win->screen->id.name+2, sizeof(win->screenname)); win->screen->winid= win->winid; win->screen->do_refresh= 1; @@ -234,13 +239,20 @@ void wm_window_close(bContext *C, wmWindowManager *wm, wmWindow *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); /* will free the current screen if it is a temp layout */ + ED_screen_exit(C, win, win->screen); + + /* if temp screen, delete it */ + if(win->screen->temp) { + Main *bmain= CTX_data_main(C); + free_libblock(&bmain->screen, 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->full!=SCREENTEMP) + if(win->screen->temp == 0) break; /* in this case we close all */ if(win==NULL) @@ -253,23 +265,21 @@ void wm_window_close(bContext *C, wmWindowManager *wm, wmWindow *win) void wm_window_title(wmWindowManager *wm, wmWindow *win) { /* handle the 'temp' window */ - if(win->screen && win->screen->full==SCREENTEMP) { + if(win->screen && win->screen->temp) { GHOST_SetTitle(win->ghostwin, "Blender"); } else { /* this is set to 1 if you don't have startup.blend open */ - if(G.save_over) { - char *str= MEM_mallocN(strlen(G.sce) + 16, "title"); + if(G.save_over && G.main->name[0]) { + char str[sizeof(G.main->name) + 12]; if(wm->file_saved) - sprintf(str, "Blender [%s]", G.sce); + sprintf(str, "Blender [%s]", G.main->name); else - sprintf(str, "Blender* [%s]", G.sce); + sprintf(str, "Blender* [%s]", G.main->name); GHOST_SetTitle(win->ghostwin, str); - - MEM_freeN(str); } else GHOST_SetTitle(win->ghostwin, "Blender"); @@ -289,7 +299,7 @@ void wm_window_title(wmWindowManager *wm, wmWindow *win) } /* belongs to below */ -static void wm_window_add_ghostwindow(bContext *C, wmWindowManager *wm, char *title, wmWindow *win) +static void wm_window_add_ghostwindow(bContext *C, const char *title, wmWindow *win) { GHOST_WindowHandle ghostwin; int scr_w, scr_h, posy; @@ -307,7 +317,7 @@ static void wm_window_add_ghostwindow(bContext *C, wmWindowManager *wm, char *ti #if defined(__APPLE__) && !defined(GHOST_COCOA) { extern int macPrefState; /* creator.c */ - inital_state += macPrefState; + initial_state += macPrefState; } #endif /* Disable AA for now, as GL_SELECT (used for border, lasso, ... select) @@ -320,6 +330,8 @@ static void wm_window_add_ghostwindow(bContext *C, wmWindowManager *wm, char *ti 0 /* no AA */); if (ghostwin) { + /* needed so we can detect the graphics card below */ + GPU_extensions_init(); /* set the state*/ GHOST_SetWindowState(ghostwin, initial_state); @@ -332,7 +344,11 @@ static void wm_window_add_ghostwindow(bContext *C, wmWindowManager *wm, char *ti /* until screens get drawn, make it nice grey */ glClearColor(.55, .55, .55, 0.0); - glClear(GL_COLOR_BUFFER_BIT); + /* Crash on OSS ATI: bugs.launchpad.net/ubuntu/+source/mesa/+bug/656100 */ + if(!GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_UNIX, GPU_DRIVER_OPENSOURCE)) { + glClear(GL_COLOR_BUFFER_BIT); + } + wm_window_swap_buffers(win); //GHOST_SetWindowState(ghostwin, GHOST_kWindowStateModified); @@ -352,7 +368,10 @@ void wm_window_add_ghostwindows(bContext* C, wmWindowManager *wm) wmKeyMap *keymap; wmWindow *win; - /* no commandline prefsize? then we set this */ + /* no commandline prefsize? then we set this. + * Note that these values will be used only + * when there is no startup.blend yet. + */ if (!prefsizx) { wm_get_screensize(&prefsizx, &prefsizy); @@ -372,18 +391,19 @@ void wm_window_add_ghostwindows(bContext* C, wmWindowManager *wm) for(win= wm->windows.first; win; win= win->next) { if(win->ghostwin==NULL) { - if(win->sizex==0) { + if(win->sizex==0 || useprefsize) { win->posx= prefstax; win->posy= prefstay; win->sizex= prefsizx; win->sizey= prefsizy; win->windowstate= initialstate; + useprefsize= 0; } - wm_window_add_ghostwindow(C, wm, "Blender", win); + wm_window_add_ghostwindow(C, "Blender", win); } /* happens after fileread */ if(win->eventstate==NULL) - win->eventstate= MEM_callocN(sizeof(wmEvent), "window event state"); + win->eventstate= MEM_callocN(sizeof(wmEvent), "window event state"); /* add keymap handlers (1 handler for all keys in map!) */ keymap= WM_keymap_find(wm->defaultconf, "Window", 0, 0); @@ -395,6 +415,11 @@ void wm_window_add_ghostwindows(bContext* C, wmWindowManager *wm) keymap= WM_keymap_find(wm->defaultconf, "Screen Editing", 0, 0); WM_event_add_keymap_handler(&win->modalhandlers, keymap); + /* add drop boxes */ + { + ListBase *lb= WM_dropboxmap_find("Window", 0, 0); + WM_event_add_dropbox_handler(&win->handlers, lb); + } wm_window_title(wm, win); } } @@ -419,7 +444,7 @@ wmWindow *WM_window_open(bContext *C, rcti *rect) return win; } -/* uses screen->full tag to define what to do, currently it limits +/* uses screen->temp tag to define what to do, currently it limits to only one "temp" window for render out, preferences, filewindow, etc */ /* type is #define in WM_api.h */ @@ -433,7 +458,7 @@ void WM_window_open_temp(bContext *C, rcti *position, int type) /* test if we have a temp screen already */ for(win= CTX_wm_manager(C)->windows.first; win; win= win->next) - if(win->screen->full == SCREENTEMP) + if(win->screen->temp) break; /* add new window? */ @@ -455,7 +480,7 @@ void WM_window_open_temp(bContext *C, rcti *position, int type) /* add new screen? */ if(win->screen==NULL) win->screen= ED_screen_add(win, CTX_data_scene(C), "temp"); - win->screen->full = SCREENTEMP; + win->screen->temp = 1; /* make window active, and validate/resize */ CTX_wm_window_set(C, win); @@ -488,7 +513,7 @@ void WM_window_open_temp(bContext *C, rcti *position, int type) /* ****************** Operators ****************** */ /* operator callback */ -int wm_window_duplicate_op(bContext *C, wmOperator *op) +int wm_window_duplicate_exec(bContext *C, wmOperator *UNUSED(op)) { wm_window_copy(C, CTX_wm_window(C)); WM_check(C); @@ -500,7 +525,7 @@ int wm_window_duplicate_op(bContext *C, wmOperator *op) /* fullscreen operator callback */ -int wm_window_fullscreen_toggle_op(bContext *C, wmOperator *op) +int wm_window_fullscreen_toggle_exec(bContext *C, wmOperator *UNUSED(op)) { wmWindow *window= CTX_wm_window(C); GHOST_TWindowState state = GHOST_GetWindowState(window->ghostwin); @@ -516,22 +541,37 @@ int wm_window_fullscreen_toggle_op(bContext *C, wmOperator *op) /* ************ events *************** */ -static int query_qual(char qual) +typedef enum +{ + SHIFT = 's', + CONTROL = 'c', + ALT = 'a', + OS = 'C' +} modifierKeyType; + +/* check if specified modifier key type is pressed */ +static int query_qual(modifierKeyType qual) { GHOST_TModifierKeyMask left, right; int val= 0; - if (qual=='s') { - left= GHOST_kModifierKeyLeftShift; - right= GHOST_kModifierKeyRightShift; - } else if (qual=='c') { - left= GHOST_kModifierKeyLeftControl; - right= GHOST_kModifierKeyRightControl; - } else if (qual=='C') { - left= right= GHOST_kModifierKeyCommand; - } else { - left= GHOST_kModifierKeyLeftAlt; - right= GHOST_kModifierKeyRightAlt; + switch(qual) { + case SHIFT: + left= GHOST_kModifierKeyLeftShift; + right= GHOST_kModifierKeyRightShift; + break; + case CONTROL: + left= GHOST_kModifierKeyLeftControl; + right= GHOST_kModifierKeyRightControl; + break; + case OS: + left= right= GHOST_kModifierKeyOS; + break; + case ALT: + default: + left= GHOST_kModifierKeyLeftAlt; + right= GHOST_kModifierKeyRightAlt; + break; } GHOST_GetModifierKeyState(g_system, left, &val); @@ -600,20 +640,20 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr private) /* bad ghost support for modifier keys... so on activate we set the modifiers again */ kdata.ascii= 0; - if (win->eventstate->shift && !query_qual('s')) { + if (win->eventstate->shift && !query_qual(SHIFT)) { kdata.key= GHOST_kKeyLeftShift; wm_event_add_ghostevent(wm, win, GHOST_kEventKeyUp, time, &kdata); } - if (win->eventstate->ctrl && !query_qual('c')) { + if (win->eventstate->ctrl && !query_qual(CONTROL)) { kdata.key= GHOST_kKeyLeftControl; wm_event_add_ghostevent(wm, win, GHOST_kEventKeyUp, time, &kdata); } - if (win->eventstate->alt && !query_qual('a')) { + if (win->eventstate->alt && !query_qual(ALT)) { kdata.key= GHOST_kKeyLeftAlt; wm_event_add_ghostevent(wm, win, GHOST_kEventKeyUp, time, &kdata); } - if (win->eventstate->oskey && !query_qual('C')) { - kdata.key= GHOST_kKeyCommand; + if (win->eventstate->oskey && !query_qual(OS)) { + kdata.key= GHOST_kKeyOS; wm_event_add_ghostevent(wm, win, GHOST_kEventKeyUp, time, &kdata); } /* keymodifier zero, it hangs on hotkeys that open windows otherwise */ @@ -787,15 +827,17 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr private) /* printf("Drop detected\n"); */ /* add drag data to wm for paths: */ - /* need icon type, some dropboxes check for that... see filesel code for this */ if(ddd->dataType == GHOST_kDragnDropTypeFilenames) { GHOST_TStringArray *stra= ddd->data; - int a; + int a, icon; for(a=0; a<stra->count; a++) { printf("drop file %s\n", stra->strings[a]); - WM_event_start_drag(C, 0, WM_DRAG_PATH, stra->strings[a], 0.0); + /* try to get icon type from extension */ + icon= ED_file_extension_icon((char *)stra->strings[a]); + + WM_event_start_drag(C, icon, WM_DRAG_PATH, stra->strings[a], 0.0); /* void poin should point to string, it makes a copy */ break; // only one drop element supported now } @@ -875,7 +917,7 @@ void wm_window_process_events(const bContext *C) PIL_sleep_ms(5); } -void wm_window_process_events_nosleep(const bContext *C) +void wm_window_process_events_nosleep(void) { if(GHOST_ProcessEvents(g_system, 0)) GHOST_DispatchEvents(g_system); @@ -923,7 +965,7 @@ void wm_ghost_exit(void) /* **************** timer ********************** */ /* to (de)activate running timers temporary */ -void WM_event_timer_sleep(wmWindowManager *wm, wmWindow *win, wmTimer *timer, int dosleep) +void WM_event_timer_sleep(wmWindowManager *wm, wmWindow *UNUSED(win), wmTimer *timer, int dosleep) { wmTimer *wt; @@ -951,7 +993,7 @@ wmTimer *WM_event_add_timer(wmWindowManager *wm, wmWindow *win, int event_type, return wt; } -void WM_event_remove_timer(wmWindowManager *wm, wmWindow *win, wmTimer *timer) +void WM_event_remove_timer(wmWindowManager *wm, wmWindow *UNUSED(win), wmTimer *timer) { wmTimer *wt; @@ -974,6 +1016,9 @@ char *WM_clipboard_text_get(int selection) { char *p, *p2, *buf, *newbuf; + if(G.background) + return NULL; + buf= (char*)GHOST_getClipboard(selection); if(!buf) return NULL; @@ -994,33 +1039,35 @@ char *WM_clipboard_text_get(int selection) void WM_clipboard_text_set(char *buf, int selection) { + if(!G.background) { #ifdef _WIN32 - /* do conversion from \n to \r\n on Windows */ - char *p, *p2, *newbuf; - int newlen= 0; - - for(p= buf; *p; p++) { - if(*p == '\n') - newlen += 2; - else - newlen++; - } + /* do conversion from \n to \r\n on Windows */ + char *p, *p2, *newbuf; + int newlen= 0; + + for(p= buf; *p; p++) { + if(*p == '\n') + newlen += 2; + else + newlen++; + } + + newbuf= MEM_callocN(newlen+1, "WM_clipboard_text_set"); - newbuf= MEM_callocN(newlen+1, "WM_clipboard_text_set"); - - for(p= buf, p2= newbuf; *p; p++, p2++) { - if(*p == '\n') { - *(p2++)= '\r'; *p2= '\n'; + for(p= buf, p2= newbuf; *p; p++, p2++) { + if(*p == '\n') { + *(p2++)= '\r'; *p2= '\n'; + } + else *p2= *p; } - else *p2= *p; - } - *p2= '\0'; - - GHOST_putClipboard((GHOST_TInt8*)newbuf, selection); - MEM_freeN(newbuf); + *p2= '\0'; + + GHOST_putClipboard((GHOST_TInt8*)newbuf, selection); + MEM_freeN(newbuf); #else - GHOST_putClipboard((GHOST_TInt8*)buf, selection); + GHOST_putClipboard((GHOST_TInt8*)buf, selection); #endif + } } /* ******************* progress bar **************** */ @@ -1109,6 +1156,7 @@ void WM_setprefsize(int stax, int stay, int sizx, int sizy) prefstay= stay; prefsizx= sizx; prefsizy= sizy; + useprefsize= 1; } /* for borderless and border windows set from command-line */ |