Fix for problem drawing second level popup menus due to recent commit,
[blender.git] / source / blender / windowmanager / intern / wm_subwindow.c
index 2f4e90a2e71f69fc6a0efdaf9a9cc10f253880ab..97b3d3e800cd33e9c2a2ef75fb4ad2fe5d93d0bc 100644 (file)
@@ -1,5 +1,5 @@
 /**
- * $Id: mywindow.c 9584 2007-01-03 13:45:03Z ton $
+ * $Id$
  *
  * ***** BEGIN GPL LICENSE BLOCK *****
  *
 #include "DNA_screen_types.h"
 
 #include "BLI_blenlib.h"
-#include "BLI_arithb.h"
+#include "BLI_math.h"
 
+#include "BKE_context.h"
 #include "BKE_global.h"
 
 #include "BIF_gl.h"
 #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 */
@@ -64,8 +66,6 @@ typedef struct wmSubWindow {
        
        rcti winrct;
        int swinid;
-       
-       float viewmat[4][4], winmat[4][4];
 } wmSubWindow;
 
 
@@ -88,24 +88,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,29 +105,41 @@ static wmSubWindow *swin_from_swinid(wmWindow *win, int swinid)
        return swin;
 }
 
-void wm_subwindow_set(wmWindow *win, int swinid)
+void wm_subwindow_getsize(wmWindow *win, int swinid, int *x, int *y) 
 {
        wmSubWindow *swin= swin_from_swinid(win, swinid);
-       int width, height;
-       
-       if(swin==NULL) {
-               printf("wm_subwindow_set %d: doesn't exist\n", swinid);
-               return;
+
+       if(swin) {
+               *x= swin->winrct.xmax - swin->winrct.xmin + 1;
+               *y= swin->winrct.ymax - swin->winrct.ymin + 1;
        }
-       
-       win->curswin= swin;
-       wm_subwindow_getsize(win, &width, &height);
-       
-       glViewport(swin->winrct.xmin, swin->winrct.ymin, width, height);
-       glScissor(swin->winrct.xmin, swin->winrct.ymin, width, height);
-       
-       glMatrixMode(GL_PROJECTION);
-       glLoadMatrixf(&swin->winmat[0][0]);
-       glMatrixMode(GL_MODELVIEW);
-       glLoadMatrixf(&swin->viewmat[0][0]);
+}
 
-       glFlush();
-       
+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) {
+               /* used by UI, should find a better way to get the matrix there */
+               if(swinid == win->screen->mainwin) {
+                       int width, height;
+
+                       wm_subwindow_getsize(win, swin->swinid, &width, &height);
+                       orthographic_m4(mat, -0.375, (float)width-0.375, -0.375, (float)height-0.375, -100, 100);
+               }
+               else
+                       glGetFloatv(GL_PROJECTION_MATRIX, (float*)mat);
+       }
 }
 
 /* always sets pixel-precise 2D window/view matrices */
@@ -161,20 +155,19 @@ int wm_subwindow_open(wmWindow *win, rcti *winrct)
                        freewinid= swin->swinid+1;
 
        win->curswin= swin= MEM_callocN(sizeof(wmSubWindow), "swinopen");
-
+       BLI_addtail(&win->subwindows, swin);
+       
+       if(G.f & G_DEBUG) printf("swin %d added\n", freewinid);
        swin->swinid= freewinid;
        swin->winrct= *winrct;
 
-       Mat4One(swin->viewmat);
-       Mat4One(swin->winmat);
+       /* and we appy it all right away */
+       wmSubWindowSet(win, swin->swinid);
        
        /* extra service */
-       wm_subwindow_getsize(win, &width, &height);
-       wmOrtho2(win, -0.375, (float)width-0.375, -0.375, (float)height-0.375);
-       wmLoadIdentity(win);
-       
-       /* and we appy it all right away */
-       wm_subwindow_set(win, swin->swinid);
+       wm_subwindow_getsize(win, swin->swinid, &width, &height);
+       wmOrtho2(-0.375, (float)width-0.375, -0.375, (float)height-0.375);
+       glLoadIdentity();
 
        return swin->swinid;
 }
