/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project .
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License , v . 2 . 0 . If a copy of the MPL was not distributed with this
* file , You can obtain one at http : //mozilla.org/MPL/2.0/.
*
* This file incorporates work covered by the following license notice :
*
* Licensed to the Apache Software Foundation ( ASF ) under one or more
* contributor license agreements . See the NOTICE file distributed
* with this work for additional information regarding copyright
* ownership . The ASF licenses this file to you under the Apache
* License , Version 2 . 0 ( the " License " ) ; you may not use this file
* except in compliance with the License . You may obtain a copy of
* the License at http : //www.apache.org/licenses/LICENSE-2.0 .
*/
#ifdef USE_RANDR
#include <X11/Xlib.h>
#include <X11/extensions/Xrandr.h>
#include <sal/log.hxx>
namespace
{
class RandRWrapper
{
bool m_bValid;
explicit RandRWrapper(Display*);
public :
static RandRWrapper& get(Display*);
static void releaseWrapper();
Bool XRRQueryExtension(Display* i_pDisp, int * o_event_base, int * o_error_base )
{
Bool bRet = False ;
if ( m_bValid )
bRet = ::XRRQueryExtension( i_pDisp, o_event_base, o_error_base );
return bRet;
}
XRRScreenConfiguration* XRRGetScreenInfo( Display* i_pDisp, Drawable i_aDrawable )
{
return m_bValid ? ::XRRGetScreenInfo( i_pDisp, i_aDrawable ) : nullptr;
}
void XRRFreeScreenConfigInfo( XRRScreenConfiguration* i_pConfig )
{
if ( m_bValid )
::XRRFreeScreenConfigInfo( i_pConfig );
}
void XRRSelectInput( Display* i_pDisp, ::Window i_window, int i_nMask )
{
if ( m_bValid )
::XRRSelectInput( i_pDisp, i_window, i_nMask );
}
int XRRUpdateConfiguration( XEvent* i_pEvent )
{
return m_bValid ? ::XRRUpdateConfiguration( i_pEvent ) : 0 ;
}
XRRScreenSize* XRRConfigSizes( XRRScreenConfiguration* i_pConfig, int * o_nSizes )
{
return m_bValid ? ::XRRConfigSizes( i_pConfig, o_nSizes ) : nullptr;
}
SizeID XRRConfigCurrentConfiguration( XRRScreenConfiguration* i_pConfig, Rotation* o_pRot )
{
return m_bValid ? ::XRRConfigCurrentConfiguration( i_pConfig, o_pRot ) : 0 ;
}
int XRRRootToScreen( Display *dpy, ::Window root )
{
return m_bValid ? ::XRRRootToScreen( dpy, root ) : -1 ;
}
};
RandRWrapper::RandRWrapper( Display* pDisplay ) :
m_bValid( true )
{
int nEventBase = 0 , nErrorBase = 0 ;
if ( !XRRQueryExtension( pDisplay, &nEventBase, &nErrorBase ) )
m_bValid = false ;
}
RandRWrapper* pWrapper = nullptr;
RandRWrapper& RandRWrapper::get( Display* i_pDisplay )
{
if ( ! pWrapper )
pWrapper = new RandRWrapper( i_pDisplay );
return *pWrapper;
}
void RandRWrapper::releaseWrapper()
{
delete pWrapper;
pWrapper = nullptr;
}
} // namespace
#endif
#include <unx/saldisp.hxx>
#if OSL_DEBUG_LEVEL > 1
#include <cstdio>
#endif
void SalDisplay::InitRandR( ::Window aRoot ) const
{
#ifdef USE_RANDR
RandRWrapper::get( GetDisplay() ).XRRSelectInput( GetDisplay(), aRoot, RRScreenChangeNotifyMask );
#else
(void )this ;
(void )aRoot;
#endif
}
void SalDisplay::DeInitRandR()
{
#ifdef USE_RANDR
RandRWrapper::releaseWrapper();
#if OSL_DEBUG_LEVEL > 1
SAL_INFO("vcl.app" , "SalDisplay::DeInitRandR()." );
#endif
#endif
}
void SalDisplay::processRandREvent( XEvent* pEvent )
{
#ifdef USE_RANDR
XConfigureEvent* pCnfEvent=reinterpret_cast <XConfigureEvent*>(pEvent);
if ( !pWrapper || pWrapper->XRRRootToScreen(GetDisplay(),pCnfEvent->window) == -1 )
return ;
int nRet = pWrapper->XRRUpdateConfiguration( pEvent );
if ( nRet != 1 || pEvent->type == ConfigureNotify) // this should then be a XRRScreenChangeNotifyEvent
return ;
// update screens
bool bNotify = false ;
for (ScreenData & rScreen : m_aScreens)
{
if ( rScreen.m_bInit )
{
XRRScreenConfiguration *pConfig = nullptr;
XRRScreenSize *pSizes = nullptr;
int nSizes = 0 ;
Rotation nRot = 0 ;
SizeID nId = 0 ;
pConfig = pWrapper->XRRGetScreenInfo( GetDisplay(), rScreen.m_aRoot );
nId = pWrapper->XRRConfigCurrentConfiguration( pConfig, &nRot );
pSizes = pWrapper->XRRConfigSizes( pConfig, &nSizes );
XRRScreenSize *pTargetSize = pSizes + nId;
bNotify = bNotify ||
rScreen.m_aSize.Width() != pTargetSize->width ||
rScreen.m_aSize.Height() != pTargetSize->height;
rScreen.m_aSize = AbsoluteScreenPixelSize( pTargetSize->width, pTargetSize->height );
pWrapper->XRRFreeScreenConfigInfo( pConfig );
#if OSL_DEBUG_LEVEL > 1
SAL_INFO("vcl.app" , "screen " << nId
<< " changed to size " << (int )pTargetSize->width
<< "x" << (int )pTargetSize->height);
#endif
}
}
if ( bNotify )
emitDisplayChanged();
#else
(void )this ;
(void )pEvent;
#endif
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Messung V0.5 in Prozent C=92 H=97 G=94
¤ Dauer der Verarbeitung: 0.16 Sekunden
(vorverarbeitet am 2026-06-12)
¤
*© Formatika GbR, Deutschland