x11 factory: use vlc_readdir
[vlc/solaris.git] / modules / gui / skins2 / x11 / x11_factory.cpp
blob7ee664da20aace05a51d4eed0e9d220f37d0cd8d
1 /*****************************************************************************
2 * x11_factory.cpp
3 *****************************************************************************
4 * Copyright (C) 2003 the VideoLAN team
5 * $Id$
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 *****************************************************************************/
25 #ifdef X11_SKINS
27 #include <unistd.h>
28 #include <dirent.h>
29 #include <sys/stat.h>
30 #include <X11/Xlib.h>
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>
45 #include <vlc_xlib.h>
47 X11Factory::X11Factory( intf_thread_t *pIntf ): OSFactory( pIntf ),
48 m_pDisplay( NULL ), m_pTimerLoop( NULL ), m_dirSep( "/" )
50 // see init()
54 X11Factory::~X11Factory()
56 delete m_pTimerLoop;
57 delete m_pDisplay;
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" );
67 return false;
70 // Create the X11 display
71 m_pDisplay = new X11Display( getIntf() );
73 // Get the display
74 Display *pDisplay = m_pDisplay->getDisplay();
75 if( pDisplay == NULL )
77 // Initialization failed
78 return false;
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" );
88 free( datadir );
89 m_resourcePath.push_back( (string)"share/skins2" );
90 datadir = config_GetDataDir( getIntf() );
91 m_resourcePath.push_back( (string)datadir + "/skins2" );
92 free( datadir );
94 // Determine the monitor geometry
95 getDefaultGeometry( &m_screenWidth, &m_screenHeight );
97 return true;
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()
126 // TODO
129 void X11Factory::addInTray()
131 // TODO
134 void X11Factory::removeFromTray()
136 // TODO
139 void X11Factory::addInTaskBar()
141 // TODO
144 void X11Factory::removeFromTaskBar()
146 // TODO
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,
189 int* p_x, int* p_y,
190 int* p_width, int* p_height ) const
192 // initialize to default geometry
193 *p_x = 0;
194 *p_y = 0;
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 );
203 Window child_wnd;
205 int x, y;
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 );
210 int num;
211 XineramaScreenInfo* info = XineramaQueryScreens( pDisplay, &num );
212 if( info )
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 );
228 XRectangle rect;
229 XClipBox( reg, &rect );
230 unsigned int surf = rect.width * rect.height;
231 if( surf > surface )
233 surface = surf;
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 );
243 XFree( info );
248 void X11Factory::getMonitorInfo( int numScreen,
249 int* p_x, int* p_y,
250 int* p_width, int* p_height ) const
252 // initialize to default geometry
253 *p_x = 0;
254 *p_y = 0;
255 *p_width = getScreenWidth();
256 *p_height = getScreenHeight();
258 // try to detect the requested screen via Xinerama
259 if( numScreen >= 0 )
261 int num;
262 Display *pDisplay = m_pDisplay->getDisplay();
263 XineramaScreenInfo* info = XineramaQueryScreens( pDisplay, &num );
264 if( info )
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;
273 XFree( info );
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
289 // virtual screen
290 int num;
291 XineramaScreenInfo* info = XineramaQueryScreens( pDisplay, &num );
292 if( info )
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;
300 break;
303 XFree( info );
308 SkinsRect X11Factory::getWorkArea() const
310 // XXX
311 return SkinsRect( 0, 0, getScreenWidth(), getScreenHeight() );
315 void X11Factory::getMousePos( int &rXPos, int &rYPos ) const
317 Window rootReturn, childReturn;
318 int winx, winy;
319 unsigned int xmask;
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 )
330 struct dirent *file;
331 DIR *dir;
332 char *entry;
333 dir = opendir( rPath.c_str() );
334 if( !dir ) return;
336 // Parse the directory and remove everything it contains
337 while( ( entry = vlc_readdir( dir ) ) != NULL )
339 struct stat statbuf;
340 string filename( entry );
342 // Skip "." and ".."
343 if( filename == "." || filename == ".." )
345 continue;
348 filename = rPath + "/" + filename;
350 if( !stat( filename.c_str(), &statbuf ) && statbuf.st_mode & S_IFDIR )
352 rmDir( filename );
354 else
356 unlink( filename.c_str() );
360 // Close the directory
361 closedir( dir );
363 // And delete it
364 rmdir( rPath.c_str() );
367 #endif