Update ooo320-m1
[ooovba.git] / vcl / unx / source / app / randrwrapper.cxx
blobc615899a979538b863daba905f6e9ae2dcf3ef03
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: randrwrapper.cxx,v $
11 * $Revision: 1.5.10.1 $
13 * This file is part of OpenOffice.org.
15 * OpenOffice.org is free software: you can redistribute it and/or modify
16 * it under the terms of the GNU Lesser General Public License version 3
17 * only, as published by the Free Software Foundation.
19 * OpenOffice.org is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU Lesser General Public License version 3 for more details
23 * (a copy is included in the LICENSE file that accompanied this code).
25 * You should have received a copy of the GNU Lesser General Public License
26 * version 3 along with OpenOffice.org. If not, see
27 * <http://www.openoffice.org/license.html>
28 * for a copy of the LGPLv3 License.
30 ************************************************************************/
32 #ifdef USE_RANDR
34 #include <tools/prex.h>
35 #include <X11/extensions/Xrandr.h>
36 #include <tools/postx.h>
38 #include "osl/module.h"
39 #include "rtl/ustring.hxx"
41 namespace
44 # ifdef XRANDR_DLOPEN
46 class RandRWrapper
48 oslModule m_pRandRLib;
50 // function pointers
51 Bool(*m_pXRRQueryExtension)(Display*,int*,int*);
52 Status(*m_pXRRQueryVersion)(Display*,int*,int*);
53 XRRScreenConfiguration*(*m_pXRRGetScreenInfo)(Display*,Drawable);
54 void(*m_pXRRFreeScreenConfigInfo)(XRRScreenConfiguration*);
55 void(*m_pXRRSelectInput)(Display*,XLIB_Window,int);
56 int(*m_pXRRUpdateConfiguration)(XEvent*);
57 XRRScreenSize*(*m_pXRRSizes)(Display*,int,int*);
58 XRRScreenSize*(*m_pXRRConfigSizes)(XRRScreenConfiguration*,int*);
59 SizeID(*m_pXRRConfigCurrentConfiguration)(XRRScreenConfiguration*,Rotation*);
60 int(*m_pXRRRootToScreen)(Display*, XLIB_Window);
62 bool m_bValid;
64 void initFromModule();
66 RandRWrapper(Display*);
67 ~RandRWrapper();
68 public:
69 static RandRWrapper& get(Display*);
70 static void releaseWrapper();
72 Bool XRRQueryExtension(Display* i_pDisp, int* o_event_base, int* o_error_base )
74 Bool bRet = False;
75 if( m_bValid )
76 bRet = m_pXRRQueryExtension( i_pDisp, o_event_base, o_error_base );
77 return bRet;
79 Status XRRQueryVersion( Display* i_pDisp, int* o_major, int* o_minor )
81 return m_bValid ? m_pXRRQueryVersion( i_pDisp, o_major, o_minor ) : 0;
83 XRRScreenConfiguration* XRRGetScreenInfo( Display* i_pDisp, Drawable i_aDrawable )
85 return m_bValid ? m_pXRRGetScreenInfo( i_pDisp, i_aDrawable ) : NULL;
87 void XRRFreeScreenConfigInfo( XRRScreenConfiguration* i_pConfig )
89 if( m_bValid )
90 m_pXRRFreeScreenConfigInfo( i_pConfig );
92 void XRRSelectInput( Display* i_pDisp, XLIB_Window i_window, int i_nMask )
94 if( m_bValid )
95 m_pXRRSelectInput( i_pDisp, i_window, i_nMask );
97 int XRRUpdateConfiguration( XEvent* i_pEvent )
99 return m_bValid ? m_pXRRUpdateConfiguration( i_pEvent ) : 0;
101 XRRScreenSize* XRRSizes( Display* i_pDisp, int i_screen, int* o_nscreens )
103 return m_bValid ? m_pXRRSizes( i_pDisp, i_screen, o_nscreens ) : NULL;
105 XRRScreenSize* XRRConfigSizes( XRRScreenConfiguration* i_pConfig, int* o_nSizes )
107 return m_bValid ? m_pXRRConfigSizes( i_pConfig, o_nSizes ) : NULL;
109 SizeID XRRConfigCurrentConfiguration( XRRScreenConfiguration* i_pConfig, Rotation* o_pRot )
111 return m_bValid ? m_pXRRConfigCurrentConfiguration( i_pConfig, o_pRot ) : 0;
113 int XRRRootToScreen( Display *dpy, XLIB_Window root )
115 return m_bValid ? m_pXRRRootToScreen( dpy, root ) : -1;
119 void RandRWrapper::initFromModule()
121 m_pXRRQueryExtension = (Bool(*)(Display*,int*,int*))osl_getAsciiFunctionSymbol( m_pRandRLib, "XRRQueryExtension" );
122 m_pXRRQueryVersion = (Status(*)(Display*,int*,int*))osl_getAsciiFunctionSymbol( m_pRandRLib, "XRRQueryVersion" );
123 m_pXRRGetScreenInfo = (XRRScreenConfiguration*(*)(Display*,Drawable))osl_getAsciiFunctionSymbol( m_pRandRLib, "XRRGetScreenInfo" );
124 m_pXRRFreeScreenConfigInfo = (void(*)(XRRScreenConfiguration*))osl_getAsciiFunctionSymbol( m_pRandRLib, "XRRFreeScreenConfigInfo" );
125 m_pXRRSelectInput = (void(*)(Display*,XLIB_Window,int))osl_getAsciiFunctionSymbol( m_pRandRLib, "XRRSelectInput" );
126 m_pXRRUpdateConfiguration = (int(*)(XEvent*))osl_getAsciiFunctionSymbol( m_pRandRLib, "XRRUpdateConfiguration" );
127 m_pXRRSizes = (XRRScreenSize*(*)(Display*,int,int*))osl_getAsciiFunctionSymbol( m_pRandRLib, "XRRSizes" );
128 m_pXRRConfigSizes = (XRRScreenSize*(*)(XRRScreenConfiguration*,int*))osl_getAsciiFunctionSymbol( m_pRandRLib, "XRRConfigSizes" );
129 m_pXRRConfigCurrentConfiguration = (SizeID(*)(XRRScreenConfiguration*,Rotation*))osl_getAsciiFunctionSymbol( m_pRandRLib, "XRRConfigCurrentConfiguration" );
130 m_pXRRRootToScreen = (int(*)(Display*,XLIB_Window))osl_getAsciiFunctionSymbol( m_pRandRLib, "XRRRootToScreen" );
132 m_bValid = m_pXRRQueryExtension &&
133 m_pXRRQueryVersion &&
134 m_pXRRGetScreenInfo &&
135 m_pXRRFreeScreenConfigInfo &&
136 m_pXRRSelectInput &&
137 m_pXRRUpdateConfiguration &&
138 m_pXRRSizes &&
139 m_pXRRConfigSizes &&
140 m_pXRRConfigCurrentConfiguration &&
141 m_pXRRRootToScreen
145 RandRWrapper::RandRWrapper( Display* pDisplay ) :
146 m_pRandRLib( NULL ),
147 m_pXRRQueryExtension( NULL ),
148 m_pXRRQueryVersion( NULL ),
149 m_pXRRGetScreenInfo( NULL ),
150 m_pXRRFreeScreenConfigInfo( NULL ),
151 m_pXRRSelectInput( NULL ),
152 m_pXRRUpdateConfiguration( NULL ),
153 m_pXRRSizes( NULL ),
154 m_pXRRConfigSizes( NULL ),
155 m_pXRRConfigCurrentConfiguration( NULL ),
156 m_pXRRRootToScreen( NULL ),
157 m_bValid( false )
159 // first try in process space (e.g. gtk links that ?)
160 initFromModule();
161 if( ! m_bValid )
163 rtl::OUString aLibName( RTL_CONSTASCII_USTRINGPARAM( "libXrandr.so.2" ) );
164 m_pRandRLib = osl_loadModule( aLibName.pData, SAL_LOADMODULE_DEFAULT );
165 initFromModule();
167 if( m_bValid )
169 int nEventBase = 0, nErrorBase = 0;
170 if( ! m_pXRRQueryExtension( pDisplay, &nEventBase, &nErrorBase ) )
171 m_bValid = false;
175 RandRWrapper::~RandRWrapper()
177 if( m_pRandRLib )
178 osl_unloadModule( m_pRandRLib );
181 static RandRWrapper* pWrapper = NULL;
183 RandRWrapper& RandRWrapper::get( Display* i_pDisplay )
185 if( ! pWrapper )
186 pWrapper = new RandRWrapper( i_pDisplay );
187 return *pWrapper;
190 void RandRWrapper::releaseWrapper()
192 delete pWrapper;
193 pWrapper = NULL;
196 # else
198 class RandRWrapper
200 bool m_bValid;
202 RandRWrapper(Display*);
203 public:
204 static RandRWrapper& get(Display*);
205 static void releaseWrapper();
207 Bool XRRQueryExtension(Display* i_pDisp, int* o_event_base, int* o_error_base )
209 Bool bRet = False;
210 if( m_bValid )
211 bRet = ::XRRQueryExtension( i_pDisp, o_event_base, o_error_base );
212 return bRet;
214 Status XRRQueryVersion( Display* i_pDisp, int* o_major, int* o_minor )
216 return m_bValid ? ::XRRQueryVersion( i_pDisp, o_major, o_minor ) : 0;
218 XRRScreenConfiguration* XRRGetScreenInfo( Display* i_pDisp, Drawable i_aDrawable )
220 return m_bValid ? ::XRRGetScreenInfo( i_pDisp, i_aDrawable ) : NULL;
222 void XRRFreeScreenConfigInfo( XRRScreenConfiguration* i_pConfig )
224 if( m_bValid )
225 ::XRRFreeScreenConfigInfo( i_pConfig );
227 void XRRSelectInput( Display* i_pDisp, XLIB_Window i_window, int i_nMask )
229 if( m_bValid )
230 ::XRRSelectInput( i_pDisp, i_window, i_nMask );
232 int XRRUpdateConfiguration( XEvent* i_pEvent )
234 return m_bValid ? ::XRRUpdateConfiguration( i_pEvent ) : 0;
236 XRRScreenSize* XRRSizes( Display* i_pDisp, int i_screen, int* o_nscreens )
238 return m_bValid ? ::XRRSizes( i_pDisp, i_screen, o_nscreens ) : NULL;
240 XRRScreenSize* XRRConfigSizes( XRRScreenConfiguration* i_pConfig, int* o_nSizes )
242 return m_bValid ? ::XRRConfigSizes( i_pConfig, o_nSizes ) : NULL;
244 SizeID XRRConfigCurrentConfiguration( XRRScreenConfiguration* i_pConfig, Rotation* o_pRot )
246 return m_bValid ? ::XRRConfigCurrentConfiguration( i_pConfig, o_pRot ) : 0;
248 int XRRRootToScreen( Display *dpy, XLIB_Window root )
250 return m_bValid ? ::XRRRootToScreen( dpy, root ) : -1;
254 RandRWrapper::RandRWrapper( Display* pDisplay ) :
255 m_bValid( true )
257 int nEventBase = 0, nErrorBase = 0;
258 if( !XRRQueryExtension( pDisplay, &nEventBase, &nErrorBase ) )
259 m_bValid = false;
262 static RandRWrapper* pWrapper = NULL;
264 RandRWrapper& RandRWrapper::get( Display* i_pDisplay )
266 if( ! pWrapper )
267 pWrapper = new RandRWrapper( i_pDisplay );
268 return *pWrapper;
271 void RandRWrapper::releaseWrapper()
273 delete pWrapper;
274 pWrapper = NULL;
277 #endif
279 } // namespace
281 #endif
283 #include "saldisp.hxx"
284 #include "salframe.h"
286 void SalDisplay::InitRandR( XLIB_Window aRoot ) const
288 #ifdef USE_RANDR
289 if( m_bUseRandRWrapper )
290 RandRWrapper::get( GetDisplay() ).XRRSelectInput( GetDisplay(), aRoot, RRScreenChangeNotifyMask );
291 #else
292 (void)aRoot;
293 #endif
296 void SalDisplay::DeInitRandR()
298 #ifdef USE_RANDR
299 if( m_bUseRandRWrapper )
300 RandRWrapper::releaseWrapper();
301 #if OSL_DEBUG_LEVEL > 1
302 fprintf( stderr, "SalDisplay::DeInitRandR()\n" );
303 #endif
304 #endif
307 int SalDisplay::processRandREvent( XEvent* pEvent )
309 int nRet = 0;
310 #ifdef USE_RANDR
311 XConfigureEvent* pCnfEvent=(XConfigureEvent*)pEvent;
312 if( m_bUseRandRWrapper && pWrapper && pWrapper->XRRRootToScreen(GetDisplay(),pCnfEvent->window) != -1 )
314 nRet = pWrapper->XRRUpdateConfiguration( pEvent );
315 if( nRet == 1 && pEvent->type != ConfigureNotify) // this should then be a XRRScreenChangeNotifyEvent
317 // update screens
318 bool bNotify = false;
319 for( size_t i = 0; i < m_aScreens.size(); i++ )
321 if( m_aScreens[i].m_bInit )
323 XRRScreenConfiguration *pConfig = NULL;
324 XRRScreenSize *pSizes = NULL;
325 int nSizes = 0;
326 Rotation nRot = 0;
327 SizeID nId = 0;
329 pConfig = pWrapper->XRRGetScreenInfo( GetDisplay(), m_aScreens[i].m_aRoot );
330 nId = pWrapper->XRRConfigCurrentConfiguration( pConfig, &nRot );
331 pSizes = pWrapper->XRRConfigSizes( pConfig, &nSizes );
332 XRRScreenSize *pTargetSize = pSizes + nId;
334 bNotify = bNotify ||
335 m_aScreens[i].m_aSize.Width() != pTargetSize->width ||
336 m_aScreens[i].m_aSize.Height() != pTargetSize->height;
338 m_aScreens[i].m_aSize = Size( pTargetSize->width, pTargetSize->height );
340 pWrapper->XRRFreeScreenConfigInfo( pConfig );
342 #if OSL_DEBUG_LEVEL > 1
343 fprintf( stderr, "screen %d changed to size %dx%d\n", (int)i, (int)pTargetSize->width, (int)pTargetSize->height );
344 #endif
347 if( bNotify && ! m_aFrames.empty() )
348 m_aFrames.front()->CallCallback( SALEVENT_DISPLAYCHANGED, 0 );
351 #else
352 (void)pEvent;
353 #endif
354 return nRet;