@ -40,6 +40,10 @@
# undef INT32
# undef INT32
# include <X11/extensions/Xrandr.h>
# include <X11/extensions/Xrandr.h>
static int refreshRateForModeInfo ( const XRRModeInfo * mode_info ) ;
static int refreshRateIndexToXRR ( int screen , int size , int index ) ;
static int refreshRateXRRToIndex ( int screen , int size , int hz ) ;
HotPlugRule : : HotPlugRule ( )
HotPlugRule : : HotPlugRule ( )
{
{
//
//
@ -169,7 +173,8 @@ KDE_EXPORT void RandRScreen::loadSettings()
}
}
if ( d - > config ) {
if ( d - > config ) {
m_currentRefreshRate = m_proposedRefreshRate = refreshRateHzToIndex ( m_currentSize , XRRConfigCurrentRate ( d - > config ) ) ;
m_currentRefreshRate = m_proposedRefreshRate =
refreshRateXRRToIndex ( m_screen , m_currentSize , XRRConfigCurrentRate ( d - > config ) ) ;
}
}
else {
else {
m_currentRefreshRate = m_proposedRefreshRate = 0 ;
m_currentRefreshRate = m_proposedRefreshRate = 0 ;
@ -185,8 +190,12 @@ KDE_EXPORT void RandRScreen::setOriginal()
KDE_EXPORT bool RandRScreen : : applyProposed ( )
KDE_EXPORT bool RandRScreen : : applyProposed ( )
{
{
//kdDebug() << k_funcinfo << " size " << (SizeID)proposedSize() << ", rotation " << proposedRotation() << ", refresh " << refreshRateIndexToHz(proposedSize(), proposedRefreshRate()) << endl;
#if 0
kdDebug ( ) < < k_funcinfo < < " size " < < ( SizeID ) proposedSize ( ) < <
" , rotation " < < proposedRotation ( ) < <
" , refresh " < < refreshRateIndexToHz ( proposedSize ( ) , proposedRefreshRate ( ) )
< < " ( " < < refreshRateIndexToXRR ( m_screen , proposedSize ( ) , proposedRefreshRate ( ) ) < < " ) " < < endl ;
# endif
Status status ;
Status status ;
if ( ! d - > config ) {
if ( ! d - > config ) {
@ -198,10 +207,11 @@ KDE_EXPORT bool RandRScreen::applyProposed()
if ( proposedRefreshRate ( ) < 0 )
if ( proposedRefreshRate ( ) < 0 )
status = XRRSetScreenConfig ( tqt_xdisplay ( ) , d - > config , DefaultRootWindow ( tqt_xdisplay ( ) ) , ( SizeID ) proposedSize ( ) , ( Rotation ) proposedRotation ( ) , CurrentTime ) ;
status = XRRSetScreenConfig ( tqt_xdisplay ( ) , d - > config , DefaultRootWindow ( tqt_xdisplay ( ) ) , ( SizeID ) proposedSize ( ) , ( Rotation ) proposedRotation ( ) , CurrentTime ) ;
else {
else {
if ( refreshRateIndexToHz ( proposedSize ( ) , proposedRefreshRate ( ) ) < = 0 ) {
int hz = refreshRateIndexToXRR ( m_screen , proposedSize ( ) , proposedRefreshRate ( ) ) ;
if ( hz < = 0 ) {
m_proposedRefreshRate = 0 ;
m_proposedRefreshRate = 0 ;
}
}
status = XRRSetScreenConfigAndRate ( tqt_xdisplay ( ) , d - > config , DefaultRootWindow ( tqt_xdisplay ( ) ) , ( SizeID ) proposedSize ( ) , ( Rotation ) proposedRotation ( ) , refres hRateIndexToH z( proposedSize ( ) , proposedRefreshRate ( ) ) , CurrentTime ) ;
status = XRRSetScreenConfigAndRate ( tqt_xdisplay ( ) , d - > config , DefaultRootWindow ( tqt_xdisplay ( ) ) , ( SizeID ) proposedSize ( ) , ( Rotation ) proposedRotation ( ) , hz, CurrentTime ) ;
}
}
}
}
else {
else {
@ -487,26 +497,22 @@ KDE_EXPORT int RandRScreen::currentMMHeight() const
return m_pixelSizes [ m_currentSize ] . height ( ) ;
return m_pixelSizes [ m_currentSize ] . height ( ) ;
}
}
KDE_EXPORT TQ StringList RandRScreen : : refreshRat es( int size ) const
KDE_EXPORT TQ ValueVector< int > RandRScreen : : refreshRat esValu es( int size ) const
{
{
int nrates ;
ScreenInfo * screeninfo = internal_read_screen_info ( tqt_xdisplay ( ) ) ;
TQStringList ret ;
int numSizes = screeninfo - > res - > nmode ;
TQValueVector < int > ret ;
if ( d - > config ) {
if ( size > numSizes - 1 ) { // out of range
short * rates = XRRRates ( tqt_xdisplay ( ) , m_screen , ( SizeID ) size , & nrates ) ;
return ret ;
for ( int i = 0 ; i < nrates ; i + + )
ret < < refreshRateDirectDescription ( rates [ i ] ) ;
}
}
else {
// Great, now we have to go after the information manually. Ughh.
char * currentModeName = screeninfo - > res - > modes [ size ] . name ;
ScreenInfo * screeninfo = internal_read_screen_info ( tqt_xdisplay ( ) ) ;
for ( int i = 0 ; i < numSizes ; i + + ) {
int numSizes = screeninfo - > res - > nmode ;
if ( strcmp ( currentModeName , screeninfo - > res - > modes [ i ] . name ) = = 0 ) {
for ( int i = 0 ; i < numSizes ; i + + ) {
int rate = refreshRateForModeInfo ( & screeninfo - > res - > modes [ i ] ) ;
int refresh_rate = ( ( screeninfo - > res - > modes [ i ] . dotClock * 1.0 ) / ( ( screeninfo - > res - > modes [ i ] . hTotal ) * ( screeninfo - > res - > modes [ i ] . vTotal ) * 1.0 ) ) ;
if ( rate ! = 0 ) {
TQString newRate = refreshRateDirectDescription ( refresh_rate ) ;
ret . append ( rate ) ;
if ( ! ret . contains ( newRate ) ) {
ret . append ( newRate ) ;
}
}
}
}
}
}
@ -514,6 +520,17 @@ KDE_EXPORT TQStringList RandRScreen::refreshRates(int size) const
return ret ;
return ret ;
}
}
KDE_EXPORT TQStringList RandRScreen : : refreshRates ( int size ) const
{
TQStringList ret ;
for ( int rate : refreshRatesValues ( size ) ) {
ret . append ( refreshRateDirectDescription ( rate ) ) ;
}
return ret ;
}
KDE_EXPORT TQString RandRScreen : : refreshRateDirectDescription ( int rate ) const
KDE_EXPORT TQString RandRScreen : : refreshRateDirectDescription ( int rate ) const
{
{
return i18n ( " Refresh rate in Hertz (Hz) " , " % 1 Hz " ).arg(rate) ;
return i18n ( " Refresh rate in Hertz (Hz) " , " % 1 Hz " ).arg(rate) ;
@ -521,7 +538,7 @@ KDE_EXPORT TQString RandRScreen::refreshRateDirectDescription(int rate) const
KDE_EXPORT TQString RandRScreen : : refreshRateIndirectDescription ( int size , int index ) const
KDE_EXPORT TQString RandRScreen : : refreshRateIndirectDescription ( int size , int index ) const
{
{
return i18n( " Refresh rate in Hertz (Hz) " , " % 1 Hz " ).arg(refreshRateIndexToHz(size, index) );
return refreshRateDirectDescription( refreshRateIndexToHz ( size , index ) );
}
}
KDE_EXPORT TQString RandRScreen : : refreshRateDescription ( int size , int index ) const
KDE_EXPORT TQString RandRScreen : : refreshRateDescription ( int size , int index ) const
@ -556,30 +573,28 @@ KDE_EXPORT int RandRScreen::proposedRefreshRate() const
KDE_EXPORT int RandRScreen : : refreshRateHzToIndex ( int size , int hz ) const
KDE_EXPORT int RandRScreen : : refreshRateHzToIndex ( int size , int hz ) const
{
{
int nrates ;
TQValueVector < int > rates = refreshRatesValues ( size ) ;
short * rates = XRRRates ( tqt_xdisplay ( ) , m_screen , ( SizeID ) size , & nrates ) ;
for ( size_t i = 0 ; i < rates . size ( ) ; i + + ) {
if ( ( int ) ( rates [ i ] + 0.5 ) = = hz ) {
for ( int i = 0 ; i < nrates ; i + + )
if ( hz = = rates [ i ] )
return i ;
return i ;
}
}
if ( nrates ! = 0 )
if ( rates. size ( ) ! = 0 )
// Wrong input Hz!
// Wrong input Hz!
Q_ASSERT ( false ) ;
Q_ASSERT ( false ) ;
return - 1 ;
return - 1 ;
}
}
KDE_EXPORT int RandRScreen : : refreshRateIndexToHz ( int size , int index ) const
KDE_EXPORT int RandRScreen : : refreshRateIndexToHz ( int size , int index ) const {
{
TQValueVector < int > rates = refreshRatesValues ( size ) ;
int nrates ;
short * rates = XRRRates ( tqt_xdisplay ( ) , m_screen , ( SizeID ) size , & nrates ) ;
if ( n rates = = 0 | | index < 0 )
if ( rates . size ( ) = = 0 | | index < 0 )
return 0 ;
return 0 ;
// Wrong input Hz !
// Wrong input index !
if ( index > = nrates )
if ( index > = ( ssize_t ) rates . size ( ) )
return 0 ;
return 0 ;
return rates [ index ] ;
return rates [ index ] ;
@ -880,4 +895,72 @@ KDE_EXPORT int RandRScreen::pixelCount( int index ) const
return sz . width ( ) * sz . height ( ) ;
return sz . width ( ) * sz . height ( ) ;
}
}
// Calculates refresh rate for modeinfo
// snatch from xrandr-1.5
static int refreshRateForModeInfo ( const XRRModeInfo * mode_info )
{
double rate ;
double vTotal = mode_info - > vTotal ;
if ( mode_info - > modeFlags & RR_DoubleScan ) {
/* doublescan doubles the number of lines */
vTotal * = 2 ;
}
if ( mode_info - > modeFlags & RR_Interlace ) {
/* interlace splits the frame into two fields */
/* the field rate is what is typically reported by monitors */
vTotal / = 2 ;
}
if ( mode_info - > hTotal & & vTotal )
rate = ( ( double ) mode_info - > dotClock /
( ( double ) mode_info - > hTotal * ( double ) vTotal ) ) ;
else
rate = 0 ;
return ( int ) ( rate + 0.5 ) ;
}
// On some video drivers (e.g. proprietary nvidia) XRandR returns incorrect
// readings for refresh rate[1], when read via XRRRates(), so for display
// purposes we will use data from XRRGetScreenResources() and some fancy
// calculations (see internal_read_screen_info() and refreshRateForModeInfo()).
// Unfortunately, other XRandR functions (like XRRConfigCurrentRate() and
// XRRSetScreenConfigAndRate()) expect the data reported by XRRRates(). So,
// in order to be able to correctly set a refresh rate we have to request
// it via XRRRates() anyway.
//
// [1]: see https://mirror.git.trinitydesktop.org/gitea/TDE/tde/issues/75
static int refreshRateXRRToIndex ( int screen , int size , int hz )
{
int nrates ;
short * rates = XRRRates ( tqt_xdisplay ( ) , screen , ( SizeID ) size , & nrates ) ;
for ( int i = 0 ; i < nrates ; i + + )
if ( hz = = rates [ i ] )
return i ;
if ( nrates ! = 0 )
// Wrong input Hz!
Q_ASSERT ( false ) ;
return - 1 ;
}
static int refreshRateIndexToXRR ( int screen , int size , int index )
{
int nrates ;
short * rates = XRRRates ( tqt_xdisplay ( ) , screen , ( SizeID ) size , & nrates ) ;
if ( nrates = = 0 | | index < 0 )
return 0 ;
// Wrong input Hz!
if ( index > = nrates )
return 0 ;
return rates [ index ] ;
}
# include "randr.moc"
# include "randr.moc"