Add monitor hotplug notification support to TDE hardware devices library

Fix spurious xcalib pipe error notifications
Fix krandr available resolution detection
pull/16/head
Timothy Pearson 12 years ago
parent 5117798410
commit e9b3f195e2

@ -285,6 +285,8 @@ extern "C" KDE_EXPORT int kdemain(int _argc, char *_argv[])
//KDialogBase::DialogType dtype = KDialogBase::Plain; // FIXME //KDialogBase::DialogType dtype = KDialogBase::Plain; // FIXME
KDialogBase::DialogType dtype = KDialogBase::IconList; // Work around a bug whereby several kcontrol modules (such as displayconfig) use an incorrect size when loaded with kcmshell in the Plain mode KDialogBase::DialogType dtype = KDialogBase::IconList; // Work around a bug whereby several kcontrol modules (such as displayconfig) use an incorrect size when loaded with kcmshell in the Plain mode
// This bug is possibly related to kcmultidialog.cpp:266 [( new TQHBoxLayout( page ) )->setAutoAdd( true );] // This bug is possibly related to kcmultidialog.cpp:266 [( new TQHBoxLayout( page ) )->setAutoAdd( true );]
// In fact, this method of display may be preferable to the Plain mode from a UX perspective,
// as the icon shows the user what the active kcontrol module is called.
if ( modules.count() < 1 ) if ( modules.count() < 1 )
return 0; return 0;

