1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
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 ************************************************************************/
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"
48 oslModule m_pRandRLib
;
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
);
64 void initFromModule();
66 RandRWrapper(Display
*);
69 static RandRWrapper
& get(Display
*);
70 static void releaseWrapper();
72 Bool
XRRQueryExtension(Display
* i_pDisp
, int* o_event_base
, int* o_error_base
)
76 bRet
= m_pXRRQueryExtension( i_pDisp
, o_event_base
, o_error_base
);
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
)
90 m_pXRRFreeScreenConfigInfo( i_pConfig
);
92 void XRRSelectInput( Display
* i_pDisp
, XLIB_Window i_window
, int i_nMask
)
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
&&
137 m_pXRRUpdateConfiguration
&&
140 m_pXRRConfigCurrentConfiguration
&&
145 RandRWrapper::RandRWrapper( Display
* pDisplay
) :
147 m_pXRRQueryExtension( NULL
),
148 m_pXRRQueryVersion( NULL
),
149 m_pXRRGetScreenInfo( NULL
),
150 m_pXRRFreeScreenConfigInfo( NULL
),
151 m_pXRRSelectInput( NULL
),
152 m_pXRRUpdateConfiguration( NULL
),
154 m_pXRRConfigSizes( NULL
),
155 m_pXRRConfigCurrentConfiguration( NULL
),
156 m_pXRRRootToScreen( NULL
),
159 // first try in process space (e.g. gtk links that ?)
163 rtl::OUString
aLibName( RTL_CONSTASCII_USTRINGPARAM( "libXrandr.so.2" ) );
164 m_pRandRLib
= osl_loadModule( aLibName
.pData
, SAL_LOADMODULE_DEFAULT
);
169 int nEventBase
= 0, nErrorBase
= 0;
170 if( ! m_pXRRQueryExtension( pDisplay
, &nEventBase
, &nErrorBase
) )
175 RandRWrapper::~RandRWrapper()
178 osl_unloadModule( m_pRandRLib
);
181 static RandRWrapper
* pWrapper
= NULL
;
183 RandRWrapper
& RandRWrapper::get( Display
* i_pDisplay
)
186 pWrapper
= new RandRWrapper( i_pDisplay
);
190 void RandRWrapper::releaseWrapper()
202 RandRWrapper(Display
*);
204 static RandRWrapper
& get(Display
*);
205 static void releaseWrapper();
207 Bool
XRRQueryExtension(Display
* i_pDisp
, int* o_event_base
, int* o_error_base
)
211 bRet
= ::XRRQueryExtension( i_pDisp
, o_event_base
, o_error_base
);
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
)
225 ::XRRFreeScreenConfigInfo( i_pConfig
);
227 void XRRSelectInput( Display
* i_pDisp
, XLIB_Window i_window
, int i_nMask
)
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
) :
257 int nEventBase
= 0, nErrorBase
= 0;
258 if( !XRRQueryExtension( pDisplay
, &nEventBase
, &nErrorBase
) )
262 static RandRWrapper
* pWrapper
= NULL
;
264 RandRWrapper
& RandRWrapper::get( Display
* i_pDisplay
)
267 pWrapper
= new RandRWrapper( i_pDisplay
);
271 void RandRWrapper::releaseWrapper()
283 #include "saldisp.hxx"
284 #include "salframe.h"
286 void SalDisplay::InitRandR( XLIB_Window aRoot
) const
289 if( m_bUseRandRWrapper
)
290 RandRWrapper::get( GetDisplay() ).XRRSelectInput( GetDisplay(), aRoot
, RRScreenChangeNotifyMask
);
296 void SalDisplay::DeInitRandR()
299 if( m_bUseRandRWrapper
)
300 RandRWrapper::releaseWrapper();
301 #if OSL_DEBUG_LEVEL > 1
302 fprintf( stderr
, "SalDisplay::DeInitRandR()\n" );
307 int SalDisplay::processRandREvent( XEvent
* pEvent
)
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
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
;
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
;
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
);
347 if( bNotify
&& ! m_aFrames
.empty() )
348 m_aFrames
.front()->CallCallback( SALEVENT_DISPLAYCHANGED
, 0 );