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/ or email : webmaster.salome@opencascade.com
21 #define QT_CLEAN_NAMESPACE /* avoid definition of INT32 and INT8 */
24 #include "OCCViewer_ViewPort.h"
26 #include "SUIT_Session.h"
33 #include <qpopupmenu.h>
34 #include <qcolordialog.h>
41 #include <X11/Xutil.h>
42 #include <X11/Xatom.h>
43 #include <X11/Xmu/StdCmap.h>
44 #undef QT_CLEAN_NAMESPACE
45 #include <Xw_Window.hxx>
46 #include <Graphic3d_GraphicDevice.hxx>
54 XStandardColormap scmap;
60 CMapEntry::CMapEntry()
70 CMapEntry::~CMapEntry()
73 XFreeColormap( QPaintDevice::x11AppDisplay(), cmap );
76 static QIntDict<CMapEntry> *cmap_dict = 0;
77 static bool mesa_gl = false;
79 static void cleanup_cmaps()
83 cmap_dict->setAutoDelete( true );
88 static Colormap choose_cmap( Display *dpy, XVisualInfo *vi )
92 cmap_dict = new QIntDict<CMapEntry>;
93 const char *v = glXQueryServerString( dpy, vi->screen, GLX_VERSION );
94 mesa_gl = strstr( v,"Mesa" ) != 0;
95 qAddPostRoutine( cleanup_cmaps );
98 CMapEntry *x = cmap_dict->find( (long)vi->visualid );
99 if ( x ) // found colormap for visual
104 XStandardColormap *c;
108 cout << "Choosing cmap for vID = " << vi->visualid << endl;
111 if ( vi->visualid == XVisualIDFromVisual( (Visual*)QPaintDevice::x11AppVisual() ) )
114 cout << "Using x11AppColormap" << endl;
116 return QPaintDevice::x11AppColormap();
121 Atom hp_cmaps = XInternAtom( dpy, "_HP_RGB_SMOOTH_MAP_LIST", true );
122 if ( hp_cmaps && vi->visual->c_class == TrueColor && vi->depth == 8 )
124 if ( XGetRGBColormaps( dpy, RootWindow( dpy, vi->screen ), &c, &n, hp_cmaps ) )
127 while ( i < n && x->cmap == 0 )
129 if ( c[i].visualid == vi->visual->visualid )
131 x->cmap = c[i].colormap;
140 #if !defined( _OS_SOLARIS_ )
143 if ( XmuLookupStandardColormap( dpy, vi->screen, vi->visualid, vi->depth, XA_RGB_DEFAULT_MAP, false, true ) )
145 if ( XGetRGBColormaps( dpy, RootWindow( dpy, vi->screen ), &c, &n, XA_RGB_DEFAULT_MAP ) )
148 while ( i < n && x->cmap == 0 )
150 if ( c[i].visualid == vi->visualid )
152 x->cmap = c[i].colormap;
164 // no shared cmap found
165 x->cmap = XCreateColormap( dpy, RootWindow( dpy, vi->screen ), vi->visual, AllocNone );
169 cmap_dict->insert( (long)vi->visualid, x ); // associate cmap with visualid
178 OCCViewer_ViewPort::OCCViewer_ViewPort( QWidget* parent )
179 : QWidget( parent, 0, WRepaintNoErase | WResizeNoErase )
187 OCCViewer_ViewPort::~OCCViewer_ViewPort()
193 Initializes viewport. [ private ]
195 void OCCViewer_ViewPort::initialize()
197 myPopupActions.setAutoDelete( true );
198 myPaintersRedrawing = false;
199 myEnableSketching = false;
200 myEnableTransform = true;
202 setMouseTracking( true );
203 setBackgroundMode( NoBackground );
204 // set focus policy to threat QContextMenuEvent from keyboard
205 setFocusPolicy( StrongFocus );
209 Cleans up the viewport. [ private ]
211 void OCCViewer_ViewPort::cleanup()
216 Selects visual ID for OpenGL window ( X11 specific ). [ protected ]
218 void OCCViewer_ViewPort::selectVisualId()
221 XVisualInfo* pVisualInfo;
224 /* Initialization with the default VisualID */
225 Visual *v = DefaultVisual( x11Display(), DefaultScreen( x11Display() ) );
226 int visualID = XVisualIDFromVisual( v );
228 /* Here we use the settings from Optimizer_ViewInfo::TxglCreateWindow() */
229 int visualAttr[] = { GLX_RGBA, GLX_DEPTH_SIZE, 1, GLX_RED_SIZE, 1, GLX_GREEN_SIZE, 1,
230 GLX_BLUE_SIZE, 1, GLX_DOUBLEBUFFER, None };
232 pVisualInfo = ::glXChooseVisual( x11Display(), DefaultScreen( x11Display() ), visualAttr );
237 XSetWindowAttributes a;
239 a.colormap = choose_cmap( x11Display(), pVisualInfo ); /* find best colormap */
240 a.background_pixel = backgroundColor().pixel();
241 a.border_pixel = black.pixel();
242 Window p = RootWindow( x11Display(), DefaultScreen( x11Display() ) );
243 if ( parentWidget() )
244 p = parentWidget()->winId();
247 /* if ( type == Type2D ) // creating simple X window for 2d
249 unsigned long xbackground =
250 BlackPixel( x11Display(), DefaultScreen( x11Display() ) );
251 unsigned long xforeground =
252 WhitePixel( x11Display(), DefaultScreen( x11Display() ) );
254 w = XCreateSimpleWindow ( x11Display(), p, x(), y(), width(),
255 height(), 0, xforeground, xbackground );
257 else if ( type == Type3D )
259 w = XCreateWindow( x11Display(), p, x(), y(), width(), height(),
260 0, pVisualInfo->depth, InputOutput, pVisualInfo->visual,
261 CWBackPixel | CWBorderPixel | CWColormap, &a );
265 w = XCreateWindow( x11Display(), p, x(), y(), width(), height(),
266 0, pVisualInfo->depth, InputOutput, pVisualInfo->visual,
267 CWBackPixel | CWBorderPixel | CWColormap, &a );
272 if ( XGetWMColormapWindows( x11Display(), topLevelWidget()->winId(), &cmwret, &count ) )
274 cmw = new Window[count+1];
275 memcpy( (char*)cmw, (char*)cmwret, sizeof(Window) * count );
276 XFree( (char*)cmwret );
279 for ( i = 0; i < count; i++ )
281 if ( cmw[i] == winId() ) /* replace old window */
288 if ( i >= count ) /* append new window */
294 cmw = new Window[count];
298 /* Creating new window (with good VisualID) for this widget */
300 XSetWMColormapWindows( x11Display(), topLevelWidget()->winId(), cmw, count );
308 XFree( (char *)pVisualInfo );
310 XFlush( x11Display() );
316 Sets the background 'color'. [ virtual ]
318 void OCCViewer_ViewPort::setBackgroundColor( const QColor& color )
320 QPalette pal = palette();
321 pal.setColor( QColorGroup::Background, color );
324 emit vpChangeBGColor( color );
328 Returns the background color. [ virtual ]
330 QColor OCCViewer_ViewPort::backgroundColor() const
332 return palette().active().background();
336 Returns 'true' if sketching is enabled in this viewport. [ public ]
338 bool OCCViewer_ViewPort::isSketchingEnabled() const
340 return myEnableSketching;
344 Enables / disables sketching [ public ]
346 void OCCViewer_ViewPort::setSketchingEnabled( bool enable )
348 myEnableSketching = enable;
352 Returns 'true' if transformations ( rotation, zoom etc. )
353 are enabled in this viewport. [ public ]
355 bool OCCViewer_ViewPort::isTransformEnabled() const
357 return myEnableTransform;
361 Enables / disables transformations. [ public ]
363 void OCCViewer_ViewPort::setTransformEnabled( bool enable )
365 myEnableTransform = enable;
369 Emits 'mouseEvent' signal. [ virtual protected ]
371 void OCCViewer_ViewPort::mousePressEvent( QMouseEvent *e )
373 emit vpMouseEvent( e );
377 Emits 'mouseEvent' signal. [ virtual protected ]
379 void OCCViewer_ViewPort::mouseMoveEvent( QMouseEvent* e )
381 emit vpMouseEvent( e );
385 Emits 'mouseEvent' signal. [ virtual protected ]
387 void OCCViewer_ViewPort::mouseReleaseEvent( QMouseEvent *e )
389 emit vpMouseEvent( e );
393 Emits 'mouseEvent' signal. [ virtual protected ]
395 void OCCViewer_ViewPort::mouseDoubleClickEvent( QMouseEvent *e )
397 emit vpMouseEvent( e );
401 Emits 'keyEvent' signal. [ virtual protected ]
403 void OCCViewer_ViewPort::keyPressEvent( QKeyEvent *e )
405 emit vpKeyEvent( e );
409 Emits 'keyEvent' signal. [ virtual protected ]
411 void OCCViewer_ViewPort::keyReleaseEvent( QKeyEvent *e )
413 emit vpKeyEvent( e );
417 Repaints the viewport. [ virtual protected ]
419 void OCCViewer_ViewPort::paintEvent( QPaintEvent* )
421 if ( myPaintersRedrawing )
424 emit vpDrawExternal( &p );
425 myPaintersRedrawing = false;
430 Forces to redraw the viewport by an external painter. [ public ]
432 void OCCViewer_ViewPort::redrawPainters()
434 myPaintersRedrawing = true;
439 Updates this view. Does nothing by default. [ virtual public ]
441 void OCCViewer_ViewPort::onUpdate()
446 Creates the popup. [ virtual protected ]
448 /*void OCCViewer_ViewPort::onCreatePopup( QPopupMenu* popup )
452 QtxAction* a = new QtxAction( "", tr( "MEN_VP_CHANGEBGR" ), 0, this );
453 a->setStatusTip( tr( "PRP_VP_CHANGEBGR" ) );
454 connect( a, SIGNAL( activated() ), SLOT( onChangeBgColor()));
455 myPopupActions.append( a );
461 Destroys the popup. [ virtual protected ]
463 /*void OCCViewer_ViewPort::onDestroyPopup( QPopupMenu* popup )
467 for ( QtxAction* a = myPopupActions.first(); a; a = myPopupActions.next() )
468 a->removeFrom( popup );
469 myPopupActions.clear();
474 Sets the background color with color selection dialog. [ virtual protected slot ]
476 void OCCViewer_ViewPort::onChangeBgColor()
478 QColor selColor = QColorDialog::getColor ( backgroundColor(), this );
479 if ( selColor.isValid() )
480 setBackgroundColor( selColor );