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 ****************************************************************************/
13 //#include <GLViewerAfx.h>
16 #define QT_CLEAN_NAMESPACE /* avoid definition of INT32 and INT8 */
19 #include "GLViewer_ViewPort.h"
21 #include "SUIT_ResourceMgr.h"
22 #include "SUIT_Session.h"
29 #include <qpopupmenu.h>
30 #include <qcolordialog.h>
37 #include <X11/Xutil.h>
38 #include <X11/Xatom.h>
39 #include <X11/Xmu/StdCmap.h>
40 #undef QT_CLEAN_NAMESPACE
41 #include <Xw_Window.hxx>
42 #include <Graphic3d_GraphicDevice.hxx>
50 XStandardColormap scmap;
53 CMapEntry::CMapEntry()
60 CMapEntry::~CMapEntry()
63 XFreeColormap( QPaintDevice::x11AppDisplay(), cmap );
66 static QIntDict<CMapEntry> *cmap_dict = 0;
67 static bool mesa_gl = false;
69 static void cleanup_cmaps()
73 cmap_dict->setAutoDelete( true );
78 static Colormap choose_cmap( Display *dpy, XVisualInfo *vi )
82 cmap_dict = new QIntDict<CMapEntry>;
83 const char *v = glXQueryServerString( dpy, vi->screen, GLX_VERSION );
84 mesa_gl = strstr( v,"Mesa" ) != 0;
85 qAddPostRoutine( cleanup_cmaps );
88 CMapEntry *x = cmap_dict->find( (long)vi->visualid );
89 if ( x ) // found colormap for visual
98 cout << "Choosing cmap for vID = " << vi->visualid << endl;
101 if ( vi->visualid == XVisualIDFromVisual( (Visual*)QPaintDevice::x11AppVisual() ) )
104 cout << "Using x11AppColormap" << endl;
106 return QPaintDevice::x11AppColormap();
111 Atom hp_cmaps = XInternAtom( dpy, "_HP_RGB_SMOOTH_MAP_LIST", true );
112 if ( hp_cmaps && vi->visual->c_class == TrueColor && vi->depth == 8 )
114 if ( XGetRGBColormaps( dpy, RootWindow( dpy, vi->screen ), &c, &n, hp_cmaps ) )
117 while ( i < n && x->cmap == 0 )
119 if ( c[i].visualid == vi->visual->visualid )
121 x->cmap = c[i].colormap;
130 #if !defined( _OS_SOLARIS_ )
133 if ( XmuLookupStandardColormap( dpy, vi->screen, vi->visualid, vi->depth, XA_RGB_DEFAULT_MAP, false, true ) )
135 if ( XGetRGBColormaps( dpy, RootWindow( dpy, vi->screen ), &c, &n, XA_RGB_DEFAULT_MAP ) )
138 while ( i < n && x->cmap == 0 )
140 if ( c[i].visualid == vi->visualid )
142 x->cmap = c[i].colormap;
154 // no shared cmap found
155 x->cmap = XCreateColormap( dpy, RootWindow( dpy, vi->screen ), vi->visual, AllocNone );
159 cmap_dict->insert( (long)vi->visualid, x ); // associate cmap with visualid
164 int GLViewer_ViewPort::nCounter = 0;
165 QCursor* GLViewer_ViewPort::defCursor = 0;
166 QCursor* GLViewer_ViewPort::panglCursor = 0;
167 QCursor* GLViewer_ViewPort::handCursor = 0;
168 QCursor* GLViewer_ViewPort::panCursor = 0;
169 QCursor* GLViewer_ViewPort::zoomCursor = 0;
170 QCursor* GLViewer_ViewPort::rotCursor = 0;
171 QCursor* GLViewer_ViewPort::sketchCursor = 0;
174 Creates the necessary viewport cursors. [ static ]
176 void GLViewer_ViewPort::createCursors ()
178 defCursor = new QCursor( ArrowCursor );
179 panglCursor = new QCursor( CrossCursor );
180 handCursor = new QCursor( PointingHandCursor );
181 panCursor = new QCursor( SizeAllCursor );
183 SUIT_ResourceMgr* rmgr = SUIT_Session::session()->resourceMgr();
184 zoomCursor = new QCursor( rmgr->loadPixmap( "GLViewer", tr( "ICON_GL_CURSOR_ZOOM" ) ) );
185 rotCursor = new QCursor( rmgr->loadPixmap( "GLViewer", tr( "ICON_GL_CURSOR_ROTATE" ) ) );
186 sketchCursor = new QCursor( rmgr->loadPixmap( "GLViewer", tr( "ICON_GL_CURSOR_SKETCH" ) ) );
190 Destroys the viewport cursors. [ static ]
192 void GLViewer_ViewPort::destroyCursors()
194 delete defCursor; defCursor = 0;
195 delete panglCursor; panglCursor = 0;
196 delete handCursor; handCursor = 0;
197 delete panCursor; panCursor = 0;
198 delete zoomCursor; zoomCursor = 0;
199 delete rotCursor; rotCursor = 0;
200 delete sketchCursor; sketchCursor = 0;
204 Sets new default cursor. [ static ]
206 void GLViewer_ViewPort::setDefaultCursor( const QCursor& newCursor )
209 defCursor = new QCursor();
210 *defCursor = newCursor;
214 Sets new cursor for drawing rectangle in the viewport. [ static ]
216 void GLViewer_ViewPort::setHandCursor( const QCursor& newCursor )
219 handCursor = new QCursor();
220 *handCursor = newCursor;
224 Sets new cursor for panning. [ static ]
226 void GLViewer_ViewPort::setPanCursor( const QCursor& newCursor )
229 panCursor = new QCursor();
230 *panCursor = newCursor;
234 Sets new cursor for global panning. [ static ]
236 void GLViewer_ViewPort::setPanglCursor( const QCursor& newCursor )
239 panglCursor = new QCursor();
240 *panglCursor = newCursor;
244 Sets new cursor for zooming. [ static ]
246 void GLViewer_ViewPort::setZoomCursor( const QCursor& newCursor )
249 zoomCursor = new QCursor();
250 *zoomCursor = newCursor;
254 Sets new cursor for rotating. [ static ]
256 void GLViewer_ViewPort::setRotCursor( const QCursor& newCursor )
259 rotCursor = new QCursor();
260 *rotCursor = newCursor;
264 Sets new cursor for rotating. [ static ]
266 void GLViewer_ViewPort::setSketchCursor( const QCursor& newCursor )
269 sketchCursor = new QCursor();
270 *sketchCursor = newCursor;
276 GLViewer_ViewPort::GLViewer_ViewPort( QWidget* parent )
277 : QWidget( parent, 0, WRepaintNoErase | WResizeNoErase )
285 GLViewer_ViewPort::~GLViewer_ViewPort()
291 Initializes viewport. [ private ]
293 void GLViewer_ViewPort::initialize()
295 if ( nCounter++ == 0 )
298 //myPopupActions.setAutoDelete( true );
299 myPaintersRedrawing = false;
300 myEnableSketching = false;
301 myEnableTransform = true;
303 setMouseTracking( true );
304 setBackgroundMode( NoBackground );
306 setFocusPolicy( StrongFocus );
310 Cleans up the viewport. [ private ]
312 void GLViewer_ViewPort::cleanup()
314 if ( --nCounter == 0 )
319 Selects visual ID for OpenGL window ( X11 specific ). [ protected ]
321 void GLViewer_ViewPort::selectVisualId( ViewType type )
324 XVisualInfo* pVisualInfo;
327 /* Initialization with the default VisualID */
328 //Visual *v = DefaultVisual( x11Display(), DefaultScreen( x11Display() ) );
329 // int visualID = XVisualIDFromVisual( v ); unused
331 /* Here we use the settings from Optimizer_ViewInfo::TxglCreateWindow() */
332 int visualAttr[] = { GLX_RGBA, GLX_DEPTH_SIZE, 1, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1,
333 GLX_BLUE_SIZE, 1, GLX_DOUBLEBUFFER, None };
335 pVisualInfo = ::glXChooseVisual( x11Display(), DefaultScreen( x11Display() ), visualAttr );
340 XSetWindowAttributes a;
342 a.colormap = choose_cmap( x11Display(), pVisualInfo ); /* find best colormap */
343 a.background_pixel = backgroundColor().pixel();
344 a.border_pixel = black.pixel();
345 Window p = RootWindow( x11Display(), DefaultScreen( x11Display() ) );
346 if ( parentWidget() )
347 p = parentWidget()->winId();
350 if ( type == Type2D ) // creating simple X window for 2d
352 unsigned long xbackground =
353 BlackPixel( x11Display(), DefaultScreen( x11Display() ) );
354 unsigned long xforeground =
355 WhitePixel( x11Display(), DefaultScreen( x11Display() ) );
357 w = XCreateSimpleWindow ( x11Display(), p, x(), y(), width(),
358 height(), 0, xforeground, xbackground );
360 else if ( type == Type3D )
362 w = XCreateWindow( x11Display(), p, x(), y(), width(), height(),
363 0, pVisualInfo->depth, InputOutput, pVisualInfo->visual,
364 CWBackPixel | CWBorderPixel | CWColormap, &a );
372 if ( XGetWMColormapWindows( x11Display(), topLevelWidget()->winId(), &cmwret, &count ) )
374 cmw = new Window[count+1];
375 memcpy( (char*)cmw, (char*)cmwret, sizeof(Window) * count );
376 XFree( (char*)cmwret );
379 for ( i = 0; i < count; i++ )
381 if ( cmw[i] == winId() ) /* replace old window */
388 if ( i >= count ) /* append new window */
394 cmw = new Window[count];
398 /* Creating new window (with good VisualID) for this widget */
400 XSetWMColormapWindows( x11Display(), topLevelWidget()->winId(), cmw, count );
408 XFree( (char *)pVisualInfo );
410 XFlush( x11Display() );
416 Sets the background 'color'. [ virtual ]
418 void GLViewer_ViewPort::setBackgroundColor( const QColor& color )
420 QPalette pal = palette();
421 pal.setColor( QColorGroup::Background, color );
427 Returns the background color. [ virtual ]
429 QColor GLViewer_ViewPort::backgroundColor() const
431 return palette().active().background();
435 Returns 'true' if sketching is enabled in this viewport. [ public ]
437 bool GLViewer_ViewPort::isSketchingEnabled() const
439 return myEnableSketching;
443 Enables / disables sketching [ public ]
445 void GLViewer_ViewPort::setSketchingEnabled( bool enable )
447 myEnableSketching = enable;
451 Returns 'true' if transformations ( rotation, zoom etc. )
452 are enabled in this viewport. [ public ]
454 bool GLViewer_ViewPort::isTransformEnabled() const
456 return myEnableTransform;
460 Enables / disables transformations. [ public ]
462 void GLViewer_ViewPort::setTransformEnabled( bool enable )
464 myEnableTransform = enable;
468 Emits 'mouseEvent' signal. [ virtual protected ]
470 void GLViewer_ViewPort::mousePressEvent( QMouseEvent *e )
472 emit vpMouseEvent( e );
476 Emits 'mouseEvent' signal. [ virtual protected ]
478 void GLViewer_ViewPort::mouseMoveEvent( QMouseEvent* e )
480 emit vpMouseEvent( e );
484 Emits 'mouseEvent' signal. [ virtual protected ]
486 void GLViewer_ViewPort::mouseReleaseEvent( QMouseEvent *e )
488 emit vpMouseEvent( e );
490 /* show popup menu */
491 if ( e->button() == Qt::RightButton )
493 //QPopupMenu* popup = createPopup();
494 //if ( popup && popup->count() )
495 // popup->exec( QCursor::pos() );
496 //destroyPopup( /*popup*/ );
501 Emits 'mouseEvent' signal. [ virtual protected ]
503 void GLViewer_ViewPort::mouseDoubleClickEvent( QMouseEvent *e )
505 emit vpMouseEvent( e );
509 Emits 'keyEvent' signal. [ virtual protected ]
511 void GLViewer_ViewPort::keyPressEvent( QKeyEvent *e )
513 emit vpKeyEvent( e );
517 Emits 'keyEvent' signal. [ virtual protected ]
519 void GLViewer_ViewPort::keyReleaseEvent( QKeyEvent *e )
521 emit vpKeyEvent( e );
525 Emits 'mouseEvent' signal. [ virtual protected ]
527 void GLViewer_ViewPort::wheelEvent( QWheelEvent *e )
529 emit vpWheelEvent( e );
533 Repaints the viewport. [ virtual protected ]
535 void GLViewer_ViewPort::paintEvent( QPaintEvent* )
537 if ( myPaintersRedrawing )
540 emit vpDrawExternal( &p );
541 myPaintersRedrawing = false;
546 Forces to redraw the viewport by an external painter. [ public ]
548 void GLViewer_ViewPort::redrawPainters()
550 myPaintersRedrawing = true;
555 Updates this view. Does nothing by default. [ virtual public ]
557 void GLViewer_ViewPort::onUpdate()
562 Sets the background color with color selection dialog. [ virtual protected slot ]
564 void GLViewer_ViewPort::onChangeBgColor()
566 QColor selColor = QColorDialog::getColor ( backgroundColor(), this );
567 if ( selColor.isValid() )
568 setBackgroundColor( selColor );
571 void GLViewer_ViewPort::contextMenuEvent( QContextMenuEvent* e )
573 //if ( e->reason() != QContextMenuEvent::Mouse )
574 emit contextMenuRequested( e );