From 2df4ef711a6dcb2c8874861a181bbc31d0e37f52 Mon Sep 17 00:00:00 2001 From: Ton Roosendaal Date: Tue, 1 Jan 2008 15:53:38 +0000 Subject: [PATCH] More work on restoring Blender; - brining back subwindow management - removing more bad level stuff --- source/blender/Makefile | 4 +- source/blender/blenkernel/intern/blender.c | 18 +- source/blender/blenlib/intern/BLI_ghash.c | 18 +- source/blender/blenloader/intern/readfile.c | 26 +- source/blender/blenloader/intern/writefile.c | 33 +- source/blender/makesdna/DNA_screen_types.h | 19 +- .../makesdna/DNA_windowmanager_types.h | 11 +- source/blender/windowmanager/WM_api.h | 12 + source/blender/windowmanager/WM_types.h | 8 + .../blender/windowmanager/intern/wm_files.c | 25 +- .../windowmanager/intern/wm_init_exit.c | 33 +- .../windowmanager/intern/wm_operators.c | 2 - .../windowmanager/intern/wm_subwindow.c | 527 ++++++++++++++++++ .../blender/windowmanager/intern/wm_window.c | 11 +- source/blender/windowmanager/wm_subwindow.h | 51 ++ 15 files changed, 670 insertions(+), 128 deletions(-) create mode 100644 source/blender/windowmanager/intern/wm_subwindow.c create mode 100644 source/blender/windowmanager/wm_subwindow.h diff --git a/source/blender/Makefile b/source/blender/Makefile index 819735400db..0c0b65599ba 100644 --- a/source/blender/Makefile +++ b/source/blender/Makefile @@ -33,10 +33,10 @@ include nan_definitions.mk -DIRS = windowmanager blenloader readblenfile +DIRS = windowmanager editors blenloader readblenfile DIRS += avi imbuf render radiosity blenlib blenkernel blenpluginapi -DIRS += makesdna yafray DIRS += nodes +DIRS += makesdna yafray ifeq ($(INTERNATIONAL), true) DIRS += ftfont diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c index 0935a7161b0..63aa861093e 100644 --- a/source/blender/blenkernel/intern/blender.c +++ b/source/blender/blenkernel/intern/blender.c @@ -84,10 +84,6 @@ #include "BLO_writefile.h" #include "BKE_utildefines.h" // O_BINARY FALSE -#include "BIF_mainqueue.h" // mainqenter for onload script -#include "mydevice.h" -#include "nla.h" -#include "blendef.h" Global G; @@ -411,7 +407,7 @@ static void setup_app_data(bContext *C, BlendFileData *bfd, char *filename) if (G.f & G_DOSCRIPTLINKS) { /* there's an onload scriptlink to execute in screenmain */ - mainqenter(ONLOAD_SCRIPT, 1); +// XXX mainqenter(ONLOAD_SCRIPT, 1); } if (G.sce != filename) /* these are the same at times, should never copy to the same location */ strcpy(G.sce, filename); @@ -430,7 +426,7 @@ static void handle_subversion_warning(Main *main) char str[128]; sprintf(str, "File written by newer Blender binary: %d.%d , expect loss of data!", main->minversionfile, main->minsubversionfile); - error(str); +// XXX error(str); } } @@ -456,7 +452,7 @@ int BKE_read_file(bContext *C, char *dir, void *unused) handle_subversion_warning(G.main); } else { - error("Loading %s failed: %s", dir, BLO_bre_as_string(bre)); +// XXX error("Loading %s failed: %s", dir, BLO_bre_as_string(bre)); } return (bfd?retval:0); @@ -471,7 +467,7 @@ int BKE_read_file_from_memory(bContext *C, char* filebuf, int filelength, void * if (bfd) { setup_app_data(C, bfd, ""); } else { - error("Loading failed: %s", BLO_bre_as_string(bre)); +// XXX error("Loading failed: %s", BLO_bre_as_string(bre)); } return (bfd?1:0); @@ -487,7 +483,7 @@ int BKE_read_file_from_memfile(bContext *C, MemFile *memfile) if (bfd) { setup_app_data(C, bfd, ""); } else { - error("Loading failed: %s", BLO_bre_as_string(bre)); +// XXX error("Loading failed: %s", BLO_bre_as_string(bre)); } return (bfd?1:0); @@ -609,7 +605,7 @@ void BKE_undo_step(bContext *C, int step) } else if(step==1) { /* curundo should never be NULL, after restart or load file it should call undo_save */ - if(curundo==NULL || curundo->prev==NULL) error("No undo available"); + if(curundo==NULL || curundo->prev==NULL) ; // XXX error("No undo available"); else { if(G.f & G_DEBUG) printf("undo %s\n", curundo->name); curundo= curundo->prev; @@ -620,7 +616,7 @@ void BKE_undo_step(bContext *C, int step) /* curundo has to remain current situation! */ - if(curundo==NULL || curundo->next==NULL) error("No redo available"); + if(curundo==NULL || curundo->next==NULL) ; // XXX error("No redo available"); else { read_undosave(C, curundo->next); curundo= curundo->next; diff --git a/source/blender/blenlib/intern/BLI_ghash.c b/source/blender/blenlib/intern/BLI_ghash.c index 5846bbda40e..6af377edfba 100644 --- a/source/blender/blenlib/intern/BLI_ghash.c +++ b/source/blender/blenlib/intern/BLI_ghash.c @@ -117,14 +117,16 @@ void BLI_ghash_insert(GHash *gh, void *key, void *val) { } } -void* BLI_ghash_lookup(GHash *gh, void *key) { - unsigned int hash= gh->hashfp(key)%gh->nbuckets; - Entry *e; - - for (e= gh->buckets[hash]; e; e= e->next) - if (gh->cmpfp(key, e->key)==0) - return e->val; - +void* BLI_ghash_lookup(GHash *gh, void *key) +{ + if(gh) { + unsigned int hash= gh->hashfp(key)%gh->nbuckets; + Entry *e; + + for (e= gh->buckets[hash]; e; e= e->next) + if (gh->cmpfp(key, e->key)==0) + return e->val; + } return NULL; } diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 14aab7f4d47..508756141df 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -3502,9 +3502,11 @@ static void direct_link_windowmanager(FileData *fd, wmWindowManager *wm) for(win= wm->windows.first; win; win= win->next) { win->ghostwin= NULL; win->eventstate= NULL; + win->curswin= NULL; win->queue.first= win->queue.last= NULL; win->handlers.first= win->handlers.last= NULL; + win->subwindows.first= win->subwindows.last= NULL; } wm->operators.first= wm->operators.last= NULL; @@ -3844,8 +3846,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->winakt= 0; + sc->mainwin= sc->subwinactive= NULL; sc->handlers.first= sc->handlers.last= NULL; /* hacky patch... but people have been saving files with the verse-blender, @@ -3858,8 +3860,7 @@ static void direct_link_screen(FileData *fd, bScreen *sc) } /* edges */ - se= sc->edgebase.first; - while(se) { + for(se= sc->edgebase.first; se; se= se->next) { se->v1= newdataadr(fd, se->v1); se->v2= newdataadr(fd, se->v2); if( (long)se->v1 > (long)se->v2) { @@ -3872,20 +3873,20 @@ static void direct_link_screen(FileData *fd, bScreen *sc) printf("error reading screen... file corrupt\n"); se->v1= se->v2; } - se= se->next; } /* areas */ - sa= sc->areabase.first; - while(sa) { + for(sa= sc->areabase.first; sa; sa= sa->next) { Panel *pa; SpaceLink *sl; + ARegion *ar; link_list(fd, &(sa->spacedata)); link_list(fd, &(sa->panels)); + link_list(fd, &(sa->regionbase)); sa->handlers.first= sa->handlers.last= NULL; - sa->regionbase.first= sa->regionbase.last= NULL; + sa->uiblocks.first= sa->uiblocks.last= NULL; /* accident can happen when read/save new file with older version */ if(sa->spacedata.first==NULL && sa->spacetype>SPACE_NLA) @@ -3943,20 +3944,19 @@ static void direct_link_screen(FileData *fd, bScreen *sc) snode->flag |= SNODE_DO_PREVIEW; } } + + for(ar= sa->regionbase.first; ar; ar= ar->next) { + ar->handlers.first= ar->handlers.last= NULL; + ar->subwin= NULL; + } sa->v1= newdataadr(fd, sa->v1); sa->v2= newdataadr(fd, sa->v2); sa->v3= newdataadr(fd, sa->v3); sa->v4= newdataadr(fd, sa->v4); - sa->win= sa->headwin= 0; - - sa->uiblocks.first= sa->uiblocks.last= NULL; - /* space handler scriptlinks */ direct_link_scriptlink(fd, &sa->scriptlink); - - sa= sa->next; } } diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 5e0c551078a..e2a09380b47 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -1,7 +1,4 @@ -/* writefile.c - * - * .blend file writing - * +/* * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** @@ -1523,35 +1520,31 @@ static void write_screens(WriteData *wd, ListBase *scrbase) sc= scrbase->first; while(sc) { + /* write LibData */ writestruct(wd, ID_SCR, "Screen", 1, sc); - if (sc->id.properties) IDP_WriteProperty(sc->id.properties, wd); + if (sc->id.properties) + IDP_WriteProperty(sc->id.properties, wd); /* direct data */ - sv= sc->vertbase.first; - while(sv) { + for(sv= sc->vertbase.first; sv; sv= sv->next) writestruct(wd, DATA, "ScrVert", 1, sv); - sv= sv->next; - } - se= sc->edgebase.first; - while(se) { + for(se= sc->edgebase.first; se; se= se->next) writestruct(wd, DATA, "ScrEdge", 1, se); - se= se->next; - } - sa= sc->areabase.first; - while(sa) { + for(sa= sc->areabase.first; sa; sa= sa->next) { SpaceLink *sl; Panel *pa; + ARegion *ar; writestruct(wd, DATA, "ScrArea", 1, sa); - pa= sa->panels.first; - while(pa) { + for(pa= sa->panels.first; pa; pa= pa->next) writestruct(wd, DATA, "Panel", 1, pa); - pa= pa->next; - } + + for(ar= sa->regionbase.first; ar; ar= ar->next) + writestruct(wd, DATA, "ARegion", 1, ar); /* space handler scriptlinks */ write_scriptlink(wd, &sa->scriptlink); @@ -1642,8 +1635,6 @@ static void write_screens(WriteData *wd, ListBase *scrbase) } sl= sl->next; } - - sa= sa->next; } sc= sc->id.next; diff --git a/source/blender/makesdna/DNA_screen_types.h b/source/blender/makesdna/DNA_screen_types.h index 7b34ee2482d..127e658308a 100644 --- a/source/blender/makesdna/DNA_screen_types.h +++ b/source/blender/makesdna/DNA_screen_types.h @@ -1,6 +1,4 @@ /** - * blenlib/DNA_screen_types.h (mar-2001 nzc) - * * $Id$ * * ***** BEGIN GPL LICENSE BLOCK ***** @@ -37,6 +35,7 @@ #include "DNA_scriptlink_types.h" struct Scene; +struct wmSubWindow; typedef struct bScreen { ID id; @@ -46,11 +45,14 @@ typedef struct bScreen { short startx, endx, starty, endy; /* framebuffer coords */ short sizex, sizey; short scenenr, screennr; /* only for pupmenu */ - short full, winid; /* win id from WM, starts with 1 */ - short mainwin, winakt; + short full, winid; /* winid from WM, starts with 1 */ + int pad; short handler[8]; /* similar to space handler now */ - ListBase handlers; + struct wmSubWindow *mainwin; /* screensize subwindow, for screenedges */ + struct wmSubWindow *subwinactive; /* active subwindow */ + + ListBase handlers; /* wmEventHandler */ } bScreen; typedef struct ScrVert { @@ -101,7 +103,7 @@ typedef struct ScrArea { float winmat[4][4]; rcti totrct, headrct, winrct; - short headwin, win; + int pad; short headertype; /* 0=no header, 1= down, 2= up */ char spacetype, butspacetype; /* SPACE_... */ short winx, winy; /* size */ @@ -116,14 +118,15 @@ typedef struct ScrArea { ListBase spacedata; ListBase uiblocks; ListBase panels; - ListBase regionbase; - ListBase handlers; + ListBase regionbase; /* ARegion */ + ListBase handlers; /* wmEventHandler */ } ScrArea; typedef struct ARegion { struct ARegion *next, *prev; rcti winrct; + struct wmSubWindow *subwin; ListBase handlers; diff --git a/source/blender/makesdna/DNA_windowmanager_types.h b/source/blender/makesdna/DNA_windowmanager_types.h index dd05e5ee397..de32fe67fe6 100644 --- a/source/blender/makesdna/DNA_windowmanager_types.h +++ b/source/blender/makesdna/DNA_windowmanager_types.h @@ -46,6 +46,7 @@ struct bContext; struct wmLocal; struct bScreen; struct uiBlock; +struct wmSubWindow; /* windowmanager is saved, tag WMAN */ typedef struct wmWindowManager { @@ -83,12 +84,16 @@ typedef struct wmWindow { short windowstate; /* borderless, full */ short monitor; /* multiscreen... no idea how to store yet */ short active; /* set to 1 if an active window, for quick rejects */ - short cursor; /* mouse cursor */ + short cursor; /* current mouse cursor type */ struct wmEvent *eventstate; /* storage for event system */ - ListBase queue; /* events */ - ListBase handlers; + struct wmSubWindow *curswin; /* internal for wm_subwindow.c only */ + + ListBase queue; /* all events (ghost level events were handled) */ + ListBase handlers; /* window handlers, overriding all queues */ + ListBase subwindows; /* opengl stuff for sub windows, see notes in wm_subwindow.c */ + } wmWindow; # diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h index 880bee6d53c..044661fb521 100644 --- a/source/blender/windowmanager/WM_api.h +++ b/source/blender/windowmanager/WM_api.h @@ -72,6 +72,18 @@ int WM_operator_winactive (struct bContext *C); wmOperatorType *WM_operatortype_find(const char *idname); void WM_operator_register(wmWindowManager *wm, wmOperator *ot); + /* OpenGL wrappers, mimicing opengl syntax */ +void wmLoadMatrix (wmWindow *win, float mat[][4]); +void wmGetMatrix (wmWindow *win, float mat[][4]); +void wmMultMatrix (wmWindow *win, float mat[][4]); +void wmGetSingleMatrix (wmWindow *win, float mat[][4]); +void wmScale (wmWindow *win, float x, float y, float z); +void wmLoadIdentity (wmWindow *win); /* note: old name clear_view_mat */ + +void wmFrustum (wmWindow *win, float x1, float x2, float y1, float y2, float n, float f); +void wmOrtho (wmWindow *win, float x1, float x2, float y1, float y2, float n, float f); +void wmOrtho2 (wmWindow *win, float x1, float x2, float y1, float y2); + #endif /* WM_API_H */ diff --git a/source/blender/windowmanager/WM_types.h b/source/blender/windowmanager/WM_types.h index c3a1662c1e1..c894a8908f0 100644 --- a/source/blender/windowmanager/WM_types.h +++ b/source/blender/windowmanager/WM_types.h @@ -66,5 +66,13 @@ typedef struct wmTabletData { } wmTabletData; +/* *************** migrated stuff, clean later? ******************************** */ + +typedef struct RecentFile { + struct RecentFile *next, *prev; + char *filename; +} RecentFile; + + #endif /* WM_TYPES_H */ diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index 05f82d4e5c7..b3e710e456c 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -46,18 +46,12 @@ #include "MEM_guardedalloc.h" #include "MEM_CacheLimiterC-Api.h" -#include "BIF_language.h" -#ifdef INTERNATIONAL -#include "FTF_Api.h" -#endif - #include "BLI_blenlib.h" #include "BLI_linklist.h" #include "DNA_object_types.h" #include "DNA_space_types.h" #include "DNA_userdef_types.h" -#include "DNA_sound_types.h" #include "DNA_scene_types.h" #include "DNA_screen_types.h" #include "DNA_windowmanager_types.h" @@ -77,24 +71,6 @@ #include "BKE_verse.h" #endif -#include "BIF_fsmenu.h" -#include "BIF_interface.h" -#include "BIF_usiblender.h" /* XXX */ - -#include "BIF_editsound.h" -#include "BIF_editmode_undo.h" -#include "BIF_filelist.h" -#include "BIF_resources.h" -#include "BIF_screen.h" -#include "BIF_space.h" -#include "BIF_toolbox.h" - -#ifdef WITH_VERSE -#include "BIF_verse.h" -#endif - -#include "BDR_editobject.h" - #include "BLO_readfile.h" #include "BLO_writefile.h" @@ -103,6 +79,7 @@ #include "datatoc.h" #include "WM_api.h" +#include "WM_types.h" #include "wm.h" /***/ diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c index 029c16cee49..2afc63a7363 100644 --- a/source/blender/windowmanager/intern/wm_init_exit.c +++ b/source/blender/windowmanager/intern/wm_init_exit.c @@ -54,44 +54,12 @@ #include "BKE_packedFile.h" #include "BMF_Api.h" -#include "BIF_language.h" #ifdef INTERNATIONAL #include "FTF_Api.h" #endif #include "BLI_blenlib.h" -#include "BIF_cursors.h" -#include "BIF_drawtext.h" -#include "BIF_editaction.h" -#include "BIF_editarmature.h" -#include "BIF_editlattice.h" -#include "BIF_editfont.h" -#include "BIF_editmesh.h" -#include "BIF_editmode_undo.h" -#include "BIF_editsound.h" -#include "BIF_filelist.h" -#include "BIF_fsmenu.h" -#include "BIF_interface.h" -#include "BIF_gl.h" -#include "BIF_poseobject.h" -#include "BIF_previewrender.h" -#include "BIF_resources.h" -#include "BIF_usiblender.h" /* XXX */ - -#include "BSE_drawview.h" -#include "BSE_edit.h" -#include "BSE_editipo.h" -#include "BSE_filesel.h" -#include "BSE_headerbuttons.h" -#include "BSE_node.h" - -#include "BDR_drawobject.h" -#include "BDR_editobject.h" -#include "BDR_editcurve.h" -#include "BDR_imagepaint.h" -#include "BDR_vpaint.h" - #include "RE_pipeline.h" /* RE_ free stuff */ #include "radio.h" @@ -101,6 +69,7 @@ #include "SYS_System.h" #include "WM_api.h" +#include "WM_types.h" #include "wm.h" #include "wm_files.h" #include "wm_window.h" diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c index a6992f5fbdb..a744d949e81 100644 --- a/source/blender/windowmanager/intern/wm_operators.c +++ b/source/blender/windowmanager/intern/wm_operators.c @@ -39,8 +39,6 @@ #include "BKE_library.h" #include "BKE_main.h" -#include "BIF_toolbox.h" - #include "WM_api.h" #include "WM_types.h" #include "wm_window.h" diff --git a/source/blender/windowmanager/intern/wm_subwindow.c b/source/blender/windowmanager/intern/wm_subwindow.c new file mode 100644 index 00000000000..a7217786138 --- /dev/null +++ b/source/blender/windowmanager/intern/wm_subwindow.c @@ -0,0 +1,527 @@ +/** + * $Id: mywindow.c 9584 2007-01-03 13:45:03Z ton $ + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * Contributor(s): 2007 Blender Foundation (refactor) + * + * ***** END GPL LICENSE BLOCK ***** + * + * + * Subwindow opengl handling. + * BTW: subwindows open/close in X11 are way too slow, tried it, and choose for my own system... (ton) + * + */ + +#include + +#include "MEM_guardedalloc.h" + +#include "DNA_windowmanager_types.h" +#include "DNA_screen_types.h" + +#include "BLI_blenlib.h" +#include "BLI_arithb.h" + +#include "BKE_global.h" + +#include "BIF_gl.h" +#include "BIF_glutil.h" + +#include "WM_api.h" +#include "wm_window.h" + +/* wmSubWindow stored in wmWindow... but not exposed outside this C file */ +/* it seems a bit redundant (area regions can store it too, but we keep it + because we can store all kind of future opengl fanciness here */ + +/* we use indices and array because: + - index has safety, no pointers from this C file hanging around + - fast lookups of indices with array, list would give overhead + - old code used it this way... + - keep option open to have 2 screens using same window +*/ + +typedef struct wmSubWindow { + struct wmSubWindow *next, *prev; + + rcti winrct; + int swinid; + + float viewmat[4][4], winmat[4][4]; +} wmSubWindow; + + +/* ******************* open, free, set, get data ******************** */ + +/* not subwindow itself */ +static void wm_subwindow_free(wmSubWindow *swin) +{ + /* future fancy stuff */ +} + +void wm_subwindows_free(wmWindow *win) +{ + wmSubWindow *swin; + + for(swin= win->subwindows.first; swin; swin= swin->next) + wm_subwindow_free(swin); + + BLI_freelistN(&win->subwindows); +} + + +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) + return win->curswin->swinid; + return 0; +} + +static wmSubWindow *swin_from_swinid(wmWindow *win, int swinid) +{ + wmSubWindow *swin; + + for(swin= win->subwindows.first; swin; swin= swin->next) + if(swin->swinid==swinid) + break; + return swin; +} + +void wm_subwindow_set(wmWindow *win, int swinid) +{ + wmSubWindow *swin= swin_from_swinid(win, swinid); + int width, height; + + if(swin==NULL) { + printf("wm_subwindow_set %d: doesn't exist\n", swinid); + return; + } + + 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(); + +} + +/* always sets pixel-precise 2D window/view matrices */ +/* coords is in whole pixels. xmin = 15, xmax= 16: means window is 2 pix big */ +int wm_subwindow_open(wmWindow *win, rcti *winrct) +{ + wmSubWindow *swin; + int width, height; + int freewinid= 1; + + for(swin= win->subwindows.first; swin; swin= swin->next) + if(freewinid <= swin->swinid) + freewinid= swin->swinid+1; + + win->curswin= swin= MEM_callocN(sizeof(wmSubWindow), "swinopen"); + + swin->swinid= freewinid; + swin->winrct= *winrct; + + Mat4One(swin->viewmat); + Mat4One(swin->winmat); + + /* 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); + + return swin->swinid; +} + + +void wm_subwindow_close(wmWindow *win, int swinid) +{ + wmSubWindow *swin= swin_from_swinid(win, swinid); + + if (swin) { + if (swin==win->curswin) + win->curswin= NULL; + wm_subwindow_free(swin); + BLI_remlink(&win->subwindows, swin); + MEM_freeN(swin); + } + else { + printf("wm_subwindow_close: Internal error, bad winid: %d\n", swinid); + } + +} + +/* pixels go from 0-99 for a 100 pixel window */ +void wm_subwindow_position(wmWindow *win, int swinid, rcti *winrct) +{ + wmSubWindow *swin= swin_from_swinid(win, swinid); + + if(swin) { + swin->winrct= *winrct; + + /* CRITICAL, this clamping ensures that + * the viewport never goes outside the screen + * edges (assuming the x, y coords aren't + * outside). This caused a hardware lock + * on Matrox cards if it happens. + * + * Really Blender should never _ever_ try + * to do such a thing, but just to be safe + * clamp it anyway (or fix the bScreen + * scaling routine, and be damn sure you + * 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; + } + else { + printf("wm_subwindow_position: Internal error, bad winid: %d\n", swinid); + } +} + +/* ---------------- WM versions of OpenGL calls, using glBlah() syntax ------------------------ */ +/* ----------------- exported in WM_api.h ------------------------------------------------------ */ + +static 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); +} + +void wmGetMatrix(wmWindow *win, float mat[][4]) +{ + if(win->curswin==NULL) return; + + if (glaGetOneInteger(GL_MATRIX_MODE)==GL_MODELVIEW) { + Mat4CpyMat4(mat, win->curswin->viewmat); + } else { + Mat4CpyMat4(mat, win->curswin->winmat); + } +} + +void wmMultMatrix(wmWindow *win, float mat[][4]) +{ + if(win->curswin==NULL) return; + + glMultMatrixf((float*) mat); + + if (glaGetOneInteger(GL_MATRIX_MODE)==GL_MODELVIEW) + glGetFloatv(GL_MODELVIEW_MATRIX, (float *)win->curswin->viewmat); + else + glGetFloatv(GL_MODELVIEW_MATRIX, (float *)win->curswin->winmat); +} + +void wmGetSingleMatrix(wmWindow *win, float mat[][4]) +{ + if(win->curswin) + Mat4MulMat4(mat, win->curswin->viewmat, win->curswin->winmat); +} + +void wmScale(wmWindow *win, float x, float y, float z) +{ + 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); + +} + +void wmLoadIdentity(wmWindow *win) +{ + if(win->curswin==NULL) return; + + if (glaGetOneInteger(GL_MATRIX_MODE)==GL_MODELVIEW) + Mat4One(win->curswin->viewmat); + else + Mat4One(win->curswin->winmat); + + glLoadIdentity(); +} + +void wmFrustum(wmWindow *win, 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); + + glGetFloatv(GL_PROJECTION_MATRIX, (float *)win->curswin->winmat); + glMatrixMode(GL_MODELVIEW); + } +} + +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); + } +} + +void wmOrtho2(wmWindow *win, 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); +} + + +/* *************************** Framebuffer color depth, for selection codes ********************** */ + +static int wm_get_colordepth(void) +{ + static int mainwin_color_depth= 0; + + if(mainwin_color_depth==0) { + GLint r, g, b; + + glGetIntegerv(GL_RED_BITS, &r); + glGetIntegerv(GL_GREEN_BITS, &g); + glGetIntegerv(GL_BLUE_BITS, &b); + + mainwin_color_depth= r + g + b; + if(G.f & G_DEBUG) { + printf("Color depth r %d g %d b %d\n", (int)r, (int)g, (int)b); + glGetIntegerv(GL_AUX_BUFFERS, &r); + printf("Aux buffers: %d\n", (int)r); + } + } + return mainwin_color_depth; +} + + +#ifdef __APPLE__ + +/* apple seems to round colors to below and up on some configs */ + +static unsigned int index_to_framebuffer(int index) +{ + unsigned int i= index; + + switch(wm_get_colordepth()) { + case 12: + i= ((i & 0xF00)<<12) + ((i & 0xF0)<<8) + ((i & 0xF)<<4); + /* sometimes dithering subtracts! */ + i |= 0x070707; + break; + case 15: + case 16: + i= ((i & 0x7C00)<<9) + ((i & 0x3E0)<<6) + ((i & 0x1F)<<3); + i |= 0x030303; + break; + case 24: + break; + default: // 18 bits... + i= ((i & 0x3F000)<<6) + ((i & 0xFC0)<<4) + ((i & 0x3F)<<2); + i |= 0x010101; + break; + } + + return i; +} + +#else + +/* 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 i= index; + + switch(wm_get_colordepth()) { + case 8: + i= ((i & 48)<<18) + ((i & 12)<<12) + ((i & 3)<<6); + i |= 0x3F3F3F; + break; + case 12: + i= ((i & 0xF00)<<12) + ((i & 0xF0)<<8) + ((i & 0xF)<<4); + /* sometimes dithering subtracts! */ + i |= 0x0F0F0F; + break; + case 15: + case 16: + i= ((i & 0x7C00)<<9) + ((i & 0x3E0)<<6) + ((i & 0x1F)<<3); + i |= 0x070707; + break; + case 24: + break; + default: // 18 bits... + i= ((i & 0x3F000)<<6) + ((i & 0xFC0)<<4) + ((i & 0x3F)<<2); + i |= 0x030303; + break; + } + + return i; +} + +#endif + +void set_framebuffer_index_color(int index) +{ + cpack(index_to_framebuffer(index)); +} + +int framebuffer_to_index(unsigned int col) +{ + if (col==0) return 0; + + switch(wm_get_colordepth()) { + case 8: + return ((col & 0xC00000)>>18) + ((col & 0xC000)>>12) + ((col & 0xC0)>>6); + case 12: + return ((col & 0xF00000)>>12) + ((col & 0xF000)>>8) + ((col & 0xF0)>>4); + case 15: + case 16: + return ((col & 0xF80000)>>9) + ((col & 0xF800)>>6) + ((col & 0xF8)>>3); + case 24: + return col & 0xFFFFFF; + default: // 18 bits... + return ((col & 0xFC0000)>>6) + ((col & 0xFC00)>>4) + ((col & 0xFC)>>2); + } +} + + +/* ********** 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); + } +} + diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c index 9ac8010ff7c..cab852e1763 100644 --- a/source/blender/windowmanager/intern/wm_window.c +++ b/source/blender/windowmanager/intern/wm_window.c @@ -48,6 +48,7 @@ #include "WM_api.h" #include "wm.h" #include "wm_window.h" +#include "wm_subwindow.h" #include "wm_event_system.h" /* the global to talk to ghost */ @@ -103,10 +104,10 @@ void wm_window_free(bContext *C, wmWindow *win) 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); @@ -238,9 +239,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 */ + { + extern void wm_set_apple_prefsize(int, int); /* wm_apple.c */ - wm_set_apple_prefsize(prefsizx, prefsizy); + wm_set_apple_prefsize(prefsizx, prefsizy); + } #else prefstax= 0; prefstay= 0; diff --git a/source/blender/windowmanager/wm_subwindow.h b/source/blender/windowmanager/wm_subwindow.h new file mode 100644 index 00000000000..93079deb633 --- /dev/null +++ b/source/blender/windowmanager/wm_subwindow.h @@ -0,0 +1,51 @@ +/** + * $Id: wm_window.h + * + * ***** BEGIN GPL LICENSE BLOCK ***** + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2007 Blender Foundation. + * All rights reserved. + * + * + * Contributor(s): Blender Foundation + * + * ***** END GPL LICENSE BLOCK ***** + */ + +#ifndef WM_SUBWINDOW_H +#define WM_SUBWINDOW_H + + +/* *************** internal api ************** */ +#define WM_MAXSUBWIN 256 + +void wm_subwindows_free(wmWindow *win); + +int wm_subwindow_open(wmWindow *win, rcti *winrct); +void wm_subwindow_set(wmWindow *win, int swinid); /* set drawable */ +void wm_subwindow_close(wmWindow *win, int swinid); +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); + + +#endif /* WM_SUBWINDOW_H */ +