1 /* -*-c++-*- Producer - Copyright (C) 2001-2004  Don Burns
2  *
3  * This library is open source and may be redistributed and/or modified under
4  * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5  * (at your option) any later version.  The full license is in LICENSE file
6  * included with this distribution, and on the openscenegraph.org website.
7  *
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
11  * OpenSceneGraph Public License for more details.
12  */
13 
14 #include <stdlib.h>
15 #include <string.h>
16 
17 #include "RenderSurface.h"
18 
19 using namespace std;
20 using namespace osgProducer;
21 
22 const std::string RenderSurface::defaultWindowName = std::string(" *** Producer::RenderSurface *** ");
23 
24 const unsigned int RenderSurface::UnknownDimension = 0xFFFFFFFF;
25 const unsigned int RenderSurface::UnknownAmount = 0xFFFFFFFF;
26 unsigned int RenderSurface::_numScreens = RenderSurface::UnknownAmount;
27 
28 bool RenderSurface::_shareAllGLContexts = false;
29 //GLContext RenderSurface::_globallySharedGLContext  = 0L;
30 
shareAllGLContexts(bool flag)31 void RenderSurface::shareAllGLContexts(bool flag)
32 {
33     _shareAllGLContexts = flag;
34 }
35 
allGLContextsAreShared()36 bool RenderSurface::allGLContextsAreShared()
37 {
38     return _shareAllGLContexts;
39 }
40 
41 
getDefaultWindowName()42 const std::string &RenderSurface::getDefaultWindowName()
43 {
44     return defaultWindowName;
45 }
46 
RenderSurface(void)47 RenderSurface::RenderSurface( void )
48 {
49     _drawableType    = DrawableType_Window;
50     _hostname        = "";
51     _displayNum     = 0;
52     _screen          = 0;
53     _mayFullScreen   = true;
54     _isFullScreen    = true;
55 
56     // This used to be #ifdefed for the X11 implementation
57     // but the code is pure C++ and should compile anywhere
58     // The _dislayNum variable is used by CGL as well.
59     char *envptr = getenv( "DISPLAY" );
60     if( envptr != NULL && *envptr != 0 )
61     {
62         size_t p0 = 0;
63         size_t p1 = string(envptr).find(":", p0);
64         _hostname = string(envptr).substr(p0,p1);
65         p0 = p1+1;
66         p1 = string(envptr).find(".", p0);
67 
68         if( p1 > 0 )
69         {
70             _displayNum = atoi((string(envptr).substr(p0,p1)).c_str());
71             p0 = p1+1;
72             p1 = string(envptr).length() - p0;
73             if( p1 > 0 )
74                 _screen = atoi((string(envptr).substr(p0,p1)).c_str());
75         }
76         else if( p1 < string(envptr).length() )
77         {
78             p1 = string(envptr).length();
79             _displayNum = atoi((string(envptr).substr(p0,p1)).c_str());
80             _screen = 0;
81         }
82     }
83 
84     _windowLeft     = 0;
85     _windowRight    = 1;
86     _windowBottom   = 0;
87     _windowTop      = 1;
88     _windowX        = 0;
89     _windowY        = 0;
90     _windowWidth    = UnknownDimension;
91     _windowHeight   = UnknownDimension;
92     _screenWidth    = UnknownDimension;
93     _screenHeight   = UnknownDimension;
94     _customFullScreenOriginX = 0;
95     _customFullScreenOriginY = 0;
96     _customFullScreenWidth   = UnknownDimension;
97     _customFullScreenHeight  = UnknownDimension;
98     _useCustomFullScreen     = false;
99 
100     _readDrawableRenderSurface = 0L;
101     _windowName      = defaultWindowName;
102     _realized        = false;
103     _useConfigEventThread = true;
104     _overrideRedirectFlag = false;
105 
106     char *override_envptr = getenv( "PRODUCER_OVERRIDE_REDIRECT" );
107     if( override_envptr != NULL && *override_envptr != 0 )
108     {
109         if (strcmp(override_envptr,"true")==0 || strcmp(override_envptr,"True")==0 || strcmp(override_envptr,"TRUE")==0)
110         {
111             _overrideRedirectFlag = true;
112         }
113         else
114         {
115             _overrideRedirectFlag = false;
116         }
117     }
118 
119     _decorations     = true;
120     _useCursorFlag   = true;
121 
122 
123 
124 
125     _useDefaultEsc = true;
126     _checkOwnEvents = true;
127     _inputRectangle.set( -1.0,  1.0, -1.0, 1.0 );
128     _bindInputRectangleToWindowSize = false;
129 
130 
131     _rtt_mode   = RenderToTextureMode_None;
132     //_rtt_mode   = RenderToRGBTexture;
133     _rtt_target = Texture2D;
134     _rtt_options = RenderToTextureOptions_Default;
135     _rtt_mipmap = 0;
136     _rtt_face = PositiveX;
137     _rtt_dirty_mipmap = true;
138     _rtt_dirty_face = true;
139 
140 
141 #ifdef _WIN32_IMPLEMENTATION
142     _ownWindow = true;
143     _ownVisualChooser = true;
144     _ownVisualInfo = true;
145     _hinstance = NULL;
146     _glcontext = NULL;
147     _mx = 0;
148     _my = 0;
149     _mbutton = 0;
150 #endif
151 }
152 
~RenderSurface(void)153 RenderSurface::~RenderSurface( void )
154 {
155 }
156 
157 
setDrawableType(RenderSurface::DrawableType drawableType)158 void RenderSurface::setDrawableType( RenderSurface::DrawableType drawableType )
159 {
160     if( _realized )
161     {
162         std::cerr << "Warning: RenderSurface::setDrawableType() "
163                      "has no effect after RenderSurface has been realized\n";
164         return;
165     }
166     _drawableType = drawableType;
167 }
168 
getDrawableType()169 RenderSurface::DrawableType RenderSurface::getDrawableType()
170 {
171     return _drawableType;
172 }
173 
setReadDrawable(osgProducer::RenderSurface * rs)174 void RenderSurface::setReadDrawable( osgProducer::RenderSurface *rs )
175 {
176     _readDrawableRenderSurface = rs;
177 #if 0
178     if( _realized )
179         makeCurrent();
180 #endif
181 }
182 
183 #if 0
184 void RenderSurface::setParentWindow( Window parent )
185 {
186      _parent = parent;
187 }
188 
189 Producer::Window RenderSurface::getParentWindow( void ) const
190 {
191     return _parent;
192 }
193 #endif
194 
setWindowName(const std::string & name)195 void RenderSurface::setWindowName( const std::string &name )
196 {
197   //    _setWindowName( name );
198     _windowName = name;
199 }
200 
getWindowName(void) const201 const std::string &RenderSurface::getWindowName( void ) const
202 {
203     return _windowName;
204 }
205 
setHostName(const std::string & name)206 void RenderSurface::setHostName( const std::string &name )
207 {
208     _hostname = name;
209 }
210 
getHostName(void) const211 const std::string &RenderSurface::getHostName( void ) const
212 {
213     return _hostname;
214 }
215 
216 #if 0
217 void RenderSurface::setDisplay( Display *dpy )
218 {
219     _dpy = dpy;
220 }
221 
222 Producer::Display *RenderSurface::getDisplay()
223 {
224 #ifdef WIN32
225     return &_hdc;
226 #else
227     return _dpy;
228 #endif
229 }
230 
231 const Producer::Display *RenderSurface::getDisplay() const
232 {
233 #ifdef WIN32
234     return &_hdc;
235 #else
236     return _dpy;
237 #endif
238 }
239 #endif
240 
setDisplayNum(int num)241 void RenderSurface::setDisplayNum( int num )
242 {
243     _displayNum = num;
244 }
245 
getDisplayNum(void) const246 int  RenderSurface::getDisplayNum( void ) const
247 {
248     return _displayNum;
249 }
250 
setScreenNum(int num)251 void RenderSurface::setScreenNum( int num )
252 {
253     _screen = num;
254 }
255 
getScreenNum(void) const256 int  RenderSurface::getScreenNum( void ) const
257 {
258     return _screen;
259 }
260 
setWindowRectangle(int x,int y,unsigned int width,unsigned int height,bool)261 void RenderSurface::setWindowRectangle( int x, int y, unsigned int width, unsigned int height, bool /*resize*/)
262 {
263     if( _useCustomFullScreen )
264     {
265         _windowX = x + _customFullScreenOriginX;
266         _windowY = y + _customFullScreenOriginY;
267     }
268     else
269     {
270         _windowX = x;
271         _windowY = y;
272     }
273     _windowWidth = width;
274     _windowHeight = height;
275 #ifdef _OSX_AGL_IMPLEMENTATION
276     fullScreen(false);                  // STH: this may break other implementations, but it is necessary for OSX
277 #else
278     _isFullScreen    = false;
279 #endif
280 #if 0
281     if( _realized && resize )
282         _resizeWindow();
283     else
284 #endif
285         if( _bindInputRectangleToWindowSize == true )
286             _inputRectangle.set( 0.0, _windowWidth, 0.0, _windowHeight );
287 }
288 
getWindowRectangle(int & x,int & y,unsigned int & width,unsigned int & height) const289 void RenderSurface::getWindowRectangle( int &x, int &y, unsigned int &width, unsigned int &height ) const
290 {
291     if( _isFullScreen )
292     {
293         x = 0;
294         y = 0;
295         if( _useCustomFullScreen == true )
296         {
297             width  = _customFullScreenWidth;
298             height = _customFullScreenHeight;
299         }
300         else
301         {
302             width = _screenWidth;
303             height = _screenHeight;
304         }
305     }
306     else
307     {
308         x      = _windowX;
309         y      = _windowY;
310         width  = _windowWidth;
311         height = _windowHeight;
312     }
313 }
314 
useDefaultFullScreenRectangle()315 void RenderSurface::useDefaultFullScreenRectangle()
316 {
317     _useCustomFullScreen = false;
318 }
319 
setCustomFullScreenRectangle(int x,int y,unsigned int width,unsigned int height)320 void RenderSurface::setCustomFullScreenRectangle( int x, int y, unsigned int width, unsigned int height )
321 {
322     _customFullScreenOriginX = x;
323     _customFullScreenOriginY = y;
324     _customFullScreenWidth   = width;
325     _customFullScreenHeight  = height;
326     _useCustomFullScreen     = true;
327 
328     _windowX += _customFullScreenOriginX;
329     _windowY += _customFullScreenOriginY;
330 }
331 
getWindowOriginX() const332 int RenderSurface::getWindowOriginX() const
333 {
334     if( _isFullScreen )
335     {
336         if( _useCustomFullScreen == true )
337             return _customFullScreenOriginX;
338         else
339             return 0;
340     }
341     return _windowX;
342 }
343 
getWindowOriginY() const344 int RenderSurface::getWindowOriginY() const
345 {
346     if( _isFullScreen )
347     {
348         if( _useCustomFullScreen == true )
349             return _customFullScreenOriginY;
350         else
351             return 0;
352     }
353     return _windowY;
354 }
355 
getWindowWidth() const356 unsigned int RenderSurface::getWindowWidth() const
357 {
358     if( _isFullScreen )
359     {
360         if( _useCustomFullScreen == true )
361             return _customFullScreenWidth;
362         else
363             return _screenWidth;
364     }
365     return _windowWidth;
366 }
367 
getWindowHeight() const368 unsigned int RenderSurface::getWindowHeight() const
369 {
370     if( _isFullScreen )
371     {
372         if( _useCustomFullScreen == true )
373             return _customFullScreenHeight;
374         else
375             return _screenHeight;
376     }
377     return _windowHeight;
378 }
379 
setInputRectangle(const InputRectangle & inputRectangle)380 void RenderSurface::setInputRectangle( const InputRectangle &inputRectangle )
381 {
382     _inputRectangle = inputRectangle;
383 }
384 
getInputRectangle() const385 const RenderSurface::InputRectangle &RenderSurface::getInputRectangle() const
386 {
387     return _inputRectangle;
388 }
389 
bindInputRectangleToWindowSize(bool flag)390 void RenderSurface::bindInputRectangleToWindowSize( bool flag)
391 {
392     _bindInputRectangleToWindowSize = flag;
393     if( _bindInputRectangleToWindowSize == true )
394         _inputRectangle.set( 0.0, float(_windowWidth), 0.0, float(_windowHeight) );
395     else
396         _inputRectangle.set( -1.0,  1.0, -1.0, 1.0 );
397 }
398 
399 
useBorder(bool flag)400 void RenderSurface::useBorder( bool flag )
401 {
402     _decorations = flag;
403 #if 0
404     if( _realized )
405           _setBorder(_decorations);
406 #endif
407 }
408 
usesBorder()409 bool RenderSurface::usesBorder()
410 {
411     return _decorations;
412 }
413 
414 #if 0
415 void RenderSurface::useCursor( bool flag )
416 {
417      _useCursor(flag);
418 }
419 
420 void RenderSurface::setCursor( Cursor cursor )
421 {
422     _setCursor(cursor);
423 }
424 
425 void RenderSurface::setCursorToDefault()
426 {
427     _setCursorToDefault();
428 }
429 void RenderSurface::setWindow( const Window win )
430 {
431     if( _realized )
432     {
433         std::cerr << "RenderSurface::setWindow() - cannot set window after RenderSurface has been realized\n";
434         return;
435     }
436     _win = win;
437 #ifdef WIN32
438     _ownWindow = false;
439 #endif
440 }
441 
442 Producer::Window RenderSurface::getWindow( void ) const
443 {
444     return _win;
445 }
446 
447 GLContext RenderSurface::getGLContext( void) const
448 {
449     return _glcontext;
450 }
451 
452 void RenderSurface::setGLContext( GLContext glContext )
453 {
454     if( _realized )
455     {
456         std::cerr << "RenderSurface::setGLContext() - Warning: Must be set before realize()." << std::endl;
457         return;
458     }
459 
460     _glcontext = glContext;
461 }
462 
463 
464 bool RenderSurface::isRealized() const
465 {
466     return _realized;
467 }
468 
469 void RenderSurface::setVisualInfo( VisualInfo *vi )
470 {
471     if( _realized )
472     {
473         std::cerr << "RenderSurface::setVisualInfo():Warning - has no effect after RenderSurface has been realized\n";
474         return;
475     }
476     _visualInfo = vi;
477 #ifdef _WIN32_IMPLEMENTATION
478     _ownVisualInfo = false;
479 #endif
480 }
481 
482 VisualInfo *RenderSurface::getVisualInfo( void  )
483 {
484     return _visualInfo;
485 }
486 
487 const VisualInfo *RenderSurface::getVisualInfo( void  ) const
488 {
489     return _visualInfo;
490 }
491 
492 #endif
493 
setVisualChooser(VisualChooser * vc)494 void RenderSurface::setVisualChooser( VisualChooser *vc )
495 {
496     if( _realized )
497     {
498         std::cerr << "RenderSurface::setVisualChooser():Warning - has no effect after RenderSurface has been realized\n";
499         return;
500     }
501     _visualChooser = vc;
502 
503 #ifdef _WIN32_IMPLEMENTATION
504     _ownVisualChooser = false;
505 #endif
506 }
507 
getVisualChooser(void)508 VisualChooser *RenderSurface::getVisualChooser( void )
509 {
510     return _visualChooser.get();
511 }
512 
getVisualChooser(void) const513 const VisualChooser *RenderSurface::getVisualChooser( void ) const
514 {
515     return _visualChooser.get();
516 }
517 
518 
519 #if 0
520 void RenderSurface::getScreenSize( unsigned int &width, unsigned int &height )  const
521 {
522     if( _realized )
523     {
524         if( _useCustomFullScreen == true )
525         {
526             width  = _customFullScreenWidth;
527             height = _customFullScreenHeight;
528         }
529         else
530         {
531             width  = _screenWidth;
532             height = _screenHeight;
533         }
534     }
535     else
536     {
537         _computeScreenSize(width, height);
538     }
539 }
540 #endif
541 
542 #if 0
543 void  RenderSurface::useConfigEventThread( bool flag )
544 {
545     if( _realized )
546     {
547         // This message is annoying.  Cameras that share a render surface will call this after the
548         // render surface has been realized, which is valid.
549         //std::cerr << "RenderSurface::useConfigEventThread():Warning - has no effect after RenderSurface has been realized\n";
550         return;
551     }
552     _useConfigEventThread = flag;
553 }
554 
555 unsigned int RenderSurface::getRefreshRate() const
556 {
557     if( !_realized ) return 0;
558     return _refreshRate;
559 }
560 
561 void RenderSurface::addRealizeCallback( Callback *realizeCB )
562 {
563     if( _realized )
564     {
565         std::cerr << "RenderSurface::addRealizeCallback() : Warning.  RenderSurface is already realized.  ignored.\n";
566             return;
567     }
568     _realizeCallbacks.push_back( realizeCB );
569 }
570 
571 bool RenderSurface::waitForRealize()
572 {
573     if( _realized ) return true;
574     while( _realized == false )
575         _realizeBlock->block();
576     return true;
577 }
578 
579 void RenderSurface::positionPointer( int x, int y )
580 {
581     _positionPointer(x,y);
582 }
583 
584 void RenderSurface::initThreads()
585 {
586     _initThreads();
587 }
588 #endif
589 
getRenderToTextureMode() const590 RenderSurface::RenderToTextureMode RenderSurface::getRenderToTextureMode() const
591 {
592     return _rtt_mode;
593 }
594 
595 
setRenderToTextureMode(RenderToTextureMode mode)596 void RenderSurface::setRenderToTextureMode(RenderToTextureMode mode)
597 {
598     _rtt_mode = mode;
599 }
600 
601 
getRenderToTextureTarget() const602 RenderSurface::RenderToTextureTarget RenderSurface::getRenderToTextureTarget() const
603 {
604     return _rtt_target;
605 }
606 
607 
setRenderToTextureTarget(RenderToTextureTarget target)608 void RenderSurface::setRenderToTextureTarget(RenderToTextureTarget target)
609 {
610     _rtt_target = target;
611 }
612 
613 
getRenderToTextureOptions() const614 RenderSurface::RenderToTextureOptions RenderSurface::getRenderToTextureOptions() const
615 {
616     return _rtt_options;
617 }
618 
619 
setRenderToTextureOptions(RenderToTextureOptions options)620 void RenderSurface::setRenderToTextureOptions(RenderToTextureOptions options)
621 {
622     _rtt_options = options;
623 }
624 
getRenderToTextureMipMapLevel() const625 int RenderSurface::getRenderToTextureMipMapLevel() const
626 {
627     return _rtt_mipmap;
628 }
629 
630 
setRenderToTextureMipMapLevel(int level)631 void RenderSurface::setRenderToTextureMipMapLevel(int level)
632 {
633     _rtt_mipmap = level;
634     _rtt_dirty_mipmap = true;
635 }
636 
getRenderToTextureFace() const637 RenderSurface::CubeMapFace RenderSurface::getRenderToTextureFace() const
638 {
639     return _rtt_face;
640 }
641 
642 
setRenderToTextureFace(CubeMapFace face)643 void RenderSurface::setRenderToTextureFace(CubeMapFace face)
644 {
645     _rtt_face = face;
646     _rtt_dirty_face = true;
647 }
648 
getPBufferUserAttributes() const649 const std::vector<int> &RenderSurface::getPBufferUserAttributes() const
650 {
651     return _user_pbattr;
652 }
653 
getPBufferUserAttributes()654 std::vector<int> &RenderSurface::getPBufferUserAttributes()
655 {
656     return _user_pbattr;
657 }
658 
659 
660 
useOverrideRedirect(bool flag)661 void RenderSurface::useOverrideRedirect(bool flag)
662 {
663     _overrideRedirectFlag = flag;
664 }
665 
usesOverrideRedirect()666 bool RenderSurface::usesOverrideRedirect()
667 {
668     return _overrideRedirectFlag;
669 }
670 
671