1 // Copyright (C) 2005 OPEN CASCADE
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
19 // Author : OPEN CASCADE
22 // File: GLViewer_ViewPort.cxx
23 // Created: November, 2004
25 //#include <GLViewerAfx.h>
27 #if !(defined WNT) && !(defined QT_CLEAN_NAMESPACE)
28 #define QT_CLEAN_NAMESPACE /* avoid definition of INT32 and INT8 */
31 #include "GLViewer_ViewPort.h"
33 #include "SUIT_ResourceMgr.h"
34 #include "SUIT_Session.h"
41 #include <qpopupmenu.h>
42 #include <qcolordialog.h>
49 #include <X11/Xutil.h>
50 #include <X11/Xatom.h>
51 #include <X11/Xmu/StdCmap.h>
52 #undef QT_CLEAN_NAMESPACE
53 #include <Xw_Window.hxx>
54 #include <Graphic3d_GraphicDevice.hxx>
67 XStandardColormap scmap;
73 CMapEntry::CMapEntry()
83 CMapEntry::~CMapEntry()
86 XFreeColormap( QPaintDevice::x11AppDisplay(), cmap );
89 static QIntDict<CMapEntry> *cmap_dict = 0;
90 static bool mesa_gl = false;
92 static void cleanup_cmaps()
96 cmap_dict->setAutoDelete( true );
101 static Colormap choose_cmap( Display *dpy, XVisualInfo *vi )
105 cmap_dict = new QIntDict<CMapEntry>;
106 const char *v = glXQueryServerString( dpy, vi->screen, GLX_VERSION );
107 mesa_gl = strstr( v,"Mesa" ) != 0;
108 qAddPostRoutine( cleanup_cmaps );
111 CMapEntry *x = cmap_dict->find( (long)vi->visualid );
112 if ( x ) // found colormap for visual
117 XStandardColormap *c;
121 cout << "Choosing cmap for vID = " << vi->visualid << endl;
124 if ( vi->visualid == XVisualIDFromVisual( (Visual*)QPaintDevice::x11AppVisual() ) )
127 cout << "Using x11AppColormap" << endl;
129 return QPaintDevice::x11AppColormap();
134 Atom hp_cmaps = XInternAtom( dpy, "_HP_RGB_SMOOTH_MAP_LIST", true );
135 if ( hp_cmaps && vi->visual->c_class == TrueColor && vi->depth == 8 )
137 if ( XGetRGBColormaps( dpy, RootWindow( dpy, vi->screen ), &c, &n, hp_cmaps ) )
140 while ( i < n && x->cmap == 0 )
142 if ( c[i].visualid == vi->visual->visualid )
144 x->cmap = c[i].colormap;
153 #if !defined( _OS_SOLARIS_ )
156 if ( XmuLookupStandardColormap( dpy, vi->screen, vi->visualid, vi->depth, XA_RGB_DEFAULT_MAP, false, true ) )
158 if ( XGetRGBColormaps( dpy, RootWindow( dpy, vi->screen ), &c, &n, XA_RGB_DEFAULT_MAP ) )
161 while ( i < n && x->cmap == 0 )
163 if ( c[i].visualid == vi->visualid )
165 x->cmap = c[i].colormap;
177 // no shared cmap found
178 x->cmap = XCreateColormap( dpy, RootWindow( dpy, vi->screen ), vi->visual, AllocNone );
182 cmap_dict->insert( (long)vi->visualid, x ); // associate cmap with visualid
187 int GLViewer_ViewPort::nCounter = 0;
188 QCursor* GLViewer_ViewPort::defCursor = 0;
189 QCursor* GLViewer_ViewPort::panglCursor = 0;
190 QCursor* GLViewer_ViewPort::handCursor = 0;
191 QCursor* GLViewer_ViewPort::panCursor = 0;
192 QCursor* GLViewer_ViewPort::zoomCursor = 0;
193 QCursor* GLViewer_ViewPort::rotCursor = 0;
194 QCursor* GLViewer_ViewPort::sketchCursor = 0;
197 Creates the necessary viewport cursors. [ static ]
199 void GLViewer_ViewPort::createCursors ()
201 defCursor = new QCursor( ArrowCursor );
202 panglCursor = new QCursor( CrossCursor );
203 handCursor = new QCursor( PointingHandCursor );
204 panCursor = new QCursor( SizeAllCursor );
206 SUIT_ResourceMgr* rmgr = SUIT_Session::session()->resourceMgr();
207 zoomCursor = new QCursor( rmgr->loadPixmap( "GLViewer", tr( "ICON_GL_CURSOR_ZOOM" ) ) );
208 rotCursor = new QCursor( rmgr->loadPixmap( "GLViewer", tr( "ICON_GL_CURSOR_ROTATE" ) ) );
209 sketchCursor = new QCursor( rmgr->loadPixmap( "GLViewer", tr( "ICON_GL_CURSOR_SKETCH" ) ) );
213 Destroys the viewport cursors. [ static ]
215 void GLViewer_ViewPort::destroyCursors()
217 delete defCursor; defCursor = 0;
218 delete panglCursor; panglCursor = 0;
219 delete handCursor; handCursor = 0;
220 delete panCursor; panCursor = 0;
221 delete zoomCursor; zoomCursor = 0;
222 delete rotCursor; rotCursor = 0;
223 delete sketchCursor; sketchCursor = 0;
227 Sets new default cursor. [ static ]
229 void GLViewer_ViewPort::setDefaultCursor( const QCursor& newCursor )
232 defCursor = new QCursor();
233 *defCursor = newCursor;
237 Sets new cursor for drawing rectangle in the viewport. [ static ]
239 void GLViewer_ViewPort::setHandCursor( const QCursor& newCursor )
242 handCursor = new QCursor();
243 *handCursor = newCursor;
247 Sets new cursor for panning. [ static ]
249 void GLViewer_ViewPort::setPanCursor( const QCursor& newCursor )
252 panCursor = new QCursor();
253 *panCursor = newCursor;
257 Sets new cursor for global panning. [ static ]
259 void GLViewer_ViewPort::setPanglCursor( const QCursor& newCursor )
262 panglCursor = new QCursor();
263 *panglCursor = newCursor;
267 Sets new cursor for zooming. [ static ]
269 void GLViewer_ViewPort::setZoomCursor( const QCursor& newCursor )
272 zoomCursor = new QCursor();
273 *zoomCursor = newCursor;
277 Sets new cursor for rotating. [ static ]
279 void GLViewer_ViewPort::setRotCursor( const QCursor& newCursor )
282 rotCursor = new QCursor();
283 *rotCursor = newCursor;
287 Sets new cursor for rotating. [ static ]
289 void GLViewer_ViewPort::setSketchCursor( const QCursor& newCursor )
292 sketchCursor = new QCursor();
293 *sketchCursor = newCursor;
299 GLViewer_ViewPort::GLViewer_ViewPort( QWidget* parent )
300 : QWidget( parent, 0, WRepaintNoErase | WResizeNoErase )
308 GLViewer_ViewPort::~GLViewer_ViewPort()
314 Initializes viewport. [ private ]
316 void GLViewer_ViewPort::initialize()
318 if ( nCounter++ == 0 )
321 //myPopupActions.setAutoDelete( true );
322 myPaintersRedrawing = false;
323 myEnableSketching = false;
324 myEnableTransform = true;
326 setMouseTracking( true );
327 setBackgroundMode( NoBackground );
329 setFocusPolicy( StrongFocus );
333 Cleans up the viewport. [ private ]
335 void GLViewer_ViewPort::cleanup()
337 if ( --nCounter == 0 )
342 Selects visual ID for OpenGL window ( X11 specific ). [ protected ]
344 void GLViewer_ViewPort::selectVisualId( ViewType type )
347 XVisualInfo* pVisualInfo;
350 /* Initialization with the default VisualID */
351 //Visual *v = DefaultVisual( x11Display(), DefaultScreen( x11Display() ) );
352 // int visualID = XVisualIDFromVisual( v ); unused
354 /* Here we use the settings from Optimizer_ViewInfo::TxglCreateWindow() */
355 int visualAttr[] = { GLX_RGBA, GLX_DEPTH_SIZE, 1, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1,
356 GLX_BLUE_SIZE, 1, GLX_DOUBLEBUFFER, None };
358 pVisualInfo = ::glXChooseVisual( x11Display(), DefaultScreen( x11Display() ), visualAttr );
363 XSetWindowAttributes a;
365 a.colormap = choose_cmap( x11Display(), pVisualInfo ); /* find best colormap */
366 a.background_pixel = backgroundColor().pixel();
367 a.border_pixel = black.pixel();
368 Window p = RootWindow( x11Display(), DefaultScreen( x11Display() ) );
369 if ( parentWidget() )
370 p = parentWidget()->winId();
373 if ( type == Type2D ) // creating simple X window for 2d
375 unsigned long xbackground =
376 BlackPixel( x11Display(), DefaultScreen( x11Display() ) );
377 unsigned long xforeground =
378 WhitePixel( x11Display(), DefaultScreen( x11Display() ) );
380 w = XCreateSimpleWindow ( x11Display(), p, x(), y(), width(),
381 height(), 0, xforeground, xbackground );
383 else if ( type == Type3D )
385 w = XCreateWindow( x11Display(), p, x(), y(), width(), height(),
386 0, pVisualInfo->depth, InputOutput, pVisualInfo->visual,
387 CWBackPixel | CWBorderPixel | CWColormap, &a );
395 if ( XGetWMColormapWindows( x11Display(), topLevelWidget()->winId(), &cmwret, &count ) )
397 cmw = new Window[count+1];
398 memcpy( (char*)cmw, (char*)cmwret, sizeof(Window) * count );
399 XFree( (char*)cmwret );
402 for ( i = 0; i < count; i++ )
404 if ( cmw[i] == winId() ) /* replace old window */
411 if ( i >= count ) /* append new window */
417 cmw = new Window[count];
421 /* Creating new window (with good VisualID) for this widget */
423 XSetWMColormapWindows( x11Display(), topLevelWidget()->winId(), cmw, count );
431 XFree( (char *)pVisualInfo );
433 XFlush( x11Display() );
439 Sets the background 'color'. [ virtual ]
441 void GLViewer_ViewPort::setBackgroundColor( const QColor& color )
443 QPalette pal = palette();
444 pal.setColor( QColorGroup::Background, color );
450 Returns the background color. [ virtual ]
452 QColor GLViewer_ViewPort::backgroundColor() const
454 return palette().active().background();
458 Returns 'true' if sketching is enabled in this viewport. [ public ]
460 bool GLViewer_ViewPort::isSketchingEnabled() const
462 return myEnableSketching;
466 Enables / disables sketching [ public ]
468 void GLViewer_ViewPort::setSketchingEnabled( bool enable )
470 myEnableSketching = enable;
474 Returns 'true' if transformations ( rotation, zoom etc. )
475 are enabled in this viewport. [ public ]
477 bool GLViewer_ViewPort::isTransformEnabled() const
479 return myEnableTransform;
483 Enables / disables transformations. [ public ]
485 void GLViewer_ViewPort::setTransformEnabled( bool enable )
487 myEnableTransform = enable;
491 Emits 'mouseEvent' signal. [ virtual protected ]
493 void GLViewer_ViewPort::mousePressEvent( QMouseEvent *e )
495 emit vpMouseEvent( e );
499 Emits 'mouseEvent' signal. [ virtual protected ]
501 void GLViewer_ViewPort::mouseMoveEvent( QMouseEvent* e )
503 emit vpMouseEvent( e );
507 Emits 'mouseEvent' signal. [ virtual protected ]
509 void GLViewer_ViewPort::mouseReleaseEvent( QMouseEvent *e )
511 emit vpMouseEvent( e );
513 /* show popup menu */
514 if ( e->button() == Qt::RightButton )
516 //QPopupMenu* popup = createPopup();
517 //if ( popup && popup->count() )
518 // popup->exec( QCursor::pos() );
519 //destroyPopup( /*popup*/ );
524 Emits 'mouseEvent' signal. [ virtual protected ]
526 void GLViewer_ViewPort::mouseDoubleClickEvent( QMouseEvent *e )
528 emit vpMouseEvent( e );
532 Emits 'keyEvent' signal. [ virtual protected ]
534 void GLViewer_ViewPort::keyPressEvent( QKeyEvent *e )
536 emit vpKeyEvent( e );
540 Emits 'keyEvent' signal. [ virtual protected ]
542 void GLViewer_ViewPort::keyReleaseEvent( QKeyEvent *e )
544 emit vpKeyEvent( e );
548 Emits 'mouseEvent' signal. [ virtual protected ]
550 void GLViewer_ViewPort::wheelEvent( QWheelEvent *e )
552 emit vpWheelEvent( e );
556 Repaints the viewport. [ virtual protected ]
558 void GLViewer_ViewPort::paintEvent( QPaintEvent* )
560 if ( myPaintersRedrawing )
563 emit vpDrawExternal( &p );
564 myPaintersRedrawing = false;
569 Forces to redraw the viewport by an external painter. [ public ]
571 void GLViewer_ViewPort::redrawPainters()
573 myPaintersRedrawing = true;
578 Updates this view. Does nothing by default. [ virtual public ]
580 void GLViewer_ViewPort::onUpdate()
585 Sets the background color with color selection dialog. [ virtual protected slot ]
587 void GLViewer_ViewPort::onChangeBgColor()
589 QColor selColor = QColorDialog::getColor ( backgroundColor(), this );
590 if ( selColor.isValid() )
591 setBackgroundColor( selColor );
595 Custom context menu event handler
597 void GLViewer_ViewPort::contextMenuEvent( QContextMenuEvent* e )
599 //if ( e->reason() != QContextMenuEvent::Mouse )
600 emit contextMenuRequested( e );