1 // Copyright (C) 2007-2016 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, or (at your option) any later version.
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>
59 XStandardColormap scmap;
65 CMapEntry::CMapEntry()
75 CMapEntry::~CMapEntry()
78 XFreeColormap( QX11Info::display(), cmap );
81 static QMultiHash<int,CMapEntry> *cmap_dict = 0;
82 static bool mesa_gl = false;
84 static void cleanup_cmaps()
88 //while (!cmap_dict->isEmpty())
89 // cmap_dict->erase(cmap_dict->begin());
95 static Colormap choose_cmap( Display *dpy, XVisualInfo *vi )
99 cmap_dict = new QMultiHash<int,CMapEntry>;
100 const char *v = glXQueryServerString( dpy, vi->screen, GLX_VERSION );
101 mesa_gl = strstr( v,"Mesa" ) != 0;
102 qAddPostRoutine( cleanup_cmaps );
105 QHash<int,CMapEntry>::iterator itH = cmap_dict->find( (long)vi->visualid );
106 if ( itH != cmap_dict->end() ) // found colormap for visual
107 return itH.value().cmap;
111 XStandardColormap *c;
115 //cout << "Choosing cmap for vID = " << vi->visualid << endl;
118 if ( vi->visualid == XVisualIDFromVisual( (Visual*)QX11Info::appVisual() ) )
121 // cout << "Using x11AppColormap" << endl;
123 return QX11Info::appColormap();
128 Atom hp_cmaps = XInternAtom( dpy, "_HP_RGB_SMOOTH_MAP_LIST", true );
129 if ( hp_cmaps && vi->visual->c_class == TrueColor && vi->depth == 8 )
131 if ( XGetRGBColormaps( dpy, RootWindow( dpy, vi->screen ), &c, &n, hp_cmaps ) )
134 while ( i < n && x.cmap == 0 )
136 if ( c[i].visualid == vi->visual->visualid )
138 x.cmap = c[i].colormap;
147 #if !defined( _OS_SOLARIS_ )
150 if ( XmuLookupStandardColormap( dpy, vi->screen, vi->visualid, vi->depth, XA_RGB_DEFAULT_MAP, false, true ) )
152 if ( XGetRGBColormaps( dpy, RootWindow( dpy, vi->screen ), &c, &n, XA_RGB_DEFAULT_MAP ) )
155 while ( i < n && x.cmap == 0 )
157 if ( c[i].visualid == vi->visualid )
159 x.cmap = c[i].colormap;
171 // no shared cmap found
172 x.cmap = XCreateColormap( dpy, RootWindow( dpy, vi->screen ), vi->visual, AllocNone );
176 cmap_dict->insert( (long)vi->visualid, x ); // associate cmap with visualid
185 OCCViewer_ViewPort::OCCViewer_ViewPort( QWidget* parent )
194 OCCViewer_ViewPort::~OCCViewer_ViewPort()
200 Initializes viewport. [ private ]
202 void OCCViewer_ViewPort::initialize()
204 myPaintersRedrawing = false;
205 myEnableSketching = true;
206 myEnableTransform = true;
208 setMouseTracking( true );
209 setBackgroundRole( QPalette::NoRole );//NoBackground );
210 // set focus policy to threat QContextMenuEvent from keyboard
211 setFocusPolicy( Qt::StrongFocus );
212 setAttribute( Qt::WA_PaintOnScreen );
213 setAttribute( Qt::WA_NoSystemBackground );
217 Cleans up the viewport. [ private ]
219 void OCCViewer_ViewPort::cleanup()
224 Selects visual ID for OpenGL window ( X11 specific ). [ protected ]
226 void OCCViewer_ViewPort::selectVisualId()
229 XVisualInfo* pVisualInfo;
230 if ( QX11Info::display() )
232 /* Initialization with the default VisualID */
233 Visual *v = DefaultVisual( QX11Info::display(), DefaultScreen( QX11Info::display() ) );
234 /*int visualID = */XVisualIDFromVisual( v );
236 /* Here we use the settings from Optimizer_ViewInfo::TxglCreateWindow() */
237 int visualAttr[] = { GLX_RGBA, GLX_DEPTH_SIZE, 1, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1,
238 GLX_BLUE_SIZE, 1, GLX_DOUBLEBUFFER, None };
240 pVisualInfo = ::glXChooseVisual( QX11Info::display(), DefaultScreen( QX11Info::display() ), visualAttr );
245 XSetWindowAttributes a;
247 a.colormap = choose_cmap( QX11Info::display(), pVisualInfo ); /* find best colormap */
248 a.background_pixel = QColormap::instance().pixel( backgroundColor() );
249 a.border_pixel = QColormap::instance().pixel( Qt::black );
250 Window p = RootWindow( QX11Info::display(), DefaultScreen( QX11Info::display() ) );
251 if ( parentWidget() )
252 p = parentWidget()->winId();
256 if ( type == Type2D ) // creating simple X window for 2d
258 unsigned long xbackground =
259 BlackPixel( QX11Info::display(), DefaultScreen( QX11Info::display() ) );
260 unsigned long xforeground =
261 WhitePixel( QX11Info::display(), DefaultScreen( QX11Info::display() ) );
263 w = XCreateSimpleWindow ( QX11Info::display(), p, x(), y(), width(),
264 height(), 0, xforeground, xbackground );
266 else if ( type == Type3D )
268 w = XCreateWindow( QX11Info::display(), p, x(), y(), width(), height(),
269 0, pVisualInfo->depth, InputOutput, pVisualInfo->visual,
270 CWBackPixel | CWBorderPixel | CWColormap, &a );
275 w = XCreateWindow( QX11Info::display(), p, x(), y(), width(), height(),
276 0, pVisualInfo->depth, InputOutput, pVisualInfo->visual,
277 CWBackPixel | CWBorderPixel | CWColormap, &a );
282 if ( XGetWMColormapWindows( QX11Info::display(), topLevelWidget()->winId(), &cmwret, &count ) )
284 cmw = new Window[count+1];
285 memcpy( (char*)cmw, (char*)cmwret, sizeof(Window) * count );
286 XFree( (char*)cmwret );
289 for ( i = 0; i < count; i++ )
291 if ( cmw[i] == winId() ) /* replace old window */
298 if ( i >= count ) /* append new window */
304 cmw = new Window[count];
308 /* Creating new window (with good VisualID) for this widget */
310 XSetWMColormapWindows( QX11Info::display(), topLevelWidget()->winId(), cmw, count );
317 XFree( (char *)pVisualInfo );
319 XFlush( QX11Info::display() );
325 Sets the background 'color'. [ virtual ]
327 void OCCViewer_ViewPort::setBackgroundColor( const QColor& color )
329 QPalette pal = palette();
330 pal.setColor( QPalette::Background, color );
333 emit vpChangeBGColor( color );
337 Returns the background color. [ virtual ]
339 QColor OCCViewer_ViewPort::backgroundColor() const
341 return palette().color( QPalette::Active, QPalette::Background );
345 Returns 'true' if sketching is enabled in this viewport. [ public ]
347 bool OCCViewer_ViewPort::isSketchingEnabled() const
349 return myEnableSketching;
353 Enables / disables sketching [ public ]
355 void OCCViewer_ViewPort::setSketchingEnabled( bool enable )
357 myEnableSketching = enable;
361 Returns 'true' if transformations ( rotation, zoom etc. )
362 are enabled in this viewport. [ public ]
364 bool OCCViewer_ViewPort::isTransformEnabled() const
366 return myEnableTransform;
370 Enables / disables transformations. [ public ]
372 void OCCViewer_ViewPort::setTransformEnabled( bool enable )
374 myEnableTransform = enable;
378 Emits 'mouseEvent' signal. [ virtual protected ]
380 void OCCViewer_ViewPort::mousePressEvent( QMouseEvent *e )
382 emit vpMouseEvent( e );
386 Emits 'mouseEvent' signal. [ virtual protected ]
388 void OCCViewer_ViewPort::mouseMoveEvent( QMouseEvent* e )
390 emit vpMouseEvent( e );
394 Emits 'mouseEvent' signal. [ virtual protected ]
396 void OCCViewer_ViewPort::mouseReleaseEvent( QMouseEvent *e )
398 emit vpMouseEvent( e );
402 Emits 'mouseEvent' signal. [ virtual protected ]
404 void OCCViewer_ViewPort::mouseDoubleClickEvent( QMouseEvent *e )
406 emit vpMouseEvent( e );
410 Emits 'keyEvent' signal. [ virtual protected ]
412 void OCCViewer_ViewPort::keyPressEvent( QKeyEvent *e )
414 emit vpKeyEvent( e );
418 Emits 'keyEvent' signal. [ virtual protected ]
420 void OCCViewer_ViewPort::keyReleaseEvent( QKeyEvent *e )
422 emit vpKeyEvent( e );
426 Repaints the viewport. [ virtual protected ]
428 void OCCViewer_ViewPort::paintEvent( QPaintEvent* )
430 if ( myPaintersRedrawing )
433 emit vpDrawExternal( &p );
434 myPaintersRedrawing = false;
439 Forces to redraw the viewport by an external painter. [ public ]
441 void OCCViewer_ViewPort::redrawPainters()
443 myPaintersRedrawing = true;
448 Updates this view. Does nothing by default. [ virtual public ]
450 void OCCViewer_ViewPort::onUpdate()
455 Get paint engine for the OpenGL viewer. [ virtual public ]
457 QPaintEngine* OCCViewer_ViewPort::paintEngine() const
463 Performs synchronization of view parameters with the specified view.
464 Returns \c true if synchronization is done successfully or \c false otherwise.
465 Default implementation does nothing (return \c false)
467 bool OCCViewer_ViewPort::synchronize( OCCViewer_ViewPort* )
473 Sets the background color with color selection dialog. [ virtual protected slot ]
475 void OCCViewer_ViewPort::onChangeBackground()
477 QColor selColor = QColorDialog::getColor ( backgroundColor(), this );
478 if ( selColor.isValid() )
479 setBackgroundColor( selColor );