1 // Copyright (C) 2005 OPEN CASCADE, CEA/DEN, EDF R&D, PRINCIPIA R&D
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/
19 /***************************************************************************
20 ** Class: OCCViewer_ViewPort
21 ** Descr: Visualisation canvas of SUIT-based application
23 ** Created: UI team, 05.09.00
24 ****************************************************************************/
26 #define QT_CLEAN_NAMESPACE /* avoid definition of INT32 and INT8 */
29 #include "OCCViewer_ViewPort.h"
31 #include "SUIT_Session.h"
38 #include <qpopupmenu.h>
39 #include <qcolordialog.h>
46 #include <X11/Xutil.h>
47 #include <X11/Xatom.h>
48 #include <X11/Xmu/StdCmap.h>
49 #undef QT_CLEAN_NAMESPACE
50 #include <Xw_Window.hxx>
51 #include <Graphic3d_GraphicDevice.hxx>
59 XStandardColormap scmap;
62 CMapEntry::CMapEntry()
69 CMapEntry::~CMapEntry()
72 XFreeColormap( QPaintDevice::x11AppDisplay(), cmap );
75 static QIntDict<CMapEntry> *cmap_dict = 0;
76 static bool mesa_gl = false;
78 static void cleanup_cmaps()
82 cmap_dict->setAutoDelete( true );
87 static Colormap choose_cmap( Display *dpy, XVisualInfo *vi )
91 cmap_dict = new QIntDict<CMapEntry>;
92 const char *v = glXQueryServerString( dpy, vi->screen, GLX_VERSION );
93 mesa_gl = strstr( v,"Mesa" ) != 0;
94 qAddPostRoutine( cleanup_cmaps );
97 CMapEntry *x = cmap_dict->find( (long)vi->visualid );
98 if ( x ) // found colormap for visual
103 XStandardColormap *c;
107 cout << "Choosing cmap for vID = " << vi->visualid << endl;
110 if ( vi->visualid == XVisualIDFromVisual( (Visual*)QPaintDevice::x11AppVisual() ) )
113 cout << "Using x11AppColormap" << endl;
115 return QPaintDevice::x11AppColormap();
120 Atom hp_cmaps = XInternAtom( dpy, "_HP_RGB_SMOOTH_MAP_LIST", true );
121 if ( hp_cmaps && vi->visual->c_class == TrueColor && vi->depth == 8 )
123 if ( XGetRGBColormaps( dpy, RootWindow( dpy, vi->screen ), &c, &n, hp_cmaps ) )
126 while ( i < n && x->cmap == 0 )
128 if ( c[i].visualid == vi->visual->visualid )
130 x->cmap = c[i].colormap;
139 #if !defined( _OS_SOLARIS_ )
142 if ( XmuLookupStandardColormap( dpy, vi->screen, vi->visualid, vi->depth, XA_RGB_DEFAULT_MAP, false, true ) )
144 if ( XGetRGBColormaps( dpy, RootWindow( dpy, vi->screen ), &c, &n, XA_RGB_DEFAULT_MAP ) )
147 while ( i < n && x->cmap == 0 )
149 if ( c[i].visualid == vi->visualid )
151 x->cmap = c[i].colormap;
163 // no shared cmap found
164 x->cmap = XCreateColormap( dpy, RootWindow( dpy, vi->screen ), vi->visual, AllocNone );
168 cmap_dict->insert( (long)vi->visualid, x ); // associate cmap with visualid
177 OCCViewer_ViewPort::OCCViewer_ViewPort( QWidget* parent )
178 : QWidget( parent, 0, WRepaintNoErase | WResizeNoErase )
186 OCCViewer_ViewPort::~OCCViewer_ViewPort()
192 Initializes viewport. [ private ]
194 void OCCViewer_ViewPort::initialize()
196 myPopupActions.setAutoDelete( true );
197 myPaintersRedrawing = false;
198 myEnableSketching = false;
199 myEnableTransform = true;
201 setMouseTracking( true );
202 setBackgroundMode( NoBackground );
203 // set focus policy to threat QContextMenuEvent from keyboard
204 setFocusPolicy( StrongFocus );
208 Cleans up the viewport. [ private ]
210 void OCCViewer_ViewPort::cleanup()
215 Selects visual ID for OpenGL window ( X11 specific ). [ protected ]
217 void OCCViewer_ViewPort::selectVisualId()
220 XVisualInfo* pVisualInfo;
223 /* Initialization with the default VisualID */
224 Visual *v = DefaultVisual( x11Display(), DefaultScreen( x11Display() ) );
225 int visualID = XVisualIDFromVisual( v );
227 /* Here we use the settings from Optimizer_ViewInfo::TxglCreateWindow() */
228 int visualAttr[] = { GLX_RGBA, GLX_DEPTH_SIZE, 1, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1,
229 GLX_BLUE_SIZE, 1, GLX_DOUBLEBUFFER, None };
231 pVisualInfo = ::glXChooseVisual( x11Display(), DefaultScreen( x11Display() ), visualAttr );
236 XSetWindowAttributes a;
238 a.colormap = choose_cmap( x11Display(), pVisualInfo ); /* find best colormap */
239 a.background_pixel = backgroundColor().pixel();
240 a.border_pixel = black.pixel();
241 Window p = RootWindow( x11Display(), DefaultScreen( x11Display() ) );
242 if ( parentWidget() )
243 p = parentWidget()->winId();
246 /* if ( type == Type2D ) // creating simple X window for 2d
248 unsigned long xbackground =
249 BlackPixel( x11Display(), DefaultScreen( x11Display() ) );
250 unsigned long xforeground =
251 WhitePixel( x11Display(), DefaultScreen( x11Display() ) );
253 w = XCreateSimpleWindow ( x11Display(), p, x(), y(), width(),
254 height(), 0, xforeground, xbackground );
256 else if ( type == Type3D )
258 w = XCreateWindow( x11Display(), p, x(), y(), width(), height(),
259 0, pVisualInfo->depth, InputOutput, pVisualInfo->visual,
260 CWBackPixel | CWBorderPixel | CWColormap, &a );
264 w = XCreateWindow( x11Display(), p, x(), y(), width(), height(),
265 0, pVisualInfo->depth, InputOutput, pVisualInfo->visual,
266 CWBackPixel | CWBorderPixel | CWColormap, &a );
271 if ( XGetWMColormapWindows( x11Display(), topLevelWidget()->winId(), &cmwret, &count ) )
273 cmw = new Window[count+1];
274 memcpy( (char*)cmw, (char*)cmwret, sizeof(Window) * count );
275 XFree( (char*)cmwret );
278 for ( i = 0; i < count; i++ )
280 if ( cmw[i] == winId() ) /* replace old window */
287 if ( i >= count ) /* append new window */
293 cmw = new Window[count];
297 /* Creating new window (with good VisualID) for this widget */
299 XSetWMColormapWindows( x11Display(), topLevelWidget()->winId(), cmw, count );
307 XFree( (char *)pVisualInfo );
309 XFlush( x11Display() );
315 Sets the background 'color'. [ virtual ]
317 void OCCViewer_ViewPort::setBackgroundColor( const QColor& color )
319 QPalette pal = palette();
320 pal.setColor( QColorGroup::Background, color );
323 emit vpChangeBGColor( color );
327 Returns the background color. [ virtual ]
329 QColor OCCViewer_ViewPort::backgroundColor() const
331 return palette().active().background();
335 Returns 'true' if sketching is enabled in this viewport. [ public ]
337 bool OCCViewer_ViewPort::isSketchingEnabled() const
339 return myEnableSketching;
343 Enables / disables sketching [ public ]
345 void OCCViewer_ViewPort::setSketchingEnabled( bool enable )
347 myEnableSketching = enable;
351 Returns 'true' if transformations ( rotation, zoom etc. )
352 are enabled in this viewport. [ public ]
354 bool OCCViewer_ViewPort::isTransformEnabled() const
356 return myEnableTransform;
360 Enables / disables transformations. [ public ]
362 void OCCViewer_ViewPort::setTransformEnabled( bool enable )
364 myEnableTransform = enable;
368 Emits 'mouseEvent' signal. [ virtual protected ]
370 void OCCViewer_ViewPort::mousePressEvent( QMouseEvent *e )
372 emit vpMouseEvent( e );
376 Emits 'mouseEvent' signal. [ virtual protected ]
378 void OCCViewer_ViewPort::mouseMoveEvent( QMouseEvent* e )
380 emit vpMouseEvent( e );
384 Emits 'mouseEvent' signal. [ virtual protected ]
386 void OCCViewer_ViewPort::mouseReleaseEvent( QMouseEvent *e )
388 emit vpMouseEvent( e );
392 Emits 'mouseEvent' signal. [ virtual protected ]
394 void OCCViewer_ViewPort::mouseDoubleClickEvent( QMouseEvent *e )
396 emit vpMouseEvent( e );
400 Emits 'keyEvent' signal. [ virtual protected ]
402 void OCCViewer_ViewPort::keyPressEvent( QKeyEvent *e )
404 emit vpKeyEvent( e );
408 Emits 'keyEvent' signal. [ virtual protected ]
410 void OCCViewer_ViewPort::keyReleaseEvent( QKeyEvent *e )
412 emit vpKeyEvent( e );
416 Repaints the viewport. [ virtual protected ]
418 void OCCViewer_ViewPort::paintEvent( QPaintEvent* )
420 if ( myPaintersRedrawing )
423 emit vpDrawExternal( &p );
424 myPaintersRedrawing = false;
429 Forces to redraw the viewport by an external painter. [ public ]
431 void OCCViewer_ViewPort::redrawPainters()
433 myPaintersRedrawing = true;
438 Updates this view. Does nothing by default. [ virtual public ]
440 void OCCViewer_ViewPort::onUpdate()
445 Creates the popup. [ virtual protected ]
447 /*void OCCViewer_ViewPort::onCreatePopup( QPopupMenu* popup )
451 QtxAction* a = new QtxAction( "", tr( "MEN_VP_CHANGEBGR" ), 0, this );
452 a->setStatusTip( tr( "PRP_VP_CHANGEBGR" ) );
453 connect( a, SIGNAL( activated() ), SLOT( onChangeBgColor()));
454 myPopupActions.append( a );
460 Destroys the popup. [ virtual protected ]
462 /*void OCCViewer_ViewPort::onDestroyPopup( QPopupMenu* popup )
466 for ( QtxAction* a = myPopupActions.first(); a; a = myPopupActions.next() )
467 a->removeFrom( popup );
468 myPopupActions.clear();
473 Sets the background color with color selection dialog. [ virtual protected slot ]
475 void OCCViewer_ViewPort::onChangeBgColor()
477 QColor selColor = QColorDialog::getColor ( backgroundColor(), this );
478 if ( selColor.isValid() )
479 setBackgroundColor( selColor );