1 // Copyright (C) 2007-2012 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
6 // This library is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 2.1 of the License.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // Lesser General Public License for more details.
16 // You should have received a copy of the GNU Lesser General Public
17 // License along with this library; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
24 #define QT_CLEAN_NAMESPACE /* avoid definition of INT32 and INT8 */
27 #include "OCCViewer_ViewPort.h"
29 #include "SUIT_Session.h"
37 #include <QColorDialog>
39 #include <QCoreApplication>
47 #include <X11/Xutil.h>
48 #include <X11/Xatom.h>
49 #include <X11/Xmu/StdCmap.h>
50 #undef QT_CLEAN_NAMESPACE
51 #include <Xw_Window.hxx>
52 #include <Graphic3d_GraphicDevice.hxx>
60 XStandardColormap scmap;
66 CMapEntry::CMapEntry()
76 CMapEntry::~CMapEntry()
79 XFreeColormap( QX11Info::display(), cmap );
82 static QMultiHash<int,CMapEntry> *cmap_dict = 0;
83 static bool mesa_gl = false;
85 static void cleanup_cmaps()
89 //while (!cmap_dict->isEmpty())
90 // cmap_dict->erase(cmap_dict->begin());
96 static Colormap choose_cmap( Display *dpy, XVisualInfo *vi )
100 cmap_dict = new QMultiHash<int,CMapEntry>;
101 const char *v = glXQueryServerString( dpy, vi->screen, GLX_VERSION );
102 mesa_gl = strstr( v,"Mesa" ) != 0;
103 qAddPostRoutine( cleanup_cmaps );
106 QHash<int,CMapEntry>::iterator itH = cmap_dict->find( (long)vi->visualid );
107 if ( itH != cmap_dict->end() ) // found colormap for visual
108 return itH.value().cmap;
112 XStandardColormap *c;
116 //cout << "Choosing cmap for vID = " << vi->visualid << endl;
119 if ( vi->visualid == XVisualIDFromVisual( (Visual*)QX11Info::appVisual() ) )
122 // cout << "Using x11AppColormap" << endl;
124 return QX11Info::appColormap();
129 Atom hp_cmaps = XInternAtom( dpy, "_HP_RGB_SMOOTH_MAP_LIST", true );
130 if ( hp_cmaps && vi->visual->c_class == TrueColor && vi->depth == 8 )
132 if ( XGetRGBColormaps( dpy, RootWindow( dpy, vi->screen ), &c, &n, hp_cmaps ) )
135 while ( i < n && x.cmap == 0 )
137 if ( c[i].visualid == vi->visual->visualid )
139 x.cmap = c[i].colormap;
148 #if !defined( _OS_SOLARIS_ )
151 if ( XmuLookupStandardColormap( dpy, vi->screen, vi->visualid, vi->depth, XA_RGB_DEFAULT_MAP, false, true ) )
153 if ( XGetRGBColormaps( dpy, RootWindow( dpy, vi->screen ), &c, &n, XA_RGB_DEFAULT_MAP ) )
156 while ( i < n && x.cmap == 0 )
158 if ( c[i].visualid == vi->visualid )
160 x.cmap = c[i].colormap;
172 // no shared cmap found
173 x.cmap = XCreateColormap( dpy, RootWindow( dpy, vi->screen ), vi->visual, AllocNone );
177 cmap_dict->insert( (long)vi->visualid, x ); // associate cmap with visualid
186 OCCViewer_ViewPort::OCCViewer_ViewPort( QWidget* parent )
195 OCCViewer_ViewPort::~OCCViewer_ViewPort()
201 Initializes viewport. [ private ]
203 void OCCViewer_ViewPort::initialize()
205 myPaintersRedrawing = false;
206 myEnableSketching = true;
207 myEnableTransform = true;
209 setMouseTracking( true );
210 setBackgroundRole( QPalette::NoRole );//NoBackground );
211 // set focus policy to threat QContextMenuEvent from keyboard
212 setFocusPolicy( Qt::StrongFocus );
213 setAttribute( Qt::WA_PaintOnScreen );
214 setAttribute( Qt::WA_NoSystemBackground );
218 Cleans up the viewport. [ private ]
220 void OCCViewer_ViewPort::cleanup()
225 Selects visual ID for OpenGL window ( X11 specific ). [ protected ]
227 void OCCViewer_ViewPort::selectVisualId()
230 XVisualInfo* pVisualInfo;
231 if ( QX11Info::display() )
233 /* Initialization with the default VisualID */
234 Visual *v = DefaultVisual( QX11Info::display(), DefaultScreen( QX11Info::display() ) );
235 /*int visualID = */XVisualIDFromVisual( v );
237 /* Here we use the settings from Optimizer_ViewInfo::TxglCreateWindow() */
238 int visualAttr[] = { GLX_RGBA, GLX_DEPTH_SIZE, 1, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1,
239 GLX_BLUE_SIZE, 1, GLX_DOUBLEBUFFER, None };
241 pVisualInfo = ::glXChooseVisual( QX11Info::display(), DefaultScreen( QX11Info::display() ), visualAttr );
246 XSetWindowAttributes a;
248 a.colormap = choose_cmap( QX11Info::display(), pVisualInfo ); /* find best colormap */
249 a.background_pixel = QColormap::instance().pixel( backgroundColor() );
250 a.border_pixel = QColormap::instance().pixel( Qt::black );
251 Window p = RootWindow( QX11Info::display(), DefaultScreen( QX11Info::display() ) );
252 if ( parentWidget() )
253 p = parentWidget()->winId();
257 if ( type == Type2D ) // creating simple X window for 2d
259 unsigned long xbackground =
260 BlackPixel( QX11Info::display(), DefaultScreen( QX11Info::display() ) );
261 unsigned long xforeground =
262 WhitePixel( QX11Info::display(), DefaultScreen( QX11Info::display() ) );
264 w = XCreateSimpleWindow ( QX11Info::display(), p, x(), y(), width(),
265 height(), 0, xforeground, xbackground );
267 else if ( type == Type3D )
269 w = XCreateWindow( QX11Info::display(), p, x(), y(), width(), height(),
270 0, pVisualInfo->depth, InputOutput, pVisualInfo->visual,
271 CWBackPixel | CWBorderPixel | CWColormap, &a );
276 w = XCreateWindow( QX11Info::display(), p, x(), y(), width(), height(),
277 0, pVisualInfo->depth, InputOutput, pVisualInfo->visual,
278 CWBackPixel | CWBorderPixel | CWColormap, &a );
283 if ( XGetWMColormapWindows( QX11Info::display(), topLevelWidget()->winId(), &cmwret, &count ) )
285 cmw = new Window[count+1];
286 memcpy( (char*)cmw, (char*)cmwret, sizeof(Window) * count );
287 XFree( (char*)cmwret );
290 for ( i = 0; i < count; i++ )
292 if ( cmw[i] == winId() ) /* replace old window */
299 if ( i >= count ) /* append new window */
305 cmw = new Window[count];
309 /* Creating new window (with good VisualID) for this widget */
311 XSetWMColormapWindows( QX11Info::display(), topLevelWidget()->winId(), cmw, count );
318 XFree( (char *)pVisualInfo );
320 XFlush( QX11Info::display() );
326 Sets the background 'color'. [ virtual ]
328 void OCCViewer_ViewPort::setBackgroundColor( const QColor& color )
330 QPalette pal = palette();
331 pal.setColor( QPalette::Background, color );
334 emit vpChangeBGColor( color );
338 Returns the background color. [ virtual ]
340 QColor OCCViewer_ViewPort::backgroundColor() const
342 return palette().color( QPalette::Active, QPalette::Background );
346 Returns 'true' if sketching is enabled in this viewport. [ public ]
348 bool OCCViewer_ViewPort::isSketchingEnabled() const
350 return myEnableSketching;
354 Enables / disables sketching [ public ]
356 void OCCViewer_ViewPort::setSketchingEnabled( bool enable )
358 myEnableSketching = enable;
362 Returns 'true' if transformations ( rotation, zoom etc. )
363 are enabled in this viewport. [ public ]
365 bool OCCViewer_ViewPort::isTransformEnabled() const
367 return myEnableTransform;
371 Enables / disables transformations. [ public ]
373 void OCCViewer_ViewPort::setTransformEnabled( bool enable )
375 myEnableTransform = enable;
379 Emits 'mouseEvent' signal. [ virtual protected ]
381 void OCCViewer_ViewPort::mousePressEvent( QMouseEvent *e )
383 emit vpMouseEvent( e );
387 Emits 'mouseEvent' signal. [ virtual protected ]
389 void OCCViewer_ViewPort::mouseMoveEvent( QMouseEvent* e )
391 emit vpMouseEvent( e );
395 Emits 'mouseEvent' signal. [ virtual protected ]
397 void OCCViewer_ViewPort::mouseReleaseEvent( QMouseEvent *e )
399 emit vpMouseEvent( e );
403 Emits 'mouseEvent' signal. [ virtual protected ]
405 void OCCViewer_ViewPort::mouseDoubleClickEvent( QMouseEvent *e )
407 emit vpMouseEvent( e );
411 Emits 'keyEvent' signal. [ virtual protected ]
413 void OCCViewer_ViewPort::keyPressEvent( QKeyEvent *e )
415 emit vpKeyEvent( e );
419 Emits 'keyEvent' signal. [ virtual protected ]
421 void OCCViewer_ViewPort::keyReleaseEvent( QKeyEvent *e )
423 emit vpKeyEvent( e );
427 Repaints the viewport. [ virtual protected ]
429 void OCCViewer_ViewPort::paintEvent( QPaintEvent* )
431 if ( myPaintersRedrawing )
434 emit vpDrawExternal( &p );
435 myPaintersRedrawing = false;
440 Forces to redraw the viewport by an external painter. [ public ]
442 void OCCViewer_ViewPort::redrawPainters()
444 myPaintersRedrawing = true;
449 Updates this view. Does nothing by default. [ virtual public ]
451 void OCCViewer_ViewPort::onUpdate()
456 Get paint engine for the OpenGL viewer. [ virtual public ]
458 QPaintEngine* OCCViewer_ViewPort::paintEngine() const
464 Creates the popup. [ virtual protected ]
466 /*void OCCViewer_ViewPort::onCreatePopup( QPopupMenu* popup )
470 QtxAction* a = new QtxAction( "", tr( "MEN_VP_CHANGEBGR" ), 0, this );
471 a->setStatusTip( tr( "PRP_VP_CHANGEBGR" ) );
472 connect( a, SIGNAL( activated() ), SLOT( onChangeBgColor()));
473 myPopupActions.append( a );
479 Destroys the popup. [ virtual protected ]
481 /*void OCCViewer_ViewPort::onDestroyPopup( QPopupMenu* popup )
485 for ( QtxAction* a = myPopupActions.first(); a; a = myPopupActions.next() )
486 a->removeFrom( popup );
487 //while (!myPopupActions.isEmpty())
488 // delete myPopupActions.takeFirst();
489 myPopupActions.clear();
494 Performs synchronization of view parameters with the specified view.
495 Returns \c true if synchronization is done successfully or \c false otherwise.
496 Default implementation does nothing (return \c false)
498 bool OCCViewer_ViewPort::synchronize( OCCViewer_ViewPort* )
504 Sets the background color with color selection dialog. [ virtual protected slot ]
506 void OCCViewer_ViewPort::onChangeBackground()
508 QColor selColor = QColorDialog::getColor ( backgroundColor(), this );
509 if ( selColor.isValid() )
510 setBackgroundColor( selColor );