1 /*****************************************************************************
2  * generic_window.cpp
3  *****************************************************************************
4  * Copyright (C) 2003 the VideoLAN team
5  * $Id: 445a3a2824696f19a90709c0b8f841b63549923c $
6  *
7  * Authors: Cyril Deguet     <asmax@via.ecp.fr>
8  *          Olivier Teulière <ipkiss@via.ecp.fr>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 2 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to the Free Software
22  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
23  *****************************************************************************/
24 
25 #include "generic_window.hpp"
26 #include "os_window.hpp"
27 #include "os_factory.hpp"
28 #include "var_manager.hpp"
29 #include "../events/evt_refresh.hpp"
30 
31 
GenericWindow(intf_thread_t * pIntf,int left,int top,bool dragDrop,bool playOnDrop,GenericWindow * pParent,WindowType_t type)32 GenericWindow::GenericWindow( intf_thread_t *pIntf, int left, int top,
33                               bool dragDrop, bool playOnDrop,
34                               GenericWindow *pParent, WindowType_t type ):
35     SkinObject( pIntf ), m_left( left ), m_top( top ), m_width( 0 ),
36     m_height( 0 ), m_pVarVisible( NULL )
37 {
38     // Get the OSFactory
39     OSFactory *pOsFactory = OSFactory::instance( getIntf() );
40 
41     // Get the parent OSWindow, if any
42     OSWindow *pOSParent = NULL;
43     if( pParent )
44     {
45         pOSParent = pParent->m_pOsWindow;
46     }
47 
48     // Create an OSWindow to handle OS specific processing
49     m_pOsWindow = pOsFactory->createOSWindow( *this, dragDrop, playOnDrop,
50                                               pOSParent, type );
51 
52     // Create the visibility variable and register it in the manager
53     m_pVarVisible = new VarBoolImpl( pIntf );
54     VarManager::instance( pIntf )->registerVar( VariablePtr( m_pVarVisible ) );
55 
56     // Observe the visibility variable
57     m_pVarVisible->addObserver( this );
58 }
59 
60 
~GenericWindow()61 GenericWindow::~GenericWindow()
62 {
63     m_pVarVisible->delObserver( this );
64 
65     delete m_pOsWindow;
66 }
67 
68 
processEvent(EvtRefresh & rEvtRefresh)69 void GenericWindow::processEvent( EvtRefresh &rEvtRefresh )
70 {
71     // Refresh the given area
72     refresh( rEvtRefresh.getXStart(), rEvtRefresh.getYStart(),
73              rEvtRefresh.getWidth(), rEvtRefresh.getHeight() );
74 }
75 
76 
show() const77 void GenericWindow::show() const
78 {
79     m_pVarVisible->set( true );
80 }
81 
82 
hide() const83 void GenericWindow::hide() const
84 {
85     m_pVarVisible->set( false );
86 }
87 
88 
move(int left,int top)89 void GenericWindow::move( int left, int top )
90 {
91     // Update the window coordinates
92     m_left = left;
93     m_top = top;
94 
95     if( m_pOsWindow && isVisible() )
96         m_pOsWindow->moveResize( left, top, m_width, m_height );
97 }
98 
99 
resize(int width,int height)100 void GenericWindow::resize( int width, int height )
101 {
102     // don't try when value is 0 (may crash)
103     if( !width || !height )
104         return;
105 
106     // Update the window size
107     m_width = width;
108     m_height = height;
109 
110     if( m_pOsWindow && isVisible() )
111         m_pOsWindow->moveResize( m_left, m_top, width, height );
112 }
113 
114 
raise() const115 void GenericWindow::raise() const
116 {
117     if( m_pOsWindow )
118         m_pOsWindow->raise();
119 }
120 
121 
setOpacity(uint8_t value)122 void GenericWindow::setOpacity( uint8_t value )
123 {
124     m_pOsWindow->setOpacity( value );
125 }
126 
127 
toggleOnTop(bool onTop) const128 void GenericWindow::toggleOnTop( bool onTop ) const
129 {
130     if( m_pOsWindow )
131         m_pOsWindow->toggleOnTop( onTop );
132 }
133 
134 
onUpdate(Subject<VarBool> & rVariable,void * arg)135 void GenericWindow::onUpdate( Subject<VarBool> &rVariable, void* arg )
136 {
137     (void)rVariable; (void)arg;
138     if (&rVariable == m_pVarVisible )
139     {
140         if( m_pVarVisible->get() )
141         {
142             innerShow();
143         }
144         else
145         {
146             innerHide();
147         }
148     }
149 }
150 
151 
innerShow()152 void GenericWindow::innerShow()
153 {
154     if( m_pOsWindow )
155     {
156         m_pOsWindow->show();
157         m_pOsWindow->moveResize( m_left, m_top, m_width, m_height );
158     }
159 }
160 
161 
innerHide()162 void GenericWindow::innerHide()
163 {
164     if( m_pOsWindow )
165     {
166         m_pOsWindow->hide();
167     }
168 }
169 
getOSHandle() const170 vlc_wnd_type GenericWindow::getOSHandle() const
171 {
172     return m_pOsWindow->getOSHandle();
173 }
174 
175 
setParent(GenericWindow * pParent,int x,int y,int w,int h)176 void GenericWindow::setParent( GenericWindow* pParent, int x, int y, int w, int h )
177 {
178     // Update the window size and position
179     m_left = x;
180     m_top = y;
181     m_width  = ( w > 0 ) ? w : m_width;
182     m_height = ( h > 0 ) ? h : m_height;
183 
184     vlc_wnd_type handle = pParent ? pParent->getOSHandle() : 0;
185     m_pOsWindow->reparent( handle, m_left, m_top, m_width, m_height );
186 }
187 
188 
invalidateRect(int left,int top,int width,int height)189 void GenericWindow::invalidateRect( int left, int top, int width, int height )
190 {
191     if( m_pOsWindow )
192     {
193         // tell the OS we invalidate a window client area
194         bool b_supported =
195             m_pOsWindow->invalidateRect( left, top, width, height );
196 
197         // if not supported, directly refresh the area
198         if( !b_supported )
199             refresh( left, top, width, height );
200     }
201 }
202 
203 
getMonitorInfo(int * x,int * y,int * width,int * height) const204 void GenericWindow::getMonitorInfo( int* x, int* y, int* width, int* height ) const
205 {
206     OSFactory *pOsFactory = OSFactory::instance( getIntf() );
207     pOsFactory->getMonitorInfo( *this, x, y, width, height );
208 }
209