Various changes made in the process of working on the UI code:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>
Tue, 11 Nov 2008 15:18:21 +0000 (15:18 +0000)
committerBrecht Van Lommel <brechtvanlommel@pandora.be>
Tue, 11 Nov 2008 15:18:21 +0000 (15:18 +0000)
* Added functions to generate Timer events. There was some unfinished code to
  create one timer per window, this replaces that with a way to let operators
  or other handlers add/remove their own timers as needed. This is currently
  delivered as an event with the timer handle, perhaps this should be a notifier
  instead? Also includes some fixes in ghost for timer events that were not
  delivered in time, due to passing negative timeout.
* Added a Message event, which is a generic event that can be added by any
  operator. This is used in the UI code to communicate the results of opened
  blocks. Again, this may be better as a notifier.
* These two events should not be blocked as they are intended for a specific
  operator or handler, so there were exceptions added for this, which is one
  of the reasons they might work better as notifiers, but currently these
  things can't listen to notifier yet.
* Added an option to events to indicate if the customdata should be freed or
  not.

* Added a free() callback for area regions, and added a free function for
  area regions in blenkernel since it was already there for screens and areas.
* Added ED_screen/area/region_exit functions to clean up things like operators
  and handlers when they are closed.
* Added screen level regions, these will draw over areas boundaries, with the
  last created region on top. These are useful for tooltips, menus, etc, and
  are not saved to file. It's using the same ARegion struct as areas to avoid
  code duplication, but perhaps that should be renamed then. Note that redraws
  currently go correct, because only full window redraws are used, for partial
  redraws without any frontbuffer drawing, the window manager needs to get
  support for compositing subwindows.

* Minor changes in the subwindow code to retrieve the matrix, and moved
  setlinestyle to glutil.c.
* Reversed argument order in WM_event_add/remove_keymap_handler to be consistent
  with modal_handler.

* Operators can now block events but not necessarily cancel/finish.
* Modal operators are now stored in a list in the window/area/region they were
  created in. This means for example that when a transform operator is invoked
  from a region but registers a handler at the window level (since mouse motion
  across areas should work), it will still get removed when the region is closed
  while the operator is running.

24 files changed:
intern/ghost/GHOST_Types.h
intern/ghost/intern/GHOST_SystemCarbon.cpp
intern/ghost/intern/GHOST_SystemWin32.cpp
intern/ghost/intern/GHOST_SystemX11.cpp
source/blender/blenkernel/BKE_screen.h
source/blender/blenkernel/intern/screen.c
source/blender/blenloader/intern/readfile.c
source/blender/editors/include/BIF_glutil.h
source/blender/editors/include/ED_screen.h
source/blender/editors/screen/area.c
source/blender/editors/screen/glutil.c
source/blender/editors/screen/screen_edit.c
source/blender/editors/space_time/space_time.c
source/blender/editors/space_view3d/space_view3d.c
source/blender/makesdna/DNA_screen_types.h
source/blender/makesdna/DNA_windowmanager_types.h
source/blender/windowmanager/WM_api.h
source/blender/windowmanager/WM_types.h
source/blender/windowmanager/intern/wm_event_system.c
source/blender/windowmanager/intern/wm_files.c
source/blender/windowmanager/intern/wm_subwindow.c
source/blender/windowmanager/intern/wm_window.c
source/blender/windowmanager/wm_event_types.h
source/blender/windowmanager/wm_subwindow.h

index 349fb5a02fc330d94c72f1c4eaa88d1b4dd70a38..a413b765ccb46374639fa658965c7929b22c43c7 100644 (file)
@@ -143,6 +143,8 @@ typedef enum {
        GHOST_kEventWindowSize,
        GHOST_kEventWindowMove,
 
+       GHOST_kEventTimer,
+
        GHOST_kNumEventTypes
 } GHOST_TEventType;
 
index 5523fab50f1a700a4cd92a1dcc196e7c65151cf2..e1980521eb08ae0ac9dcc4d4b6239a428aec2709 100644 (file)
@@ -423,17 +423,15 @@ bool GHOST_SystemCarbon::processEvents(bool waitForEvent)
                GHOST_TimerManager* timerMgr = getTimerManager();
 
                if (waitForEvent) {
-                       GHOST_TUns64 curtime = getMilliSeconds();
                        GHOST_TUns64 next = timerMgr->nextFireTime();
                        double timeOut;
                        
                        if (next == GHOST_kFireTimeNever) {
                                timeOut = kEventDurationForever;
                        } else {
-                               if (next<=curtime)
+                               timeOut = (double)(next - getMilliSeconds())/1000.0;
+                               if (timeOut < 0.0)
                                        timeOut = 0.0;
-                               else
-                                       timeOut = (double) (next - getMilliSeconds())/1000.0;
                        }
                        
                        ::ReceiveNextEvent(0, NULL, timeOut, false, &event);
index 6f9bad0f876ff251569ba9b6ef777c80640b6e24..61b504400d229a1e5ab3f34143d7d14594b7ccff 100644 (file)
@@ -190,11 +190,12 @@ bool GHOST_SystemWin32::processEvents(bool waitForEvent)
                        ::Sleep(1);
 #else
                        GHOST_TUns64 next = timerMgr->nextFireTime();
+                       GHOST_TInt64 maxSleep = next - getMilliSeconds();
                        
                        if (next == GHOST_kFireTimeNever) {
                                ::WaitMessage();
-                       } else {
-                               ::SetTimer(NULL, 0, next - getMilliSeconds(), NULL);
+                       } else if(maxSleep >= 0.0) {
+                               ::SetTimer(NULL, 0, maxSleep, NULL);
                                ::WaitMessage();
                                ::KillTimer(NULL, 0);
                        }
index bbce940f1b30fa5da3d6998e4fa2e7740add4cd6..170a7c23843c6788c02a09dd716283d654ecbee3 100644 (file)
@@ -309,7 +309,10 @@ processEvents(
                        if (next==GHOST_kFireTimeNever) {
                                SleepTillEvent(m_display, -1);
                        } else {
-                               SleepTillEvent(m_display, next - getMilliSeconds());
+                               GHOST_TInt64 maxSleep = next - getMilliSeconds();
+
+                               if(maxSleep >= 0)
+                                       SleepTillEvent(m_display, next - getMilliSeconds());
                        }
                }
                
index 14090719de62f6f7c25e26c360f6400091f19dd2..ebaf85a58f92b42f0988c4e7e396f4258ce41052 100644 (file)
@@ -82,10 +82,12 @@ typedef struct ARegionType {
        void            (*draw)(const struct bContext *, struct ARegion *);             /* draw entirely, windowsize changes should be handled here */
        
        void            (*listener)(struct ARegion *, struct wmNotifier *);
+       void            (*free)(struct ARegion *);
 } ARegionType;
 
 
 void BKE_screen_area_free(struct ScrArea *sa);
+void BKE_area_region_free(struct ARegion *ar);
 void free_screen(struct bScreen *sc); 
 
 struct SpaceType *BKE_spacetype_from_id(int spaceid);
index b259138ee42c8c57940f94e189084e3c85714946..926a62e9f697460290f5c0647218274eb9c68cd7 100644 (file)
@@ -90,11 +90,21 @@ void BKE_spacedata_copylist(ListBase *lb1, ListBase *lb2)
        }
 }
 
