/* * vim: softtabstop=4 shiftwidth=4 cindent foldmethod=marker expandtab * * $LastChangedDate$ * $Revision$ * $LastChangedBy$ * $URL$ * * Copyright 2009-2011 Eric Connell * * This file is part of Mangler. * * Mangler 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 3 of the License, or * (at your option) any later version. * * Mangler 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 Mangler. If not, see . */ #include "config.h" #include "mangler.h" #include "manglersettings.h" #include #include "manglerintegration.h" #include "mangleraudio.h" #ifdef HAVE_XOSD # include "manglerosd.h" #endif #define PTT_KEY_GET "<press the set button to define a hotkey>" #define PTT_KEY_SET "<Hold a key combination and click done...>" #define PTT_MOUSE_GET "<press the set button to define a button>" #define PTT_MOUSE_SET "<Click a mouse button you wish to use...>" ManglerSettings::ManglerSettings(Glib::RefPtr builder) {/*{{{*/ this->builder = builder; // Connect our signals for this window builder->get_widget("settingsWindow", settingsWindow); /* * Set window properties that are not settable in builder */ settingsWindow->set_keep_above(true); settingsWindow->signal_show().connect(sigc::mem_fun(this, &ManglerSettings::settingsWindow_show_cb)); settingsWindow->signal_hide().connect(sigc::mem_fun(this, &ManglerSettings::settingsWindow_hide_cb)); builder->get_widget("settingsCancelButton", button); button->signal_clicked().connect(sigc::mem_fun(this, &ManglerSettings::settingsCancelButton_clicked_cb)); builder->get_widget("settingsApplyButton", button); button->signal_clicked().connect(sigc::mem_fun(this, &ManglerSettings::settingsApplyButton_clicked_cb)); builder->get_widget("settingsOkButton", button); button->signal_clicked().connect(sigc::mem_fun(this, &ManglerSettings::settingsOkButton_clicked_cb)); builder->get_widget("settingsEnablePTTKeyCheckButton", checkbutton); checkbutton->signal_toggled().connect(sigc::mem_fun(this, &ManglerSettings::settingsEnablePTTKeyCheckButton_toggled_cb)); builder->get_widget("settingsPTTKeyButton", button); button->signal_clicked().connect(sigc::mem_fun(this, &ManglerSettings::settingsPTTKeyButton_clicked_cb)); builder->get_widget("settingsEnablePTTMouseCheckButton", checkbutton); checkbutton->signal_toggled().connect(sigc::mem_fun(this, &ManglerSettings::settingsEnablePTTMouseCheckButton_toggled_cb)); builder->get_widget("settingsPTTMouseButton", button); button->signal_clicked().connect(sigc::mem_fun(this, &ManglerSettings::settingsPTTMouseButton_clicked_cb)); builder->get_widget("settingsEnableAudioIntegrationCheckButton", checkbutton); checkbutton->signal_toggled().connect(sigc::mem_fun(this, &ManglerSettings::settingsEnableAudioIntegrationCheckButton_toggled_cb)); builder->get_widget("settingsAudioIntegrationComboBox", audioPlayerComboBox); audioPlayerTreeModel = Gtk::ListStore::create(audioPlayerColumns); audioPlayerComboBox->set_model(audioPlayerTreeModel); // create a "none" row Gtk::TreeModel::Row audioPlayerNoneRow = *(audioPlayerTreeModel->append()); audioPlayerNoneRow[audioPlayerColumns.id] = MusicClient_None; audioPlayerNoneRow[audioPlayerColumns.name] = "None"; #ifdef HAVE_LIBMPDCLIENT // add MPD row Gtk::TreeModel::Row audioPlayerMPDRow = *(audioPlayerTreeModel->append()); audioPlayerMPDRow[audioPlayerColumns.id] = MusicClient_MPD; audioPlayerMPDRow[audioPlayerColumns.name] = "MPD"; #endif #ifdef HAVE_DBUS // add DBUS client rows // rhythmbox Gtk::TreeModel::Row audioPlayerRBRow = *(audioPlayerTreeModel->append()); audioPlayerRBRow[audioPlayerColumns.id] = MusicClient_Rhythmbox; audioPlayerRBRow[audioPlayerColumns.name] = "Rhythmbox"; // amarok Gtk::TreeModel::Row audioPlayerAmarokRow = *(audioPlayerTreeModel->append()); audioPlayerAmarokRow[audioPlayerColumns.id] = MusicClient_Amarok; audioPlayerAmarokRow[audioPlayerColumns.name] = "Amarok"; #endif audioPlayerComboBox->pack_start(audioPlayerColumns.name); audioPlayerComboBox->set_active(audioPlayerNoneRow); builder->get_widget("settingsEnableVoiceActivationCheckButton", checkbutton); checkbutton->signal_toggled().connect(sigc::mem_fun(this, &ManglerSettings::settingsEnableVoiceActivationCheckButton_toggled_cb)); #ifdef HAVE_XOSD builder->get_widget("settingsOSD", vbox); vbox->set_sensitive(true); builder->get_widget("settingsEnableOnScreenDisplayCheckButton", checkbutton); checkbutton->signal_toggled().connect(sigc::mem_fun(this, &ManglerSettings::settingsEnableOnScreenDisplayCheckButton_toggled_cb)); builder->get_widget("settingsOSDverticalPos", osdPosition); osdPositionModel = Gtk::ListStore::create(osdPositionColumns); osdPosition->set_model(osdPositionModel); osdPosition->pack_start(osdPositionColumns.name); Gtk::TreeModel::Row posrow; posrow = *osdPositionModel->append(); posrow[osdPositionColumns.id] = XOSD_top; posrow[osdPositionColumns.name] = "Top"; posrow = *osdPositionModel->append(); posrow[osdPositionColumns.id] = XOSD_middle; posrow[osdPositionColumns.name] = "Middle"; posrow = *osdPositionModel->append(); posrow[osdPositionColumns.id] = XOSD_bottom; posrow[osdPositionColumns.name] = "Bottom"; builder->get_widget("settingsOSDhorizontalPos", osdAlignment); osdAlignmentModel = Gtk::ListStore::create(osdAlignmentColumns); osdAlignment->set_model(osdAlignmentModel); osdAlignment->pack_start(osdAlignmentColumns.name); Gtk::TreeModel::Row alnrow; alnrow = *osdAlignmentModel->append(); alnrow[osdAlignmentColumns.id] = XOSD_center; alnrow[osdAlignmentColumns.name] = "Center"; alnrow = *osdAlignmentModel->append(); alnrow[osdAlignmentColumns.id] = XOSD_left; alnrow[osdAlignmentColumns.name] = "Left"; alnrow = *osdAlignmentModel->append(); alnrow[osdAlignmentColumns.id] = XOSD_right; alnrow[osdAlignmentColumns.name] = "Right"; builder->get_widget("settingsOSDfontsize", osdFontSize); builder->get_widget("settingsOSDcolor", osdColor); #endif builder->get_widget("audioSubsystemComboBox", audioSubsystemComboBox); audioSubsystemTreeModel = Gtk::ListStore::create(audioSubsystemColumns); audioSubsystemComboBox->set_model(audioSubsystemTreeModel); audioSubsystemComboBox->pack_start(audioSubsystemColumns.name); audioSubsystemComboBox->signal_changed().connect(sigc::mem_fun(this, &ManglerSettings::audioSubsystemComboBox_changed_cb)); builder->get_widget("inputDeviceComboBox", inputDeviceComboBox); inputDeviceTreeModel = Gtk::ListStore::create(inputColumns); inputDeviceComboBox->set_model(inputDeviceTreeModel); inputDeviceComboBox->pack_start(inputColumns.description); inputDeviceComboBox->signal_changed().connect(sigc::mem_fun(this, &ManglerSettings::inputDeviceComboBox_changed_cb)); builder->get_widget("inputDeviceCustomName", inputDeviceCustomName); builder->get_widget("outputDeviceComboBox", outputDeviceComboBox); outputDeviceTreeModel = Gtk::ListStore::create(outputColumns); outputDeviceComboBox->set_model(outputDeviceTreeModel); outputDeviceComboBox->pack_start(outputColumns.description); outputDeviceComboBox->signal_changed().connect(sigc::mem_fun(this, &ManglerSettings::outputDeviceComboBox_changed_cb)); builder->get_widget("outputDeviceCustomName", outputDeviceCustomName); builder->get_widget("notificationDeviceComboBox", notificationDeviceComboBox); notificationDeviceTreeModel = Gtk::ListStore::create(notificationColumns); notificationDeviceComboBox->set_model(notificationDeviceTreeModel); notificationDeviceComboBox->pack_start(notificationColumns.description); notificationDeviceComboBox->signal_changed().connect(sigc::mem_fun(this, &ManglerSettings::notificationDeviceComboBox_changed_cb)); builder->get_widget("notificationDeviceCustomName", notificationDeviceCustomName); mouseInputDevices = getInputDeviceList(); builder->get_widget("settingsMouseDeviceComboBox", mouseDeviceComboBox); mouseDeviceTreeModel = Gtk::ListStore::create(mouseColumns); mouseDeviceComboBox->set_model(mouseDeviceTreeModel); mouseDeviceComboBox->pack_start(mouseColumns.name); // Audio Subsystem audioSubsystemTreeModel->clear(); Gtk::TreeModel::Row audioSubsystemRow; #ifdef HAVE_PULSE audioSubsystemRow = *(audioSubsystemTreeModel->append()); audioSubsystemRow[audioSubsystemColumns.id] = "pulse"; audioSubsystemRow[audioSubsystemColumns.name] = "PulseAudio"; #endif #ifdef HAVE_ALSA audioSubsystemRow = *(audioSubsystemTreeModel->append()); audioSubsystemRow[audioSubsystemColumns.id] = "alsa"; audioSubsystemRow[audioSubsystemColumns.name] = "ALSA"; #endif #ifdef HAVE_OSS audioSubsystemRow = *(audioSubsystemTreeModel->append()); audioSubsystemRow[audioSubsystemColumns.id] = "oss"; audioSubsystemRow[audioSubsystemColumns.name] = "OSS"; #endif // Master Volume volumeAdjustment = new Gtk::Adjustment(79, 0, 158, 1, 10, 10); volumehscale = new Gtk::HScale(*volumeAdjustment); volumehscale->add_mark(148, Gtk::POS_LEFT, "200%"); volumehscale->add_mark(79, Gtk::POS_LEFT, "100%"); volumehscale->add_mark(0, Gtk::POS_LEFT, "0%"); volumehscale->set_inverted(false); volumehscale->set_draw_value(false); builder->get_widget("masterVolumeVbox", vbox); vbox->pack_start(*volumehscale); volumehscale->show(); // Input Gain gainAdjustment = new Gtk::Adjustment(79, 0, 158, 1, 10, 10); gainhscale = new Gtk::HScale(*gainAdjustment); gainhscale->add_mark(148, Gtk::POS_LEFT, "200%"); gainhscale->add_mark(79, Gtk::POS_LEFT, "100%"); gainhscale->add_mark(0, Gtk::POS_LEFT, "0%"); gainhscale->set_inverted(false); gainhscale->set_draw_value(false); builder->get_widget("inputGainVbox", vbox); vbox->pack_start(*gainhscale); gainhscale->show(); }/*}}}*/ void ManglerSettings::applySettings(void) {/*{{{*/ Gtk::TreeModel::iterator iter; GdkWindow *rootwin = gdk_get_default_root_window(); // Key Push to Talk builder->get_widget("settingsEnablePTTKeyCheckButton", checkbutton); Mangler::config["PushToTalkKeyEnabled"] = checkbutton->get_active(); builder->get_widget("settingsPTTKeyValueLabel", label); if (label->get_label() != PTT_KEY_GET && label->get_label() != PTT_KEY_SET) { Mangler::config["PushToTalkKeyValue"] = label->get_text(); } else { Mangler::config["PushToTalkKeyValue"] = ""; } //Mangler::config.parsePushToTalkValue(config.PushToTalkKeyValue); // Mouse Push to Talk builder->get_widget("settingsMouseDeviceComboBox", combobox); iter = combobox->get_active(); if (iter) { Gtk::TreeModel::Row row = *iter; Mangler::config["MouseDeviceName"] = Glib::ustring( row[mouseColumns.name] ); } builder->get_widget("settingsEnablePTTMouseCheckButton", checkbutton); Mangler::config["PushToTalkMouseEnabled"] = checkbutton->get_active(); builder->get_widget("settingsPTTMouseValueLabel", label); if (label->get_label() != PTT_MOUSE_GET && label->get_label() != PTT_MOUSE_SET) { Glib::ustring PushToTalkMouseValue = label->get_text(); if (PushToTalkMouseValue.length() > 6) { Mangler::config["PushToTalkMouseValue"] = PushToTalkMouseValue.substr(6); } else { Mangler::config["PushToTalkMouseValue"] = PushToTalkMouseValue; } } else { Mangler::config["PushToTalkMouseValue"] = ""; } XUngrabButton(GDK_WINDOW_XDISPLAY(rootwin), AnyButton, AnyModifier, GDK_ROOT_WINDOW()); XAllowEvents (GDK_WINDOW_XDISPLAY(rootwin), AsyncBoth, CurrentTime); /* if (checkbutton->get_active()) { XGrabButton(GDK_WINDOW_XDISPLAY(rootwin), config.PushToTalkMouseValueInt, AnyModifier, GDK_ROOT_WINDOW(), False, ButtonPressMask|ButtonReleaseMask, GrabModeAsync, GrabModeAsync, None, None); } */ // Audio Player Integration builder->get_widget("settingsEnableAudioIntegrationCheckButton", checkbutton); Mangler::config["AudioIntegrationEnabled"] = checkbutton->get_active(); iter = audioPlayerComboBox->get_active(); if (iter) { Gtk::TreeModel::Row row = *iter; uint8_t id = row[audioPlayerColumns.id]; Mangler::config["AudioIntegrationPlayer"] = id; if (Mangler::config["AudioIntegrationEnabled"].toBool()) { mangler->integration->setClient((MusicClient)id); } else { mangler->integration->setClient(MusicClient_None); } } mangler->integration->update(true); // Voice Activation builder->get_widget("settingsEnableVoiceActivationCheckButton", checkbutton); Mangler::config["VoiceActivationEnabled"] = checkbutton->get_active(); builder->get_widget("settingsVoiceActivationSilenceDurationSpinButton", spinbutton); Mangler::config["VoiceActivationSilenceDuration"] = spinbutton->get_value() * 1000.0; builder->get_widget("settingsVoiceActivationSensitivitySpinButton", spinbutton); Mangler::config["VoiceActivationSensitivity"] = spinbutton->get_value_as_int(); #ifdef HAVE_XOSD // On-Screen Display builder->get_widget("settingsEnableOnScreenDisplayCheckButton", checkbutton); Mangler::config["OnScreenDisplayEnabled"] = checkbutton->get_active(); if (checkbutton->get_active()) { Gtk::TreeModel::iterator pos_iter = osdPosition->get_active(); if (pos_iter) { int vert_pos_int = (*pos_iter)[osdPositionColumns.id]; Mangler::config["OnScreenDisplayVerticalPosition"] = vert_pos_int; } Gtk::TreeModel::iterator aln_iter = osdAlignment->get_active(); if (aln_iter) { int horz_aln_int = (*aln_iter)[osdAlignmentColumns.id]; Mangler::config["OnScreenDisplayHorizontalAlignment"] = horz_aln_int; } Mangler::config["OnScreenDisplayFontSize"] = osdFontSize->get_value(); Gdk::Color color = osdColor->get_color(); char colorstr[16]; snprintf(colorstr, 15, "#%02x%02x%02x", color.get_red() / 256, color.get_green() / 256, color.get_blue() / 256); Mangler::config["OnScreenDisplayColor"] = colorstr; mangler->osd->destroyOsd(); } #endif // Audio Devices iter = inputDeviceComboBox->get_active(); if (iter) { Gtk::TreeModel::Row row = *iter; Mangler::config["InputDeviceName"] = Glib::ustring( row[inputColumns.name] ); } Mangler::config["InputDeviceCustomName"] = inputDeviceCustomName->get_text(); iter = outputDeviceComboBox->get_active(); if (iter) { Gtk::TreeModel::Row row = *iter; Mangler::config["OutputDeviceName"] = Glib::ustring( row[outputColumns.name] ); } Mangler::config["OutputDeviceCustomName"] = outputDeviceCustomName->get_text(); iter = notificationDeviceComboBox->get_active(); if (iter) { Gtk::TreeModel::Row row = *iter; Mangler::config["NotificationDeviceName"] = Glib::ustring( row[notificationColumns.name] ); } Mangler::config["NotificationDeviceCustomName"] = notificationDeviceCustomName->get_text(); iter = audioSubsystemComboBox->get_active(); if (iter) { Gtk::TreeModel::Row row = *iter; Mangler::config["AudioSubsystem"] = Glib::ustring( row[audioSubsystemColumns.id] ); } // Master Volume Mangler::config["MasterVolumeLevel"] = volumeAdjustment->get_value(); v3_set_volume_master(Mangler::config["MasterVolumeLevel"].toInt()); mangler->setTooltip(); // Input Gain Mangler::config["InputGainLevel"] = gainAdjustment->get_value(); fprintf(stderr, "setting gain to %d", Mangler::config["InputGainLevel"].toInt()); v3_set_volume_xmit(Mangler::config["InputGainLevel"].toInt()); mangler->setTooltip(); // Notification Sounds builder->get_widget("notificationLoginLogoutCheckButton", checkbutton); Mangler::config["NotificationLoginLogout"] = checkbutton->get_active(); builder->get_widget("notificationChannelEnterLeaveCheckButton", checkbutton); Mangler::config["NotificationChannelEnterLeave"] = checkbutton->get_active(); builder->get_widget("notificationTalkStartEndCheckButton", checkbutton); Mangler::config["NotificationTransmitStartStop"] = checkbutton->get_active(); builder->get_widget("notificationTTSCheckButton", checkbutton); Mangler::config["NotificationTextToSpeech"] = checkbutton->get_active(); // Debug Level uint32_t debuglevel = 0; builder->get_widget("debugStatus", checkbutton); debuglevel |= checkbutton->get_active() ? V3_DEBUG_STATUS : 0; builder->get_widget("debugError", checkbutton); debuglevel |= checkbutton->get_active() ? V3_DEBUG_ERROR : 0; builder->get_widget("debugStack", checkbutton); debuglevel |= checkbutton->get_active() ? V3_DEBUG_STACK : 0; builder->get_widget("debugInternalNet", checkbutton); debuglevel |= checkbutton->get_active() ? V3_DEBUG_INTERNAL : 0; builder->get_widget("debugPacketDump", checkbutton); debuglevel |= checkbutton->get_active() ? V3_DEBUG_PACKET : 0; builder->get_widget("debugPacketParse", checkbutton); debuglevel |= checkbutton->get_active() ? V3_DEBUG_PACKET_PARSE : 0; builder->get_widget("debugEventQueue", checkbutton); debuglevel |= checkbutton->get_active() ? V3_DEBUG_EVENT : 0; builder->get_widget("debugSocket", checkbutton); debuglevel |= checkbutton->get_active() ? V3_DEBUG_SOCKET : 0; builder->get_widget("debugNotice", checkbutton); debuglevel |= checkbutton->get_active() ? V3_DEBUG_NOTICE : 0; builder->get_widget("debugInfo", checkbutton); debuglevel |= checkbutton->get_active() ? V3_DEBUG_INFO : 0; builder->get_widget("debugMutex", checkbutton); debuglevel |= checkbutton->get_active() ? V3_DEBUG_MUTEX : 0; builder->get_widget("debugMemory", checkbutton); debuglevel |= checkbutton->get_active() ? V3_DEBUG_MEMORY : 0; builder->get_widget("debugEncryptedPacket", checkbutton); debuglevel |= checkbutton->get_active() ? V3_DEBUG_PACKET_ENCRYPTED : 0; Mangler::config["lv3_debuglevel"] = debuglevel; v3_debuglevel(debuglevel); Mangler::config.config.save(); }/*}}}*/ void ManglerSettings::initSettings(void) {/*{{{*/ // Key Push to Talk builder->get_widget("settingsEnablePTTKeyCheckButton", checkbutton); checkbutton->set_active(Mangler::config["PushToTalkKeyEnabled"].toBool()); builder->get_widget("settingsPTTKeyValueLabel", label); if (Mangler::config["PushToTalkKeyValue"].length()) { label->set_text(Mangler::config["PushToTalkKeyValue"].toUString()); } else { label->set_markup(PTT_KEY_GET); } // Mouse Push to Talk builder->get_widget("settingsEnablePTTMouseCheckButton", checkbutton); checkbutton->set_active(Mangler::config["PushToTalkMouseEnabled"].toBool()); builder->get_widget("settingsPTTMouseValueLabel", label); if (Mangler::config["PushToTalkMouseValue"].length()) { label->set_text("Button" + Mangler::config["PushToTalkMouseValue"].toUString()); } else { label->set_markup(PTT_MOUSE_GET); } // Audio Player Integration builder->get_widget("settingsEnableAudioIntegrationCheckButton", checkbutton); checkbutton->set_active(Mangler::config["AudioIntegrationEnabled"].toBool()); int audioPlayerSelection = 0; int audioPlayerCtr = 0; Gtk::TreeModel::Children apChildren = audioPlayerTreeModel->children(); for (Gtk::TreeModel::Children::iterator apIter = apChildren.begin(); apIter != apChildren.end(); ++apIter, audioPlayerCtr++) { Gtk::TreeModel::Row row = *apIter; uint8_t id = row[audioPlayerColumns.id]; if (Mangler::config["AudioIntegrationPlayer"].toUInt() == id) { audioPlayerSelection = audioPlayerCtr; } } audioPlayerComboBox->set_active(audioPlayerSelection); /* iterate through whatever is available based on what we can find and populate the store audioPlayerComboBox->set_active(iterOfSelectedinStore); */ // Voice Activation builder->get_widget("settingsEnableVoiceActivationCheckButton", checkbutton); checkbutton->set_active(Mangler::config["VoiceActivationEnabled"].toBool()); builder->get_widget("settingsVoiceActivationSilenceDurationSpinButton", spinbutton); spinbutton->set_value(Mangler::config["VoiceActivationSilenceDuration"].toDouble() / 1000.0); builder->get_widget("settingsVoiceActivationSensitivitySpinButton", spinbutton); spinbutton->set_value(Mangler::config["VoiceActivationSensitivity"].toUInt()); #ifdef HAVE_XOSD // On-Screen Display builder->get_widget("settingsEnableOnScreenDisplayCheckButton", checkbutton); checkbutton->set_active(Mangler::config["OnScreenDisplayEnabled"].toBool()); Gtk::TreeModel::iterator hz_iter = osdAlignmentModel->children().begin(); while (hz_iter != osdAlignmentModel->children().end()) { int hzint = (*hz_iter)[osdAlignmentColumns.id]; if (Mangler::config["OnScreenDisplayHorizontalAlignment"].toInt() == hzint || (!Mangler::config["OnScreenDisplayHorizontalAlignment"].length() && hzint == XOSD_center)) { osdAlignment->set_active(hz_iter); break; } hz_iter++; } Gtk::TreeModel::iterator vt_iter = osdPositionModel->children().begin(); while (vt_iter != osdPositionModel->children().end()) { int vtint = (*vt_iter)[osdPositionColumns.id]; if (Mangler::config["OnScreenDisplayVerticalPosition"].toInt() == vtint || (!Mangler::config["OnScreenDisplayVerticalPosition"].length() && vtint == XOSD_top)) { osdPosition->set_active(vt_iter); break; } vt_iter++; } if (Mangler::config["OnScreenDisplayFontSize"].length()) { osdFontSize->set_value(Mangler::config["OnScreenDisplayFontSize"].toDouble()); } else { osdFontSize->set_value(8.0); } if (Mangler::config["OnScreenDisplayColor"].length()) { Gdk::Color color; color.set(Mangler::config["OnScreenDisplayColor"].toUString()); osdColor->set_color(color); } #endif // Audio Subsystem for (Gtk::TreeModel::iterator asIter = audioSubsystemTreeModel->children().begin(); asIter != audioSubsystemTreeModel->children().end(); asIter++) { if ((*asIter)[audioSubsystemColumns.id] == Mangler::config["AudioSubsystem"].toLower()) { audioSubsystemComboBox->set_active(asIter); } } // Audio Devices inputDeviceCustomName->set_text(Mangler::config["InputDeviceCustomName"].toUString()); outputDeviceCustomName->set_text(Mangler::config["OutputDeviceCustomName"].toUString()); notificationDeviceCustomName->set_text(Mangler::config["NotificationDeviceCustomName"].toUString()); // Notification Sounds builder->get_widget("notificationLoginLogoutCheckButton", checkbutton); checkbutton->set_active(Mangler::config["NotificationLoginLogout"].toBool()); builder->get_widget("notificationChannelEnterLeaveCheckButton", checkbutton); checkbutton->set_active(Mangler::config["NotificationChannelEnterLeave"].toBool()); builder->get_widget("notificationTalkStartEndCheckButton", checkbutton); checkbutton->set_active(Mangler::config["NotificationTransmitStartStop"].toBool()); builder->get_widget("notificationTTSCheckButton", checkbutton); checkbutton->set_active(Mangler::config["NotificationTextToSpeech"].toBool()); #ifdef HAVE_ESPEAK checkbutton->set_sensitive(true); #endif // Master Volume if (Mangler::config["MasterVolumeLevel"].length()) { volumeAdjustment->set_value(Mangler::config["MasterVolumeLevel"].toInt()); } // Input Gain if (Mangler::config["InputGainLevel"].length()) { gainAdjustment->set_value(Mangler::config["InputGainLevel"].toInt()); } // Debug Level builder->get_widget("debugStatus", checkbutton); uint32_t config_lv3_debuglevel = Mangler::config["lv3_debuglevel"].toULong(); checkbutton->set_active(config_lv3_debuglevel & V3_DEBUG_STATUS ? 1 : 0); builder->get_widget("debugError", checkbutton); checkbutton->set_active(config_lv3_debuglevel & V3_DEBUG_ERROR ? 1 : 0); builder->get_widget("debugStack", checkbutton); checkbutton->set_active(config_lv3_debuglevel & V3_DEBUG_STACK ? 1 : 0); builder->get_widget("debugInternalNet", checkbutton); checkbutton->set_active(config_lv3_debuglevel & V3_DEBUG_INTERNAL ? 1 : 0); builder->get_widget("debugPacketDump", checkbutton); checkbutton->set_active(config_lv3_debuglevel & V3_DEBUG_PACKET ? 1 : 0); builder->get_widget("debugPacketParse", checkbutton); checkbutton->set_active(config_lv3_debuglevel & V3_DEBUG_PACKET_PARSE ? 1 : 0); builder->get_widget("debugEventQueue", checkbutton); checkbutton->set_active(config_lv3_debuglevel & V3_DEBUG_EVENT ? 1 : 0); builder->get_widget("debugSocket", checkbutton); checkbutton->set_active(config_lv3_debuglevel & V3_DEBUG_SOCKET ? 1 : 0); builder->get_widget("debugNotice", checkbutton); checkbutton->set_active(config_lv3_debuglevel & (uint32_t)V3_DEBUG_NOTICE ? 1 : 0); builder->get_widget("debugInfo", checkbutton); checkbutton->set_active(config_lv3_debuglevel & V3_DEBUG_INFO ? 1 : 0); builder->get_widget("debugMutex", checkbutton); checkbutton->set_active(config_lv3_debuglevel & V3_DEBUG_MUTEX ? 1 : 0); builder->get_widget("debugMemory", checkbutton); checkbutton->set_active(config_lv3_debuglevel & V3_DEBUG_MEMORY ? 1 : 0); builder->get_widget("debugEncryptedPacket", checkbutton); checkbutton->set_active(config_lv3_debuglevel & V3_DEBUG_PACKET_ENCRYPTED ? 1 : 0); }/*}}}*/ // Settings Window Callbacks void ManglerSettings::showSettingsWindow(void) {/*{{{*/ settingsWindow->show(); }/*}}}*/ void ManglerSettings::settingsWindow_show_cb(void) {/*{{{*/ Gtk::TreeModel::Row row; isDetectingKey = false; isDetectingMouse = false; initSettings(); // these callbacks initialize the state settingsEnablePTTKeyCheckButton_toggled_cb(); settingsEnablePTTMouseCheckButton_toggled_cb(); updateDeviceComboBoxes(); // Clear the mouse device store and rebuild it from the audioControl vector mouseDeviceTreeModel->clear(); int mouseSelection = 0; int mouseCtr = 0; for ( std::map::iterator i = mouseInputDevices.begin(); i != mouseInputDevices.end(); i++, mouseCtr++) { Gtk::TreeModel::Row row = *(mouseDeviceTreeModel->append()); row[mouseColumns.id] = (*i).first; row[mouseColumns.name] = (*i).second; if (Mangler::config["MouseDeviceName"] == (*i).second) { mouseSelection = mouseCtr; } } if (!mouseSelection) { int mouseCtr = 0; for ( std::map::iterator i = mouseInputDevices.begin(); i != mouseInputDevices.end(); i++, mouseCtr++) { if ((*i).second.find("Mouse") != std::string::npos) { mouseSelection = mouseCtr; } } } // TODO: get the currently selected item from settings object and select it mouseDeviceComboBox->set_active(mouseSelection); }/*}}}*/ void ManglerSettings::settingsWindow_hide_cb(void) {/*{{{*/ isDetectingKey = false; isDetectingMouse = false; }/*}}}*/ void ManglerSettings::settingsCancelButton_clicked_cb(void) {/*{{{*/ // additional cleanup should happen in ManglerSettings::settingsWindow_hide_cb() settingsWindow->hide(); }/*}}}*/ void ManglerSettings::settingsApplyButton_clicked_cb(void) {/*{{{*/ applySettings(); }/*}}}*/ void ManglerSettings::settingsOkButton_clicked_cb(void) {/*{{{*/ applySettings(); settingsWindow->hide(); }/*}}}*/ void ManglerSettings::settingsEnablePTTKeyCheckButton_toggled_cb(void) {/*{{{*/ builder->get_widget("settingsEnablePTTKeyCheckButton", checkbutton); if (checkbutton->get_active()) { // box was checked builder->get_widget("settingsPTTKeyLabel", label); label->set_sensitive(true); builder->get_widget("settingsPTTKeyValueLabel", label); label->set_sensitive(true); builder->get_widget("settingsPTTKeyButton", button); button->set_sensitive(true); } else { // box was unchecked builder->get_widget("settingsPTTKeyLabel", label); label->set_sensitive(false); builder->get_widget("settingsPTTKeyValueLabel", label); label->set_sensitive(false); builder->get_widget("settingsPTTKeyButton", button); button->set_sensitive(false); } }/*}}}*/ void ManglerSettings::settingsEnableAudioIntegrationCheckButton_toggled_cb(void) {/*{{{*/ builder->get_widget("settingsEnableAudioIntegrationCheckButton", checkbutton); if (checkbutton->get_active()) { builder->get_widget("settingsAudioIntegrationLabel", label); label->set_sensitive(true); audioPlayerComboBox->set_sensitive(true); } else { builder->get_widget("settingsAudioIntegrationLabel", label); label->set_sensitive(false); audioPlayerComboBox->set_sensitive(false); } }/*}}}*/ void ManglerSettings::settingsEnableVoiceActivationCheckButton_toggled_cb(void) {/*{{{*/ builder->get_widget("settingsEnableVoiceActivationCheckButton", checkbutton); if (checkbutton->get_active()) { builder->get_widget("settingsVoiceActivationTable", table); table->set_sensitive(true); } else { builder->get_widget("settingsVoiceActivationTable", table); table->set_sensitive(false); } }/*}}}*/ void ManglerSettings::settingsEnableOnScreenDisplayCheckButton_toggled_cb(void) {/*{{{*/ builder->get_widget("settingsEnableOnScreenDisplayCheckButton", checkbutton); builder->get_widget("settingsOSDTable", table); table->set_sensitive(checkbutton->get_active()); }/*}}}*/ /* * When this button is pressed, we need to disable all of the other items on * the page until the user clicks the button again. This starts a timer to * check keyboard state and update the settingsPTTKeyLabel to the key * combination value. Setting isDetectingKey to false will cause the timer * callback to stop running. * The timer callback is ManglerSettings::settingsPTTKeyDetect. */ void ManglerSettings::settingsPTTKeyButton_clicked_cb(void) {/*{{{*/ builder->get_widget("settingsPTTKeyButton", button); if (button->get_label() == "Set") { isDetectingKey = true; button->set_label("Done"); builder->get_widget("settingsCancelButton", button); button->set_sensitive(false); builder->get_widget("settingsApplyButton", button); button->set_sensitive(false); builder->get_widget("settingsOkButton", button); button->set_sensitive(false); Glib::signal_timeout().connect( sigc::mem_fun(*this, &ManglerSettings::settingsPTTKeyDetect), 100 ); } else { isDetectingKey = false; button->set_label("Set"); builder->get_widget("settingsCancelButton", button); button->set_sensitive(true); builder->get_widget("settingsApplyButton", button); button->set_sensitive(true); builder->get_widget("settingsOkButton", button); button->set_sensitive(true); builder->get_widget("settingsPTTKeyValueLabel", label); // if the text is as follows, the user pressed done without any keys // pressed down and reset it to the default text if (label->get_label() == PTT_KEY_SET) { label->set_markup(PTT_KEY_GET); } } }/*}}}*/ void ManglerSettings::settingsEnablePTTMouseCheckButton_toggled_cb(void) {/*{{{*/ builder->get_widget("settingsEnablePTTMouseCheckButton", checkbutton); if (checkbutton->get_active()) { // box was checked builder->get_widget("settingsPTTMouseLabel", label); label->set_sensitive(true); builder->get_widget("settingsPTTMouseValueLabel", label); label->set_sensitive(true); builder->get_widget("settingsPTTMouseButton", button); button->set_sensitive(true); builder->get_widget("settingsMouseDeviceLabel", label); label->set_sensitive(true); builder->get_widget("settingsMouseDeviceComboBox", combobox); combobox->set_sensitive(true); } else { // box was unchecked builder->get_widget("settingsPTTMouseLabel", label); label->set_sensitive(false); builder->get_widget("settingsPTTMouseValueLabel", label); label->set_sensitive(false); builder->get_widget("settingsPTTMouseButton", button); button->set_sensitive(false); builder->get_widget("settingsMouseDeviceLabel", label); label->set_sensitive(false); builder->get_widget("settingsMouseDeviceComboBox", combobox); combobox->set_sensitive(false); } }/*}}}*/ void ManglerSettings::settingsPTTMouseButton_clicked_cb(void) {/*{{{*/ isDetectingMouse = true; builder->get_widget("settingsPTTMouseValueLabel", label); label->set_markup(PTT_MOUSE_SET); builder->get_widget("settingsPTTMouseButton", button); button->set_sensitive(false); builder->get_widget("settingsCancelButton", button); button->set_sensitive(false); builder->get_widget("settingsApplyButton", button); button->set_sensitive(false); builder->get_widget("settingsOkButton", button); button->set_sensitive(false); builder->get_widget("settingsMouseDeviceComboBox", combobox); combobox->set_sensitive(false); Glib::signal_timeout().connect( sigc::mem_fun(*this, &ManglerSettings::settingsPTTMouseDetect), 100 ); }/*}}}*/ std::map ManglerSettings::getInputDeviceList(void) {/*{{{*/ GdkWindow *rootwin = gdk_get_default_root_window(); XDeviceInfo *xdev; int ndevices_return; std::map devicelist; xdev = XListInputDevices(GDK_WINDOW_XDISPLAY(rootwin), &ndevices_return); for (int ctr = 0; ctr < ndevices_return; ctr++) { if (xdev[ctr].use == IsXExtensionPointer) { devicelist[xdev[ctr].id] = xdev[ctr].name; } } XFreeDeviceList(xdev); return(devicelist); }/*}}}*/ void ManglerSettings::audioSubsystemComboBox_changed_cb(void) {/*{{{*/ Gtk::TreeModel::iterator iter; iter = audioSubsystemComboBox->get_active(); if (iter) { Gtk::TreeModel::Row row = *iter; Glib::ustring id = row[audioSubsystemColumns.id]; Glib::ustring name = row[audioSubsystemColumns.name]; if (mangler) { mangler->audioControl->getDeviceList(id); updateDeviceComboBoxes(); } } }/*}}}*/ bool ManglerSettings::settingsPTTKeyDetect(void) {/*{{{*/ char pressed_keys[32]; Glib::ustring ptt_keylist; GdkWindow *rootwin = gdk_get_default_root_window(); // TODO: window close event needs to set isDetectingKey if (!isDetectingKey) { return false; } /* * Query the X keymap and get a list of all the keys are pressed. Convert * keycodes to keysyms to keynames and build a human readable string that * will be the actual value stored in the settings file */ XQueryKeymap(GDK_WINDOW_XDISPLAY(rootwin), pressed_keys); for (int ctr = 0; ctr < 256; ctr++) { if ((pressed_keys[ctr >> 3] >> (ctr & 0x07)) & 0x01) { char *keystring = XKeysymToString(XKeycodeToKeysym(GDK_WINDOW_XDISPLAY(rootwin), ctr, 0)); if (keystring == NULL) continue; std::string keyname = keystring; if (keyname.length() > 1) { ptt_keylist.insert(0, "<" + keyname + ">" + (ptt_keylist.empty() ? "" : "+")); } else { keyname[0] = toupper(keyname[0]); ptt_keylist.append((ptt_keylist.empty() ? "" : "+") + keyname); } } } builder->get_widget("settingsPTTKeyValueLabel", label); if (ptt_keylist.empty()) { label->set_markup(PTT_KEY_SET); } else { label->set_text(ptt_keylist); } return(true); }/*}}}*/ bool ManglerSettings::settingsPTTMouseDetect(void) {/*{{{*/ GdkWindow *rootwin = gdk_get_default_root_window(); Glib::ustring buttonname; char mousebutton[8]; static bool grabbed = false; int flag = 0; int x, y; XEvent ev; // TODO: window close event needs to set isDetectingKey if (!isDetectingMouse) { return false; } if (! grabbed) { XUngrabPointer(GDK_WINDOW_XDISPLAY(rootwin), CurrentTime); XGrabPointer(GDK_WINDOW_XDISPLAY(rootwin), GDK_ROOT_WINDOW(), False, ButtonPress, GrabModeAsync, GrabModeAsync, None, None, CurrentTime); grabbed = true; } while (flag == 0) { while (!XPending(GDK_WINDOW_XDISPLAY(rootwin))) { usleep(100000); } XNextEvent(GDK_WINDOW_XDISPLAY(rootwin), &ev); switch (ev.type) { case ButtonPress: snprintf(mousebutton, 7, "%d", ev.xbutton.button); buttonname = "Button" + Glib::ustring(mousebutton); flag = 1; XUngrabPointer(GDK_WINDOW_XDISPLAY(rootwin), CurrentTime); grabbed = false; isDetectingMouse = false; x = ev.xbutton.x_root; y = ev.xbutton.y_root; break; case MotionNotify: break; default: break; } XAllowEvents(GDK_WINDOW_XDISPLAY(rootwin), AsyncBoth, CurrentTime); } isDetectingMouse = false; builder->get_widget("settingsPTTMouseValueLabel", label); label->set_markup(buttonname); builder->get_widget("settingsCancelButton", button); button->set_sensitive(true); builder->get_widget("settingsApplyButton", button); button->set_sensitive(true); builder->get_widget("settingsOkButton", button); button->set_sensitive(true); builder->get_widget("settingsOkButton", button); button->set_sensitive(true); builder->get_widget("settingsPTTMouseButton", button); button->set_sensitive(true); builder->get_widget("settingsMouseDeviceComboBox", combobox); combobox->set_sensitive(true); return(true); }/*}}}*/ void ManglerSettings::updateDeviceComboBoxes(void) {/*{{{*/ Gtk::TreeModel::Row row; Gtk::TreeModel::iterator iter; // Clear the input device store and rebuild it from the audioControl vector inputDeviceTreeModel->clear(); row = *(inputDeviceTreeModel->append()); row[inputColumns.id] = -1; row[inputColumns.name] = "Default"; row[inputColumns.description] = "Default"; int inputSelection = 0; int inputCtr = 1; for ( std::vector::iterator i = mangler->audioControl->inputDevices.begin(); i < mangler->audioControl->inputDevices.end(); i++, inputCtr++) { Gtk::TreeModel::Row row = *(inputDeviceTreeModel->append()); row[inputColumns.id] = (*i)->id; row[inputColumns.name] = (*i)->name; row[inputColumns.description] = (*i)->description; if (Mangler::config["InputDeviceName"] == (*i)->name) { inputSelection = inputCtr; } } iter = audioSubsystemComboBox->get_active(); if (iter && (*iter)[audioSubsystemColumns.id] != "pulse") { row = *(inputDeviceTreeModel->append()); row[inputColumns.id] = -2; row[inputColumns.name] = "Custom"; row[inputColumns.description] = "Custom"; if (Mangler::config["InputDeviceName"] == "Custom") { inputSelection = inputCtr; } } // TODO: get the currently selected item from settings object and select it inputDeviceComboBox->set_active(inputSelection); // Clear the output device store and rebuild it from the audioControl vector outputDeviceTreeModel->clear(); row = *(outputDeviceTreeModel->append()); row[outputColumns.id] = -1; row[outputColumns.name] = "Default"; row[outputColumns.description] = "Default"; int outputSelection = 0; int outputCtr = 1; for ( std::vector::iterator i = mangler->audioControl->outputDevices.begin(); i < mangler->audioControl->outputDevices.end(); i++, outputCtr++) { Gtk::TreeModel::Row row = *(outputDeviceTreeModel->append()); row[outputColumns.id] = (*i)->id; row[outputColumns.name] = (*i)->name; row[outputColumns.description] = (*i)->description; if (Mangler::config["OutputDeviceName"] == (*i)->name) { outputSelection = outputCtr; } } iter = audioSubsystemComboBox->get_active(); if (iter && (*iter)[audioSubsystemColumns.id] != "pulse") { row = *(outputDeviceTreeModel->append()); row[outputColumns.id] = -2; row[outputColumns.name] = "Custom"; row[outputColumns.description] = "Custom"; if (Mangler::config["OutputDeviceName"] == "Custom") { outputSelection = outputCtr; } } // TODO: get the currently selected item from settings object and select it outputDeviceComboBox->set_active(outputSelection); // Clear the notification device store and rebuild it from the audioControl vector notificationDeviceTreeModel->clear(); row = *(notificationDeviceTreeModel->append()); row[notificationColumns.id] = -1; row[notificationColumns.name] = "Default"; row[notificationColumns.description] = "Default"; int notificationSelection = 0; int notificationCtr = 1; for ( std::vector::iterator i = mangler->audioControl->outputDevices.begin(); i < mangler->audioControl->outputDevices.end(); i++, notificationCtr++) { Gtk::TreeModel::Row row = *(notificationDeviceTreeModel->append()); row[notificationColumns.id] = (*i)->id; row[notificationColumns.name] = (*i)->name; row[notificationColumns.description] = (*i)->description; if (Mangler::config["NotificationDeviceName"] == (*i)->name) { notificationSelection = notificationCtr; } } iter = audioSubsystemComboBox->get_active(); if (iter && (*iter)[audioSubsystemColumns.id] != "pulse") { row = *(notificationDeviceTreeModel->append()); row[notificationColumns.id] = -2; row[notificationColumns.name] = "Custom"; row[notificationColumns.description] = "Custom"; if (Mangler::config["NotificationDeviceName"] == "Custom") { notificationSelection = notificationCtr; } } // TODO: get the currently selected item from settings object and select it notificationDeviceComboBox->set_active(notificationSelection); }/*}}}*/ void ManglerSettings::inputDeviceComboBox_changed_cb(void) {/*{{{*/ Gtk::TreeModel::iterator iter = inputDeviceComboBox->get_active(); builder->get_widget("CustomInputLabel", label); if (iter && (*iter)[inputColumns.id] == -2) { inputDeviceCustomName->show(); label->show(); return; } inputDeviceCustomName->hide(); label->hide(); }/*}}}*/ void ManglerSettings::outputDeviceComboBox_changed_cb(void) {/*{{{*/ Gtk::TreeModel::iterator iter = outputDeviceComboBox->get_active(); builder->get_widget("CustomOutputLabel", label); if (iter && (*iter)[outputColumns.id] == -2) { outputDeviceCustomName->show(); label->show(); return; } outputDeviceCustomName->hide(); label->hide(); }/*}}}*/ void ManglerSettings::notificationDeviceComboBox_changed_cb(void) {/*{{{*/ Gtk::TreeModel::iterator iter = notificationDeviceComboBox->get_active(); builder->get_widget("CustomNotificationLabel", label); if (iter && (*iter)[notificationColumns.id] == -2) { notificationDeviceCustomName->show(); label->show(); return; } notificationDeviceCustomName->hide(); label->hide(); }/*}}}*/