File indexing completed on 2024-11-24 05:00:25
0001 /* 0002 SPDX-FileCopyrightText: 2009 Wang Hoi <zealot.hoi@gmail.com> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 /** @file scim_panel_dbus.cpp 0008 */ 0009 0010 #define KDE_signal signal 0011 0012 #undef QT_NO_STL 0013 #define QT_STL 0014 0015 #include <config-scim.h> 0016 #include <errno.h> 0017 #include <list> 0018 #include <signal.h> 0019 #include <stdlib.h> 0020 #include <sys/time.h> 0021 #include <sys/types.h> 0022 #include <sys/wait.h> 0023 #include <unistd.h> 0024 0025 #include <QCoreApplication> 0026 #include <QDBusConnection> 0027 #include <QDBusMessage> 0028 #include <QMutex> 0029 #include <QObject> 0030 #include <QProcess> 0031 #include <QString> 0032 #include <QStringList> 0033 #include <QThread> 0034 0035 #define Uses_C_STDIO 0036 #define Uses_C_STDLIB 0037 #define Uses_SCIM_LOOKUP_TABLE 0038 #define Uses_SCIM_SOCKET 0039 #define Uses_SCIM_TRANSACTION 0040 #define Uses_SCIM_TRANS_COMMANDS 0041 #define Uses_SCIM_CONFIG 0042 #define Uses_SCIM_CONFIG_MODULE 0043 // #define Uses_SCIM_DEBUG 0044 #define Uses_SCIM_HELPER 0045 #define Uses_SCIM_HELPER_MODULE 0046 #define Uses_SCIM_PANEL_AGENT 0047 #define Uses_STL_MAP 0048 0049 #define ENABLE_DEBUG 9 0050 // scim use exceptions and template, so it doesn't work in hidden visibility 0051 #pragma GCC visibility push(default) 0052 #include <scim.h> 0053 #pragma GCC visibility pop 0054 0055 Q_DECLARE_METATYPE(scim::Property) 0056 Q_DECLARE_METATYPE(scim::PanelFactoryInfo) 0057 Q_DECLARE_METATYPE(scim::HelperInfo) 0058 0059 using namespace Qt::StringLiterals; 0060 using namespace scim; 0061 0062 // PanelAgent related functions 0063 static bool initialize_panel_agent(const String &config, const String &display, bool resident); 0064 static bool run_panel_agent(void); 0065 static void start_auto_start_helpers(void); 0066 0067 static void slot_transaction_start(void); 0068 static void slot_transaction_end(void); 0069 static void slot_reload_config(void); 0070 static void slot_turn_on(void); 0071 static void slot_turn_off(void); 0072 static void slot_update_screen(int screen); 0073 static void slot_update_spot_location(int x, int y); 0074 static void slot_update_factory_info(const PanelFactoryInfo &info); 0075 static void slot_show_help(const String &help); 0076 static void slot_show_factory_menu(const std::vector<PanelFactoryInfo> &menu); 0077 0078 static void slot_show_preedit_string(void); 0079 static void slot_show_aux_string(void); 0080 static void slot_show_lookup_table(void); 0081 static void slot_hide_preedit_string(void); 0082 static void slot_hide_aux_string(void); 0083 static void slot_hide_lookup_table(void); 0084 static void slot_update_preedit_string(const String &str, const AttributeList &attrs); 0085 static void slot_update_preedit_caret(int caret); 0086 static void slot_update_aux_string(const String &str, const AttributeList &attrs); 0087 static void slot_update_lookup_table(const LookupTable &table); 0088 static void slot_register_properties(const PropertyList &props); 0089 static void slot_update_property(const Property &prop); 0090 0091 static void slot_register_helper_properties(int id, const PropertyList &props); 0092 static void slot_update_helper_property(int id, const Property &prop); 0093 static void slot_register_helper(int id, const HelperInfo &helper); 0094 static void slot_remove_helper(int id); 0095 static void slot_lock(void); 0096 static void slot_unlock(void); 0097 0098 ///////////////////////////////////////////////////////////////////////////// 0099 // Declaration of internal variables. 0100 ///////////////////////////////////////////////////////////////////////////// 0101 // static bool _ui_initialized = false; 0102 0103 static ConfigModule *_config_module = nullptr; 0104 static ConfigPointer _config; 0105 0106 static std::vector<HelperInfo> _helper_list; 0107 0108 static bool _should_exit = false; 0109 0110 // static bool _panel_is_on = false; 0111 0112 static PanelAgent *_panel_agent = nullptr; 0113 0114 static QList<PanelFactoryInfo> _factory_list; 0115 0116 class PanelAgentThread; 0117 PanelAgentThread *_panel_agent_thread; 0118 0119 class DBusHandler; 0120 DBusHandler *_dbus_handler; 0121 0122 static QMutex _panel_agent_lock; 0123 static QMutex _global_resource_lock; 0124 static QMutex _transaction_lock; 0125 0126 ///////////////////////////////////////////////////////////////////////////// 0127 // Implementation of internal functions. 0128 ///////////////////////////////////////////////////////////////////////////// 0129 0130 static void ui_config_reload_callback(const ConfigPointer &config) 0131 { 0132 _config = config; 0133 } 0134 0135 static QString AttrList2String(const AttributeList &attr_list) 0136 { 0137 QString result; 0138 for (const Attribute &attr : attr_list) { 0139 int type = (int)attr.get_type(); 0140 unsigned int start = attr.get_start(); 0141 unsigned int length = attr.get_length(); 0142 unsigned int value = attr.get_value(); 0143 result += QString::fromLatin1("%1:%2:%3:%4;").arg(type).arg(start).arg(length).arg(value); 0144 } 0145 return result; 0146 } 0147 0148 static QVariantList LookupTable2VariantList(const LookupTable &lookup_table) 0149 { 0150 QVariantList result; 0151 QStringList labels; 0152 QStringList candidates; 0153 QStringList attrlist_list; 0154 int current_page_size = lookup_table.get_current_page_size(); 0155 0156 for (int i = 0; i < current_page_size; ++i) { 0157 labels << QString::fromStdWString(lookup_table.get_candidate_label(i)); 0158 } 0159 for (int i = 0; i < current_page_size; ++i) { 0160 candidates << QString::fromStdWString(lookup_table.get_candidate_in_current_page(i)); 0161 attrlist_list << AttrList2String(lookup_table.get_attributes_in_current_page(i)); 0162 } 0163 0164 result << labels << candidates << attrlist_list << lookup_table.get_current_page_start() 0165 << (lookup_table.get_current_page_start() + lookup_table.get_current_page_size() < ((int)lookup_table.number_of_candidates())); 0166 0167 // result << labels << candidates << attrlist_list; 0168 return result; 0169 } 0170 0171 static QString Property2String(const Property &prop) 0172 { 0173 QString result; 0174 int state = 0; 0175 if (prop.active()) 0176 state |= SCIM_PROPERTY_ACTIVE; 0177 if (prop.visible()) 0178 state |= SCIM_PROPERTY_VISIBLE; 0179 result = QString::fromLatin1("%1:%2:%3:%4:%5") 0180 .arg(QString::fromUtf8(prop.get_key().c_str())) 0181 .arg(QString::fromUtf8(prop.get_label().c_str())) 0182 .arg(QString::fromUtf8(prop.get_icon().c_str())) 0183 .arg(QString::fromUtf8(prop.get_tip().c_str())) 0184 .arg(state); 0185 return result; 0186 } 0187 0188 #if 0 0189 static QString 0190 PanelFactoryInfo2String(const PanelFactoryInfo &info) 0191 { 0192 QString result = QString("%1:%2:%3:%4") 0193 .arg(QString::fromUtf8(info.uuid.c_str())) 0194 .arg(QString::fromUtf8(info.name.c_str())) 0195 .arg(QString::fromUtf8(info.icon.c_str())) 0196 .arg(QString::fromUtf8(info.lang.c_str())); 0197 return result; 0198 } 0199 #endif 0200 0201 static QStringList PropertyList2LeafOnlyStringList(const QList<Property> &props) 0202 { 0203 QStringList list; 0204 list.clear(); 0205 for (int i = 0; i < props.size(); ++i) { 0206 bool ok = true; 0207 for (int j = 0; j < props.size(); ++j) { 0208 if (props.at(i).is_a_leaf_of(props.at(j))) { 0209 SCIM_DEBUG_MAIN(1) << "Leaf" << props.at(i).get_key() << " " << props.at(j).get_key() << "\n"; 0210 ok = false; 0211 } 0212 } 0213 if (ok) 0214 list << Property2String(props.at(i)); 0215 } 0216 return list; 0217 } 0218 0219 static int dbus_event_type = QEvent::registerEventType(1988); 0220 class DBusEvent : public QEvent 0221 { 0222 public: 0223 enum SCIM_EVENT_TYPE { 0224 TURN_ON, 0225 TURN_OFF, 0226 UP_SCREEN, 0227 UP_SPOT_LOC, 0228 UP_AUX, 0229 UP_PREEDIT_STR, 0230 UP_PREEDIT_CARET, 0231 UP_LOOKUPTABLE, 0232 UP_LOOKUPTABLE_CURSOR, 0233 UP_FACTORY_INFO, 0234 UP_PROPERTY, 0235 UP_HELPER_PROPERTY, 0236 REG_PROPERTIES, 0237 REG_HELPER_PROPERTIES, 0238 REG_HELPER, 0239 RM_HELPER, 0240 RM_PROPERTY, 0241 SHOW_LOOKUPTABLE, 0242 HIDE_LOOKUPTABLE, 0243 SHOW_PREEDIT, 0244 HIDE_PREEDIT, 0245 SHOW_AUX, 0246 HIDE_AUX, 0247 SHOW_HELP, 0248 SHOW_FACTORY_MENU, 0249 }; 0250 DBusEvent(SCIM_EVENT_TYPE t, const QVariantList &arglist = QVariantList()) 0251 : QEvent((QEvent::Type)dbus_event_type) 0252 , m_evtype(t) 0253 , m_data(arglist) 0254 { 0255 } 0256 SCIM_EVENT_TYPE scim_event_type() const 0257 { 0258 return m_evtype; 0259 } 0260 const QVariantList &data() const 0261 { 0262 return m_data; 0263 } 0264 0265 private: 0266 SCIM_EVENT_TYPE m_evtype; 0267 QVariantList m_data; 0268 }; 0269 class DBusHandler : public QObject 0270 { 0271 Q_OBJECT 0272 public: 0273 explicit DBusHandler(QObject *parent = nullptr) 0274 : QObject(parent) 0275 { 0276 QDBusConnection("scim_panel"_L1).connect(""_L1, ""_L1, "org.kde.impanel"_L1, "MovePreeditCaret"_L1, this, SLOT(MovePreeditCaret(int))); 0277 QDBusConnection("scim_panel"_L1).connect(""_L1, ""_L1, "org.kde.impanel"_L1, "SelectCandidate"_L1, this, SLOT(SelectCandidate(int))); 0278 QDBusConnection("scim_panel"_L1).connect(""_L1, ""_L1, "org.kde.impanel"_L1, "LookupTablePageUp"_L1, this, SLOT(LookupTablePageUp())); 0279 QDBusConnection("scim_panel"_L1).connect(""_L1, ""_L1, "org.kde.impanel"_L1, "LookupTablePageDown"_L1, this, SLOT(LookupTablePageDown())); 0280 QDBusConnection("scim_panel"_L1).connect(""_L1, ""_L1, "org.kde.impanel"_L1, "TriggerProperty"_L1, this, SLOT(TriggerProperty(QString))); 0281 QDBusConnection("scim_panel"_L1).connect(""_L1, ""_L1, "org.kde.impanel"_L1, "PanelCreated"_L1, this, SLOT(PanelCreated())); 0282 QDBusConnection("scim_panel"_L1).connect(""_L1, ""_L1, "org.kde.impanel"_L1, "Exit"_L1, this, SLOT(Exit())); 0283 QDBusConnection("scim_panel"_L1).connect(""_L1, ""_L1, "org.kde.impanel"_L1, "ReloadConfig"_L1, this, SLOT(ReloadConfig())); 0284 QDBusConnection("scim_panel"_L1).connect(""_L1, ""_L1, "org.kde.impanel"_L1, "Configure"_L1, this, SLOT(Configure())); 0285 0286 logo_prop = Property("/Logo", "SCIM", String(SCIM_ICON_DIR) + "/trademark.png", "SCIM Input Method"); 0287 show_help_prop = Property("/StartHelp", "Help", "help-about", "About SCIM…"); 0288 factory_prop_prefix = QString::fromUtf8("/Factory/"); 0289 helper_prop_prefix = QString::fromUtf8("/Helper/"); 0290 } 0291 ~DBusHandler() 0292 { 0293 } 0294 0295 void setInitialHelpers(const std::vector<HelperInfo> &_helper_list) 0296 { 0297 QList<Property> props; 0298 for (const HelperInfo &info : _helper_list) { 0299 if (((info.option & SCIM_HELPER_STAND_ALONE) != 0) && ((info.option & SCIM_HELPER_AUTO_START) == 0)) { 0300 props << Property(String(helper_prop_prefix.toUtf8().constData()) + info.uuid, info.name, info.icon, info.description); 0301 } 0302 } 0303 if (!props.isEmpty()) { 0304 helper_props_map.insert(0, props); 0305 } 0306 } 0307 public Q_SLOTS: 0308 void MovePreeditCaret(int pos) 0309 { 0310 SCIM_DEBUG_MAIN(1) << Q_FUNC_INFO << pos << "\n"; 0311 _panel_agent->move_preedit_caret(pos); 0312 } 0313 void SelectCandidate(int idx) 0314 { 0315 SCIM_DEBUG_MAIN(1) << Q_FUNC_INFO << idx << "\n"; 0316 _panel_agent->select_candidate(idx); 0317 } 0318 void LookupTablePageUp() 0319 { 0320 SCIM_DEBUG_MAIN(1) << Q_FUNC_INFO << "\n"; 0321 _panel_agent->lookup_table_page_up(); 0322 } 0323 void LookupTablePageDown() 0324 { 0325 SCIM_DEBUG_MAIN(1) << Q_FUNC_INFO << "\n"; 0326 _panel_agent->lookup_table_page_down(); 0327 } 0328 void TriggerProperty(const QString &key) 0329 { 0330 SCIM_DEBUG_MAIN(1) << qPrintable(key) << "\n"; 0331 if (key == QString::fromUtf8(show_help_prop.get_key().c_str())) { 0332 SCIM_DEBUG_MAIN(1) << "about_to_show_help" 0333 << "\n"; 0334 _panel_agent->request_help(); 0335 return; 0336 } 0337 if (key == QString::fromUtf8(logo_prop.get_key().c_str())) { 0338 SCIM_DEBUG_MAIN(1) << "about_to_show_factory_menu" 0339 << "\n"; 0340 _panel_agent->request_factory_menu(); 0341 return; 0342 } 0343 if (key.startsWith(factory_prop_prefix)) { 0344 QString factory_uuid = key; 0345 factory_uuid.remove(0, factory_prop_prefix.size()); 0346 SCIM_DEBUG_MAIN(1) << "about_to_change_factory" << qPrintable(factory_uuid) << "\n"; 0347 _panel_agent->change_factory(factory_uuid.toUtf8().constData()); 0348 return; 0349 } 0350 if (key.startsWith(helper_prop_prefix)) { 0351 QString helper_uuid = key; 0352 helper_uuid.remove(0, helper_prop_prefix.size()); 0353 SCIM_DEBUG_MAIN(1) << "about_to_start_helper" << qPrintable(helper_uuid) << "\n"; 0354 _panel_agent->start_helper(helper_uuid.toUtf8().constData()); 0355 return; 0356 } 0357 int i = 0; 0358 for (i = 0; i < panel_props.size(); ++i) { 0359 if (panel_props.at(i).get_key() == String(key.toUtf8().constData())) { 0360 break; 0361 } 0362 } 0363 // found one 0364 QStringList list_result; 0365 list_result.clear(); 0366 if (i < panel_props.size()) { 0367 for (int j = 0; j < panel_props.size(); ++j) { 0368 if (panel_props.at(j).is_a_leaf_of(panel_props.at(i))) { 0369 list_result << Property2String(panel_props.at(j)); 0370 } 0371 } 0372 if (list_result.isEmpty()) { 0373 _panel_agent->trigger_property(key.toUtf8().constData()); 0374 } else { 0375 SCIM_DEBUG_MAIN(1) << "ExecMenu" << qPrintable(key) << "\n"; 0376 QDBusMessage message = QDBusMessage::createSignal("/kimpanel"_L1, "org.kde.kimpanel.inputmethod"_L1, "ExecMenu"_L1); 0377 message << list_result; 0378 QDBusConnection("scim_panel"_L1).send(message); 0379 } 0380 } 0381 } 0382 void PanelCreated() 0383 { 0384 QDBusMessage message; 0385 QStringList list_result; 0386 0387 list_result.clear(); 0388 list_result << Property2String(logo_prop); 0389 list_result << PropertyList2LeafOnlyStringList(panel_props); 0390 0391 for (const QList<Property> &props : std::as_const(helper_props_map)) { 0392 list_result << PropertyList2LeafOnlyStringList(props); 0393 } 0394 0395 list_result << Property2String(show_help_prop); 0396 0397 message = QDBusMessage::createSignal("/kimpanel"_L1, "org.kde.kimpanel.inputmethod"_L1, "RegisterProperties"_L1); 0398 0399 message << list_result; 0400 QDBusConnection("scim_panel"_L1).send(message); 0401 } 0402 void Exit() 0403 { 0404 SCIM_DEBUG_MAIN(1) << Q_FUNC_INFO << "\n"; 0405 _panel_agent->exit(); 0406 _panel_agent->stop(); 0407 exit(1); 0408 } 0409 void ReloadConfig() 0410 { 0411 SCIM_DEBUG_MAIN(1) << Q_FUNC_INFO << "\n"; 0412 _panel_agent->reload_config(); 0413 if (!_config.null()) 0414 _config->reload(); 0415 } 0416 void Configure() 0417 { 0418 SCIM_DEBUG_MAIN(1) << Q_FUNC_INFO << "\n"; 0419 QProcess::startDetached("scim-setup"_L1, QStringList()); 0420 } 0421 0422 protected: 0423 bool event(QEvent *e) override 0424 { 0425 QStringList list_result; 0426 QList<Property> prop_list; 0427 if (e->type() == dbus_event_type) { 0428 DBusEvent *ev = (DBusEvent *)e; 0429 0430 QDBusMessage message; 0431 QVariantList data; 0432 0433 switch (ev->scim_event_type()) { 0434 case DBusEvent::TURN_ON: 0435 /* 0436 list_result.clear(); 0437 list_result << Property2String(logo_prop); 0438 list_result << PropertyList2LeafOnlyStringList(panel_props); 0439 for(const QList<Property> &props : std::as_const(helper_props_map)) { 0440 list_result << PropertyList2LeafOnlyStringList(props); 0441 } 0442 list_result << Property2String(show_help_prop); 0443 0444 message = QDBusMessage::createSignal("/kimpanel"_L1, 0445 "org.kde.kimpanel.inputmethod", 0446 "RegisterProperties"); 0447 0448 message << list_result; 0449 QDBusConnection("scim_panel").send(message); 0450 */ 0451 message = QDBusMessage::createSignal("/kimpanel"_L1, "org.kde.kimpanel.inputmethod"_L1, "Enable"_L1); 0452 message << true; 0453 QDBusConnection("scim_panel"_L1).send(message); 0454 break; 0455 case DBusEvent::TURN_OFF: 0456 logo_prop.set_icon(String(SCIM_ICON_DIR) + "/trademark.png"); 0457 0458 message = QDBusMessage::createSignal("/kimpanel"_L1, "org.kde.kimpanel.inputmethod"_L1, "UpdateProperty"_L1); 0459 message << Property2String(logo_prop); 0460 QDBusConnection("scim_panel"_L1).send(message); 0461 /* 0462 list_result.clear(); 0463 list_result << Property2String(logo_prop); 0464 for (const QList<Property> &prop_list : std::as_const(helper_props_map)) { 0465 list_result << PropertyList2LeafOnlyStringList(prop_list); 0466 } 0467 list_result << Property2String(show_help_prop); 0468 0469 message = QDBusMessage::createSignal("/kimpanel", 0470 "org.kde.kimpanel.inputmethod", 0471 "RegisterProperties"); 0472 0473 message << list_result; 0474 0475 QDBusConnection("scim_panel").send(message); 0476 */ 0477 message = QDBusMessage::createSignal("/kimpanel"_L1, "org.kde.kimpanel.inputmethod"_L1, "Enable"_L1); 0478 message << false; 0479 QDBusConnection("scim_panel"_L1).send(message); 0480 break; 0481 case DBusEvent::SHOW_HELP: 0482 message = QDBusMessage::createSignal("/kimpanel"_L1, "org.kde.kimpanel.inputmethod"_L1, "ExecDialog"_L1); 0483 message << Property2String(Property("/Help", "Help", "", ev->data().at(0).toString().toUtf8().constData())); 0484 QDBusConnection("scim_panel"_L1).send(message); 0485 break; 0486 case DBusEvent::SHOW_FACTORY_MENU: 0487 message = QDBusMessage::createSignal("/kimpanel"_L1, "org.kde.kimpanel.inputmethod"_L1, "ExecMenu"_L1); 0488 // X _factory_list.clear(); 0489 list_result.clear(); 0490 data = ev->data(); 0491 for (const QVariant &v : std::as_const(data)) { 0492 PanelFactoryInfo factory_info = v.value<PanelFactoryInfo>(); 0493 // X _factory_list << factory_info; 0494 list_result << Property2String(Property(String(factory_prop_prefix.toUtf8().constData()) + factory_info.uuid, 0495 factory_info.name, 0496 factory_info.icon, 0497 factory_info.lang)); 0498 } 0499 message << list_result; 0500 SCIM_DEBUG_MAIN(1) << qPrintable(list_result.join(QLatin1Char(';'))) << "\n"; 0501 QDBusConnection("scim_panel"_L1).send(message); 0502 break; 0503 case DBusEvent::SHOW_PREEDIT: 0504 message = QDBusMessage::createSignal("/kimpanel"_L1, "org.kde.kimpanel.inputmethod"_L1, "ShowPreedit"_L1); 0505 message << true; 0506 QDBusConnection("scim_panel"_L1).send(message); 0507 break; 0508 case DBusEvent::SHOW_AUX: 0509 message = QDBusMessage::createSignal("/kimpanel"_L1, "org.kde.kimpanel.inputmethod"_L1, "ShowAux"_L1); 0510 message << true; 0511 QDBusConnection("scim_panel"_L1).send(message); 0512 break; 0513 case DBusEvent::SHOW_LOOKUPTABLE: 0514 message = QDBusMessage::createSignal("/kimpanel"_L1, "org.kde.kimpanel.inputmethod"_L1, "ShowLookupTable"_L1); 0515 message << true; 0516 QDBusConnection("scim_panel"_L1).send(message); 0517 break; 0518 case DBusEvent::HIDE_PREEDIT: 0519 message = QDBusMessage::createSignal("/kimpanel"_L1, "org.kde.kimpanel.inputmethod"_L1, "ShowPreedit"_L1); 0520 message << false; 0521 QDBusConnection("scim_panel"_L1).send(message); 0522 break; 0523 case DBusEvent::HIDE_AUX: 0524 message = QDBusMessage::createSignal("/kimpanel"_L1, "org.kde.kimpanel.inputmethod"_L1, "ShowAux"_L1); 0525 message << false; 0526 QDBusConnection("scim_panel"_L1).send(message); 0527 break; 0528 case DBusEvent::HIDE_LOOKUPTABLE: 0529 message = QDBusMessage::createSignal("/kimpanel"_L1, "org.kde.kimpanel.inputmethod"_L1, "ShowLookupTable"_L1); 0530 message << false; 0531 QDBusConnection("scim_panel"_L1).send(message); 0532 break; 0533 case DBusEvent::UP_PROPERTY: 0534 message = QDBusMessage::createSignal("/kimpanel"_L1, "org.kde.kimpanel.inputmethod"_L1, "UpdateProperty"_L1); 0535 message << Property2String(ev->data().at(0).value<Property>()); 0536 QDBusConnection("scim_panel"_L1).send(message); 0537 break; 0538 case DBusEvent::UP_LOOKUPTABLE: 0539 message = QDBusMessage::createSignal("/kimpanel"_L1, "org.kde.kimpanel.inputmethod"_L1, "UpdateLookupTable"_L1); 0540 message << ev->data().at(0).toStringList(); 0541 message << ev->data().at(1).toStringList(); 0542 message << ev->data().at(2).toStringList(); 0543 message << ev->data().at(3).toBool(); 0544 message << ev->data().at(4).toBool(); 0545 QDBusConnection("scim_panel"_L1).send(message); 0546 break; 0547 case DBusEvent::UP_LOOKUPTABLE_CURSOR: 0548 message = QDBusMessage::createSignal("/kimpanel"_L1, "org.kde.kimpanel.inputmethod"_L1, "UpdateLookupTableCursor"_L1); 0549 message << ev->data().at(0).toInt(); 0550 QDBusConnection("scim_panel"_L1).send(message); 0551 break; 0552 case DBusEvent::UP_PREEDIT_CARET: 0553 message = QDBusMessage::createSignal("/kimpanel"_L1, "org.kde.kimpanel.inputmethod"_L1, "UpdatePreeditCaret"_L1); 0554 message << ev->data().at(0).toInt(); 0555 QDBusConnection("scim_panel"_L1).send(message); 0556 break; 0557 case DBusEvent::UP_PREEDIT_STR: 0558 message = QDBusMessage::createSignal("/kimpanel"_L1, "org.kde.kimpanel.inputmethod"_L1, "UpdatePreeditText"_L1); 0559 message << ev->data().at(0).toString(); 0560 message << ev->data().at(1).toString(); 0561 QDBusConnection("scim_panel"_L1).send(message); 0562 break; 0563 case DBusEvent::UP_AUX: 0564 message = QDBusMessage::createSignal("/kimpanel"_L1, "org.kde.kimpanel.inputmethod"_L1, "UpdateAux"_L1); 0565 message << ev->data().at(0).toString(); 0566 message << ev->data().at(1).toString(); 0567 QDBusConnection("scim_panel"_L1).send(message); 0568 break; 0569 case DBusEvent::UP_SPOT_LOC: 0570 message = QDBusMessage::createSignal("/kimpanel"_L1, "org.kde.kimpanel.inputmethod"_L1, "UpdateSpotLocation"_L1); 0571 message << ev->data().at(0).toInt(); 0572 message << ev->data().at(1).toInt(); 0573 QDBusConnection("scim_panel"_L1).send(message); 0574 break; 0575 case DBusEvent::UP_SCREEN: 0576 message = QDBusMessage::createSignal("/kimpanel"_L1, "org.kde.kimpanel.inputmethod"_L1, "UpdateScreen"_L1); 0577 message << ev->data().at(0).toInt(); 0578 QDBusConnection("scim_panel"_L1).send(message); 0579 break; 0580 case DBusEvent::UP_FACTORY_INFO: 0581 SCIM_DEBUG_MAIN(1) << "update factory info\n"; 0582 0583 logo_prop.set_icon(ev->data().at(0).value<PanelFactoryInfo>().icon); 0584 message = QDBusMessage::createSignal("/kimpanel"_L1, "org.kde.kimpanel.inputmethod"_L1, "UpdateProperty"_L1); 0585 message << Property2String(logo_prop); 0586 QDBusConnection("scim_panel"_L1).send(message); 0587 break; 0588 case DBusEvent::REG_HELPER: 0589 break; 0590 case DBusEvent::REG_HELPER_PROPERTIES: 0591 helper_props_map.clear(); 0592 prop_list.clear(); 0593 data = ev->data().at(1).toList(); 0594 for (const QVariant &v : std::as_const(data)) { 0595 Property prop = v.value<Property>(); 0596 prop_list << prop; 0597 } 0598 helper_props_map.insert(ev->data().at(0).toInt(), prop_list); 0599 0600 list_result.clear(); 0601 list_result << Property2String(logo_prop); 0602 list_result << PropertyList2LeafOnlyStringList(panel_props); 0603 for (const QList<Property> &props : std::as_const(helper_props_map)) { 0604 list_result << PropertyList2LeafOnlyStringList(props); 0605 } 0606 list_result << Property2String(show_help_prop); 0607 0608 message = QDBusMessage::createSignal("/kimpanel"_L1, "org.kde.kimpanel.inputmethod"_L1, "RegisterProperties"_L1); 0609 0610 message << list_result; 0611 QDBusConnection("scim_panel"_L1).send(message); 0612 0613 break; 0614 case DBusEvent::REG_PROPERTIES: 0615 panel_props.clear(); 0616 data = ev->data(); 0617 for (const QVariant &v : std::as_const(data)) { 0618 Property prop = v.value<Property>(); 0619 panel_props << prop; 0620 SCIM_DEBUG_MAIN(1) << "REG_PROPERTIES" << qPrintable(Property2String(v.value<Property>())) << "\n"; 0621 } 0622 0623 list_result.clear(); 0624 list_result << Property2String(logo_prop); 0625 list_result << PropertyList2LeafOnlyStringList(panel_props); 0626 SCIM_DEBUG_MAIN(1) << "SIMPLIFY_PROPS " << panel_props.size() << " " << list_result.size() - 1 << "\n"; 0627 for (const QList<Property> &props : std::as_const(helper_props_map)) { 0628 list_result << PropertyList2LeafOnlyStringList(props); 0629 } 0630 list_result << Property2String(show_help_prop); 0631 0632 message = QDBusMessage::createSignal("/kimpanel"_L1, "org.kde.kimpanel.inputmethod"_L1, "RegisterProperties"_L1); 0633 0634 message << list_result; 0635 QDBusConnection("scim_panel"_L1).send(message); 0636 0637 break; 0638 case DBusEvent::RM_HELPER: 0639 helper_props_map.remove(ev->data().at(0).toInt()); 0640 list_result.clear(); 0641 list_result << Property2String(logo_prop); 0642 list_result << PropertyList2LeafOnlyStringList(panel_props); 0643 for (const QList<Property> &props : std::as_const(helper_props_map)) { 0644 list_result << PropertyList2LeafOnlyStringList(props); 0645 } 0646 list_result << Property2String(show_help_prop); 0647 0648 message = QDBusMessage::createSignal("/kimpanel"_L1, "org.kde.kimpanel.inputmethod"_L1, "RegisterProperties"_L1); 0649 0650 message << list_result; 0651 QDBusConnection("scim_panel"_L1).send(message); 0652 0653 break; 0654 case DBusEvent::RM_PROPERTY: 0655 message = QDBusMessage::createSignal("/kimpanel"_L1, "org.kde.kimpanel.inputmethod"_L1, "RemoveProperty"_L1); 0656 // message << ev->data().at(0).V(); 0657 QDBusConnection("scim_panel"_L1).send(message); 0658 break; 0659 default: 0660 message = QDBusMessage::createSignal("/kimpanel"_L1, "org.kde.kimpanel.inputmethod"_L1, "ImplementMe"_L1); 0661 // message << ev->data().at(0).toInt(); 0662 SCIM_DEBUG_MAIN(1) << "Implement me:" << ev->scim_event_type() << "\n"; 0663 QDBusConnection("scim_panel"_L1).send(message); 0664 break; 0665 } 0666 0667 return true; 0668 } 0669 return QObject::event(e); 0670 } 0671 0672 private: 0673 QList<Property> panel_props; 0674 QMap<int, QList<Property>> helper_props_map; 0675 Property logo_prop; 0676 Property show_help_prop; 0677 QString factory_prop_prefix; 0678 QString helper_prop_prefix; 0679 QStringList cached_panel_props; 0680 }; 0681 0682 class PanelAgentThread : public QThread 0683 { 0684 Q_OBJECT 0685 public: 0686 explicit PanelAgentThread(QObject *parent = nullptr) 0687 : QThread(parent) 0688 { 0689 } 0690 ~PanelAgentThread() 0691 { 0692 } 0693 void run() override 0694 { 0695 if (!_panel_agent->run()) 0696 std::cerr << "Failed to run Panel.\n"; 0697 _global_resource_lock.lock(); 0698 _should_exit = true; 0699 _global_resource_lock.unlock(); 0700 } 0701 }; 0702 0703 ////////////////////////////////////////////////////////////////////// 0704 // Start of PanelAgent Functions 0705 ////////////////////////////////////////////////////////////////////// 0706 static bool initialize_panel_agent(const String &config, const String &display, bool resident) 0707 { 0708 _panel_agent = new PanelAgent(); 0709 0710 if (!_panel_agent->initialize(config, display, resident)) 0711 return false; 0712 0713 _panel_agent->signal_connect_transaction_start(slot(slot_transaction_start)); 0714 _panel_agent->signal_connect_transaction_end(slot(slot_transaction_end)); 0715 _panel_agent->signal_connect_reload_config(slot(slot_reload_config)); 0716 _panel_agent->signal_connect_turn_on(slot(slot_turn_on)); 0717 _panel_agent->signal_connect_turn_off(slot(slot_turn_off)); 0718 _panel_agent->signal_connect_update_screen(slot(slot_update_screen)); 0719 _panel_agent->signal_connect_update_spot_location(slot(slot_update_spot_location)); 0720 _panel_agent->signal_connect_update_factory_info(slot(slot_update_factory_info)); 0721 _panel_agent->signal_connect_show_help(slot(slot_show_help)); 0722 _panel_agent->signal_connect_show_factory_menu(slot(slot_show_factory_menu)); 0723 _panel_agent->signal_connect_show_preedit_string(slot(slot_show_preedit_string)); 0724 _panel_agent->signal_connect_show_aux_string(slot(slot_show_aux_string)); 0725 _panel_agent->signal_connect_show_lookup_table(slot(slot_show_lookup_table)); 0726 _panel_agent->signal_connect_hide_preedit_string(slot(slot_hide_preedit_string)); 0727 _panel_agent->signal_connect_hide_aux_string(slot(slot_hide_aux_string)); 0728 _panel_agent->signal_connect_hide_lookup_table(slot(slot_hide_lookup_table)); 0729 _panel_agent->signal_connect_update_preedit_string(slot(slot_update_preedit_string)); 0730 _panel_agent->signal_connect_update_preedit_caret(slot(slot_update_preedit_caret)); 0731 _panel_agent->signal_connect_update_aux_string(slot(slot_update_aux_string)); 0732 _panel_agent->signal_connect_update_lookup_table(slot(slot_update_lookup_table)); 0733 _panel_agent->signal_connect_register_properties(slot(slot_register_properties)); 0734 _panel_agent->signal_connect_update_property(slot(slot_update_property)); 0735 _panel_agent->signal_connect_register_helper_properties(slot(slot_register_helper_properties)); 0736 _panel_agent->signal_connect_update_helper_property(slot(slot_update_helper_property)); 0737 _panel_agent->signal_connect_register_helper(slot(slot_register_helper)); 0738 _panel_agent->signal_connect_remove_helper(slot(slot_remove_helper)); 0739 _panel_agent->signal_connect_lock(slot(slot_lock)); 0740 _panel_agent->signal_connect_unlock(slot(slot_unlock)); 0741 0742 _panel_agent->get_helper_list(_helper_list); 0743 0744 return true; 0745 } 0746 0747 static bool run_panel_agent(void) 0748 { 0749 SCIM_DEBUG_MAIN(1) << "run_panel_agent ()\n"; 0750 0751 _panel_agent_thread = NULL; 0752 0753 if (_panel_agent && _panel_agent->valid()) { 0754 _panel_agent_thread = new PanelAgentThread(); 0755 _panel_agent_thread->start(); 0756 } 0757 0758 return (_panel_agent_thread != NULL); 0759 } 0760 0761 static void start_auto_start_helpers(void) 0762 { 0763 SCIM_DEBUG_MAIN(1) << "start_auto_start_helpers () begin\n"; 0764 0765 // Add Helper object items. 0766 for (size_t i = 0; i < _helper_list.size(); ++i) { 0767 SCIM_DEBUG_MAIN(1) << "--" << _helper_list[i].uuid << "--" << _helper_list[i].name << "--\n"; 0768 if ((_helper_list[i].option & SCIM_HELPER_AUTO_START)) { 0769 _panel_agent->start_helper(_helper_list[i].uuid); 0770 } 0771 } 0772 SCIM_DEBUG_MAIN(1) << "start_auto_start_helpers () end\n"; 0773 } 0774 0775 static void slot_transaction_start(void) 0776 { 0777 SCIM_DEBUG_MAIN(1) << "slot_transaction_start ()\n"; 0778 _transaction_lock.lock(); 0779 } 0780 0781 static void slot_transaction_end(void) 0782 { 0783 SCIM_DEBUG_MAIN(1) << "slot_transaction_end ()\n"; 0784 _transaction_lock.unlock(); 0785 } 0786 0787 static void slot_reload_config(void) 0788 { 0789 SCIM_DEBUG_MAIN(1) << "slot_reload_config ()\n"; 0790 if (!_config.null()) 0791 _config->reload(); 0792 else 0793 SCIM_DEBUG_MAIN(1) << "config is null\n"; 0794 } 0795 0796 static void slot_turn_on(void) 0797 { 0798 SCIM_DEBUG_MAIN(1) << "slot_turn_on ()" << _dbus_handler << "\n"; 0799 qApp->postEvent(_dbus_handler, new DBusEvent(DBusEvent::TURN_ON)); 0800 } 0801 0802 static void slot_turn_off(void) 0803 { 0804 SCIM_DEBUG_MAIN(1) << "slot_turn_off ()\n"; 0805 qApp->postEvent(_dbus_handler, new DBusEvent(DBusEvent::TURN_OFF)); 0806 0807 /* 0808 */ 0809 } 0810 0811 static void slot_update_screen(int num) 0812 { 0813 SCIM_DEBUG_MAIN(1) << "slot_update_screen ()\n"; 0814 qApp->postEvent(_dbus_handler, new DBusEvent(DBusEvent::UP_SCREEN, QVariantList() << num)); 0815 } 0816 0817 static void slot_update_factory_info(const PanelFactoryInfo &info) 0818 { 0819 SCIM_DEBUG_MAIN(1) << "slot_update_factory_info ()\n"; 0820 qApp->postEvent(_dbus_handler, new DBusEvent(DBusEvent::UP_FACTORY_INFO, QVariantList() << QVariant::fromValue(info))); 0821 } 0822 0823 static void slot_show_help(const String &help) 0824 { 0825 SCIM_DEBUG_MAIN(1) << "slot_show_help ()\n"; 0826 qApp->postEvent(_dbus_handler, new DBusEvent(DBusEvent::SHOW_HELP, QVariantList() << QString::fromUtf8(help.c_str()))); 0827 } 0828 0829 static void slot_show_factory_menu(const std::vector<PanelFactoryInfo> &factories) 0830 { 0831 SCIM_DEBUG_MAIN(1) << "slot_show_factory_menu ()\n"; 0832 QVariantList list; 0833 for (const PanelFactoryInfo &info : factories) { 0834 list << QVariant::fromValue(info); 0835 } 0836 qApp->postEvent(_dbus_handler, new DBusEvent(DBusEvent::SHOW_FACTORY_MENU, list)); 0837 } 0838 0839 static void slot_update_spot_location(int x, int y) 0840 { 0841 SCIM_DEBUG_MAIN(1) << "slot_update_spot_location ()\n"; 0842 qApp->postEvent(_dbus_handler, new DBusEvent(DBusEvent::UP_SPOT_LOC, QVariantList() << x << y)); 0843 } 0844 0845 static void slot_show_preedit_string(void) 0846 { 0847 SCIM_DEBUG_MAIN(1) << "slot_show_preedit_string ()\n"; 0848 qApp->postEvent(_dbus_handler, new DBusEvent(DBusEvent::SHOW_PREEDIT)); 0849 } 0850 0851 static void slot_show_aux_string(void) 0852 { 0853 SCIM_DEBUG_MAIN(1) << "slot_show_aux_string ()\n"; 0854 qApp->postEvent(_dbus_handler, new DBusEvent(DBusEvent::SHOW_AUX)); 0855 } 0856 0857 static void slot_show_lookup_table(void) 0858 { 0859 SCIM_DEBUG_MAIN(1) << "slot_show_lookup_table ()\n"; 0860 qApp->postEvent(_dbus_handler, new DBusEvent(DBusEvent::SHOW_LOOKUPTABLE)); 0861 } 0862 0863 static void slot_hide_preedit_string(void) 0864 { 0865 SCIM_DEBUG_MAIN(1) << "slot_hide_preedit_string ()\n"; 0866 qApp->postEvent(_dbus_handler, new DBusEvent(DBusEvent::HIDE_PREEDIT)); 0867 } 0868 0869 static void slot_hide_aux_string(void) 0870 { 0871 SCIM_DEBUG_MAIN(1) << "slot_hide_aux_string ()\n"; 0872 qApp->postEvent(_dbus_handler, new DBusEvent(DBusEvent::HIDE_AUX)); 0873 } 0874 0875 static void slot_hide_lookup_table(void) 0876 { 0877 SCIM_DEBUG_MAIN(1) << "slot_hide_lookup_table ()\n"; 0878 qApp->postEvent(_dbus_handler, new DBusEvent(DBusEvent::HIDE_LOOKUPTABLE)); 0879 } 0880 0881 static void slot_update_preedit_string(const String &str, const AttributeList &attrs) 0882 { 0883 SCIM_DEBUG_MAIN(1) << "slot_update_preedit_string ()" << str << "\n"; 0884 qApp->postEvent(_dbus_handler, new DBusEvent(DBusEvent::UP_PREEDIT_STR, QVariantList() << QString::fromUtf8(str.c_str()) << AttrList2String(attrs))); 0885 } 0886 0887 static void slot_update_preedit_caret(int caret) 0888 { 0889 SCIM_DEBUG_MAIN(1) << "slot_update_preedit_caret ()" << caret << "\n"; 0890 qApp->postEvent(_dbus_handler, new DBusEvent(DBusEvent::UP_PREEDIT_CARET, QVariantList() << caret)); 0891 } 0892 0893 static void slot_update_aux_string(const String &str, const AttributeList &attrs) 0894 { 0895 SCIM_DEBUG_MAIN(1) << "slot_update_aux_string ()" << str << "\n"; 0896 qApp->postEvent(_dbus_handler, new DBusEvent(DBusEvent::UP_AUX, QVariantList() << QString::fromUtf8(str.c_str()) << AttrList2String(attrs))); 0897 } 0898 0899 static void slot_update_lookup_table(const LookupTable &table) 0900 { 0901 SCIM_DEBUG_MAIN(1) << "slot_update_lookup_table ()\n"; 0902 qApp->postEvent(_dbus_handler, new DBusEvent(DBusEvent::UP_LOOKUPTABLE, LookupTable2VariantList(table))); 0903 0904 qApp->postEvent( 0905 _dbus_handler, 0906 new DBusEvent(DBusEvent::UP_LOOKUPTABLE_CURSOR, QVariantList() << (table.is_cursor_visible() ? table.get_cursor_pos_in_current_page() : -1))); 0907 } 0908 0909 static void slot_register_properties(const PropertyList &props) 0910 { 0911 SCIM_DEBUG_MAIN(1) << "slot_register_properties ()\n"; 0912 QVariantList list; 0913 for (const Property &prop : props) { 0914 list << QVariant::fromValue(prop); 0915 } 0916 qApp->postEvent(_dbus_handler, new DBusEvent(DBusEvent::REG_PROPERTIES, list)); 0917 } 0918 0919 static void slot_update_property(const Property &prop) 0920 { 0921 SCIM_DEBUG_MAIN(1) << "slot_update_property ()\n"; 0922 qApp->postEvent(_dbus_handler, new DBusEvent(DBusEvent::UP_PROPERTY, QVariantList() << QVariant::fromValue(prop))); 0923 } 0924 0925 static void slot_register_helper_properties(int id, const PropertyList &props) 0926 { 0927 SCIM_DEBUG_MAIN(1) << "slot_register_helper_properties ()\n"; 0928 QVariantList list; 0929 for (const Property &prop : props) { 0930 list << QVariant::fromValue(prop); 0931 } 0932 qApp->postEvent(_dbus_handler, new DBusEvent(DBusEvent::REG_HELPER_PROPERTIES, QVariantList() << id << list)); 0933 } 0934 0935 static void slot_update_helper_property(int id, const Property &prop) 0936 { 0937 SCIM_DEBUG_MAIN(1) << "slot_update_helper_property ()\n"; 0938 qApp->postEvent(_dbus_handler, new DBusEvent(DBusEvent::UP_HELPER_PROPERTY, QVariantList() << id << QVariant::fromValue(prop))); 0939 } 0940 0941 static void slot_register_helper(int id, const HelperInfo &helper) 0942 { 0943 SCIM_DEBUG_MAIN(1) << "slot_register_helper ()\n"; 0944 qApp->postEvent(_dbus_handler, new DBusEvent(DBusEvent::REG_HELPER, QVariantList() << id << QVariant::fromValue(helper))); 0945 } 0946 0947 static void slot_remove_helper(int id) 0948 { 0949 SCIM_DEBUG_MAIN(1) << "slot_remove_helper ()\n"; 0950 qApp->postEvent(_dbus_handler, new DBusEvent(DBusEvent::RM_HELPER, QVariantList() << id)); 0951 } 0952 0953 static void slot_lock(void) 0954 { 0955 SCIM_DEBUG_MAIN(1) << "slot_lock ()\n"; 0956 //_panel_agent_lock.lock(); 0957 } 0958 0959 static void slot_unlock(void) 0960 { 0961 SCIM_DEBUG_MAIN(1) << "slot_unlock ()\n"; 0962 //_panel_agent_lock.unlock(); 0963 } 0964 ////////////////////////////////////////////////////////////////////// 0965 // End of PanelAgent-Functions 0966 ////////////////////////////////////////////////////////////////////// 0967 0968 static void signalhandler(int sig) 0969 { 0970 Q_UNUSED(sig) 0971 SCIM_DEBUG_MAIN(1) << "In signal handler...\n"; 0972 0973 if (_panel_agent) 0974 _panel_agent->stop(); 0975 } 0976 0977 int main(int argc, char *argv[]) 0978 { 0979 std::vector<String> config_list; 0980 0981 int i; 0982 0983 bool daemon = false; 0984 0985 int new_argc = 0; 0986 char **new_argv = new char *[40]; 0987 0988 String config_name("simple"); 0989 String display_name; 0990 bool should_resident = true; 0991 0992 // QTextCodec::setCodecForCStrings(QTextCodec::codecForLocale()); 0993 // Display version info 0994 // std::cerr << "GTK Panel of SCIM " << SCIM_VERSION << "\n\n"; 0995 0996 // get modules list 0997 scim_get_config_module_list(config_list); 0998 0999 // Add a dummy config module, it's not really a module! 1000 config_list.push_back("dummy"); 1001 1002 // Use socket Config module as default if available. 1003 if (!config_list.empty()) { 1004 if (std::find(config_list.begin(), config_list.end(), config_name) == config_list.end()) 1005 config_name = config_list[0]; 1006 } 1007 1008 // DebugOutput::set_output("/home/ora/a.log"); 1009 // DebugOutput::enable_debug (SCIM_DEBUG_AllMask); 1010 1011 // parse command options 1012 i = 0; 1013 while (i < argc) { 1014 if (++i >= argc) 1015 break; 1016 1017 if (String("-l") == argv[i] || String("--list") == argv[i]) { 1018 std::vector<String>::iterator it; 1019 1020 std::cout << "\n"; 1021 std::cout << "Available Config module:\n"; 1022 for (it = config_list.begin(); it != config_list.end(); ++it) 1023 std::cout << " " << *it << "\n"; 1024 1025 return 0; 1026 } 1027 1028 if (String("-c") == argv[i] || String("--config") == argv[i]) { 1029 if (++i >= argc) { 1030 std::cerr << "no argument for option " << argv[i - 1] << "\n"; 1031 return -1; 1032 } 1033 config_name = argv[i]; 1034 continue; 1035 } 1036 1037 if (String("-h") == argv[i] || String("--help") == argv[i]) { 1038 std::cout << "Usage: " << argv[0] << " [option]...\n\n" 1039 << "The options are: \n" 1040 << " --display DISPLAY Run on display DISPLAY.\n" 1041 << " -l, --list List all of available config modules.\n" 1042 << " -c, --config NAME Uses specified Config module.\n" 1043 << " -d, --daemon Run " << argv[0] << " as a daemon.\n" 1044 << " -ns, --no-stay Quit if no connected client.\n" 1045 #if ENABLE_DEBUG 1046 << " -v, --verbose LEVEL Enable debug info, to specific LEVEL.\n" 1047 << " -o, --output FILE Output debug information into FILE.\n" 1048 #endif 1049 << " -h, --help Show this help message.\n"; 1050 return 0; 1051 } 1052 1053 if (String("-d") == argv[i] || String("--daemon") == argv[i]) { 1054 daemon = true; 1055 continue; 1056 } 1057 1058 if (String("-ns") == argv[i] || String("--no-stay") == argv[i]) { 1059 should_resident = false; 1060 continue; 1061 } 1062 1063 if (String("-v") == argv[i] || String("--verbose") == argv[i]) { 1064 if (++i >= argc) { 1065 std::cerr << "no argument for option " << argv[i - 1] << "\n"; 1066 return -1; 1067 } 1068 DebugOutput::set_verbose_level(atoi(argv[i])); 1069 continue; 1070 } 1071 1072 if (String("-o") == argv[i] || String("--output") == argv[i]) { 1073 if (++i >= argc) { 1074 std::cerr << "No argument for option " << argv[i - 1] << "\n"; 1075 return -1; 1076 } 1077 DebugOutput::set_output(argv[i]); 1078 continue; 1079 } 1080 1081 if (String("--display") == argv[i]) { 1082 if (++i >= argc) { 1083 std::cerr << "No argument for option " << argv[i - 1] << "\n"; 1084 return -1; 1085 } 1086 display_name = argv[i]; 1087 continue; 1088 } 1089 1090 if (String("--") == argv[i]) 1091 break; 1092 1093 std::cerr << "Invalid command line option: " << argv[i] << "\n"; 1094 return -1; 1095 } // End of command line parsing. 1096 1097 new_argv[new_argc++] = argv[0]; 1098 1099 // Store the rest argvs into new_argv. 1100 for (++i; i < argc && new_argc < 40; ++i) { 1101 new_argv[new_argc++] = argv[i]; 1102 } 1103 1104 // Make up DISPLAY env. 1105 if (display_name.length()) { 1106 new_argv[new_argc++] = strdup("--display"); 1107 new_argv[new_argc++] = const_cast<char *>(display_name.c_str()); 1108 1109 setenv("DISPLAY", display_name.c_str(), 1); 1110 } 1111 1112 new_argv[new_argc] = 0; 1113 1114 if (!config_name.length()) { 1115 std::cerr << "No Config module is available!\n"; 1116 return -1; 1117 } 1118 1119 if (config_name != "dummy") { 1120 // load config module 1121 _config_module = new ConfigModule(config_name); 1122 1123 if (!_config_module || !_config_module->valid()) { 1124 std::cerr << "Can not load " << config_name << " Config module.\n"; 1125 return -1; 1126 } 1127 1128 // create config instance 1129 _config = _config_module->create_config(); 1130 } else { 1131 _config = new DummyConfig(); 1132 } 1133 1134 if (_config.null()) { 1135 std::cerr << "Failed to create Config instance from " << config_name << " Config module.\n"; 1136 return -1; 1137 } 1138 1139 KDE_signal(SIGQUIT, signalhandler); 1140 KDE_signal(SIGTERM, signalhandler); 1141 KDE_signal(SIGINT, signalhandler); 1142 KDE_signal(SIGHUP, signalhandler); 1143 1144 const QByteArray display = qgetenv("DISPLAY"); 1145 if (display.constData()) 1146 display_name = String(display.constData()); 1147 1148 if (!initialize_panel_agent(config_name, display_name, should_resident)) { 1149 std::cerr << "Failed to initialize Panel Agent!\n"; 1150 return -1; 1151 } 1152 1153 if (daemon) 1154 scim_daemon(); 1155 1156 // connect the configuration reload signal. 1157 _config->signal_connect_reload(slot(ui_config_reload_callback)); 1158 1159 qRegisterMetaType<scim::Property>("scim::Property"); 1160 qRegisterMetaType<PanelFactoryInfo>("PanelFactoryInfo"); 1161 qRegisterMetaType<HelperInfo>("HelperInfo"); 1162 1163 QDBusConnection::connectToBus(QDBusConnection::SessionBus, "scim_panel"_L1); 1164 _dbus_handler = new DBusHandler(); 1165 _dbus_handler->setInitialHelpers(_helper_list); 1166 1167 if (!run_panel_agent()) { 1168 std::cerr << "Failed to run Socket Server!\n"; 1169 return -1; 1170 } 1171 1172 start_auto_start_helpers(); 1173 1174 QCoreApplication app(argc, argv); 1175 app.exec(); 1176 1177 _panel_agent_thread->wait(); 1178 _config.reset(); 1179 1180 std::cerr << "Successfully exited.\n"; 1181 1182 return 0; 1183 } 1184 1185 #include "main.moc" 1186 1187 #undef QT_NO_KEYWORDS 1188 1189 /* 1190 vim:ts=4:nowrap:expandtab 1191 */