@ -24,6 +24,7 @@
# include <tqlineedit.h>
# include <tqpushbutton.h>
# include <tqtabwidget.h>
# include <tqtimer.h>
# include <dcopclient.h>
@ -62,22 +63,6 @@ K_EXPORT_COMPONENT_FACTORY( kcm_displayconfig, KDisplayCFactory("kcmdisplayconfi
KSimpleConfig * systemconfig ;
// This routine is courtsey of an answer on "Stack Overflow"
// It takes an LSB-first int and makes it an MSB-first int (or vice versa)
unsigned int reverse_bits ( register unsigned int x )
{
x = ( ( ( x & 0xaaaaaaaa ) > > 1 ) | ( ( x & 0x55555555 ) < < 1 ) ) ;
x = ( ( ( x & 0xcccccccc ) > > 2 ) | ( ( x & 0x33333333 ) < < 2 ) ) ;
x = ( ( ( x & 0xf0f0f0f0 ) > > 4 ) | ( ( x & 0x0f0f0f0f ) < < 4 ) ) ;
x = ( ( ( x & 0xff00ff00 ) > > 8 ) | ( ( x & 0x00ff00ff ) < < 8 ) ) ;
return ( ( x > > 16 ) | ( x < < 16 ) ) ;
}
TQString capitalizeString ( TQString in ) {
return in . left ( 1 ) . upper ( ) + in . right ( in . length ( ) - 1 ) ;
}
TQPoint moveTQRectOutsideTQRect ( TQRect base , TQRect movable , int fallback_level = 0 ) {
TQPoint final_result ;
@ -455,6 +440,9 @@ void KDisplayConfig::updateDraggableMonitorInformationInternal (int monitor_id,
}
}
TQString rotationDesired = * screendata - > rotations . at ( screendata - > current_rotation_index ) ;
bool isvisiblyrotated = ( ( rotationDesired = = " Rotate 90 degrees " ) | | ( rotationDesired = = " Rotate 270 degrees " ) ) ;
if ( screendata - > is_extended ) {
moved_monitor - > show ( ) ;
}
@ -463,6 +451,9 @@ void KDisplayConfig::updateDraggableMonitorInformationInternal (int monitor_id,
}
// Handle resizing
if ( isvisiblyrotated )
moved_monitor - > setFixedSize ( screendata - > current_y_pixel_count * base - > monitorPhyArrange - > resize_factor , screendata - > current_x_pixel_count * base - > monitorPhyArrange - > resize_factor ) ;
else
moved_monitor - > setFixedSize ( screendata - > current_x_pixel_count * base - > monitorPhyArrange - > resize_factor , screendata - > current_y_pixel_count * base - > monitorPhyArrange - > resize_factor ) ;
// Find the primary monitor
@ -680,6 +671,9 @@ KDisplayConfig::KDisplayConfig(TQWidget *parent, const char *name, const TQStrin
connect ( base - > systemEnableSupport , TQT_SIGNAL ( clicked ( ) ) , TQT_SLOT ( changed ( ) ) ) ;
connect ( base - > systemEnableSupport , TQT_SIGNAL ( clicked ( ) ) , TQT_SLOT ( processLockoutControls ( ) ) ) ;
connect ( base - > monitorDisplaySelectDD , TQT_SIGNAL ( activated ( int ) ) , TQT_SLOT ( changed ( ) ) ) ;
connect ( base - > rotationSelectDD , TQT_SIGNAL ( activated ( int ) ) , TQT_SLOT ( rotationInfoChanged ( ) ) ) ;
connect ( base - > orientationHFlip , TQT_SIGNAL ( clicked ( ) ) , TQT_SLOT ( rotationInfoChanged ( ) ) ) ;
connect ( base - > orientationVFlip , TQT_SIGNAL ( clicked ( ) ) , TQT_SLOT ( rotationInfoChanged ( ) ) ) ;
connect ( base - > resolutionSlider , TQT_SIGNAL ( valueChanged ( int ) ) , TQT_SLOT ( resolutionSliderChanged ( int ) ) ) ;
connect ( base - > monitorDisplaySelectDD , TQT_SIGNAL ( activated ( int ) ) , TQT_SLOT ( selectScreen ( int ) ) ) ;
connect ( base - > monitorPhyArrange , TQT_SIGNAL ( workspaceRelayoutNeeded ( ) ) , this , TQT_SLOT ( layoutDragDropDisplay ( ) ) ) ;
@ -691,6 +685,8 @@ KDisplayConfig::KDisplayConfig(TQWidget *parent, const char *name, const TQStrin
connect ( base - > systemEnableSupport , TQT_SIGNAL ( toggled ( bool ) ) , base - > monitorDisplaySelectDD , TQT_SLOT ( setEnabled ( bool ) ) ) ;
connect ( base - > previewConfiguration , TQT_SIGNAL ( clicked ( ) ) , TQT_SLOT ( activatePreview ( ) ) ) ;
load ( ) ;
addTab ( " iccconfig " , i18n ( " Color Profiles " ) ) ; // [FIXME[ No way to save settings here yet
@ -728,6 +724,10 @@ void KDisplayConfig::addProfile () {
}
void KDisplayConfig : : activatePreview ( ) {
m_randrsimple - > applySystemwideDisplayConfiguration ( m_screenInfoArray , TRUE ) ;
}
void KDisplayConfig : : load ( )
{
load ( false ) ;
@ -743,249 +743,8 @@ void KDisplayConfig::selectScreen (int slotNumber) {
}
void KDisplayConfig : : updateArray ( void ) {
// Discover display information
int i ;
int j ;
XRROutputInfo * output_info ;
// Clear existing info
SingleScreenData * screendata ;
for ( screendata = m_screenInfoArray . first ( ) ; screendata ; screendata = m_screenInfoArray . next ( ) ) {
m_screenInfoArray . remove ( screendata ) ;
delete screendata ;
}
numberOfScreens = 0 ;
if ( m_randrsimple - > isValid ( ) = = true ) {
randr_display = XOpenDisplay ( NULL ) ;
randr_screen_info = m_randrsimple - > read_screen_info ( randr_display ) ;
for ( i = 0 ; i < randr_screen_info - > n_output ; i + + ) {
output_info = randr_screen_info - > outputs [ i ] - > info ;
// Create new data object
screendata = new SingleScreenData ;
m_screenInfoArray . append ( screendata ) ;
screendata - > screenFriendlyName = TQString ( i18n ( " %1. %2 output on %3 " ) ) . arg ( i + 1 ) . arg ( capitalizeString ( output_info - > name ) ) . arg ( " :0 " ) ; // [FIXME] How can I get the name of the Xorg graphics driver currently in use?
screendata - > generic_screen_detected = false ;
// Attempt to use KMS to find screen EDID and name
TQString edid = getEDIDMonitorName ( 0 , output_info - > name ) ; // [FIXME] Don't hardwire to card 0!
if ( ! edid . isNull ( ) ) {
screendata - > screenFriendlyName = TQString ( i18n ( " %1. %2 on %3 on card %4 " ) ) . arg ( i + 1 ) . arg ( edid ) . arg ( capitalizeString ( output_info - > name ) ) . arg ( " 0 " ) ; // [FIXME] How can I get the name of the Xorg graphics driver currently in use?
}
// Get resolutions
RandRScreen * cur_screen = m_randrsimple - > screen ( i ) ;
if ( cur_screen ) {
screendata - > screen_connected = true ;
for ( int j = 0 ; j < cur_screen - > numSizes ( ) ; j + + ) {
screendata - > resolutions . append ( i18n ( " %1 x %2 " ) . tqarg ( cur_screen - > pixelSize ( j ) . width ( ) ) . tqarg ( cur_screen - > pixelSize ( j ) . height ( ) ) ) ;
}
screendata - > current_resolution_index = cur_screen - > proposedSize ( ) ;
// Get refresh rates
TQStringList rr = cur_screen - > refreshRates ( screendata - > current_resolution_index ) ;
for ( TQStringList : : Iterator it = rr . begin ( ) ; it ! = rr . end ( ) ; + + it ) {
screendata - > refresh_rates . append ( * it ) ;
}
screendata - > current_refresh_rate_index = cur_screen - > proposedRefreshRate ( ) ;
// Get color depths
// [FIXME]
screendata - > color_depths . append ( i18n ( " Default " ) ) ;
screendata - > current_color_depth_index = 0 ;
// Get orientation flags
// RandRScreen::Rotate0
// RandRScreen::Rotate90
// RandRScreen::Rotate180
// RandRScreen::Rotate270
// RandRScreen::ReflectX
// RandRScreen::ReflectY
screendata - > rotations . append ( i18n ( " Normal " ) ) ;
screendata - > rotations . append ( i18n ( " Rotate 90 degrees " ) ) ;
screendata - > rotations . append ( i18n ( " Rotate 180 degrees " ) ) ;
screendata - > rotations . append ( i18n ( " Rotate 270 degrees " ) ) ;
screendata - > current_orientation_mask = cur_screen - > proposedRotation ( ) ;
switch ( screendata - > current_orientation_mask & RandRScreen : : RotateMask ) {
case RandRScreen : : Rotate0 :
screendata - > current_rotation_index = 0 ;
break ;
case RandRScreen : : Rotate90 :
screendata - > current_rotation_index = 1 ;
break ;
case RandRScreen : : Rotate180 :
screendata - > current_rotation_index = 2 ;
break ;
case RandRScreen : : Rotate270 :
screendata - > current_rotation_index = 3 ;
break ;
default :
// Shouldn't hit this one
Q_ASSERT ( screendata - > current_orientation_mask & RandRScreen : : RotateMask ) ;
break ;
}
screendata - > has_x_flip = ( screendata - > current_orientation_mask & RandRScreen : : ReflectX ) ;
screendata - > has_y_flip = ( screendata - > current_orientation_mask & RandRScreen : : ReflectY ) ;
screendata - > supports_transformations = ( cur_screen - > rotations ( ) ! = RandRScreen : : Rotate0 ) ;
// Determine if this display is primary and/or extended
// [FIXME]
screendata - > is_primary = false ;
screendata - > is_extended = false ;
// Get this screen's absolute position
// [FIXME]
screendata - > absolute_x_position = 0 ;
screendata - > absolute_y_position = 0 ;
// Get this screen's current resolution
screendata - > current_x_pixel_count = cur_screen - > pixelSize ( screendata - > current_resolution_index ) . width ( ) ;
screendata - > current_y_pixel_count = cur_screen - > pixelSize ( screendata - > current_resolution_index ) . height ( ) ;
}
else {
// Fill in generic data for this disconnected output
screendata - > screenFriendlyName = screendata - > screenFriendlyName + TQString ( " ( " ) + i18n ( " disconnected " ) + TQString ( " ) " ) ;
screendata - > screen_connected = false ;
screendata - > resolutions = i18n ( " Default " ) ;
screendata - > refresh_rates = i18n ( " Default " ) ;
screendata - > color_depths = i18n ( " Default " ) ;
screendata - > rotations = i18n ( " N/A " ) ;
screendata - > current_resolution_index = 0 ;
screendata - > current_refresh_rate_index = 0 ;
screendata - > current_color_depth_index = 0 ;
screendata - > current_rotation_index = 0 ;
screendata - > current_orientation_mask = 0 ;
screendata - > has_x_flip = false ;
screendata - > has_y_flip = false ;
screendata - > supports_transformations = false ;
screendata - > is_primary = false ;
screendata - > is_extended = false ;
screendata - > absolute_x_position = 0 ;
screendata - > absolute_y_position = 0 ;
screendata - > current_x_pixel_count = 640 ;
screendata - > current_y_pixel_count = 480 ;
}
// Check for more screens...
numberOfScreens + + ;
}
}
else {
screendata = new SingleScreenData ;
m_screenInfoArray . append ( screendata ) ;
// Fill in a bunch of generic data
screendata - > screenFriendlyName = i18n ( " Default output on generic video card " ) ;
screendata - > generic_screen_detected = true ;
screendata - > screen_connected = true ;
screendata - > resolutions = i18n ( " Default " ) ;
screendata - > refresh_rates = i18n ( " Default " ) ;
screendata - > color_depths = i18n ( " Default " ) ;
screendata - > rotations = i18n ( " N/A " ) ;
screendata - > current_resolution_index = 0 ;
screendata - > current_refresh_rate_index = 0 ;
screendata - > current_color_depth_index = 0 ;
screendata - > current_rotation_index = 0 ;
screendata - > current_orientation_mask = 0 ;
screendata - > has_x_flip = false ;
screendata - > has_y_flip = false ;
screendata - > supports_transformations = false ;
screendata - > is_primary = true ;
screendata - > is_extended = true ;
screendata - > absolute_x_position = 0 ;
screendata - > absolute_y_position = 0 ;
screendata - > current_x_pixel_count = 640 ;
screendata - > current_y_pixel_count = 480 ;
numberOfScreens + + ;
}
// [FIXME]
// Set this on the real primary monitor only!
screendata = m_screenInfoArray . at ( 0 ) ;
screendata - > is_primary = true ;
}
TQString KDisplayConfig : : getEDIDMonitorName ( int card , TQString displayname ) {
TQString edid ;
TQByteArray binaryedid = getEDID ( card , displayname ) ;
if ( binaryedid . isNull ( ) )
return TQString ( ) ;
// Get the manufacturer ID
unsigned char letter_1 = ( ( binaryedid [ 8 ] > > 2 ) & 0x1F ) + 0x40 ;
unsigned char letter_2 = ( ( ( binaryedid [ 8 ] & 0x03 ) < < 3 ) | ( ( binaryedid [ 9 ] > > 5 ) & 0x07 ) ) + 0x40 ;
unsigned char letter_3 = ( binaryedid [ 9 ] & 0x1F ) + 0x40 ;
TQChar qletter_1 = TQChar ( letter_1 ) ;
TQChar qletter_2 = TQChar ( letter_2 ) ;
TQChar qletter_3 = TQChar ( letter_3 ) ;
TQString manufacturer_id = TQString ( " %1%2%3 " ) . arg ( qletter_1 ) . arg ( qletter_2 ) . arg ( qletter_3 ) ;
// Get the model ID
unsigned int raw_model_id = ( ( ( binaryedid [ 10 ] < < 8 ) | binaryedid [ 11 ] ) < < 16 ) & 0xFFFF0000 ;
// Reverse the bit order
unsigned int model_id = reverse_bits ( raw_model_id ) ;
// Try to get the model name
bool has_friendly_name = false ;
unsigned char descriptor_block [ 18 ] ;
int i ;
for ( i = 72 ; i < 90 ; i + + ) {
descriptor_block [ i - 72 ] = binaryedid [ i ] & 0xFF ;
}
if ( ( descriptor_block [ 0 ] ! = 0 ) | | ( descriptor_block [ 1 ] ! = 0 ) | | ( descriptor_block [ 3 ] ! = 0xFC ) ) {
for ( i = 90 ; i < 108 ; i + + ) {
descriptor_block [ i - 90 ] = binaryedid [ i ] & 0xFF ;
}
if ( ( descriptor_block [ 0 ] ! = 0 ) | | ( descriptor_block [ 1 ] ! = 0 ) | | ( descriptor_block [ 3 ] ! = 0xFC ) ) {
for ( i = 108 ; i < 126 ; i + + ) {
descriptor_block [ i - 108 ] = binaryedid [ i ] & 0xFF ;
}
}
}
TQString monitor_name ;
if ( ( descriptor_block [ 0 ] = = 0 ) & & ( descriptor_block [ 1 ] = = 0 ) & & ( descriptor_block [ 3 ] = = 0xFC ) ) {
char * pos = strchr ( ( char * ) ( descriptor_block + 5 ) , ' \n ' ) ;
if ( pos ) {
* pos = 0 ;
has_friendly_name = true ;
monitor_name = TQString ( ( char * ) ( descriptor_block + 5 ) ) ;
}
else {
has_friendly_name = false ;
}
}
// [FIXME]
// Look up manudacturer names if possible!
if ( has_friendly_name )
edid = TQString ( " %1 %2 " ) . arg ( manufacturer_id ) . arg ( monitor_name ) ;
else
edid = TQString ( " %1 0x%2 " ) . arg ( manufacturer_id ) . arg ( model_id , 0 , 16 ) ;
return edid ;
}
TQByteArray KDisplayConfig : : getEDID ( int card , TQString displayname ) {
TQFile file ( TQString ( " /sys/class/drm/card%1-%2/edid " ) . arg ( card ) . arg ( displayname ) ) ;
if ( ! file . open ( IO_ReadOnly ) )
return TQByteArray ( ) ;
TQByteArray binaryedid = file . readAll ( ) ;
file . close ( ) ;
return binaryedid ;
m_screenInfoArray = m_randrsimple - > readCurrentDisplayConfiguration ( ) ;
numberOfScreens = m_screenInfoArray . count ( ) ;
}
void KDisplayConfig : : updateDisplayedInformation ( ) {
@ -1130,11 +889,16 @@ void KDisplayConfig::updateDragDropDisplay() {
base - > monitorPhyArrange - > resize_factor = 0.0625 ; // This always needs to divide by a multiple of 2
for ( i = 0 ; i < numberOfScreens ; i + + ) {
screendata = m_screenInfoArray . at ( i ) ;
TQString rotationDesired = * screendata - > rotations . at ( screendata - > current_rotation_index ) ;
bool isvisiblyrotated = ( ( rotationDesired = = " Rotate 90 degrees " ) | | ( rotationDesired = = " Rotate 270 degrees " ) ) ;
DraggableMonitor * m = new DraggableMonitor ( base - > monitorPhyArrange , 0 , WStyle_Customize | WDestructiveClose | WStyle_NoBorder | WX11BypassWM ) ;
connect ( m , TQT_SIGNAL ( workspaceRelayoutNeeded ( ) ) , this , TQT_SLOT ( layoutDragDropDisplay ( ) ) ) ;
connect ( m , TQT_SIGNAL ( monitorSelected ( int ) ) , this , TQT_SLOT ( selectScreen ( int ) ) ) ;
connect ( m , TQT_SIGNAL ( monitorDragComplete ( int ) ) , this , TQT_SLOT ( updateDraggableMonitorInformation ( int ) ) ) ;
m - > screen_id = i ;
if ( isvisiblyrotated )
m - > setFixedSize ( screendata - > current_y_pixel_count * base - > monitorPhyArrange - > resize_factor , screendata - > current_x_pixel_count * base - > monitorPhyArrange - > resize_factor ) ;
else
m - > setFixedSize ( screendata - > current_x_pixel_count * base - > monitorPhyArrange - > resize_factor , screendata - > current_y_pixel_count * base - > monitorPhyArrange - > resize_factor ) ;
m - > setText ( TQString ( " %1 " ) . arg ( i + 1 ) ) ;
m - > show ( ) ;
@ -1169,66 +933,7 @@ void KDisplayConfig::layoutDragDropDisplay() {
}
void KDisplayConfig : : ensureMonitorDataConsistency ( ) {
int i ;
SingleScreenData * screendata ;
for ( i = 0 ; i < numberOfScreens ; i + + ) {
screendata = m_screenInfoArray . at ( i ) ;
if ( ! screendata - > screen_connected ) {
screendata - > is_primary = false ;
screendata - > is_extended = false ;
}
}
bool has_primary_monitor = false ;
for ( i = 0 ; i < numberOfScreens ; i + + ) {
screendata = m_screenInfoArray . at ( i ) ;
if ( screendata - > is_primary )
has_primary_monitor = true ;
}
if ( ! has_primary_monitor ) {
for ( i = 0 ; i < numberOfScreens ; i + + ) {
screendata = m_screenInfoArray . at ( i ) ;
if ( ! has_primary_monitor ) {
if ( screendata - > is_extended ) {
screendata - > is_primary = true ;
screendata - > is_extended = true ;
has_primary_monitor = true ;
}
}
}
}
if ( ! has_primary_monitor ) {
for ( i = 0 ; i < numberOfScreens ; i + + ) {
screendata = m_screenInfoArray . at ( i ) ;
if ( ! has_primary_monitor ) {
if ( screendata - > screen_connected ) {
screendata - > is_primary = true ;
screendata - > is_extended = true ;
has_primary_monitor = true ;
}
}
}
}
for ( i = 0 ; i < numberOfScreens ; i + + ) {
screendata = m_screenInfoArray . at ( i ) ;
if ( screendata - > is_primary ) {
screendata - > absolute_x_position = 0 ;
screendata - > absolute_y_position = 0 ;
screendata - > is_extended = true ;
}
}
for ( i = 0 ; i < numberOfScreens ; i + + ) {
screendata = m_screenInfoArray . at ( i ) ;
TQString resolutionstring = screendata - > resolutions [ screendata - > current_resolution_index ] ;
int separator_pos = resolutionstring . find ( " x " ) ;
TQString x_res_string = resolutionstring . left ( separator_pos ) ;
TQString y_res_string = resolutionstring . right ( resolutionstring . length ( ) - separator_pos - 3 ) ;
screendata - > current_x_pixel_count = x_res_string . toInt ( ) ;
screendata - > current_y_pixel_count = y_res_string . toInt ( ) ;
}
m_randrsimple - > ensureMonitorDataConsistency ( m_screenInfoArray ) ;
}
void KDisplayConfig : : resolutionSliderTextUpdate ( int index ) {
@ -1245,6 +950,21 @@ void KDisplayConfig::resolutionSliderChanged(int index) {
screendata - > current_resolution_index = realResolutionSliderValue ( ) ;
updateDisplayedInformation ( ) ;
updateDraggableMonitorInformation ( base - > monitorDisplaySelectDD - > currentItem ( ) ) ;
changed ( ) ;
}
void KDisplayConfig : : rotationInfoChanged ( ) {
SingleScreenData * screendata ;
screendata = m_screenInfoArray . at ( base - > monitorDisplaySelectDD - > currentItem ( ) ) ;
screendata - > current_rotation_index = base - > rotationSelectDD - > currentItem ( ) ;
screendata - > has_x_flip = base - > orientationHFlip - > isChecked ( ) ;
screendata - > has_y_flip = base - > orientationVFlip - > isChecked ( ) ;
updateDisplayedInformation ( ) ;
updateDraggableMonitorInformation ( base - > monitorDisplaySelectDD - > currentItem ( ) ) ;
changed ( ) ;
}
TQString KDisplayConfig : : extractFileName ( TQString displayName , TQString profileName ) {
@ -1331,19 +1051,24 @@ void KDisplayConfig::load(bool useDefaults )
void KDisplayConfig : : save ( )
{
int i ;
int j ;
KRandrSimpleAPI * m_randrsimple = new KRandrSimpleAPI ( ) ;
if ( m_randrsimple - > applySystemwideDisplayConfiguration ( m_screenInfoArray , TRUE ) ) {
m_randrsimple - > saveSystemwideDisplayConfiguration ( " " , KDE_CONFDIR , m_screenInfoArray ) ;
// Write system configuration
systemconfig - > setGroup ( NULL ) ;
systemconfig - > writeEntry ( " EnableDisplayControl " , base - > systemEnableSupport - > isChecked ( ) ) ;
systemconfig - > sync ( ) ;
emit changed ( false ) ;
}
else {
// Signal that settings were NOT applied
TQTimer * t = new TQTimer ( this ) ;
connect ( t , SIGNAL ( timeout ( ) ) , SLOT ( changed ( ) ) ) ;
t - > start ( 100 , FALSE ) ;
}
}
void KDisplayConfig : : defaults ( )
{