/*************************************************************************** susehwitem.cpp - description ------------------- copyright : (C) 2002 SUSE AG email : Oliver.Ries@suse.de ***************************************************************************/ /*************************************************************************** * * * 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. * * * ***************************************************************************/ #include #include #include "susehwitem.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "susehwitemhandler.h" #include "susehwpopup.h" #define LOCKFILE "/var/lib/hardware/LOCK" #define YAST2_DEFAULT "kdesu --nonewdcop -- /sbin/yast2" #define SUSEID "X-SUSE-DevID" #define SUSESUBID "X-SUSE-SubID" #define DG "Desktop Entry" str_list_t *search_str_list(str_list_t *sl, char *str) { if (!str) return NULL; for (; sl; sl=sl->next) if (sl->str && !strcmp(sl->str, str)) return sl; return NULL; } /* A macro function to convert HAL string properties to QString */ QString libhal_device_get_property_QString(LibHalContext *ctx, const char* udi, const char *key) { if (udi == 0 || !strlen(udi)) return QString(); char* _ppt_string; QString _ppt_QString; kdDebug() << "libhal_device_get_property_QString() with udi=" << udi << ", and key=" << key << endl; DBusError error; dbus_error_init (&error); if (!libhal_device_property_exists( ctx, udi, key, &error )) return QString(); DBusError anotherError; dbus_error_init (&anotherError); _ppt_string = libhal_device_get_property_string(ctx, udi, key, &anotherError); if (_ppt_string) _ppt_QString = _ppt_string; libhal_free_string(_ppt_string); return _ppt_QString; } bool isConfigured(LibHalContext *halc, const char *udi, const char *parent) { static hd_data_t hd_data; static bool inited_hd = false; if ( !inited_hd ) { memset(&hd_data, 0, sizeof(hd_data)); inited_hd = true; } hd_t *hd = hd_read_config(&hd_data, udi); if (!hd && parent) { kdDebug() << "not found " << udi << endl; QString parent_udi = libhal_device_get_property_QString(halc, udi, parent); if (!parent_udi.isNull()) hd = hd_read_config(&hd_data, parent_udi); } bool conf = false; if ( hd && hd->status.configured != status_new ) conf = true; if (conf) kdDebug() << udi << " is already configured " << endl; return conf; } HWItem::HWItem(LibHalContext *halContext, const QString &udi, QObject *_parent) : QObject( _parent ), m_udi(udi) { m_halContext = halContext; connect(this, SIGNAL(queueDialogforPopup(HWItem *)), _parent, SLOT(queueDialogforPopup(HWItem *))); connect(this, SIGNAL(queuedDialogDone(HWItem * )), _parent, SLOT(queuedDialogDone(HWItem *))); connect(this, SIGNAL(dequeueAll()), _parent, SLOT(dequeueAll())); readConfig(); } bool HWItem::added() { /* We don't deal with devices that do not expose their capabilities. If we don't check this, we will get a lot of warning messages from libhal */ if (!libhal_device_property_exists(m_halContext, m_udi, "info.capabilities", NULL)) return false; model = libhal_device_get_property_QString(m_halContext, m_udi, "info.product"); if (isConfigured(m_halContext, m_udi, NULL)) return false; if (libhal_device_query_capability(m_halContext, m_udi, "net", NULL)) { if (isConfigured(m_halContext, m_udi, "net.physical_device")) return false; // now try to check if networkmanager is running - it's just a hack DCOPRef ref( "kded", "networkstatus" ); DCOPReply reply = ref.call( "networks" ); if ( reply.isValid() ) { QStringList list = reply; if ( list.contains( "NetworkManagersNetwork" ) ) return false; } type="network"; type_string = i18n("Network Interface"); pixmap="network"; QString parent_udi = libhal_device_get_property_QString(m_halContext, m_udi, "net.physical_device"); if (parent_udi.isNull()) return false; model = libhal_device_get_property_QString(m_halContext, parent_udi, "info.product"); return newHardwarePopup(); } if (libhal_device_query_capability(m_halContext, m_udi, "input.mouse", NULL)) { type_string = i18n("Mouse"); type="mouse"; pixmap="mouse"; QString parent_udi = libhal_device_get_property_QString(m_halContext, m_udi, "input.physical_device"); if (parent_udi.isNull()) return false; Q_ASSERT( !parent_udi.isEmpty() ); model = libhal_device_get_property_QString(m_halContext, parent_udi, "info.product"); return newHardwarePopup(); } if (libhal_device_query_capability(m_halContext, m_udi, "input.keyboard", NULL)) { type_string = i18n("Keyboard"); type="keyboard"; pixmap="kxkb"; QString parent_udi = libhal_device_get_property_QString(m_halContext, m_udi, "input.physical_device"); if (parent_udi.isNull()) return false; model = libhal_device_get_property_QString(m_halContext, parent_udi, "info.product"); return newHardwarePopup(); } if (libhal_device_query_capability(m_halContext, m_udi, "bluetooth_hci", NULL)) { KProcess *proc = new KProcess(this); *proc << "kbluetooth"; proc->setUseShell(true); proc->start(KProcess::DontCare); return false; } if (libhal_device_query_capability(m_halContext, m_udi, "printer", NULL)) { if (isConfigured(m_halContext, m_udi, "printer.physical_device")) return false; model = libhal_device_get_property_QString(m_halContext, m_udi, "printer.description"); type_string = i18n("Printer"); type="printer"; pixmap="printer1"; return newHardwarePopup(); } if (libhal_device_query_capability(m_halContext, m_udi, "scanner", NULL)) { type_string = i18n("Scanner"); type="scanner"; pixmap="scanner"; return newHardwarePopup(); } if (libhal_device_query_capability(m_halContext, m_udi, "pda", NULL)) { type_string = i18n("PDA"); type="pda"; pixmap="kpf"; postcommand=""; return false; // newHardwarePopup(); } if (libhal_device_query_capability(m_halContext, m_udi, "serial", NULL)) { type_string = i18n("Modem"); type="modem"; pixmap="kpf"; postcommand="kinternet"; return newHardwarePopup(); } if (libhal_device_get_property_QString(m_halContext, m_udi, "linux.subsystem") == "usb") { type_string = i18n("USB"); return true; } #if 0 // unhandled switch (hw_class) { case hw_monitor: return i18n("Monitor"); case hw_display: return i18n("Display"); case hw_joystick: return i18n("Joystick"); case hw_chipcard: return i18n("Chipcard"); case hw_sound: return i18n("Sound Device"); case hw_tv: return i18n("TV Card"); case hw_isdn: return i18n("ISDN Controller"); default: return i18n("Unknown"); case hw_joystick: type="joystick"; pixmap="kdebluetooth"; break; case hw_chipcard: type="chipcard"; pixmap="kdebluetooth"; break; case hw_monitor: type="monitor"; pixmap="kdebluetooth"; break; case hw_display: type="display"; pixmap="kdebluetooth"; break; case hw_sound: type="sound"; pixmap="kdebluetooth"; break; case hw_tv: type="tv"; pixmap="kdebluetooth"; break; case hw_isdn: type="isdn"; pixmap="kdebluetooth"; break; } #endif // kdDebug() << "unhandled udi " << m_udi << endl; return false; } void HWItem::readConfig() { KGlobal::config()->setGroup("General"); pixmap = KGlobal::config()->readEntry("IconFn", pixmap); } void HWItem::popupDialog() { emit queueDialogforPopup(this); } /*************************** Dialog stuff ************************/ bool HWItem::newHardwarePopup() { QString description; KConfig *config = KGlobal::config(); config->setGroup(type); QString tmp = config->readEntry("ConfigExec"); if (tmp.isEmpty()) { kdDebug() << "can't be configured due to lack of config exec " << m_udi << endl; return false; } config->setGroup("General"); if (config->readBoolEntry("DoNotShowPopup")) { return false; } config->setGroup(m_udi); if (config->readBoolEntry("PopupDone")){ kdDebug() << "already asked for " << m_udi << endl; return false; } pop1 = new SUSEHWPopup1((QWidget*)parent()->parent(), NULL, false, WDestructiveClose); positivedestruction = true; kdDebug() << "pop1\n"; /*** handler for the dialog buttons ***/ connect(pop1, SIGNAL(sigYes()), SLOT(slotPopupYes())); connect(pop1, SIGNAL(sigNo()), SLOT(slotPopupNo())); connect(pop1, SIGNAL(destroyed()), SLOT(slotPopupDestroyed())); // TODO if (model.isEmpty()) description=i18n("Configure the %1?").arg(getTypeString()); else description=i18n("Configure the %1 \"%2\"?").arg(getTypeString()).arg(model); // pop1->Description->setAlignment(Qt::WordBreak); pop1->Description->setText(description); pop1->Icon->setPixmap( KGlobal::iconLoader()->loadIcon(pixmap, KIcon::Panel,0)); pop1->hide(); popupDialog(); return true; } void HWItem::slotPopupYes() { positivedestruction = false; kdDebug() << "slotPopupYes" << endl; slotLaunch(); this->evaluatePopupCombo(); KConfig *config = KGlobal::config(); config->setGroup(m_udi); config->writeEntry("PopupDone", true); config->sync(); } void HWItem::slotPopupNo() { kdDebug() << "slotPopupNo\n"; positivedestruction = false; this->evaluatePopupCombo(); KConfig *config = KGlobal::config(); config->setGroup(m_udi); config->writeEntry("PopupDone", true); config->sync(); emit queuedDialogDone(this); //dequeue this item from Hwsusekicker::dialogQueue } void HWItem::slotPopupDestroyed() { kdDebug() << "destroyed " << positivedestruction << endl; if (positivedestruction) emit dequeueAll(); } void HWItem::evaluatePopupCombo() { //should be PopupCheckBox :) if (!pop1->CheckBoxInform->isOn()) { KConfig *config = KGlobal::config(); config->setGroup("General"); config->writeEntry("DoNotShowPopup", true); } } void HWItem::slotConfigToolDone() { if (!postcommand.isEmpty()) { KRun::runCommand(postcommand); } emit queuedDialogDone(this); } void HWItem::showPopup() { kdDebug() << "show popup for " << m_udi << endl; pop1->show(); } void HWItem::slotLaunch() { KConfig *config = KGlobal::config(); config->setGroup(type); QString pkg = config->readEntry("YaST-Package"); if ( pkg.isEmpty() ) { slotLaunchConfig(); return; } KProcess *proc = new KProcess; proc->setUseShell(true); *proc << "rpm" << "-q" << pkg; proc->start(KProcess::Block); if( proc->normalExit() && proc->exitStatus() == 0 ) slotLaunchConfig(); // otherwise do nothing } void HWItem::slotLaunchConfig() { KConfig *config = KGlobal::config(); config->setGroup(type); QString tmp = config->readEntry("ConfigExec"); if (tmp.isEmpty()) return; KProcess *proc=new KProcess; int ct=0; ct=tmp.find(" "); while(ct!=-1){ *proc << tmp.left(ct); tmp=tmp.right(tmp.length()-ct-1); ct=tmp.find(" "); } *proc << tmp; connect(proc,SIGNAL(processExited(KProcess *)), this,SLOT(slotConfigToolDone())); proc->start(KProcess::NotifyOnExit); } void HWItem::runCommand() { kdDebug() << "runCommand " << command_to_run << endl; KProcess *proc = new KProcess(this); proc->setUseShell(true); *proc << command_to_run; proc->start(KProcess::DontCare); } #include "susehwitem.moc"