2.5
[blender-staging.git] / source / blender / windowmanager / intern / wm_window.c
index 16ed2e7b4e5b3eaf244c2257df57e08966c3cb8d..884abc1fa256e35f9f52c146cf028b6c41534efb 100644 (file)
@@ -21,7 +21,7 @@
  * on ghostwinlay.c (C) 2001-2002 by NaN Holding BV
  * All rights reserved.
  *
- * Contributor(s): Blender Foundation
+ * Contributor(s): Blender Foundation, 2008
  *
  * ***** END GPL LICENSE BLOCK *****
  */
 #include "BIF_gl.h"
 
 #include "WM_api.h"
+#include "WM_types.h"
 #include "wm.h"
 #include "wm_window.h"
+#include "wm_subwindow.h"
 #include "wm_event_system.h"
 
+#include "ED_screen.h"
+
 /* the global to talk to ghost */
 GHOST_SystemHandle g_system= NULL;
 
@@ -72,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;
@@ -87,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) {
@@ -99,14 +98,14 @@ 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);
-       
-       BLI_freelistN(&win->queue);
-       wm_event_free_handlers(&win->handlers);
-       
+
        wm_event_free_all(win);
+       wm_subwindows_free(win);
+       
        wm_ghostwindow_destroy(win);
        
        MEM_freeN(win);
@@ -125,38 +124,32 @@ static int find_free_winid(wmWindowManager *wm)
 }
 
 /* dont change context itself */
-wmWindow *wm_window_new(bContext *C, bScreen *screen)
+wmWindow *wm_window_new(bContext *C)
 {
        wmWindow *win= MEM_callocN(sizeof(wmWindow), "window");
        
        BLI_addtail(&C->wm->windows, win);
        win->winid= find_free_winid(C->wm);
 
-       win->screen= screen;
        return win;
 }
 
+
 /* part of wm_window.c api */
 wmWindow *wm_window_copy(bContext *C, wmWindow *winorig)
 {
-       wmWindow *win= wm_window_new(C, winorig->screen); /* XXX need copy */
+       wmWindow *win= wm_window_new(C);
        
        win->posx= winorig->posx+10;
        win->posy= winorig->posy;
        win->sizex= winorig->sizex;
        win->sizey= winorig->sizey;
        
-       return win;
-}
-
-/* operator callback */
-int wm_window_duplicate_op(bContext *C, wmOperator *op)
-{
-       
-       wm_window_copy(C, C->window);
-       wm_check(C);
+       win->screen= ED_screen_duplicate(win, winorig->screen);
+       win->screen->do_refresh= 1;
+       win->screen->do_draw= 1;
        
-       return 1;
+       return win;
 }
 
 /* this is event from ghost */
@@ -169,7 +162,8 @@ static void wm_window_close(bContext *C, wmWindow *win)
                WM_exit(C);
 }
 
-static void wm_window_open(wmWindowManager *wm, char *title, wmWindow *win)
+/* belongs to below */
+static void wm_window_add_ghostwindow(wmWindowManager *wm, char *title, wmWindow *win)
 {
        GHOST_WindowHandle ghostwin;
        GHOST_TWindowState inital_state;
@@ -178,12 +172,9 @@ static void wm_window_open(wmWindowManager *wm, char *title, wmWindow *win)
        wm_get_screensize(&scr_w, &scr_h);
        posy= (scr_h - win->posy - win->sizey);
        
-       if (win->windowstate == G_WINDOWSTATE_FULLSCREEN)
-               inital_state = GHOST_kWindowStateFullScreen;
-       else if (win->windowstate == G_WINDOWSTATE_BORDER)
-               inital_state = GHOST_kWindowStateMaximized;
-       else
-               inital_state = GHOST_kWindowStateNormal;
+       //              inital_state = GHOST_kWindowStateFullScreen;
+       //              inital_state = GHOST_kWindowStateMaximized;
+       inital_state = GHOST_kWindowStateNormal;
        
 #ifdef __APPLE__
        {
@@ -199,26 +190,29 @@ static void wm_window_open(wmWindowManager *wm, char *title, wmWindow *win)
                                                                 0 /* no stereo */);
        
        if (ghostwin) {
-
+               
                win->ghostwin= ghostwin;
                GHOST_SetWindowUserData(ghostwin, win); /* pointer back */
                
                if(win->eventstate==NULL)
                        win->eventstate= MEM_callocN(sizeof(wmEvent), "window event state");
                
-               /* add keymap handler (1 for all keys in map!) */
-               WM_event_add_keymap_handler(&wm->windowkeymap, &win->handlers);
+               /* add keymap handlers (1 for all keys in map!) */
+               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);
                glClear(GL_COLOR_BUFFER_BIT);
                wm_window_swap_buffers(win);
+               
+               /* standard state vars for window */
+               glEnable(GL_SCISSOR_TEST);
        }
-       
-       
 }
 
 /* for wmWindows without ghostwin, open these and clear */
+/* window size is read from window, if 0 it uses prefsize */
 void wm_window_add_ghostwindows(wmWindowManager *wm)
 {
        wmWindow *win;
@@ -228,9 +222,11 @@ void wm_window_add_ghostwindows(wmWindowManager *wm)
                wm_get_screensize(&prefsizx, &prefsizy);
                
 #ifdef __APPLE__
-               extern void wm_set_apple_prefsize(int, int);    /* wm_apple.c */
-               
-               wm_set_apple_prefsize(prefsizx, prefsizy);
+               {
+                       extern void wm_set_apple_prefsize(int, int);    /* wm_apple.c */
+                       
+                       wm_set_apple_prefsize(prefsizx, prefsizy);
+               }
 #else
                prefstax= 0;
                prefstay= 0;
@@ -245,13 +241,70 @@ void wm_window_add_ghostwindows(wmWindowManager *wm)
                                win->posy= prefstay;
                                win->sizex= prefsizx;
                                win->sizey= prefsizy;
-                               win->windowstate= G.windowstate;
+                               win->windowstate= 0;
                        }
