From e9b3f195e2d568e25b8b73810503518e4e7f8480 Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Wed, 9 Jan 2013 16:37:06 -0600 Subject: [PATCH] Add monitor hotplug notification support to TDE hardware devices library Fix spurious xcalib pipe error notifications Fix krandr available resolution detection --- kcmshell/main.cpp | 2 + krandr/libkrandr.cc | 83 ++++++++++++++++++---------------- krandr/libkrandr.h | 10 ++++ krandr/lowlevel_randr.c | 5 ++ krandr/lowlevel_randr.h | 1 + krandr/randr.cpp | 12 +++-- kutils/kcmoduleproxy.cpp | 7 +-- tdecore/tdehardwaredevices.cpp | 16 ++++++- 8 files changed, 89 insertions(+), 47 deletions(-) diff --git a/kcmshell/main.cpp b/kcmshell/main.cpp index 22e42fda3..902b2397f 100644 --- a/kcmshell/main.cpp +++ b/kcmshell/main.cpp @@ -285,6 +285,8 @@ extern "C" KDE_EXPORT int kdemain(int _argc, char *_argv[]) //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 // 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 ) return 0; diff --git a/krandr/libkrandr.cc b/krandr/libkrandr.cc index 0ac816b48..79faa9a88 100644 --- a/krandr/libkrandr.cc +++ b/krandr/libkrandr.cc @@ -177,7 +177,7 @@ TQString KRandrSimpleAPI::applyIccFile(TQString screenName, TQString fileName) { icc_command = TQString("xcalib \"%1\"").arg(fileName); if ((pipe_xcalib = popen(icc_command.ascii(), "r")) == NULL) { - printf("Xcalib pipe error\n\r"); + printf("Xcalib pipe error\n\r [xcalib apply]"); } else { if (fgets(xcalib_result, 2048, pipe_xcalib)) { @@ -193,7 +193,7 @@ TQString KRandrSimpleAPI::applyIccFile(TQString screenName, TQString fileName) { } } else { - printf("Xcalib pipe error\n\r"); + return ""; } } } @@ -246,7 +246,7 @@ TQString KRandrSimpleAPI::applyIccFile(TQString screenName, TQString fileName) { icc_command = TQString("xcalib -c"); if ((pipe_xcalib = popen(icc_command.ascii(), "r")) == NULL) { - printf("Xcalib pipe error\n\r"); + printf("Xcalib pipe error\n\r [xcalib clear]"); } else { if (fgets(xcalib_result, 2048, pipe_xcalib)) { @@ -262,7 +262,7 @@ TQString KRandrSimpleAPI::applyIccFile(TQString screenName, TQString fileName) { } } 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)); if ((pipe_xcalib = popen(icc_command.ascii(), "r")) == NULL) { - printf("Xcalib pipe error\n\r"); + printf("Xcalib pipe error [xcalib apply]\n\r"); } else { if (fgets(xcalib_result, 2048, pipe_xcalib)) { @@ -417,7 +417,7 @@ TQString KRandrSimpleAPI::applySystemWideIccConfiguration(TQString kde_confdir) } } else { - printf("Xcalib pipe error\n\r"); + return ""; } } return ""; @@ -569,16 +569,16 @@ TQPtrList KRandrSimpleAPI::loadSystemwideDisplayConfiguration( int KRandrSimpleAPI::getHardwareRotationFlags(SingleScreenData* screendata) { int rotationFlags = 0; TQString rotationDesired = *screendata->rotations.at(screendata->current_rotation_index); - if (rotationDesired == "Normal") { + if (rotationDesired == ROTATION_0_DEGREES_STRING) { rotationFlags = rotationFlags | RandRScreen::Rotate0; } - else if (rotationDesired == "Rotate 90 degrees") { + else if (rotationDesired == ROTATION_90_DEGREES_STRING) { rotationFlags = rotationFlags | RandRScreen::Rotate90; } - else if (rotationDesired == "Rotate 180 degrees") { + else if (rotationDesired == ROTATION_180_DEGREES_STRING) { rotationFlags = rotationFlags | RandRScreen::Rotate180; } - else if (rotationDesired == "Rotate 270 degrees") { + else if (rotationDesired == ROTATION_270_DEGREES_STRING) { rotationFlags = rotationFlags | RandRScreen::Rotate270; } if (screendata->has_x_flip) { @@ -658,21 +658,6 @@ bool KRandrSimpleAPI::applySystemwideDisplayConfiguration(TQPtrListdesktop()->numScreens() > 1) { - for (i = 0; i < screenInfoArray.count(); i++) { - screendata = screenInfoArray.at(i); - if (screendata->is_primary == true) { - kapp->desktop()->emitResizedSignal(i); - } - } - } #else randr_display = tqt_xdisplay(); randr_screen_info = read_screen_info(randr_display); @@ -804,8 +789,9 @@ void KRandrSimpleAPI::ensureMonitorDataConsistency(TQPtrList s bool has_primary_monitor = false; for (i=0;iis_primary) + if (screendata->is_primary) { has_primary_monitor = true; + } } if (!has_primary_monitor) { for (i=0;i KRandrSimpleAPI::readCurrentDisplayConfiguration() { // 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->rotations.append(i18n(ROTATION_0_DEGREES_STRING)); + screendata->rotations.append(i18n(ROTATION_90_DEGREES_STRING)); + screendata->rotations.append(i18n(ROTATION_180_DEGREES_STRING)); + screendata->rotations.append(i18n(ROTATION_270_DEGREES_STRING)); screendata->supports_transformations = (cur_screen->rotations() != RandRScreen::Rotate0); if (screendata->supports_transformations) { screendata->current_orientation_mask = cur_screen->proposedRotation(); @@ -1154,13 +1140,16 @@ TQPtrList KRandrSimpleAPI::readCurrentDisplayConfiguration() { // Determine if this display is primary and/or extended 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; - else + } + else { screendata->is_primary = true; + } screendata->is_extended = screen_active; - if (!screendata->is_extended) + if (!screendata->is_extended) { screendata->is_primary = false; + } // Get this screen's absolute position screendata->absolute_x_position = 0; @@ -1277,10 +1266,21 @@ TQPtrList KRandrSimpleAPI::readCurrentDisplayConfiguration() { numberOfScreens++; } - // [FIXME] - // Set this on the real primary monitor only! - screendata = screenInfoArray.at(0); - screendata->is_primary = true; + bool primary_set = false; + for ( screendata=screenInfoArray.first(); screendata; screendata=screenInfoArray.next() ) { + if (screendata->is_primary) { + 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; } @@ -1296,7 +1296,7 @@ TQString KRandrSimpleAPI::clearIccConfiguration() { icc_command = TQString("xcalib -c"); if ((pipe_xcalib = popen(icc_command.ascii(), "r")) == NULL) { - printf("Xcalib pipe error\n\r"); + printf("Xcalib pipe error [xcalib clear]\n\r"); } else { if (fgets(xcalib_result, 2048, pipe_xcalib)) { @@ -1312,7 +1312,7 @@ TQString KRandrSimpleAPI::clearIccConfiguration() { } } else { - printf("Xcalib pipe error\n\r"); + return ""; } } return ""; @@ -1388,6 +1388,11 @@ int KRandrSimpleAPI::main_low_apply (ScreenInfo *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) { return isValid(); diff --git a/krandr/libkrandr.h b/krandr/libkrandr.h index f29383f02..6f03a5c2b 100644 --- a/krandr/libkrandr.h +++ b/krandr/libkrandr.h @@ -35,6 +35,11 @@ #include #include +#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. * @@ -158,6 +163,11 @@ class KRANDR_EXPORT KRandrSimpleAPI : public RandRDisplay */ 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 */ diff --git a/krandr/lowlevel_randr.c b/krandr/lowlevel_randr.c index 251d3bef5..c7a2edc2a 100644 --- a/krandr/lowlevel_randr.c +++ b/krandr/lowlevel_randr.c @@ -673,3 +673,8 @@ void internal_output_off (struct ScreenInfo *screen_info, struct OutputInfo *out screen_info->cur_crtc = NULL; 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); +} \ No newline at end of file diff --git a/krandr/lowlevel_randr.h b/krandr/lowlevel_randr.h index 54538aa44..b5825e450 100644 --- a/krandr/lowlevel_randr.h +++ b/krandr/lowlevel_randr.h @@ -85,6 +85,7 @@ struct ScreenInfo* internal_read_screen_info (Display *); int internal_set_screen_size (struct ScreenInfo *screen_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_set_primary (struct ScreenInfo *screen_info, RROutput output_id); 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); diff --git a/krandr/randr.cpp b/krandr/randr.cpp index 2da9b4520..e118549e2 100644 --- a/krandr/randr.cpp +++ b/krandr/randr.cpp @@ -85,8 +85,9 @@ public: RandRScreenPrivate() : config(0L) {}; ~RandRScreenPrivate() { - if (config) + if (config) { XRRFreeScreenConfigInfo(config); + } } XRRScreenConfiguration* config; @@ -108,8 +109,9 @@ KDE_EXPORT RandRScreen::~RandRScreen() KDE_EXPORT void RandRScreen::loadSettings() { - if (d->config) + if (d->config) { XRRFreeScreenConfigInfo(d->config); + } 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()); XRROutputInfo *output_info = screeninfo->outputs[m_screen]->info; 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++) { - 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)) { m_pixelSizes.append(newSize); m_mmSizes.append(TQSize(output_info->mm_width, output_info->mm_height)); diff --git a/kutils/kcmoduleproxy.cpp b/kutils/kcmoduleproxy.cpp index e0074defe..2323cd262 100644 --- a/kutils/kcmoduleproxy.cpp +++ b/kutils/kcmoduleproxy.cpp @@ -195,9 +195,10 @@ KCModule * KCModuleProxy::realModule() const d->topLayout->addWidget( d->kcm ); - if ( !d->rootInfo && /* If it's already done */ - moduleInfo().needsRootPrivileges() /* root, anyone? */ && - !KUser().isSuperUser() ) /* Not necessary if we're root */ + if ( !d->rootInfo && /* If the message was not yet created */ + d->kcm->useRootOnlyMsg() /* and the module requests the message */ && + moduleInfo().needsRootPrivileges() /* and the module wants root access */ && + !KUser().isSuperUser() ) /* and we are not currently root */ { d->rootInfo = new TQLabel( that, "rootInfo" ); diff --git a/tdecore/tdehardwaredevices.cpp b/tdecore/tdehardwaredevices.cpp index e143e00d5..c0c97679a 100644 --- a/tdecore/tdehardwaredevices.cpp +++ b/tdecore/tdehardwaredevices.cpp @@ -2002,7 +2002,18 @@ void TDEHardwareDevices::processHotPluggedHardware() { emit hardwareUpdated(hwdevice); 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->m_friendlyName = monitor_info.first + " " + monitor_info.second; } + else { + mdevice->m_friendlyName = i18n("Generic %1 Device").arg(genericPortName); + } mdevice->internalSetEdid(getEDID(mdevice->systemPath())); } else {