+/* not region itself */
+void BKE_area_region_free(ARegion *ar)
+{
+       if(ar->type && ar->type->free)
+               ar->type->free(ar);
+}
 
 /* not area itself */
 void BKE_screen_area_free(ScrArea *sa)
 {
+       ARegion *ar;
        
+       for(ar=sa->regionbase.first; ar; ar=ar->next)
+               BKE_area_region_free(ar);
+
        BKE_spacedata_freelist(&sa->spacedata);
        
        BLI_freelistN(&sa->regionbase);
index 4fffaf02b09102a536094221af956b232070dd0d..5c8583cd5ee4522fcfa18faa26d6be22b7c6fc2c 100644 (file)
@@ -3492,6 +3492,7 @@ static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm)
                
                win->queue.first= win->queue.last= NULL;
                win->handlers.first= win->handlers.last= NULL;
+               win->modalops.first= win->modalops.last= NULL;
                win->subwindows.first= win->subwindows.last= NULL;
        }
        
@@ -3836,7 +3837,8 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
        link_list(fd, &(sc->vertbase));
        link_list(fd, &(sc->edgebase));
        link_list(fd, &(sc->areabase));
-       
+       sc->regionbase.first= sc->regionbase.last= NULL;
+
        sc->mainwin= sc->subwinactive= 0;       /* indices */
        
        /* hacky patch... but people have been saving files with the verse-blender,
@@ -3875,6 +3877,7 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
                link_list(fd, &(sa->regionbase));
 
                sa->handlers.first= sa->handlers.last= NULL;
+               sa->modalops.first= sa->modalops.last= NULL;
                sa->uiblocks.first= sa->uiblocks.last= NULL;
                sa->type= NULL; /* spacetype callbacks */
                
@@ -3937,6 +3940,9 @@ static void direct_link_screen(FileData *fd, bScreen *sc)
                
                for(ar= sa->regionbase.first; ar; ar= ar->next) {
                        ar->handlers.first= ar->handlers.last= NULL;
+                       ar->modalops.first= ar->modalops.last= NULL;
+                       ar->uiblocks.first= ar->uiblocks.last= NULL;
+                       ar->regiondata= NULL;
                        ar->swinid= 0;
                        ar->type= NULL;
                }
index bc622a94be5fb26486e5ffbb6570ca90a1696c5f..3fcb88b1c4983c95504a0126ce09ecf15dbd5a8b 100644 (file)
@@ -206,6 +206,7 @@ void bglVertex2fv(float *vec);
 void bglFlush(void);
 int is_a_really_crappy_intel_card(void);
 void set_inverted_drawing(int enable);
+void setlinestyle(int nr);
 
 
 /* own working polygon offset */
index f1ce0d5e66e7800b44cdb51fa2d75d8baaceb231..095ccf09457bd49625733f3ec0c4b75e580ce4c0 100644 (file)
@@ -38,9 +38,11 @@ struct wmWindow;
 struct wmNotifier;
 
 /* regions */
+void   ED_region_initialize(struct wmWindowManager *wm, struct wmWindow *win, struct ARegion *ar);
 void   ED_region_do_listen(ARegion *ar, struct wmNotifier *note);
 void   ED_region_do_draw(struct bContext *C, ARegion *ar);
 void   ED_region_do_refresh(struct bContext *C, ARegion *ar);
+void   ED_region_exit(struct bContext *C, ARegion *ar);
 
 /* spaces */
 void   ED_spacetypes_init(void);
@@ -48,6 +50,7 @@ void  ED_spacetypes_keymap(struct wmWindowManager *wm);
 
 /* areas */
 void   ED_area_initialize(struct wmWindowManager *wm, struct wmWindow *win, struct ScrArea *sa);
+void   ED_area_exit(struct bContext *C, ScrArea *sa);
 
 /* screens */
 void   ED_screens_initialize(struct wmWindowManager *wm);
@@ -58,6 +61,7 @@ void  ED_screen_do_listen(struct wmWindow *win, struct wmNotifier *note);
 bScreen *ED_screen_duplicate(struct wmWindow *win, bScreen *sc);
 bScreen *ED_screen_riparea(struct wmWindow *win, bScreen *sc, struct ScrArea *sa);
 void   ED_screen_set_subwinactive(struct wmWindow *win);
+void   ED_screen_exit(struct bContext *C, struct wmWindow *window, bScreen *screen);
 
 void   ED_operatortypes_screen(void);
 void   ED_keymap_screen(struct wmWindowManager *wm);
index ac6058a0c5ca6f325481110a152247730b5acaab..6d77dc4eee99cc0bbaa3d720bd91c84f357323b8 100644 (file)
@@ -173,6 +173,8 @@ static void region_rect_recursive(ARegion *ar, rcti *remainder)
        
        /* hidden is user flag */
        if(ar->flag & RGN_FLAG_HIDDEN);
+       /* XXX floating area region, not handled yet here */
+       else if(ar->alignment == RGN_ALIGN_FLOAT);
        /* remainder is too small for any usage */
        else if( rct_fits(remainder, 'v', 1)==0 || rct_fits(remainder, 'h', 1) < 0 ) {
                ar->flag |= RGN_FLAG_TOO_SMALL;
@@ -189,7 +191,7 @@ static void region_rect_recursive(ARegion *ar, rcti *remainder)
                }
                else {
                        int fac= rct_fits(remainder, 'v', ar->size);
-                       
+
                        if(fac < 0 )
                                ar->size += fac;
                        
@@ -352,6 +354,20 @@ void area_azone_initialize(ScrArea *sa) {
        }
 }
 
+/* used for area and screen regions */
+void ED_region_initialize(wmWindowManager *wm, wmWindow *win, ARegion *ar)
+{
+       if(ar->flag & (RGN_FLAG_HIDDEN|RGN_FLAG_TOO_SMALL)) {
+               if(ar->swinid)
+                       wm_subwindow_close(win, ar->swinid);
+               ar->swinid= 0;
+       }
+       else if(ar->swinid==0)
+               ar->swinid= wm_subwindow_open(win, &ar->winrct);
+       else 
+               wm_subwindow_position(win, ar->swinid, &ar->winrct);
+}
+
 /* called in screen_refresh, or screens_init */
 void ED_area_initialize(wmWindowManager *wm, wmWindow *win, ScrArea *sa)
 {
@@ -376,17 +392,8 @@ void ED_area_initialize(wmWindowManager *wm, wmWindow *win, ScrArea *sa)
        region_rect_recursive(sa->regionbase.first, &rect);
        
        /* region windows */
-       for(ar= sa->regionbase.first; ar; ar= ar->next) {
-               if(ar->flag & (RGN_FLAG_HIDDEN|RGN_FLAG_TOO_SMALL)) {
-                       if(ar->swinid)
-                               wm_subwindow_close(win, ar->swinid);
-                       ar->swinid= 0;
-               }
-               else if(ar->swinid==0)
-                       ar->swinid= wm_subwindow_open(win, &ar->winrct);
-               else 
-                       wm_subwindow_position(win, ar->swinid, &ar->winrct);
-       }
+       for(ar= sa->regionbase.first; ar; ar= ar->next)
+               ED_region_initialize(wm, win, ar);
        
        area_azone_initialize(sa);
 }
