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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/windowmanager/intern/wm_event_system.c')
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c140
1 files changed, 101 insertions, 39 deletions
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index bb0ad54d967..af61b787462 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -121,23 +121,37 @@ void wm_event_do_notifiers(bContext *C)
for(win= C->wm->windows.first; win; win= win->next) {
ScrArea *sa;
+
+ C->window= win;
+ C->screen= win->screen;
if(note->window && note->window!=win)
continue;
if(win->screen==NULL)
continue;
+
printf("notifier win %d screen %s\n", win->winid, win->screen->id.name+2);
ED_screen_do_listen(win, note);
for(sa= win->screen->areabase.first; sa; sa= sa->next) {
ARegion *ar= sa->regionbase.first;
+ C->area= sa;
+
for(; ar; ar= ar->next) {
if(note->swinid && note->swinid!=ar->swinid)
continue;
+
+ C->region= ar;
ED_region_do_listen(ar, note);
+ C->region= NULL;
}
+
+ C->area= NULL;
}
+
+ C->window= NULL;
+ C->screen= NULL;
}
if(note->data)
MEM_freeN(note->data);
@@ -178,6 +192,9 @@ void wm_draw_update(bContext *C)
for(win= C->wm->windows.first; win; win= win->next) {
if(wm_draw_update_test_window(win)) {
ScrArea *sa;
+
+ C->window= win;
+ C->screen= win->screen;
/* sets context window+screen */
wm_window_make_drawable(C, win);
@@ -189,9 +206,13 @@ void wm_draw_update(bContext *C)
for(sa= win->screen->areabase.first; sa; sa= sa->next) {
ARegion *ar= sa->regionbase.first;
int hasdrawn= 0;
+
+ C->area= sa;
for(; ar; ar= ar->next) {
hasdrawn |= ar->do_draw;
+
+ C->region= ar;
/* cached notifiers */
if(ar->do_refresh)
@@ -199,7 +220,11 @@ void wm_draw_update(bContext *C)
if(ar->swinid && ar->do_draw)
ED_region_do_draw(C, ar);
+
+ C->region= NULL;
}
+
+ C->area = NULL;
}
/* move this here so we can do area 'overlay' drawing */
@@ -210,6 +235,9 @@ void wm_draw_update(bContext *C)
ED_screen_gesture(win);
wm_window_swap_buffers(win);
+
+ C->window= NULL;
+ C->screen= NULL;
}
}
}
@@ -219,8 +247,6 @@ void wm_draw_update(bContext *C)
/* not handler itself */
static void wm_event_free_handler(wmEventHandler *handler)
{
- if(handler->op)
- MEM_freeN(handler->op);
}
void wm_event_free_handlers(ListBase *lb)
@@ -252,57 +278,77 @@ static int wm_eventmatch(wmEvent *winevent, wmKeymapItem *km)
return 1;
}
+/* note: this might free the handler from the operator */
static int wm_handler_operator_call(bContext *C, wmEventHandler *handler, wmEvent *event)
{
- int retval= 0;
+ int retval= OPERATOR_PASS_THROUGH;
/* derived, modal or blocking operator */
if(handler->op) {
- if(handler->op->type->modal)
- retval= handler->op->type->modal(C, handler->op, event);
+ wmOperator *op= handler->op;
+ wmOperatorType *ot= op->type;
+
+ if(ot->modal) {
+
+ retval= ot->modal(C, op, event);
+
+ if(retval == OPERATOR_FINISHED && (ot->flag & OPTYPE_REGISTER))
+ wm_operator_register(C->wm, op);
+ else if(retval == OPERATOR_CANCELLED || retval == OPERATOR_FINISHED)
+ wm_operator_free(op);
+ }
else
printf("wm_handler_operator_call error\n");
}
else {
wmOperatorType *ot= WM_operatortype_find(event->keymap_idname);
+
if(ot) {
if(ot->poll==NULL || ot->poll(C)) {
- /* operator on stack, register or new modal handle malloc-copies */
- wmOperator op;
-
- memset(&op, 0, sizeof(wmOperator));
- op.type= ot;
+ wmOperator *op= MEM_callocN(sizeof(wmOperator), "wmOperator");
- if(op.type->invoke)
- retval= (*op.type->invoke)(C, &op, event);
- else if(&op.type->exec)
- retval= op.type->exec(C, &op);
-
- if( ot->flag & OPTYPE_REGISTER)
- wm_operator_register(C->wm, &op);
+ op->type= ot;
+
+ if(op->type->invoke)
+ retval= (*op->type->invoke)(C, op, event);
+ else if(op->type->exec)
+ retval= op->type->exec(C, op);
+
+ if(retval == OPERATOR_FINISHED && (ot->flag & OPTYPE_REGISTER))
+ wm_operator_register(C->wm, op);
+ else if(retval != OPERATOR_RUNNING_MODAL)
+ wm_operator_free(op);
}
}
}
- if(retval)
- return WM_HANDLER_BREAK;
-
- return WM_HANDLER_CONTINUE;
+
+ if(retval == OPERATOR_PASS_THROUGH)
+ return WM_HANDLER_CONTINUE;
+
+ return WM_HANDLER_BREAK;
}
static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers)
{
- wmEventHandler *handler;
+ wmEventHandler *handler, *nexthandler;
int action= WM_HANDLER_CONTINUE;
if(handlers==NULL) return action;
- for(handler= handlers->first; handler; handler= handler->next) {
+ /* in this loop, the handler might be freed in wm_handler_operator_call,
+ * and new handler might be added to the head of the list */
+ for(handler= handlers->first; handler; handler= nexthandler) {
+ nexthandler= handler->next;
+
+ /* modal+blocking handler */
+ if(handler->flag & WM_HANDLER_BLOCKING)
+ action= WM_HANDLER_BREAK;
+
if(handler->keymap) {
wmKeymapItem *km;
for(km= handler->keymap->first; km; km= km->next) {
if(wm_eventmatch(event, km)) {
-
if(event->type!=MOUSEMOVE)
printf("handle evt %d win %d op %s\n", event->type, C->window->winid, km->idname);
@@ -319,10 +365,6 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers)
action= wm_handler_operator_call(C, handler, event);
}
- /* modal+blocking handler */
- if(handler->flag & WM_HANDLER_BLOCKING)
- action= WM_HANDLER_BREAK;
-
if(action==WM_HANDLER_BREAK)
break;
@@ -341,7 +383,7 @@ static int wm_event_inside_i(wmEvent *event, rcti *rect)
void wm_event_do_handlers(bContext *C)
{
wmWindow *win;
-
+
for(win= C->wm->windows.first; win; win= win->next) {
wmEvent *event;
@@ -350,12 +392,11 @@ void wm_event_do_handlers(bContext *C)
while( (event=wm_event_next(win)) ) {
int action;
-
- if(event->type==BORDERSELECT)
- printf("BORDERSELECT Event!!\n");
+
+ C->window= win;
+ C->screen= win->screen;
/* MVC demands to not draw in event handlers... for now we leave it */
- /* it also updates context (win, screen) */
wm_window_make_drawable(C, win);
action= wm_handlers_do(C, event, &win->handlers);
@@ -366,7 +407,7 @@ void wm_event_do_handlers(bContext *C)
for(; sa; sa= sa->next) {
if(wm_event_inside_i(event, &sa->totrct)) {
- C->curarea= sa;
+ C->area= sa;
action= wm_handlers_do(C, event, &sa->handlers);
if(action==WM_HANDLER_CONTINUE) {
ARegion *ar= sa->regionbase.first;
@@ -375,17 +416,22 @@ void wm_event_do_handlers(bContext *C)
if(wm_event_inside_i(event, &ar->winrct)) {
C->region= ar;
action= wm_handlers_do(C, event, &ar->handlers);
+ C->region= NULL;
if(action==WM_HANDLER_BREAK)
break;
}
}
}
+ C->area= NULL;
if(action==WM_HANDLER_BREAK)
break;
}
}
}
wm_event_free(event);
+
+ C->window= NULL;
+ C->screen= NULL;
}
}
}
@@ -404,11 +450,8 @@ wmEventHandler *WM_event_add_modal_handler(ListBase *handlers, wmOperator *op)
}
else {
wmEventHandler *handler= MEM_callocN(sizeof(wmEventHandler), "event handler");
- wmOperator *opc= MEM_mallocN(sizeof(wmOperator), "operator modal");
-
+ handler->op= op;
BLI_addhead(handlers, handler);
- *opc= *op;
- handler->op= opc;
return handler;
}
@@ -431,14 +474,33 @@ void WM_event_remove_modal_handler(ListBase *handlers, wmOperator *op)
wmEventHandler *WM_event_add_keymap_handler(ListBase *keymap, ListBase *handlers)
{
- wmEventHandler *handler= MEM_callocN(sizeof(wmEventHandler), "event handler");
+ wmEventHandler *handler;
+ /* only allow same keymap once */
+ for(handler= handlers->first; handler; handler= handler->next)
+ if(handler->keymap==keymap)
+ return;
+
+ handler= MEM_callocN(sizeof(wmEventHandler), "event handler");
BLI_addtail(handlers, handler);
handler->keymap= keymap;
return handler;
}
+void WM_event_remove_keymap_handler(ListBase *keymap, ListBase *handlers)
+{
+ wmEventHandler *handler;
+
+ for(handler= handlers->first; handler; handler= handler->next) {
+ if(handler->keymap==keymap) {
+ BLI_remlink(handlers, handler);
+ wm_event_free_handler(handler);
+ MEM_freeN(handler);
+ break;
+ }
+ }
+}
/* ********************* ghost stuff *************** */