@@ -203,6 +196,8 @@ void wm_subwindow_position(wmWindow *win, int swinid, rcti *winrct)
        wmSubWindow *swin= swin_from_swinid(win, swinid);
        
        if(swin) {
+               int width, height;
+               
                swin->winrct= *winrct;
                
                /* CRITICAL, this clamping ensures that
@@ -218,10 +213,15 @@ void wm_subwindow_position(wmWindow *win, int swinid, rcti *winrct)
                    * fixed it). - zr  (2001!)
                        */
                
-               if (swin->winrct.xmax >= win->sizex)
-                       swin->winrct.xmax= win->sizex-1;
-               if (swin->winrct.ymax >= win->sizey)
-                       swin->winrct.ymax= win->sizey-1;
+               if (swin->winrct.xmax > win->sizex)
+                       swin->winrct.xmax= win->sizex;
+               if (swin->winrct.ymax > win->sizey)
+                       swin->winrct.ymax= win->sizey;
+               
+               /* extra service */
+               wmSubWindowSet(win, swinid);
+               wm_subwindow_getsize(win, swinid, &width, &height);
+               wmOrtho2(-0.375, (float)width-0.375, -0.375, (float)height-0.375);
        }
        else {
                printf("wm_subwindow_position: Internal error, bad winid: %d\n", swinid);
@@ -231,112 +231,74 @@ void wm_subwindow_position(wmWindow *win, int swinid, rcti *winrct)
 /* ---------------- WM versions of OpenGL calls, using glBlah() syntax ------------------------ */
 /* ----------------- exported in WM_api.h ------------------------------------------------------ */
 
-int glaGetOneInteger(int a)
-{
-       return 0; // XXX
-}
-
-void wmLoadMatrix(wmWindow *win, float mat[][4])
-{
-       if(win->curswin==NULL) return;
-       
-       glLoadMatrixf(mat);
-       
-       if (glaGetOneInteger(GL_MATRIX_MODE)==GL_MODELVIEW)
-               Mat4CpyMat4(win->curswin->viewmat, mat);
-       else
-               Mat4CpyMat4(win->curswin->winmat, mat);
-}
+/* internal state, no threaded opengl! XXX */
+static wmWindow *_curwindow= NULL;
+static wmSubWindow *_curswin= NULL;
 
-void wmGetMatrix(wmWindow *win, float mat[][4])
+void wmSubWindowScissorSet(wmWindow *win, int swinid, rcti *srct)
 {
-       if(win->curswin==NULL) return;
+       int width, height;
+       _curswin= swin_from_swinid(win, swinid);
        
-       if (glaGetOneInteger(GL_MATRIX_MODE)==GL_MODELVIEW) {
-               Mat4CpyMat4(mat, win->curswin->viewmat);
-       } else {
-               Mat4CpyMat4(mat, win->curswin->winmat);
+       if(_curswin==NULL) {
+               printf("wmSubWindowSet %d: doesn't exist\n", swinid);
+               return;
        }
-}
-
-void wmMultMatrix(wmWindow *win, float mat[][4])
-{
-       if(win->curswin==NULL) return;
        
-       glMultMatrixf((float*) mat);
+       win->curswin= _curswin;
+       _curwindow= win;
        
-       if (glaGetOneInteger(GL_MATRIX_MODE)==GL_MODELVIEW)
-               glGetFloatv(GL_MODELVIEW_MATRIX, (float *)win->curswin->viewmat);
+       width= _curswin->winrct.xmax - _curswin->winrct.xmin + 1;
+       height= _curswin->winrct.ymax - _curswin->winrct.ymin + 1;
+       glViewport(_curswin->winrct.xmin, _curswin->winrct.ymin, width, height);
+
+       if(srct) {
+               width= srct->xmax - srct->xmin + 1;
+               height= srct->ymax - srct->ymin + 1;
+               glScissor(srct->xmin, srct->ymin, width, height);
+       }
        else
-               glGetFloatv(GL_MODELVIEW_MATRIX, (float *)win->curswin->winmat);
-}
+               glScissor(_curswin->winrct.xmin, _curswin->winrct.ymin, width, height);
+       
+       wmOrtho2(-0.375, (float)width-0.375, -0.375, (float)height-0.375);
+       glLoadIdentity();
 
-void wmGetSingleMatrix(wmWindow *win, float mat[][4])
-{
-       if(win->curswin)
-               Mat4MulMat4(mat, win->curswin->viewmat, win->curswin->winmat);
+       glFlush();
 }
 
-void wmScale(wmWindow *win, float x, float y, float z)
+
+/* enable the WM versions of opengl calls */
+void wmSubWindowSet(wmWindow *win, int swinid)
 {
-       if(win->curswin==NULL) return;
-       
-       glScalef(x, y, z);
-       
-       if (glaGetOneInteger(GL_MATRIX_MODE)==GL_MODELVIEW)
-               glGetFloatv(GL_MODELVIEW_MATRIX, (float *)win->curswin->viewmat);
-       else
-               glGetFloatv(GL_MODELVIEW_MATRIX, (float *)win->curswin->winmat);
-       
+       wmSubWindowScissorSet(win, swinid, NULL);
 }
 
-void wmLoadIdentity(wmWindow *win)
+void wmFrustum(float x1, float x2, float y1, float y2, float n, float f)
 {
-       if(win->curswin==NULL) return;
-       
-       if (glaGetOneInteger(GL_MATRIX_MODE)==GL_MODELVIEW)
-               Mat4One(win->curswin->viewmat);
-       else
-               Mat4One(win->curswin->winmat);
-       
+       glMatrixMode(GL_PROJECTION);
        glLoadIdentity();
+       glFrustum(x1, x2, y1, y2, n, f);
+       glMatrixMode(GL_MODELVIEW);
 }
 
-void wmFrustum(wmWindow *win, float x1, float x2, float y1, float y2, float n, float f)
+void wmOrtho(float x1, float x2, float y1, float y2, float n, float f)
 {
-       if(win->curswin) {
-
-               glMatrixMode(GL_PROJECTION);
-               glLoadIdentity();
-               glFrustum(x1, x2, y1, y2, n, f);
+       glMatrixMode(GL_PROJECTION);
+       glLoadIdentity();
 
-               glGetFloatv(GL_PROJECTION_MATRIX, (float *)win->curswin->winmat);
-               glMatrixMode(GL_MODELVIEW);
-       }
-}
+       glOrtho(x1, x2, y1, y2, n, f);
 
-void wmOrtho(wmWindow *win, float x1, float x2, float y1, float y2, float n, float f)
-{
-       if(win->curswin) {
-               
-               glMatrixMode(GL_PROJECTION);
-               glLoadIdentity();
-               
-               glOrtho(x1, x2, y1, y2, n, f);
-               
-               glGetFloatv(GL_PROJECTION_MATRIX, (float *)win->curswin->winmat);
-               glMatrixMode(GL_MODELVIEW);
-       }
+       glMatrixMode(GL_MODELVIEW);
 }
 
-void wmOrtho2(wmWindow *win, float x1, float x2, float y1, float y2)
+void wmOrtho2(float x1, float x2, float y1, float y2)
 {
        /* prevent opengl from generating errors */
        if(x1==x2) x2+=1.0;
        if(y1==y2) y2+=1.0;
-       wmOrtho(win, x1, x2, y1, y2, -100, 100);
-}
 
+       wmOrtho(x1, x2, y1, y2, -100, 100);
+}
 
 /* *************************** Framebuffer color depth, for selection codes ********************** */
 
@@ -366,7 +328,7 @@ static int wm_get_colordepth(void)
 
 /* apple seems to round colors to below and up on some configs */
 
-static unsigned int index_to_framebuffer(int index)
+unsigned int index_to_framebuffer(int index)
 {
        unsigned int i= index;
 
@@ -396,7 +358,7 @@ static unsigned int index_to_framebuffer(int index)
 
 /* this is the old method as being in use for ages.... seems to work? colors are rounded to lower values */
 
-static unsigned int index_to_framebuffer(int index)
+unsigned int index_to_framebuffer(int index)
 {
        unsigned int i= index;
        
@@ -428,12 +390,12 @@ static unsigned int index_to_framebuffer(int index)
 
 #endif
 
-void set_framebuffer_index_color(int index)
+void WM_set_framebuffer_index_color(int index)
 {
        cpack(index_to_framebuffer(index));
 }
 
-int framebuffer_to_index(unsigned int col)
+int WM_framebuffer_to_index(unsigned int col)
 {
        if (col==0) return 0;
 
@@ -455,73 +417,3 @@ int framebuffer_to_index(unsigned int col)
 
 /* ********** END MY WINDOW ************** */
 
-#ifdef WIN32
-static int is_a_really_crappy_nvidia_card(void) {
-       static int well_is_it= -1;
-
-               /* Do you understand the implication? Do you? */
-       if (well_is_it==-1)
-               well_is_it= (strcmp((char*) glGetString(GL_VENDOR), "NVIDIA Corporation") == 0);
-
-       return well_is_it;
-}
-#endif
-
-void myswapbuffers(void)       /* XXX */
-{
-       ScrArea *sa;
-       
-       sa= G.curscreen->areabase.first;
-       while(sa) {
-               if(sa->win_swap==WIN_BACK_OK) sa->win_swap= WIN_FRONT_OK;
-               if(sa->head_swap==WIN_BACK_OK) sa->head_swap= WIN_FRONT_OK;
-               
-               sa= sa->next;
-       }
-
-       /* HACK, some windows drivers feel they should honor the scissor
-        * test when swapping buffers, disable the test while swapping
-        * on WIN32. (namely Matrox and NVidia's new drivers around Oct 1 2001)
-        * - zr
-        */
-
-#ifdef WIN32
-               /* HACK, in some NVidia driver release some kind of
-                * fancy optimiziation (I presume) was put in which for
-                * some reason causes parts of the buffer not to be
-                * swapped. One way to defeat it is the following wierd
-                * code (which we only do for nvidia cards). This should
-                * be removed if NVidia fixes their drivers. - zr
-                */
-       if (is_a_really_crappy_nvidia_card()) {
-               glDrawBuffer(GL_FRONT);
-
-               glBegin(GL_LINES);
-               glEnd();
-
-               glDrawBuffer(GL_BACK);
-       }
-
-       glDisable(GL_SCISSOR_TEST);
-//     window_swap_buffers(winlay_mainwindow);
-       glEnable(GL_SCISSOR_TEST);
-#else
-//     window_swap_buffers(winlay_mainwindow);
-#endif
-}
-
-
-/* *********************** PATTERNS ETC ***************** */
-
-void setlinestyle(int nr)      /* Move? XXX */
-{
-       if(nr==0) {
-               glDisable(GL_LINE_STIPPLE);
-       }
-       else {
-               
-               glEnable(GL_LINE_STIPPLE);
-               glLineStipple(nr, 0xAAAA);
-       }
-}
-