@@ -435,8 +442,11 @@ void area_copy_data(ScrArea *sa1, ScrArea *sa2, int swap_space)
        /* regions */
        BLI_freelistN(&sa1->regionbase);
        BLI_duplicatelist(&sa1->regionbase, &sa2->regionbase);
-       for(ar= sa1->regionbase.first; ar; ar= ar->next)
+       for(ar= sa1->regionbase.first; ar; ar= ar->next) {
+               ar->handlers.first= ar->handlers.last= NULL;
+               ar->uiblocks.first= ar->uiblocks.last= NULL;
                ar->swinid= 0;
+       }
                
        /* scripts */
        BPY_free_scriptlink(&sa1->scriptlink);
index 4a7b3766ea8cb475c323d9f21437a7b7061508b5..5b776fd7f496697aadbd8740feb91b6ba585529c 100644 (file)
@@ -151,6 +151,18 @@ void sdrawbox(short x1, short y1, short x2, short y2)
 
 /* ******************************************** */
 
+void setlinestyle(int nr)
+{
+       if(nr==0) {
+               glDisable(GL_LINE_STIPPLE);
+       }
+       else {
+               
+               glEnable(GL_LINE_STIPPLE);
+               glLineStipple(nr, 0xAAAA);
+       }
+}
+
        /* Invert line handling */
        
 #define glToggle(mode, onoff)  (((onoff)?glEnable:glDisable)(mode))
index 7d827a5daade699763e005dab95c76f25a24b70f..98c5eecfe4bb1eb3b8b2ce7daaccb6f2137274ab 100644 (file)
@@ -37,7 +37,6 @@
 
 #include "BIF_gl.h"
 #include "BIF_glutil.h"
-#include "BIF_resources.h"
 
 #include "WM_api.h"
 #include "WM_types.h"
