You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
912 lines
27 KiB
912 lines
27 KiB
/* |
|
* Copyright (c) 2002,2003 Hamish Rodda <rodda@kde.org> |
|
* |
|
* This program is free software; you can redistribute it and/or modify |
|
* it under the terms of the GNU General Public License as published by |
|
* the Free Software Foundation; either version 2 of the License, or |
|
* (at your option) any later version. |
|
* |
|
* This program is distributed in the hope that it will be useful, |
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
* GNU General Public License for more details. |
|
* |
|
* You should have received a copy of the GNU General Public License |
|
* along with this program; if not, write to the Free Software |
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
*/ |
|
|
|
#ifdef HAVE_CONFIG_H |
|
#include <config.h> |
|
#endif |
|
|
|
#include <tqtimer.h> |
|
#include <tqimage.h> |
|
#include <tqtooltip.h> |
|
|
|
#include <tdeaction.h> |
|
#include <tdeapplication.h> |
|
#include <kcmultidialog.h> |
|
#include <kdebug.h> |
|
#include <khelpmenu.h> |
|
#include <kiconloader.h> |
|
#include <tdelocale.h> |
|
#include <tdepopupmenu.h> |
|
#include <kstdaction.h> |
|
#include <kstdguiitem.h> |
|
#include <tdeglobal.h> |
|
#include <tdemessagebox.h> |
|
#include <kstandarddirs.h> |
|
|
|
#include <cstdlib> |
|
#include <unistd.h> |
|
|
|
#include "configdialog.h" |
|
|
|
#include "tderandrtray.h" |
|
#include "tderandrpassivepopup.h" |
|
#include "tderandrtray.moc" |
|
|
|
#define OUTPUT_CONNECTED (1 << 0) |
|
#define OUTPUT_UNKNOWN (1 << 1) |
|
#define OUTPUT_DISCONNECTED (1 << 2) |
|
#define OUTPUT_ON (1 << 3) |
|
#define OUTPUT_ALL (0xf) |
|
|
|
KRandRSystemTray::KRandRSystemTray(TQWidget* parent, const char *name) |
|
: KSystemTray(parent, name) |
|
, m_popupUp(false) |
|
, m_help(new KHelpMenu(this, TDEGlobal::instance()->aboutData(), false, actionCollection())) |
|
{ |
|
TDEPopupMenu *help = m_help->menu(); |
|
help->connectItem(KHelpMenu::menuHelpContents, this, TQT_SLOT(slotHelpContents())); |
|
setPixmap(KSystemTray::loadIcon("randr")); |
|
setAlignment(Qt::AlignHCenter | Qt::AlignVCenter); |
|
connect(this, TQT_SIGNAL(quitSelected()), this, TQT_SLOT(_quit())); |
|
TQToolTip::add(this, i18n("Screen resize & rotate")); |
|
my_parent = parent; |
|
|
|
//printf("Reading configuration...\n"); |
|
globalKeys = new TDEGlobalAccel(TQT_TQOBJECT(this)); |
|
TDEGlobalAccel* keys = globalKeys; |
|
#include "tderandrbindings.cpp" |
|
// the keys need to be read from kdeglobals, not kickerrc |
|
globalKeys->readSettings(); |
|
globalKeys->setEnabled(true); |
|
globalKeys->updateConnections(); |
|
|
|
connect(kapp, TQT_SIGNAL(settingsChanged(int)), TQT_SLOT(slotSettingsChanged(int))); |
|
|
|
#if (TQT_VERSION-0 >= 0x030200) // XRANDR support |
|
// connect(this, TQT_SIGNAL(screenSizeChanged(int, int)), kapp->desktop(), TQT_SLOT( desktopResized())); |
|
#endif |
|
|
|
randr_display = XOpenDisplay(NULL); |
|
|
|
if (isValid() == true) { |
|
last_known_x = currentScreen()->currentPixelWidth(); |
|
last_known_y = currentScreen()->currentPixelHeight(); |
|
} |
|
|
|
t_config = new KSimpleConfig("kiccconfigrc"); |
|
|
|
TQString cur_profile; |
|
cur_profile = getCurrentProfile(); |
|
if (cur_profile != "") { |
|
applyIccConfiguration(cur_profile, NULL); |
|
} |
|
|
|
#ifdef WITH_TDEHWLIB |
|
TDEHardwareDevices *hwdevices = TDEGlobal::hardwareDevices(); |
|
connect(hwdevices, TQT_SIGNAL(hardwareUpdated(TDEGenericDevice*)), this, TQT_SLOT(deviceChanged(TDEGenericDevice*))); |
|
#endif |
|
} |
|
|
|
/*! |
|
* \b TQT_SLOT which called if tderandrtray is exited by the user. In this case the user |
|
* is asked through a yes/no box if "KRandRTray should start automatically on log in" and the |
|
* result is written to the KDE configfile. |
|
*/ |
|
void KRandRSystemTray::_quit (){ |
|
r_config = new KSimpleConfig("tderandrtrayrc"); |
|
|
|
TQString tmp1 = i18n ("Start KRandRTray automatically when you log in?"); |
|
int tmp2 = KMessageBox::questionYesNo ( 0, tmp1, i18n("Question"), i18n("Start Automatically"), i18n("Do Not Start")); |
|
r_config->setGroup("General"); |
|
r_config->writeEntry ("Autostart", tmp2 == KMessageBox::Yes); |
|
r_config->sync (); |
|
|
|
exit(0); |
|
} |
|
|
|
void KRandRSystemTray::resizeTrayIcon () |
|
{ |
|
// Honor Free Desktop specifications that allow for arbitrary system tray icon sizes |
|
TQPixmap origpixmap; |
|
TQPixmap scaledpixmap; |
|
TQImage newIcon; |
|
origpixmap = KSystemTray::loadSizedIcon( "randr", width() ); |
|
newIcon = origpixmap; |
|
newIcon = newIcon.smoothScale(width(), height()); |
|
scaledpixmap = newIcon; |
|
setPixmap(scaledpixmap); |
|
} |
|
|
|
void KRandRSystemTray::resizeEvent ( TQResizeEvent * ) |
|
{ |
|
// Honor Free Desktop specifications that allow for arbitrary system tray icon sizes |
|
resizeTrayIcon(); |
|
} |
|
|
|
void KRandRSystemTray::showEvent ( TQShowEvent * ) |
|
{ |
|
// Honor Free Desktop specifications that allow for arbitrary system tray icon sizes |
|
resizeTrayIcon(); |
|
} |
|
|
|
void KRandRSystemTray::mousePressEvent(TQMouseEvent* e) |
|
{ |
|
// Popup the context menu with left-click |
|
if (e->button() == Qt::LeftButton) { |
|
contextMenuAboutToShow(contextMenu()); |
|
contextMenu()->popup(e->globalPos()); |
|
e->accept(); |
|
return; |
|
} |
|
|
|
KSystemTray::mousePressEvent(e); |
|
} |
|
|
|
void KRandRSystemTray::reloadDisplayConfiguration() |
|
{ |
|
// Reload the randr configuration... |
|
int i; |
|
int activeOutputs = 0; |
|
int screenDeactivated = 0; |
|
|
|
if (isValid() == true) { |
|
randr_screen_info = read_screen_info(randr_display); |
|
|
|
// Count outputs in the active state |
|
activeOutputs = 0; |
|
for (i = 0; i < randr_screen_info->n_output; i++) { |
|
// Look for ON outputs |
|
if (!randr_screen_info->outputs[i]->cur_crtc) { |
|
continue; |
|
} |
|
// Look for CONNECTED outputs |
|
if (RR_Disconnected == randr_screen_info->outputs[i]->info->connection) { |
|
continue; |
|
} |
|
|
|
activeOutputs++; |
|
} |
|
|
|
if (activeOutputs < 1) { |
|
// Houston, we have a problem! |
|
// There are no active displays! |
|
// Activate the first connected display we come across... |
|
for (i = 0; i < randr_screen_info->n_output; i++) { |
|
// Look for OFF outputs |
|
if (randr_screen_info->outputs[i]->cur_crtc) { |
|
continue; |
|
} |
|
// Look for CONNECTED outputs |
|
if (RR_Disconnected == randr_screen_info->outputs[i]->info->connection) { |
|
continue; |
|
} |
|
|
|
// Activate this output |
|
randr_screen_info->cur_crtc = randr_screen_info->outputs[i]->cur_crtc; |
|
randr_screen_info->cur_output = randr_screen_info->outputs[i]; |
|
randr_screen_info->cur_output->auto_set = 1; |
|
randr_screen_info->cur_output->off_set = 0; |
|
output_auto (randr_screen_info, randr_screen_info->cur_output); |
|
i=main_low_apply(randr_screen_info); |
|
|
|
if (randr_screen_info->outputs[i]->cur_crtc) { |
|
// Output successfully activated! |
|
set_primary_output(randr_screen_info, randr_screen_info->cur_output->id); |
|
break; |
|
} |
|
} |
|
} |
|
|
|
for (i = 0; i < randr_screen_info->n_output; i++) { |
|
// Look for ON outputs |
|
if (!randr_screen_info->outputs[i]->cur_crtc) { |
|
continue; |
|
} |
|
// Look for DISCONNECTED outputs |
|
if (RR_Disconnected != randr_screen_info->outputs[i]->info->connection) { |
|
continue; |
|
} |
|
|
|
// Deactivate this display to avoid a crash! |
|
randr_screen_info->cur_crtc = randr_screen_info->outputs[i]->cur_crtc; |
|
randr_screen_info->cur_output = randr_screen_info->outputs[i]; |
|
randr_screen_info->cur_output->auto_set = 0; |
|
randr_screen_info->cur_output->off_set = 1; |
|
output_off(randr_screen_info, randr_screen_info->cur_output); |
|
main_low_apply(randr_screen_info); |
|
|
|
screenDeactivated = 1; |
|
} |
|
|
|
if (screenDeactivated == 1) { |
|
findPrimaryDisplay(); |
|
refresh(); |
|
|
|
currentScreen()->proposeSize(GetDefaultResolutionParameter()); |
|
currentScreen()->applyProposed(); |
|
} |
|
} |
|
} |
|
|
|
void KRandRSystemTray::contextMenuAboutToShow(TDEPopupMenu* menu) |
|
{ |
|
int lastIndex = 0; |
|
|
|
reloadDisplayConfiguration(); |
|
|
|
menu->clear(); |
|
menu->setCheckable(true); |
|
|
|
bool valid = isValid(); |
|
|
|
if (!valid) { |
|
lastIndex = menu->insertItem(i18n("Required X Extension Not Available")); |
|
menu->setItemEnabled(lastIndex, false); |
|
|
|
} |
|
else { |
|
m_screenPopups.clear(); |
|
for (int s = 0; s < numScreens() /*&& numScreens() > 1 */; s++) { |
|
setCurrentScreen(s); |
|
if (s == screenIndexOfWidget(this)) { |
|
/*lastIndex = menu->insertItem(i18n("Screen %1").arg(s+1)); |
|
menu->setItemEnabled(lastIndex, false);*/ |
|
} else { |
|
TDEPopupMenu* subMenu = new TDEPopupMenu(menu, TQString("screen%1").arg(s+1).latin1()); |
|
m_screenPopups.append(subMenu); |
|
populateMenu(subMenu); |
|
lastIndex = menu->insertItem(i18n("Screen %1").arg(s+1), subMenu); |
|
connect(subMenu, TQT_SIGNAL(activated(int)), TQT_SLOT(slotScreenActivated())); |
|
} |
|
} |
|
|
|
setCurrentScreen(screenIndexOfWidget(this)); |
|
populateMenu(menu); |
|
} |
|
|
|
addOutputMenu(menu); |
|
|
|
// Find any user ICC profiles |
|
TQStringList cfgProfiles; |
|
cfgProfiles = t_config->groupList(); |
|
if (cfgProfiles.isEmpty() == false) { |
|
menu->insertTitle(SmallIcon("kcoloredit"), i18n("Color Profile")); |
|
} |
|
for (TQStringList::Iterator t(cfgProfiles.begin()); t != cfgProfiles.end(); ++t) { |
|
lastIndex = menu->insertItem(*t); |
|
if (t_config->readEntry("CurrentProfile") == (*t)) { |
|
menu->setItemChecked(lastIndex, true); |
|
} |
|
menu->setItemEnabled(lastIndex, t_config->readBoolEntry("EnableICC", false)); |
|
menu->connectItem(lastIndex, this, TQT_SLOT(slotColorProfileChanged(int))); |
|
} |
|
|
|
if (valid) { |
|
// Find any display profiles |
|
TQStringList displayProfiles; |
|
displayProfiles = getDisplayConfigurationProfiles(locateLocal("config", "/", true)); |
|
if (!displayProfiles.isEmpty()) { |
|
menu->insertTitle(SmallIcon("background"), i18n("Display Profiles")); |
|
lastIndex = menu->insertItem(SmallIcon("bookmark"), "<default>"); |
|
menu->connectItem(lastIndex, this, TQT_SLOT(slotDisplayProfileChanged(int))); |
|
for (TQStringList::Iterator t(displayProfiles.begin()); t != displayProfiles.end(); ++t) { |
|
lastIndex = menu->insertItem(SmallIcon("bookmark"), *t); |
|
menu->connectItem(lastIndex, this, TQT_SLOT(slotDisplayProfileChanged(int))); |
|
} |
|
} |
|
} |
|
|
|
menu->insertTitle(SmallIcon("randr"), i18n("Global Configuration")); |
|
|
|
TDEAction *actColors = new TDEAction( i18n( "Configure Displays..." ), |
|
SmallIconSet( "configure" ), TDEShortcut(), TQT_TQOBJECT(this), TQT_SLOT( slotDisplayConfig() ), |
|
actionCollection() ); |
|
actColors->plug( menu ); |
|
|
|
// TDEAction *actPrefs = new TDEAction( i18n( "Configure Display..." ), |
|
// SmallIconSet( "configure" ), TDEShortcut(), this, TQT_SLOT( slotPrefs() ), |
|
// actionCollection() ); |
|
// actPrefs->plug( menu ); |
|
|
|
TDEAction *actSKeys = new TDEAction( i18n( "Configure Shortcut Keys..." ), |
|
SmallIconSet( "configure" ), TDEShortcut(), TQT_TQOBJECT(this), TQT_SLOT( slotSKeys() ), |
|
actionCollection() ); |
|
actSKeys->plug( menu ); |
|
|
|
menu->insertItem(SmallIcon("help"),KStdGuiItem::help().text(), m_help->menu()); |
|
TDEAction *quitAction = actionCollection()->action(KStdAction::name(KStdAction::Quit)); |
|
quitAction->plug(menu); |
|
|
|
m_menu = menu; |
|
} |
|
|
|
void KRandRSystemTray::slotScreenActivated() |
|
{ |
|
setCurrentScreen(m_screenPopups.find(static_cast<const TDEPopupMenu*>(sender()))); |
|
} |
|
|
|
void KRandRSystemTray::configChanged() |
|
{ |
|
refresh(); |
|
|
|
static bool first = true; |
|
|
|
if ((last_known_x == currentScreen()->currentPixelWidth()) && \ |
|
(last_known_y == currentScreen()->currentPixelHeight())) { |
|
first = true; |
|
} |
|
|
|
last_known_x = currentScreen()->currentPixelWidth(); |
|
last_known_y = currentScreen()->currentPixelHeight(); |
|
|
|
if (!first) { |
|
emit (screenSizeChanged(currentScreen()->currentPixelWidth(), currentScreen()->currentPixelHeight())); |
|
|
|
KRandrPassivePopup::message( |
|
i18n("Screen configuration has changed"), |
|
currentScreen()->changedMessage(), SmallIcon("view-fullscreen"), |
|
this, "ScreenChangeNotification"); |
|
} |
|
|
|
first = false; |
|
|
|
TQString cur_profile; |
|
cur_profile = getCurrentProfile(); |
|
if (cur_profile != "") { |
|
applyIccConfiguration(cur_profile, NULL); |
|
} |
|
} |
|
|
|
int KRandRSystemTray::GetDefaultResolutionParameter() |
|
{ |
|
int returnIndex = 0; |
|
|
|
int numSizes = currentScreen()->numSizes(); |
|
int* sizeSort = new int[numSizes]; |
|
|
|
for (int i = 0; i < numSizes; i++) { |
|
sizeSort[i] = currentScreen()->pixelCount(i); |
|
} |
|
|
|
int highest = -1, highestIndex = -1; |
|
|
|
for (int i = 0; i < numSizes; i++) { |
|
if (sizeSort[i] && sizeSort[i] > highest) { |
|
highest = sizeSort[i]; |
|
highestIndex = i; |
|
} |
|
} |
|
sizeSort[highestIndex] = -1; |
|
Q_ASSERT(highestIndex != -1); |
|
|
|
returnIndex = highestIndex; |
|
|
|
delete [] sizeSort; |
|
sizeSort = 0L; |
|
|
|
return returnIndex; |
|
} |
|
|
|
int KRandRSystemTray::GetHackResolutionParameter() { |
|
int resparm; |
|
|
|
resparm = GetDefaultResolutionParameter(); |
|
resparm++; |
|
|
|
return resparm; |
|
} |
|
|
|
void KRandRSystemTray::populateMenu(TDEPopupMenu* menu) |
|
{ |
|
int lastIndex = 0; |
|
|
|
menu->insertTitle(SmallIcon("view-fullscreen"), i18n("Screen Size")); |
|
|
|
int numSizes = currentScreen()->numSizes(); |
|
int* sizeSort = new int[numSizes]; |
|
|
|
for (int i = 0; i < numSizes; i++) { |
|
sizeSort[i] = currentScreen()->pixelCount(i); |
|
} |
|
|
|
for (int j = 0; j < numSizes; j++) { |
|
int highest = -1, highestIndex = -1; |
|
|
|
for (int i = 0; i < numSizes; i++) { |
|
if (sizeSort[i] && sizeSort[i] > highest) { |
|
highest = sizeSort[i]; |
|
highestIndex = i; |
|
} |
|
} |
|
sizeSort[highestIndex] = -1; |
|
Q_ASSERT(highestIndex != -1); |
|
|
|
lastIndex = menu->insertItem(i18n("%1 x %2").arg(currentScreen()->pixelSize(highestIndex).width()).arg(currentScreen()->pixelSize(highestIndex).height())); |
|
|
|
if (currentScreen()->proposedSize() == highestIndex) |
|
menu->setItemChecked(lastIndex, true); |
|
|
|
menu->setItemParameter(lastIndex, highestIndex); |
|
menu->connectItem(lastIndex, this, TQT_SLOT(slotResolutionChanged(int))); |
|
} |
|
delete [] sizeSort; |
|
sizeSort = 0L; |
|
|
|
// Don't display the rotation options if there is no point (ie. none are supported) |
|
// XFree86 4.3 does not include rotation support. |
|
if (currentScreen()->rotations() != RandRScreen::Rotate0) { |
|
menu->insertTitle(SmallIcon("reload"), i18n("Orientation")); |
|
|
|
for (int i = 0; i < 6; i++) { |
|
if ((1 << i) & currentScreen()->rotations()) { |
|
lastIndex = menu->insertItem(currentScreen()->rotationIcon(1 << i), RandRScreen::rotationName(1 << i)); |
|
|
|
if (currentScreen()->proposedRotation() & (1 << i)) |
|
menu->setItemChecked(lastIndex, true); |
|
|
|
menu->setItemParameter(lastIndex, 1 << i); |
|
menu->connectItem(lastIndex, this, TQT_SLOT(slotOrientationChanged(int))); |
|
} |
|
} |
|
} |
|
|
|
TQStringList rr = currentScreen()->refreshRates(currentScreen()->proposedSize()); |
|
|
|
if (rr.count()) |
|
menu->insertTitle(SmallIcon("clock"), i18n("Refresh Rate")); |
|
|
|
int i = 0; |
|
for (TQStringList::Iterator it = rr.begin(); it != rr.end(); ++it, i++) { |
|
lastIndex = menu->insertItem(*it); |
|
|
|
if (currentScreen()->proposedRefreshRate() == i) |
|
menu->setItemChecked(lastIndex, true); |
|
|
|
menu->setItemParameter(lastIndex, i); |
|
menu->connectItem(lastIndex, this, TQT_SLOT(slotRefreshRateChanged(int))); |
|
} |
|
} |
|
|
|
void KRandRSystemTray::slotResolutionChanged(int parameter) |
|
{ |
|
if (currentScreen()->currentSize() == parameter) { |
|
//printf("This resolution is already in use; applying again...\n"); |
|
currentScreen()->proposeSize(parameter); |
|
currentScreen()->applyProposed(); |
|
return; |
|
} |
|
|
|
currentScreen()->proposeSize(parameter); |
|
|
|
currentScreen()->proposeRefreshRate(-1); |
|
|
|
if (currentScreen()->applyProposedAndConfirm()) { |
|
TDEConfig config("kcmrandrrc"); |
|
if (syncTrayApp(config)) |
|
currentScreen()->save(config); |
|
} |
|
} |
|
|
|
void KRandRSystemTray::slotOrientationChanged(int parameter) |
|
{ |
|
int propose = currentScreen()->currentRotation(); |
|
|
|
if (parameter & RandRScreen::RotateMask) |
|
propose &= RandRScreen::ReflectMask; |
|
|
|
propose ^= parameter; |
|
|
|
if (currentScreen()->currentRotation() == propose) |
|
return; |
|
|
|
currentScreen()->proposeRotation(propose); |
|
|
|
if (currentScreen()->applyProposedAndConfirm()) { |
|
TDEConfig config("kcmrandrrc"); |
|
if (syncTrayApp(config)) |
|
currentScreen()->save(config); |
|
} |
|
} |
|
|
|
void KRandRSystemTray::slotRefreshRateChanged(int parameter) |
|
{ |
|
if (currentScreen()->currentRefreshRate() == parameter) |
|
return; |
|
|
|
currentScreen()->proposeRefreshRate(parameter); |
|
|
|
if (currentScreen()->applyProposedAndConfirm()) { |
|
TDEConfig config("kcmrandrrc"); |
|
if (syncTrayApp(config)) |
|
currentScreen()->save(config); |
|
} |
|
} |
|
|
|
void KRandRSystemTray::slotPrefs() |
|
{ |
|
KCMultiDialog *kcm = new KCMultiDialog( KDialogBase::Plain, i18n( "Configure" ), this ); |
|
|
|
kcm->addModule( "displayconfig" ); |
|
kcm->setPlainCaption( i18n( "Configure Display" ) ); |
|
kcm->exec(); |
|
} |
|
|
|
void KRandRSystemTray::slotDisplayConfig() |
|
{ |
|
KCMultiDialog *kcm = new KCMultiDialog( KDialogBase::Plain, i18n( "Configure" ), this ); |
|
|
|
kcm->addModule( "displayconfig" ); |
|
kcm->setPlainCaption( i18n( "Configure Displays" ) ); |
|
kcm->exec(); |
|
} |
|
|
|
void KRandRSystemTray::slotSettingsChanged(int category) |
|
{ |
|
if ( category == (int) TDEApplication::SETTINGS_SHORTCUTS ) { |
|
globalKeys->readSettings(); |
|
globalKeys->updateConnections(); |
|
} |
|
} |
|
|
|
void KRandRSystemTray::slotSKeys() |
|
{ |
|
ConfigDialog *dlg = new ConfigDialog(globalKeys, true); |
|
|
|
if ( dlg->exec() == TQDialog::Accepted ) { |
|
dlg->commitShortcuts(); |
|
globalKeys->writeSettings(0, true); |
|
globalKeys->updateConnections(); |
|
} |
|
|
|
delete dlg; |
|
} |
|
|
|
void KRandRSystemTray::slotCycleDisplays() |
|
{ |
|
XRROutputInfo *output_info; |
|
char *output_name; |
|
int i; |
|
int current_on_index = -1; |
|
int max_index = -1; |
|
int prev_on_index; |
|
|
|
randr_screen_info = read_screen_info(randr_display); |
|
|
|
for (i = 0; i < randr_screen_info->n_output; i++) { |
|
output_info = randr_screen_info->outputs[i]->info; |
|
// Look for ON outputs... |
|
if (!randr_screen_info->outputs[i]->cur_crtc) { |
|
continue; |
|
} |
|
// ...that are connected |
|
if (RR_Disconnected == randr_screen_info->outputs[i]->info->connection) { |
|
continue; |
|
} |
|
|
|
output_name = output_info->name; |
|
current_on_index = i; |
|
if (i > max_index) { |
|
max_index = i; |
|
} |
|
} |
|
|
|
for (i = 0; i < randr_screen_info->n_output; i++) { |
|
output_info = randr_screen_info->outputs[i]->info; |
|
// Look for CONNECTED outputs.... |
|
if (RR_Disconnected == randr_screen_info->outputs[i]->info->connection) { |
|
continue; |
|
} |
|
// ...that are not ON |
|
if (randr_screen_info->outputs[i]->cur_crtc) { |
|
continue; |
|
} |
|
|
|
output_name = output_info->name; |
|
if (i > max_index) { |
|
max_index = i; |
|
} |
|
} |
|
|
|
for (i = 0; i < randr_screen_info->n_output; i++) { |
|
output_info = randr_screen_info->outputs[i]->info; |
|
// Look for ALL outputs that are not connected.... |
|
if (RR_Disconnected != randr_screen_info->outputs[i]->info->connection) { |
|
continue; |
|
} |
|
// ...or ON |
|
if (randr_screen_info->outputs[i]->cur_crtc) { |
|
continue; |
|
} |
|
|
|
output_name = output_info->name; |
|
if (i > max_index) { |
|
max_index = i; |
|
} |
|
} |
|
|
|
//printf("Active: %d\n", current_on_index); |
|
//printf("Max: %d\n", max_index); |
|
|
|
if ((current_on_index == -1) && (max_index == -1)) { |
|
// There is no connected display available! ABORT |
|
return; |
|
} |
|
|
|
prev_on_index = current_on_index; |
|
current_on_index = current_on_index + 1; |
|
if (current_on_index > max_index) { |
|
current_on_index = 0; |
|
} |
|
while (RR_Disconnected == randr_screen_info->outputs[current_on_index]->info->connection) { |
|
current_on_index = current_on_index + 1; |
|
if (current_on_index > max_index) { |
|
current_on_index = 0; |
|
} |
|
} |
|
if (prev_on_index != current_on_index) { |
|
randr_screen_info->cur_crtc = randr_screen_info->outputs[current_on_index]->cur_crtc; |
|
randr_screen_info->cur_output = randr_screen_info->outputs[current_on_index]; |
|
randr_screen_info->cur_output->auto_set = 1; |
|
randr_screen_info->cur_output->off_set = 0; |
|
output_auto (randr_screen_info, randr_screen_info->cur_output); |
|
i=main_low_apply(randr_screen_info); |
|
|
|
if (randr_screen_info->outputs[current_on_index]->cur_crtc) { |
|
// Output successfully activated! |
|
set_primary_output(randr_screen_info, randr_screen_info->cur_output->id); |
|
|
|
if (prev_on_index != -1) { |
|
if (randr_screen_info->outputs[prev_on_index]->cur_crtc != NULL) { |
|
if (RR_Disconnected != randr_screen_info->outputs[prev_on_index]->info->connection) { |
|
randr_screen_info->cur_crtc = randr_screen_info->outputs[prev_on_index]->cur_crtc; |
|
randr_screen_info->cur_output = randr_screen_info->outputs[prev_on_index]; |
|
randr_screen_info->cur_output->auto_set = 0; |
|
randr_screen_info->cur_output->off_set = 1; |
|
output_off(randr_screen_info, randr_screen_info->cur_output); |
|
i=main_low_apply(randr_screen_info); |
|
} |
|
} |
|
} |
|
|
|
// Do something about the disconnected outputs |
|
for (i = 0; i < randr_screen_info->n_output; i++) { |
|
output_info = randr_screen_info->outputs[i]->info; |
|
// Look for ON outputs |
|
if (!randr_screen_info->outputs[i]->cur_crtc) { |
|
continue; |
|
} |
|
if (RR_Disconnected != randr_screen_info->outputs[i]->info->connection) { |
|
continue; |
|
} |
|
|
|
output_name = output_info->name; |
|
|
|
// Deactivate this display to avoid a crash! |
|
randr_screen_info->cur_crtc = randr_screen_info->outputs[i]->cur_crtc; |
|
randr_screen_info->cur_output = randr_screen_info->outputs[i]; |
|
randr_screen_info->cur_output->auto_set = 0; |
|
randr_screen_info->cur_output->off_set = 1; |
|
output_off(randr_screen_info, randr_screen_info->cur_output); |
|
main_low_apply(randr_screen_info); |
|
} |
|
|
|
findPrimaryDisplay(); |
|
refresh(); |
|
|
|
currentScreen()->proposeSize(GetDefaultResolutionParameter()); |
|
currentScreen()->applyProposed(); |
|
} |
|
else { |
|
output_name = randr_screen_info->outputs[current_on_index]->info->name; |
|
KMessageBox::sorry(my_parent, i18n("<b>Unable to activate output %1</b><p>Either the output is not connected to a display,<br>or the display configuration is not detectable").arg(output_name), i18n("Output Unavailable")); |
|
} |
|
} |
|
} |
|
|
|
void KRandRSystemTray::findPrimaryDisplay() |
|
{ |
|
int i; |
|
|
|
for (i = 0; i < randr_screen_info->n_output; i++) { |
|
// Look for ON outputs... |
|
if (!randr_screen_info->outputs[i]->cur_crtc) { |
|
continue; |
|
} |
|
|
|
// ...that are connected |
|
if (RR_Disconnected == randr_screen_info->outputs[i]->info->connection) { |
|
continue; |
|
} |
|
|
|
randr_screen_info->cur_crtc = randr_screen_info->outputs[i]->cur_crtc; |
|
randr_screen_info->cur_output = randr_screen_info->outputs[i]; |
|
} |
|
} |
|
|
|
void KRandRSystemTray::addOutputMenu(TDEPopupMenu* menu) |
|
{ |
|
XRROutputInfo *output_info; |
|
char *output_name; |
|
int i; |
|
int lastIndex = 0; |
|
int connected_displays = 0; |
|
|
|
if (isValid() == true) { |
|
menu->insertTitle(SmallIcon("kcmkwm"), i18n("Output Port")); |
|
|
|
for (i = 0; i < randr_screen_info->n_output; i++) { |
|
output_info = randr_screen_info->outputs[i]->info; |
|
// Look for ON outputs |
|
if (!randr_screen_info->outputs[i]->cur_crtc) { |
|
continue; |
|
} |
|
if (RR_Disconnected == randr_screen_info->outputs[i]->info->connection) { |
|
continue; |
|
} |
|
|
|
output_name = output_info->name; |
|
//printf("ON: Found output %s\n", output_name); |
|
|
|
lastIndex = menu->insertItem(i18n("%1 (Active)").arg(output_name)); |
|
menu->setItemChecked(lastIndex, true); |
|
menu->connectItem(lastIndex, this, TQT_SLOT(slotOutputChanged(int))); |
|
menu->setItemParameter(lastIndex, i); |
|
|
|
connected_displays++; |
|
} |
|
|
|
for (i = 0; i < randr_screen_info->n_output; i++) { |
|
output_info = randr_screen_info->outputs[i]->info; |
|
// Look for CONNECTED outputs.... |
|
if (RR_Disconnected == randr_screen_info->outputs[i]->info->connection) { |
|
continue; |
|
} |
|
// ...that are not ON |
|
if (randr_screen_info->outputs[i]->cur_crtc) { |
|
continue; |
|
} |
|
|
|
output_name = output_info->name; |
|
//printf("CONNECTED, NOT ON: Found output %s\n", output_name); |
|
|
|
lastIndex = menu->insertItem(i18n("%1 (Connected, Inactive)").arg(output_name)); |
|
menu->setItemChecked(lastIndex, false); |
|
menu->connectItem(lastIndex, this, TQT_SLOT(slotOutputChanged(int))); |
|
menu->setItemParameter(lastIndex, i); |
|
|
|
connected_displays++; |
|
} |
|
|
|
for (i = 0; i < randr_screen_info->n_output; i++) { |
|
output_info = randr_screen_info->outputs[i]->info; |
|
// Look for ALL outputs that are not connected.... |
|
if (RR_Disconnected != randr_screen_info->outputs[i]->info->connection) { |
|
continue; |
|
} |
|
// ...or ON |
|
if (randr_screen_info->outputs[i]->cur_crtc) { |
|
continue; |
|
} |
|
|
|
output_name = output_info->name; |
|
//printf("DISCONNECTED, NOT ON: Found output %s\n", output_name); |
|
|
|
lastIndex = menu->insertItem(i18n("%1 (Disconnected, Inactive)").arg(output_name)); |
|
menu->setItemChecked(lastIndex, false); |
|
menu->setItemEnabled(lastIndex, false); |
|
menu->connectItem(lastIndex, this, TQT_SLOT(slotOutputChanged(int))); |
|
menu->setItemParameter(lastIndex, i); |
|
} |
|
|
|
lastIndex = menu->insertItem(SmallIcon("forward"), i18n("Next available output")); |
|
if (connected_displays < 2) { |
|
menu->setItemEnabled(lastIndex, false); |
|
} |
|
menu->connectItem(lastIndex, this, TQT_SLOT(slotCycleDisplays())); |
|
} |
|
} |
|
|
|
void KRandRSystemTray::slotColorProfileChanged(int parameter) |
|
{ |
|
t_config->writeEntry("CurrentProfile", m_menu->text(parameter)); |
|
applyIccConfiguration(m_menu->text(parameter), NULL); |
|
} |
|
|
|
void KRandRSystemTray::slotDisplayProfileChanged(int parameter) |
|
{ |
|
TQString profileName = m_menu->text(parameter); |
|
if (profileName == "<default>") { |
|
profileName = ""; |
|
} |
|
TQPtrList<SingleScreenData> profileData = loadDisplayConfiguration(profileName, locateLocal("config", "/", true)); |
|
applyDisplayConfiguration(profileData, TRUE, locateLocal("config", "/", true)); |
|
destroyScreenInformationObject(profileData); |
|
} |
|
|
|
void KRandRSystemTray::slotOutputChanged(int parameter) |
|
{ |
|
char *output_name; |
|
int i; |
|
int num_outputs_on; |
|
|
|
num_outputs_on = 0; |
|
for (i = 0; i < randr_screen_info->n_output; i++) { |
|
// Look for ON outputs |
|
if (!randr_screen_info->outputs[i]->cur_crtc) { |
|
continue; |
|
} |
|
|
|
num_outputs_on++; |
|
} |
|
|
|
if (!randr_screen_info->outputs[parameter]->cur_crtc) { |
|
//printf("Screen was off, turning it on...\n"); |
|
|
|
randr_screen_info->cur_crtc = randr_screen_info->outputs[parameter]->cur_crtc; |
|
randr_screen_info->cur_output = randr_screen_info->outputs[parameter]; |
|
randr_screen_info->cur_output->auto_set = 1; |
|
randr_screen_info->cur_output->off_set = 0; |
|
output_auto (randr_screen_info, randr_screen_info->cur_output); |
|
i=main_low_apply(randr_screen_info); |
|
|
|
if (!randr_screen_info->outputs[parameter]->cur_crtc) { |
|
output_name = randr_screen_info->outputs[parameter]->info->name; |
|
KMessageBox::sorry(my_parent, i18n("<b>Unable to activate output %1</b><p>Either the output is not connected to a display,<br>or the display configuration is not detectable").arg(output_name), i18n("Output Unavailable")); |
|
} |
|
} |
|
else { |
|
if (num_outputs_on > 1) { |
|
//printf("Screen was on, turning it off...\n"); |
|
randr_screen_info->cur_crtc = randr_screen_info->outputs[parameter]->cur_crtc; |
|
randr_screen_info->cur_output = randr_screen_info->outputs[parameter]; |
|
randr_screen_info->cur_output->auto_set = 0; |
|
randr_screen_info->cur_output->off_set = 1; |
|
output_off(randr_screen_info, randr_screen_info->cur_output); |
|
i=main_low_apply(randr_screen_info); |
|
|
|
findPrimaryDisplay(); |
|
refresh(); |
|
|
|
currentScreen()->proposeSize(GetDefaultResolutionParameter()); |
|
currentScreen()->applyProposed(); |
|
} |
|
else { |
|
KMessageBox::sorry(my_parent, i18n("<b>You are attempting to deactivate the only active output</b><p>You must keep at least one display output active at all times!"), i18n("Invalid Operation Requested")); |
|
} |
|
} |
|
} |
|
|
|
void KRandRSystemTray::deviceChanged (TDEGenericDevice* device) { |
|
#ifdef WITH_TDEHWLIB |
|
if (device->type() == TDEGenericDeviceType::Monitor) { |
|
KRandrPassivePopup::message( |
|
i18n("New display output options are available!"), |
|
i18n("A screen has been added, removed, or changed"), SmallIcon("view-fullscreen"), |
|
this, "ScreenChangeNotification"); |
|
|
|
reloadDisplayConfiguration(); |
|
applyHotplugRules(locateLocal("config", "/", true)); |
|
} |
|
#endif |
|
} |
|
|
|
void KRandRSystemTray::slotHelpContents() |
|
{ |
|
kapp->invokeHelp(TQString::null, "tderandrtray"); |
|
} |
|
|
|
|