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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
19 // Author : OPEN CASCADE
22 // File: GLViewer_ViewPort.cxx
23 // Created: November, 2004
25 /***************************************************************************
26 ** Class: GLViewer_ViewPort
27 ** Descr: Visualisation canvas of QAD-based application
29 ** Created: UI team, 05.09.00
30 ****************************************************************************/
32 //#include <GLViewerAfx.h>
35 #define QT_CLEAN_NAMESPACE /* avoid definition of INT32 and INT8 */
38 #include "GLViewer_ViewPort.h"
40 #include "SUIT_ResourceMgr.h"
41 #include "SUIT_Session.h"
48 #include <qpopupmenu.h>
49 #include <qcolordialog.h>
56 #include <X11/Xutil.h>
57 #include <X11/Xatom.h>
58 #include <X11/Xmu/StdCmap.h>
59 #undef QT_CLEAN_NAMESPACE
60 #include <Xw_Window.hxx>
61 #include <Graphic3d_GraphicDevice.hxx>
69 XStandardColormap scmap;
72 CMapEntry::CMapEntry()
79 CMapEntry::~CMapEntry()
82 XFreeColormap( QPaintDevice::x11AppDisplay(), cmap );
85 static QIntDict<CMapEntry> *cmap_dict = 0;
86 static bool mesa_gl = false;
88 static void cleanup_cmaps()
92 cmap_dict->setAutoDelete( true );
97 static Colormap choose_cmap( Display *dpy, XVisualInfo *vi )
101 cmap_dict = new QIntDict<CMapEntry>;
102 const char *v = glXQueryServerString( dpy, vi->screen, GLX_VERSION );
103 mesa_gl = strstr( v,"Mesa" ) != 0;
104 qAddPostRoutine( cleanup_cmaps );
107 CMapEntry *x = cmap_dict->find( (long)vi->visualid );
108 if ( x ) // found colormap for visual
113 XStandardColormap *c;
117 cout << "Choosing cmap for vID = " << vi->visualid << endl;
120 if ( vi->visualid == XVisualIDFromVisual( (Visual*)QPaintDevice::x11AppVisual() ) )
123 cout << "Using x11AppColormap" << endl;
125 return QPaintDevice::x11AppColormap();
130 Atom hp_cmaps = XInternAtom( dpy, "_HP_RGB_SMOOTH_MAP_LIST", true );
131 if ( hp_cmaps && vi->visual->c_class == TrueColor && vi->depth == 8 )
133 if ( XGetRGBColormaps( dpy, RootWindow( dpy, vi->screen ), &c, &n, hp_cmaps ) )
136 while ( i < n && x->cmap == 0 )
138 if ( c[i].visualid == vi->visual->visualid )
140 x->cmap = c[i].colormap;
149 #if !defined( _OS_SOLARIS_ )
152 if ( XmuLookupStandardColormap( dpy, vi->screen, vi->visualid, vi->depth, XA_RGB_DEFAULT_MAP, false, true ) )
154 if ( XGetRGBColormaps( dpy, RootWindow( dpy, vi->screen ), &c, &n, XA_RGB_DEFAULT_MAP ) )
157 while ( i < n && x->cmap == 0 )
159 if ( c[i].visualid == vi->visualid )
161 x->cmap = c[i].colormap;
173 // no shared cmap found
174 x->cmap = XCreateColormap( dpy, RootWindow( dpy, vi->screen ), vi->visual, AllocNone );
178 cmap_dict->insert( (long)vi->visualid, x ); // associate cmap with visualid
183 int GLViewer_ViewPort::nCounter = 0;
184 QCursor* GLViewer_ViewPort::defCursor = 0;
185 QCursor* GLViewer_ViewPort::panglCursor = 0;
186 QCursor* GLViewer_ViewPort::handCursor = 0;
187 QCursor* GLViewer_ViewPort::panCursor = 0;
188 QCursor* GLViewer_ViewPort::zoomCursor = 0;
189 QCursor* GLViewer_ViewPort::rotCursor = 0;
190 QCursor* GLViewer_ViewPort::sketchCursor = 0;
193 Creates the necessary viewport cursors. [ static ]
195 void GLViewer_ViewPort::createCursors ()
197 defCursor = new QCursor( ArrowCursor );
198 panglCursor = new QCursor( CrossCursor );
199 handCursor = new QCursor( PointingHandCursor );
200 panCursor = new QCursor( SizeAllCursor );
202 SUIT_ResourceMgr* rmgr = SUIT_Session::session()->resourceMgr();
203 zoomCursor = new QCursor( rmgr->loadPixmap( "GLViewer", tr( "ICON_GL_CURSOR_ZOOM" ) ) );
204 rotCursor = new QCursor( rmgr->loadPixmap( "GLViewer", tr( "ICON_GL_CURSOR_ROTATE" ) ) );
205 sketchCursor = new QCursor( rmgr->loadPixmap( "GLViewer", tr( "ICON_GL_CURSOR_SKETCH" ) ) );
209 Destroys the viewport cursors. [ static ]
211 void GLViewer_ViewPort::destroyCursors()
213 delete defCursor; defCursor = 0;
214 delete panglCursor; panglCursor = 0;
215 delete handCursor; handCursor = 0;
216 delete panCursor; panCursor = 0;
217 delete zoomCursor; zoomCursor = 0;
218 delete rotCursor; rotCursor = 0;
219 delete sketchCursor; sketchCursor = 0;
223 Sets new default cursor. [ static ]
225 void GLViewer_ViewPort::setDefaultCursor( const QCursor& newCursor )
228 defCursor = new QCursor();
229 *defCursor = newCursor;
233 Sets new cursor for drawing rectangle in the viewport. [ static ]
235 void GLViewer_ViewPort::setHandCursor( const QCursor& newCursor )
238 handCursor = new QCursor();
239 *handCursor = newCursor;
243 Sets new cursor for panning. [ static ]
245 void GLViewer_ViewPort::setPanCursor( const QCursor& newCursor )
248 panCursor = new QCursor();
249 *panCursor = newCursor;
253 Sets new cursor for global panning. [ static ]
255 void GLViewer_ViewPort::setPanglCursor( const QCursor& newCursor )
258 panglCursor = new QCursor();
259 *panglCursor = newCursor;
263 Sets new cursor for zooming. [ static ]
265 void GLViewer_ViewPort::setZoomCursor( const QCursor& newCursor )
268 zoomCursor = new QCursor();
269 *zoomCursor = newCursor;
273 Sets new cursor for rotating. [ static ]
275 void GLViewer_ViewPort::setRotCursor( const QCursor& newCursor )
278 rotCursor = new QCursor();
279 *rotCursor = newCursor;
283 Sets new cursor for rotating. [ static ]
285 void GLViewer_ViewPort::setSketchCursor( const QCursor& newCursor )
288 sketchCursor = new QCursor();
289 *sketchCursor = newCursor;
295 GLViewer_ViewPort::GLViewer_ViewPort( QWidget* parent )
296 : QWidget( parent, 0, WRepaintNoErase | WResizeNoErase )
304 GLViewer_ViewPort::~GLViewer_ViewPort()
310 Initializes viewport. [ private ]
312 void GLViewer_ViewPort::initialize()
314 if ( nCounter++ == 0 )
317 //myPopupActions.setAutoDelete( true );
318 myPaintersRedrawing = false;
319 myEnableSketching = false;
320 myEnableTransform = true;
322 setMouseTracking( true );
323 setBackgroundMode( NoBackground );
325 setFocusPolicy( StrongFocus );
329 Cleans up the viewport. [ private ]
331 void GLViewer_ViewPort::cleanup()
333 if ( --nCounter == 0 )
338 Selects visual ID for OpenGL window ( X11 specific ). [ protected ]
340 void GLViewer_ViewPort::selectVisualId( ViewType type )
343 XVisualInfo* pVisualInfo;
346 /* Initialization with the default VisualID */
347 //Visual *v = DefaultVisual( x11Display(), DefaultScreen( x11Display() ) );
348 // int visualID = XVisualIDFromVisual( v ); unused
350 /* Here we use the settings from Optimizer_ViewInfo::TxglCreateWindow() */
351 int visualAttr[] = { GLX_RGBA, GLX_DEPTH_SIZE, 1, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1,
352 GLX_BLUE_SIZE, 1, GLX_DOUBLEBUFFER, None };
354 pVisualInfo = ::glXChooseVisual( x11Display(), DefaultScreen( x11Display() ), visualAttr );
359 XSetWindowAttributes a;
361 a.colormap = choose_cmap( x11Display(), pVisualInfo ); /* find best colormap */
362 a.background_pixel = backgroundColor().pixel();
363 a.border_pixel = black.pixel();
364 Window p = RootWindow( x11Display(), DefaultScreen( x11Display() ) );
365 if ( parentWidget() )
366 p = parentWidget()->winId();
369 if ( type == Type2D ) // creating simple X window for 2d
371 unsigned long xbackground =
372 BlackPixel( x11Display(), DefaultScreen( x11Display() ) );
373 unsigned long xforeground =
374 WhitePixel( x11Display(), DefaultScreen( x11Display() ) );
376 w = XCreateSimpleWindow ( x11Display(), p, x(), y(), width(),
377 height(), 0, xforeground, xbackground );
379 else if ( type == Type3D )
381 w = XCreateWindow( x11Display(), p, x(), y(), width(), height(),
382 0, pVisualInfo->depth, InputOutput, pVisualInfo->visual,
383 CWBackPixel | CWBorderPixel | CWColormap, &a );
391 if ( XGetWMColormapWindows( x11Display(), topLevelWidget()->winId(), &cmwret, &count ) )
393 cmw = new Window[count+1];
394 memcpy( (char*)cmw, (char*)cmwret, sizeof(Window) * count );
395 XFree( (char*)cmwret );
398 for ( i = 0; i < count; i++ )
400 if ( cmw[i] == winId() ) /* replace old window */
407 if ( i >= count ) /* append new window */
413 cmw = new Window[count];
417 /* Creating new window (with good VisualID) for this widget */
419 XSetWMColormapWindows( x11Display(), topLevelWidget()->winId(), cmw, count );
427 XFree( (char *)pVisualInfo );
429 XFlush( x11Display() );
435 Sets the background 'color'. [ virtual ]
437 void GLViewer_ViewPort::setBackgroundColor( const QColor& color )
439 QPalette pal = palette();
440 pal.setColor( QColorGroup::Background, color );
446 Returns the background color. [ virtual ]
448 QColor GLViewer_ViewPort::backgroundColor() const
450 return palette().active().background();
454 Returns 'true' if sketching is enabled in this viewport. [ public ]
456 bool GLViewer_ViewPort::isSketchingEnabled() const
458 return myEnableSketching;
462 Enables / disables sketching [ public ]
464 void GLViewer_ViewPort::setSketchingEnabled( bool enable )
466 myEnableSketching = enable;
470 Returns 'true' if transformations ( rotation, zoom etc. )
471 are enabled in this viewport. [ public ]
473 bool GLViewer_ViewPort::isTransformEnabled() const
475 return myEnableTransform;
479 Enables / disables transformations. [ public ]
481 void GLViewer_ViewPort::setTransformEnabled( bool enable )
483 myEnableTransform = enable;
487 Emits 'mouseEvent' signal. [ virtual protected ]
489 void GLViewer_ViewPort::mousePressEvent( QMouseEvent *e )
491 emit vpMouseEvent( e );
495 Emits 'mouseEvent' signal. [ virtual protected ]
497 void GLViewer_ViewPort::mouseMoveEvent( QMouseEvent* e )
499 emit vpMouseEvent( e );
503 Emits 'mouseEvent' signal. [ virtual protected ]
505 void GLViewer_ViewPort::mouseReleaseEvent( QMouseEvent *e )
507 emit vpMouseEvent( e );
509 /* show popup menu */
510 if ( e->button() == Qt::RightButton )
512 //QPopupMenu* popup = createPopup();
513 //if ( popup && popup->count() )
514 // popup->exec( QCursor::pos() );
515 //destroyPopup( /*popup*/ );
520 Emits 'mouseEvent' signal. [ virtual protected ]
522 void GLViewer_ViewPort::mouseDoubleClickEvent( QMouseEvent *e )
524 emit vpMouseEvent( e );
528 Emits 'keyEvent' signal. [ virtual protected ]
530 void GLViewer_ViewPort::keyPressEvent( QKeyEvent *e )
532 emit vpKeyEvent( e );
536 Emits 'keyEvent' signal. [ virtual protected ]
538 void GLViewer_ViewPort::keyReleaseEvent( QKeyEvent *e )
540 emit vpKeyEvent( e );
544 Emits 'mouseEvent' signal. [ virtual protected ]
546 void GLViewer_ViewPort::wheelEvent( QWheelEvent *e )
548 emit vpWheelEvent( e );
552 Repaints the viewport. [ virtual protected ]
554 void GLViewer_ViewPort::paintEvent( QPaintEvent* )
556 if ( myPaintersRedrawing )
559 emit vpDrawExternal( &p );
560 myPaintersRedrawing = false;
565 Forces to redraw the viewport by an external painter. [ public ]
567 void GLViewer_ViewPort::redrawPainters()
569 myPaintersRedrawing = true;
574 Updates this view. Does nothing by default. [ virtual public ]
576 void GLViewer_ViewPort::onUpdate()
581 Sets the background color with color selection dialog. [ virtual protected slot ]
583 void GLViewer_ViewPort::onChangeBgColor()
585 QColor selColor = QColorDialog::getColor ( backgroundColor(), this );
586 if ( selColor.isValid() )
587 setBackgroundColor( selColor );
590 void GLViewer_ViewPort::contextMenuEvent( QContextMenuEvent* e )
592 //if ( e->reason() != QContextMenuEvent::Mouse )
593 emit contextMenuRequested( e );