1 /*****************************************************************************
3 *****************************************************************************
4 * Copyright (C) 2003 the VideoLAN team
7 * Authors: Cyril Deguet <asmax@via.ecp.fr>
8 * Olivier Teulière <ipkiss@via.ecp.fr>
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.
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.
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 *****************************************************************************/
31 #include <X11/extensions/Xinerama.h>
33 #include "x11_factory.hpp"
34 #include "x11_display.hpp"
35 #include "x11_graphics.hpp"
36 #include "x11_loop.hpp"
37 #include "x11_popup.hpp"
38 #include "x11_timer.hpp"
39 #include "x11_window.hpp"
40 #include "x11_tooltip.hpp"
42 #include "../src/generic_window.hpp"
44 #include <vlc_common.h>
47 X11Factory::X11Factory( intf_thread_t
*pIntf
): OSFactory( pIntf
),
48 m_pDisplay( NULL
), m_pTimerLoop( NULL
), m_dirSep( "/" )
54 X11Factory::~X11Factory()
61 bool X11Factory::init()
63 // make sure xlib is safe-thread
64 if( !vlc_xlib_init( VLC_OBJECT( getIntf() ) ) )
66 msg_Err( getIntf(), "initializing xlib for multi-threading failed" );
70 // Create the X11 display
71 m_pDisplay
= new X11Display( getIntf() );
74 Display
*pDisplay
= m_pDisplay
->getDisplay();
75 if( pDisplay
== NULL
)
77 // Initialization failed
81 // Create the timer loop
82 m_pTimerLoop
= new X11TimerLoop( getIntf(),
83 ConnectionNumber( pDisplay
) );
85 // Initialize the resource path
86 char *datadir
= config_GetUserDir( VLC_DATA_DIR
);
87 m_resourcePath
.push_back( (string
)datadir
+ "/skins2" );
89 m_resourcePath
.push_back( (string
)"share/skins2" );
90 datadir
= config_GetDataDir( getIntf() );
91 m_resourcePath
.push_back( (string
)datadir
+ "/skins2" );
94 // Determine the monitor geometry
95 getDefaultGeometry( &m_screenWidth
, &m_screenHeight
);
101 OSGraphics
*X11Factory::createOSGraphics( int width
, int height
)
103 return new X11Graphics( getIntf(), *m_pDisplay
, width
, height
);
107 OSLoop
*X11Factory::getOSLoop()
109 return X11Loop::instance( getIntf(), *m_pDisplay
);
113 void X11Factory::destroyOSLoop()
115 X11Loop::destroy( getIntf() );
118 void X11Factory::minimize()
120 XIconifyWindow( m_pDisplay
->getDisplay(), m_pDisplay
->getMainWindow(),
121 DefaultScreen( m_pDisplay
->getDisplay() ) );
124 void X11Factory::restore()
129 void X11Factory::addInTray()
134 void X11Factory::removeFromTray()
139 void X11Factory::addInTaskBar()
144 void X11Factory::removeFromTaskBar()
149 OSTimer
*X11Factory::createOSTimer( CmdGeneric
&rCmd
)
151 return new X11Timer( getIntf(), rCmd
);
155 OSWindow
*X11Factory::createOSWindow( GenericWindow
&rWindow
, bool dragDrop
,
156 bool playOnDrop
, OSWindow
*pParent
,
157 GenericWindow::WindowType_t type
)
159 return new X11Window( getIntf(), rWindow
, *m_pDisplay
, dragDrop
,
160 playOnDrop
, (X11Window
*)pParent
, type
);
164 OSTooltip
*X11Factory::createOSTooltip()
166 return new X11Tooltip( getIntf(), *m_pDisplay
);
170 OSPopup
*X11Factory::createOSPopup()
172 return new X11Popup( getIntf(), *m_pDisplay
);
176 int X11Factory::getScreenWidth() const
178 return m_screenWidth
;
182 int X11Factory::getScreenHeight() const
184 return m_screenHeight
;
188 void X11Factory::getMonitorInfo( const GenericWindow
&rWindow
,
190 int* p_width
, int* p_height
) const
192 // initialize to default geometry
195 *p_width
= getScreenWidth();
196 *p_height
= getScreenHeight();
198 // Use Xinerama to determine the monitor where the video
199 // mostly resides (biggest surface)
200 Display
*pDisplay
= m_pDisplay
->getDisplay();
201 Window wnd
= (Window
)rWindow
.getOSHandle();
202 Window root
= DefaultRootWindow( pDisplay
);
206 unsigned int w
, h
, border
, depth
;
207 XGetGeometry( pDisplay
, wnd
, &root
, &x
, &y
, &w
, &h
, &border
, &depth
);
208 XTranslateCoordinates( pDisplay
, wnd
, root
, 0, 0, &x
, &y
, &child_wnd
);
211 XineramaScreenInfo
* info
= XineramaQueryScreens( pDisplay
, &num
);
214 Region reg1
= XCreateRegion();
215 XRectangle rect1
= { x
, y
, w
, h
};
216 XUnionRectWithRegion( &rect1
, reg1
, reg1
);
218 unsigned int surface
= 0;
219 for( int i
= 0; i
< num
; i
++ )
221 Region reg2
= XCreateRegion();
222 XRectangle rect2
= { info
[i
].x_org
, info
[i
].y_org
,
223 info
[i
].width
, info
[i
].height
};
224 XUnionRectWithRegion( &rect2
, reg2
, reg2
);
226 Region reg
= XCreateRegion();
227 XIntersectRegion( reg1
, reg2
, reg
);
229 XClipBox( reg
, &rect
);
230 unsigned int surf
= rect
.width
* rect
.height
;
234 *p_x
= info
[i
].x_org
;
235 *p_y
= info
[i
].y_org
;
236 *p_width
= info
[i
].width
;
237 *p_height
= info
[i
].height
;
239 XDestroyRegion( reg
);
240 XDestroyRegion( reg2
);
242 XDestroyRegion( reg1
);
248 void X11Factory::getMonitorInfo( int numScreen
,
250 int* p_width
, int* p_height
) const
252 // initialize to default geometry
255 *p_width
= getScreenWidth();
256 *p_height
= getScreenHeight();
258 // try to detect the requested screen via Xinerama
262 Display
*pDisplay
= m_pDisplay
->getDisplay();
263 XineramaScreenInfo
* info
= XineramaQueryScreens( pDisplay
, &num
);
266 if( numScreen
< num
)
268 *p_x
= info
[numScreen
].x_org
;
269 *p_y
= info
[numScreen
].y_org
;
270 *p_width
= info
[numScreen
].width
;
271 *p_height
= info
[numScreen
].height
;
279 void X11Factory::getDefaultGeometry( int* p_width
, int* p_height
) const
281 Display
*pDisplay
= m_pDisplay
->getDisplay();
283 // Initialize to defaults
284 int screen
= DefaultScreen( pDisplay
);
285 *p_width
= DisplayWidth( pDisplay
, screen
);
286 *p_height
= DisplayHeight( pDisplay
, screen
);
288 // Use Xinerama to restrain to the first monitor instead of the full
291 XineramaScreenInfo
* info
= XineramaQueryScreens( pDisplay
, &num
);
294 for( int i
= 0; i
< num
; i
++ )
296 if( info
[i
].x_org
== 0 && info
[i
].y_org
== 0 )
298 *p_width
= info
[i
].width
;
299 *p_height
= info
[i
].height
;
308 SkinsRect
X11Factory::getWorkArea() const
311 return SkinsRect( 0, 0, getScreenWidth(), getScreenHeight() );
315 void X11Factory::getMousePos( int &rXPos
, int &rYPos
) const
317 Window rootReturn
, childReturn
;
321 Display
*pDisplay
= m_pDisplay
->getDisplay();
322 Window root
= DefaultRootWindow( pDisplay
);
323 XQueryPointer( pDisplay
, root
, &rootReturn
, &childReturn
,
324 &rXPos
, &rYPos
, &winx
, &winy
, &xmask
);
328 void X11Factory::rmDir( const string
&rPath
)
333 dir
= opendir( rPath
.c_str() );
336 // Parse the directory and remove everything it contains
337 while( ( entry
= vlc_readdir( dir
) ) != NULL
)
340 string
filename( entry
);
343 if( filename
== "." || filename
== ".." )
348 filename
= rPath
+ "/" + filename
;
350 if( !stat( filename
.c_str(), &statbuf
) && statbuf
.st_mode
& S_IFDIR
)
356 unlink( filename
.c_str() );
360 // Close the directory
364 rmdir( rPath
.c_str() );