-                       wm_window_open(wm, "Blender", win);
+                       wm_window_add_ghostwindow(wm, "Blender", win);
                }
        }
 }
 
+/* new window, no screen yet, but we open ghostwindow for it */
+/* also gets the window level handlers */
+/* area-rip calls this */
+wmWindow *WM_window_open(bContext *C, rcti *rect)
+{
+       wmWindow *win= wm_window_new(C);
+       
+       win->posx= rect->xmin;
+       win->posy= rect->ymin;
+       win->sizex= rect->xmax - rect->xmin;
+       win->sizey= rect->ymax - rect->ymin;
+       
+       wm_window_add_ghostwindow(C->wm, "Blender", win);
+       
+       return win;
+}
+
+
+/* ****************** Operators ****************** */
+
+/* operator callback */
+int wm_window_duplicate_op(bContext *C, wmOperator *op)
+{
+       wm_window_copy(C, C->window);
+       wm_check(C);
+       
+       return OPERATOR_FINISHED;
+}
+
+
+/* fullscreen operator callback */
+int wm_window_fullscreen_toggle_op(bContext *C, wmOperator *op)
+{
+       GHOST_TWindowState state = GHOST_GetWindowState(C->window->ghostwin);
+       if(state!=GHOST_kWindowStateFullScreen)
+               GHOST_SetWindowState(C->window->ghostwin, GHOST_kWindowStateFullScreen);
+       else
+               GHOST_SetWindowState(C->window->ghostwin, GHOST_kWindowStateNormal);
+
+       return OPERATOR_FINISHED;
+       
+}
+
+       
+/* exit blender */
+int wm_exit_blender_op(bContext *C, wmOperator *op)
+{
+       wmWindow *win= C->wm->windows.first;
+       while(win) {
+               wm_window_close(C, win);
+               win= win->next;
+       }
+
+       return OPERATOR_FINISHED;
+}
+
+
 /* ************ events *************** */
 
 static int query_qual(char qual) 
@@ -281,19 +334,17 @@ static int query_qual(char qual)
 
 void wm_window_make_drawable(bContext *C, wmWindow *win) 
 {
-       if (win != C->window && win->ghostwin) {
+       if (win != C->wm->windrawable && win->ghostwin) {
 //             win->lmbut= 0;  /* keeps hanging when mousepressed while other window opened */
                
                C->wm->windrawable= win;
-               C->window= win;
-               C->screen= win->screen;
-               
+               if(G.f & G_DEBUG) printf("set drawable %d\n", win->winid);
                GHOST_ActivateWindowDrawingContext(win->ghostwin);
        }
 }
 
 /* called by ghost, here we handle events for windows themselves or send to event system */
-int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr private) 
+static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr private) 
 {
        bContext *C= private;
        GHOST_TEventType type= GHOST_GetEventType(evt);
@@ -328,12 +379,12 @@ int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr private)
                                GHOST_TEventKeyData kdata;
                                int cx, cy, wx, wy;
                                
-                               C->wm->winactive= win; /* no context change! c->window is drawable, or for area queues */
+                               C->wm->winactive= win; /* no context change! c->wm->windrawable is drawable, or for area queues */
                                
                                win->active= 1;
 //                             window_handle(win, INPUTCHANGE, win->active);
                                
-                               /* bad ghost support for modifier keys... */
+                               /* bad ghost support for modifier keys... so on activate we set the modifiers again */
                                kdata.ascii= 0;
                                if (win->eventstate->shift && !query_qual('s')) {
                                        kdata.key= GHOST_kKeyLeftShift;
@@ -359,6 +410,9 @@ int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr private)
                                win->eventstate->x= cx;
                                win->eventstate->y= (win->sizey-1) - cy;
                                
+                               ED_screen_set_subwinactive(win);        /* active subwindow in screen */
+                               
+                               wm_window_make_drawable(C, win);
                                break;
                        }
                        case GHOST_kEventWindowClose: {
@@ -366,7 +420,11 @@ int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr private)
                                break;
                        }
                        case GHOST_kEventWindowUpdate: {
-//                             window_handle(win, REDRAW, 1);
+                               if(G.f & G_DEBUG) printf("ghost redraw\n");
+                               
+                               wm_window_make_drawable(C, win);
+                               WM_event_add_notifier(C, WM_NOTE_WINDOW_REDRAW, 0, NULL);
+
                                break;
                        }
                        case GHOST_kEventWindowSize:
@@ -385,13 +443,38 @@ int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr private)
                                win->posx= l;
                                win->posy= scr_h - t - win->sizey;
 
-                               if(type!=GHOST_kEventWindowSize)
-                                       printf("win move event pos %d %d size %d %d\n", win->posx, win->posy, win->sizex, win->sizey);
+                               /* debug prints */
+                               if(0) {
+                                       GHOST_TWindowState state;
+                                       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);
+                                       }
+                                       
+                               }
+                               
+                               wm_window_make_drawable(C, win);
+                               WM_event_add_notifier(C, WM_NOTE_SCREEN_CHANGED, 0, NULL);
                                
-//                             window_handle(win, RESHAPE, 1);
                                break;
                        }
                        default:
+                               if(type==GHOST_kEventKeyDown) // XXX debug
+                                       WM_event_add_notifier(C, WM_NOTE_WINDOW_REDRAW, 0, NULL);
                                wm_event_add_ghostevent(win, type, data);
                                break;
                }
@@ -420,19 +503,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);
 }
 
 /* ************************************ */