1 // File: GLViewer_ViewPort.cxx
2 // Created: November, 2004
4 // Copyright (C) CEA 2004
6 /***************************************************************************
7 ** Class: GLViewer_ViewPort
8 ** Descr: Visualisation canvas of QAD-based application
10 ** Created: UI team, 05.09.00
11 ****************************************************************************/
14 #define QT_CLEAN_NAMESPACE /* avoid definition of INT32 and INT8 */
17 #include "GLViewer_ViewPort.h"
19 #include "SUIT_ResourceMgr.h"
20 #include "SUIT_Session.h"
27 #include <qpopupmenu.h>
28 #include <qcolordialog.h>
35 #include <X11/Xutil.h>
36 #include <X11/Xatom.h>
37 #include <X11/Xmu/StdCmap.h>
38 #undef QT_CLEAN_NAMESPACE
39 #include <Xw_Window.hxx>
40 #include <Graphic3d_GraphicDevice.hxx>
48 XStandardColormap scmap;
51 CMapEntry::CMapEntry()
58 CMapEntry::~CMapEntry()
61 XFreeColormap( QPaintDevice::x11AppDisplay(), cmap );
64 static QIntDict<CMapEntry> *cmap_dict = 0;
65 static bool mesa_gl = false;
67 static void cleanup_cmaps()
71 cmap_dict->setAutoDelete( true );
76 static Colormap choose_cmap( Display *dpy, XVisualInfo *vi )
80 cmap_dict = new QIntDict<CMapEntry>;
81 const char *v = glXQueryServerString( dpy, vi->screen, GLX_VERSION );
82 mesa_gl = strstr( v,"Mesa" ) != 0;
83 qAddPostRoutine( cleanup_cmaps );
86 CMapEntry *x = cmap_dict->find( (long)vi->visualid );
87 if ( x ) // found colormap for visual
96 cout << "Choosing cmap for vID = " << vi->visualid << endl;
99 if ( vi->visualid == XVisualIDFromVisual( (Visual*)QPaintDevice::x11AppVisual() ) )
102 cout << "Using x11AppColormap" << endl;
104 return QPaintDevice::x11AppColormap();
109 Atom hp_cmaps = XInternAtom( dpy, "_HP_RGB_SMOOTH_MAP_LIST", true );
110 if ( hp_cmaps && vi->visual->c_class == TrueColor && vi->depth == 8 )
112 if ( XGetRGBColormaps( dpy, RootWindow( dpy, vi->screen ), &c, &n, hp_cmaps ) )
115 while ( i < n && x->cmap == 0 )
117 if ( c[i].visualid == vi->visual->visualid )
119 x->cmap = c[i].colormap;
128 #if !defined( _OS_SOLARIS_ )
131 if ( XmuLookupStandardColormap( dpy, vi->screen, vi->visualid, vi->depth, XA_RGB_DEFAULT_MAP, false, true ) )
133 if ( XGetRGBColormaps( dpy, RootWindow( dpy, vi->screen ), &c, &n, XA_RGB_DEFAULT_MAP ) )
136 while ( i < n && x->cmap == 0 )
138 if ( c[i].visualid == vi->visualid )
140 x->cmap = c[i].colormap;
152 // no shared cmap found
153 x->cmap = XCreateColormap( dpy, RootWindow( dpy, vi->screen ), vi->visual, AllocNone );
157 cmap_dict->insert( (long)vi->visualid, x ); // associate cmap with visualid
162 int GLViewer_ViewPort::nCounter = 0;
163 QCursor* GLViewer_ViewPort::defCursor = 0;
164 QCursor* GLViewer_ViewPort::panglCursor = 0;
165 QCursor* GLViewer_ViewPort::handCursor = 0;
166 QCursor* GLViewer_ViewPort::panCursor = 0;
167 QCursor* GLViewer_ViewPort::zoomCursor = 0;
168 QCursor* GLViewer_ViewPort::rotCursor = 0;
169 QCursor* GLViewer_ViewPort::sketchCursor = 0;
172 Creates the necessary viewport cursors. [ static ]
174 void GLViewer_ViewPort::createCursors ()
176 defCursor = new QCursor( ArrowCursor );
177 panglCursor = new QCursor( CrossCursor );
178 handCursor = new QCursor( PointingHandCursor );
179 panCursor = new QCursor( SizeAllCursor );
181 SUIT_ResourceMgr* rmgr = SUIT_Session::session()->resourceMgr();
182 zoomCursor = new QCursor( rmgr->loadPixmap( "GLViewer", tr( "ICON_CURSOR_ZOOM" ) ) );
183 rotCursor = new QCursor( rmgr->loadPixmap( "GLViewer", tr( "ICON_CURSOR_ROTATE" ) ) );
184 sketchCursor = new QCursor( rmgr->loadPixmap( "GLViewer", tr( "ICON_CURSOR_SKETCH" ) ) );
188 Destroys the viewport cursors. [ static ]
190 void GLViewer_ViewPort::destroyCursors()
192 delete defCursor; defCursor = 0;
193 delete panglCursor; panglCursor = 0;
194 delete handCursor; handCursor = 0;
195 delete panCursor; panCursor = 0;
196 delete zoomCursor; zoomCursor = 0;
197 delete rotCursor; rotCursor = 0;
198 delete sketchCursor; sketchCursor = 0;
202 Sets new default cursor. [ static ]
204 void GLViewer_ViewPort::setDefaultCursor( const QCursor& newCursor )
207 defCursor = new QCursor();
208 *defCursor = newCursor;
212 Sets new cursor for drawing rectangle in the viewport. [ static ]
214 void GLViewer_ViewPort::setHandCursor( const QCursor& newCursor )
217 handCursor = new QCursor();
218 *handCursor = newCursor;
222 Sets new cursor for panning. [ static ]
224 void GLViewer_ViewPort::setPanCursor( const QCursor& newCursor )
227 panCursor = new QCursor();
228 *panCursor = newCursor;
232 Sets new cursor for global panning. [ static ]
234 void GLViewer_ViewPort::setPanglCursor( const QCursor& newCursor )
237 panglCursor = new QCursor();
238 *panglCursor = newCursor;
242 Sets new cursor for zooming. [ static ]
244 void GLViewer_ViewPort::setZoomCursor( const QCursor& newCursor )
247 zoomCursor = new QCursor();
248 *zoomCursor = newCursor;
252 Sets new cursor for rotating. [ static ]
254 void GLViewer_ViewPort::setRotCursor( const QCursor& newCursor )
257 rotCursor = new QCursor();
258 *rotCursor = newCursor;
262 Sets new cursor for rotating. [ static ]
264 void GLViewer_ViewPort::setSketchCursor( const QCursor& newCursor )
267 sketchCursor = new QCursor();
268 *sketchCursor = newCursor;
274 GLViewer_ViewPort::GLViewer_ViewPort( QWidget* parent )
275 : QWidget( parent, 0, WRepaintNoErase | WResizeNoErase )
283 GLViewer_ViewPort::~GLViewer_ViewPort()
289 Initializes viewport. [ private ]
291 void GLViewer_ViewPort::initialize()
293 if ( nCounter++ == 0 )
296 //myPopupActions.setAutoDelete( true );
297 myPaintersRedrawing = false;
298 myEnableSketching = false;
299 myEnableTransform = true;
301 setMouseTracking( true );
302 setBackgroundMode( NoBackground );
303 // set focus policy to threat QContextMenuEvent from keyboard
304 setFocusPolicy( StrongFocus );
308 Cleans up the viewport. [ private ]
310 void GLViewer_ViewPort::cleanup()
312 if ( --nCounter == 0 )
317 Selects visual ID for OpenGL window ( X11 specific ). [ protected ]
319 void GLViewer_ViewPort::selectVisualId( ViewType type )
322 XVisualInfo* pVisualInfo;
325 /* Initialization with the default VisualID */
326 Visual *v = DefaultVisual( x11Display(), DefaultScreen( x11Display() ) );
327 /*int visualID = */XVisualIDFromVisual( v );
329 /* Here we use the settings from Optimizer_ViewInfo::TxglCreateWindow() */
330 int visualAttr[] = { GLX_RGBA, GLX_DEPTH_SIZE, 1, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1,
331 GLX_BLUE_SIZE, 1, GLX_DOUBLEBUFFER, None };
333 pVisualInfo = ::glXChooseVisual( x11Display(), DefaultScreen( x11Display() ), visualAttr );
338 XSetWindowAttributes a;
340 a.colormap = choose_cmap( x11Display(), pVisualInfo ); /* find best colormap */
341 a.background_pixel = backgroundColor().pixel();
342 a.border_pixel = black.pixel();
343 Window p = RootWindow( x11Display(), DefaultScreen( x11Display() ) );
344 if ( parentWidget() )
345 p = parentWidget()->winId();
348 if ( type == Type2D ) // creating simple X window for 2d
350 unsigned long xbackground =
351 BlackPixel( x11Display(), DefaultScreen( x11Display() ) );
352 unsigned long xforeground =
353 WhitePixel( x11Display(), DefaultScreen( x11Display() ) );
355 w = XCreateSimpleWindow ( x11Display(), p, x(), y(), width(),
356 height(), 0, xforeground, xbackground );
358 else if ( type == Type3D )
360 w = XCreateWindow( x11Display(), p, x(), y(), width(), height(),
361 0, pVisualInfo->depth, InputOutput, pVisualInfo->visual,
362 CWBackPixel | CWBorderPixel | CWColormap, &a );
370 if ( XGetWMColormapWindows( x11Display(), topLevelWidget()->winId(), &cmwret, &count ) )
372 cmw = new Window[count+1];
373 memcpy( (char*)cmw, (char*)cmwret, sizeof(Window) * count );
374 XFree( (char*)cmwret );
377 for ( i = 0; i < count; i++ )
379 if ( cmw[i] == winId() ) /* replace old window */
386 if ( i >= count ) /* append new window */
392 cmw = new Window[count];
396 /* Creating new window (with good VisualID) for this widget */
398 XSetWMColormapWindows( x11Display(), topLevelWidget()->winId(), cmw, count );
406 XFree( (char *)pVisualInfo );
408 XFlush( x11Display() );
414 Sets the background 'color'. [ virtual ]
416 void GLViewer_ViewPort::setBackgroundColor( const QColor& color )
418 QPalette pal = palette();
419 pal.setColor( QColorGroup::Background, color );
425 Returns the background color. [ virtual ]
427 QColor GLViewer_ViewPort::backgroundColor() const
429 return palette().active().background();
433 Returns 'true' if sketching is enabled in this viewport. [ public ]
435 bool GLViewer_ViewPort::isSketchingEnabled() const
437 return myEnableSketching;
441 Enables / disables sketching [ public ]
443 void GLViewer_ViewPort::setSketchingEnabled( bool enable )
445 myEnableSketching = enable;
449 Returns 'true' if transformations ( rotation, zoom etc. )
450 are enabled in this viewport. [ public ]
452 bool GLViewer_ViewPort::isTransformEnabled() const
454 return myEnableTransform;
458 Enables / disables transformations. [ public ]
460 void GLViewer_ViewPort::setTransformEnabled( bool enable )
462 myEnableTransform = enable;
466 Emits 'mouseEvent' signal. [ virtual protected ]
468 void GLViewer_ViewPort::mousePressEvent( QMouseEvent *e )
470 emit vpMouseEvent( e );
474 Emits 'mouseEvent' signal. [ virtual protected ]
476 void GLViewer_ViewPort::mouseMoveEvent( QMouseEvent* e )
478 emit vpMouseEvent( e );
482 Emits 'mouseEvent' signal. [ virtual protected ]
484 void GLViewer_ViewPort::mouseReleaseEvent( QMouseEvent *e )
486 emit vpMouseEvent( e );
488 /* show popup menu */
489 if ( e->button() == Qt::RightButton )
491 //QPopupMenu* popup = createPopup();
492 //if ( popup && popup->count() )
493 // popup->exec( QCursor::pos() );
494 //destroyPopup( /*popup*/ );
499 Emits 'mouseEvent' signal. [ virtual protected ]
501 void GLViewer_ViewPort::mouseDoubleClickEvent( QMouseEvent *e )
503 emit vpMouseEvent( e );
507 Emits 'keyEvent' signal. [ virtual protected ]
509 void GLViewer_ViewPort::keyPressEvent( QKeyEvent *e )
511 emit vpKeyEvent( e );
515 Emits 'keyEvent' signal. [ virtual protected ]
517 void GLViewer_ViewPort::keyReleaseEvent( QKeyEvent *e )
519 emit vpKeyEvent( e );
523 Emits 'mouseEvent' signal. [ virtual protected ]
525 void GLViewer_ViewPort::wheelEvent( QWheelEvent *e )
527 emit vpWheelEvent( e );
531 Repaints the viewport. [ virtual protected ]
533 void GLViewer_ViewPort::paintEvent( QPaintEvent* )
535 if ( myPaintersRedrawing )
538 emit vpDrawExternal( &p );
539 myPaintersRedrawing = false;
544 Forces to redraw the viewport by an external painter. [ public ]
546 void GLViewer_ViewPort::redrawPainters()
548 myPaintersRedrawing = true;
553 Updates this view. Does nothing by default. [ virtual public ]
555 void GLViewer_ViewPort::onUpdate()
560 Creates the popup. [ virtual protected ]
562 void GLViewer_ViewPort::onCreatePopup( QPopupMenu* popup )
567 if( myPopupActions.isEmpty() )
569 QAction* a = new QAction( "", tr( "MEN_VP_CHANGEBGR" ), 0, this );
570 a->setStatusTip( tr( "PRP_VP_CHANGEBGR" ) );
571 connect( a, SIGNAL( activated() ), SLOT( onChangeBgColor() ) );
572 myPopupActions.append( a );
579 Destroys the popup. [ virtual protected ]
581 void GLViewer_ViewPort::onDestroyPopup( QPopupMenu* popup )
586 for ( QAction* a = myPopupActions.first(); a; a = myPopupActions.next() )
587 a->removeFrom( popup );
588 myPopupActions.clear();
594 Sets the background color with color selection dialog. [ virtual protected slot ]
596 void GLViewer_ViewPort::onChangeBgColor()
598 QColor selColor = QColorDialog::getColor ( backgroundColor(), this );
599 if ( selColor.isValid() )
600 setBackgroundColor( selColor );
604 //****************************************************************
605 void GLViewer_ViewPort::contextMenuEvent ( QContextMenuEvent * e )
607 //if ( e->reason() != QContextMenuEvent::Mouse )
608 emit contextMenuRequested( e );