@@ -389,7 +388,6 @@ static void select_connected_scredge(bScreen *sc, ScrEdge *edge)
 
 static ScrArea *screen_addarea(bScreen *sc, ScrVert *v1, ScrVert *v2, ScrVert *v3, ScrVert *v4, short headertype, short spacetype)
 {
-       AZone *az= NULL;
        ScrArea *sa= MEM_callocN(sizeof(ScrArea), "addscrarea");
        sa->v1= v1;
        sa->v2= v2;
@@ -404,7 +402,8 @@ static ScrArea *screen_addarea(bScreen *sc, ScrVert *v1, ScrVert *v2, ScrVert *v
 }
 
 static void screen_delarea(bScreen *sc, ScrArea *sa)
-{      
+{
+       /* XXX need context to cancel operators ED_area_exit(C, sa); */
        BKE_screen_area_free(sa);
        BLI_remlink(&sc->areabase, sa);
        MEM_freeN(sa);
@@ -456,6 +455,7 @@ static void screen_copy(bScreen *to, bScreen *from)
        BLI_duplicatelist(&to->vertbase, &from->vertbase);
        BLI_duplicatelist(&to->edgebase, &from->edgebase);
        BLI_duplicatelist(&to->areabase, &from->areabase);
+       to->regionbase.first= to->regionbase.last= NULL;
        
        s2= to->vertbase.first;
        for(s1= from->vertbase.first; s1; s1= s1->next, s2= s2->next) {
@@ -808,11 +808,8 @@ void screen_test_scale(bScreen *sc, int winsizex, int winsizey)
        /* test for collapsed areas. This could happen in some blender version... */
        for(sa= sc->areabase.first; sa; sa= san) {
                san= sa->next;
-               if(sa->v1==sa->v2 || sa->v3==sa->v4 || sa->v2==sa->v3) {
-                       BKE_screen_area_free(sa);
-                       BLI_remlink(&sc->areabase, sa);
-                       MEM_freeN(sa);
-               }
+               if(sa->v1==sa->v2 || sa->v3==sa->v4 || sa->v2==sa->v3)
+                       screen_delarea(sc, sa);
        }
 }
 
@@ -1123,6 +1120,7 @@ void ED_screen_gesture(wmWindow *win)
 void ED_screen_refresh(wmWindowManager *wm, wmWindow *win)
 {
        ScrArea *sa;
+       ARegion *ar;
        rcti winrct= {0, win->sizex, 0, win->sizey};
        
        screen_test_scale(win->screen, win->sizex, win->sizey);
@@ -1137,6 +1135,11 @@ void ED_screen_refresh(wmWindowManager *wm, wmWindow *win)
                /* sets subwindow */
                ED_area_initialize(wm, win, sa);
        }
+
+       for(ar= win->screen->regionbase.first; ar; ar= ar->next) {
+               /* set subwindow */
+               ED_region_initialize(wm, win, ar);
+       }
        
        if(G.f & G_DEBUG) printf("set screen\n");
        win->screen->do_refresh= 0;
@@ -1157,6 +1160,38 @@ void ED_screens_initialize(wmWindowManager *wm)
        }
 }
 
+void ED_region_exit(bContext *C, ARegion *ar)
+{
+       WM_operator_cancel(C, &ar->modalops, NULL);
+       WM_event_remove_handlers(&ar->handlers);
+}
+
+void ED_area_exit(bContext *C, ScrArea *sa)
+{
+       ARegion *ar;
+
+       for(ar= sa->regionbase.first; ar; ar= ar->next)
+               ED_region_exit(C, ar);
+
+       WM_operator_cancel(C, &sa->modalops, NULL);
+       WM_event_remove_handlers(&sa->handlers);
+}
+
+void ED_screen_exit(bContext *C, wmWindow *window, bScreen *screen)
+{
+       ScrArea *sa;
+       ARegion *ar;
+
+       for(ar= screen->regionbase.first; ar; ar= ar->next)
+               ED_region_exit(C, ar);
+
+       for(sa= screen->areabase.first; sa; sa= sa->next)
+               ED_area_exit(C, sa);
+
+       WM_operator_cancel(C, &window->modalops, NULL);
+       WM_event_remove_handlers(&window->handlers);
+}
+
 void placeholder()
 {
        removenotused_scrverts(NULL);
index 1d35e7a57e01d2bffdcf25cdebc5bec01b6603ae..02a07044a8a866714d163db9989ffdb5ed9fee47 100644 (file)
@@ -202,7 +202,7 @@ static void time_init(wmWindowManager *wm, ScrArea *sa)
        /* add types to regions */
        for(ar= sa->regionbase.first; ar; ar= ar->next) {
                if(ar->regiontype == RGN_TYPE_WINDOW) {
-                       static ARegionType mainart={NULL, NULL, NULL, NULL};
+                       static ARegionType mainart={NULL, NULL, NULL, NULL, NULL};
 
                        mainart.init= time_main_area_init;
                        mainart.refresh= time_main_area_refresh;
@@ -216,11 +216,11 @@ static void time_init(wmWindowManager *wm, ScrArea *sa)
                         * to add the keymap handler, also will need to take care of
                         * area type changes, etc, basically space callbacks need to
                         * be looked at further */
-                       WM_event_remove_keymap_handler(&wm->timekeymap, &ar->handlers);
-                       WM_event_add_keymap_handler(&wm->timekeymap, &ar->handlers);
+                       WM_event_remove_keymap_handler(&ar->handlers, &wm->timekeymap);
+                       WM_event_add_keymap_handler(&ar->handlers, &wm->timekeymap);
                }
                else {
-                       static ARegionType art={NULL, NULL, NULL, NULL};
+                       static ARegionType art={NULL, NULL, NULL, NULL, NULL};
 
                        /* for time being; register 1 type */
                        ar->type= &art;
index 1abd860c661d70dfd4006c02ba104d6f02f43d66..d60dd6a4062aa5a86b50ee81f2eddb2ba960ad3e 100644 (file)
@@ -128,7 +128,7 @@ static void view3d_init(struct wmWindowManager *wm, ScrArea *sa)
        
        /* add types to regions */
        for(ar= sa->regionbase.first; ar; ar= ar->next) {
-               static ARegionType art={NULL, NULL, NULL, NULL};
+               static ARegionType art={NULL, NULL, NULL, NULL, NULL};
                
                /* for time being; register 1 type */
                ar->type= &art;
index 1a1287309102b6fcc70e00cf18b50711e2955ff1..c5ec847608ff88077037a7f1954d88eeb7bc8281 100644 (file)
@@ -46,7 +46,9 @@ struct wmWindowManager;
 typedef struct bScreen {
        ID id;
        
-       ListBase vertbase, edgebase, areabase;
+       ListBase vertbase, edgebase;
+       ListBase areabase;
+       ListBase regionbase;                            /* screen level regions, runtime only */
        struct Scene *scene;
        
        short scenenr, screennr;                        /* only for pupmenu */
@@ -127,6 +129,7 @@ typedef struct ScrArea {
        ListBase panels;
        ListBase regionbase;    /* ARegion */
        ListBase handlers;              /* wmEventHandler */
+       ListBase modalops;              /* wmOperator */
        
        ListBase actionzones;   /* AZone */
 } ScrArea;
@@ -149,8 +152,11 @@ typedef struct ARegion {
        
        struct ARegionType *type;       /* callbacks for this region type */
        
-       ListBase handlers;
+       ListBase uiblocks;
+       ListBase handlers;                      /* wmEventHandler */
+       ListBase modalops;                      /* wmOperator */
        
+       void *regiondata;                       /* XXX 2.50, need spacedata equivalent? */
 } ARegion;
 
 /* area->flag */
@@ -205,6 +211,7 @@ typedef struct ARegion {
 /* regiontype, first two are the default set */
 #define RGN_TYPE_WINDOW                0
 #define RGN_TYPE_HEADER                1
+#define RGN_TYPE_TEMPORARY     2
 
 /* region alignment */
 #define RGN_ALIGN_NONE         0
@@ -214,6 +221,7 @@ typedef struct ARegion {
 #define RGN_ALIGN_RIGHT                4
 #define RGN_ALIGN_HSPLIT       5
 #define RGN_ALIGN_VSPLIT       6
+#define RGN_ALIGN_FLOAT                7
 
 /* region flag */
 #define RGN_FLAG_HIDDEN                1
index 99334d705dc881327a9f2c86e14b00c59e913dbd..bb5bf6d19b31bf5b9b8dd465b398ef2d0a836463 100644 (file)
@@ -78,10 +78,8 @@ typedef struct wmWindow {
        struct wmWindow *next, *prev;
        
        void *ghostwin;         /* dont want to include ghost.h stuff */
-       void *timer;
-       int timer_event;
        
-       int winid;      /* winid also in screens, is for retrieving this window after read */
+       int winid, pad;         /* winid also in screens, is for retrieving this window after read */
        
        struct bScreen *screen; /* active screen */
        char screenname[32];    /* MAX_ID_NAME for matching window with active screen after file read */
@@ -96,11 +94,12 @@ typedef struct wmWindow {
        
        struct wmSubWindow *curswin;    /* internal for wm_subwindow.c only */
        
-       ListBase queue;                 /* all events (ghost level events were handled) */
-       ListBase handlers;              /* window+screen handlers, overriding all queues */
+       ListBase queue;                         /* all events (ghost level events were handled) */
+       ListBase handlers;                      /* window+screen handlers, overriding all queues */
+       ListBase modalops;                      /* wmOperator, operators running modal */
        
        ListBase subwindows;    /* opengl stuff for sub windows, see notes in wm_subwindow.c */
-       ListBase gesture;       /* gesture stuff */
+       ListBase gesture;               /* gesture stuff */
 } wmWindow;
 
 #
@@ -169,13 +168,16 @@ typedef struct wmOperator {
        /* or IDproperty list */
        IDProperty *properties;
 
+       /* runtime */
+       ListBase *modallist;
 } wmOperator;
 
-/* operator type exec(), invoke() modal(), cancel() return values */
-#define OPERATOR_PASS_THROUGH  0
+/* operator type exec(), invoke() modal(), return values */
 #define OPERATOR_RUNNING_MODAL 1
 #define OPERATOR_CANCELLED             2
-#define OPERATOR_FINISHED              3
+#define OPERATOR_FINISHED              4
+/* add this flag if the event should pass through */
+#define OPERATOR_PASS_THROUGH  8
 
 #endif /* DNA_WINDOWMANAGER_TYPES_H */
 
index 2f450c9bbd731d4c23c70074299c626f9211d3f4..d19d189af82f88c4dfc890f2479dd7e9a80f830c 100644 (file)
@@ -64,15 +64,22 @@ void                WM_keymap_verify_item(ListBase *lb, char *idname, short type,
                                                                 short val, int modifier, short keymodifier);
 void           WM_keymap_add_item      (ListBase *lb, char *idname, short type, 
                                                                 short val, int modifier, short keymodifier);
-struct wmEventHandler *WM_event_add_keymap_handler(ListBase *keymap, ListBase *handlers);
-void           WM_event_remove_keymap_handler(ListBase *keymap, ListBase *handlers);
+struct wmEventHandler *WM_event_add_keymap_handler(ListBase *handlers, ListBase *keymap);
+void           WM_event_remove_keymap_handler(ListBase *handlers, ListBase *keymap);
 struct wmEventHandler *WM_event_add_modal_handler(ListBase *handlers, wmOperator *op);
 void           WM_event_remove_modal_handler(ListBase *handlers, wmOperator *op);
+void           WM_event_remove_handlers(ListBase *handlers);
+
+void           WM_event_add_message(wmWindowManager *wm, void *customdata,
+                                 short customdatafree);
 
 void           WM_event_add_notifier(wmWindowManager *wm, wmWindow *window,
                                        int swinid, int type,
                                        int value, void *data);
 
+                       /* one-shot timer, returns wmTimerData.handle */
+struct wmTimerHandle *WM_event_add_window_timer(wmWindow *win, int delay_ms, int interval_ms);
+void           WM_event_remove_window_timer(wmWindow *wm, struct wmTimerHandle *handle);
 
                        /* operator api, default callbacks */
                        /* confirm menu + exec */
@@ -84,6 +91,9 @@ int                   WM_operator_winactive   (struct bContext *C);
 wmOperatorType *WM_operatortype_find(const char *idname);
 void           WM_operatortype_append(void (*opfunc)(wmOperatorType*));
 
+int                    WM_operator_invoke(struct bContext *C, wmOperatorType *ot, struct wmEvent *event);
+void           WM_operator_cancel(struct bContext *C, ListBase *modalops, wmOperatorType *ot);
+
 /* 
  * Operator property api
  *
index a85988b6a09d3b07cfec77b068c4554fc13c989d..5bb796814670718ae378ec4842f4ae2486ca301e 100644 (file)
@@ -63,6 +63,7 @@ typedef struct wmEvent {
        /* custom data */
        short custom;   /* custom data type, stylus, 6dof, see wm_event_types.h */
        void *customdata;       /* ascii, unicode, mouse coords, angles, vectors, dragdrop info */
+       short customdatafree;
        
 } wmEvent;
 
@@ -138,6 +139,9 @@ typedef struct wmBorderSelect {
        short x2, y2;
 } wmBorderSelect;
 
+struct wmTimerHandle;
+typedef struct wmTimerHandle wmTimerHandle;
+
 /* ****************** Messages ********************* */
 
 enum {
index c33ac0cd3422f39d4ab4579e92ec0585b9f122bb..700ac04603dcbefac9995ce8654e5f581ec859a5 100644 (file)
@@ -73,7 +73,8 @@ wmEvent *wm_event_next(wmWindow *win)
 
 static void wm_event_free(wmEvent *event)
 {
-       if(event->customdata) MEM_freeN(event->customdata);
+       if(event->customdata && event->customdatafree)
+               MEM_freeN(event->customdata);
        MEM_freeN(event);
 }
 
@@ -121,6 +122,7 @@ void wm_event_do_notifiers(bContext *C)
                
                for(win= C->wm->windows.first; win; win= win->next) {
                        ScrArea *sa;
+                       ARegion *ar;
 
                        C->window= win;
                        C->screen= win->screen;
@@ -130,15 +132,22 @@ void wm_event_do_notifiers(bContext *C)
                        if(win->screen==NULL)
                                continue;
 
-                       printf("notifier win %d screen %s\n", win->winid, win->screen->id.name+2);
+                       /* printf("notifier win %d screen %s\n", win->winid, win->screen->id.name+2); */
                        ED_screen_do_listen(win, note);
+
+                       for(ar=win->screen->regionbase.first; ar; ar= ar->next) {
+                               if(note->swinid && note->swinid!=ar->swinid)
+                                       continue;
+
+                               C->region= ar;
+                               ED_region_do_listen(ar, note);
+                               C->region= NULL;
+                       }
                        
                        for(sa= win->screen->areabase.first; sa; sa= sa->next) {
-                               ARegion *ar= sa->regionbase.first;
-                               
                                C->area= sa;
 
-                               for(; ar; ar= ar->next) {
+                               for(ar=sa->regionbase.first; ar; ar= ar->next) {
                                        if(note->swinid && note->swinid!=ar->swinid)
                                                continue;
 
@@ -163,6 +172,7 @@ void wm_event_do_notifiers(bContext *C)
 static int wm_draw_update_test_window(wmWindow *win)
 {
        ScrArea *sa;
+       ARegion *ar;
        
        if(win->screen->do_refresh)
                return 1;
@@ -171,10 +181,16 @@ static int wm_draw_update_test_window(wmWindow *win)
        if(win->screen->do_gesture)
                return 1;
 
+       for(ar=win->screen->regionbase.first; ar; ar= ar->next) {
+               /* cached notifiers */
+               if(ar->do_refresh)
+                       return 1;
+               if(ar->swinid && ar->do_draw)
+                       return 1;
+       }
+
        for(sa= win->screen->areabase.first; sa; sa= sa->next) {
-               ARegion *ar= sa->regionbase.first;
-               
-               for(; ar; ar= ar->next) {
+               for(ar=sa->regionbase.first; ar; ar= ar->next) {
                        /* cached notifiers */
                        if(ar->do_refresh)
                                return 1;
@@ -192,6 +208,7 @@ 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;
+                       ARegion *ar;
 
                        C->window= win;
                        C->screen= win->screen;
@@ -202,16 +219,11 @@ void wm_draw_update(bContext *C)
                        /* notifiers for screen redraw */
                        if(win->screen->do_refresh)
                                ED_screen_refresh(C->wm, win);
-                       
-                       for(sa= win->screen->areabase.first; sa; sa= sa->next) {
-                               ARegion *ar= sa->regionbase.first;
-                               int hasdrawn= 0;
 
+                       for(sa= win->screen->areabase.first; sa; sa= sa->next) {
                                C->area= sa;
                                
-                               for(; ar; ar= ar->next) {
-                                       hasdrawn |= ar->do_draw;
-
+                               for(ar=sa->regionbase.first; ar; ar= ar->next) {
                                        C->region= ar;
                                        
                                        /* cached notifiers */
@@ -230,6 +242,19 @@ void wm_draw_update(bContext *C)
                        /* move this here so we can do area 'overlay' drawing */
                        if(win->screen->do_draw)
                                ED_screen_draw(win);
+
+                       for(ar=win->screen->regionbase.first; ar; ar= ar->next) {
+                               C->region= ar;
+                               
+                               /* cached notifiers */
+                               if(ar->do_refresh)
+                                       ED_region_do_refresh(C, ar);
+                               
+                               if(ar->swinid && ar->do_draw)
+                                       ED_region_do_draw(C, ar);
+
+                               C->region= NULL;
+                       }
                        
                        if(win->screen->do_gesture)
                                ED_screen_gesture(win);
@@ -242,6 +267,73 @@ void wm_draw_update(bContext *C)
        }
 }
 
+/* ********************* operators ******************* */
+
+static ListBase *wm_modalops_list(bContext *C)
+{
+       if(C->region)
+               return &C->region->modalops;
+       else if(C->area)
+               return &C->area->modalops;
+       else if(C->window)
+               return &C->window->modalops;
+       else
+               return NULL;
+}
+
+int WM_operator_invoke(bContext *C, wmOperatorType *ot, wmEvent *event)
+{
+       int retval= OPERATOR_PASS_THROUGH;
+
+       if(ot->poll==NULL || ot->poll(C)) {
+               wmOperator *op= MEM_callocN(sizeof(wmOperator), "wmOperator");
+
+               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);
+               }
+               else {
+                       op->modallist= wm_modalops_list(C);
+                       BLI_addtail(op->modallist, op);
+               }
+       }
+
+       return retval;
+}
+
+void WM_operator_cancel(bContext *C, ListBase *lb, wmOperatorType *type)
+{
+       wmOperator *op, *nextop;
+
+       if(!lb)
+               lb= wm_modalops_list(C);
+       if(!lb)
+               return;
+
+       for(op=lb->first; op; op=nextop) {
+               nextop= op->next;
+
+               if(type == NULL || op->type == type) {
+                       if(op->type->cancel)
+                               op->type->cancel(C, op);
+
+                       BLI_remlink(op->modallist, op);
+                       op->modallist= NULL;
+
+                       wm_operator_free(op);
+               }
+       }
+}
+
 /* ********************* handlers *************** */
 
 /* not handler itself */
@@ -259,6 +351,11 @@ void wm_event_free_handlers(ListBase *lb)
        BLI_freelistN(lb);
 }
 
+void WM_event_remove_handlers(ListBase *handlers)
+{
+       wm_event_free_handlers(handlers);
+}
+
 static int wm_eventmatch(wmEvent *winevent, wmKeymapItem *km)
 {
        if(winevent->type!=km->type) return 0;
@@ -289,13 +386,18 @@ static int wm_handler_operator_call(bContext *C, wmEventHandler *handler, wmEven
                wmOperatorType *ot= op->type;
 
                if(ot->modal) {
-
                        retval= ot->modal(C, op, event);
 
-                       if(retval == OPERATOR_FINISHED && (ot->flag & OPTYPE_REGISTER))
+                       if((retval & OPERATOR_FINISHED) && (ot->flag & OPTYPE_REGISTER)) {
+                               BLI_remlink(op->modallist, op);
+                               op->modallist= NULL;
                                wm_operator_register(C->wm, op);
-                       else if(retval == OPERATOR_CANCELLED || retval == OPERATOR_FINISHED)
+                       }
+                       else if(retval & (OPERATOR_CANCELLED|OPERATOR_FINISHED)) {
+                               BLI_remlink(op->modallist, op);
+                               op->modallist= NULL;
                                wm_operator_free(op);
+                       }
                }
                else
                        printf("wm_handler_operator_call error\n");
@@ -303,36 +405,27 @@ static int wm_handler_operator_call(bContext *C, wmEventHandler *handler, wmEven
        else {
                wmOperatorType *ot= WM_operatortype_find(event->keymap_idname);
 
-               if(ot) {
-                       if(ot->poll==NULL || ot->poll(C)) {
-                               wmOperator *op= MEM_callocN(sizeof(wmOperator), "wmOperator");
-
-                               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(ot)
+                       retval= WM_operator_invoke(C, ot, event);
        }
 
-       if(retval == OPERATOR_PASS_THROUGH)
+       if(retval & OPERATOR_PASS_THROUGH)
                return WM_HANDLER_CONTINUE;
 
        return WM_HANDLER_BREAK;
 }
 
+static int wm_event_always_pass(wmEvent *event)
+{
+       /* some events we always pass on, to ensure proper communication */
+       return (event->type == TIMER || event->type == MESSAGE);
+}
+
 static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers)
 {
        wmEventHandler *handler, *nexthandler;
        int action= WM_HANDLER_CONTINUE;
-       
+
        if(handlers==NULL) return action;
        
        /* in this loop, the handler might be freed in wm_handler_operator_call,
@@ -349,13 +442,13 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers)
                        
                        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);
+                                       /*if(event->type!=MOUSEMOVE)
+                                               printf("handle evt %d win %d op %s\n", event->type, C->window->winid, km->idname);*/
                                        
                                        event->keymap_idname= km->idname;       /* weak, but allows interactive callback to not use rawkey */
                                        
                                        action= wm_handler_operator_call(C, handler, event);
-                                       if(action==WM_HANDLER_BREAK)
+                                       if(!wm_event_always_pass(event) && action==WM_HANDLER_BREAK)
                                                break;
                                }
                        }
@@ -365,7 +458,7 @@ static int wm_handlers_do(bContext *C, wmEvent *event, ListBase *handlers)
                        action= wm_handler_operator_call(C, handler, event);
                }
 
-               if(action==WM_HANDLER_BREAK)
+               if(!wm_event_always_pass(event) && action==WM_HANDLER_BREAK)
                        break;
                
        }
@@ -401,30 +494,55 @@ void wm_event_do_handlers(bContext *C)
                        
                        action= wm_handlers_do(C, event, &win->handlers);
                        
-                       if(action==WM_HANDLER_CONTINUE) {
-                               ScrArea *sa= win->screen->areabase.first;
-                               
-                               for(; sa; sa= sa->next) {
-                                       if(wm_event_inside_i(event, &sa->totrct)) {
-                                               
+                       if(wm_event_always_pass(event) || action==WM_HANDLER_CONTINUE) {
+                               ARegion *ar;
+
+                               /* region are in drawing order, i.e. frontmost region last so
+                                * we handle events in the opposite order last to first */
+                               for(ar=win->screen->regionbase.last; ar; ar= ar->prev) {
+                                       if(wm_event_always_pass(event) || wm_event_inside_i(event, &ar->winrct)) {
+                                               C->region= ar;
+                                               wm_handlers_do(C, event, &ar->handlers);
+                                               C->region= NULL;
+
+                                               if(!wm_event_always_pass(event)) {
+                                                       action= WM_HANDLER_BREAK;
+                                                       break;
+                                               }
+                                       }
+                               }
+                       }
+       
+                       if(wm_event_always_pass(event) || action==WM_HANDLER_CONTINUE) {
+                               ScrArea *sa;
+                               ARegion *ar;
+
+                               for(sa= win->screen->areabase.first; sa; sa= sa->next) {
+                                       if(wm_event_always_pass(event) || wm_event_inside_i(event, &sa->totrct)) {
                                                C->area= sa;
                                                action= wm_handlers_do(C, event, &sa->handlers);
-                                               if(action==WM_HANDLER_CONTINUE) {
-                                                       ARegion *ar= sa->regionbase.first;
-                                                       
-                                                       for(; ar; ar= ar->next) {
-                                                               if(wm_event_inside_i(event, &ar->winrct)) {
+
+                                               if(wm_event_always_pass(event) || 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)) {
                                                                        C->region= ar;
                                                                        action= wm_handlers_do(C, event, &ar->handlers);
                                                                        C->region= NULL;
-                                                                       if(action==WM_HANDLER_BREAK)
+
+                                                                       if(!wm_event_always_pass(event)) {
+                                                                               action= WM_HANDLER_BREAK;
                                                                                break;
+                                                                       }
                                                                }
                                                        }
                                                }
+
                                                C->area= NULL;
-                                               if(action==WM_HANDLER_BREAK)
+
+                                               if(!wm_event_always_pass(event)) {
+                                                       action= WM_HANDLER_BREAK;
                                                        break;
+                                               }
                                        }
                                }
                        }
@@ -472,7 +590,7 @@ void WM_event_remove_modal_handler(ListBase *handlers, wmOperator *op)
        }
 }
 
-wmEventHandler *WM_event_add_keymap_handler(ListBase *keymap, ListBase *handlers)
+wmEventHandler *WM_event_add_keymap_handler(ListBase *handlers, ListBase *keymap)
 {
        wmEventHandler *handler;
        
@@ -484,11 +602,11 @@ wmEventHandler *WM_event_add_keymap_handler(ListBase *keymap, ListBase *handlers
        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)
+void WM_event_remove_keymap_handler(ListBase *handlers, ListBase *keymap)
 {
        wmEventHandler *handler;
        
@@ -502,6 +620,24 @@ void WM_event_remove_keymap_handler(ListBase *keymap, ListBase *handlers)
        }
 }
 
+void WM_event_add_message(wmWindowManager *wm, void *customdata, short customdatafree)
+{
+       wmEvent event;
+       wmWindow *win;
+
+       for(win=wm->windows.first; win; win=win->next) {
+               event= *(win->eventstate);
+
+               event.type= MESSAGE;
+               if(customdata) {
+                       event.custom= EVT_MESSAGE;
+                       event.customdata= customdata;
+                       event.customdatafree= customdatafree;
+               }
+               wm_event_add(win, &event);
+       }
+}
+
 /* ********************* ghost stuff *************** */
 
 static int convert_key(GHOST_TKey key) 
@@ -596,6 +732,7 @@ static void update_tablet_data(wmWindow *win, wmEvent *event)
                
                event->custom= EVT_TABLET;
                event->customdata= wmtab;
+               event->customdatafree= 1;
        } 
 }
 
@@ -688,6 +825,15 @@ void wm_event_add_ghostevent(wmWindow *win, int type, void *customdata)
                        
                        break;
                }
+               case GHOST_kEventTimer: {
+                       event.type= TIMER;
+                       event.custom= EVT_TIMER;
+                       event.customdata= customdata;
+                       wm_event_add(win, &event);
+
+                       break;
+               }
+
                case GHOST_kEventUnknown:
                case GHOST_kNumEventTypes:
                        break;
index 70bdb60eb48bb2a95cb55f653946364fbf1a83ab..ec2e750eb2c31301c76e7558f92021c7ba787666 100644 (file)
@@ -405,12 +405,11 @@ static void wm_window_match_do(bContext *C, ListBase *wmlist)
                        for(wm= wmlist->first; wm; wm= wm->id.next) {
                                for(win= wm->windows.first; win; win= win->next) {
                                        win->screen= (bScreen *)find_id("SR", win->screenname);
-                                       if(win->screen->winid==0) {
-                                               if(win->screen==NULL)
-                                                       win->screen= C->screen; /* active screen */
-                                               
+                                       if(win->screen==NULL)
+                                               win->screen= C->screen; /* active screen */
+
+                                       if(win->screen->winid==0)
                                                win->screen->winid= win->winid;
-                                       }
                                }
                        }
                        /* XXX still solve, case where multiple windows open */
index b0789ba08ed06afc3a7377449038184a8d8c3a96..cfd111d355c849fa84ed4dde4d77d9bc8d974678 100644 (file)
@@ -46,6 +46,7 @@
 #include "BIF_glutil.h"
 
 #include "WM_api.h"
+#include "wm_subwindow.h"
 #include "wm_window.h"
 
 /* wmSubWindow stored in wmWindow... but not exposed outside this C file */
@@ -88,24 +89,6 @@ void wm_subwindows_free(wmWindow *win)
 }
 
 
-void wm_subwindow_getsize(wmWindow *win, int *x, int *y) 
-{
-       if(win->curswin) {
-               wmSubWindow *swin= win->curswin;
-               *x= swin->winrct.xmax - swin->winrct.xmin + 1;
-               *y= swin->winrct.ymax - swin->winrct.ymin + 1;
-       }
-}
-
-void wm_subwindow_getorigin(wmWindow *win, int *x, int *y)
-{
-       if(win->curswin) {
-               wmSubWindow *swin= win->curswin;
-               *x= swin->winrct.xmin;
-               *y= swin->winrct.ymin;
-       }
-}
-
 int wm_subwindow_get(wmWindow *win)    
 {
        if(win->curswin)
@@ -123,6 +106,34 @@ static wmSubWindow *swin_from_swinid(wmWindow *win, int swinid)
        return swin;
 }
 
+void wm_subwindow_getsize(wmWindow *win, int swinid, int *x, int *y) 
+{
+       wmSubWindow *swin= swin_from_swinid(win, swinid);
+
+       if(swin) {
+               *x= swin->winrct.xmax - swin->winrct.xmin + 1;
+               *y= swin->winrct.ymax - swin->winrct.ymin + 1;
+       }
+}
+
+void wm_subwindow_getorigin(wmWindow *win, int swinid, int *x, int *y)
+{
+       wmSubWindow *swin= swin_from_swinid(win, swinid);
+
+       if(swin) {
+               *x= swin->winrct.xmin;
+               *y= swin->winrct.ymin;
+       }
+}
+
+void wm_subwindow_getmatrix(wmWindow *win, int swinid, float mat[][4])
+{
+       wmSubWindow *swin= swin_from_swinid(win, swinid);
+
+       if(swin)
+               Mat4MulMat4(mat, swin->viewmat, swin->winmat);
+}
+
 void wm_subwindow_set(wmWindow *win, int swinid)
 {
        wmSubWindow *swin= swin_from_swinid(win, swinid);
@@ -134,7 +145,7 @@ void wm_subwindow_set(wmWindow *win, int swinid)
        }
        
        win->curswin= swin;
-       wm_subwindow_getsize(win, &width, &height);
+       wm_subwindow_getsize(win, swinid, &width, &height);
 
        glViewport(swin->winrct.xmin, swin->winrct.ymin, width, height);
        glScissor(swin->winrct.xmin, swin->winrct.ymin, width, height);
@@ -174,7 +185,7 @@ int wm_subwindow_open(wmWindow *win, rcti *winrct)
        wm_subwindow_set(win, swin->swinid);
        
        /* extra service */
-       wm_subwindow_getsize(win, &width, &height);
+       wm_subwindow_getsize(win, swin->swinid, &width, &height);
        wmOrtho2(win, -0.375, (float)width-0.375, -0.375, (float)height-0.375);
        wmLoadIdentity(win);
 
@@ -229,7 +240,7 @@ void wm_subwindow_position(wmWindow *win, int swinid, rcti *winrct)
                
                /* extra service */
                wm_subwindow_set(win, swinid);
-               wm_subwindow_getsize(win, &width, &height);
+               wm_subwindow_getsize(win, swinid, &width, &height);
                wmOrtho2(win, -0.375, (float)width-0.375, -0.375, (float)height-0.375);
        }
        else {
@@ -515,18 +526,3 @@ void myswapbuffers(void)   /* XXX */
 #endif
 }
 
-
-/* *********************** PATTERNS ETC ***************** */
-
-void setlinestyle(int nr)      /* Move? XXX */
-{
-       if(nr==0) {
-               glDisable(GL_LINE_STIPPLE);
-       }
-       else {
-               
-               glEnable(GL_LINE_STIPPLE);
-               glLineStipple(nr, 0xAAAA);
-       }
-}
-
index 9425dd6cf58d4c17cfc22be07f8d2518220b35a9..259e16a389a4ee5aedd5dbb4ab3cd16f8bd7b96f 100644 (file)
@@ -76,12 +76,6 @@ static void wm_get_screensize(int *width_r, int *height_r)
 
 static void wm_ghostwindow_destroy(wmWindow *win) 
 {
-       
-       if (win->timer) {
-               GHOST_RemoveTimer(g_system, (GHOST_TimerTaskHandle)win->timer);
-               win->timer= NULL;
-       }
-       
        if(win->ghostwin) {
                GHOST_DisposeWindow(g_system, win->ghostwin);
                win->ghostwin= NULL;
@@ -91,6 +85,7 @@ static void wm_ghostwindow_destroy(wmWindow *win)
 /* including window itself */
 void wm_window_free(bContext *C, wmWindow *win)
 {
+       ED_screen_exit(C, win, win->screen);
        
        /* update context */
        if(C) {
@@ -103,12 +98,12 @@ void wm_window_free(bContext *C, wmWindow *win)
                if(C->screen==win->screen)
                        C->screen= NULL;
        }       
+
        /* XXX free screens */
        
        if(win->eventstate) MEM_freeN(win->eventstate);
 
        WM_gesture_free(win);
-       wm_event_free_handlers(&win->handlers);
        wm_event_free_all(win);
        wm_subwindows_free(win);
        
@@ -276,8 +271,8 @@ static void wm_window_open(wmWindowManager *wm, char *title, wmWindow *win)
                        win->eventstate= MEM_callocN(sizeof(wmEvent), "window event state");
                
                /* add keymap handlers (1 for all keys in map!) */
-               WM_event_add_keymap_handler(&wm->windowkeymap, &win->handlers);
-               WM_event_add_keymap_handler(&wm->screenkeymap, &win->handlers);
+               WM_event_add_keymap_handler(&win->handlers, &wm->windowkeymap);
+               WM_event_add_keymap_handler(&win->handlers, &wm->screenkeymap);
                
                /* until screens get drawn, make it nice grey */
                glClearColor(.55, .55, .55, 0.0);
@@ -523,19 +518,24 @@ void wm_ghost_init(bContext *C)
 
 /* **************** timer ********************** */
 
-static void window_timer_proc(GHOST_TimerTaskHandle timer, GHOST_TUns64 time)
+static void window_event_timer_proc(GHOST_TimerTaskHandle timer, GHOST_TUns64 time)
 {
-       wmWindow *win= GHOST_GetTimerTaskUserData(timer);
-       
-       wm_event_add_ghostevent(win, win->timer_event, NULL);
+       wmWindow *window;
+
+       window= GHOST_GetTimerTaskUserData(timer);
+
+       wm_event_add_ghostevent(window, GHOST_kEventTimer, (wmTimerHandle*)timer);
 }
 
-void wm_window_set_timer(wmWindow *win, int delay_ms, int event)
+wmTimerHandle *WM_event_add_window_timer(wmWindow *win, int delay_ms, int interval_ms)
 {
-       if (win->timer) GHOST_RemoveTimer(g_system, win->timer);
-       
-       win->timer_event= event;
-       win->timer= GHOST_InstallTimer(g_system, delay_ms, delay_ms, window_timer_proc, win);
+       return (wmTimerHandle*)GHOST_InstallTimer(g_system, delay_ms, interval_ms,
+               window_event_timer_proc, win);
+}
+
+void WM_event_remove_window_timer(wmWindow *wm, wmTimerHandle *handle)
+{
+       GHOST_RemoveTimer(g_system, (GHOST_TimerTaskHandle)handle);
 }
 
 /* ************************************ */
index 842bf0fce845628f22c762412edd5d3a22a245c2..0e2a7c3b9fb23e1fd62b7c514052ff320f17fb1b 100644 (file)
@@ -38,6 +38,8 @@
 /* custom data type */
 #define EVT_TABLET     1
 #define EVT_GESTURE    2
+#define EVT_TIMER      3
+#define EVT_MESSAGE    4
 
 #define MOUSEX         0x004   
 #define MOUSEY         0x005   
 
 
 /* SYSTEM : 0x01x */
-#define KEYBD                  0x010   /* keyboard */
-#define RAWKEYBD               0x011   /* raw keyboard for keyboard manager */
-#define REDRAW                 0x012   /* used by port manager to signal redraws */
-#define        INPUTCHANGE             0x013   /* input connected or disconnected */
-#define        QFULL                   0x014   /* queue was filled */
-#define WINFREEZE              0x015   /* user wants process in this win to shut up */
-#define WINTHAW                        0x016   /* user wants process in this win to go again */
-#define WINCLOSE               0x017   /* window close */
-#define WINQUIT                        0x018   /* signal from user that app is to go away */
-#define Q_FIRSTTIME            0x019   /* on startup */
+#define KEYBD                  0x0100  /* keyboard */
+#define RAWKEYBD               0x0101  /* raw keyboard for keyboard manager */
+#define REDRAW                 0x0102  /* used by port manager to signal redraws */
+#define        INPUTCHANGE             0x0103  /* input connected or disconnected */
+#define        QFULL                   0x0104  /* queue was filled */
+#define WINFREEZE              0x0105  /* user wants process in this win to shut up */
+#define WINTHAW                        0x0106  /* user wants process in this win to go again */
+#define WINCLOSE               0x0107  /* window close */
+#define WINQUIT                        0x0108  /* signal from user that app is to go away */
+#define Q_FIRSTTIME            0x0109  /* on startup */
+#define TIMER                  0x0110  /* timer event */
+#define MESSAGE                        0x0111  /* message event */
 
 /* standard keyboard */
 
index b4d12d1358c9bf48b04867a36e5d14ce68c8ae15..0e8c76a8eece4c9db0c6aae1ec7889d252879b73 100644 (file)
@@ -42,9 +42,9 @@ int           wm_subwindow_get(wmWindow *win);                                /* returns id */
 
 void   wm_subwindow_position(wmWindow *win, int swinid, rcti *winrct);
 
-
-void   wm_subwindow_getsize(wmWindow *win, int *x, int *y);
-void   wm_subwindow_getorigin(wmWindow *win, int *x, int *y);
+void   wm_subwindow_getsize(wmWindow *win, int swinid, int *x, int *y);
+void   wm_subwindow_getorigin(wmWindow *win, int swinid, int *x, int *y);
+void   wm_subwindow_getmatrix(wmWindow *win, int swinid, float mat[][4]);
 
 
 #endif /* WM_SUBWINDOW_H */