Back to index

salome-gui  6.5.0
OCCViewer_ViewPort.cxx
Go to the documentation of this file.
00001 // Copyright (C) 2007-2012  CEA/DEN, EDF R&D, OPEN CASCADE
00002 //
00003 // Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
00004 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
00005 //
00006 // This library is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 2.1 of the License.
00010 //
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 // Lesser General Public License for more details.
00015 //
00016 // You should have received a copy of the GNU Lesser General Public
00017 // License along with this library; if not, write to the Free Software
00018 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
00019 //
00020 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
00021 //
00022 
00023 #if !defined WNT
00024 #define QT_CLEAN_NAMESPACE         /* avoid definition of INT32 and INT8 */
00025 #endif
00026 
00027 #include "OCCViewer_ViewPort.h"
00028 
00029 #include "SUIT_Session.h"
00030 
00031 #include <QColor>
00032 #include <QRect>
00033 #include <QPixmap>
00034 #include <QPainter>
00035 #include <QMultiHash>
00036 #include <QMenu>
00037 #include <QColorDialog>
00038 #include <QColormap>
00039 #include <QCoreApplication>
00040 
00041 #include <stdlib.h>
00042 
00043 #if !defined WNT
00044 #include <QX11Info>
00045 #include <GL/glx.h>
00046 #include <X11/Xlib.h>
00047 #include <X11/Xutil.h>
00048 #include <X11/Xatom.h>
00049 #include <X11/Xmu/StdCmap.h>
00050 #undef QT_CLEAN_NAMESPACE
00051 #include <Xw_Window.hxx>
00052 #include <Graphic3d_GraphicDevice.hxx>
00053 
00054 struct CMapEntry
00055 {
00056   CMapEntry();
00057   ~CMapEntry();
00058   Colormap          cmap;
00059   bool              alloc;
00060   XStandardColormap scmap;
00061 };
00062 
00066 CMapEntry::CMapEntry()
00067 {
00068   cmap = 0;
00069   alloc = false;
00070   scmap.colormap = 0;
00071 }
00072 
00076 CMapEntry::~CMapEntry()
00077 {
00078   if ( alloc )
00079     XFreeColormap( QX11Info::display(), cmap );
00080 }
00081 
00082 static QMultiHash<int,CMapEntry> *cmap_dict = 0;
00083 static bool mesa_gl = false;
00084 
00085 static void cleanup_cmaps()
00086 {
00087   if ( !cmap_dict )
00088     return;
00089   //while (!cmap_dict->isEmpty())
00090   //  cmap_dict->erase(cmap_dict->begin());
00091   cmap_dict->clear();
00092   delete cmap_dict;
00093   cmap_dict = 0;
00094 }
00095 
00096 static Colormap choose_cmap( Display *dpy, XVisualInfo *vi )
00097 {
00098   if ( !cmap_dict )
00099   {
00100     cmap_dict = new QMultiHash<int,CMapEntry>;
00101     const char *v = glXQueryServerString( dpy, vi->screen, GLX_VERSION );
00102     mesa_gl = strstr( v,"Mesa" ) != 0;
00103     qAddPostRoutine( cleanup_cmaps );
00104   }
00105 
00106   QHash<int,CMapEntry>::iterator itH = cmap_dict->find( (long)vi->visualid );
00107   if ( itH != cmap_dict->end() )  // found colormap for visual
00108     return itH.value().cmap;
00109   
00110   CMapEntry x;
00111   
00112   XStandardColormap *c;
00113   int n, i;
00114 
00115   //#ifdef DEBUG
00116   //cout << "Choosing cmap for vID = " << vi->visualid << endl;
00117   //#endif
00118 
00119   if ( vi->visualid == XVisualIDFromVisual( (Visual*)QX11Info::appVisual() ) )
00120   {
00121 #ifdef DEBUG
00122 //    cout << "Using x11AppColormap" << endl;
00123 #endif
00124     return QX11Info::appColormap();
00125   }
00126 
00127   if ( mesa_gl )
00128   {
00129     Atom hp_cmaps = XInternAtom( dpy, "_HP_RGB_SMOOTH_MAP_LIST", true );
00130     if ( hp_cmaps && vi->visual->c_class == TrueColor && vi->depth == 8 )
00131     {
00132       if ( XGetRGBColormaps( dpy, RootWindow( dpy, vi->screen ), &c, &n, hp_cmaps ) )
00133       {
00134         i = 0;
00135         while ( i < n && x.cmap == 0 )
00136         {
00137           if ( c[i].visualid == vi->visual->visualid )
00138           {
00139             x.cmap = c[i].colormap;
00140             x.scmap = c[i];
00141           }
00142           i++;
00143         }
00144         XFree( (char*)c );
00145       }
00146     }
00147   }
00148 #if !defined( _OS_SOLARIS_ )
00149   if ( !x.cmap )
00150   {
00151     if ( XmuLookupStandardColormap( dpy, vi->screen, vi->visualid, vi->depth, XA_RGB_DEFAULT_MAP, false, true ) )
00152     {
00153       if ( XGetRGBColormaps( dpy, RootWindow( dpy, vi->screen ), &c, &n, XA_RGB_DEFAULT_MAP ) )
00154       {
00155         i = 0;
00156         while ( i < n && x.cmap == 0 )
00157         {
00158           if ( c[i].visualid == vi->visualid )
00159           {
00160             x.cmap = c[i].colormap;
00161             x.scmap = c[i];
00162           }
00163           i++;
00164         }
00165         XFree( (char *)c );
00166       }
00167     }
00168   }
00169 #endif
00170   if ( !x.cmap )
00171   {
00172     // no shared cmap found
00173     x.cmap = XCreateColormap( dpy, RootWindow( dpy, vi->screen ), vi->visual, AllocNone );
00174     x.alloc = true;
00175   }
00176 
00177   cmap_dict->insert( (long)vi->visualid, x ); // associate cmap with visualid
00178   return x.cmap;
00179 }
00180 #endif
00181 
00182 
00186 OCCViewer_ViewPort::OCCViewer_ViewPort( QWidget* parent )
00187 : QWidget( parent )
00188 {
00189   initialize();
00190 }
00191 
00195 OCCViewer_ViewPort::~OCCViewer_ViewPort()
00196 {
00197   cleanup();
00198 }
00199 
00203 void OCCViewer_ViewPort::initialize()
00204 {
00205   myPaintersRedrawing = false;
00206   myEnableSketching = true;
00207   myEnableTransform = true;
00208   
00209   setMouseTracking( true );
00210   setBackgroundRole( QPalette::NoRole );//NoBackground );
00211   // set focus policy to threat QContextMenuEvent from keyboard  
00212   setFocusPolicy( Qt::StrongFocus );
00213   setAttribute( Qt::WA_PaintOnScreen );
00214   setAttribute( Qt::WA_NoSystemBackground );
00215 }
00216 
00220 void OCCViewer_ViewPort::cleanup()
00221 {
00222 }
00223 
00227 void OCCViewer_ViewPort::selectVisualId()
00228 {
00229 #if !defined WNT
00230   XVisualInfo* pVisualInfo;
00231   if ( QX11Info::display() )
00232   {
00233     /* Initialization with the default VisualID */
00234     Visual *v = DefaultVisual( QX11Info::display(), DefaultScreen( QX11Info::display() ) );
00235     /*int visualID = */XVisualIDFromVisual( v );
00236     
00237     /*  Here we use the settings from Optimizer_ViewInfo::TxglCreateWindow() */
00238     int visualAttr[] = { GLX_RGBA, GLX_DEPTH_SIZE, 1, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1,
00239                           GLX_BLUE_SIZE, 1, GLX_DOUBLEBUFFER, None };
00240     
00241     pVisualInfo = ::glXChooseVisual( QX11Info::display(), DefaultScreen( QX11Info::display() ), visualAttr );
00242     
00243     if ( isVisible() )
00244       hide();
00245     
00246     XSetWindowAttributes a;
00247     
00248     a.colormap = choose_cmap( QX11Info::display(), pVisualInfo );       /* find best colormap */
00249     a.background_pixel = QColormap::instance().pixel( backgroundColor() );
00250     a.border_pixel = QColormap::instance().pixel( Qt::black );
00251     Window p = RootWindow( QX11Info::display(), DefaultScreen( QX11Info::display() ) );
00252     if ( parentWidget() )
00253       p = parentWidget()->winId();
00254     
00255     Window w;
00256     /*
00257     if ( type == Type2D )  // creating simple X window for 2d
00258     {
00259       unsigned long xbackground =
00260           BlackPixel( QX11Info::display(), DefaultScreen( QX11Info::display() ) );
00261       unsigned long xforeground =
00262           WhitePixel( QX11Info::display(), DefaultScreen( QX11Info::display() ) );
00263 
00264       w = XCreateSimpleWindow ( QX11Info::display(), p, x(), y(), width(),
00265                                 height(), 0, xforeground, xbackground );
00266     }
00267     else if ( type == Type3D )
00268     {
00269       w = XCreateWindow( QX11Info::display(), p,  x(), y(), width(), height(),
00270                           0, pVisualInfo->depth, InputOutput, pVisualInfo->visual,
00271                           CWBackPixel | CWBorderPixel | CWColormap, &a );
00272     }
00273     else
00274       return;
00275     */
00276     w = XCreateWindow( QX11Info::display(), p,  x(), y(), width(), height(),
00277                       0, pVisualInfo->depth, InputOutput, pVisualInfo->visual,
00278                       CWBackPixel | CWBorderPixel | CWColormap, &a );
00279   
00280     Window *cmw;
00281     Window *cmwret;
00282     int count;
00283     if ( XGetWMColormapWindows( QX11Info::display(), topLevelWidget()->winId(), &cmwret, &count ) )
00284     {
00285       cmw = new Window[count+1];
00286       memcpy( (char*)cmw, (char*)cmwret, sizeof(Window) * count );
00287       XFree( (char*)cmwret );
00288       int i;
00289 
00290       for ( i = 0; i < count; i++ )
00291       {
00292         if ( cmw[i] == winId() ) /* replace old window */
00293         {
00294           cmw[i] = w;
00295           break;
00296         }
00297       }
00298 
00299       if ( i >= count )                        /* append new window */
00300         cmw[count++] = w;
00301     }
00302     else
00303     {
00304       count = 1;
00305       cmw = new Window[count];
00306       cmw[0] = w;
00307     }
00308 
00309     /* Creating new window (with good VisualID) for this widget */
00310     create(w);
00311     XSetWMColormapWindows( QX11Info::display(), topLevelWidget()->winId(), cmw, count );
00312     delete[] cmw;
00313 
00314     if ( isVisible() )
00315       show();
00316 
00317     if ( pVisualInfo )
00318       XFree( (char *)pVisualInfo );
00319 
00320     XFlush( QX11Info::display() );
00321   }
00322 #endif
00323 }
00324 
00328 void OCCViewer_ViewPort::setBackgroundColor( const QColor& color )
00329 {
00330   QPalette pal = palette();
00331   pal.setColor( QPalette::Background, color );
00332   setPalette( pal );
00333   repaint();
00334   emit vpChangeBGColor( color );
00335 }
00336 
00340 QColor OCCViewer_ViewPort::backgroundColor() const
00341 {
00342   return palette().color( QPalette::Active, QPalette::Background );
00343 }
00344 
00348 bool OCCViewer_ViewPort::isSketchingEnabled() const
00349 {
00350   return myEnableSketching;
00351 }
00352 
00356 void OCCViewer_ViewPort::setSketchingEnabled( bool enable )
00357 {
00358   myEnableSketching = enable;
00359 }
00360 
00365 bool OCCViewer_ViewPort::isTransformEnabled() const
00366 {
00367   return myEnableTransform;
00368 }
00369 
00373 void OCCViewer_ViewPort::setTransformEnabled( bool enable )
00374 {
00375   myEnableTransform = enable;
00376 }
00377 
00381 void OCCViewer_ViewPort::mousePressEvent( QMouseEvent *e )
00382 {
00383     emit vpMouseEvent( e );
00384 }
00385 
00389 void OCCViewer_ViewPort::mouseMoveEvent( QMouseEvent* e )
00390 {
00391   emit vpMouseEvent( e );
00392 }
00393 
00397 void OCCViewer_ViewPort::mouseReleaseEvent( QMouseEvent *e )
00398 {
00399   emit vpMouseEvent( e );
00400 }
00401 
00405 void OCCViewer_ViewPort::mouseDoubleClickEvent( QMouseEvent *e )
00406 {
00407   emit vpMouseEvent( e );
00408 }
00409 
00413 void OCCViewer_ViewPort::keyPressEvent( QKeyEvent *e )
00414 {
00415   emit vpKeyEvent( e );
00416 }
00417 
00421 void OCCViewer_ViewPort::keyReleaseEvent( QKeyEvent *e )
00422 {
00423   emit vpKeyEvent( e );
00424 }
00425 
00429 void OCCViewer_ViewPort::paintEvent( QPaintEvent* )
00430 {
00431   if ( myPaintersRedrawing )
00432   {
00433     QPainter p( this );
00434     emit vpDrawExternal( &p );
00435     myPaintersRedrawing = false;
00436   }
00437 }
00438 
00442 void OCCViewer_ViewPort::redrawPainters()
00443 {
00444   myPaintersRedrawing = true;
00445   repaint();
00446 }
00447 
00451 void OCCViewer_ViewPort::onUpdate()
00452 {
00453 }
00454 
00458 QPaintEngine* OCCViewer_ViewPort::paintEngine() const
00459 {
00460   return 0;
00461 }
00462 
00466 /*void OCCViewer_ViewPort::onCreatePopup( QPopupMenu* popup )
00467 {
00468   if ( popup )
00469   {
00470     QtxAction* a = new QtxAction( "", tr( "MEN_VP_CHANGEBGR" ), 0, this );
00471     a->setStatusTip( tr( "PRP_VP_CHANGEBGR" ) );
00472     connect( a, SIGNAL( activated() ), SLOT( onChangeBgColor()));
00473     myPopupActions.append( a );
00474     a->addTo( popup );
00475   }
00476 }*/
00477 
00481 /*void OCCViewer_ViewPort::onDestroyPopup( QPopupMenu* popup )
00482 {
00483   if ( popup )
00484   {
00485     for ( QtxAction* a = myPopupActions.first(); a; a = myPopupActions.next() )
00486       a->removeFrom( popup );
00487     //while (!myPopupActions.isEmpty())
00488     //  delete myPopupActions.takeFirst();
00489     myPopupActions.clear();
00490   }
00491 }*/
00492 
00498 bool OCCViewer_ViewPort::synchronize( OCCViewer_ViewPort* )
00499 {
00500   return false;
00501 }
00502 
00506 void OCCViewer_ViewPort::onChangeBackground()
00507 {
00508   QColor selColor = QColorDialog::getColor ( backgroundColor(), this );
00509   if ( selColor.isValid() )
00510     setBackgroundColor( selColor );
00511 }