diff options
author | Lukas Steiblys <imbusy@imbusy.org> | 2009-10-02 02:29:15 +0400 |
---|---|---|
committer | Lukas Steiblys <imbusy@imbusy.org> | 2009-10-02 02:29:15 +0400 |
commit | 0677398a649b6b8c293df3ce3c6668f0a3be3bc8 (patch) | |
tree | 9d510a5bd23559bf4fae670ed04d7e5d6c12578c /source/blender/windowmanager | |
parent | 59248e9f62006ba05e3098e4d213f3dcb23fe711 (diff) | |
parent | bc942eceacb638735dc4f4f68252c4c207147a70 (diff) |
merge from 23153 to 23595soc-2009-imbusy
Diffstat (limited to 'source/blender/windowmanager')
-rw-r--r-- | source/blender/windowmanager/SConscript | 7 | ||||
-rw-r--r-- | source/blender/windowmanager/WM_api.h | 27 | ||||
-rw-r--r-- | source/blender/windowmanager/WM_types.h | 15 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm.c | 8 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_event_system.c | 187 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_files.c | 5 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_init_exit.c | 11 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_jobs.c | 33 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_keymap.c | 39 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_operators.c | 352 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_window.c | 88 | ||||
-rw-r--r-- | source/blender/windowmanager/wm_event_system.h | 2 | ||||
-rw-r--r-- | source/blender/windowmanager/wm_event_types.h | 12 |
13 files changed, 545 insertions, 241 deletions
diff --git a/source/blender/windowmanager/SConscript b/source/blender/windowmanager/SConscript index 91635904524..08a291871f1 100644 --- a/source/blender/windowmanager/SConscript +++ b/source/blender/windowmanager/SConscript @@ -19,4 +19,11 @@ defs = [] if not env['WITH_BF_PYTHON']: defs.append('DISABLE_PYTHON') +if env['OURPLATFORM'] == 'linux2': + cflags='-pthread' + incs += ' ../../../extern/binreloc/include' + +if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'): + incs += ' ' + env['BF_PTHREADS_INC'] + env.BlenderLib ( 'bf_windowmanager', sources, Split(incs), defs, libtype=['core'], priority=[5] ) diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 544804b26d6..489f27990cd 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -83,12 +83,12 @@ void WM_paint_cursor_end(struct wmWindowManager *wm, void *handle); /* keymap */ void WM_keymap_init (struct bContext *C); -wmKeymapItem *WM_keymap_verify_item(ListBase *lb, char *idname, short type, +wmKeymapItem *WM_keymap_verify_item(wmKeyMap *keymap, char *idname, short type, short val, int modifier, short keymodifier); -wmKeymapItem *WM_keymap_add_item(ListBase *lb, char *idname, short type, +wmKeymapItem *WM_keymap_add_item(wmKeyMap *keymap, char *idname, short type, short val, int modifier, short keymodifier); -void WM_keymap_tweak (ListBase *lb, short type, short val, int modifier, short keymodifier); -ListBase *WM_keymap_listbase (struct wmWindowManager *wm, const char *nameid, +void WM_keymap_tweak (wmKeyMap *keymap, short type, short val, int modifier, short keymodifier); +wmKeyMap *WM_keymap_find (struct wmWindowManager *wm, const char *nameid, short spaceid, short regionid); wmKeyMap *WM_modalkeymap_add(struct wmWindowManager *wm, const char *nameid, struct EnumPropertyItem *items); @@ -104,13 +104,13 @@ void WM_key_event_operator_change(const struct bContext *C, const char *opname, /* handlers */ -struct wmEventHandler *WM_event_add_keymap_handler(ListBase *handlers, ListBase *keymap); +struct wmEventHandler *WM_event_add_keymap_handler(ListBase *handlers, wmKeyMap *keymap); /* boundbox, optional subwindow boundbox for offset */ -struct wmEventHandler *WM_event_add_keymap_handler_bb(ListBase *handlers, ListBase *keymap, rcti *bb, rcti *swinbb); +struct wmEventHandler *WM_event_add_keymap_handler_bb(ListBase *handlers, wmKeyMap *keymap, rcti *bb, rcti *swinbb); /* priority not implemented, it adds in begin */ -struct wmEventHandler *WM_event_add_keymap_handler_priority(ListBase *handlers, ListBase *keymap, int priority); +struct wmEventHandler *WM_event_add_keymap_handler_priority(ListBase *handlers, wmKeyMap *keymap, int priority); -void WM_event_remove_keymap_handler(ListBase *handlers, ListBase *keymap); +void WM_event_remove_keymap_handler(ListBase *handlers, wmKeyMap *keymap); struct wmEventHandler *WM_event_add_ui_handler(const struct bContext *C, ListBase *handlers, int (*func)(struct bContext *C, struct wmEvent *event, void *userdata), @@ -119,7 +119,7 @@ void WM_event_remove_ui_handler(ListBase *handlers, int (*func)(struct bContext *C, struct wmEvent *event, void *userdata), void (*remove)(struct bContext *C, void *userdata), void *userdata); -struct wmEventHandler *WM_event_add_modal_handler(struct bContext *C, ListBase *handlers, struct wmOperator *op); +struct wmEventHandler *WM_event_add_modal_handler(struct bContext *C, struct wmOperator *op); void WM_event_remove_handlers(struct bContext *C, ListBase *handlers); void WM_event_add_mousemove(struct bContext *C); @@ -139,7 +139,7 @@ void WM_event_window_timer_sleep(struct wmWindow *win, struct wmTimer *timer, i int WM_menu_invoke (struct bContext *C, struct wmOperator *op, struct wmEvent *event); /* invoke callback, confirm menu + exec */ int WM_operator_confirm (struct bContext *C, struct wmOperator *op, struct wmEvent *event); - /* invoke callback, file selector "filename" unset + exec */ + /* invoke callback, file selector "path" unset + exec */ int WM_operator_filesel (struct bContext *C, struct wmOperator *op, struct wmEvent *event); /* poll callback, context checks */ int WM_operator_winactive (struct bContext *C); @@ -162,6 +162,7 @@ wmOperatorType *WM_operatortype_append_macro(char *idname, char *name, int flag) wmOperatorTypeMacro *WM_operatortype_macro_define(wmOperatorType *ot, const char *idname); +int WM_operator_poll (struct bContext *C, struct wmOperatorType *ot); int WM_operator_call (struct bContext *C, struct wmOperator *op); int WM_operator_repeat (struct bContext *C, struct wmOperator *op); int WM_operator_name_call (struct bContext *C, const char *opstring, int context, struct PointerRNA *properties); @@ -169,7 +170,7 @@ int WM_operator_call_py(struct bContext *C, struct wmOperatorType *ot, int con void WM_operator_properties_create(struct PointerRNA *ptr, const char *opstring); void WM_operator_properties_free(struct PointerRNA *ptr); -void WM_operator_properties_filesel(struct wmOperatorType *ot, int filter); +void WM_operator_properties_filesel(struct wmOperatorType *ot, int filter, short type); /* operator as a python command (resultuing string must be free'd) */ char *WM_operator_pystring(struct bContext *C, struct wmOperatorType *ot, struct PointerRNA *opptr, int all_args); @@ -225,8 +226,10 @@ void WM_set_framebuffer_index_color(int index); int WM_framebuffer_to_index(unsigned int col); /* threaded Jobs Manager */ +#define WM_JOB_PRIORITY 1 +#define WM_JOB_EXCL_RENDER 2 -struct wmJob *WM_jobs_get(struct wmWindowManager *wm, struct wmWindow *win, void *owner); +struct wmJob *WM_jobs_get(struct wmWindowManager *wm, struct wmWindow *win, void *owner, int flag); int WM_jobs_test(struct wmWindowManager *wm, void *owner); diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h index 806f5409b0a..d746df01421 100644 --- a/source/blender/windowmanager/WM_types.h +++ b/source/blender/windowmanager/WM_types.h @@ -183,9 +183,12 @@ typedef struct wmNotifier { #define ND_SHADING_DRAW (31<<16) /* NC_LAMP Lamp */ -#define ND_LIGHTING (44<<16) -#define ND_LIGHTING_DRAW (45<<16) -#define ND_SKY (46<<16) +#define ND_LIGHTING (40<<16) +#define ND_LIGHTING_DRAW (41<<16) +#define ND_SKY (42<<16) + + /* NC_WORLD World */ +#define ND_WORLD_DRAW (45<<16) /* NC_TEXT Text */ #define ND_CURSOR (50<<16) @@ -276,12 +279,8 @@ typedef struct wmGesture { } wmGesture; /* ************** custom wmEvent data ************** */ - -#define DEV_STYLUS 1 -#define DEV_ERASER 2 - typedef struct wmTabletData { - int Active; /* 0=None, 1=Stylus, 2=Eraser */ + int Active; /* 0=EVT_TABLET_NONE, 1=EVT_TABLET_STYLUS, 2=EVT_TABLET_ERASER */ float Pressure; /* range 0.0 (not touching) to 1.0 (full pressure) */ float Xtilt; /* range 0.0 (upright) to 1.0 (tilted fully against the tablet surface) */ float Ytilt; /* as above */ diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c index 38cf39c2081..4405b52888d 100644 --- a/source/blender/windowmanager/intern/wm.c +++ b/source/blender/windowmanager/intern/wm.c @@ -69,15 +69,17 @@ void WM_operator_free(wmOperator *op) MEM_freeN(op->properties); } - if(op->reports && (op->flag & OPERATOR_REPORT_FREE)) { + if(op->reports && (op->reports->flag & RPT_FREE)) { BKE_reports_clear(op->reports); MEM_freeN(op->reports); } if(op->macro.first) { - wmOperator *opm; - for(opm= op->macro.first; opm; opm= opm->next) + wmOperator *opm, *opmnext; + for(opm= op->macro.first; opm; opm= opmnext) { + opmnext = opm->next; WM_operator_free(opm); + } } MEM_freeN(op); diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c index 3c03d24ca93..b7156a17383 100644 --- a/source/blender/windowmanager/intern/wm_event_system.c +++ b/source/blender/windowmanager/intern/wm_event_system.c @@ -239,7 +239,7 @@ void wm_event_do_notifiers(bContext *C) if(G.rendering==0) { // XXX make lock in future, or separated derivedmesh users in scene - /* update all objects, ipos, matrices, displists, etc. Flags set by depgraph or manual, + /* update all objects, drivers, matrices, displists, etc. Flags set by depgraph or manual, no layer check here, gets correct flushed */ /* sets first, we allow per definition current scene to have dependencies on sets */ if(scene->set) { @@ -259,20 +259,23 @@ void wm_event_do_notifiers(bContext *C) /* ********************* operators ******************* */ -static int wm_operator_poll(bContext *C, wmOperatorType *ot) +int WM_operator_poll(bContext *C, wmOperatorType *ot) { wmOperatorTypeMacro *otmacro; for(otmacro= ot->macro.first; otmacro; otmacro= otmacro->next) { wmOperatorType *ot= WM_operatortype_find(otmacro->idname, 0); - if(0==wm_operator_poll(C, ot)) + if(0==WM_operator_poll(C, ot)) return 0; } - if(ot->poll) + /* python needs operator type, so we added exception for it */ + if(ot->pyop_poll) + return ot->pyop_poll(C, ot); + else if(ot->poll) return ot->poll(C); - + return 1; } @@ -284,7 +287,7 @@ static int wm_operator_exec(bContext *C, wmOperator *op, int repeat) if(op==NULL || op->type==NULL) return retval; - if(0==wm_operator_poll(C, op->type)) + if(0==WM_operator_poll(C, op->type)) return retval; if(op->type->exec) @@ -349,8 +352,7 @@ static wmOperator *wm_operator_create(wmWindowManager *wm, wmOperatorType *ot, P } else { op->reports= MEM_mallocN(sizeof(ReportList), "wmOperatorReportList"); - BKE_reports_init(op->reports, RPT_STORE); - op->flag |= OPERATOR_REPORT_FREE; + BKE_reports_init(op->reports, RPT_STORE|RPT_FREE); } /* recursive filling of operator macro list */ @@ -398,7 +400,7 @@ static int wm_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event, P wmWindowManager *wm= CTX_wm_manager(C); int retval= OPERATOR_PASS_THROUGH; - if(wm_operator_poll(C, ot)) { + if(WM_operator_poll(C, ot)) { wmOperator *op= wm_operator_create(wm, ot, properties, reports); /* if reports==NULL, theyll be initialized */ if((G.f & G_DEBUG) && event && event->type!=MOUSEMOVE) @@ -413,7 +415,9 @@ static int wm_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event, P else printf("invalid operator call %s\n", ot->idname); /* debug, important to leave a while, should never happen */ - if(!(retval & OPERATOR_RUNNING_MODAL)) { + /* Note, if the report is given as an argument then assume the caller will deal with displaying them + * currently python only uses this */ + if(!(retval & OPERATOR_RUNNING_MODAL) && reports==NULL) { if(op->reports->list.first) /* only show the report if the report list was not given in the function */ uiPupMenuReports(C, op->reports); @@ -555,6 +559,12 @@ int WM_operator_call_py(bContext *C, wmOperatorType *ot, int context, PointerRNA retval= wm_operator_call_internal(C, ot, context, properties, reports); + /* keep the reports around if needed later */ + if (retval & OPERATOR_RUNNING_MODAL || ot->flag & OPTYPE_REGISTER) + { + reports->flag |= RPT_FREE; + } + return retval; } @@ -710,7 +720,7 @@ static int wm_eventmatch(wmEvent *winevent, wmKeymapItem *kmi) /* the matching rules */ if(kmitype==KM_TEXTINPUT) - if(ISKEYBOARD(winevent->type)) return 1; + if(ISTEXTINPUT(winevent->type) && winevent->ascii) return 1; if(kmitype!=KM_ANY) if(winevent->type!=kmitype) return 0; @@ -733,7 +743,7 @@ static int wm_eventmatch(wmEvent *winevent, wmKeymapItem *kmi) /* key modifiers always check when event has it */ /* otherwise regular keypresses with keymodifier still work */ if(winevent->keymodifier) - if(ISKEYBOARD(winevent->type)) + if(ISTEXTINPUT(winevent->type)) if(winevent->keymodifier!=kmi->keymodifier) return 0; return 1; @@ -895,9 +905,7 @@ static int wm_handler_fileselect_call(bContext *C, ListBase *handlers, wmEventHa switch(event->val) { case EVT_FILESELECT_OPEN: case EVT_FILESELECT_FULL_OPEN: - { - char *dir= NULL; char *path= RNA_string_get_alloc(handler->op->ptr, "filename", NULL, 0); - + { if(event->val==EVT_FILESELECT_OPEN) ED_area_newspace(C, handler->op_area, SPACE_FILE); else @@ -908,8 +916,6 @@ static int wm_handler_fileselect_call(bContext *C, ListBase *handlers, wmEventHa sfile->op= handler->op; ED_fileselect_set_params(sfile); - dir = NULL; - MEM_freeN(path); action= WM_HANDLER_BREAK; } @@ -920,7 +926,7 @@ static int wm_handler_fileselect_call(bContext *C, ListBase *handlers, wmEventHa { /* XXX validate area and region? */ bScreen *screen= CTX_wm_screen(C); - char *path= RNA_string_get_alloc(handler->op->ptr, "filename", NULL, 0); + char *path= RNA_string_get_alloc(handler->op->ptr, "path", NULL, 0); if(screen != handler->filescreen) ED_screen_full_prevspace(C); @@ -937,7 +943,7 @@ static int wm_handler_fileselect_call(bContext *C, ListBase *handlers, wmEventHa /* XXX also extension code in image-save doesnt work for this yet */ if(strncmp(handler->op->type->name, "Save", 4)==0) { /* this gives ownership to pupmenu */ - uiPupMenuSaveOver(C, handler->op, path); + uiPupMenuSaveOver(C, handler->op, (path)? path: ""); } else { int retval= handler->op->type->exec(C, handler->op); @@ -955,7 +961,8 @@ static int wm_handler_fileselect_call(bContext *C, ListBase *handlers, wmEventHa WM_operator_free(handler->op); wm_event_free_handler(handler); - MEM_freeN(path); + if(path) + MEM_freeN(path); action= WM_HANDLER_BREAK; } @@ -998,7 +1005,7 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers) int always_pass; if(handlers==NULL) return action; - + /* modal handlers can get removed in this loop, we keep the loop this way */ for(handler= handlers->first; handler; handler= nexthandler) { nexthandler= handler->next; @@ -1013,16 +1020,19 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers) action= WM_HANDLER_BREAK; if(handler->keymap) { + wmKeyMap *keymap= handler->keymap; wmKeymapItem *kmi; - for(kmi= handler->keymap->first; kmi; kmi= kmi->next) { - if(wm_eventmatch(event, kmi)) { - - event->keymap_idname= kmi->idname; /* weak, but allows interactive callback to not use rawkey */ - - action= wm_handler_operator_call(C, handlers, handler, event, kmi->ptr); - if(action==WM_HANDLER_BREAK) /* not wm_event_always_pass(event) here, it denotes removed handler */ - break; + if(!keymap->poll || keymap->poll(C)) { + for(kmi= keymap->keymap.first; kmi; kmi= kmi->next) { + if(wm_eventmatch(event, kmi)) { + + event->keymap_idname= kmi->idname; /* weak, but allows interactive callback to not use rawkey */ + + action= wm_handler_operator_call(C, handlers, handler, event, kmi->ptr); + if(action==WM_HANDLER_BREAK) /* not always_pass here, it denotes removed handler */ + break; + } } } } @@ -1038,8 +1048,12 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers) action= wm_handler_operator_call(C, handlers, handler, event, NULL); } - if(!always_pass && action==WM_HANDLER_BREAK) - break; + if(action==WM_HANDLER_BREAK) { + if(always_pass) + action= WM_HANDLER_CONTINUE; + else + break; + } } /* fileread case */ @@ -1051,6 +1065,8 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers) static int wm_event_inside_i(wmEvent *event, rcti *rect) { + if(wm_event_always_pass(event)) + return 1; if(BLI_in_rcti(rect, event->x, event->y)) return 1; if(event->type==MOUSEMOVE) { @@ -1142,7 +1158,7 @@ void wm_event_do_handlers(bContext *C) while( (event= win->queue.first) ) { int action; - + CTX_wm_window_set(C, win); /* we let modal handlers get active area/region, also wm_paintcursor_test needs it */ @@ -1152,61 +1168,73 @@ void wm_event_do_handlers(bContext *C) /* MVC demands to not draw in event handlers... but we need to leave it for ogl selecting etc */ wm_window_make_drawable(C, win); - action= wm_handlers_do(C, event, &win->handlers); + /* first we do priority handlers, modal + some limited keymaps */ + action= wm_handlers_do(C, event, &win->modalhandlers); /* fileread case */ - if(CTX_wm_window(C)==NULL) { + if(CTX_wm_window(C)==NULL) return; - } /* builtin tweak, if action is break it removes tweak */ - if(!wm_event_always_pass(event)) - wm_tweakevent_test(C, event, action); - - if(wm_event_always_pass(event) || action==WM_HANDLER_CONTINUE) { + wm_tweakevent_test(C, event, action); + + if(action==WM_HANDLER_CONTINUE) { ScrArea *sa; ARegion *ar; int doit= 0; /* XXX to solve, here screen handlers? */ - if(!wm_event_always_pass(event)) { - if(event->type==MOUSEMOVE) { - /* state variables in screen, cursors */ - ED_screen_set_subwinactive(win, event); - /* for regions having custom cursors */ - wm_paintcursor_test(C, event); - } + if(event->type==MOUSEMOVE) { + /* state variables in screen, cursors */ + ED_screen_set_subwinactive(win, event); + /* for regions having custom cursors */ + wm_paintcursor_test(C, event); } - + for(sa= win->screen->areabase.first; sa; sa= sa->next) { - if(wm_event_always_pass(event) || wm_event_inside_i(event, &sa->totrct)) { - + if(wm_event_inside_i(event, &sa->totrct)) { CTX_wm_area_set(C, sa); - CTX_wm_region_set(C, NULL); - action= wm_handlers_do(C, event, &sa->handlers); - if(wm_event_always_pass(event) || action==WM_HANDLER_CONTINUE) { + if(action==WM_HANDLER_CONTINUE) { for(ar=sa->regionbase.first; ar; ar= ar->next) { - if(wm_event_always_pass(event) || wm_event_inside_i(event, &ar->winrct)) { + if(wm_event_inside_i(event, &ar->winrct)) { CTX_wm_region_set(C, ar); action= wm_handlers_do(C, event, &ar->handlers); doit |= (BLI_in_rcti(&ar->winrct, event->x, event->y)); - if(!wm_event_always_pass(event)) { - if(action==WM_HANDLER_BREAK) - break; - } + if(action==WM_HANDLER_BREAK) + break; } } } + + CTX_wm_region_set(C, NULL); + + if(action==WM_HANDLER_CONTINUE) + action= wm_handlers_do(C, event, &sa->handlers); + + CTX_wm_area_set(C, NULL); + /* NOTE: do not escape on WM_HANDLER_BREAK, mousemove needs handled for previous area */ } } + if(action==WM_HANDLER_CONTINUE) { + /* also some non-modal handlers need active area/region */ + CTX_wm_area_set(C, area_event_inside(C, event->x, event->y)); + CTX_wm_region_set(C, region_event_inside(C, event->x, event->y)); + + action= wm_handlers_do(C, event, &win->handlers); + + /* fileread case */ + if(CTX_wm_window(C)==NULL) + return; + } + /* XXX hrmf, this gives reliable previous mouse coord for area change, feels bad? doing it on ghost queue gives errors when mousemoves go over area borders */ - if(doit && win->screen->subwinactive != win->screen->mainwin) { + if(doit && win->screen && win->screen->subwinactive != win->screen->mainwin) { win->eventstate->prevx= event->x; win->eventstate->prevy= event->y; } @@ -1219,7 +1247,7 @@ void wm_event_do_handlers(bContext *C) } /* only add mousemove when queue was read entirely */ - if(win->addmousemove) { + if(win->addmousemove && win->eventstate) { wmEvent event= *(win->eventstate); event.type= MOUSEMOVE; event.prevx= event.x; @@ -1250,7 +1278,7 @@ void WM_event_fileselect_event(bContext *C, void *ophandle, int eventval) } } -/* operator is supposed to have a filled "filename" property */ +/* operator is supposed to have a filled "path" property */ /* optional property: filetype (XXX enum?) */ /* Idea is to keep a handler alive on window queue, owning the operator. @@ -1270,7 +1298,7 @@ void WM_event_add_fileselect(bContext *C, wmOperator *op) handler->op_region= CTX_wm_region(C); handler->filescreen= CTX_wm_screen(C); - BLI_addhead(&win->handlers, handler); + BLI_addhead(&win->modalhandlers, handler); WM_event_fileselect_event(C, op, full?EVT_FILESELECT_FULL_OPEN:EVT_FILESELECT_OPEN); } @@ -1281,9 +1309,10 @@ void WM_event_set_handler_flag(wmEventHandler *handler, int flag) handler->flag= flag; } -wmEventHandler *WM_event_add_modal_handler(bContext *C, ListBase *handlers, wmOperator *op) +wmEventHandler *WM_event_add_modal_handler(bContext *C, wmOperator *op) { wmEventHandler *handler= MEM_callocN(sizeof(wmEventHandler), "event modal handler"); + wmWindow *win= CTX_wm_window(C); /* operator was part of macro */ if(op->opm) { @@ -1298,15 +1327,20 @@ wmEventHandler *WM_event_add_modal_handler(bContext *C, ListBase *handlers, wmOp handler->op_area= CTX_wm_area(C); /* means frozen screen context for modal handlers! */ handler->op_region= CTX_wm_region(C); - BLI_addhead(handlers, handler); + BLI_addhead(&win->modalhandlers, handler); return handler; } -wmEventHandler *WM_event_add_keymap_handler(ListBase *handlers, ListBase *keymap) +wmEventHandler *WM_event_add_keymap_handler(ListBase *handlers, wmKeyMap *keymap) { wmEventHandler *handler; + if(!keymap) { + printf("WM_event_add_keymap_handler called with NULL keymap\n"); + return NULL; + } + /* only allow same keymap once */ for(handler= handlers->first; handler; handler= handler->next) if(handler->keymap==keymap) @@ -1320,7 +1354,7 @@ wmEventHandler *WM_event_add_keymap_handler(ListBase *handlers, ListBase *keymap } /* priorities not implemented yet, for time being just insert in begin of list */ -wmEventHandler *WM_event_add_keymap_handler_priority(ListBase *handlers, ListBase *keymap, int priority) +wmEventHandler *WM_event_add_keymap_handler_priority(ListBase *handlers, wmKeyMap *keymap, int priority) { wmEventHandler *handler; @@ -1333,7 +1367,7 @@ wmEventHandler *WM_event_add_keymap_handler_priority(ListBase *handlers, ListBas return handler; } -wmEventHandler *WM_event_add_keymap_handler_bb(ListBase *handlers, ListBase *keymap, rcti *bblocal, rcti *bbwin) +wmEventHandler *WM_event_add_keymap_handler_bb(ListBase *handlers, wmKeyMap *keymap, rcti *bblocal, rcti *bbwin) { wmEventHandler *handler= WM_event_add_keymap_handler(handlers, keymap); @@ -1344,7 +1378,7 @@ wmEventHandler *WM_event_add_keymap_handler_bb(ListBase *handlers, ListBase *key return handler; } -void WM_event_remove_keymap_handler(ListBase *handlers, ListBase *keymap) +void WM_event_remove_keymap_handler(ListBase *handlers, wmKeyMap *keymap) { wmEventHandler *handler; @@ -1497,10 +1531,10 @@ static void update_tablet_data(wmWindow *win, wmEvent *event) const GHOST_TabletData *td= GHOST_GetTabletData(win->ghostwin); /* if there's tablet data from an active tablet device then add it */ - if ((td != NULL) && td->Active) { + if ((td != NULL) && td->Active != GHOST_kTabletModeNone) { struct wmTabletData *wmtab= MEM_mallocN(sizeof(wmTabletData), "customdata tablet"); - wmtab->Active = td->Active; + wmtab->Active = (int)td->Active; wmtab->Pressure = td->Pressure; wmtab->Xtilt = td->Xtilt; wmtab->Ytilt = td->Ytilt; @@ -1542,12 +1576,16 @@ void wm_event_add_ghostevent(wmWindow *win, int type, void *customdata) case GHOST_kEventButtonDown: case GHOST_kEventButtonUp: { GHOST_TEventButtonData *bd= customdata; - event.val= (type==GHOST_kEventButtonDown); + event.val= (type==GHOST_kEventButtonDown) ? KM_PRESS:KM_RELEASE; /* Note!, this starts as 0/1 but later is converted to KM_PRESS/KM_RELEASE by tweak */ if (bd->button == GHOST_kButtonMaskLeft) event.type= LEFTMOUSE; else if (bd->button == GHOST_kButtonMaskRight) event.type= RIGHTMOUSE; + else if (bd->button == GHOST_kButtonMaskButton4) + event.type= BUTTON4MOUSE; + else if (bd->button == GHOST_kButtonMaskButton5) + event.type= BUTTON5MOUSE; else event.type= MIDDLEMOUSE; @@ -1565,7 +1603,7 @@ void wm_event_add_ghostevent(wmWindow *win, int type, void *customdata) event.val= (type==GHOST_kEventKeyDown)?KM_PRESS:KM_RELEASE; /* exclude arrow keys, esc, etc from text input */ - if(type==GHOST_kEventKeyUp || (event.ascii<32 && event.ascii>14)) + if(type==GHOST_kEventKeyUp || (event.ascii<32 && event.ascii>0)) event.ascii= '\0'; /* modifiers */ @@ -1595,6 +1633,13 @@ void wm_event_add_ghostevent(wmWindow *win, int type, void *customdata) else if(event.val==KM_RELEASE && event.keymodifier==event.type) event.keymodifier= evt->keymodifier= 0; } + + /* this case happens on some systems that on holding a key pressed, + generate press events without release, we still want to keep the + modifier in win->eventstate, but for the press event of the same + key we don't want the key modifier */ + if(event.keymodifier == event.type) + event.keymodifier= 0; /* if test_break set, it catches this. XXX Keep global for now? */ if(event.type==ESCKEY) diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 9694a8fa1c6..1aca9a66e57 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -195,6 +195,7 @@ static void wm_window_match_do(bContext *C, ListBase *oldwmlist) /* ensure making new keymaps and set space types */ wm->initialized= 0; + wm->winactive= NULL; /* only first wm in list has ghostwins */ for(win= wm->windows.first; win; win= win->next) { @@ -202,6 +203,10 @@ static void wm_window_match_do(bContext *C, ListBase *oldwmlist) if(oldwin->winid == win->winid ) { win->ghostwin= oldwin->ghostwin; + win->active= oldwin->active; + if(win->active) + wm->winactive= win; + GHOST_SetWindowUserData(win->ghostwin, win); /* pointer back */ oldwin->ghostwin= NULL; diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index b2cdddf5b63..b4328d12e81 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -78,7 +78,7 @@ #include "ED_armature.h" #include "ED_keyframing.h" #include "ED_node.h" -#include "ED_previewrender.h" +#include "ED_render.h" #include "ED_space_api.h" #include "ED_screen.h" #include "ED_util.h" @@ -90,6 +90,7 @@ #include "GPU_extensions.h" #include "GPU_draw.h" +#include "BKE_depsgraph.h" #include "BKE_sound.h" static void wm_init_reports(bContext *C) @@ -113,6 +114,7 @@ void WM_init(bContext *C) set_free_windowmanager_cb(wm_close_and_free); /* library.c */ set_blender_test_break_cb(wm_window_testbreak); /* blender.c */ + DAG_editors_update_cb(ED_render_id_flush_update); /* depsgraph.c */ ED_spacetypes_init(); /* editors/space_api/spacetype.c */ @@ -129,6 +131,8 @@ void WM_init(bContext *C) wm_init_reports(C); /* reports cant be initialized before the wm */ + GPU_extensions_init(); + UI_init(); // clear_matcopybuf(); /* XXX */ @@ -139,8 +143,6 @@ void WM_init(bContext *C) ED_preview_init_dbase(); - GPU_extensions_init(); - G.ndofdevice = -1; /* XXX bad initializer, needs set otherwise buttons show! */ read_Blog(); @@ -167,6 +169,7 @@ extern wchar_t *copybufinfo; // XXX copy/paste buffer stuff... extern void free_anim_copybuf(); +extern void free_anim_drivers_copybuf(); extern void free_posebuf(); /* called in creator.c even... tsk, split this! */ @@ -187,6 +190,7 @@ void WM_exit(bContext *C) CTX_wm_window_set(C, win); /* needed by operator close callbacks */ WM_event_remove_handlers(C, &win->handlers); + WM_event_remove_handlers(C, &win->modalhandlers); ED_screen_exit(C, win, win->screen); } } @@ -213,6 +217,7 @@ void WM_exit(bContext *C) free_blender(); /* blender.c, does entire library and spacetypes */ // free_matcopybuf(); free_anim_copybuf(); + free_anim_drivers_copybuf(); free_posebuf(); // free_vertexpaint(); // free_imagepaint(); diff --git a/source/blender/windowmanager/intern/wm_jobs.c b/source/blender/windowmanager/intern/wm_jobs.c index bef3268920d..9e16ce4082f 100644 --- a/source/blender/windowmanager/intern/wm_jobs.c +++ b/source/blender/windowmanager/intern/wm_jobs.c @@ -107,6 +107,7 @@ struct wmJob { /* internal */ void *owner; + int flag; short suspended, running, ready, do_update, stop; /* once running, we store this separately */ @@ -123,7 +124,7 @@ struct wmJob { /* returns current or adds new job, but doesnt run it */ /* every owner only gets a single job, adding a new one will stop running stop and when stopped it starts the new one */ -wmJob *WM_jobs_get(wmWindowManager *wm, wmWindow *win, void *owner) +wmJob *WM_jobs_get(wmWindowManager *wm, wmWindow *win, void *owner, int flag) { wmJob *steve; @@ -137,6 +138,7 @@ wmJob *WM_jobs_get(wmWindowManager *wm, wmWindow *win, void *owner) BLI_addtail(&wm->jobs, steve); steve->win= win; steve->owner= owner; + steve->flag= flag; } return steve; @@ -198,20 +200,25 @@ static void *do_job_thread(void *job_v) } /* dont allow same startjob to be executed twice */ -static void wm_jobs_test_suspend(wmWindowManager *wm, wmJob *test) +static void wm_jobs_test_suspend_stop(wmWindowManager *wm, wmJob *test) { wmJob *steve; + int suspend= 0; - for(steve= wm->jobs.first; steve; steve= steve->next) - if(steve!=test) - if(steve->running) - if(steve->startjob==test->startjob) - break; - - if(steve) - test->suspended= 1; - else - test->suspended= 0; + for(steve= wm->jobs.first; steve; steve= steve->next) { + if(steve==test || !steve->running) continue; + if(steve->startjob!=test->startjob && !(test->flag & WM_JOB_EXCL_RENDER)) continue; + if((test->flag & WM_JOB_EXCL_RENDER) && !(steve->flag & WM_JOB_EXCL_RENDER)) continue; + + suspend= 1; + + /* if this job has higher priority, stop others */ + if(test->flag & WM_JOB_PRIORITY) + steve->stop= 1; + } + + /* possible suspend ourselfs, waiting for other jobs, or de-suspend */ + test->suspended= suspend; } /* if job running, the same owner gave it a new job */ @@ -225,7 +232,7 @@ void WM_jobs_start(wmWindowManager *wm, wmJob *steve) else { if(steve->customdata && steve->startjob) { - wm_jobs_test_suspend(wm, steve); + wm_jobs_test_suspend_stop(wm, steve); if(steve->suspended==0) { /* copy to ensure proper free in end */ diff --git a/source/blender/windowmanager/intern/wm_keymap.c b/source/blender/windowmanager/intern/wm_keymap.c index 5566aeba260..7d25fb8172e 100644 --- a/source/blender/windowmanager/intern/wm_keymap.c +++ b/source/blender/windowmanager/intern/wm_keymap.c @@ -96,17 +96,17 @@ static void keymap_properties_set(wmKeymapItem *kmi) } /* if item was added, then bail out */ -wmKeymapItem *WM_keymap_verify_item(ListBase *lb, char *idname, short type, short val, int modifier, short keymodifier) +wmKeymapItem *WM_keymap_verify_item(wmKeyMap *keymap, char *idname, short type, short val, int modifier, short keymodifier) { wmKeymapItem *kmi; - for(kmi= lb->first; kmi; kmi= kmi->next) + for(kmi= keymap->keymap.first; kmi; kmi= kmi->next) if(strncmp(kmi->idname, idname, OP_MAX_TYPENAME)==0) break; if(kmi==NULL) { kmi= MEM_callocN(sizeof(wmKeymapItem), "keymap entry"); - BLI_addtail(lb, kmi); + BLI_addtail(&keymap->keymap, kmi); BLI_strncpy(kmi->idname, idname, OP_MAX_TYPENAME); keymap_event_set(kmi, type, val, modifier, keymodifier); @@ -116,11 +116,11 @@ wmKeymapItem *WM_keymap_verify_item(ListBase *lb, char *idname, short type, shor } /* always add item */ -wmKeymapItem *WM_keymap_add_item(ListBase *lb, char *idname, short type, short val, int modifier, short keymodifier) +wmKeymapItem *WM_keymap_add_item(wmKeyMap *keymap, char *idname, short type, short val, int modifier, short keymodifier) { wmKeymapItem *kmi= MEM_callocN(sizeof(wmKeymapItem), "keymap entry"); - BLI_addtail(lb, kmi); + BLI_addtail(&keymap->keymap, kmi); BLI_strncpy(kmi->idname, idname, OP_MAX_TYPENAME); keymap_event_set(kmi, type, val, modifier, keymodifier); @@ -134,14 +134,14 @@ wmKeymapItem *WM_keymap_add_item(ListBase *lb, char *idname, short type, short v space/region ids are same as DNA_space_types.h */ /* gets free'd in wm.c */ -static wmKeyMap *wm_keymap_add(wmWindowManager *wm, const char *nameid, short spaceid, short regionid) +wmKeyMap *WM_keymap_find(wmWindowManager *wm, const char *nameid, short spaceid, short regionid) { wmKeyMap *km; for(km= wm->keymaps.first; km; km= km->next) if(km->spaceid==spaceid && km->regionid==regionid) if(0==strncmp(nameid, km->nameid, KMAP_MAX_NAME)) - break; + return km; if(km==NULL) { km= MEM_callocN(sizeof(struct wmKeyMap), "keymap list"); @@ -154,19 +154,13 @@ static wmKeyMap *wm_keymap_add(wmWindowManager *wm, const char *nameid, short sp return km; } -ListBase *WM_keymap_listbase(wmWindowManager *wm, const char *nameid, short spaceid, short regionid) -{ - wmKeyMap *km= wm_keymap_add(wm, nameid, spaceid, regionid); - return &km->keymap; -} - /* ****************** modal keymaps ************ */ /* modal maps get linked to a running operator, and filter the keys before sending to modal() callback */ wmKeyMap *WM_modalkeymap_add(wmWindowManager *wm, const char *nameid, EnumPropertyItem *items) { - wmKeyMap *km= wm_keymap_add(wm, nameid, 0, 0); + wmKeyMap *km= WM_keymap_find(wm, nameid, 0, 0); km->is_modal= 1; km->items= items; @@ -242,15 +236,18 @@ static char *wm_keymap_item_to_string(wmKeymapItem *kmi, char *str, int len) return str; } -static wmKeymapItem *wm_keymap_item_find_handlers(ListBase *handlers, const char *opname, int opcontext, IDProperty *properties, int compare_props) +static wmKeymapItem *wm_keymap_item_find_handlers(const bContext *C, ListBase *handlers, const char *opname, int opcontext, IDProperty *properties, int compare_props) { wmEventHandler *handler; + wmKeyMap *keymap; wmKeymapItem *kmi; /* find keymap item in handlers */ for(handler=handlers->first; handler; handler=handler->next) { - if(handler->keymap) { - for(kmi=handler->keymap->first; kmi; kmi=kmi->next) { + keymap= handler->keymap; + + if(keymap && (!keymap->poll || keymap->poll((bContext*)C))) { + for(kmi=keymap->keymap.first; kmi; kmi=kmi->next) { if(strcmp(kmi->idname, opname) == 0 && WM_key_event_string(kmi->type)[0]) { if(compare_props) { if(kmi->ptr && IDP_EqualsProperties(properties, kmi->ptr->data)) @@ -272,11 +269,11 @@ static wmKeymapItem *wm_keymap_item_find(const bContext *C, const char *opname, /* look into multiple handler lists to find the item */ if(CTX_wm_window(C)) - found= wm_keymap_item_find_handlers(&CTX_wm_window(C)->handlers, opname, opcontext, properties, compare_props); + found= wm_keymap_item_find_handlers(C, &CTX_wm_window(C)->handlers, opname, opcontext, properties, compare_props); if(CTX_wm_area(C) && found==NULL) - found= wm_keymap_item_find_handlers(&CTX_wm_area(C)->handlers, opname, opcontext, properties, compare_props); + found= wm_keymap_item_find_handlers(C, &CTX_wm_area(C)->handlers, opname, opcontext, properties, compare_props); if(found==NULL) { if(ELEM(opcontext, WM_OP_EXEC_REGION_WIN, WM_OP_INVOKE_REGION_WIN)) { @@ -287,12 +284,12 @@ static wmKeymapItem *wm_keymap_item_find(const bContext *C, const char *opname, break; if(ar) - found= wm_keymap_item_find_handlers(&ar->handlers, opname, opcontext, properties, compare_props); + found= wm_keymap_item_find_handlers(C, &ar->handlers, opname, opcontext, properties, compare_props); } } else { if(CTX_wm_region(C)) - found= wm_keymap_item_find_handlers(&CTX_wm_region(C)->handlers, opname, opcontext, properties, compare_props); + found= wm_keymap_item_find_handlers(C, &CTX_wm_region(C)->handlers, opname, opcontext, properties, compare_props); } } diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index 37cd424ac18..2c124437eb2 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -34,6 +34,7 @@ #include <stdio.h> #include "DNA_ID.h" +#include "DNA_object_types.h" #include "DNA_screen_types.h" #include "DNA_scene_types.h" #include "DNA_userdef_types.h" @@ -46,12 +47,16 @@ #include "BLI_blenlib.h" #include "BLI_dynstr.h" /*for WM_operator_pystring */ +#include "BLO_readfile.h" + #include "BKE_blender.h" #include "BKE_context.h" +#include "BKE_depsgraph.h" #include "BKE_idprop.h" #include "BKE_library.h" #include "BKE_global.h" #include "BKE_main.h" +#include "BKE_report.h" #include "BKE_scene.h" #include "BKE_utildefines.h" @@ -242,7 +247,7 @@ wmOperatorType *WM_operatortype_append_macro(char *idname, char *name, int flag) ot->idname= idname; ot->name= name; - ot->flag= OPTYPE_MACRO | flag; + ot->flag= OPTYPE_MACRO|flag; ot->exec= wm_macro_exec; ot->invoke= wm_macro_invoke; @@ -496,10 +501,10 @@ int WM_operator_confirm(bContext *C, wmOperator *op, wmEvent *event) return OPERATOR_CANCELLED; } -/* op->invoke, opens fileselect if filename property not set, otherwise executes */ +/* op->invoke, opens fileselect if path property not set, otherwise executes */ int WM_operator_filesel(bContext *C, wmOperator *op, wmEvent *event) { - if (RNA_property_is_set(op->ptr, "filename")) { + if (RNA_property_is_set(op->ptr, "path")) { return WM_operator_call(C, op); } else { @@ -509,9 +514,11 @@ int WM_operator_filesel(bContext *C, wmOperator *op, wmEvent *event) } /* default properties for fileselect */ -void WM_operator_properties_filesel(wmOperatorType *ot, int filter) +void WM_operator_properties_filesel(wmOperatorType *ot, int filter, short type) { - RNA_def_string_file_path(ot->srna, "filename", "", FILE_MAX, "Filename", "Path to file."); + RNA_def_string_file_path(ot->srna, "path", "", FILE_MAX, "FilePath", "Path to file."); + RNA_def_string_file_name(ot->srna, "filename", "", FILE_MAX, "FileName", "Name of the file."); + RNA_def_string_dir_path(ot->srna, "directory", "", FILE_MAX, "Directory", "Directory of the file."); RNA_def_boolean(ot->srna, "filter_blender", (filter & BLENDERFILE), "Filter .blend files", ""); RNA_def_boolean(ot->srna, "filter_image", (filter & IMAGEFILE), "Filter image files", ""); @@ -521,6 +528,10 @@ void WM_operator_properties_filesel(wmOperatorType *ot, int filter) RNA_def_boolean(ot->srna, "filter_sound", (filter & SOUNDFILE), "Filter sound files", ""); RNA_def_boolean(ot->srna, "filter_text", (filter & TEXTFILE), "Filter text files", ""); RNA_def_boolean(ot->srna, "filter_folder", (filter & FOLDERFILE), "Filter folders", ""); + + RNA_def_int(ot->srna, "filemode", type, FILE_LOADLIB, FILE_SPECIAL, + "File Browser Mode", "The setting for the file browser mode to load a .blend file, a library or a special file.", + FILE_LOADLIB, FILE_SPECIAL); } /* op->poll */ @@ -531,7 +542,7 @@ int WM_operator_winactive(bContext *C) } /* op->invoke */ -static void redo_cb(bContext *C, void *arg_op, void *arg2) +static void redo_cb(bContext *C, void *arg_op, int event) { wmOperator *lastop= arg_op; @@ -553,7 +564,7 @@ static uiBlock *wm_block_create_redo(bContext *C, ARegion *ar, void *arg_op) block= uiBeginBlock(C, ar, "redo_popup", UI_EMBOSS); uiBlockClearFlag(block, UI_BLOCK_LOOP); uiBlockSetFlag(block, UI_BLOCK_KEEP_OPEN|UI_BLOCK_RET_1); - uiBlockSetFunc(block, redo_cb, arg_op, NULL); + uiBlockSetHandleFunc(block, redo_cb, arg_op); if(!op->properties) { IDPropertyTemplate val = {0}; @@ -671,7 +682,7 @@ static void operator_search_cb(const struct bContext *C, void *arg, char *str, u for(; ot; ot= ot->next) { if(BLI_strcasestr(ot->name, str)) { - if(ot->poll==NULL || ot->poll((bContext *)C)) { + if(WM_operator_poll((bContext*)C, ot)) { char name[256]; int len= strlen(ot->name); @@ -736,11 +747,12 @@ static int wm_search_menu_invoke(bContext *C, wmOperator *op, wmEvent *event) } /* op->poll */ -int wm_search_menu_poll(bContext *C) +static int wm_search_menu_poll(bContext *C) { if(CTX_wm_window(C)==NULL) return 0; if(CTX_wm_area(C) && CTX_wm_area(C)->spacetype==SPACE_CONSOLE) return 0; // XXX - so we can use the shortcut in the console if(CTX_wm_area(C) && CTX_wm_area(C)->spacetype==SPACE_TEXT) return 0; // XXX - so we can use the spacebar in the text editor + if(CTX_data_edit_object(C) && CTX_data_edit_object(C)->type==OB_CURVE) return 0; // XXX - so we can use the spacebar for entering text return 1; } @@ -869,21 +881,9 @@ static void WM_OT_open_recentfile(wmOperatorType *ot) RNA_def_enum_funcs(prop, open_recentfile_itemf); } -/* ********* main file *********** */ +/* *************** open file **************** */ -static void untitled(char *name) -{ - if (G.save_over == 0 && strlen(name) < FILE_MAX-16) { - char *c= BLI_last_slash(name); - - if (c) - strcpy(&c[1], "untitled.blend"); - else - strcpy(name, "untitled.blend"); - } -} - -static void load_set_load_ui(wmOperator *op) +static void open_set_load_ui(wmOperator *op) { if(!RNA_property_is_set(op->ptr, "load_ui")) RNA_boolean_set(op->ptr, "load_ui", !(U.flag & USER_FILENOUI)); @@ -891,8 +891,8 @@ static void load_set_load_ui(wmOperator *op) static int wm_open_mainfile_invoke(bContext *C, wmOperator *op, wmEvent *event) { - RNA_string_set(op->ptr, "filename", G.sce); - load_set_load_ui(op); + RNA_string_set(op->ptr, "path", G.sce); + open_set_load_ui(op); WM_event_add_fileselect(C, op); @@ -901,10 +901,10 @@ static int wm_open_mainfile_invoke(bContext *C, wmOperator *op, wmEvent *event) static int wm_open_mainfile_exec(bContext *C, wmOperator *op) { - char filename[FILE_MAX]; + char path[FILE_MAX]; - RNA_string_get(op->ptr, "filename", filename); - load_set_load_ui(op); + RNA_string_get(op->ptr, "path", path); + open_set_load_ui(op); if(RNA_boolean_get(op->ptr, "load_ui")) G.fileflags &= ~G_FILE_NO_UI; @@ -915,7 +915,7 @@ static int wm_open_mainfile_exec(bContext *C, wmOperator *op) // do it before for now, but is this correct with multiple windows? WM_event_add_notifier(C, NC_WINDOW, NULL); - WM_read_file(C, filename, op->reports); + WM_read_file(C, path, op->reports); return 0; } @@ -930,11 +930,171 @@ static void WM_OT_open_mainfile(wmOperatorType *ot) ot->exec= wm_open_mainfile_exec; ot->poll= WM_operator_winactive; - WM_operator_properties_filesel(ot, FOLDERFILE|BLENDERFILE); + WM_operator_properties_filesel(ot, FOLDERFILE|BLENDERFILE, FILE_BLENDER); RNA_def_boolean(ot->srna, "load_ui", 1, "Load UI", "Load user interface setup in the .blend file."); } +/* **************** link/append *************** */ + +static int wm_link_append_invoke(bContext *C, wmOperator *op, wmEvent *event) +{ + if(RNA_property_is_set(op->ptr, "path")) { + return WM_operator_call(C, op); + } + else { + /* XXX TODO solve where to get last linked library from */ + RNA_string_set(op->ptr, "path", G.lib); + WM_event_add_fileselect(C, op); + return OPERATOR_RUNNING_MODAL; + } +} + +static short wm_link_append_flag(wmOperator *op) +{ + short flag= 0; + + if(RNA_boolean_get(op->ptr, "autoselect")) flag |= FILE_AUTOSELECT; + if(RNA_boolean_get(op->ptr, "active_layer")) flag |= FILE_ACTIVELAY; + if(RNA_boolean_get(op->ptr, "relative_paths")) flag |= FILE_STRINGCODE; + if(RNA_boolean_get(op->ptr, "link")) flag |= FILE_LINK; + + return flag; +} + +static void wm_link_make_library_local(Main *main, const char *libname) +{ + Library *lib; + + /* and now find the latest append lib file */ + for(lib= main->library.first; lib; lib=lib->id.next) + if(BLI_streq(libname, lib->filename)) + break; + + /* make local */ + if(lib) { + all_local(lib, 1); + /* important we unset, otherwise these object wont + * link into other scenes from this blend file */ + flag_all_listbases_ids(LIB_APPEND_TAG, 0); + } +} + +static int wm_link_append_exec(bContext *C, wmOperator *op) +{ + Main *bmain= CTX_data_main(C); + Scene *scene= CTX_data_scene(C); + Main *mainl= 0; + BlendHandle *bh; + PropertyRNA *prop; + char name[FILE_MAX], dir[FILE_MAX], libname[FILE_MAX], group[GROUP_MAX]; + int idcode, totfiles=0; + short flag; + + name[0] = '\0'; + RNA_string_get(op->ptr, "filename", name); + RNA_string_get(op->ptr, "directory", dir); + + /* test if we have a valid data */ + if(BLO_is_a_library(dir, libname, group) == 0) { + BKE_report(op->reports, RPT_ERROR, "Not a library"); + return OPERATOR_CANCELLED; + } + else if(group[0] == 0) { + BKE_report(op->reports, RPT_ERROR, "Nothing indicated"); + return OPERATOR_CANCELLED; + } + else if(BLI_streq(bmain->name, libname)) { + BKE_report(op->reports, RPT_ERROR, "Cannot use current file as library"); + return OPERATOR_CANCELLED; + } + + /* check if something is indicated for append/link */ + prop = RNA_struct_find_property(op->ptr, "files"); + if(prop) { + totfiles= RNA_property_collection_length(op->ptr, prop); + if(totfiles == 0) { + if(name[0] == '\0') { + BKE_report(op->reports, RPT_ERROR, "Nothing indicated"); + return OPERATOR_CANCELLED; + } + } + } + else if(name[0] == '\0') { + BKE_report(op->reports, RPT_ERROR, "Nothing indicated"); + return OPERATOR_CANCELLED; + } + + /* now we have or selected, or an indicated file */ + if(RNA_boolean_get(op->ptr, "autoselect")) + scene_deselect_all(scene); + + bh = BLO_blendhandle_from_file(libname); + idcode = BLO_idcode_from_name(group); + + flag = wm_link_append_flag(op); + + /* tag everything, all untagged data can be made local */ + if((flag & FILE_LINK)==0) + flag_all_listbases_ids(LIB_APPEND_TAG, 1); + + /* here appending/linking starts */ + mainl = BLO_library_append_begin(C, &bh, libname); + if(totfiles == 0) { + BLO_library_append_named_part(C, mainl, &bh, name, idcode, flag); + } + else { + RNA_BEGIN(op->ptr, itemptr, "files") { + RNA_string_get(&itemptr, "name", name); + BLO_library_append_named_part(C, mainl, &bh, name, idcode, flag); + } + RNA_END; + } + BLO_library_append_end(C, mainl, &bh, idcode, flag); + + /* mark all library linked objects to be updated */ + recalc_all_library_objects(bmain); + + /* append, rather than linking */ + if((flag & FILE_LINK)==0) + wm_link_make_library_local(bmain, libname); + + /* recreate dependency graph to include new objects */ + DAG_scene_sort(scene); + DAG_ids_flush_update(0); + + BLO_blendhandle_close(bh); + + /* XXX TODO: align G.lib with other directory storage (like last opened image etc...) */ + BLI_strncpy(G.lib, dir, FILE_MAX); + + WM_event_add_notifier(C, NC_WINDOW, NULL); + + return OPERATOR_FINISHED; +} + +static void WM_OT_link_append(wmOperatorType *ot) +{ + ot->name= "Link/Append from Library"; + ot->idname= "WM_OT_link_append"; + ot->description= "Link or Append from a Library .blend file"; + + ot->invoke= wm_link_append_invoke; + ot->exec= wm_link_append_exec; + ot->poll= WM_operator_winactive; + + WM_operator_properties_filesel(ot, FOLDERFILE|BLENDERFILE, FILE_LOADLIB); + + RNA_def_boolean(ot->srna, "link", 1, "Link", "Link the objects or datablocks rather than appending."); + RNA_def_boolean(ot->srna, "autoselect", 1, "Select", "Select the linked objects."); + RNA_def_boolean(ot->srna, "active_layer", 1, "Active Layer", "Put the linked objects on the active layer."); + RNA_def_boolean(ot->srna, "relative_paths", 1, "Relative Paths", "Store the library path as a relative path to current .blend file."); + + RNA_def_collection_runtime(ot->srna, "files", &RNA_OperatorFileListElement, "Files", ""); +} + +/* *************** recover last session **************** */ + static int wm_recover_last_session_exec(bContext *C, wmOperator *op) { char scestr[FILE_MAX], filename[FILE_MAX]; @@ -969,6 +1129,20 @@ static void WM_OT_recover_last_session(wmOperatorType *ot) ot->poll= WM_operator_winactive; } +/* *************** save file as **************** */ + +static void untitled(char *name) +{ + if(G.save_over == 0 && strlen(name) < FILE_MAX-16) { + char *c= BLI_last_slash(name); + + if(c) + strcpy(&c[1], "untitled.blend"); + else + strcpy(name, "untitled.blend"); + } +} + static void save_set_compress(wmOperator *op) { if(!RNA_property_is_set(op->ptr, "compress")) { @@ -987,7 +1161,7 @@ static int wm_save_as_mainfile_invoke(bContext *C, wmOperator *op, wmEvent *even BLI_strncpy(name, G.sce, FILE_MAX); untitled(name); - RNA_string_set(op->ptr, "filename", name); + RNA_string_set(op->ptr, "path", name); WM_event_add_fileselect(C, op); @@ -997,20 +1171,20 @@ static int wm_save_as_mainfile_invoke(bContext *C, wmOperator *op, wmEvent *even /* function used for WM_OT_save_mainfile too */ static int wm_save_as_mainfile_exec(bContext *C, wmOperator *op) { - char filename[FILE_MAX]; + char path[FILE_MAX]; int compress; save_set_compress(op); compress= RNA_boolean_get(op->ptr, "compress"); - if(RNA_property_is_set(op->ptr, "filename")) - RNA_string_get(op->ptr, "filename", filename); + if(RNA_property_is_set(op->ptr, "path")) + RNA_string_get(op->ptr, "path", path); else { - BLI_strncpy(filename, G.sce, FILE_MAX); - untitled(filename); + BLI_strncpy(path, G.sce, FILE_MAX); + untitled(path); } - WM_write_file(C, filename, compress, op->reports); + WM_write_file(C, path, compress, op->reports); WM_event_add_notifier(C, NC_WM|ND_FILESAVE, NULL); @@ -1027,11 +1201,11 @@ static void WM_OT_save_as_mainfile(wmOperatorType *ot) ot->exec= wm_save_as_mainfile_exec; ot->poll= WM_operator_winactive; - WM_operator_properties_filesel(ot, FOLDERFILE|BLENDERFILE); + WM_operator_properties_filesel(ot, FOLDERFILE|BLENDERFILE, FILE_BLENDER); RNA_def_boolean(ot->srna, "compress", 0, "Compress", "Write compressed .blend file."); } -/* *************** Save file directly ******** */ +/* *************** save file directly ******** */ static int wm_save_mainfile_invoke(bContext *C, wmOperator *op, wmEvent *event) { @@ -1041,7 +1215,7 @@ static int wm_save_mainfile_invoke(bContext *C, wmOperator *op, wmEvent *event) BLI_strncpy(name, G.sce, FILE_MAX); untitled(name); - RNA_string_set(op->ptr, "filename", name); + RNA_string_set(op->ptr, "path", name); uiPupMenuSaveOver(C, op, name); return OPERATOR_RUNNING_MODAL; @@ -1057,7 +1231,7 @@ static void WM_OT_save_mainfile(wmOperatorType *ot) ot->exec= wm_save_as_mainfile_exec; ot->poll= WM_operator_winactive; - WM_operator_properties_filesel(ot, FOLDERFILE|BLENDERFILE); + WM_operator_properties_filesel(ot, FOLDERFILE|BLENDERFILE, FILE_BLENDER); RNA_def_boolean(ot->srna, "compress", 0, "Compress", "Write compressed .blend file."); } @@ -1194,7 +1368,7 @@ int WM_border_select_invoke(bContext *C, wmOperator *op, wmEvent *event) op->customdata= WM_gesture_new(C, event, WM_GESTURE_CROSS_RECT); /* add modal handler */ - WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + WM_event_add_modal_handler(C, op); wm_gesture_tag_redraw(C); @@ -1258,7 +1432,7 @@ int WM_gesture_circle_invoke(bContext *C, wmOperator *op, wmEvent *event) op->customdata= WM_gesture_new(C, event, WM_GESTURE_CIRCLE); /* add modal handler */ - WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + WM_event_add_modal_handler(C, op); wm_gesture_tag_redraw(C); @@ -1311,7 +1485,7 @@ int WM_gesture_circle_modal(bContext *C, wmOperator *op, wmEvent *event) case LEFTMOUSE: case MIDDLEMOUSE: case RIGHTMOUSE: - if(event->val==0) { /* key release */ + if(event->val==KM_RELEASE) { /* key release */ wm_gesture_end(C, op); return OPERATOR_FINISHED; } @@ -1394,7 +1568,7 @@ static void tweak_gesture_modal(bContext *C, wmEvent *event) if(gesture->event_type==event->type) { WM_gesture_end(C, gesture); window->tweak= NULL; - + /* when tweak fails we should give the other keymap entries a chance */ event->val= KM_RELEASE; } @@ -1412,7 +1586,7 @@ void wm_tweakevent_test(bContext *C, wmEvent *event, int action) if(win->tweak==NULL) { if(CTX_wm_region(C)) { - if(event->val) { // pressed + if(event->val==KM_PRESS) { // pressed if( ELEM3(event->type, LEFTMOUSE, MIDDLEMOUSE, RIGHTMOUSE) ) win->tweak= WM_gesture_new(C, event, WM_GESTURE_TWEAK); } @@ -1435,7 +1609,7 @@ int WM_gesture_lasso_invoke(bContext *C, wmOperator *op, wmEvent *event) op->customdata= WM_gesture_new(C, event, WM_GESTURE_LASSO); /* add modal handler */ - WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + WM_event_add_modal_handler(C, op); wm_gesture_tag_redraw(C); @@ -1450,7 +1624,7 @@ int WM_gesture_lines_invoke(bContext *C, wmOperator *op, wmEvent *event) op->customdata= WM_gesture_new(C, event, WM_GESTURE_LINES); /* add modal handler */ - WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + WM_event_add_modal_handler(C, op); wm_gesture_tag_redraw(C); @@ -1512,7 +1686,7 @@ int WM_gesture_lasso_modal(bContext *C, wmOperator *op, wmEvent *event) case LEFTMOUSE: case MIDDLEMOUSE: case RIGHTMOUSE: - if(event->val==0) { /* key release */ + if(event->val==KM_RELEASE) { /* key release */ gesture_lasso_apply(C, op, event->type); return OPERATOR_FINISHED; } @@ -1757,7 +1931,7 @@ int WM_radial_control_invoke(bContext *C, wmOperator *op, wmEvent *event) wm_radial_control_paint, op->customdata); /* add modal handler */ - WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op); + WM_event_add_modal_handler(C, op); WM_radial_control_modal(C, op, event); @@ -1805,17 +1979,19 @@ void WM_OT_radial_control_partial(wmOperatorType *ot) /* uses no type defines, fully local testing function anyway... ;) */ -static int ten_timer_exec(bContext *C, wmOperator *op) +static int redraw_timer_exec(bContext *C, wmOperator *op) { ARegion *ar= CTX_wm_region(C); double stime= PIL_check_seconds_timer(); int type = RNA_int_get(op->ptr, "type"); - int a, time; - char tmpstr[128]; + int iter = RNA_int_get(op->ptr, "iterations"); + int a; + float time; + char *infostr= ""; WM_cursor_wait(1); - - for(a=0; a<10; a++) { + + for(a=0; a<iter; a++) { if (type==0) { ED_region_do_draw(C, ar); } @@ -1831,13 +2007,35 @@ static int ten_timer_exec(bContext *C, wmOperator *op) wmWindow *win= CTX_wm_window(C); ScrArea *sa; + ScrArea *sa_back= CTX_wm_area(C); + ARegion *ar_back= CTX_wm_region(C); + + for(sa= CTX_wm_screen(C)->areabase.first; sa; sa= sa->next) { + ARegion *ar_iter; + CTX_wm_area_set(C, sa); + + for(ar_iter= sa->regionbase.first; ar_iter; ar_iter= ar_iter->next) { + CTX_wm_region_set(C, ar_iter); + ED_region_do_draw(C, ar_iter); + } + } + + CTX_wm_window_set(C, win); /* XXX context manipulation warning! */ + + CTX_wm_area_set(C, sa_back); + CTX_wm_region_set(C, ar_back); + } + else if (type==3) { + wmWindow *win= CTX_wm_window(C); + ScrArea *sa; + for(sa= CTX_wm_screen(C)->areabase.first; sa; sa= sa->next) ED_area_tag_redraw(sa); wm_draw_update(C); CTX_wm_window_set(C, win); /* XXX context manipulation warning! */ } - else if (type==3) { + else if (type==4) { Scene *scene= CTX_data_scene(C); if(a & 1) scene->r.cfra--; @@ -1850,40 +2048,44 @@ static int ten_timer_exec(bContext *C, wmOperator *op) } } - time= (int) ((PIL_check_seconds_timer()-stime)*1000); + time= ((PIL_check_seconds_timer()-stime)*1000); - if(type==0) sprintf(tmpstr, "10 x Draw Region: %d ms", time); - if(type==1) sprintf(tmpstr, "10 x Draw Region and Swap: %d ms", time); - if(type==2) sprintf(tmpstr, "10 x Draw Window and Swap: %d ms", time); - if(type==3) sprintf(tmpstr, "Anim Step: %d ms", time); - if(type==4) sprintf(tmpstr, "10 x Undo/Redo: %d ms", time); + if(type==0) infostr= "Draw Region"; + if(type==1) infostr= "Draw Region and Swap"; + if(type==2) infostr= "Draw Window"; + if(type==3) infostr= "Draw Window and Swap"; + if(type==4) infostr= "Animation Steps"; + if(type==5) infostr= "Undo/Redo"; WM_cursor_wait(0); - uiPupMenuNotice(C, tmpstr); + BKE_reportf(op->reports, RPT_INFO, "%d x %s: %.2f ms, average: %.4f", iter, infostr, time, time/iter); return OPERATOR_FINISHED; } -static void WM_OT_ten_timer(wmOperatorType *ot) +static void WM_OT_redraw_timer(wmOperatorType *ot) { static EnumPropertyItem prop_type_items[] = { {0, "DRAW", 0, "Draw Region", ""}, - {1, "DRAWSWAP", 0, "Draw Region + Swap", ""}, - {2, "DRAWWINSWAP", 0, "Draw Window + Swap", ""}, - {3, "ANIMSTEP", 0, "Anim Step", ""}, - {4, "UNDO", 0, "Undo/Redo", ""}, + {1, "DRAW_SWAP", 0, "Draw Region + Swap", ""}, + {2, "DRAW_WIN", 0, "Draw Window", ""}, + {3, "DRAW_WIN_SWAP", 0, "Draw Window + Swap", ""}, + {4, "ANIM_STEP", 0, "Anim Step", ""}, + {5, "UNDO", 0, "Undo/Redo", ""}, {0, NULL, 0, NULL, NULL}}; - ot->name= "Ten Timer"; - ot->idname= "WM_OT_ten_timer"; + ot->name= "Redraw Timer"; + ot->idname= "WM_OT_redraw_timer"; + ot->description="Simple redraw timer to test the speed of updating the interface."; ot->description="Ten Timer operator."; ot->invoke= WM_menu_invoke; - ot->exec= ten_timer_exec; + ot->exec= redraw_timer_exec; ot->poll= WM_operator_winactive; RNA_def_enum(ot->srna, "type", prop_type_items, 0, "Type", ""); + RNA_def_int(ot->srna, "iterations", 10, 1,INT_MAX, "Iterations", "Number of times to redraw", 1,1000); } @@ -1913,11 +2115,12 @@ void wm_operatortype_init(void) WM_operatortype_append(WM_OT_exit_blender); WM_operatortype_append(WM_OT_open_recentfile); 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_save_as_mainfile); WM_operatortype_append(WM_OT_save_mainfile); - WM_operatortype_append(WM_OT_ten_timer); + WM_operatortype_append(WM_OT_redraw_timer); WM_operatortype_append(WM_OT_debug_menu); WM_operatortype_append(WM_OT_search_menu); } @@ -1925,7 +2128,7 @@ void wm_operatortype_init(void) /* default keymap for windows and screens, only call once per WM */ void wm_window_keymap(wmWindowManager *wm) { - ListBase *keymap= WM_keymap_listbase(wm, "Window", 0, 0); + wmKeyMap *keymap= WM_keymap_find(wm, "Window", 0, 0); /* items to make WM work */ WM_keymap_verify_item(keymap, "WM_OT_jobs_timer", TIMERJOBS, KM_ANY, KM_ANY, 0); @@ -1944,6 +2147,7 @@ void wm_window_keymap(wmWindowManager *wm) WM_keymap_add_item(keymap, "WM_OT_save_homefile", UKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "WM_OT_open_recentfile", OKEY, KM_PRESS, KM_SHIFT|KM_CTRL, 0); WM_keymap_add_item(keymap, "WM_OT_open_mainfile", OKEY, KM_PRESS, KM_CTRL, 0); + WM_keymap_add_item(keymap, "WM_OT_link_append", OKEY, KM_PRESS, KM_CTRL|KM_ALT, 0); WM_keymap_add_item(keymap, "WM_OT_save_mainfile", SKEY, KM_PRESS, KM_CTRL, 0); WM_keymap_add_item(keymap, "WM_OT_save_as_mainfile", SKEY, KM_PRESS, KM_SHIFT|KM_CTRL, 0); @@ -1951,7 +2155,7 @@ void wm_window_keymap(wmWindowManager *wm) WM_keymap_add_item(keymap, "WM_OT_exit_blender", QKEY, KM_PRESS, KM_CTRL, 0); /* debug/testing */ - WM_keymap_verify_item(keymap, "WM_OT_ten_timer", TKEY, KM_PRESS, KM_ALT|KM_CTRL, 0); + WM_keymap_verify_item(keymap, "WM_OT_redraw_timer", TKEY, KM_PRESS, KM_ALT|KM_CTRL, 0); WM_keymap_verify_item(keymap, "WM_OT_debug_menu", DKEY, KM_PRESS, KM_ALT|KM_CTRL, 0); WM_keymap_verify_item(keymap, "WM_OT_search_menu", SPACEKEY, KM_PRESS, 0, 0); diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index d70516ef02e..c853afe4507 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -146,6 +146,7 @@ void wm_window_free(bContext *C, wmWindow *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) { @@ -331,7 +332,7 @@ static void wm_window_add_ghostwindow(wmWindowManager *wm, char *title, wmWindow /* called in wm_check, also inits stuff after file read */ void wm_window_add_ghostwindows(wmWindowManager *wm) { - ListBase *keymap; + wmKeyMap *keymap; wmWindow *win; /* no commandline prefsize? then we set this */ @@ -367,11 +368,14 @@ void wm_window_add_ghostwindows(wmWindowManager *wm) win->eventstate= MEM_callocN(sizeof(wmEvent), "window event state"); /* add keymap handlers (1 handler for all keys in map!) */ - keymap= WM_keymap_listbase(wm, "Window", 0, 0); + keymap= WM_keymap_find(wm, "Window", 0, 0); WM_event_add_keymap_handler(&win->handlers, keymap); - keymap= WM_keymap_listbase(wm, "Screen", 0, 0); + keymap= WM_keymap_find(wm, "Screen", 0, 0); WM_event_add_keymap_handler(&win->handlers, keymap); + + keymap= WM_keymap_find(wm, "Screen Editing", 0, 0); + WM_event_add_keymap_handler(&win->modalhandlers, keymap); wm_window_title(wm, win); } @@ -623,6 +627,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr private) if(state!=GHOST_kWindowStateMinimized) { GHOST_RectangleHandle client_rect; int l, t, r, b, scr_w, scr_h; + int sizex, sizey, posx, posy; client_rect= GHOST_GetClientBounds(win->ghostwin); GHOST_GetRectangle(client_rect, &l, &t, &r, &b); @@ -630,37 +635,56 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr private) GHOST_DisposeRectangle(client_rect); wm_get_screensize(&scr_w, &scr_h); - win->sizex= r-l; - win->sizey= b-t; - win->posx= l; - win->posy= scr_h - t - win->sizey; - - /* debug prints */ - if(0) { - state = GHOST_GetWindowState(win->ghostwin); - - if(state==GHOST_kWindowStateNormal) { - if(G.f & G_DEBUG) printf("window state: normal\n"); - } - else if(state==GHOST_kWindowStateMinimized) { - if(G.f & G_DEBUG) printf("window state: minimized\n"); - } - else if(state==GHOST_kWindowStateMaximized) { - if(G.f & G_DEBUG) printf("window state: maximized\n"); + sizex= r-l; + sizey= b-t; + posx= l; + posy= scr_h - t - win->sizey; + + /* + * Ghost sometimes send size or move events when the window hasn't changed. + * One case of this is using compiz on linux. To alleviate the problem + * we ignore all such event here. + * + * It might be good to eventually do that at Ghost level, but that is for + * another time. + */ + if (win->sizex != sizex || + win->sizey != sizey || + win->posx != posx || + win->posy != posy) + { + win->sizex= sizex; + win->sizey= sizey; + win->posx= posx; + win->posy= posy; + + /* debug prints */ + if(0) { + state = GHOST_GetWindowState(win->ghostwin); + + if(state==GHOST_kWindowStateNormal) { + if(G.f & G_DEBUG) printf("window state: normal\n"); + } + else if(state==GHOST_kWindowStateMinimized) { + if(G.f & G_DEBUG) printf("window state: minimized\n"); + } + else if(state==GHOST_kWindowStateMaximized) { + if(G.f & G_DEBUG) printf("window state: maximized\n"); + } + else if(state==GHOST_kWindowStateFullScreen) { + if(G.f & G_DEBUG) printf("window state: fullscreen\n"); + } + + if(type!=GHOST_kEventWindowSize) { + if(G.f & G_DEBUG) printf("win move event pos %d %d size %d %d\n", win->posx, win->posy, win->sizex, win->sizey); + } + } - else if(state==GHOST_kWindowStateFullScreen) { - if(G.f & G_DEBUG) printf("window state: fullscreen\n"); - } - - if(type!=GHOST_kEventWindowSize) { - if(G.f & G_DEBUG) printf("win move event pos %d %d size %d %d\n", win->posx, win->posy, win->sizex, win->sizey); - } - + + wm_window_make_drawable(C, win); + wm_draw_window_clear(win); + WM_event_add_notifier(C, NC_SCREEN|NA_EDITED, NULL); } - - wm_window_make_drawable(C, win); - wm_draw_window_clear(win); - WM_event_add_notifier(C, NC_SCREEN|NA_EDITED, NULL); } break; } diff --git a/source/blender/windowmanager/wm_event_system.h b/source/blender/windowmanager/wm_event_system.h index 9a3bba9af1d..4360e49e371 100644 --- a/source/blender/windowmanager/wm_event_system.h +++ b/source/blender/windowmanager/wm_event_system.h @@ -43,7 +43,7 @@ typedef struct wmEventHandler { int type, flag; /* type default=0, rest is custom */ /* keymap handler */ - ListBase *keymap; /* pointer to builtin/custom keymaps */ + wmKeyMap *keymap; /* pointer to builtin/custom keymaps */ rcti *bblocal, *bbwin; /* optional local and windowspace bb */ diff --git a/source/blender/windowmanager/wm_event_types.h b/source/blender/windowmanager/wm_event_types.h index 3da621bda85..cc6041ce529 100644 --- a/source/blender/windowmanager/wm_event_types.h +++ b/source/blender/windowmanager/wm_event_types.h @@ -40,7 +40,7 @@ #define EVT_DATA_GESTURE 2 #define EVT_DATA_TIMER 3 -/* tablet active */ +/* tablet active, matches GHOST_TTabletMode */ #define EVT_TABLET_NONE 0 #define EVT_TABLET_STYLUS 1 #define EVT_TABLET_ERASER 2 @@ -56,6 +56,9 @@ /* only use if you want user option switch possible */ #define ACTIONMOUSE 0x005 #define SELECTMOUSE 0x006 +/* Extra mouse buttons */ +#define BUTTON4MOUSE 0x007 +#define BUTTON5MOUSE 0x008 /* defaults from ghost */ #define WHEELUPMOUSE 0x00a #define WHEELDOWNMOUSE 0x00b @@ -191,10 +194,13 @@ /* for event checks */ /* only used for KM_TEXTINPUT, so assume that we want all user-inputtable ascii codes included */ -#define ISKEYBOARD(event) (event >=' ' && event <=255) +#define ISTEXTINPUT(event) (event >=' ' && event <=255) + + /* test wether the event is a key on the keyboard */ +#define ISKEYBOARD(event) (event >=' ' && event <=320) /* test whether event type is acceptable as hotkey, excluding modifiers */ -#define ISHOTKEY(event) (event >=' ' && event <=320 && !(event>=LEFTCTRLKEY && event<=ESCKEY) && !(event>=UNKNOWNKEY && event<=GRLESSKEY)) +#define ISHOTKEY(event) (ISKEYBOARD(event) && !(event>=LEFTCTRLKEY && event<=ESCKEY) && !(event>=UNKNOWNKEY && event<=GRLESSKEY)) /* **************** BLENDER GESTURE EVENTS ********************* */ |