@ -177,7 +177,7 @@ TQString KRandrSimpleAPI::applyIccFile(TQString screenName, TQString fileName) {
icc_command = TQString("xcalib \"%1\"").arg(fileName); icc_command = TQString("xcalib \"%1\"").arg(fileName);
if ((pipe_xcalib = popen(icc_command.ascii(), "r")) == NULL) if ((pipe_xcalib = popen(icc_command.ascii(), "r")) == NULL)
{ {
printf("Xcalib pipe error\n\r"); printf("Xcalib pipe error\n\r [xcalib apply]");
} }
else { else {
if (fgets(xcalib_result, 2048, pipe_xcalib)) { if (fgets(xcalib_result, 2048, pipe_xcalib)) {
@ -193,7 +193,7 @@ TQString KRandrSimpleAPI::applyIccFile(TQString screenName, TQString fileName) {
} }
} }
else { else {
printf("Xcalib pipe error\n\r"); return "";
} }
} }
} }
@ -246,7 +246,7 @@ TQString KRandrSimpleAPI::applyIccFile(TQString screenName, TQString fileName) {
icc_command = TQString("xcalib -c"); icc_command = TQString("xcalib -c");
if ((pipe_xcalib = popen(icc_command.ascii(), "r")) == NULL) if ((pipe_xcalib = popen(icc_command.ascii(), "r")) == NULL)
{ {
printf("Xcalib pipe error\n\r"); printf("Xcalib pipe error\n\r [xcalib clear]");
} }
else { else {
if (fgets(xcalib_result, 2048, pipe_xcalib)) { if (fgets(xcalib_result, 2048, pipe_xcalib)) {
@ -262,7 +262,7 @@ TQString KRandrSimpleAPI::applyIccFile(TQString screenName, TQString fileName) {
} }
} }
else { else {
printf("Xcalib pipe error\n\r"); return "";
} }
} }
} }
@ -401,7 +401,7 @@ TQString KRandrSimpleAPI::applySystemWideIccConfiguration(TQString kde_confdir)
icc_command = TQString("xcalib \"%1\"").arg(getIccFileName(NULL, "Default", kde_confdir)); icc_command = TQString("xcalib \"%1\"").arg(getIccFileName(NULL, "Default", kde_confdir));
if ((pipe_xcalib = popen(icc_command.ascii(), "r")) == NULL) if ((pipe_xcalib = popen(icc_command.ascii(), "r")) == NULL)
{ {
printf("Xcalib pipe error\n\r"); printf("Xcalib pipe error [xcalib apply]\n\r");
} }
else { else {
if (fgets(xcalib_result, 2048, pipe_xcalib)) { if (fgets(xcalib_result, 2048, pipe_xcalib)) {
@ -417,7 +417,7 @@ TQString KRandrSimpleAPI::applySystemWideIccConfiguration(TQString kde_confdir)
} }
} }
else { else {
printf("Xcalib pipe error\n\r"); return "";
} }
} }
return ""; return "";
@ -569,16 +569,16 @@ TQPtrList<SingleScreenData> KRandrSimpleAPI::loadSystemwideDisplayConfiguration(
int KRandrSimpleAPI::getHardwareRotationFlags(SingleScreenData* screendata) { int KRandrSimpleAPI::getHardwareRotationFlags(SingleScreenData* screendata) {
int rotationFlags = 0; int rotationFlags = 0;
TQString rotationDesired = *screendata->rotations.at(screendata->current_rotation_index); TQString rotationDesired = *screendata->rotations.at(screendata->current_rotation_index);
if (rotationDesired == "Normal") { if (rotationDesired == ROTATION_0_DEGREES_STRING) {
rotationFlags = rotationFlags | RandRScreen::Rotate0; rotationFlags = rotationFlags | RandRScreen::Rotate0;
} }
else if (rotationDesired == "Rotate 90 degrees") { else if (rotationDesired == ROTATION_90_DEGREES_STRING) {
rotationFlags = rotationFlags | RandRScreen::Rotate90; rotationFlags = rotationFlags | RandRScreen::Rotate90;
} }
else if (rotationDesired == "Rotate 180 degrees") { else if (rotationDesired == ROTATION_180_DEGREES_STRING) {
rotationFlags = rotationFlags | RandRScreen::Rotate180; rotationFlags = rotationFlags | RandRScreen::Rotate180;
} }
else if (rotationDesired == "Rotate 270 degrees") { else if (rotationDesired == ROTATION_270_DEGREES_STRING) {
rotationFlags = rotationFlags | RandRScreen::Rotate270; rotationFlags = rotationFlags | RandRScreen::Rotate270;
} }
if (screendata->has_x_flip) { if (screendata->has_x_flip) {
@ -658,21 +658,6 @@ bool KRandrSimpleAPI::applySystemwideDisplayConfiguration(TQPtrList<SingleScreen
return accepted; return accepted;
} }
} }
// HACK
// This is needed because Qt does not properly generate screen
// resize events when switching screens, so KDE gets stuck in the old resolution
// This only seems to happen with more than one screen, so check for that condition...
// FIXME: This also only occurs when the primary display has been changed
// FIXME: Check for that condition as well!
if (kapp->desktop()->numScreens() > 1) {
for (i = 0; i < screenInfoArray.count(); i++) {
screendata = screenInfoArray.at(i);
if (screendata->is_primary == true) {
kapp->desktop()->emitResizedSignal(i);
}
}
}
#else #else
randr_display = tqt_xdisplay(); randr_display = tqt_xdisplay();
randr_screen_info = read_screen_info(randr_display); randr_screen_info = read_screen_info(randr_display);
@ -804,8 +789,9 @@ void KRandrSimpleAPI::ensureMonitorDataConsistency(TQPtrList<SingleScreenData> s
bool has_primary_monitor = false; bool has_primary_monitor = false;
for (i=0;i<numberOfScreens;i++) { for (i=0;i<numberOfScreens;i++) {
screendata = screenInfoArray.at(i); screendata = screenInfoArray.at(i);
if (screendata->is_primary) if (screendata->is_primary) {
has_primary_monitor = true; has_primary_monitor = true;
}
} }
if (!has_primary_monitor) { if (!has_primary_monitor) {
for (i=0;i<numberOfScreens;i++) { for (i=0;i<numberOfScreens;i++) {
@ -1117,10 +1103,10 @@ TQPtrList<SingleScreenData> KRandrSimpleAPI::readCurrentDisplayConfiguration() {
// RandRScreen::ReflectX // RandRScreen::ReflectX
// RandRScreen::ReflectY // RandRScreen::ReflectY
screendata->rotations.append(i18n("Normal")); screendata->rotations.append(i18n(ROTATION_0_DEGREES_STRING));
screendata->rotations.append(i18n("Rotate 90 degrees")); screendata->rotations.append(i18n(ROTATION_90_DEGREES_STRING));
screendata->rotations.append(i18n("Rotate 180 degrees")); screendata->rotations.append(i18n(ROTATION_180_DEGREES_STRING));
screendata->rotations.append(i18n("Rotate 270 degrees")); screendata->rotations.append(i18n(ROTATION_270_DEGREES_STRING));
screendata->supports_transformations = (cur_screen->rotations() != RandRScreen::Rotate0); screendata->supports_transformations = (cur_screen->rotations() != RandRScreen::Rotate0);
if (screendata->supports_transformations) { if (screendata->supports_transformations) {
screendata->current_orientation_mask = cur_screen->proposedRotation(); screendata->current_orientation_mask = cur_screen->proposedRotation();
@ -1154,13 +1140,16 @@ TQPtrList<SingleScreenData> KRandrSimpleAPI::readCurrentDisplayConfiguration() {
// Determine if this display is primary and/or extended // Determine if this display is primary and/or extended
RROutput primaryoutput = XRRGetOutputPrimary(tqt_xdisplay(), DefaultRootWindow(tqt_xdisplay())); RROutput primaryoutput = XRRGetOutputPrimary(tqt_xdisplay(), DefaultRootWindow(tqt_xdisplay()));
if (primaryoutput == randr_screen_info->outputs[i]->id) if (primaryoutput == randr_screen_info->outputs[i]->id) {
screendata->is_primary = false; screendata->is_primary = false;
else }
else {
screendata->is_primary = true; screendata->is_primary = true;
}
screendata->is_extended = screen_active; screendata->is_extended = screen_active;
if (!screendata->is_extended) if (!screendata->is_extended) {
screendata->is_primary = false; screendata->is_primary = false;
}
// Get this screen's absolute position // Get this screen's absolute position
screendata->absolute_x_position = 0; screendata->absolute_x_position = 0;
@ -1277,10 +1266,21 @@ TQPtrList<SingleScreenData> KRandrSimpleAPI::readCurrentDisplayConfiguration() {
numberOfScreens++; numberOfScreens++;
} }
// [FIXME] bool primary_set = false;
// Set this on the real primary monitor only! for ( screendata=screenInfoArray.first(); screendata; screendata=screenInfoArray.next() ) {
screendata = screenInfoArray.at(0); if (screendata->is_primary) {
screendata->is_primary = true; primary_set = true;
break;
}
}
// If there is no primary monitor set, xrandr is probably not functioning correctly!
Q_ASSERT(primary_set);
if (!primary_set) {
// [FIXME]
// Set this on the real primary monitor only!
screendata = screenInfoArray.at(0);
screendata->is_primary = true;
}
return screenInfoArray; return screenInfoArray;
} }
@ -1296,7 +1296,7 @@ TQString KRandrSimpleAPI::clearIccConfiguration() {
icc_command = TQString("xcalib -c"); icc_command = TQString("xcalib -c");
if ((pipe_xcalib = popen(icc_command.ascii(), "r")) == NULL) if ((pipe_xcalib = popen(icc_command.ascii(), "r")) == NULL)
{ {
printf("Xcalib pipe error\n\r"); printf("Xcalib pipe error [xcalib clear]\n\r");
} }
else { else {
if (fgets(xcalib_result, 2048, pipe_xcalib)) { if (fgets(xcalib_result, 2048, pipe_xcalib)) {
@ -1312,7 +1312,7 @@ TQString KRandrSimpleAPI::clearIccConfiguration() {
} }
} }
else { else {
printf("Xcalib pipe error\n\r"); return "";
} }
} }
return ""; return "";
@ -1388,6 +1388,11 @@ int KRandrSimpleAPI::main_low_apply (ScreenInfo *screen_info)
return internal_main_low_apply (screen_info); return internal_main_low_apply (screen_info);
} }
void KRandrSimpleAPI::set_primary_output (ScreenInfo *screen_info, RROutput output_id)
{
internal_output_set_primary(screen_info, output_id);
}
bool KRandrSimpleAPI::kRandrHasRandr(void) bool KRandrSimpleAPI::kRandrHasRandr(void)
{ {
return isValid(); return isValid();

@ -35,6 +35,11 @@
#include <ksimpleconfig.h> #include <ksimpleconfig.h>
#include <tdelibs_export.h> #include <tdelibs_export.h>
#define ROTATION_0_DEGREES_STRING "0 degrees"
#define ROTATION_90_DEGREES_STRING "90 degrees"
#define ROTATION_180_DEGREES_STRING "180 degrees"
#define ROTATION_270_DEGREES_STRING "270 degrees"
/** /**
* Simple API covering most of the uses of libkrandr. * Simple API covering most of the uses of libkrandr.
* *
@ -158,6 +163,11 @@ class KRANDR_EXPORT KRandrSimpleAPI : public RandRDisplay
*/ */
int main_low_apply (ScreenInfo *screen_info); int main_low_apply (ScreenInfo *screen_info);
/**
* Sets the primary output device to the specified output_id
*/
void set_primary_output (ScreenInfo *screen_info, RROutput output_id);
/** /**
* Gets the binary monitor EDID for the specified card and display * Gets the binary monitor EDID for the specified card and display
*/ */

@ -673,3 +673,8 @@ void internal_output_off (struct ScreenInfo *screen_info, struct OutputInfo *out
screen_info->cur_crtc = NULL; screen_info->cur_crtc = NULL;
output->off_set = 1; output->off_set = 1;
} }
void internal_output_set_primary (struct ScreenInfo *screen_info, RROutput output_id)
{
XRRSetOutputPrimary(screen_info->dpy, screen_info->window, output_id);
}

@ -85,6 +85,7 @@ struct ScreenInfo* internal_read_screen_info (Display *);
int internal_set_screen_size (struct ScreenInfo *screen_info); int internal_set_screen_size (struct ScreenInfo *screen_info);
void internal_output_auto (struct ScreenInfo *screen_info, struct OutputInfo *output_info); void internal_output_auto (struct ScreenInfo *screen_info, struct OutputInfo *output_info);
void internal_output_off (struct ScreenInfo *screen_info, struct OutputInfo *output); void internal_output_off (struct ScreenInfo *screen_info, struct OutputInfo *output);
void internal_output_set_primary (struct ScreenInfo *screen_info, RROutput output_id);
struct CrtcInfo* internal_auto_find_crtc (struct ScreenInfo *screen_info, struct OutputInfo *output_info); struct CrtcInfo* internal_auto_find_crtc (struct ScreenInfo *screen_info, struct OutputInfo *output_info);
XRRModeInfo *internal_find_mode_by_xid (struct ScreenInfo *screen_info, RRMode mode_id); XRRModeInfo *internal_find_mode_by_xid (struct ScreenInfo *screen_info, RRMode mode_id);

@ -85,8 +85,9 @@ public:
RandRScreenPrivate() : config(0L) {}; RandRScreenPrivate() : config(0L) {};
~RandRScreenPrivate() ~RandRScreenPrivate()
{ {
if (config) if (config) {
XRRFreeScreenConfigInfo(config); XRRFreeScreenConfigInfo(config);
}
} }
XRRScreenConfiguration* config; XRRScreenConfiguration* config;
@ -108,8 +109,9 @@ KDE_EXPORT RandRScreen::~RandRScreen()
KDE_EXPORT void RandRScreen::loadSettings() KDE_EXPORT void RandRScreen::loadSettings()
{ {
if (d->config) if (d->config) {
XRRFreeScreenConfigInfo(d->config); XRRFreeScreenConfigInfo(d->config);
}
d->config = XRRGetScreenInfo(tqt_xdisplay(), RootWindow(tqt_xdisplay(), m_screen)); d->config = XRRGetScreenInfo(tqt_xdisplay(), RootWindow(tqt_xdisplay(), m_screen));
@ -141,9 +143,11 @@ KDE_EXPORT void RandRScreen::loadSettings()
ScreenInfo *screeninfo = internal_read_screen_info(tqt_xdisplay()); ScreenInfo *screeninfo = internal_read_screen_info(tqt_xdisplay());
XRROutputInfo *output_info = screeninfo->outputs[m_screen]->info; XRROutputInfo *output_info = screeninfo->outputs[m_screen]->info;
CrtcInfo *current_crtc = screeninfo->outputs[m_screen]->cur_crtc; CrtcInfo *current_crtc = screeninfo->outputs[m_screen]->cur_crtc;
int numSizes = screeninfo->res->nmode; int numSizes = output_info->nmode;
for (int i = 0; i < numSizes; i++) { for (int i = 0; i < numSizes; i++) {
TQSize newSize = TQSize(screeninfo->res->modes[i].width, screeninfo->res->modes[i].height); XRRModeInfo *xrrmode;
xrrmode = internal_find_mode_by_xid (screeninfo, output_info->modes[i]);
TQSize newSize = TQSize(xrrmode->width, xrrmode->height);
if (!m_pixelSizes.contains(newSize)) { if (!m_pixelSizes.contains(newSize)) {
m_pixelSizes.append(newSize); m_pixelSizes.append(newSize);
m_mmSizes.append(TQSize(output_info->mm_width, output_info->mm_height)); m_mmSizes.append(TQSize(output_info->mm_width, output_info->mm_height));

@ -195,9 +195,10 @@ KCModule * KCModuleProxy::realModule() const
d->topLayout->addWidget( d->kcm ); d->topLayout->addWidget( d->kcm );
if ( !d->rootInfo && /* If it's already done */ if ( !d->rootInfo && /* If the message was not yet created */
moduleInfo().needsRootPrivileges() /* root, anyone? */ && d->kcm->useRootOnlyMsg() /* and the module requests the message */ &&
!KUser().isSuperUser() ) /* Not necessary if we're root */ moduleInfo().needsRootPrivileges() /* and the module wants root access */ &&
!KUser().isSuperUser() ) /* and we are not currently root */
{ {
d->rootInfo = new TQLabel( that, "rootInfo" ); d->rootInfo = new TQLabel( that, "rootInfo" );

@ -2002,7 +2002,18 @@ void TDEHardwareDevices::processHotPluggedHardware() {
emit hardwareUpdated(hwdevice); emit hardwareUpdated(hwdevice);
emit hardwareEvent(TDEHardwareEvent::HardwareUpdated, hwdevice->uniqueID()); emit hardwareEvent(TDEHardwareEvent::HardwareUpdated, hwdevice->uniqueID());
} }
break; }
else if ((hwdevice->type() == TDEGenericDeviceType::Monitor)
&& (hwdevice->systemPath().contains(systempath))) {
if (!hwdevice->blacklistedForUpdate()) {
struct udev_device *slavedev;
slavedev = udev_device_new_from_syspath(m_udevStruct, hwdevice->systemPath().ascii());
classifyUnknownDevice(slavedev, hwdevice, false);
udev_device_unref(slavedev);
updateParentDeviceInformation(hwdevice); // Update parent/child tables for this device
emit hardwareUpdated(hwdevice);
emit hardwareEvent(TDEHardwareEvent::HardwareUpdated, hwdevice->uniqueID());
}
} }
} }
} }
@ -4289,6 +4300,9 @@ TDEGenericDevice* TDEHardwareDevices::classifyUnknownDevice(udev_device* dev, TD
mdevice->internalSetVendorModel(monitor_info.second); mdevice->internalSetVendorModel(monitor_info.second);
mdevice->m_friendlyName = monitor_info.first + " " + monitor_info.second; mdevice->m_friendlyName = monitor_info.first + " " + monitor_info.second;
} }
else {
mdevice->m_friendlyName = i18n("Generic %1 Device").arg(genericPortName);
}
mdevice->internalSetEdid(getEDID(mdevice->systemPath())); mdevice->internalSetEdid(getEDID(mdevice->systemPath()));
} }
else { else {

Loading…
Cancel
Save