Merge pull request #1935 from obsproject/clang-format

Apply clang-format to the project
This commit is contained in:
Jim 2019-06-24 19:41:51 -07:00 committed by GitHub
commit c938ea712b
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
587 changed files with 34226 additions and 32904 deletions

106
.clang-format Normal file
View file

@ -0,0 +1,106 @@
# please use clang-format version 8 or later
Language: Cpp
Standard: Cpp11
AccessModifierOffset: -8
AlignAfterOpenBracket: Align
AlignConsecutiveAssignments: false
AlignConsecutiveDeclarations: false
AlignEscapedNewlines: Left
AlignOperands: true
AlignTrailingComments: true
#AllowAllArgumentsOnNextLine: false # requires clang-format 9
#AllowAllConstructorInitializersOnNextLine: false # requires clang-format 9
AllowAllParametersOfDeclarationOnNextLine: false
AllowShortBlocksOnASingleLine: false
AllowShortCaseLabelsOnASingleLine: false
AllowShortFunctionsOnASingleLine: Inline
AllowShortIfStatementsOnASingleLine: false
#AllowShortLambdasOnASingleLine: Inline # requires clang-format 9
AllowShortLoopsOnASingleLine: false
AlwaysBreakAfterDefinitionReturnType: None
AlwaysBreakAfterReturnType: None
AlwaysBreakBeforeMultilineStrings: false
AlwaysBreakTemplateDeclarations: false
BinPackArguments: true
BinPackParameters: true
BraceWrapping:
AfterClass: false
AfterControlStatement: false
AfterEnum: false
AfterFunction: true
AfterNamespace: false
AfterObjCDeclaration: false
AfterStruct: false
AfterUnion: false
AfterExternBlock: false
BeforeCatch: false
BeforeElse: false
IndentBraces: false
SplitEmptyFunction: true
SplitEmptyRecord: true
SplitEmptyNamespace: true
BreakBeforeBinaryOperators: None
BreakBeforeBraces: Custom
BreakBeforeTernaryOperators: true
BreakConstructorInitializers: BeforeColon
BreakStringLiterals: false # apparently unpredictable
ColumnLimit: 80
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 8
ContinuationIndentWidth: 8
Cpp11BracedListStyle: true
DerivePointerAlignment: false
DisableFormat: false
FixNamespaceComments: false
ForEachMacros:
- 'json_object_foreach'
- 'json_object_foreach_safe'
- 'json_array_foreach'
IncludeBlocks: Preserve
IndentCaseLabels: false
IndentPPDirectives: None
IndentWidth: 8
IndentWrappedFunctionNames: false
KeepEmptyLinesAtTheStartOfBlocks: true
MaxEmptyLinesToKeep: 1
NamespaceIndentation: None
ObjCBinPackProtocolList: Auto # requires clang-format 7
ObjCBlockIndentWidth: 8
ObjCSpaceAfterProperty: true
ObjCSpaceBeforeProtocolList: true
PenaltyBreakAssignment: 10
PenaltyBreakBeforeFirstCallParameter: 30
PenaltyBreakComment: 10
PenaltyBreakFirstLessLess: 0
PenaltyBreakString: 10
PenaltyExcessCharacter: 100
PenaltyReturnTypeOnItsOwnLine: 60
PointerAlignment: Right
ReflowComments: false
SortIncludes: false
SortUsingDeclarations: false
SpaceAfterCStyleCast: false
#SpaceAfterLogicalNot: false # requires clang-format 9
SpaceAfterTemplateKeyword: false
SpaceBeforeAssignmentOperators: true
SpaceBeforeCtorInitializerColon: true # requires clang-format 7
SpaceBeforeInheritanceColon: true # requires clang-format 7
SpaceBeforeParens: ControlStatements
SpaceBeforeRangeBasedForLoopColon: true # requires clang-format 7
SpaceInEmptyParentheses: false
SpacesBeforeTrailingComments: 1
SpacesInAngles: false
SpacesInCStyleCastParentheses: false
SpacesInContainerLiterals: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
StatementMacros: # requires clang-format 8
- 'Q_OBJECT'
TabWidth: 8
#TypenameMacros: # requires clang-format 9
# - 'DARRAY'
UseTab: ForContinuationAndIndentation

View file

@ -26,34 +26,34 @@ OBSAdvAudioCtrl::OBSAdvAudioCtrl(QGridLayout *, obs_source_t *source_)
uint32_t flags = obs_source_get_flags(source);
uint32_t mixers = obs_source_get_audio_mixers(source);
forceMonoContainer = new QWidget();
mixerContainer = new QWidget();
balanceContainer = new QWidget();
labelL = new QLabel();
labelR = new QLabel();
nameLabel = new QLabel();
volume = new QDoubleSpinBox();
forceMono = new QCheckBox();
balance = new BalanceSlider();
forceMonoContainer = new QWidget();
mixerContainer = new QWidget();
balanceContainer = new QWidget();
labelL = new QLabel();
labelR = new QLabel();
nameLabel = new QLabel();
volume = new QDoubleSpinBox();
forceMono = new QCheckBox();
balance = new BalanceSlider();
#if defined(_WIN32) || defined(__APPLE__) || HAVE_PULSEAUDIO
monitoringType = new QComboBox();
monitoringType = new QComboBox();
#endif
syncOffset = new QSpinBox();
mixer1 = new QCheckBox();
mixer2 = new QCheckBox();
mixer3 = new QCheckBox();
mixer4 = new QCheckBox();
mixer5 = new QCheckBox();
mixer6 = new QCheckBox();
syncOffset = new QSpinBox();
mixer1 = new QCheckBox();
mixer2 = new QCheckBox();
mixer3 = new QCheckBox();
mixer4 = new QCheckBox();
mixer5 = new QCheckBox();
mixer6 = new QCheckBox();
volChangedSignal.Connect(handler, "volume", OBSSourceVolumeChanged,
this);
this);
syncOffsetSignal.Connect(handler, "audio_sync", OBSSourceSyncChanged,
this);
this);
flagsSignal.Connect(handler, "update_flags", OBSSourceFlagsChanged,
this);
this);
mixersSignal.Connect(handler, "audio_mixers", OBSSourceMixersChanged,
this);
this);
hlayout = new QHBoxLayout();
hlayout->setContentsMargins(0, 0, 0, 0);
@ -87,8 +87,8 @@ OBSAdvAudioCtrl::OBSAdvAudioCtrl(QGridLayout *, obs_source_t *source_)
forceMono->setChecked((flags & OBS_SOURCE_FLAG_FORCE_MONO) != 0);
forceMonoContainer->layout()->addWidget(forceMono);
forceMonoContainer->layout()->setAlignment(forceMono,
Qt::AlignHCenter | Qt::AlignVCenter);
forceMonoContainer->layout()->setAlignment(
forceMono, Qt::AlignHCenter | Qt::AlignVCenter);
balance->setOrientation(Qt::Horizontal);
balance->setMinimum(0);
@ -96,10 +96,10 @@ OBSAdvAudioCtrl::OBSAdvAudioCtrl(QGridLayout *, obs_source_t *source_)
balance->setTickPosition(QSlider::TicksAbove);
balance->setTickInterval(50);
OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
const char *speakers = config_get_string(main->Config(), "Audio",
"ChannelSetup");
const char *speakers =
config_get_string(main->Config(), "Audio", "ChannelSetup");
if (strcmp(speakers, "Mono") == 0)
balance->setEnabled(false);
@ -117,31 +117,31 @@ OBSAdvAudioCtrl::OBSAdvAudioCtrl(QGridLayout *, obs_source_t *source_)
int idx;
#if defined(_WIN32) || defined(__APPLE__) || HAVE_PULSEAUDIO
monitoringType->addItem(QTStr("Basic.AdvAudio.Monitoring.None"),
(int)OBS_MONITORING_TYPE_NONE);
(int)OBS_MONITORING_TYPE_NONE);
monitoringType->addItem(QTStr("Basic.AdvAudio.Monitoring.MonitorOnly"),
(int)OBS_MONITORING_TYPE_MONITOR_ONLY);
(int)OBS_MONITORING_TYPE_MONITOR_ONLY);
monitoringType->addItem(QTStr("Basic.AdvAudio.Monitoring.Both"),
(int)OBS_MONITORING_TYPE_MONITOR_AND_OUTPUT);
(int)OBS_MONITORING_TYPE_MONITOR_AND_OUTPUT);
int mt = (int)obs_source_get_monitoring_type(source);
idx = monitoringType->findData(mt);
monitoringType->setCurrentIndex(idx);
#endif
mixer1->setText("1");
mixer1->setChecked(mixers & (1<<0));
mixer1->setChecked(mixers & (1 << 0));
mixer2->setText("2");
mixer2->setChecked(mixers & (1<<1));
mixer2->setChecked(mixers & (1 << 1));
mixer3->setText("3");
mixer3->setChecked(mixers & (1<<2));
mixer3->setChecked(mixers & (1 << 2));
mixer4->setText("4");
mixer4->setChecked(mixers & (1<<3));
mixer4->setChecked(mixers & (1 << 3));
mixer5->setText("5");
mixer5->setChecked(mixers & (1<<4));
mixer5->setChecked(mixers & (1 << 4));
mixer6->setText("6");
mixer6->setChecked(mixers & (1<<5));
mixer6->setChecked(mixers & (1 << 5));
speaker_layout sl = obs_source_get_speaker_layout(source);
if (sl == SPEAKERS_STEREO) {
balanceContainer->layout()->addWidget(labelL);
balanceContainer->layout()->addWidget(balance);
@ -156,32 +156,32 @@ OBSAdvAudioCtrl::OBSAdvAudioCtrl(QGridLayout *, obs_source_t *source_)
mixerContainer->layout()->addWidget(mixer5);
mixerContainer->layout()->addWidget(mixer6);
QWidget::connect(volume, SIGNAL(valueChanged(double)),
this, SLOT(volumeChanged(double)));
QWidget::connect(forceMono, SIGNAL(clicked(bool)),
this, SLOT(downmixMonoChanged(bool)));
QWidget::connect(balance, SIGNAL(valueChanged(int)),
this, SLOT(balanceChanged(int)));
QWidget::connect(balance, SIGNAL(doubleClicked()),
this, SLOT(ResetBalance()));
QWidget::connect(syncOffset, SIGNAL(valueChanged(int)),
this, SLOT(syncOffsetChanged(int)));
QWidget::connect(volume, SIGNAL(valueChanged(double)), this,
SLOT(volumeChanged(double)));
QWidget::connect(forceMono, SIGNAL(clicked(bool)), this,
SLOT(downmixMonoChanged(bool)));
QWidget::connect(balance, SIGNAL(valueChanged(int)), this,
SLOT(balanceChanged(int)));
QWidget::connect(balance, SIGNAL(doubleClicked()), this,
SLOT(ResetBalance()));
QWidget::connect(syncOffset, SIGNAL(valueChanged(int)), this,
SLOT(syncOffsetChanged(int)));
#if defined(_WIN32) || defined(__APPLE__) || HAVE_PULSEAUDIO
QWidget::connect(monitoringType, SIGNAL(currentIndexChanged(int)),
this, SLOT(monitoringTypeChanged(int)));
QWidget::connect(monitoringType, SIGNAL(currentIndexChanged(int)), this,
SLOT(monitoringTypeChanged(int)));
#endif
QWidget::connect(mixer1, SIGNAL(clicked(bool)),
this, SLOT(mixer1Changed(bool)));
QWidget::connect(mixer2, SIGNAL(clicked(bool)),
this, SLOT(mixer2Changed(bool)));
QWidget::connect(mixer3, SIGNAL(clicked(bool)),
this, SLOT(mixer3Changed(bool)));
QWidget::connect(mixer4, SIGNAL(clicked(bool)),
this, SLOT(mixer4Changed(bool)));
QWidget::connect(mixer5, SIGNAL(clicked(bool)),
this, SLOT(mixer5Changed(bool)));
QWidget::connect(mixer6, SIGNAL(clicked(bool)),
this, SLOT(mixer6Changed(bool)));
QWidget::connect(mixer1, SIGNAL(clicked(bool)), this,
SLOT(mixer1Changed(bool)));
QWidget::connect(mixer2, SIGNAL(clicked(bool)), this,
SLOT(mixer2Changed(bool)));
QWidget::connect(mixer3, SIGNAL(clicked(bool)), this,
SLOT(mixer3Changed(bool)));
QWidget::connect(mixer4, SIGNAL(clicked(bool)), this,
SLOT(mixer4Changed(bool)));
QWidget::connect(mixer5, SIGNAL(clicked(bool)), this,
SLOT(mixer5Changed(bool)));
QWidget::connect(mixer6, SIGNAL(clicked(bool)), this,
SLOT(mixer6Changed(bool)));
setObjectName(sourceName);
}
@ -214,7 +214,7 @@ void OBSAdvAudioCtrl::ShowAudioControl(QGridLayout *layout)
#endif
layout->addWidget(mixerContainer, lastRow, idx++);
layout->layout()->setAlignment(mixerContainer,
Qt::AlignHCenter | Qt::AlignVCenter);
Qt::AlignHCenter | Qt::AlignVCenter);
}
/* ------------------------------------------------------------------------- */
@ -223,30 +223,30 @@ void OBSAdvAudioCtrl::ShowAudioControl(QGridLayout *layout)
void OBSAdvAudioCtrl::OBSSourceFlagsChanged(void *param, calldata_t *calldata)
{
uint32_t flags = (uint32_t)calldata_int(calldata, "flags");
QMetaObject::invokeMethod(reinterpret_cast<OBSAdvAudioCtrl*>(param),
"SourceFlagsChanged", Q_ARG(uint32_t, flags));
QMetaObject::invokeMethod(reinterpret_cast<OBSAdvAudioCtrl *>(param),
"SourceFlagsChanged", Q_ARG(uint32_t, flags));
}
void OBSAdvAudioCtrl::OBSSourceVolumeChanged(void *param, calldata_t *calldata)
{
float volume = (float)calldata_float(calldata, "volume");
QMetaObject::invokeMethod(reinterpret_cast<OBSAdvAudioCtrl*>(param),
"SourceVolumeChanged", Q_ARG(float, volume));
QMetaObject::invokeMethod(reinterpret_cast<OBSAdvAudioCtrl *>(param),
"SourceVolumeChanged", Q_ARG(float, volume));
}
void OBSAdvAudioCtrl::OBSSourceSyncChanged(void *param, calldata_t *calldata)
{
int64_t offset = calldata_int(calldata, "offset");
QMetaObject::invokeMethod(reinterpret_cast<OBSAdvAudioCtrl*>(param),
"SourceSyncChanged", Q_ARG(int64_t, offset));
QMetaObject::invokeMethod(reinterpret_cast<OBSAdvAudioCtrl *>(param),
"SourceSyncChanged", Q_ARG(int64_t, offset));
}
void OBSAdvAudioCtrl::OBSSourceMixersChanged(void *param, calldata_t *calldata)
{
uint32_t mixers = (uint32_t)calldata_int(calldata, "mixers");
QMetaObject::invokeMethod(reinterpret_cast<OBSAdvAudioCtrl*>(param),
"SourceMixersChanged", Q_ARG(uint32_t, mixers));
QMetaObject::invokeMethod(reinterpret_cast<OBSAdvAudioCtrl *>(param),
"SourceMixersChanged",
Q_ARG(uint32_t, mixers));
}
/* ------------------------------------------------------------------------- */
@ -279,12 +279,12 @@ void OBSAdvAudioCtrl::SourceSyncChanged(int64_t offset)
void OBSAdvAudioCtrl::SourceMixersChanged(uint32_t mixers)
{
setCheckboxState(mixer1, mixers & (1<<0));
setCheckboxState(mixer2, mixers & (1<<1));
setCheckboxState(mixer3, mixers & (1<<2));
setCheckboxState(mixer4, mixers & (1<<3));
setCheckboxState(mixer5, mixers & (1<<4));
setCheckboxState(mixer6, mixers & (1<<5));
setCheckboxState(mixer1, mixers & (1 << 0));
setCheckboxState(mixer2, mixers & (1 << 1));
setCheckboxState(mixer3, mixers & (1 << 2));
setCheckboxState(mixer4, mixers & (1 << 3));
setCheckboxState(mixer5, mixers & (1 << 4));
setCheckboxState(mixer6, mixers & (1 << 5));
}
/* ------------------------------------------------------------------------- */
@ -335,14 +335,13 @@ void OBSAdvAudioCtrl::ResetBalance()
balance->setValue(50);
}
void OBSAdvAudioCtrl::syncOffsetChanged(int milliseconds)
{
int64_t cur_val = obs_source_get_sync_offset(source);
if (cur_val / NSEC_PER_MSEC != milliseconds)
obs_source_set_sync_offset(source,
int64_t(milliseconds) * NSEC_PER_MSEC);
obs_source_set_sync_offset(source, int64_t(milliseconds) *
NSEC_PER_MSEC);
}
void OBSAdvAudioCtrl::monitoringTypeChanged(int index)
@ -365,17 +364,19 @@ void OBSAdvAudioCtrl::monitoringTypeChanged(int index)
}
blog(LOG_INFO, "User changed audio monitoring for source '%s' to: %s",
obs_source_get_name(source), type);
obs_source_get_name(source), type);
}
static inline void setMixer(obs_source_t *source, const int mixerIdx,
const bool checked)
const bool checked)
{
uint32_t mixers = obs_source_get_audio_mixers(source);
uint32_t new_mixers = mixers;
if (checked) new_mixers |= (1<<mixerIdx);
else new_mixers &= ~(1<<mixerIdx);
if (checked)
new_mixers |= (1 << mixerIdx);
else
new_mixers &= ~(1 << mixerIdx);
obs_source_set_audio_mixers(source, new_mixers);
}

View file

@ -16,31 +16,31 @@ class OBSAdvAudioCtrl : public QObject {
Q_OBJECT
private:
OBSSource source;
OBSSource source;
QPointer<QWidget> forceMonoContainer;
QPointer<QWidget> mixerContainer;
QPointer<QWidget> balanceContainer;
QPointer<QWidget> forceMonoContainer;
QPointer<QWidget> mixerContainer;
QPointer<QWidget> balanceContainer;
QPointer<QLabel> nameLabel;
QPointer<QLabel> nameLabel;
QPointer<QDoubleSpinBox> volume;
QPointer<QCheckBox> forceMono;
QPointer<BalanceSlider>balance;
QPointer<QLabel> labelL;
QPointer<QLabel> labelR;
QPointer<QSpinBox> syncOffset;
QPointer<QComboBox> monitoringType;
QPointer<QCheckBox> mixer1;
QPointer<QCheckBox> mixer2;
QPointer<QCheckBox> mixer3;
QPointer<QCheckBox> mixer4;
QPointer<QCheckBox> mixer5;
QPointer<QCheckBox> mixer6;
QPointer<QCheckBox> forceMono;
QPointer<BalanceSlider> balance;
QPointer<QLabel> labelL;
QPointer<QLabel> labelR;
QPointer<QSpinBox> syncOffset;
QPointer<QComboBox> monitoringType;
QPointer<QCheckBox> mixer1;
QPointer<QCheckBox> mixer2;
QPointer<QCheckBox> mixer3;
QPointer<QCheckBox> mixer4;
QPointer<QCheckBox> mixer5;
QPointer<QCheckBox> mixer6;
OBSSignal volChangedSignal;
OBSSignal syncOffsetSignal;
OBSSignal flagsSignal;
OBSSignal mixersSignal;
OBSSignal volChangedSignal;
OBSSignal syncOffsetSignal;
OBSSignal flagsSignal;
OBSSignal mixersSignal;
static void OBSSourceFlagsChanged(void *param, calldata_t *calldata);
static void OBSSourceVolumeChanged(void *param, calldata_t *calldata);
@ -51,7 +51,7 @@ public:
OBSAdvAudioCtrl(QGridLayout *layout, obs_source_t *source_);
virtual ~OBSAdvAudioCtrl();
inline obs_source_t *GetSource() const {return source;}
inline obs_source_t *GetSource() const { return source; }
void ShowAudioControl(QGridLayout *layout);
public slots:

View file

@ -11,14 +11,13 @@ using namespace std;
Q_DECLARE_METATYPE(OBSScene);
Q_DECLARE_METATYPE(OBSSource);
template <typename T>
static T GetOBSRef(QListWidgetItem *item)
template<typename T> static T GetOBSRef(QListWidgetItem *item)
{
return item->data(static_cast<int>(QtDataRole::OBSRef)).value<T>();
}
void EnumProfiles(function<bool (const char *, const char *)> &&cb);
void EnumSceneCollections(function<bool (const char *, const char *)> &&cb);
void EnumProfiles(function<bool(const char *, const char *)> &&cb);
void EnumSceneCollections(function<bool(const char *, const char *)> &&cb);
extern volatile bool streaming_active;
extern volatile bool recording_active;
@ -30,18 +29,18 @@ template<typename T> struct OBSStudioCallback {
T callback;
void *private_data;
inline OBSStudioCallback(T cb, void *p) :
callback(cb), private_data(p)
{}
inline OBSStudioCallback(T cb, void *p) : callback(cb), private_data(p)
{
}
};
template <typename T> inline size_t GetCallbackIdx(
vector<OBSStudioCallback<T>> &callbacks,
T callback, void *private_data)
template<typename T>
inline size_t GetCallbackIdx(vector<OBSStudioCallback<T>> &callbacks,
T callback, void *private_data)
{
for (size_t i = 0; i < callbacks.size(); i++) {
OBSStudioCallback<T> curCB = callbacks[i];
if (curCB.callback == callback &&
if (curCB.callback == callback &&
curCB.private_data == private_data)
return i;
}
@ -59,21 +58,21 @@ struct OBSStudioAPI : obs_frontend_callbacks {
void *obs_frontend_get_main_window(void) override
{
return (void*)main;
return (void *)main;
}
void *obs_frontend_get_main_window_handle(void) override
{
return (void*)main->winId();
return (void *)main->winId();
}
void *obs_frontend_get_system_tray(void) override
{
return (void*)main->trayIcon.data();
return (void *)main->trayIcon.data();
}
void obs_frontend_get_scenes(
struct obs_frontend_source_list *sources) override
struct obs_frontend_source_list *sources) override
{
for (int i = 0; i < main->ui->scenes->count(); i++) {
QListWidgetItem *item = main->ui->scenes->item(i);
@ -101,23 +100,23 @@ struct OBSStudioAPI : obs_frontend_callbacks {
void obs_frontend_set_current_scene(obs_source_t *scene) override
{
if (main->IsPreviewProgramMode()) {
QMetaObject::invokeMethod(main, "TransitionToScene",
WaitConnection(),
Q_ARG(OBSSource, OBSSource(scene)));
QMetaObject::invokeMethod(
main, "TransitionToScene", WaitConnection(),
Q_ARG(OBSSource, OBSSource(scene)));
} else {
QMetaObject::invokeMethod(main, "SetCurrentScene",
WaitConnection(),
Q_ARG(OBSSource, OBSSource(scene)),
Q_ARG(bool, false));
QMetaObject::invokeMethod(
main, "SetCurrentScene", WaitConnection(),
Q_ARG(OBSSource, OBSSource(scene)),
Q_ARG(bool, false));
}
}
void obs_frontend_get_transitions(
struct obs_frontend_source_list *sources) override
struct obs_frontend_source_list *sources) override
{
for (int i = 0; i < main->ui->transitions->count(); i++) {
OBSSource tr = main->ui->transitions->itemData(i)
.value<OBSSource>();
.value<OBSSource>();
obs_source_addref(tr);
da_push_back(sources->sources, &tr);
@ -132,11 +131,12 @@ struct OBSStudioAPI : obs_frontend_callbacks {
return tr;
}
void obs_frontend_set_current_transition(
obs_source_t *transition) override
void
obs_frontend_set_current_transition(obs_source_t *transition) override
{
QMetaObject::invokeMethod(main, "SetTransition",
Q_ARG(OBSSource, OBSSource(transition)));
Q_ARG(OBSSource,
OBSSource(transition)));
}
int obs_frontend_get_transition_duration(void) override
@ -146,15 +146,14 @@ struct OBSStudioAPI : obs_frontend_callbacks {
void obs_frontend_set_transition_duration(int duration) override
{
QMetaObject::invokeMethod(main->ui->transitionDuration, "setValue",
Q_ARG(int, duration));
QMetaObject::invokeMethod(main->ui->transitionDuration,
"setValue", Q_ARG(int, duration));
}
void obs_frontend_get_scene_collections(
std::vector<std::string> &strings) override
std::vector<std::string> &strings) override
{
auto addCollection = [&](const char *name, const char *)
{
auto addCollection = [&](const char *name, const char *) {
strings.emplace_back(name);
return true;
};
@ -164,15 +163,15 @@ struct OBSStudioAPI : obs_frontend_callbacks {
char *obs_frontend_get_current_scene_collection(void) override
{
const char *cur_name = config_get_string(App()->GlobalConfig(),
"Basic", "SceneCollection");
const char *cur_name = config_get_string(
App()->GlobalConfig(), "Basic", "SceneCollection");
return bstrdup(cur_name);
}
void obs_frontend_set_current_scene_collection(
const char *collection) override
const char *collection) override
{
QList<QAction*> menuActions =
QList<QAction *> menuActions =
main->ui->sceneCollectionMenu->actions();
QString qstrCollection = QT_UTF8(collection);
@ -189,24 +188,21 @@ struct OBSStudioAPI : obs_frontend_callbacks {
}
}
bool obs_frontend_add_scene_collection(
const char *name) override
bool obs_frontend_add_scene_collection(const char *name) override
{
bool success = false;
QMetaObject::invokeMethod(main,
"AddSceneCollection",
WaitConnection(),
Q_RETURN_ARG(bool, success),
Q_ARG(bool, true),
Q_ARG(QString, QT_UTF8(name)));
QMetaObject::invokeMethod(main, "AddSceneCollection",
WaitConnection(),
Q_RETURN_ARG(bool, success),
Q_ARG(bool, true),
Q_ARG(QString, QT_UTF8(name)));
return success;
}
void obs_frontend_get_profiles(
std::vector<std::string> &strings) override
void
obs_frontend_get_profiles(std::vector<std::string> &strings) override
{
auto addProfile = [&](const char *name, const char *)
{
auto addProfile = [&](const char *name, const char *) {
strings.emplace_back(name);
return true;
};
@ -217,14 +213,13 @@ struct OBSStudioAPI : obs_frontend_callbacks {
char *obs_frontend_get_current_profile(void) override
{
const char *name = config_get_string(App()->GlobalConfig(),
"Basic", "Profile");
"Basic", "Profile");
return bstrdup(name);
}
void obs_frontend_set_current_profile(const char *profile) override
{
QList<QAction*> menuActions =
main->ui->profileMenu->actions();
QList<QAction *> menuActions = main->ui->profileMenu->actions();
QString qstrProfile = QT_UTF8(profile);
for (int i = 0; i < menuActions.count(); i++) {
@ -293,16 +288,16 @@ struct OBSStudioAPI : obs_frontend_callbacks {
void *obs_frontend_add_tools_menu_qaction(const char *name) override
{
main->ui->menuTools->setEnabled(true);
return (void*)main->ui->menuTools->addAction(QT_UTF8(name));
return (void *)main->ui->menuTools->addAction(QT_UTF8(name));
}
void obs_frontend_add_tools_menu_item(const char *name,
obs_frontend_cb callback, void *private_data) override
obs_frontend_cb callback,
void *private_data) override
{
main->ui->menuTools->setEnabled(true);
auto func = [private_data, callback] ()
{
auto func = [private_data, callback]() {
callback(private_data);
};
@ -312,11 +307,11 @@ struct OBSStudioAPI : obs_frontend_callbacks {
void *obs_frontend_add_dock(void *dock) override
{
return (void*)main->AddDockWidget((QDockWidget *)dock);
return (void *)main->AddDockWidget((QDockWidget *)dock);
}
void obs_frontend_add_event_callback(obs_frontend_event_cb callback,
void *private_data) override
void *private_data) override
{
size_t idx = GetCallbackIdx(callbacks, callback, private_data);
if (idx == (size_t)-1)
@ -324,7 +319,7 @@ struct OBSStudioAPI : obs_frontend_callbacks {
}
void obs_frontend_remove_event_callback(obs_frontend_event_cb callback,
void *private_data) override
void *private_data) override
{
size_t idx = GetCallbackIdx(callbacks, callback, private_data);
if (idx == (size_t)-1)
@ -364,10 +359,7 @@ struct OBSStudioAPI : obs_frontend_callbacks {
return App()->GlobalConfig();
}
void obs_frontend_save(void) override
{
main->SaveProject();
}
void obs_frontend_save(void) override { main->SaveProject(); }
void obs_frontend_defer_save_begin(void) override
{
@ -380,19 +372,19 @@ struct OBSStudioAPI : obs_frontend_callbacks {
}
void obs_frontend_add_save_callback(obs_frontend_save_cb callback,
void *private_data) override
void *private_data) override
{
size_t idx = GetCallbackIdx(saveCallbacks, callback,
private_data);
size_t idx =
GetCallbackIdx(saveCallbacks, callback, private_data);
if (idx == (size_t)-1)
saveCallbacks.emplace_back(callback, private_data);
}
void obs_frontend_remove_save_callback(obs_frontend_save_cb callback,
void *private_data) override
void *private_data) override
{
size_t idx = GetCallbackIdx(saveCallbacks, callback,
private_data);
size_t idx =
GetCallbackIdx(saveCallbacks, callback, private_data);
if (idx == (size_t)-1)
return;
@ -400,19 +392,19 @@ struct OBSStudioAPI : obs_frontend_callbacks {
}
void obs_frontend_add_preload_callback(obs_frontend_save_cb callback,
void *private_data) override
void *private_data) override
{
size_t idx = GetCallbackIdx(preloadCallbacks, callback,
private_data);
private_data);
if (idx == (size_t)-1)
preloadCallbacks.emplace_back(callback, private_data);
}
void obs_frontend_remove_preload_callback(obs_frontend_save_cb callback,
void *private_data) override
void *private_data) override
{
size_t idx = GetCallbackIdx(preloadCallbacks, callback,
private_data);
private_data);
if (idx == (size_t)-1)
return;
@ -420,7 +412,7 @@ struct OBSStudioAPI : obs_frontend_callbacks {
}
void obs_frontend_push_ui_translation(
obs_frontend_translate_ui_cb translate) override
obs_frontend_translate_ui_cb translate) override
{
App()->PushUITranslation(translate);
}
@ -483,12 +475,14 @@ struct OBSStudioAPI : obs_frontend_callbacks {
return source;
}
void obs_frontend_set_current_preview_scene(obs_source_t *scene) override
void
obs_frontend_set_current_preview_scene(obs_source_t *scene) override
{
if (main->IsPreviewProgramMode()) {
QMetaObject::invokeMethod(main, "SetCurrentScene",
Q_ARG(OBSSource, OBSSource(scene)),
Q_ARG(bool, false));
Q_ARG(OBSSource,
OBSSource(scene)),
Q_ARG(bool, false));
}
}

View file

@ -32,7 +32,7 @@ static const char *EncoderName(const char *id)
return NullToEmpty(obs_encoder_get_display_name(id));
}
static map<int, const char*> bitrateMap;
static map<int, const char *> bitrateMap;
static once_flag populateBitrateMap;
static void HandleIntProperty(obs_property_t *prop, const char *id)
@ -48,10 +48,11 @@ static void HandleListProperty(obs_property_t *prop, const char *id)
{
obs_combo_format format = obs_property_list_format(prop);
if (format != OBS_COMBO_FORMAT_INT) {
blog(LOG_ERROR, "Encoder '%s' (%s) returned bitrate "
"OBS_PROPERTY_LIST property of unhandled "
"format %d",
EncoderName(id), id, static_cast<int>(format));
blog(LOG_ERROR,
"Encoder '%s' (%s) returned bitrate "
"OBS_PROPERTY_LIST property of unhandled "
"format %d",
EncoderName(id), id, static_cast<int>(format));
return;
}
@ -60,38 +61,35 @@ static void HandleListProperty(obs_property_t *prop, const char *id)
if (obs_property_list_item_disabled(prop, i))
continue;
int bitrate = static_cast<int>(
obs_property_list_item_int(prop, i));
int bitrate =
static_cast<int>(obs_property_list_item_int(prop, i));
bitrateMap[bitrate] = id;
}
}
static void HandleSampleRate(obs_property_t* prop, const char *id)
static void HandleSampleRate(obs_property_t *prop, const char *id)
{
auto ReleaseData = [](obs_data_t *data)
{
obs_data_release(data);
};
auto ReleaseData = [](obs_data_t *data) { obs_data_release(data); };
std::unique_ptr<obs_data_t, decltype(ReleaseData)> data{
obs_encoder_defaults(id),
ReleaseData};
obs_encoder_defaults(id), ReleaseData};
if (!data) {
blog(LOG_ERROR, "Failed to get defaults for encoder '%s' (%s) "
"while populating bitrate map",
EncoderName(id), id);
blog(LOG_ERROR,
"Failed to get defaults for encoder '%s' (%s) "
"while populating bitrate map",
EncoderName(id), id);
return;
}
auto main = reinterpret_cast<OBSMainWindow*>(App()->GetMainWindow());
auto main = reinterpret_cast<OBSMainWindow *>(App()->GetMainWindow());
if (!main) {
blog(LOG_ERROR, "Failed to get main window while populating "
"bitrate map");
return;
}
uint32_t sampleRate = config_get_uint(main->Config(), "Audio",
"SampleRate");
uint32_t sampleRate =
config_get_uint(main->Config(), "Audio", "SampleRate");
obs_data_set_int(data.get(), "samplerate", sampleRate);
@ -100,23 +98,22 @@ static void HandleSampleRate(obs_property_t* prop, const char *id)
static void HandleEncoderProperties(const char *id)
{
auto DestroyProperties = [](obs_properties_t *props)
{
auto DestroyProperties = [](obs_properties_t *props) {
obs_properties_destroy(props);
};
std::unique_ptr<obs_properties_t, decltype(DestroyProperties)> props{
obs_get_encoder_properties(id),
DestroyProperties};
obs_get_encoder_properties(id), DestroyProperties};
if (!props) {
blog(LOG_ERROR, "Failed to get properties for encoder "
"'%s' (%s)",
EncoderName(id), id);
blog(LOG_ERROR,
"Failed to get properties for encoder "
"'%s' (%s)",
EncoderName(id), id);
return;
}
obs_property_t *samplerate = obs_properties_get(props.get(),
"samplerate");
obs_property_t *samplerate =
obs_properties_get(props.get(), "samplerate");
if (samplerate)
HandleSampleRate(samplerate, id);
@ -130,12 +127,14 @@ static void HandleEncoderProperties(const char *id)
case OBS_PROPERTY_LIST:
return HandleListProperty(bitrate, id);
default: break;
default:
break;
}
blog(LOG_ERROR, "Encoder '%s' (%s) returned bitrate property "
"of unhandled type %d", EncoderName(id), id,
static_cast<int>(type));
blog(LOG_ERROR,
"Encoder '%s' (%s) returned bitrate property "
"of unhandled type %d",
EncoderName(id), id, static_cast<int>(type));
}
static const char *GetCodec(const char *id)
@ -146,8 +145,7 @@ static const char *GetCodec(const char *id)
static const string aac_ = "AAC";
static void PopulateBitrateMap()
{
call_once(populateBitrateMap, []()
{
call_once(populateBitrateMap, []() {
struct obs_audio_info aoi;
obs_get_audio_info(&aoi);
uint32_t output_channels = get_audio_channels(aoi.speakers);
@ -156,13 +154,12 @@ static void PopulateBitrateMap()
const char *id = nullptr;
for (size_t i = 0; obs_enum_encoder_types(i, &id); i++) {
auto Compare = [=](const string &val)
{
auto Compare = [=](const string &val) {
return val == NullToEmpty(id);
};
if (find_if(begin(encoders), end(encoders), Compare) !=
end(encoders))
end(encoders))
continue;
if (aac_ != GetCodec(id))
@ -198,11 +195,11 @@ static void PopulateBitrateMap()
<< entry.second << ')';
blog(LOG_DEBUG, "AAC encoder bitrate mapping:%s",
ss.str().c_str());
ss.str().c_str());
});
}
const map<int, const char*> &GetAACEncoderBitrateMap()
const map<int, const char *> &GetAACEncoderBitrateMap()
{
PopulateBitrateMap();
return bitrateMap;

View file

@ -4,6 +4,6 @@
#include <map>
const std::map<int, const char*> &GetAACEncoderBitrateMap();
const std::map<int, const char *> &GetAACEncoderBitrateMap();
const char *GetAACEncoderForBitrate(int bitrate);
int FindClosestAvailableAACBitrate(int bitrate);

View file

@ -43,7 +43,8 @@ void Auth::Load()
{
OBSBasic *main = OBSBasic::Get();
const char *typeStr = config_get_string(main->Config(), "Auth", "Type");
if (!typeStr) typeStr = "";
if (!typeStr)
typeStr = "";
main->auth = Create(typeStr);
if (main->auth) {

View file

@ -8,8 +8,8 @@ class Auth : public QObject {
Q_OBJECT
protected:
virtual void SaveInternal()=0;
virtual bool LoadInternal()=0;
virtual void SaveInternal() = 0;
virtual bool LoadInternal() = 0;
bool firstLoad = true;
@ -19,13 +19,14 @@ protected:
ErrorInfo(std::string message_, std::string error_)
: message(message_), error(error_)
{}
{
}
};
public:
enum class Type {
None,
OAuth_StreamKey
OAuth_StreamKey,
};
struct Def {
@ -33,13 +34,13 @@ public:
Type type;
};
typedef std::function<std::shared_ptr<Auth> ()> create_cb;
typedef std::function<std::shared_ptr<Auth>()> create_cb;
inline Auth(const Def &d) : def(d) {}
virtual ~Auth() {}
inline Type type() const {return def.type;}
inline const char *service() const {return def.service.c_str();}
inline Type type() const { return def.type; }
inline const char *service() const { return def.service.c_str(); }
virtual void LoadUI() {}

View file

@ -26,24 +26,16 @@ extern QCefCookieManager *panel_cookies;
/* ------------------------------------------------------------------------- */
#define MIXER_AUTH_URL \
"https://obsproject.com/app-auth/mixer?action=redirect"
#define MIXER_TOKEN_URL \
"https://obsproject.com/app-auth/mixer-token"
#define MIXER_AUTH_URL "https://obsproject.com/app-auth/mixer?action=redirect"
#define MIXER_TOKEN_URL "https://obsproject.com/app-auth/mixer-token"
#define MIXER_SCOPE_VERSION 1
static Auth::Def mixerDef = {
"Mixer",
Auth::Type::OAuth_StreamKey
};
static Auth::Def mixerDef = {"Mixer", Auth::Type::OAuth_StreamKey};
/* ------------------------------------------------------------------------- */
MixerAuth::MixerAuth(const Def &d)
: OAuthStreamKey(d)
{
}
MixerAuth::MixerAuth(const Def &d) : OAuthStreamKey(d) {}
bool MixerAuth::GetChannelInfo(bool allow_retry)
try {
@ -71,23 +63,16 @@ try {
bool success;
if (id.empty()) {
auto func = [&] () {
auto func = [&]() {
success = GetRemoteFile(
"https://mixer.com/api/v1/users/current",
output,
error,
nullptr,
"application/json",
nullptr,
headers,
nullptr,
5);
"https://mixer.com/api/v1/users/current",
output, error, nullptr, "application/json",
nullptr, headers, nullptr, 5);
};
ExecThreadedWithoutBlocking(
func,
QTStr("Auth.LoadingChannel.Title"),
QTStr("Auth.LoadingChannel.Text").arg(service()));
func, QTStr("Auth.LoadingChannel.Title"),
QTStr("Auth.LoadingChannel.Text").arg(service()));
if (!success || output.empty())
throw ErrorInfo("Failed to get user info from remote",
error);
@ -98,11 +83,12 @@ try {
error = json["error"].string_value();
if (!error.empty())
throw ErrorInfo(error,
json["error_description"].string_value());
throw ErrorInfo(
error,
json["error_description"].string_value());
id = std::to_string(json["channel"]["id"].int_value());
name = json["channel"]["token"].string_value();
id = std::to_string(json["channel"]["id"].int_value());
name = json["channel"]["token"].string_value();
}
/* ------------------ */
@ -114,23 +100,15 @@ try {
output.clear();
auto func = [&] () {
success = GetRemoteFile(
url.c_str(),
output,
error,
nullptr,
"application/json",
nullptr,
headers,
nullptr,
5);
auto func = [&]() {
success = GetRemoteFile(url.c_str(), output, error, nullptr,
"application/json", nullptr, headers,
nullptr, 5);
};
ExecThreadedWithoutBlocking(
func,
QTStr("Auth.LoadingChannel.Title"),
QTStr("Auth.LoadingChannel.Text").arg(service()));
func, QTStr("Auth.LoadingChannel.Title"),
QTStr("Auth.LoadingChannel.Text").arg(service()));
if (!success || output.empty())
throw ErrorInfo("Failed to get stream key from remote", error);
@ -140,7 +118,8 @@ try {
error = json["error"].string_value();
if (!error.empty())
throw ErrorInfo(error, json["error_description"].string_value());
throw ErrorInfo(error,
json["error_description"].string_value());
std::string key_suffix = json["streamKey"].string_value();
@ -161,14 +140,13 @@ try {
} catch (ErrorInfo info) {
QString title = QTStr("Auth.ChannelFailure.Title");
QString text = QTStr("Auth.ChannelFailure.Text")
.arg(service(), info.message.c_str(), info.error.c_str());
.arg(service(), info.message.c_str(),
info.error.c_str());
QMessageBox::warning(OBSBasic::Get(), title, text);
blog(LOG_WARNING, "%s: %s: %s",
__FUNCTION__,
info.message.c_str(),
info.error.c_str());
blog(LOG_WARNING, "%s: %s: %s", __FUNCTION__, info.message.c_str(),
info.error.c_str());
return false;
}
@ -179,15 +157,13 @@ void MixerAuth::SaveInternal()
config_set_string(main->Config(), service(), "Id", id.c_str());
if (uiLoaded) {
config_set_string(main->Config(), service(), "DockState",
main->saveState().toBase64().constData());
main->saveState().toBase64().constData());
}
OAuthStreamKey::SaveInternal();
}
static inline std::string get_config_str(
OBSBasic *main,
const char *section,
const char *name)
static inline std::string get_config_str(OBSBasic *main, const char *section,
const char *name)
{
const char *val = config_get_string(main->Config(), section, name);
return val ? val : "";
@ -252,8 +228,8 @@ void MixerAuth::LoadUI()
if (firstLoad) {
chat->setVisible(true);
} else {
const char *dockStateStr = config_get_string(main->Config(),
service(), "DockState");
const char *dockStateStr = config_get_string(
main->Config(), service(), "DockState");
QByteArray dockState =
QByteArray::fromBase64(QByteArray(dockStateStr));
main->restoreState(dockState);
@ -301,7 +277,7 @@ std::shared_ptr<Auth> MixerAuth::Login(QWidget *parent)
deobfuscate_str(&client_id[0], MIXER_HASH);
if (!auth->GetToken(MIXER_TOKEN_URL, client_id, MIXER_SCOPE_VERSION,
QT_TO_UTF8(login.GetCode()))) {
QT_TO_UTF8(login.GetCode()))) {
return nullptr;
}
@ -328,9 +304,6 @@ static void DeleteCookies()
void RegisterMixerAuth()
{
OAuth::RegisterOAuth(
mixerDef,
CreateMixerAuth,
MixerAuth::Login,
DeleteCookies);
OAuth::RegisterOAuth(mixerDef, CreateMixerAuth, MixerAuth::Login,
DeleteCookies);
}

View file

@ -23,8 +23,7 @@ extern QCefCookieManager *panel_cookies;
/* ------------------------------------------------------------------------- */
OAuthLogin::OAuthLogin(QWidget *parent, const std::string &url, bool token)
: QDialog (parent),
get_token (token)
: QDialog(parent), get_token(token)
{
if (!cef) {
return;
@ -46,14 +45,13 @@ OAuthLogin::OAuthLogin(QWidget *parent, const std::string &url, bool token)
return;
}
connect(cefWidget, SIGNAL(titleChanged(const QString &)),
this, SLOT(setWindowTitle(const QString &)));
connect(cefWidget, SIGNAL(urlChanged(const QString &)),
this, SLOT(urlChanged(const QString &)));
connect(cefWidget, SIGNAL(titleChanged(const QString &)), this,
SLOT(setWindowTitle(const QString &)));
connect(cefWidget, SIGNAL(urlChanged(const QString &)), this,
SLOT(urlChanged(const QString &)));
QPushButton *close = new QPushButton(QTStr("Cancel"));
connect(close, &QAbstractButton::clicked,
this, &QDialog::reject);
connect(close, &QAbstractButton::clicked, this, &QDialog::reject);
QHBoxLayout *bottomLayout = new QHBoxLayout();
bottomLayout->addStretch();
@ -111,7 +109,7 @@ struct OAuthInfo {
static std::vector<OAuthInfo> loginCBs;
void OAuth::RegisterOAuth(const Def &d, create_cb create, login_cb login,
delete_cookies_cb delete_cookies)
delete_cookies_cb delete_cookies)
{
OAuthInfo info = {d, login, delete_cookies};
loginCBs.push_back(info);
@ -142,16 +140,14 @@ void OAuth::SaveInternal()
{
OBSBasic *main = OBSBasic::Get();
config_set_string(main->Config(), service(), "RefreshToken",
refresh_token.c_str());
refresh_token.c_str());
config_set_string(main->Config(), service(), "Token", token.c_str());
config_set_uint(main->Config(), service(), "ExpireTime", expire_time);
config_set_int(main->Config(), service(), "ScopeVer", currentScopeVer);
}
static inline std::string get_config_str(
OBSBasic *main,
const char *section,
const char *name)
static inline std::string get_config_str(OBSBasic *main, const char *section,
const char *name)
{
const char *val = config_get_string(main->Config(), section, name);
return val ? val : "";
@ -163,11 +159,9 @@ bool OAuth::LoadInternal()
refresh_token = get_config_str(main, service(), "RefreshToken");
token = get_config_str(main, service(), "Token");
expire_time = config_get_uint(main->Config(), service(), "ExpireTime");
currentScopeVer = (int)config_get_int(main->Config(), service(),
"ScopeVer");
return implicit
? !token.empty()
: !refresh_token.empty();
currentScopeVer =
(int)config_get_int(main->Config(), service(), "ScopeVer");
return implicit ? !token.empty() : !refresh_token.empty();
}
bool OAuth::TokenExpired()
@ -180,7 +174,7 @@ bool OAuth::TokenExpired()
}
bool OAuth::GetToken(const char *url, const std::string &client_id,
int scope_ver, const std::string &auth_code, bool retry)
int scope_ver, const std::string &auth_code, bool retry)
try {
std::string output;
std::string error;
@ -191,8 +185,8 @@ try {
return true;
} else {
QString title = QTStr("Auth.InvalidScope.Title");
QString text = QTStr("Auth.InvalidScope.Text")
.arg(service());
QString text =
QTStr("Auth.InvalidScope.Text").arg(service());
QMessageBox::warning(OBSBasic::Get(), title, text);
}
@ -216,23 +210,15 @@ try {
bool success = false;
auto func = [&] () {
success = GetRemoteFile(
url,
output,
error,
nullptr,
"application/x-www-form-urlencoded",
post_data.c_str(),
std::vector<std::string>(),
nullptr,
5);
auto func = [&]() {
success = GetRemoteFile(url, output, error, nullptr,
"application/x-www-form-urlencoded",
post_data.c_str(),
std::vector<std::string>(), nullptr, 5);
};
ExecThreadedWithoutBlocking(
func,
QTStr("Auth.Authing.Title"),
QTStr("Auth.Authing.Text").arg(service()));
ExecThreadedWithoutBlocking(func, QTStr("Auth.Authing.Title"),
QTStr("Auth.Authing.Text").arg(service()));
if (!success || output.empty())
throw ErrorInfo("Failed to get token from remote", error);
@ -250,13 +236,14 @@ try {
}
}
if (!error.empty())
throw ErrorInfo(error, json["error_description"].string_value());
throw ErrorInfo(error,
json["error_description"].string_value());
/* -------------------------- */
/* success! */
expire_time = (uint64_t)time(nullptr) + json["expires_in"].int_value();
token = json["access_token"].string_value();
token = json["access_token"].string_value();
if (token.empty())
throw ErrorInfo("Failed to get token from remote", error);
@ -264,7 +251,8 @@ try {
refresh_token = json["refresh_token"].string_value();
if (refresh_token.empty())
throw ErrorInfo("Failed to get refresh token from "
"remote", error);
"remote",
error);
currentScopeVer = scope_ver;
}
@ -275,15 +263,14 @@ try {
if (!retry) {
QString title = QTStr("Auth.AuthFailure.Title");
QString text = QTStr("Auth.AuthFailure.Text")
.arg(service(), info.message.c_str(), info.error.c_str());
.arg(service(), info.message.c_str(),
info.error.c_str());
QMessageBox::warning(OBSBasic::Get(), title, text);
}
blog(LOG_WARNING, "%s: %s: %s",
__FUNCTION__,
info.message.c_str(),
info.error.c_str());
blog(LOG_WARNING, "%s: %s: %s", __FUNCTION__, info.message.c_str(),
info.error.c_str());
return false;
}
@ -301,7 +288,7 @@ void OAuthStreamKey::OnStreamConfig()
if (bwtest && strcmp(this->service(), "Twitch") == 0)
obs_data_set_string(settings, "key",
(key_ + "?bandwidthtest=true").c_str());
(key_ + "?bandwidthtest=true").c_str());
else
obs_data_set_string(settings, "key", key_.c_str());

View file

@ -20,8 +20,8 @@ public:
OAuthLogin(QWidget *parent, const std::string &url, bool token);
~OAuthLogin();
inline QString GetCode() const {return code;}
inline bool LoadFail() const {return fail;}
inline QString GetCode() const { return code; }
inline bool LoadFail() const { return fail; }
virtual int exec() override;
@ -35,15 +35,16 @@ class OAuth : public Auth {
public:
inline OAuth(const Def &d) : Auth(d) {}
typedef std::function<std::shared_ptr<Auth> (QWidget *)> login_cb;
typedef std::function<std::shared_ptr<Auth>(QWidget *)> login_cb;
typedef std::function<void()> delete_cookies_cb;
static std::shared_ptr<Auth> Login(QWidget *parent,
const std::string &service);
const std::string &service);
static void DeleteCookies(const std::string &service);
static void RegisterOAuth(const Def &d, create_cb create,
login_cb login, delete_cookies_cb delete_cookies);
login_cb login,
delete_cookies_cb delete_cookies);
protected:
std::string refresh_token;
@ -55,12 +56,12 @@ protected:
virtual void SaveInternal() override;
virtual bool LoadInternal() override;
virtual bool RetryLogin()=0;
virtual bool RetryLogin() = 0;
bool TokenExpired();
bool GetToken(const char *url, const std::string &client_id,
int scope_ver,
const std::string &auth_code = std::string(),
bool retry = false);
int scope_ver,
const std::string &auth_code = std::string(),
bool retry = false);
};
class OAuthStreamKey : public OAuth {
@ -72,7 +73,7 @@ protected:
public:
inline OAuthStreamKey(const Def &d) : OAuth(d) {}
inline const std::string &key() const {return key_;}
inline const std::string &key() const { return key_; }
virtual void OnStreamConfig() override;
};

View file

@ -22,23 +22,17 @@ extern QCefCookieManager *panel_cookies;
/* ------------------------------------------------------------------------- */
#define RESTREAM_AUTH_URL "https://obsproject.com/app-auth/restream?action=redirect"
#define RESTREAM_AUTH_URL \
"https://obsproject.com/app-auth/restream?action=redirect"
#define RESTREAM_TOKEN_URL "https://obsproject.com/app-auth/restream-token"
#define RESTREAM_STREAMKEY_URL "https://api.restream.io/v2/user/streamKey"
#define RESTREAM_SCOPE_VERSION 1
static Auth::Def restreamDef = {
"Restream",
Auth::Type::OAuth_StreamKey
};
static Auth::Def restreamDef = {"Restream", Auth::Type::OAuth_StreamKey};
/* ------------------------------------------------------------------------- */
RestreamAuth::RestreamAuth(const Def &d)
: OAuthStreamKey(d)
{
}
RestreamAuth::RestreamAuth(const Def &d) : OAuthStreamKey(d) {}
bool RestreamAuth::GetChannelInfo()
try {
@ -65,23 +59,15 @@ try {
Json json;
bool success;
auto func = [&] () {
success = GetRemoteFile(
RESTREAM_STREAMKEY_URL,
output,
error,
nullptr,
"application/json",
nullptr,
headers,
nullptr,
5);
auto func = [&]() {
success = GetRemoteFile(RESTREAM_STREAMKEY_URL, output, error,
nullptr, "application/json", nullptr,
headers, nullptr, 5);
};
ExecThreadedWithoutBlocking(
func,
QTStr("Auth.LoadingChannel.Title"),
QTStr("Auth.LoadingChannel.Text").arg(service()));
func, QTStr("Auth.LoadingChannel.Title"),
QTStr("Auth.LoadingChannel.Text").arg(service()));
if (!success || output.empty())
throw ErrorInfo("Failed to get stream key from remote", error);
@ -91,7 +77,8 @@ try {
error = json["error"].string_value();
if (!error.empty())
throw ErrorInfo(error, json["error_description"].string_value());
throw ErrorInfo(error,
json["error_description"].string_value());
key_ = json["streamKey"].string_value();
@ -99,14 +86,13 @@ try {
} catch (ErrorInfo info) {
QString title = QTStr("Auth.ChannelFailure.Title");
QString text = QTStr("Auth.ChannelFailure.Text")
.arg(service(), info.message.c_str(), info.error.c_str());
.arg(service(), info.message.c_str(),
info.error.c_str());
QMessageBox::warning(OBSBasic::Get(), title, text);
blog(LOG_WARNING, "%s: %s: %s",
__FUNCTION__,
info.message.c_str(),
info.error.c_str());
blog(LOG_WARNING, "%s: %s: %s", __FUNCTION__, info.message.c_str(),
info.error.c_str());
return false;
}
@ -114,14 +100,12 @@ void RestreamAuth::SaveInternal()
{
OBSBasic *main = OBSBasic::Get();
config_set_string(main->Config(), service(), "DockState",
main->saveState().toBase64().constData());
main->saveState().toBase64().constData());
OAuthStreamKey::SaveInternal();
}
static inline std::string get_config_str(
OBSBasic *main,
const char *section,
const char *name)
static inline std::string get_config_str(OBSBasic *main, const char *section,
const char *name)
{
const char *val = config_get_string(main->Config(), section, name);
return val ? val : "";
@ -201,10 +185,9 @@ void RestreamAuth::LoadUI()
if (firstLoad) {
chat->setVisible(true);
info->setVisible(true);
}
else {
const char *dockStateStr = config_get_string(main->Config(),
service(), "DockState");
} else {
const char *dockStateStr = config_get_string(
main->Config(), service(), "DockState");
QByteArray dockState =
QByteArray::fromBase64(QByteArray(dockStateStr));
main->restoreState(dockState);
@ -227,8 +210,7 @@ bool RestreamAuth::RetryLogin()
std::string client_id = RESTREAM_CLIENTID;
deobfuscate_str(&client_id[0], RESTREAM_HASH);
return GetToken(RESTREAM_TOKEN_URL, client_id,
RESTREAM_SCOPE_VERSION,
return GetToken(RESTREAM_TOKEN_URL, client_id, RESTREAM_SCOPE_VERSION,
QT_TO_UTF8(login.GetCode()), true);
}
@ -248,8 +230,8 @@ std::shared_ptr<Auth> RestreamAuth::Login(QWidget *parent)
deobfuscate_str(&client_id[0], RESTREAM_HASH);
if (!auth->GetToken(RESTREAM_TOKEN_URL, client_id,
RESTREAM_SCOPE_VERSION,
QT_TO_UTF8(login.GetCode()))) {
RESTREAM_SCOPE_VERSION,
QT_TO_UTF8(login.GetCode()))) {
return nullptr;
}
@ -275,9 +257,6 @@ static void DeleteCookies()
void RegisterRestreamAuth()
{
OAuth::RegisterOAuth(
restreamDef,
CreateRestreamAuth,
RestreamAuth::Login,
DeleteCookies);
OAuth::RegisterOAuth(restreamDef, CreateRestreamAuth,
RestreamAuth::Login, DeleteCookies);
}

View file

@ -24,35 +24,28 @@ extern QCefCookieManager *panel_cookies;
/* ------------------------------------------------------------------------- */
#define TWITCH_AUTH_URL \
"https://obsproject.com/app-auth/twitch?action=redirect"
#define TWITCH_TOKEN_URL \
"https://obsproject.com/app-auth/twitch-token"
#define ACCEPT_HEADER \
"Accept: application/vnd.twitchtv.v5+json"
#define TWITCH_AUTH_URL "https://obsproject.com/app-auth/twitch?action=redirect"
#define TWITCH_TOKEN_URL "https://obsproject.com/app-auth/twitch-token"
#define ACCEPT_HEADER "Accept: application/vnd.twitchtv.v5+json"
#define TWITCH_SCOPE_VERSION 1
static Auth::Def twitchDef = {
"Twitch",
Auth::Type::OAuth_StreamKey
};
static Auth::Def twitchDef = {"Twitch", Auth::Type::OAuth_StreamKey};
/* ------------------------------------------------------------------------- */
TwitchAuth::TwitchAuth(const Def &d)
: OAuthStreamKey(d)
TwitchAuth::TwitchAuth(const Def &d) : OAuthStreamKey(d)
{
if (!cef)
return;
cef->add_popup_whitelist_url(
"https://twitch.tv/popout/frankerfacez/chat?ffz-settings",
this);
"https://twitch.tv/popout/frankerfacez/chat?ffz-settings",
this);
uiLoadTimer.setSingleShot(true);
uiLoadTimer.setInterval(500);
connect(&uiLoadTimer, &QTimer::timeout,
this, &TwitchAuth::TryLoadSecondaryUIPanes);
connect(&uiLoadTimer, &QTimer::timeout, this,
&TwitchAuth::TryLoadSecondaryUIPanes);
}
bool TwitchAuth::GetChannelInfo()
@ -82,33 +75,25 @@ try {
bool success = false;
auto func = [&] () {
success = GetRemoteFile(
"https://api.twitch.tv/kraken/channel",
output,
error,
&error_code,
"application/json",
nullptr,
headers,
nullptr,
5);
auto func = [&]() {
success = GetRemoteFile("https://api.twitch.tv/kraken/channel",
output, error, &error_code,
"application/json", nullptr, headers,
nullptr, 5);
};
ExecThreadedWithoutBlocking(
func,
QTStr("Auth.LoadingChannel.Title"),
QTStr("Auth.LoadingChannel.Text").arg(service()));
func, QTStr("Auth.LoadingChannel.Title"),
QTStr("Auth.LoadingChannel.Text").arg(service()));
if (error_code == 403) {
OBSMessageBox::warning(OBSBasic::Get(),
Str("TwitchAuth.TwoFactorFail.Title"),
Str("TwitchAuth.TwoFactorFail.Text"),
true);
blog(LOG_WARNING, "%s: %s",
__FUNCTION__,
"Got 403 from Twitch, user probably does not "
"have two-factor authentication enabled on "
"their account");
Str("TwitchAuth.TwoFactorFail.Title"),
Str("TwitchAuth.TwoFactorFail.Text"),
true);
blog(LOG_WARNING, "%s: %s", __FUNCTION__,
"Got 403 from Twitch, user probably does not "
"have two-factor authentication enabled on "
"their account");
return false;
}
@ -125,10 +110,10 @@ try {
if (RetryLogin()) {
return GetChannelInfo();
}
throw ErrorInfo(error,
json["message"].string_value());
throw ErrorInfo(error, json["message"].string_value());
}
throw ErrorInfo(error, json["error_description"].string_value());
throw ErrorInfo(error,
json["error_description"].string_value());
}
name = json["name"].string_value();
@ -138,14 +123,13 @@ try {
} catch (ErrorInfo info) {
QString title = QTStr("Auth.ChannelFailure.Title");
QString text = QTStr("Auth.ChannelFailure.Text")
.arg(service(), info.message.c_str(), info.error.c_str());
.arg(service(), info.message.c_str(),
info.error.c_str());
QMessageBox::warning(OBSBasic::Get(), title, text);
blog(LOG_WARNING, "%s: %s: %s",
__FUNCTION__,
info.message.c_str(),
info.error.c_str());
blog(LOG_WARNING, "%s: %s: %s", __FUNCTION__, info.message.c_str(),
info.error.c_str());
return false;
}
@ -155,15 +139,13 @@ void TwitchAuth::SaveInternal()
config_set_string(main->Config(), service(), "Name", name.c_str());
if (uiLoaded) {
config_set_string(main->Config(), service(), "DockState",
main->saveState().toBase64().constData());
main->saveState().toBase64().constData());
}
OAuthStreamKey::SaveInternal();
}
static inline std::string get_config_str(
OBSBasic *main,
const char *section,
const char *name)
static inline std::string get_config_str(OBSBasic *main, const char *section,
const char *name)
{
const char *val = config_get_string(main->Config(), section, name);
return val ? val : "";
@ -266,8 +248,8 @@ void TwitchAuth::LoadUI()
if (firstLoad) {
chat->setVisible(true);
} else {
const char *dockStateStr = config_get_string(main->Config(),
service(), "DockState");
const char *dockStateStr = config_get_string(
main->Config(), service(), "DockState");
QByteArray dockState =
QByteArray::fromBase64(QByteArray(dockStateStr));
main->restoreState(dockState);
@ -367,8 +349,8 @@ void TwitchAuth::LoadSecondaryUIPanes()
QSize statSize = stat->frameSize();
info->move(pos.x() + 50, pos.y() + 50);
stat->move(pos.x() + size.width() / 2 - statSize.width() / 2,
pos.y() + size.height() / 2 - statSize.height() / 2);
stat->move(pos.x() + size.width() / 2 - statSize.width() / 2,
pos.y() + size.height() / 2 - statSize.height() / 2);
feed->move(pos.x() + 100, pos.y() + 100);
if (firstLoad) {
@ -376,15 +358,15 @@ void TwitchAuth::LoadSecondaryUIPanes()
stat->setVisible(false);
feed->setVisible(false);
} else {
uint32_t lastVersion = config_get_int(App()->GlobalConfig(), "General",
"LastVersion");
uint32_t lastVersion = config_get_int(App()->GlobalConfig(),
"General", "LastVersion");
if (lastVersion <= MAKE_SEMANTIC_VERSION(23, 0, 2)) {
feed->setVisible(false);
}
const char *dockStateStr = config_get_string(main->Config(),
service(), "DockState");
const char *dockStateStr = config_get_string(
main->Config(), service(), "DockState");
QByteArray dockState =
QByteArray::fromBase64(QByteArray(dockStateStr));
main->restoreState(dockState);
@ -405,21 +387,21 @@ void TwitchAuth::TryLoadSecondaryUIPanes()
{
QPointer<TwitchAuth> this_ = this;
auto cb = [this_] (bool found)
{
auto cb = [this_](bool found) {
if (!this_) {
return;
}
if (!found) {
QMetaObject::invokeMethod(&this_->uiLoadTimer,
"start");
QMetaObject::invokeMethod(&this_->uiLoadTimer, "start");
} else {
QMetaObject::invokeMethod(this_, "LoadSecondaryUIPanes");
QMetaObject::invokeMethod(this_,
"LoadSecondaryUIPanes");
}
};
panel_cookies->CheckForCookie("https://www.twitch.tv", "auth-token", cb);
panel_cookies->CheckForCookie("https://www.twitch.tv", "auth-token",
cb);
}
bool TwitchAuth::RetryLogin()
@ -429,7 +411,8 @@ bool TwitchAuth::RetryLogin()
return false;
}
std::shared_ptr<TwitchAuth> auth = std::make_shared<TwitchAuth>(twitchDef);
std::shared_ptr<TwitchAuth> auth =
std::make_shared<TwitchAuth>(twitchDef);
std::string client_id = TWITCH_CLIENTID;
deobfuscate_str(&client_id[0], TWITCH_HASH);
@ -444,13 +427,14 @@ std::shared_ptr<Auth> TwitchAuth::Login(QWidget *parent)
return nullptr;
}
std::shared_ptr<TwitchAuth> auth = std::make_shared<TwitchAuth>(twitchDef);
std::shared_ptr<TwitchAuth> auth =
std::make_shared<TwitchAuth>(twitchDef);
std::string client_id = TWITCH_CLIENTID;
deobfuscate_str(&client_id[0], TWITCH_HASH);
if (!auth->GetToken(TWITCH_TOKEN_URL, client_id, TWITCH_SCOPE_VERSION,
QT_TO_UTF8(login.GetCode()))) {
QT_TO_UTF8(login.GetCode()))) {
return nullptr;
}
@ -475,9 +459,6 @@ static void DeleteCookies()
void RegisterTwitchAuth()
{
OAuth::RegisterOAuth(
twitchDef,
CreateTwitchAuth,
TwitchAuth::Login,
DeleteCookies);
OAuth::RegisterOAuth(twitchDef, CreateTwitchAuth, TwitchAuth::Login,
DeleteCookies);
}

View file

@ -4,7 +4,7 @@
#include <QMouseEvent>
class ClickableLabel : public QLabel {
Q_OBJECT
Q_OBJECT
public:
inline ClickableLabel(QWidget *parent = 0) : QLabel(parent) {}

View file

@ -32,10 +32,10 @@ OBSCrashReport::OBSCrashReport(QWidget *parent, const char *text)
setLayout(mainLayout);
QWidget::connect(copyButton, SIGNAL(clicked()),
this, SLOT(CopyClicked()));
QWidget::connect(exitButton, SIGNAL(clicked()),
this, SLOT(ExitClicked()));
QWidget::connect(copyButton, SIGNAL(clicked()), this,
SLOT(CopyClicked()));
QWidget::connect(exitButton, SIGNAL(clicked()), this,
SLOT(ExitClicked()));
resize(800, 600);
setWindowTitle("Oops, OBS has crashed!");

View file

@ -21,15 +21,15 @@
#define SUPPORTS_FRACTIONAL_SCALING
#endif
static inline void GetScaleAndCenterPos(
int baseCX, int baseCY, int windowCX, int windowCY,
int &x, int &y, float &scale)
static inline void GetScaleAndCenterPos(int baseCX, int baseCY, int windowCX,
int windowCY, int &x, int &y,
float &scale)
{
double windowAspect, baseAspect;
int newCX, newCY;
windowAspect = double(windowCX) / double(windowCY);
baseAspect = double(baseCX) / double(baseCY);
baseAspect = double(baseCX) / double(baseCY);
if (windowAspect > baseAspect) {
scale = float(windowCY) / float(baseCY);
@ -41,16 +41,16 @@ static inline void GetScaleAndCenterPos(
newCY = int(float(windowCX) / baseAspect);
}
x = windowCX/2 - newCX/2;
y = windowCY/2 - newCY/2;
x = windowCX / 2 - newCX / 2;
y = windowCY / 2 - newCY / 2;
}
static inline void GetCenterPosFromFixedScale(
int baseCX, int baseCY, int windowCX, int windowCY,
int &x, int &y, float scale)
static inline void GetCenterPosFromFixedScale(int baseCX, int baseCY,
int windowCX, int windowCY,
int &x, int &y, float scale)
{
x = (float(windowCX) - float(baseCX)*scale) / 2.0f;
y = (float(windowCY) - float(baseCY)*scale) / 2.0f;
x = (float(windowCX) - float(baseCX) * scale) / 2.0f;
y = (float(windowCY) - float(baseCY) * scale) / 2.0f;
}
static inline QSize GetPixelSize(QWidget *widget)

View file

@ -4,12 +4,12 @@
DoubleSlider::DoubleSlider(QWidget *parent) : SliderIgnoreScroll(parent)
{
connect(this, SIGNAL(valueChanged(int)),
this, SLOT(intValChanged(int)));
connect(this, SIGNAL(valueChanged(int)), this,
SLOT(intValChanged(int)));
}
void DoubleSlider::setDoubleConstraints(double newMin, double newMax,
double newStep, double val)
double newStep, double val)
{
minVal = newMin;
maxVal = newMax;
@ -26,7 +26,7 @@ void DoubleSlider::setDoubleConstraints(double newMin, double newMax,
void DoubleSlider::intValChanged(int val)
{
emit doubleValChanged((minVal/minStep + val) * minStep);
emit doubleValChanged((minVal / minStep + val) * minStep);
}
void DoubleSlider::setDoubleVal(double val)

View file

@ -11,8 +11,8 @@ class DoubleSlider : public SliderIgnoreScroll {
public:
DoubleSlider(QWidget *parent = nullptr);
void setDoubleConstraints(double newMin, double newMax,
double newStep, double val);
void setDoubleConstraints(double newMin, double newMax, double newStep,
double val);
signals:
void doubleValChanged(double val);

View file

@ -2,8 +2,7 @@
#include <QListWidget>
class FocusList : public QListWidget
{
class FocusList : public QListWidget {
Q_OBJECT
public:

View file

@ -5,8 +5,7 @@
#include "decklink-ui-main.h"
DecklinkOutputUI::DecklinkOutputUI(QWidget *parent)
: QDialog(parent),
ui(new Ui_Output)
: QDialog(parent), ui(new Ui_Output)
{
ui->setupUi(this);
@ -20,8 +19,10 @@ DecklinkOutputUI::DecklinkOutputUI(QWidget *parent)
connect(ui->startOutput, SIGNAL(released()), this, SLOT(StartOutput()));
connect(ui->stopOutput, SIGNAL(released()), this, SLOT(StopOutput()));
connect(ui->startPreviewOutput, SIGNAL(released()), this, SLOT(StartPreviewOutput()));
connect(ui->stopPreviewOutput, SIGNAL(released()), this, SLOT(StopPreviewOutput()));
connect(ui->startPreviewOutput, SIGNAL(released()), this,
SLOT(StartPreviewOutput()));
connect(ui->stopPreviewOutput, SIGNAL(released()), this,
SLOT(StopPreviewOutput()));
}
void DecklinkOutputUI::ShowHideDialog()
@ -43,25 +44,26 @@ void DecklinkOutputUI::SetupPropertiesView()
if (data)
obs_data_apply(settings, data);
propertiesView = new OBSPropertiesView(settings,
"decklink_output",
(PropertiesReloadCallback) obs_get_output_properties,
170);
propertiesView = new OBSPropertiesView(
settings, "decklink_output",
(PropertiesReloadCallback)obs_get_output_properties, 170);
ui->propertiesLayout->addWidget(propertiesView);
obs_data_release(settings);
connect(propertiesView, SIGNAL(Changed()), this, SLOT(PropertiesChanged()));
connect(propertiesView, SIGNAL(Changed()), this,
SLOT(PropertiesChanged()));
}
void DecklinkOutputUI::SaveSettings()
{
BPtr<char> modulePath = obs_module_get_config_path(obs_current_module(), "");
BPtr<char> modulePath =
obs_module_get_config_path(obs_current_module(), "");
os_mkdirs(modulePath);
BPtr<char> path = obs_module_get_config_path(obs_current_module(),
"decklinkOutputProps.json");
BPtr<char> path = obs_module_get_config_path(
obs_current_module(), "decklinkOutputProps.json");
obs_data_t *settings = propertiesView->GetSettings();
if (settings)
@ -79,15 +81,15 @@ void DecklinkOutputUI::SetupPreviewPropertiesView()
if (data)
obs_data_apply(settings, data);
previewPropertiesView = new OBSPropertiesView(settings,
"decklink_output",
(PropertiesReloadCallback) obs_get_output_properties,
170);
previewPropertiesView = new OBSPropertiesView(
settings, "decklink_output",
(PropertiesReloadCallback)obs_get_output_properties, 170);
ui->previewPropertiesLayout->addWidget(previewPropertiesView);
obs_data_release(settings);
connect(previewPropertiesView, SIGNAL(Changed()), this, SLOT(PreviewPropertiesChanged()));
connect(previewPropertiesView, SIGNAL(Changed()), this,
SLOT(PreviewPropertiesChanged()));
}
void DecklinkOutputUI::SavePreviewSettings()
@ -96,15 +98,14 @@ void DecklinkOutputUI::SavePreviewSettings()
os_mkdirs(modulePath);
char *path = obs_module_get_config_path(obs_current_module(),
"decklinkPreviewOutputProps.json");
char *path = obs_module_get_config_path(
obs_current_module(), "decklinkPreviewOutputProps.json");
obs_data_t *settings = previewPropertiesView->GetSettings();
if (settings)
obs_data_save_json_safe(settings, path, "tmp", "bak");
}
void DecklinkOutputUI::StartOutput()
{
SaveSettings();
@ -121,7 +122,6 @@ void DecklinkOutputUI::PropertiesChanged()
SaveSettings();
}
void DecklinkOutputUI::StartPreviewOutput()
{
SavePreviewSettings();

View file

@ -6,7 +6,7 @@
#include "../../UI/properties-view.hpp"
class DecklinkOutputUI : public QDialog {
Q_OBJECT
Q_OBJECT
private:
OBSPropertiesView *propertiesView;
OBSPropertiesView *previewPropertiesView;

View file

@ -37,8 +37,8 @@ static struct preview_output context = {0};
OBSData load_settings()
{
BPtr<char> path = obs_module_get_config_path(obs_current_module(),
"decklinkOutputProps.json");
BPtr<char> path = obs_module_get_config_path(
obs_current_module(), "decklinkOutputProps.json");
BPtr<char> jsonData = os_quick_read_utf8_file(path);
if (!!jsonData) {
obs_data_t *data = obs_data_create_from_json(jsonData);
@ -57,8 +57,9 @@ void output_start()
OBSData settings = load_settings();
if (settings != nullptr) {
output = obs_output_create("decklink_output",
"decklink_output", settings, NULL);
output = obs_output_create("decklink_output",
"decklink_output", settings,
NULL);
obs_output_start(output);
obs_data_release(settings);
@ -77,11 +78,10 @@ void output_stop()
}
}
OBSData load_preview_settings()
{
BPtr<char> path = obs_module_get_config_path(obs_current_module(),
"decklinkPreviewOutputProps.json");
BPtr<char> path = obs_module_get_config_path(
obs_current_module(), "decklinkPreviewOutputProps.json");
BPtr<char> jsonData = os_quick_read_utf8_file(path);
if (!!jsonData) {
obs_data_t *data = obs_data_create_from_json(jsonData);
@ -103,8 +103,9 @@ void preview_output_start()
OBSData settings = load_preview_settings();
if (settings != nullptr) {
context.output = obs_output_create("decklink_output",
"decklink_preview_output", settings, NULL);
context.output = obs_output_create(
"decklink_output", "decklink_preview_output",
settings, NULL);
obs_get_video_info(&context.ovi);
@ -112,11 +113,14 @@ void preview_output_start()
uint32_t height = context.ovi.base_height;
obs_enter_graphics();
context.texrender = gs_texrender_create(GS_BGRA, GS_ZS_NONE);
context.stagesurface = gs_stagesurface_create(width, height, GS_BGRA);
context.texrender =
gs_texrender_create(GS_BGRA, GS_ZS_NONE);
context.stagesurface =
gs_stagesurface_create(width, height, GS_BGRA);
obs_leave_graphics();
const video_output_info *mainVOI = video_output_get_info(obs_get_video());
const video_output_info *mainVOI =
video_output_get_info(obs_get_video());
video_output_info vi = {0};
vi.format = VIDEO_FORMAT_BGRA;
@ -131,15 +135,21 @@ void preview_output_start()
video_output_open(&context.video_queue, &vi);
obs_frontend_add_event_callback(on_preview_scene_changed, &context);
obs_frontend_add_event_callback(
on_preview_scene_changed, &context);
if (obs_frontend_preview_program_mode_active()) {
context.current_source = obs_frontend_get_current_preview_scene();
context.current_source =
obs_frontend_get_current_preview_scene();
} else {
context.current_source = obs_frontend_get_current_scene();
context.current_source =
obs_frontend_get_current_scene();
}
obs_add_main_render_callback(render_preview_source, &context);
obs_add_main_render_callback(render_preview_source,
&context);
obs_output_set_media(context.output, context.video_queue, obs_get_audio());
obs_output_set_media(context.output,
context.video_queue,
obs_get_audio());
obs_output_start(context.output);
preview_output_running = true;
@ -153,8 +163,10 @@ void preview_output_stop()
obs_output_stop(context.output);
video_output_stop(context.video_queue);
obs_remove_main_render_callback(render_preview_source, &context);
obs_frontend_remove_event_callback(on_preview_scene_changed, &context);
obs_remove_main_render_callback(render_preview_source,
&context);
obs_frontend_remove_event_callback(on_preview_scene_changed,
&context);
obs_source_release(context.current_source);
@ -171,33 +183,34 @@ void preview_output_stop()
void on_preview_scene_changed(enum obs_frontend_event event, void *param)
{
auto ctx = (struct preview_output*)param;
auto ctx = (struct preview_output *)param;
switch (event) {
case OBS_FRONTEND_EVENT_STUDIO_MODE_ENABLED:
case OBS_FRONTEND_EVENT_PREVIEW_SCENE_CHANGED:
obs_source_release(ctx->current_source);
ctx->current_source = obs_frontend_get_current_preview_scene();
break;
case OBS_FRONTEND_EVENT_STUDIO_MODE_DISABLED:
case OBS_FRONTEND_EVENT_STUDIO_MODE_ENABLED:
case OBS_FRONTEND_EVENT_PREVIEW_SCENE_CHANGED:
obs_source_release(ctx->current_source);
ctx->current_source = obs_frontend_get_current_preview_scene();
break;
case OBS_FRONTEND_EVENT_STUDIO_MODE_DISABLED:
obs_source_release(ctx->current_source);
ctx->current_source = obs_frontend_get_current_scene();
break;
case OBS_FRONTEND_EVENT_SCENE_CHANGED:
if (!obs_frontend_preview_program_mode_active()) {
obs_source_release(ctx->current_source);
ctx->current_source = obs_frontend_get_current_scene();
break;
case OBS_FRONTEND_EVENT_SCENE_CHANGED:
if (!obs_frontend_preview_program_mode_active()) {
obs_source_release(ctx->current_source);
ctx->current_source = obs_frontend_get_current_scene();
}
break;
default:
break;
}
break;
default:
break;
}
}
void render_preview_source(void *param, uint32_t cx, uint32_t cy)
{
auto ctx = (struct preview_output*)param;
auto ctx = (struct preview_output *)param;
if (!ctx->current_source) return;
if (!ctx->current_source)
return;
uint32_t width = obs_source_get_base_width(ctx->current_source);
uint32_t height = obs_source_get_base_height(ctx->current_source);
@ -209,7 +222,8 @@ void render_preview_source(void *param, uint32_t cx, uint32_t cy)
vec4_zero(&background);
gs_clear(GS_CLEAR_COLOR, &background, 0.0f, 0);
gs_ortho(0.0f, (float)width, 0.0f, (float)height, -100.0f, 100.0f);
gs_ortho(0.0f, (float)width, 0.0f, (float)height, -100.0f,
100.0f);
gs_blend_state_push();
gs_blend_function(GS_BLEND_ONE, GS_BLEND_ZERO);
@ -220,18 +234,25 @@ void render_preview_source(void *param, uint32_t cx, uint32_t cy)
gs_texrender_end(ctx->texrender);
struct video_frame output_frame;
if (video_output_lock_frame(ctx->video_queue, &output_frame, 1, os_gettime_ns()))
{
gs_stage_texture(ctx->stagesurface, gs_texrender_get_texture(ctx->texrender));
if (video_output_lock_frame(ctx->video_queue, &output_frame, 1,
os_gettime_ns())) {
gs_stage_texture(
ctx->stagesurface,
gs_texrender_get_texture(ctx->texrender));
if (gs_stagesurface_map(ctx->stagesurface, &ctx->video_data, &ctx->video_linesize)) {
if (gs_stagesurface_map(ctx->stagesurface,
&ctx->video_data,
&ctx->video_linesize)) {
uint32_t linesize = output_frame.linesize[0];
for (uint32_t i = 0; i < ctx->ovi.base_height; i++) {
for (uint32_t i = 0; i < ctx->ovi.base_height;
i++) {
uint32_t dst_offset = linesize * i;
uint32_t src_offset = ctx->video_linesize * i;
memcpy(output_frame.data[0] + dst_offset,
ctx->video_data + src_offset,
linesize);
uint32_t src_offset =
ctx->video_linesize * i;
memcpy(output_frame.data[0] +
dst_offset,
ctx->video_data + src_offset,
linesize);
}
gs_stagesurface_unmap(ctx->stagesurface);
@ -245,18 +266,16 @@ void render_preview_source(void *param, uint32_t cx, uint32_t cy)
void addOutputUI(void)
{
QAction *action = (QAction*)obs_frontend_add_tools_menu_qaction(
obs_module_text("Decklink Output"));
QAction *action = (QAction *)obs_frontend_add_tools_menu_qaction(
obs_module_text("Decklink Output"));
QMainWindow *window = (QMainWindow*)obs_frontend_get_main_window();
QMainWindow *window = (QMainWindow *)obs_frontend_get_main_window();
obs_frontend_push_ui_translation(obs_module_get_string);
doUI = new DecklinkOutputUI(window);
obs_frontend_pop_ui_translation();
auto cb = []() {
doUI->ShowHideDialog();
};
auto cb = []() { doUI->ShowHideDialog(); };
action->connect(action, &QAction::triggered, cb);
}
@ -271,7 +290,8 @@ static void OBSEvent(enum obs_frontend_event event, void *)
OBSData previewSettings = load_preview_settings();
if (previewSettings && obs_data_get_bool(previewSettings, "auto_start"))
if (previewSettings &&
obs_data_get_bool(previewSettings, "auto_start"))
preview_output_start();
}
}

View file

@ -17,7 +17,7 @@
using namespace std;
static Display* xdisplay = 0;
static Display *xdisplay = 0;
Display *disp()
{
@ -39,31 +39,22 @@ void cleanupDisplay()
static bool ewmhIsSupported()
{
Display *display = disp();
Atom netSupportingWmCheck = XInternAtom(display,
"_NET_SUPPORTING_WM_CHECK", true);
Atom netSupportingWmCheck =
XInternAtom(display, "_NET_SUPPORTING_WM_CHECK", true);
Atom actualType;
int format = 0;
unsigned long num = 0, bytes = 0;
unsigned char *data = NULL;
Window ewmh_window = 0;
int status = XGetWindowProperty(
display,
DefaultRootWindow(display),
netSupportingWmCheck,
0L,
1L,
false,
XA_WINDOW,
&actualType,
&format,
&num,
&bytes,
&data);
int status = XGetWindowProperty(display, DefaultRootWindow(display),
netSupportingWmCheck, 0L, 1L, false,
XA_WINDOW, &actualType, &format, &num,
&bytes, &data);
if (status == Success) {
if (num > 0) {
ewmh_window = ((Window*)data)[0];
ewmh_window = ((Window *)data)[0];
}
if (data) {
XFree(data);
@ -72,21 +63,12 @@ static bool ewmhIsSupported()
}
if (ewmh_window) {
status = XGetWindowProperty(
display,
ewmh_window,
netSupportingWmCheck,
0L,
1L,
false,
XA_WINDOW,
&actualType,
&format,
&num,
&bytes,
&data);
status = XGetWindowProperty(display, ewmh_window,
netSupportingWmCheck, 0L, 1L, false,
XA_WINDOW, &actualType, &format,
&num, &bytes, &data);
if (status != Success || num == 0 ||
ewmh_window != ((Window*)data)[0]) {
ewmh_window != ((Window *)data)[0]) {
ewmh_window = 0;
}
if (status == Success && data) {
@ -111,24 +93,15 @@ static std::vector<Window> getTopLevelWindows()
Atom actualType;
int format;
unsigned long num, bytes;
Window* data = 0;
Window *data = 0;
for (int i = 0; i < ScreenCount(disp()); ++i) {
Window rootWin = RootWindow(disp(), i);
int status = XGetWindowProperty(
disp(),
rootWin,
netClList,
0L,
~0L,
false,
AnyPropertyType,
&actualType,
&format,
&num,
&bytes,
(uint8_t**)&data);
int status = XGetWindowProperty(disp(), rootWin, netClList, 0L,
~0L, false, AnyPropertyType,
&actualType, &format, &num,
&bytes, (uint8_t **)&data);
if (status != Success) {
continue;
@ -147,11 +120,10 @@ static std::string GetWindowTitle(size_t i)
{
Window w = getTopLevelWindows().at(i);
std::string windowTitle;
char* name;
char *name;
int status = XFetchName(disp(), w, &name);
if (status >= Success && name != nullptr)
{
if (status >= Success && name != nullptr) {
std::string str(name);
windowTitle = str;
}
@ -165,7 +137,7 @@ void GetWindowList(vector<string> &windows)
{
windows.resize(0);
for (size_t i = 0; i < getTopLevelWindows().size(); ++i){
for (size_t i = 0; i < getTopLevelWindows().size(); ++i) {
if (GetWindowTitle(i) != "")
windows.emplace_back(GetWindowTitle(i));
}
@ -181,24 +153,14 @@ void GetCurrentWindowTitle(string &title)
Atom actualType;
int format;
unsigned long num, bytes;
Window* data = 0;
char* name;
Window *data = 0;
char *name;
Window rootWin = RootWindow(disp(), 0);
XGetWindowProperty(
disp(),
rootWin,
active,
0L,
~0L,
false,
AnyPropertyType,
&actualType,
&format,
&num,
&bytes,
(uint8_t**)&data);
XGetWindowProperty(disp(), rootWin, active, 0L, ~0L, false,
AnyPropertyType, &actualType, &format, &num, &bytes,
(uint8_t **)&data);
int status = XFetchName(disp(), data[0], &name);

View file

@ -32,7 +32,7 @@ static bool WindowValid(HWND window)
return false;
GetClientRect(window, &rect);
styles = GetWindowLongPtr(window, GWL_STYLE);
styles = GetWindowLongPtr(window, GWL_STYLE);
ex_styles = GetWindowLongPtr(window, GWL_EXSTYLE);
if (ex_styles & WS_EX_TOOLWINDOW)

View file

@ -69,23 +69,19 @@ struct SwitcherData {
}
}
inline ~SwitcherData()
{
Stop();
}
inline ~SwitcherData() { Stop(); }
};
static SwitcherData *switcher = nullptr;
static inline QString MakeSwitchName(const QString &scene,
const QString &window)
const QString &window)
{
return QStringLiteral("[") + scene + QStringLiteral("]: ") + window;
}
SceneSwitcher::SceneSwitcher(QWidget *parent)
: QDialog(parent),
ui(new Ui_SceneSwitcher)
: QDialog(parent), ui(new Ui_SceneSwitcher)
{
ui->setupUi(this);
@ -95,7 +91,7 @@ SceneSwitcher::SceneSwitcher(QWidget *parent)
switcher->Prune();
BPtr<char*> scenes = obs_frontend_get_scene_names();
BPtr<char *> scenes = obs_frontend_get_scene_names();
char **temp = scenes;
while (*temp) {
const char *name = *temp;
@ -110,7 +106,7 @@ SceneSwitcher::SceneSwitcher(QWidget *parent)
ui->noMatchDontSwitch->setChecked(true);
ui->noMatchSwitchScene->setCurrentText(
GetWeakSourceName(switcher->nonMatchingScene).c_str());
GetWeakSourceName(switcher->nonMatchingScene).c_str());
ui->checkInterval->setValue(switcher->interval);
vector<string> windows;
@ -121,11 +117,10 @@ SceneSwitcher::SceneSwitcher(QWidget *parent)
for (auto &s : switcher->switches) {
string sceneName = GetWeakSourceName(s.scene);
QString text = MakeSwitchName(sceneName.c_str(),
s.window.c_str());
QString text =
MakeSwitchName(sceneName.c_str(), s.window.c_str());
QListWidgetItem *item = new QListWidgetItem(text,
ui->switches);
QListWidgetItem *item = new QListWidgetItem(text, ui->switches);
item->setData(Qt::UserRole, s.window.c_str());
}
@ -137,7 +132,7 @@ SceneSwitcher::SceneSwitcher(QWidget *parent)
loading = false;
}
void SceneSwitcher::closeEvent(QCloseEvent*)
void SceneSwitcher::closeEvent(QCloseEvent *)
{
obs_frontend_save();
}
@ -149,8 +144,7 @@ int SceneSwitcher::FindByData(const QString &window)
for (int i = 0; i < count; i++) {
QListWidgetItem *item = ui->switches->item(i);
QString itemWindow =
item->data(Qt::UserRole).toString();
QString itemWindow = item->data(Qt::UserRole).toString();
if (itemWindow == window) {
idx = i;
@ -206,16 +200,16 @@ void SceneSwitcher::on_add_clicked()
if (idx == -1) {
try {
lock_guard<mutex> lock(switcher->m);
switcher->switches.emplace_back(source,
windowName.toUtf8().constData());
QListWidgetItem *item = new QListWidgetItem(text,
ui->switches);
switcher->switches.emplace_back(
source, windowName.toUtf8().constData());
QListWidgetItem *item =
new QListWidgetItem(text, ui->switches);
item->setData(Qt::UserRole, v);
} catch (const regex_error &) {
QMessageBox::warning(this,
obs_module_text("InvalidRegex.Title"),
obs_module_text("InvalidRegex.Text"));
QMessageBox::warning(
this, obs_module_text("InvalidRegex.Title"),
obs_module_text("InvalidRegex.Text"));
}
} else {
QListWidgetItem *item = ui->switches->item(idx);
@ -274,8 +268,7 @@ void SceneSwitcher::on_startAtLaunch_toggled(bool value)
void SceneSwitcher::UpdateNonMatchingScene(const QString &name)
{
obs_source_t *scene = obs_get_source_by_name(
name.toUtf8().constData());
obs_source_t *scene = obs_get_source_by_name(name.toUtf8().constData());
obs_weak_source_t *ws = obs_source_get_weak_source(scene);
switcher->nonMatchingScene = ws;
@ -303,8 +296,7 @@ void SceneSwitcher::on_noMatchSwitch_clicked()
UpdateNonMatchingScene(ui->noMatchSwitchScene->currentText());
}
void SceneSwitcher::on_noMatchSwitchScene_currentTextChanged(
const QString &text)
void SceneSwitcher::on_noMatchSwitchScene_currentTextChanged(const QString &text)
{
if (loading)
return;
@ -357,13 +349,13 @@ static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
for (SceneSwitch &s : switcher->switches) {
obs_data_t *array_obj = obs_data_create();
obs_source_t *source = obs_weak_source_get_source(
s.scene);
obs_source_t *source =
obs_weak_source_get_source(s.scene);
if (source) {
const char *n = obs_source_get_name(source);
obs_data_set_string(array_obj, "scene", n);
obs_data_set_string(array_obj, "window_title",
s.window.c_str());
s.window.c_str());
obs_data_array_push_back(array, array_obj);
obs_source_release(source);
}
@ -376,9 +368,9 @@ static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
obs_data_set_int(obj, "interval", switcher->interval);
obs_data_set_string(obj, "non_matching_scene",
nonMatchingSceneName.c_str());
nonMatchingSceneName.c_str());
obs_data_set_bool(obj, "switch_if_not_matching",
switcher->switchIfNotMatching);
switcher->switchIfNotMatching);
obs_data_set_bool(obj, "active", switcher->th.joinable());
obs_data_set_array(obj, "switches", array);
@ -389,8 +381,8 @@ static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
} else {
switcher->m.lock();
obs_data_t *obj = obs_data_get_obj(save_data,
"auto-scene-switcher");
obs_data_t *obj =
obs_data_get_obj(save_data, "auto-scene-switcher");
obs_data_array_t *array = obs_data_get_array(obj, "switches");
size_t count = obs_data_array_count(array);
@ -420,8 +412,7 @@ static void SaveSceneSwitcher(obs_data_t *save_data, bool saving, void *)
obs_data_get_string(array_obj, "window_title");
switcher->switches.emplace_back(
GetWeakSourceByName(scene),
window);
GetWeakSourceByName(scene), window);
obs_data_release(array_obj);
}
@ -476,18 +467,18 @@ void SwitcherData::Thread()
for (SceneSwitch &s : switches) {
try {
bool matches = regex_match(
title, s.re);
title, s.re);
if (matches) {
match = true;
scene = s.scene;
break;
}
} catch (const regex_error &) {}
} catch (const regex_error &) {
}
}
}
if (!match && switchIfNotMatching &&
nonMatchingScene) {
if (!match && switchIfNotMatching && nonMatchingScene) {
match = true;
scene = nonMatchingScene;
}
@ -513,7 +504,7 @@ void SwitcherData::Thread()
void SwitcherData::Start()
{
if (!switcher->th.joinable())
switcher->th = thread([] () {switcher->Thread();});
switcher->th = thread([]() { switcher->Thread(); });
}
void SwitcherData::Stop()
@ -542,17 +533,16 @@ static void OBSEvent(enum obs_frontend_event event, void *)
extern "C" void InitSceneSwitcher()
{
QAction *action = (QAction*)obs_frontend_add_tools_menu_qaction(
obs_module_text("SceneSwitcher"));
QAction *action = (QAction *)obs_frontend_add_tools_menu_qaction(
obs_module_text("SceneSwitcher"));
switcher = new SwitcherData;
auto cb = [] ()
{
auto cb = []() {
obs_frontend_push_ui_translation(obs_module_get_string);
QMainWindow *window =
(QMainWindow*)obs_frontend_get_main_window();
(QMainWindow *)obs_frontend_get_main_window();
SceneSwitcher ss(window);
ss.exec();

View file

@ -1,33 +1,24 @@
#include "captions-handler.hpp"
captions_handler::captions_handler(
captions_cb callback,
enum audio_format format,
uint32_t sample_rate)
captions_handler::captions_handler(captions_cb callback,
enum audio_format format,
uint32_t sample_rate)
: cb(callback)
{
if (!reset_resampler(format, sample_rate))
throw CAPTIONS_ERROR_GENERIC_FAIL;
}
bool captions_handler::reset_resampler(
enum audio_format format,
uint32_t sample_rate)
bool captions_handler::reset_resampler(enum audio_format format,
uint32_t sample_rate)
try {
obs_audio_info ai;
if (!obs_get_audio_info(&ai))
throw std::string("Failed to get OBS audio info");
resample_info src = {
ai.samples_per_sec,
AUDIO_FORMAT_FLOAT_PLANAR,
ai.speakers
};
resample_info dst = {
sample_rate,
format,
SPEAKERS_MONO
};
resample_info src = {ai.samples_per_sec, AUDIO_FORMAT_FLOAT_PLANAR,
ai.speakers};
resample_info dst = {sample_rate, format, SPEAKERS_MONO};
if (!resampler.reset(dst, src))
throw std::string("Failed to create audio resampler");
@ -46,9 +37,9 @@ void captions_handler::push_audio(const audio_data *audio)
uint64_t ts_offset;
bool success;
success = audio_resampler_resample(resampler,
out, &frames, &ts_offset,
(const uint8_t *const *)audio->data, audio->frames);
success = audio_resampler_resample(resampler, out, &frames, &ts_offset,
(const uint8_t *const *)audio->data,
audio->frames);
if (success)
pcm_data(out[0], frames);
}

View file

@ -9,10 +9,7 @@ class resampler_obj {
audio_resampler_t *resampler = nullptr;
public:
inline ~resampler_obj()
{
audio_resampler_destroy(resampler);
}
inline ~resampler_obj() { audio_resampler_destroy(resampler); }
inline bool reset(const resample_info &dst, const resample_info &src)
{
@ -21,15 +18,15 @@ public:
return !!resampler;
}
inline operator audio_resampler_t*() {return resampler;}
inline operator audio_resampler_t *() { return resampler; }
};
/* ------------------------------------------------------------------------- */
typedef std::function<void (const std::string &)> captions_cb;
typedef std::function<void(const std::string &)> captions_cb;
#define captions_error(s) std::string(obs_module_text("Captions.Error." ## s))
#define CAPTIONS_ERROR_GENERIC_FAIL captions_error("GenericFail")
#define captions_error(s) std::string(obs_module_text("Captions.Error."##s))
#define CAPTIONS_ERROR_GENERIC_FAIL captions_error("GenericFail")
/* ------------------------------------------------------------------------- */
@ -38,22 +35,17 @@ class captions_handler {
resampler_obj resampler;
protected:
inline void callback(const std::string &text)
{
cb(text);
}
inline void callback(const std::string &text) { cb(text); }
virtual void pcm_data(const void *data, size_t frames)=0;
virtual void pcm_data(const void *data, size_t frames) = 0;
/* always resamples to 1 channel */
bool reset_resampler(enum audio_format format, uint32_t sample_rate);
public:
/* throw std::string for errors shown to users */
captions_handler(
captions_cb callback,
enum audio_format format,
uint32_t sample_rate);
captions_handler(captions_cb callback, enum audio_format format,
uint32_t sample_rate);
virtual ~captions_handler() {}
void push_audio(const audio_data *audio);
@ -62,6 +54,6 @@ public:
/* ------------------------------------------------------------------------- */
struct captions_handler_info {
std::string (*name)(void);
std::string (*name)(void);
captions_handler *(*create)(captions_cb cb, const std::string &lang);
};

View file

@ -8,16 +8,17 @@
using namespace std;
#if 0
#define debugfunc(format, ...) blog(LOG_DEBUG, "[Captions] %s(" format ")", \
__FUNCTION__, ##__VA_ARGS__)
#define debugfunc(format, ...) \
blog(LOG_DEBUG, "[Captions] %s(" format ")", __FUNCTION__, \
##__VA_ARGS__)
#else
#define debugfunc(format, ...)
#endif
CaptionStream::CaptionStream(DWORD samplerate_, mssapi_captions *handler_) :
handler(handler_),
samplerate(samplerate_),
event(CreateEvent(nullptr, false, false, nullptr))
CaptionStream::CaptionStream(DWORD samplerate_, mssapi_captions *handler_)
: handler(handler_),
samplerate(samplerate_),
event(CreateEvent(nullptr, false, false, nullptr))
{
buf_info.ulMsMinNotification = 50;
buf_info.ulMsBufferSize = 500;
@ -66,15 +67,15 @@ STDMETHODIMP CaptionStream::QueryInterface(REFIID riid, void **ppv)
} else if (riid == IID_IStream) {
AddRef();
*ppv = (IStream*)this;
*ppv = (IStream *)this;
} else if (riid == IID_ISpStreamFormat) {
AddRef();
*ppv = (ISpStreamFormat*)this;
*ppv = (ISpStreamFormat *)this;
} else if (riid == IID_ISpAudio) {
AddRef();
*ppv = (ISpAudio*)this;
*ppv = (ISpAudio *)this;
} else {
*ppv = nullptr;
@ -134,8 +135,7 @@ STDMETHODIMP CaptionStream::Read(void *data, ULONG bytes, ULONG *read_bytes)
return hr;
}
STDMETHODIMP CaptionStream::Write(const void *, ULONG bytes,
ULONG*)
STDMETHODIMP CaptionStream::Write(const void *, ULONG bytes, ULONG *)
{
debugfunc("data, %lu, written_bytes", bytes);
UNUSED_PARAMETER(bytes);
@ -146,7 +146,7 @@ STDMETHODIMP CaptionStream::Write(const void *, ULONG bytes,
// IStream methods
STDMETHODIMP CaptionStream::Seek(LARGE_INTEGER move, DWORD origin,
ULARGE_INTEGER *new_pos)
ULARGE_INTEGER *new_pos)
{
debugfunc("%lld, %lx, new_pos", move, origin);
UNUSED_PARAMETER(move);
@ -170,8 +170,8 @@ STDMETHODIMP CaptionStream::SetSize(ULARGE_INTEGER new_size)
}
STDMETHODIMP CaptionStream::CopyTo(IStream *stream, ULARGE_INTEGER bytes,
ULARGE_INTEGER *read_bytes,
ULARGE_INTEGER *written_bytes)
ULARGE_INTEGER *read_bytes,
ULARGE_INTEGER *written_bytes)
{
HRESULT hr;
@ -213,7 +213,7 @@ STDMETHODIMP CaptionStream::Revert(void)
}
STDMETHODIMP CaptionStream::LockRegion(ULARGE_INTEGER offset,
ULARGE_INTEGER size, DWORD type)
ULARGE_INTEGER size, DWORD type)
{
debugfunc("%llu, %llu, %ld", offset, size, type);
UNUSED_PARAMETER(offset);
@ -224,7 +224,7 @@ STDMETHODIMP CaptionStream::LockRegion(ULARGE_INTEGER offset,
}
STDMETHODIMP CaptionStream::UnlockRegion(ULARGE_INTEGER offset,
ULARGE_INTEGER size, DWORD type)
ULARGE_INTEGER size, DWORD type)
{
debugfunc("%llu, %llu, %ld", offset, size, type);
UNUSED_PARAMETER(offset);
@ -250,7 +250,7 @@ STDMETHODIMP CaptionStream::Stat(STATSTG *stg, DWORD flag)
if (flag == STATFLAG_DEFAULT) {
size_t byte_size = (wcslen(stat_name) + 1) * sizeof(wchar_t);
stg->pwcsName = (wchar_t*)CoTaskMemAlloc(byte_size);
stg->pwcsName = (wchar_t *)CoTaskMemAlloc(byte_size);
memcpy(stg->pwcsName, stat_name, byte_size);
}
@ -267,7 +267,7 @@ STDMETHODIMP CaptionStream::Clone(IStream **stream)
// ISpStreamFormat methods
STDMETHODIMP CaptionStream::GetFormat(GUID *guid,
WAVEFORMATEX **co_mem_wfex_out)
WAVEFORMATEX **co_mem_wfex_out)
{
debugfunc("guid, co_mem_wfex_out");
@ -282,7 +282,7 @@ STDMETHODIMP CaptionStream::GetFormat(GUID *guid,
void *wfex = CoTaskMemAlloc(sizeof(format));
memcpy(wfex, &format, sizeof(format));
*co_mem_wfex_out = (WAVEFORMATEX*)wfex;
*co_mem_wfex_out = (WAVEFORMATEX *)wfex;
return S_OK;
}
@ -296,7 +296,7 @@ STDMETHODIMP CaptionStream::SetState(SPAUDIOSTATE state_, ULONGLONG)
}
STDMETHODIMP CaptionStream::SetFormat(REFGUID guid_ref,
const WAVEFORMATEX *wfex)
const WAVEFORMATEX *wfex)
{
debugfunc("guid, wfex");
if (!wfex)
@ -306,7 +306,7 @@ STDMETHODIMP CaptionStream::SetFormat(REFGUID guid_ref,
lock_guard<mutex> lock(m);
memcpy(&format, wfex, sizeof(format));
if (!handler->reset_resampler(AUDIO_FORMAT_16BIT,
wfex->nSamplesPerSec))
wfex->nSamplesPerSec))
return E_FAIL;
/* 50 msec */
@ -354,7 +354,7 @@ STDMETHODIMP CaptionStream::GetBufferInfo(SPAUDIOBUFFERINFO *buf_info_)
}
STDMETHODIMP CaptionStream::GetDefaultFormat(GUID *format,
WAVEFORMATEX **co_mem_wfex_out)
WAVEFORMATEX **co_mem_wfex_out)
{
debugfunc("format, co_mem_wfex_out");
@ -365,7 +365,7 @@ STDMETHODIMP CaptionStream::GetDefaultFormat(GUID *format,
memcpy(wfex, &format, sizeof(format));
*format = SPDFID_WaveFormatEx;
*co_mem_wfex_out = (WAVEFORMATEX*)wfex;
*co_mem_wfex_out = (WAVEFORMATEX *)wfex;
return S_OK;
}

View file

@ -13,10 +13,11 @@
class CircleBuf {
circlebuf buf = {};
public:
inline ~CircleBuf() {circlebuf_free(&buf);}
inline operator circlebuf*() {return &buf;}
inline circlebuf *operator->() {return &buf;}
inline ~CircleBuf() { circlebuf_free(&buf); }
inline operator circlebuf *() { return &buf; }
inline circlebuf *operator->() { return &buf; }
};
class mssapi_captions;
@ -54,38 +55,38 @@ public:
// ISequentialStream methods
STDMETHODIMP Read(void *data, ULONG bytes, ULONG *read_bytes) override;
STDMETHODIMP Write(const void *data, ULONG bytes, ULONG *written_bytes)
override;
STDMETHODIMP Write(const void *data, ULONG bytes,
ULONG *written_bytes) override;
// IStream methods
STDMETHODIMP Seek(LARGE_INTEGER move, DWORD origin,
ULARGE_INTEGER *new_pos) override;
ULARGE_INTEGER *new_pos) override;
STDMETHODIMP SetSize(ULARGE_INTEGER new_size) override;
STDMETHODIMP CopyTo(IStream *stream, ULARGE_INTEGER bytes,
ULARGE_INTEGER *read_bytes,
ULARGE_INTEGER *written_bytes) override;
ULARGE_INTEGER *read_bytes,
ULARGE_INTEGER *written_bytes) override;
STDMETHODIMP Commit(DWORD commit_flags) override;
STDMETHODIMP Revert(void) override;
STDMETHODIMP LockRegion(ULARGE_INTEGER offset, ULARGE_INTEGER size,
DWORD type) override;
DWORD type) override;
STDMETHODIMP UnlockRegion(ULARGE_INTEGER offset, ULARGE_INTEGER size,
DWORD type) override;
DWORD type) override;
STDMETHODIMP Stat(STATSTG *stg, DWORD flags) override;
STDMETHODIMP Clone(IStream **stream) override;
// ISpStreamFormat methods
STDMETHODIMP GetFormat(GUID *guid, WAVEFORMATEX **co_mem_wfex_out)
override;
STDMETHODIMP GetFormat(GUID *guid,
WAVEFORMATEX **co_mem_wfex_out) override;
// ISpAudio methods
STDMETHODIMP SetState(SPAUDIOSTATE state, ULONGLONG reserved) override;
STDMETHODIMP SetFormat(REFGUID guid_ref, const WAVEFORMATEX *wfex)
override;
STDMETHODIMP SetFormat(REFGUID guid_ref,
const WAVEFORMATEX *wfex) override;
STDMETHODIMP GetStatus(SPAUDIOSTATUS *status) override;
STDMETHODIMP SetBufferInfo(const SPAUDIOBUFFERINFO *buf_info) override;
STDMETHODIMP GetBufferInfo(SPAUDIOBUFFERINFO *buf_info) override;
STDMETHODIMP GetDefaultFormat(GUID *format,
WAVEFORMATEX **co_mem_wfex_out) override;
WAVEFORMATEX **co_mem_wfex_out) override;
STDMETHODIMP_(HANDLE) EventHandle(void) override;
STDMETHODIMP GetVolumeLevel(ULONG *level) override;
STDMETHODIMP SetVolumeLevel(ULONG level) override;

View file

@ -1,16 +1,13 @@
#include "captions-mssapi.hpp"
#define do_log(type, format, ...) blog(type, "[Captions] " format, \
##__VA_ARGS__)
#define do_log(type, format, ...) \
blog(type, "[Captions] " format, ##__VA_ARGS__)
#define error(format, ...) do_log(LOG_ERROR, format, ##__VA_ARGS__)
#define debug(format, ...) do_log(LOG_DEBUG, format, ##__VA_ARGS__)
mssapi_captions::mssapi_captions(
captions_cb callback,
const std::string &lang) try
: captions_handler(callback, AUDIO_FORMAT_16BIT, 16000)
{
mssapi_captions::mssapi_captions(captions_cb callback, const std::string &lang)
try : captions_handler(callback, AUDIO_FORMAT_16BIT, 16000) {
HRESULT hr;
std::wstring wlang;
@ -33,7 +30,7 @@ mssapi_captions::mssapi_captions(
throw HRError("SpFindBestToken failed", hr);
hr = CoCreateInstance(CLSID_SpInprocRecognizer, nullptr, CLSCTX_ALL,
__uuidof(ISpRecognizer), (void**)&recognizer);
__uuidof(ISpRecognizer), (void **)&recognizer);
if (FAILED(hr))
throw HRError("CoCreateInstance for recognizer failed", hr);
@ -50,7 +47,7 @@ mssapi_captions::mssapi_captions(
throw HRError("CreateRecoContext failed", hr);
ULONGLONG interest = SPFEI(SPEI_RECOGNITION) |
SPFEI(SPEI_END_SR_STREAM);
SPFEI(SPEI_END_SR_STREAM);
hr = context->SetInterest(interest, interest);
if (FAILED(hr))
throw HRError("SetInterest failed", hr);
@ -80,7 +77,7 @@ mssapi_captions::mssapi_captions(
throw HRError("LoadDictation failed", hr);
try {
t = std::thread([this] () {main_thread();});
t = std::thread([this]() { main_thread(); });
} catch (...) {
throw "Failed to create thread";
}
@ -133,8 +130,8 @@ try {
ISpRecoResult *result = event.RecoResult();
CoTaskMemPtr<wchar_t> text;
hr = result->GetText((ULONG)-1, (ULONG)-1,
true, &text, nullptr);
hr = result->GetText((ULONG)-1, (ULONG)-1, true,
&text, nullptr);
if (FAILED(hr))
continue;
@ -168,12 +165,7 @@ void mssapi_captions::pcm_data(const void *data, size_t frames)
}
captions_handler_info mssapi_info = {
[] () -> std::string
{
return "Microsoft Speech-to-Text";
},
[] (captions_cb cb, const std::string &lang) -> captions_handler *
{
[]() -> std::string { return "Microsoft Speech-to-Text"; },
[](captions_cb cb, const std::string &lang) -> captions_handler * {
return new mssapi_captions(cb, lang);
}
};
}};

View file

@ -27,16 +27,16 @@
class mssapi_captions : public captions_handler {
friend class CaptionStream;
ComPtr<CaptionStream> audio;
ComPtr<CaptionStream> audio;
ComPtr<ISpObjectToken> token;
ComPtr<ISpRecoGrammar> grammar;
ComPtr<ISpRecognizer> recognizer;
ComPtr<ISpRecognizer> recognizer;
ComPtr<ISpRecoContext> context;
HANDLE notify;
WinHandle stop;
std::thread t;
bool started = false;
HANDLE notify;
WinHandle stop;
std::thread t;
bool started = false;
void main_thread();

View file

@ -31,8 +31,8 @@
#include "captions-mssapi.hpp"
#define do_log(type, format, ...) blog(type, "[Captions] " format, \
##__VA_ARGS__)
#define do_log(type, format, ...) \
blog(type, "[Captions] " format, ##__VA_ARGS__)
#define warn(format, ...) do_log(LOG_WARNING, format, ##__VA_ARGS__)
#define debug(format, ...) do_log(LOG_DEBUG, format, ##__VA_ARGS__)
@ -48,10 +48,10 @@ struct obs_captions {
unique_ptr<captions_handler> handler;
LANGID lang_id = GetUserDefaultUILanguage();
std::unordered_map<std::string, captions_handler_info&> handler_types;
std::unordered_map<std::string, captions_handler_info &> handler_types;
inline void register_handler(const char *id,
captions_handler_info &info)
captions_handler_info &info)
{
handler_types.emplace(id, info);
}
@ -60,7 +60,7 @@ struct obs_captions {
void stop();
obs_captions();
inline ~obs_captions() {stop();}
inline ~obs_captions() { stop(); }
};
static obs_captions *captions = nullptr;
@ -74,9 +74,9 @@ struct locale_info {
inline locale_info() {}
inline locale_info(const locale_info &) = delete;
inline locale_info(locale_info &&li)
: name(std::move(li.name)),
id(li.id)
{}
: name(std::move(li.name)), id(li.id)
{
}
};
static void get_valid_locale_names(vector<locale_info> &names);
@ -84,16 +84,14 @@ static bool valid_lang(LANGID id);
/* ------------------------------------------------------------------------- */
CaptionsDialog::CaptionsDialog(QWidget *parent) :
QDialog(parent),
ui(new Ui_CaptionsDialog)
CaptionsDialog::CaptionsDialog(QWidget *parent)
: QDialog(parent), ui(new Ui_CaptionsDialog)
{
ui->setupUi(this);
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
auto cb = [this] (obs_source_t *source)
{
auto cb = [this](obs_source_t *source) {
uint32_t caps = obs_source_get_output_flags(source);
QString name = obs_source_get_name(source);
@ -111,8 +109,11 @@ CaptionsDialog::CaptionsDialog(QWidget *parent) :
ui->source->blockSignals(true);
ui->source->addItem(QStringLiteral(""));
ui->source->setCurrentIndex(0);
obs_enum_sources([] (void *data, obs_source_t *source) {
return (*static_cast<cb_t*>(data))(source);}, &cb);
obs_enum_sources(
[](void *data, obs_source_t *source) {
return (*static_cast<cb_t *>(data))(source);
},
&cb);
ui->source->blockSignals(false);
for (auto &ht : captions->handler_types) {
@ -232,8 +233,8 @@ static void caption_text(const std::string &text)
}
}
static void audio_capture(void*, obs_source_t*,
const struct audio_data *audio, bool)
static void audio_capture(void *, obs_source_t *,
const struct audio_data *audio, bool)
{
captions->handler->push_audio(audio);
}
@ -245,14 +246,13 @@ void obs_captions::start()
auto pair = handler_types.find(handler_id);
if (pair == handler_types.end()) {
warn("Failed to find handler '%s'",
handler_id.c_str());
warn("Failed to find handler '%s'", handler_id.c_str());
return;
}
if (!LCIDToLocaleName(lang_id, wname, 256, 0)) {
warn("Failed to get locale name: %d",
(int)GetLastError());
(int)GetLastError());
return;
}
@ -271,24 +271,24 @@ void obs_captions::start()
}
try {
captions_handler *h = pair->second.create(caption_text,
lang_name);
captions_handler *h =
pair->second.create(caption_text, lang_name);
handler.reset(h);
OBSSource s = OBSGetStrongRef(source);
obs_source_add_audio_capture_callback(s,
audio_capture, nullptr);
obs_source_add_audio_capture_callback(s, audio_capture,
nullptr);
} catch (std::string text) {
QWidget *window =
(QWidget*)obs_frontend_get_main_window();
(QWidget *)obs_frontend_get_main_window();
warn("Failed to create handler: %s", text.c_str());
QMessageBox::warning(window,
QMessageBox::warning(
window,
obs_module_text("Captions.Error.GenericFail"),
text.c_str());
}
}
}
@ -297,8 +297,8 @@ void obs_captions::stop()
{
OBSSource s = OBSGetStrongRef(source);
if (s)
obs_source_remove_audio_capture_callback(s,
audio_capture, nullptr);
obs_source_remove_audio_capture_callback(s, audio_capture,
nullptr);
handler.reset();
}
@ -332,42 +332,18 @@ static void get_valid_locale_names(vector<locale_info> &locales)
char locale_name[256];
static const LANGID default_locales[] = {
0x0409,
0x0401,
0x0402,
0x0403,
0x0404,
0x0405,
0x0406,
0x0407,
0x0408,
0x040a,
0x040b,
0x040c,
0x040d,
0x040e,
0x040f,
0x0410,
0x0411,
0x0412,
0x0413,
0x0414,
0x0415,
0x0416,
0x0417,
0x0418,
0x0419,
0x041a,
0
};
0x0409, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406,
0x0407, 0x0408, 0x040a, 0x040b, 0x040c, 0x040d, 0x040e,
0x040f, 0x0410, 0x0411, 0x0412, 0x0413, 0x0414, 0x0415,
0x0416, 0x0417, 0x0418, 0x0419, 0x041a, 0};
/* ---------------------------------- */
LANGID def_id = GetUserDefaultUILanguage();
LANGID id = def_id;
if (valid_lang(id) && get_locale_name(id, locale_name)) {
dstr_copy(cur.name, obs_module_text(
"Captions.CurrentSystemLanguage"));
dstr_copy(cur.name,
obs_module_text("Captions.CurrentSystemLanguage"));
dstr_replace(cur.name, "%1", locale_name);
cur.id = id;
@ -381,8 +357,7 @@ static void get_valid_locale_names(vector<locale_info> &locales)
while (*locale) {
id = *locale;
if (id != def_id &&
valid_lang(id) &&
if (id != def_id && valid_lang(id) &&
get_locale_name(id, locale_name)) {
dstr_copy(cur.name, locale_name);
@ -418,17 +393,17 @@ static void obs_event(enum obs_frontend_event event, void *)
FreeCaptions();
}
static void save_caption_data(obs_data_t *save_data, bool saving, void*)
static void save_caption_data(obs_data_t *save_data, bool saving, void *)
{
if (saving) {
obs_data_t *obj = obs_data_create();
obs_data_set_string(obj, "source",
captions->source_name.c_str());
captions->source_name.c_str());
obs_data_set_bool(obj, "enabled", !!captions->handler);
obs_data_set_int(obj, "lang_id", captions->lang_id);
obs_data_set_string(obj, "provider",
captions->handler_id.c_str());
captions->handler_id.c_str());
obs_data_set_obj(save_data, "captions", obj);
obs_data_release(obj);
@ -440,15 +415,15 @@ static void save_caption_data(obs_data_t *save_data, bool saving, void*)
obj = obs_data_create();
obs_data_set_default_int(obj, "lang_id",
GetUserDefaultUILanguage());
GetUserDefaultUILanguage());
obs_data_set_default_string(obj, "provider", DEFAULT_HANDLER);
bool enabled = obs_data_get_bool(obj, "enabled");
captions->source_name = obs_data_get_string(obj, "source");
captions->lang_id = (int)obs_data_get_int(obj, "lang_id");
captions->handler_id = obs_data_get_string(obj, "provider");
captions->source = GetWeakSourceByName(
captions->source_name.c_str());
captions->source =
GetWeakSourceByName(captions->source_name.c_str());
obs_data_release(obj);
if (enabled)
@ -458,17 +433,15 @@ static void save_caption_data(obs_data_t *save_data, bool saving, void*)
extern "C" void InitCaptions()
{
QAction *action = (QAction*)obs_frontend_add_tools_menu_qaction(
obs_module_text("Captions"));
QAction *action = (QAction *)obs_frontend_add_tools_menu_qaction(
obs_module_text("Captions"));
captions = new obs_captions;
auto cb = [] ()
{
auto cb = []() {
obs_frontend_push_ui_translation(obs_module_get_string);
QWidget *window =
(QWidget*)obs_frontend_get_main_window();
QWidget *window = (QWidget *)obs_frontend_get_main_window();
CaptionsDialog dialog(window);
dialog.exec();

View file

@ -13,19 +13,18 @@ using namespace std;
OutputTimer *ot;
OutputTimer::OutputTimer(QWidget *parent)
: QDialog(parent),
ui(new Ui_OutputTimer)
: QDialog(parent), ui(new Ui_OutputTimer)
{
ui->setupUi(this);
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
QObject::connect(ui->outputTimerStream, SIGNAL(clicked()), this,
SLOT(StreamingTimerButton()));
SLOT(StreamingTimerButton()));
QObject::connect(ui->outputTimerRecord, SIGNAL(clicked()), this,
SLOT(RecordingTimerButton()));
SLOT(RecordingTimerButton()));
QObject::connect(ui->buttonBox->button(QDialogButtonBox::Close),
SIGNAL(clicked()), this, SLOT(hide()));
SIGNAL(clicked()), this, SLOT(hide()));
streamingTimer = new QTimer(this);
streamingTimerDisplay = new QTimer(this);
@ -34,7 +33,7 @@ OutputTimer::OutputTimer(QWidget *parent)
recordingTimerDisplay = new QTimer(this);
}
void OutputTimer::closeEvent(QCloseEvent*)
void OutputTimer::closeEvent(QCloseEvent *)
{
obs_frontend_save();
}
@ -78,9 +77,7 @@ void OutputTimer::StreamTimerStart()
int minutes = ui->streamingTimerMinutes->value();
int seconds = ui->streamingTimerSeconds->value();
int total = (((hours * 3600) +
(minutes * 60)) +
seconds) * 1000;
int total = (((hours * 3600) + (minutes * 60)) + seconds) * 1000;
if (total == 0)
total = 1000;
@ -89,10 +86,10 @@ void OutputTimer::StreamTimerStart()
streamingTimer->setSingleShot(true);
QObject::connect(streamingTimer, SIGNAL(timeout()),
SLOT(EventStopStreaming()));
SLOT(EventStopStreaming()));
QObject::connect(streamingTimerDisplay, SIGNAL(timeout()), this,
SLOT(UpdateStreamTimerDisplay()));
SLOT(UpdateStreamTimerDisplay()));
streamingTimer->start();
streamingTimerDisplay->start(1000);
@ -112,9 +109,7 @@ void OutputTimer::RecordTimerStart()
int minutes = ui->recordingTimerMinutes->value();
int seconds = ui->recordingTimerSeconds->value();
int total = (((hours * 3600) +
(minutes * 60)) +
seconds) * 1000;
int total = (((hours * 3600) + (minutes * 60)) + seconds) * 1000;
if (total == 0)
total = 1000;
@ -123,10 +118,10 @@ void OutputTimer::RecordTimerStart()
recordingTimer->setSingleShot(true);
QObject::connect(recordingTimer, SIGNAL(timeout()),
SLOT(EventStopRecording()));
SLOT(EventStopRecording()));
QObject::connect(recordingTimerDisplay, SIGNAL(timeout()), this,
SLOT(UpdateRecordTimerDisplay()));
SLOT(UpdateRecordTimerDisplay()));
recordingTimer->start();
recordingTimerDisplay->start(1000);
@ -226,60 +221,57 @@ static void SaveOutputTimer(obs_data_t *save_data, bool saving, void *)
obs_data_t *obj = obs_data_create();
obs_data_set_int(obj, "streamTimerHours",
ot->ui->streamingTimerHours->value());
ot->ui->streamingTimerHours->value());
obs_data_set_int(obj, "streamTimerMinutes",
ot->ui->streamingTimerMinutes->value());
ot->ui->streamingTimerMinutes->value());
obs_data_set_int(obj, "streamTimerSeconds",
ot->ui->streamingTimerSeconds->value());
ot->ui->streamingTimerSeconds->value());
obs_data_set_int(obj, "recordTimerHours",
ot->ui->recordingTimerHours->value());
ot->ui->recordingTimerHours->value());
obs_data_set_int(obj, "recordTimerMinutes",
ot->ui->recordingTimerMinutes->value());
ot->ui->recordingTimerMinutes->value());
obs_data_set_int(obj, "recordTimerSeconds",
ot->ui->recordingTimerSeconds->value());
ot->ui->recordingTimerSeconds->value());
obs_data_set_bool(obj, "autoStartStreamTimer",
ot->ui->autoStartStreamTimer->isChecked());
ot->ui->autoStartStreamTimer->isChecked());
obs_data_set_bool(obj, "autoStartRecordTimer",
ot->ui->autoStartRecordTimer->isChecked());
ot->ui->autoStartRecordTimer->isChecked());
obs_data_set_obj(save_data, "output-timer", obj);
obs_data_release(obj);
} else {
obs_data_t *obj = obs_data_get_obj(save_data,
"output-timer");
obs_data_t *obj = obs_data_get_obj(save_data, "output-timer");
if (!obj)
obj = obs_data_create();
ot->ui->streamingTimerHours->setValue(
obs_data_get_int(obj, "streamTimerHours"));
obs_data_get_int(obj, "streamTimerHours"));
ot->ui->streamingTimerMinutes->setValue(
obs_data_get_int(obj, "streamTimerMinutes"));
obs_data_get_int(obj, "streamTimerMinutes"));
ot->ui->streamingTimerSeconds->setValue(
obs_data_get_int(obj, "streamTimerSeconds"));
obs_data_get_int(obj, "streamTimerSeconds"));
ot->ui->recordingTimerHours->setValue(
obs_data_get_int(obj, "recordTimerHours"));
obs_data_get_int(obj, "recordTimerHours"));
ot->ui->recordingTimerMinutes->setValue(
obs_data_get_int(obj, "recordTimerMinutes"));
obs_data_get_int(obj, "recordTimerMinutes"));
ot->ui->recordingTimerSeconds->setValue(
obs_data_get_int(obj, "recordTimerSeconds"));
obs_data_get_int(obj, "recordTimerSeconds"));
ot->ui->autoStartStreamTimer->setChecked(
obs_data_get_bool(obj, "autoStartStreamTimer"));
obs_data_get_bool(obj, "autoStartStreamTimer"));
ot->ui->autoStartRecordTimer->setChecked(
obs_data_get_bool(obj, "autoStartRecordTimer"));
obs_data_get_bool(obj, "autoStartRecordTimer"));
obs_data_release(obj);
}
}
extern "C" void FreeOutputTimer()
{
}
extern "C" void FreeOutputTimer() {}
static void OBSEvent(enum obs_frontend_event event, void *)
{
@ -299,19 +291,16 @@ static void OBSEvent(enum obs_frontend_event event, void *)
extern "C" void InitOutputTimer()
{
QAction *action = (QAction*)obs_frontend_add_tools_menu_qaction(
obs_module_text("OutputTimer"));
QAction *action = (QAction *)obs_frontend_add_tools_menu_qaction(
obs_module_text("OutputTimer"));
obs_frontend_push_ui_translation(obs_module_get_string);
QMainWindow *window = (QMainWindow*)obs_frontend_get_main_window();
QMainWindow *window = (QMainWindow *)obs_frontend_get_main_window();
ot = new OutputTimer(window);
auto cb = [] ()
{
ot->ShowHideDialog();
};
auto cb = []() { ot->ShowHideDialog(); };
obs_frontend_pop_ui_translation();

View file

@ -43,7 +43,7 @@
/* ----------------------------------------------------------------- */
using OBSScript = OBSObj<obs_script_t*, obs_script_destroy>;
using OBSScript = OBSObj<obs_script_t *, obs_script_destroy>;
struct ScriptData {
std::vector<OBSScript> scripts;
@ -92,11 +92,10 @@ ScriptLogWindow::ScriptLogWindow() : QWidget(nullptr)
QHBoxLayout *buttonLayout = new QHBoxLayout();
QPushButton *clearButton = new QPushButton(tr("Clear"));
connect(clearButton, &QPushButton::clicked,
this, &ScriptLogWindow::ClearWindow);
connect(clearButton, &QPushButton::clicked, this,
&ScriptLogWindow::ClearWindow);
QPushButton *closeButton = new QPushButton(tr("Close"));
connect(closeButton, &QPushButton::clicked,
this, &QDialog::hide);
connect(closeButton, &QPushButton::clicked, this, &QDialog::hide);
buttonLayout->addStretch();
buttonLayout->addWidget(clearButton);
@ -112,8 +111,8 @@ ScriptLogWindow::ScriptLogWindow() : QWidget(nullptr)
resize(600, 400);
config_t *global_config = obs_frontend_get_global_config();
const char *geom = config_get_string(global_config,
"ScriptLogWindow", "geometry");
const char *geom =
config_get_string(global_config, "ScriptLogWindow", "geometry");
if (geom != nullptr) {
QByteArray ba = QByteArray::fromBase64(QByteArray(geom));
restoreGeometry(ba);
@ -121,16 +120,15 @@ ScriptLogWindow::ScriptLogWindow() : QWidget(nullptr)
setWindowTitle(obs_module_text("ScriptLogWindow"));
connect(edit->verticalScrollBar(), &QAbstractSlider::sliderMoved,
this, &ScriptLogWindow::ScrollChanged);
connect(edit->verticalScrollBar(), &QAbstractSlider::sliderMoved, this,
&ScriptLogWindow::ScrollChanged);
}
ScriptLogWindow::~ScriptLogWindow()
{
config_t *global_config = obs_frontend_get_global_config();
config_set_string(global_config,
"ScriptLogWindow", "geometry",
saveGeometry().toBase64().constData());
config_set_string(global_config, "ScriptLogWindow", "geometry",
saveGeometry().toBase64().constData());
}
void ScriptLogWindow::ScrollChanged(int val)
@ -180,17 +178,15 @@ void ScriptLogWindow::Clear()
/* ----------------------------------------------------------------- */
ScriptsTool::ScriptsTool()
: QWidget (nullptr),
ui (new Ui_ScriptsTool)
ScriptsTool::ScriptsTool() : QWidget(nullptr), ui(new Ui_ScriptsTool)
{
ui->setupUi(this);
RefreshLists();
#if PYTHON_UI
config_t *config = obs_frontend_get_global_config();
const char *path = config_get_string(config, "Python",
"Path" ARCH_NAME);
const char *path =
config_get_string(config, "Python", "Path" ARCH_NAME);
ui->pythonPath->setText(path);
ui->pythonPathLabel->setText(obs_module_text(PYTHONPATH_LABEL_TEXT));
#else
@ -201,7 +197,7 @@ ScriptsTool::ScriptsTool()
delete propertiesView;
propertiesView = new QWidget();
propertiesView->setSizePolicy(QSizePolicy::Expanding,
QSizePolicy::Expanding);
QSizePolicy::Expanding);
ui->propertiesLayout->addWidget(propertiesView);
}
@ -217,8 +213,8 @@ void ScriptsTool::RemoveScript(const char *path)
const char *script_path = obs_script_get_path(script);
if (strcmp(script_path, path) == 0) {
scriptData->scripts.erase(
scriptData->scripts.begin() + i);
scriptData->scripts.erase(scriptData->scripts.begin() +
i);
break;
}
}
@ -323,7 +319,8 @@ void ScriptsTool::on_addScripts_clicked()
scriptData->scripts.emplace_back(script);
QListWidgetItem *item = new QListWidgetItem(script_file);
QListWidgetItem *item =
new QListWidgetItem(script_file);
item->setData(Qt::UserRole, QString(file));
ui->scripts->addItem(item);
@ -343,8 +340,10 @@ void ScriptsTool::on_removeScripts_clicked()
QList<QListWidgetItem *> items = ui->scripts->selectedItems();
for (QListWidgetItem *item : items)
RemoveScript(item->data(Qt::UserRole).toString()
.toUtf8().constData());
RemoveScript(item->data(Qt::UserRole)
.toString()
.toUtf8()
.constData());
RefreshLists();
}
@ -352,8 +351,10 @@ void ScriptsTool::on_reloadScripts_clicked()
{
QList<QListWidgetItem *> items = ui->scripts->selectedItems();
for (QListWidgetItem *item : items)
ReloadScript(item->data(Qt::UserRole).toString()
.toUtf8().constData());
ReloadScript(item->data(Qt::UserRole)
.toString()
.toUtf8()
.constData());
on_scripts_currentRowChanged(ui->scripts->currentRow());
}
@ -368,9 +369,7 @@ void ScriptsTool::on_pythonPathBrowse_clicked()
{
QString curPath = ui->pythonPath->text();
QString newPath = QFileDialog::getExistingDirectory(
this,
ui->pythonPathLabel->text(),
curPath);
this, ui->pythonPathLabel->text(), curPath);
if (newPath.isEmpty())
return;
@ -406,14 +405,14 @@ void ScriptsTool::on_scripts_currentRowChanged(int row)
if (row == -1) {
propertiesView = new QWidget();
propertiesView->setSizePolicy(QSizePolicy::Expanding,
QSizePolicy::Expanding);
QSizePolicy::Expanding);
ui->propertiesLayout->addWidget(propertiesView);
ui->description->setText(QString());
return;
}
QByteArray array = ui->scripts->item(row)->data(Qt::UserRole)
.toString().toUtf8();
QByteArray array =
ui->scripts->item(row)->data(Qt::UserRole).toString().toUtf8();
const char *path = array.constData();
obs_script_t *script = scriptData->FindScript(path);
@ -425,9 +424,10 @@ void ScriptsTool::on_scripts_currentRowChanged(int row)
OBSData settings = obs_script_get_settings(script);
obs_data_release(settings);
propertiesView = new OBSPropertiesView(settings, script,
(PropertiesReloadCallback)obs_script_get_properties,
(PropertiesUpdateCallback)obs_script_update);
propertiesView = new OBSPropertiesView(
settings, script,
(PropertiesReloadCallback)obs_script_get_properties,
(PropertiesUpdateCallback)obs_script_update);
ui->propertiesLayout->addWidget(propertiesView);
ui->description->setText(obs_script_get_description(script));
}
@ -457,8 +457,7 @@ static void obs_event(enum obs_frontend_event event, void *)
static void load_script_data(obs_data_t *load_data, bool, void *)
{
obs_data_array_t *array = obs_data_get_array(load_data,
"scripts-tool");
obs_data_array_t *array = obs_data_get_array(load_data, "scripts-tool");
delete scriptData;
scriptData = new ScriptData;
@ -509,21 +508,19 @@ static void save_script_data(obs_data_t *save_data, bool saving, void *)
}
static void script_log(void *, obs_script_t *script, int log_level,
const char *message)
const char *message)
{
QString qmsg;
if (script) {
qmsg = QStringLiteral("[%1] %2").arg(
obs_script_get_file(script),
message);
obs_script_get_file(script), message);
} else {
qmsg = QStringLiteral("[Unknown Script] %1").arg(message);
}
QMetaObject::invokeMethod(scriptLogWindow, "AddLogMsg",
Q_ARG(int, log_level),
Q_ARG(QString, qmsg));
Q_ARG(int, log_level), Q_ARG(QString, qmsg));
}
extern "C" void InitScripts()
@ -533,13 +530,13 @@ extern "C" void InitScripts()
obs_scripting_load();
obs_scripting_set_log_callback(script_log, nullptr);
QAction *action = (QAction*)obs_frontend_add_tools_menu_qaction(
obs_module_text("Scripts"));
QAction *action = (QAction *)obs_frontend_add_tools_menu_qaction(
obs_module_text("Scripts"));
#if PYTHON_UI
config_t *config = obs_frontend_get_global_config();
const char *python_path = config_get_string(config, "Python",
"Path" ARCH_NAME);
const char *python_path =
config_get_string(config, "Python", "Path" ARCH_NAME);
if (!obs_scripting_python_loaded() && python_path && *python_path)
obs_scripting_load_python(python_path);
@ -547,8 +544,7 @@ extern "C" void InitScripts()
scriptData = new ScriptData;
auto cb = [] ()
{
auto cb = []() {
obs_frontend_push_ui_translation(obs_module_get_string);
if (!scriptsWindow) {

View file

@ -8,8 +8,7 @@ class HScrollArea : public QScrollArea {
Q_OBJECT
public:
inline HScrollArea(QWidget *parent = nullptr)
: QScrollArea(parent)
inline HScrollArea(QWidget *parent = nullptr) : QScrollArea(parent)
{
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
}

View file

@ -25,13 +25,13 @@
#include "qt-wrappers.hpp"
static inline bool operator!=(const obs_key_combination_t &c1,
const obs_key_combination_t &c2)
const obs_key_combination_t &c2)
{
return c1.modifiers != c2.modifiers || c1.key != c2.key;
}
static inline bool operator==(const obs_key_combination_t &c1,
const obs_key_combination_t &c2)
const obs_key_combination_t &c2)
{
return !(c1 != c2);
}
@ -105,32 +105,34 @@ void OBSHotkeyEdit::mousePressEvent(QMouseEvent *event)
new_key.key = OBS_KEY_MOUSE3;
break;
#define MAP_BUTTON(i, j) case Qt::ExtraButton ## i: \
new_key.key = OBS_KEY_MOUSE ## j; break;
MAP_BUTTON( 1, 4);
MAP_BUTTON( 2, 5);
MAP_BUTTON( 3, 6);
MAP_BUTTON( 4, 7);
MAP_BUTTON( 5, 8);
MAP_BUTTON( 6, 9);
MAP_BUTTON( 7, 10);
MAP_BUTTON( 8, 11);
MAP_BUTTON( 9, 12);
MAP_BUTTON(10, 13);
MAP_BUTTON(11, 14);
MAP_BUTTON(12, 15);
MAP_BUTTON(13, 16);
MAP_BUTTON(14, 17);
MAP_BUTTON(15, 18);
MAP_BUTTON(16, 19);
MAP_BUTTON(17, 20);
MAP_BUTTON(18, 21);
MAP_BUTTON(19, 22);
MAP_BUTTON(20, 23);
MAP_BUTTON(21, 24);
MAP_BUTTON(22, 25);
MAP_BUTTON(23, 26);
MAP_BUTTON(24, 27);
#define MAP_BUTTON(i, j) \
case Qt::ExtraButton##i: \
new_key.key = OBS_KEY_MOUSE##j; \
break;
MAP_BUTTON(1, 4)
MAP_BUTTON(2, 5)
MAP_BUTTON(3, 6)
MAP_BUTTON(4, 7)
MAP_BUTTON(5, 8)
MAP_BUTTON(6, 9)
MAP_BUTTON(7, 10)
MAP_BUTTON(8, 11)
MAP_BUTTON(9, 12)
MAP_BUTTON(10, 13)
MAP_BUTTON(11, 14)
MAP_BUTTON(12, 15)
MAP_BUTTON(13, 16)
MAP_BUTTON(14, 17)
MAP_BUTTON(15, 18)
MAP_BUTTON(16, 19)
MAP_BUTTON(17, 20)
MAP_BUTTON(18, 21)
MAP_BUTTON(19, 22)
MAP_BUTTON(20, 23)
MAP_BUTTON(21, 24)
MAP_BUTTON(22, 25)
MAP_BUTTON(23, 26)
MAP_BUTTON(24, 27)
#undef MAP_BUTTON
}
@ -183,13 +185,13 @@ void OBSHotkeyEdit::ClearKey()
void OBSHotkeyEdit::InitSignalHandler()
{
layoutChanged = {obs_get_signal_handler(),
"hotkey_layout_change",
[](void *this_, calldata_t*)
{
auto edit = static_cast<OBSHotkeyEdit*>(this_);
QMetaObject::invokeMethod(edit, "ReloadKeyLayout");
}, this};
layoutChanged = {
obs_get_signal_handler(), "hotkey_layout_change",
[](void *this_, calldata_t *) {
auto edit = static_cast<OBSHotkeyEdit *>(this_);
QMetaObject::invokeMethod(edit, "ReloadKeyLayout");
},
this};
}
void OBSHotkeyEdit::ReloadKeyLayout()
@ -198,7 +200,7 @@ void OBSHotkeyEdit::ReloadKeyLayout()
}
void OBSHotkeyWidget::SetKeyCombinations(
const std::vector<obs_key_combination_t> &combos)
const std::vector<obs_key_combination_t> &combos)
{
if (combos.empty())
AddEdit({0, OBS_KEY_NONE});
@ -210,10 +212,8 @@ void OBSHotkeyWidget::SetKeyCombinations(
bool OBSHotkeyWidget::Changed() const
{
return changed ||
std::any_of(begin(edits), end(edits), [](OBSHotkeyEdit *edit)
{
return edit->changed;
});
std::any_of(begin(edits), end(edits),
[](OBSHotkeyEdit *edit) { return edit->changed; });
}
void OBSHotkeyWidget::Apply()
@ -230,7 +230,7 @@ void OBSHotkeyWidget::Apply()
}
void OBSHotkeyWidget::GetCombinations(
std::vector<obs_key_combination_t> &combinations) const
std::vector<obs_key_combination_t> &combinations) const
{
combinations.clear();
for (auto &edit : edits)
@ -249,21 +249,19 @@ void OBSHotkeyWidget::Save(std::vector<obs_key_combination_t> &combinations)
GetCombinations(combinations);
Apply();
auto AtomicUpdate = [&]()
{
auto AtomicUpdate = [&]() {
ignoreChangedBindings = true;
obs_hotkey_load_bindings(id,
combinations.data(), combinations.size());
obs_hotkey_load_bindings(id, combinations.data(),
combinations.size());
ignoreChangedBindings = false;
};
using AtomicUpdate_t = decltype(&AtomicUpdate);
obs_hotkey_update_atomic([](void *d)
{
(*static_cast<AtomicUpdate_t>(d))();
}, static_cast<void*>(&AtomicUpdate));
obs_hotkey_update_atomic(
[](void *d) { (*static_cast<AtomicUpdate_t>(d))(); },
static_cast<void *>(&AtomicUpdate));
}
void OBSHotkeyWidget::AddEdit(obs_key_combination combo, int idx)
@ -285,12 +283,13 @@ void OBSHotkeyWidget::AddEdit(obs_key_combination combo, int idx)
clear->setFlat(true);
clear->setEnabled(!obs_key_combination_is_empty(combo));
QObject::connect(edit, &OBSHotkeyEdit::KeyChanged,
[=](obs_key_combination_t new_combo)
{
clear->setEnabled(!obs_key_combination_is_empty(new_combo));
revert->setEnabled(edit->original != new_combo);
});
QObject::connect(
edit, &OBSHotkeyEdit::KeyChanged,
[=](obs_key_combination_t new_combo) {
clear->setEnabled(
!obs_key_combination_is_empty(new_combo));
revert->setEnabled(edit->original != new_combo);
});
auto add = new QPushButton;
add->setProperty("themeID", "addIconSmall");
@ -303,25 +302,18 @@ void OBSHotkeyWidget::AddEdit(obs_key_combination combo, int idx)
remove->setFixedSize(24, 24);
remove->setFlat(true);
auto CurrentIndex = [&, remove]
{
auto res = std::find(begin(removeButtons),
end(removeButtons),
remove);
auto CurrentIndex = [&, remove] {
auto res = std::find(begin(removeButtons), end(removeButtons),
remove);
return std::distance(begin(removeButtons), res);
};
QObject::connect(add, &QPushButton::clicked,
[&, CurrentIndex]
{
QObject::connect(add, &QPushButton::clicked, [&, CurrentIndex] {
AddEdit({0, OBS_KEY_NONE}, CurrentIndex() + 1);
});
QObject::connect(remove, &QPushButton::clicked,
[&, CurrentIndex]
{
RemoveEdit(CurrentIndex());
});
[&, CurrentIndex] { RemoveEdit(CurrentIndex()); });
QHBoxLayout *subLayout = new QHBoxLayout;
subLayout->setContentsMargins(0, 4, 0, 0);
@ -346,16 +338,13 @@ void OBSHotkeyWidget::AddEdit(obs_key_combination combo, int idx)
layout()->insertLayout(idx, subLayout);
QObject::connect(revert, &QPushButton::clicked,
edit, &OBSHotkeyEdit::ResetKey);
QObject::connect(clear, &QPushButton::clicked,
edit, &OBSHotkeyEdit::ClearKey);
QObject::connect(revert, &QPushButton::clicked, edit,
&OBSHotkeyEdit::ResetKey);
QObject::connect(clear, &QPushButton::clicked, edit,
&OBSHotkeyEdit::ClearKey);
QObject::connect(edit, &OBSHotkeyEdit::KeyChanged,
[&](obs_key_combination)
{
emit KeyChanged();
});
[&](obs_key_combination) { emit KeyChanged(); });
}
void OBSHotkeyWidget::RemoveEdit(size_t idx, bool signal)
@ -384,34 +373,35 @@ void OBSHotkeyWidget::RemoveEdit(size_t idx, bool signal)
void OBSHotkeyWidget::BindingsChanged(void *data, calldata_t *param)
{
auto widget = static_cast<OBSHotkeyWidget*>(data);
auto key = static_cast<obs_hotkey_t*>(calldata_ptr(param, "key"));
auto widget = static_cast<OBSHotkeyWidget *>(data);
auto key = static_cast<obs_hotkey_t *>(calldata_ptr(param, "key"));
QMetaObject::invokeMethod(widget, "HandleChangedBindings",
Q_ARG(obs_hotkey_id, obs_hotkey_get_id(key)));
Q_ARG(obs_hotkey_id, obs_hotkey_get_id(key)));
}
void OBSHotkeyWidget::HandleChangedBindings(obs_hotkey_id id_)
{
if (ignoreChangedBindings || id != id_) return;
if (ignoreChangedBindings || id != id_)
return;
std::vector<obs_key_combination_t> bindings;
auto LoadBindings = [&](obs_hotkey_binding_t *binding)
{
if (obs_hotkey_binding_get_hotkey_id(binding) != id) return;
auto LoadBindings = [&](obs_hotkey_binding_t *binding) {
if (obs_hotkey_binding_get_hotkey_id(binding) != id)
return;
auto get_combo = obs_hotkey_binding_get_key_combination;
bindings.push_back(get_combo(binding));
};
using LoadBindings_t = decltype(&LoadBindings);
obs_enum_hotkey_bindings([](void *data,
size_t, obs_hotkey_binding_t *binding)
{
auto LoadBindings = *static_cast<LoadBindings_t>(data);
LoadBindings(binding);
return true;
}, static_cast<void*>(&LoadBindings));
obs_enum_hotkey_bindings(
[](void *data, size_t, obs_hotkey_binding_t *binding) {
auto LoadBindings = *static_cast<LoadBindings_t>(data);
LoadBindings(binding);
return true;
},
static_cast<void *>(&LoadBindings));
while (edits.size() > 0)
RemoveEdit(edits.size() - 1, false);

View file

@ -45,10 +45,8 @@ class OBSHotkeyEdit : public QLineEdit {
Q_OBJECT;
public:
OBSHotkeyEdit(obs_key_combination_t original,
QWidget *parent=nullptr)
: QLineEdit(parent),
original(original)
OBSHotkeyEdit(obs_key_combination_t original, QWidget *parent = nullptr)
: QLineEdit(parent), original(original)
{
#ifdef __APPLE__
// disable the input cursor on OSX, focus should be clear
@ -63,9 +61,10 @@ public:
obs_key_combination_t original;
obs_key_combination_t key;
bool changed = false;
bool changed = false;
protected:
OBSSignal layoutChanged;
OBSSignal layoutChanged;
void InitSignalHandler();
@ -92,15 +91,14 @@ class OBSHotkeyWidget : public QWidget {
public:
OBSHotkeyWidget(obs_hotkey_id id, std::string name,
const std::vector<obs_key_combination_t> &combos={},
QWidget *parent=nullptr)
const std::vector<obs_key_combination_t> &combos = {},
QWidget *parent = nullptr)
: QWidget(parent),
id(id),
name(name),
bindingsChanged(obs_get_signal_handler(),
"hotkey_bindings_changed",
&OBSHotkeyWidget::BindingsChanged,
this)
&OBSHotkeyWidget::BindingsChanged, this)
{
auto layout = new QVBoxLayout;
layout->setSpacing(0);
@ -110,7 +108,7 @@ public:
SetKeyCombinations(combos);
}
void SetKeyCombinations(const std::vector<obs_key_combination_t>&);
void SetKeyCombinations(const std::vector<obs_key_combination_t> &);
obs_hotkey_id id;
std::string name;
@ -129,7 +127,7 @@ public:
}
void Apply();
void GetCombinations(std::vector<obs_key_combination_t>&) const;
void GetCombinations(std::vector<obs_key_combination_t> &) const;
void Save();
void Save(std::vector<obs_key_combination_t> &combinations);
@ -137,8 +135,8 @@ public:
void leaveEvent(QEvent *event) override;
private:
void AddEdit(obs_key_combination combo, int idx=-1);
void RemoveEdit(size_t idx, bool signal=true);
void AddEdit(obs_key_combination combo, int idx = -1);
void RemoveEdit(size_t idx, bool signal = true);
static void BindingsChanged(void *data, calldata_t *param);
@ -150,7 +148,7 @@ private:
QVBoxLayout *layout() const
{
return dynamic_cast<QVBoxLayout*>(QWidget::layout());
return dynamic_cast<QVBoxLayout *>(QWidget::layout());
}
private slots:

View file

@ -16,7 +16,7 @@ public:
}
explicit inline MenuButton(const QString &text,
QWidget *parent = nullptr)
QWidget *parent = nullptr)
: QPushButton(text, parent)
{
}

View file

@ -1,21 +1,20 @@
#include "obf.h"
#include <stdbool.h>
#define LOWER_HALFBYTE(x) ((x) & 0xF)
#define LOWER_HALFBYTE(x) ((x)&0xF)
#define UPPER_HALFBYTE(x) (((x) >> 4) & 0xF)
void deobfuscate_str(char *str, uint64_t val)
{
uint8_t *dec_val = (uint8_t*)&val;
uint8_t *dec_val = (uint8_t *)&val;
int i = 0;
while (*str != 0) {
int pos = i / 2;
bool bottom = (i % 2) == 0;
uint8_t *ch = (uint8_t*)str;
uint8_t xor = bottom ?
LOWER_HALFBYTE(dec_val[pos]) :
UPPER_HALFBYTE(dec_val[pos]);
uint8_t *ch = (uint8_t *)str;
uint8_t xor = bottom ? LOWER_HALFBYTE(dec_val[pos])
: UPPER_HALFBYTE(dec_val[pos]);
*ch ^= xor;

File diff suppressed because it is too large Load diff

View file

@ -36,48 +36,50 @@
std::string CurrentTimeString();
std::string CurrentDateTimeString();
std::string GenerateTimeDateFilename(const char *extension, bool noSpace=false);
std::string GenerateTimeDateFilename(const char *extension,
bool noSpace = false);
std::string GenerateSpecifiedFilename(const char *extension, bool noSpace,
const char *format);
const char *format);
QObject *CreateShortcutFilter();
struct BaseLexer {
lexer lex;
public:
inline BaseLexer() {lexer_init(&lex);}
inline ~BaseLexer() {lexer_free(&lex);}
operator lexer*() {return &lex;}
inline BaseLexer() { lexer_init(&lex); }
inline ~BaseLexer() { lexer_free(&lex); }
operator lexer *() { return &lex; }
};
class OBSTranslator : public QTranslator {
Q_OBJECT
public:
virtual bool isEmpty() const override {return false;}
virtual bool isEmpty() const override { return false; }
virtual QString translate(const char *context, const char *sourceText,
const char *disambiguation, int n) const override;
const char *disambiguation,
int n) const override;
};
typedef std::function<void ()> VoidFunc;
typedef std::function<void()> VoidFunc;
class OBSApp : public QApplication {
Q_OBJECT
private:
std::string locale;
std::string theme;
ConfigFile globalConfig;
TextLookup textLookup;
OBSContext obsContext;
QPointer<OBSMainWindow> mainWindow;
profiler_name_store_t *profilerNameStore = nullptr;
std::string locale;
std::string theme;
ConfigFile globalConfig;
TextLookup textLookup;
OBSContext obsContext;
QPointer<OBSMainWindow> mainWindow;
profiler_name_store_t *profilerNameStore = nullptr;
os_inhibit_t *sleepInhibitor = nullptr;
int sleepInhibitRefs = 0;
bool enableHotkeysInFocus = true;
os_inhibit_t *sleepInhibitor = nullptr;
int sleepInhibitRefs = 0;
bool enableHotkeysInFocus = true;
std::deque<obs_frontend_translate_ui_cb> translatorHooks;
@ -93,8 +95,8 @@ private:
QPalette defaultPalette;
void ParseExtraThemeData(const char *path);
void AddExtraThemeColor(QPalette &pal, int group,
const char *name, uint32_t color);
void AddExtraThemeColor(QPalette &pal, int group, const char *name,
uint32_t color);
public:
OBSApp(int &argc, char **argv, profiler_name_store_t *store);
@ -105,19 +107,16 @@ public:
void EnableInFocusHotkeys(bool enable);
inline QMainWindow *GetMainWindow() const {return mainWindow.data();}
inline QMainWindow *GetMainWindow() const { return mainWindow.data(); }
inline config_t *GlobalConfig() const {return globalConfig;}
inline config_t *GlobalConfig() const { return globalConfig; }
inline const char *GetLocale() const
{
return locale.c_str();
}
inline const char *GetLocale() const { return locale.c_str(); }
inline const char *GetTheme() const {return theme.c_str();}
inline const char *GetTheme() const { return theme.c_str(); }
bool SetTheme(std::string name, std::string path = "");
inline lookup_t *GetTextLookup() const {return textLookup;}
inline lookup_t *GetTextLookup() const { return textLookup; }
inline const char *GetString(const char *lookupVal) const
{
@ -146,15 +145,18 @@ public:
inline void IncrementSleepInhibition()
{
if (!sleepInhibitor) return;
if (!sleepInhibitor)
return;
if (sleepInhibitRefs++ == 0)
os_inhibit_sleep_set_active(sleepInhibitor, true);
}
inline void DecrementSleepInhibition()
{
if (!sleepInhibitor) return;
if (sleepInhibitRefs == 0) return;
if (!sleepInhibitor)
return;
if (sleepInhibitRefs == 0)
return;
if (--sleepInhibitRefs == 0)
os_inhibit_sleep_set_active(sleepInhibitor, false);
}
@ -164,10 +166,7 @@ public:
translatorHooks.emplace_front(cb);
}
inline void PopUITranslation()
{
translatorHooks.pop_front();
}
inline void PopUITranslation() { translatorHooks.pop_front(); }
public slots:
void Exec(VoidFunc func);
@ -182,12 +181,21 @@ char *GetConfigPathPtr(const char *name);
int GetProgramDataPath(char *path, size_t size, const char *name);
char *GetProgramDataPathPtr(const char *name);
inline OBSApp *App() {return static_cast<OBSApp*>(qApp);}
inline OBSApp *App()
{
return static_cast<OBSApp *>(qApp);
}
inline config_t *GetGlobalConfig() {return App()->GlobalConfig();}
inline config_t *GetGlobalConfig()
{
return App()->GlobalConfig();
}
std::vector<std::pair<std::string, std::string>> GetLocaleNames();
inline const char *Str(const char *lookup) {return App()->GetString(lookup);}
inline const char *Str(const char *lookup)
{
return App()->GetString(lookup);
}
#define QTStr(lookupVal) QString::fromUtf8(Str(lookupVal))
bool GetFileSafeName(const char *name, std::string &file);
@ -197,8 +205,8 @@ bool WindowPositionValid(QRect rect);
static inline int GetProfilePath(char *path, size_t size, const char *file)
{
OBSMainWindow *window = reinterpret_cast<OBSMainWindow*>(
App()->GetMainWindow());
OBSMainWindow *window =
reinterpret_cast<OBSMainWindow *>(App()->GetMainWindow());
return window->GetProfilePath(path, size, file);
}

View file

@ -14,7 +14,7 @@ static inline bool callbacks_valid_(const char *func_name)
{
if (!c) {
blog(LOG_WARNING, "Tried to call %s with no callbacks!",
func_name);
func_name);
return false;
}
@ -26,7 +26,7 @@ static inline bool callbacks_valid_(const char *func_name)
static char **convert_string_list(vector<string> &strings)
{
size_t size = 0;
size_t string_data_offset = (strings.size() + 1) * sizeof(char*);
size_t string_data_offset = (strings.size() + 1) * sizeof(char *);
uint8_t *out;
char **ptr_list;
char *string_data;
@ -39,9 +39,9 @@ static char **convert_string_list(vector<string> &strings)
if (!size)
return 0;
out = (uint8_t*)bmalloc(size);
ptr_list = (char**)out;
string_data = (char*)(out + string_data_offset);
out = (uint8_t *)bmalloc(size);
ptr_list = (char **)out;
string_data = (char *)(out + string_data_offset);
for (auto &str : strings) {
*ptr_list = string_data;
@ -52,30 +52,27 @@ static char **convert_string_list(vector<string> &strings)
}
*ptr_list = nullptr;
return (char**)out;
return (char **)out;
}
/* ------------------------------------------------------------------------- */
void *obs_frontend_get_main_window(void)
{
return !!callbacks_valid()
? c->obs_frontend_get_main_window()
: nullptr;
return !!callbacks_valid() ? c->obs_frontend_get_main_window()
: nullptr;
}
void *obs_frontend_get_main_window_handle(void)
{
return !!callbacks_valid()
? c->obs_frontend_get_main_window_handle()
: nullptr;
return !!callbacks_valid() ? c->obs_frontend_get_main_window_handle()
: nullptr;
}
void *obs_frontend_get_system_tray(void)
{
return !!callbacks_valid()
? c->obs_frontend_get_system_tray()
: nullptr;
return !!callbacks_valid() ? c->obs_frontend_get_system_tray()
: nullptr;
}
char **obs_frontend_get_scene_names(void)
@ -99,31 +96,32 @@ char **obs_frontend_get_scene_names(void)
void obs_frontend_get_scenes(struct obs_frontend_source_list *sources)
{
if (callbacks_valid()) c->obs_frontend_get_scenes(sources);
if (callbacks_valid())
c->obs_frontend_get_scenes(sources);
}
obs_source_t *obs_frontend_get_current_scene(void)
{
return !!callbacks_valid()
? c->obs_frontend_get_current_scene()
: nullptr;
return !!callbacks_valid() ? c->obs_frontend_get_current_scene()
: nullptr;
}
void obs_frontend_set_current_scene(obs_source_t *scene)
{
if (callbacks_valid()) c->obs_frontend_set_current_scene(scene);
if (callbacks_valid())
c->obs_frontend_set_current_scene(scene);
}
void obs_frontend_get_transitions(struct obs_frontend_source_list *sources)
{
if (callbacks_valid()) c->obs_frontend_get_transitions(sources);
if (callbacks_valid())
c->obs_frontend_get_transitions(sources);
}
obs_source_t *obs_frontend_get_current_transition(void)
{
return !!callbacks_valid()
? c->obs_frontend_get_current_transition()
: nullptr;
return !!callbacks_valid() ? c->obs_frontend_get_current_transition()
: nullptr;
}
void obs_frontend_set_current_transition(obs_source_t *transition)
@ -134,9 +132,8 @@ void obs_frontend_set_current_transition(obs_source_t *transition)
int obs_frontend_get_transition_duration(void)
{
return !!callbacks_valid()
? c->obs_frontend_get_transition_duration()
: 0;
return !!callbacks_valid() ? c->obs_frontend_get_transition_duration()
: 0;
}
void obs_frontend_set_transition_duration(int duration)
@ -158,8 +155,8 @@ char **obs_frontend_get_scene_collections(void)
char *obs_frontend_get_current_scene_collection(void)
{
return !!callbacks_valid()
? c->obs_frontend_get_current_scene_collection()
: nullptr;
? c->obs_frontend_get_current_scene_collection()
: nullptr;
}
void obs_frontend_set_current_scene_collection(const char *collection)
@ -170,9 +167,8 @@ void obs_frontend_set_current_scene_collection(const char *collection)
bool obs_frontend_add_scene_collection(const char *name)
{
return callbacks_valid()
? c->obs_frontend_add_scene_collection(name)
: false;
return callbacks_valid() ? c->obs_frontend_add_scene_collection(name)
: false;
}
char **obs_frontend_get_profiles(void)
@ -187,9 +183,8 @@ char **obs_frontend_get_profiles(void)
char *obs_frontend_get_current_profile(void)
{
return !!callbacks_valid()
? c->obs_frontend_get_current_profile()
: nullptr;
return !!callbacks_valid() ? c->obs_frontend_get_current_profile()
: nullptr;
}
void obs_frontend_set_current_profile(const char *profile)
@ -200,91 +195,92 @@ void obs_frontend_set_current_profile(const char *profile)
void obs_frontend_streaming_start(void)
{
if (callbacks_valid()) c->obs_frontend_streaming_start();
if (callbacks_valid())
c->obs_frontend_streaming_start();
}
void obs_frontend_streaming_stop(void)
{
if (callbacks_valid()) c->obs_frontend_streaming_stop();
if (callbacks_valid())
c->obs_frontend_streaming_stop();
}
bool obs_frontend_streaming_active(void)
{
return !!callbacks_valid()
? c->obs_frontend_streaming_active()
: false;
return !!callbacks_valid() ? c->obs_frontend_streaming_active() : false;
}
void obs_frontend_recording_start(void)
{
if (callbacks_valid()) c->obs_frontend_recording_start();
if (callbacks_valid())
c->obs_frontend_recording_start();
}
void obs_frontend_recording_stop(void)
{
if (callbacks_valid()) c->obs_frontend_recording_stop();
if (callbacks_valid())
c->obs_frontend_recording_stop();
}
bool obs_frontend_recording_active(void)
{
return !!callbacks_valid()
? c->obs_frontend_recording_active()
: false;
return !!callbacks_valid() ? c->obs_frontend_recording_active() : false;
}
void obs_frontend_replay_buffer_start(void)
{
if (callbacks_valid()) c->obs_frontend_replay_buffer_start();
if (callbacks_valid())
c->obs_frontend_replay_buffer_start();
}
void obs_frontend_replay_buffer_save(void)
{
if (callbacks_valid()) c->obs_frontend_replay_buffer_save();
if (callbacks_valid())
c->obs_frontend_replay_buffer_save();
}
void obs_frontend_replay_buffer_stop(void)
{
if (callbacks_valid()) c->obs_frontend_replay_buffer_stop();
if (callbacks_valid())
c->obs_frontend_replay_buffer_stop();
}
bool obs_frontend_replay_buffer_active(void)
{
return !!callbacks_valid()
? c->obs_frontend_replay_buffer_active()
: false;
return !!callbacks_valid() ? c->obs_frontend_replay_buffer_active()
: false;
}
void *obs_frontend_add_tools_menu_qaction(const char *name)
{
return !!callbacks_valid()
? c->obs_frontend_add_tools_menu_qaction(name)
: nullptr;
? c->obs_frontend_add_tools_menu_qaction(name)
: nullptr;
}
void obs_frontend_add_tools_menu_item(const char *name,
obs_frontend_cb callback, void *private_data)
obs_frontend_cb callback,
void *private_data)
{
if (callbacks_valid())
c->obs_frontend_add_tools_menu_item(name, callback,
private_data);
private_data);
}
void *obs_frontend_add_dock(void *dock)
{
return !!callbacks_valid()
? c->obs_frontend_add_dock(dock)
: nullptr;
return !!callbacks_valid() ? c->obs_frontend_add_dock(dock) : nullptr;
}
void obs_frontend_add_event_callback(obs_frontend_event_cb callback,
void *private_data)
void *private_data)
{
if (callbacks_valid())
c->obs_frontend_add_event_callback(callback, private_data);
}
void obs_frontend_remove_event_callback(obs_frontend_event_cb callback,
void *private_data)
void *private_data)
{
if (callbacks_valid())
c->obs_frontend_remove_event_callback(callback, private_data);
@ -292,37 +288,32 @@ void obs_frontend_remove_event_callback(obs_frontend_event_cb callback,
obs_output_t *obs_frontend_get_streaming_output(void)
{
return !!callbacks_valid()
? c->obs_frontend_get_streaming_output()
: nullptr;
return !!callbacks_valid() ? c->obs_frontend_get_streaming_output()
: nullptr;
}
obs_output_t *obs_frontend_get_recording_output(void)
{
return !!callbacks_valid()
? c->obs_frontend_get_recording_output()
: nullptr;
return !!callbacks_valid() ? c->obs_frontend_get_recording_output()
: nullptr;
}
obs_output_t *obs_frontend_get_replay_buffer_output(void)
{
return !!callbacks_valid()
? c->obs_frontend_get_replay_buffer_output()
: nullptr;
return !!callbacks_valid() ? c->obs_frontend_get_replay_buffer_output()
: nullptr;
}
config_t *obs_frontend_get_profile_config(void)
{
return !!callbacks_valid()
? c->obs_frontend_get_profile_config()
: nullptr;
return !!callbacks_valid() ? c->obs_frontend_get_profile_config()
: nullptr;
}
config_t *obs_frontend_get_global_config(void)
{
return !!callbacks_valid()
? c->obs_frontend_get_global_config()
: nullptr;
return !!callbacks_valid() ? c->obs_frontend_get_global_config()
: nullptr;
}
void obs_frontend_save(void)
@ -344,28 +335,28 @@ void obs_frontend_defer_save_end(void)
}
void obs_frontend_add_save_callback(obs_frontend_save_cb callback,
void *private_data)
void *private_data)
{
if (callbacks_valid())
c->obs_frontend_add_save_callback(callback, private_data);
}
void obs_frontend_remove_save_callback(obs_frontend_save_cb callback,
void *private_data)
void *private_data)
{
if (callbacks_valid())
c->obs_frontend_remove_save_callback(callback, private_data);
}
void obs_frontend_add_preload_callback(obs_frontend_save_cb callback,
void *private_data)
void *private_data)
{
if (callbacks_valid())
c->obs_frontend_add_preload_callback(callback, private_data);
}
void obs_frontend_remove_preload_callback(obs_frontend_save_cb callback,
void *private_data)
void *private_data)
{
if (callbacks_valid())
c->obs_frontend_remove_preload_callback(callback, private_data);
@ -389,11 +380,10 @@ void obs_frontend_set_streaming_service(obs_service_t *service)
c->obs_frontend_set_streaming_service(service);
}
obs_service_t* obs_frontend_get_streaming_service(void)
obs_service_t *obs_frontend_get_streaming_service(void)
{
return !!callbacks_valid()
? c->obs_frontend_get_streaming_service()
: nullptr;
return !!callbacks_valid() ? c->obs_frontend_get_streaming_service()
: nullptr;
}
void obs_frontend_save_streaming_service(void)
@ -405,8 +395,8 @@ void obs_frontend_save_streaming_service(void)
bool obs_frontend_preview_program_mode_active(void)
{
return !!callbacks_valid()
? c->obs_frontend_preview_program_mode_active()
: false;
? c->obs_frontend_preview_program_mode_active()
: false;
}
void obs_frontend_set_preview_program_mode(bool enable)
@ -429,16 +419,13 @@ void obs_frontend_set_preview_enabled(bool enable)
bool obs_frontend_preview_enabled(void)
{
return !!callbacks_valid()
? c->obs_frontend_preview_enabled()
: false;
return !!callbacks_valid() ? c->obs_frontend_preview_enabled() : false;
}
obs_source_t *obs_frontend_get_current_preview_scene(void)
{
return !!callbacks_valid()
? c->obs_frontend_get_current_preview_scene()
: nullptr;
return !!callbacks_valid() ? c->obs_frontend_get_current_preview_scene()
: nullptr;
}
void obs_frontend_set_current_preview_scene(obs_source_t *scene)

View file

@ -43,7 +43,7 @@ enum obs_frontend_event {
OBS_FRONTEND_EVENT_PREVIEW_SCENE_CHANGED,
OBS_FRONTEND_EVENT_SCENE_COLLECTION_CLEANUP,
OBS_FRONTEND_EVENT_FINISHED_LOADING
OBS_FRONTEND_EVENT_FINISHED_LOADING,
};
/* ------------------------------------------------------------------------- */
@ -51,11 +51,11 @@ enum obs_frontend_event {
#ifndef SWIG
struct obs_frontend_source_list {
DARRAY(obs_source_t*) sources;
DARRAY(obs_source_t *) sources;
};
static inline void obs_frontend_source_list_free(
struct obs_frontend_source_list *source_list)
static inline void
obs_frontend_source_list_free(struct obs_frontend_source_list *source_list)
{
size_t num = source_list->sources.num;
for (size_t i = 0; i < num; i++)
@ -89,8 +89,8 @@ EXPORT void obs_frontend_get_scenes(struct obs_frontend_source_list *sources);
EXPORT obs_source_t *obs_frontend_get_current_scene(void);
EXPORT void obs_frontend_set_current_scene(obs_source_t *scene);
EXPORT void obs_frontend_get_transitions(
struct obs_frontend_source_list *sources);
EXPORT void
obs_frontend_get_transitions(struct obs_frontend_source_list *sources);
EXPORT obs_source_t *obs_frontend_get_current_transition(void);
EXPORT void obs_frontend_set_current_transition(obs_source_t *transition);
EXPORT int obs_frontend_get_transition_duration(void);
@ -109,37 +109,38 @@ typedef void (*obs_frontend_cb)(void *private_data);
EXPORT void *obs_frontend_add_tools_menu_qaction(const char *name);
EXPORT void obs_frontend_add_tools_menu_item(const char *name,
obs_frontend_cb callback, void *private_data);
obs_frontend_cb callback,
void *private_data);
/* takes QDockWidget and returns QAction */
EXPORT void *obs_frontend_add_dock(void *dock);
typedef void (*obs_frontend_event_cb)(enum obs_frontend_event event,
void *private_data);
void *private_data);
EXPORT void obs_frontend_add_event_callback(obs_frontend_event_cb callback,
void *private_data);
void *private_data);
EXPORT void obs_frontend_remove_event_callback(obs_frontend_event_cb callback,
void *private_data);
void *private_data);
typedef void (*obs_frontend_save_cb)(obs_data_t *save_data, bool saving,
void *private_data);
void *private_data);
EXPORT void obs_frontend_add_save_callback(obs_frontend_save_cb callback,
void *private_data);
void *private_data);
EXPORT void obs_frontend_remove_save_callback(obs_frontend_save_cb callback,
void *private_data);
void *private_data);
EXPORT void obs_frontend_add_preload_callback(obs_frontend_save_cb callback,
void *private_data);
void *private_data);
EXPORT void obs_frontend_remove_preload_callback(obs_frontend_save_cb callback,
void *private_data);
void *private_data);
typedef bool (*obs_frontend_translate_ui_cb)(const char *text,
const char **out);
const char **out);
EXPORT void obs_frontend_push_ui_translation(
obs_frontend_translate_ui_cb translate);
EXPORT void
obs_frontend_push_ui_translation(obs_frontend_translate_ui_cb translate);
EXPORT void obs_frontend_pop_ui_translation(void);
#endif //!SWIG
@ -169,7 +170,7 @@ EXPORT config_t *obs_frontend_get_profile_config(void);
EXPORT config_t *obs_frontend_get_global_config(void);
EXPORT void obs_frontend_set_streaming_service(obs_service_t *service);
EXPORT obs_service_t* obs_frontend_get_streaming_service(void);
EXPORT obs_service_t *obs_frontend_get_streaming_service(void);
EXPORT void obs_frontend_save_streaming_service(void);
EXPORT bool obs_frontend_preview_program_mode_active(void);

View file

@ -7,103 +7,111 @@
struct obs_frontend_callbacks {
virtual ~obs_frontend_callbacks() {}
virtual void *obs_frontend_get_main_window(void)=0;
virtual void *obs_frontend_get_main_window_handle(void)=0;
virtual void *obs_frontend_get_system_tray(void)=0;
virtual void *obs_frontend_get_main_window(void) = 0;
virtual void *obs_frontend_get_main_window_handle(void) = 0;
virtual void *obs_frontend_get_system_tray(void) = 0;
virtual void obs_frontend_get_scenes(
struct obs_frontend_source_list *sources)=0;
virtual obs_source_t *obs_frontend_get_current_scene(void)=0;
virtual void obs_frontend_set_current_scene(obs_source_t *scene)=0;
virtual void
obs_frontend_get_scenes(struct obs_frontend_source_list *sources) = 0;
virtual obs_source_t *obs_frontend_get_current_scene(void) = 0;
virtual void obs_frontend_set_current_scene(obs_source_t *scene) = 0;
virtual void obs_frontend_get_transitions(
struct obs_frontend_source_list *sources)=0;
virtual obs_source_t *obs_frontend_get_current_transition(void)=0;
virtual void obs_frontend_set_current_transition(
obs_source_t *transition)=0;
virtual int obs_frontend_get_transition_duration(void)=0;
virtual void obs_frontend_set_transition_duration(int duration)=0;
struct obs_frontend_source_list *sources) = 0;
virtual obs_source_t *obs_frontend_get_current_transition(void) = 0;
virtual void
obs_frontend_set_current_transition(obs_source_t *transition) = 0;
virtual int obs_frontend_get_transition_duration(void) = 0;
virtual void obs_frontend_set_transition_duration(int duration) = 0;
virtual void obs_frontend_get_scene_collections(
std::vector<std::string> &strings)=0;
virtual char *obs_frontend_get_current_scene_collection(void)=0;
virtual void obs_frontend_set_current_scene_collection(
const char *collection)=0;
virtual bool obs_frontend_add_scene_collection(const char *name)=0;
std::vector<std::string> &strings) = 0;
virtual char *obs_frontend_get_current_scene_collection(void) = 0;
virtual void
obs_frontend_set_current_scene_collection(const char *collection) = 0;
virtual bool obs_frontend_add_scene_collection(const char *name) = 0;
virtual void obs_frontend_get_profiles(
std::vector<std::string> &strings)=0;
virtual char *obs_frontend_get_current_profile(void)=0;
virtual void obs_frontend_set_current_profile(const char *profile)=0;
virtual void
obs_frontend_get_profiles(std::vector<std::string> &strings) = 0;
virtual char *obs_frontend_get_current_profile(void) = 0;
virtual void obs_frontend_set_current_profile(const char *profile) = 0;
virtual void obs_frontend_streaming_start(void)=0;
virtual void obs_frontend_streaming_stop(void)=0;
virtual bool obs_frontend_streaming_active(void)=0;
virtual void obs_frontend_streaming_start(void) = 0;
virtual void obs_frontend_streaming_stop(void) = 0;
virtual bool obs_frontend_streaming_active(void) = 0;
virtual void obs_frontend_recording_start(void)=0;
virtual void obs_frontend_recording_stop(void)=0;
virtual bool obs_frontend_recording_active(void)=0;
virtual void obs_frontend_recording_start(void) = 0;
virtual void obs_frontend_recording_stop(void) = 0;
virtual bool obs_frontend_recording_active(void) = 0;
virtual void obs_frontend_replay_buffer_start(void)=0;
virtual void obs_frontend_replay_buffer_start(void) = 0;
virtual void obs_frontend_replay_buffer_save(void) = 0;
virtual void obs_frontend_replay_buffer_stop(void)=0;
virtual bool obs_frontend_replay_buffer_active(void)=0;
virtual void obs_frontend_replay_buffer_stop(void) = 0;
virtual bool obs_frontend_replay_buffer_active(void) = 0;
virtual void *obs_frontend_add_tools_menu_qaction(const char *name)=0;
virtual void *obs_frontend_add_tools_menu_qaction(const char *name) = 0;
virtual void obs_frontend_add_tools_menu_item(const char *name,
obs_frontend_cb callback, void *private_data)=0;
obs_frontend_cb callback,
void *private_data) = 0;
virtual void *obs_frontend_add_dock(void *dock)=0;
virtual void *obs_frontend_add_dock(void *dock) = 0;
virtual void obs_frontend_add_event_callback(
obs_frontend_event_cb callback, void *private_data)=0;
virtual void obs_frontend_remove_event_callback(
obs_frontend_event_cb callback, void *private_data)=0;
virtual void
obs_frontend_add_event_callback(obs_frontend_event_cb callback,
void *private_data) = 0;
virtual void
obs_frontend_remove_event_callback(obs_frontend_event_cb callback,
void *private_data) = 0;
virtual obs_output_t *obs_frontend_get_streaming_output(void)=0;
virtual obs_output_t *obs_frontend_get_recording_output(void)=0;
virtual obs_output_t *obs_frontend_get_replay_buffer_output(void)=0;
virtual obs_output_t *obs_frontend_get_streaming_output(void) = 0;
virtual obs_output_t *obs_frontend_get_recording_output(void) = 0;
virtual obs_output_t *obs_frontend_get_replay_buffer_output(void) = 0;
virtual config_t *obs_frontend_get_profile_config(void)=0;
virtual config_t *obs_frontend_get_global_config(void)=0;
virtual config_t *obs_frontend_get_profile_config(void) = 0;
virtual config_t *obs_frontend_get_global_config(void) = 0;
virtual void obs_frontend_save(void) = 0;
virtual void obs_frontend_defer_save_begin(void) = 0;
virtual void obs_frontend_defer_save_end(void) = 0;
virtual void obs_frontend_add_save_callback(
obs_frontend_save_cb callback, void *private_data)=0;
virtual void obs_frontend_remove_save_callback(
obs_frontend_save_cb callback, void *private_data)=0;
virtual void
obs_frontend_add_save_callback(obs_frontend_save_cb callback,
void *private_data) = 0;
virtual void
obs_frontend_remove_save_callback(obs_frontend_save_cb callback,
void *private_data) = 0;
virtual void obs_frontend_add_preload_callback(
obs_frontend_save_cb callback, void *private_data)=0;
virtual void obs_frontend_remove_preload_callback(
obs_frontend_save_cb callback, void *private_data)=0;
virtual void
obs_frontend_add_preload_callback(obs_frontend_save_cb callback,
void *private_data) = 0;
virtual void
obs_frontend_remove_preload_callback(obs_frontend_save_cb callback,
void *private_data) = 0;
virtual void obs_frontend_push_ui_translation(
obs_frontend_translate_ui_cb translate)=0;
virtual void obs_frontend_pop_ui_translation(void)=0;
obs_frontend_translate_ui_cb translate) = 0;
virtual void obs_frontend_pop_ui_translation(void) = 0;
virtual void obs_frontend_set_streaming_service(
obs_service_t *service)=0;
virtual obs_service_t *obs_frontend_get_streaming_service(void)=0;
virtual void obs_frontend_save_streaming_service()=0;
virtual void
obs_frontend_set_streaming_service(obs_service_t *service) = 0;
virtual obs_service_t *obs_frontend_get_streaming_service(void) = 0;
virtual void obs_frontend_save_streaming_service() = 0;
virtual bool obs_frontend_preview_program_mode_active(void)=0;
virtual void obs_frontend_set_preview_program_mode(bool enable)=0;
virtual void obs_frontend_preview_program_trigger_transition(void)=0;
virtual bool obs_frontend_preview_program_mode_active(void) = 0;
virtual void obs_frontend_set_preview_program_mode(bool enable) = 0;
virtual void obs_frontend_preview_program_trigger_transition(void) = 0;
virtual bool obs_frontend_preview_enabled(void)=0;
virtual void obs_frontend_set_preview_enabled(bool enable)=0;
virtual bool obs_frontend_preview_enabled(void) = 0;
virtual void obs_frontend_set_preview_enabled(bool enable) = 0;
virtual obs_source_t *obs_frontend_get_current_preview_scene(void)=0;
virtual void obs_frontend_set_current_preview_scene(obs_source_t *scene)=0;
virtual obs_source_t *obs_frontend_get_current_preview_scene(void) = 0;
virtual void
obs_frontend_set_current_preview_scene(obs_source_t *scene) = 0;
virtual void on_load(obs_data_t *settings)=0;
virtual void on_preload(obs_data_t *settings)=0;
virtual void on_save(obs_data_t *settings)=0;
virtual void on_event(enum obs_frontend_event event)=0;
virtual void on_load(obs_data_t *settings) = 0;
virtual void on_preload(obs_data_t *settings) = 0;
virtual void on_save(obs_data_t *settings) = 0;
virtual void on_event(enum obs_frontend_event event) = 0;
};
EXPORT void obs_frontend_set_callbacks_internal(
obs_frontend_callbacks *callbacks);
EXPORT void
obs_frontend_set_callbacks_internal(obs_frontend_callbacks *callbacks);

View file

@ -37,8 +37,8 @@ using namespace std;
#include <util/windows/HRError.hpp>
#include <util/windows/ComPtr.hpp>
static inline bool check_path(const char* data, const char *path,
string &output)
static inline bool check_path(const char *data, const char *path,
string &output)
{
ostringstream str;
str << path << data;
@ -65,10 +65,10 @@ bool InitApplicationBundle()
string GetDefaultVideoSavePath()
{
wchar_t path_utf16[MAX_PATH];
char path_utf8[MAX_PATH] = {};
char path_utf8[MAX_PATH] = {};
SHGetFolderPathW(NULL, CSIDL_MYVIDEO, NULL, SHGFP_TYPE_CURRENT,
path_utf16);
path_utf16);
os_wcs_to_utf8(path_utf16, wcslen(path_utf16), path_utf8, MAX_PATH);
return string(path_utf8);
@ -79,18 +79,18 @@ static vector<string> GetUserPreferredLocales()
vector<string> result;
ULONG num, length = 0;
if (!GetUserPreferredUILanguages(MUI_LANGUAGE_NAME, &num,
nullptr, &length))
if (!GetUserPreferredUILanguages(MUI_LANGUAGE_NAME, &num, nullptr,
&length))
return result;
vector<wchar_t> buffer(length);
if (!GetUserPreferredUILanguages(MUI_LANGUAGE_NAME, &num,
&buffer.front(), &length))
&buffer.front(), &length))
return result;
result.reserve(num);
auto start = begin(buffer);
auto end_ = end(buffer);
auto end_ = end(buffer);
decltype(start) separator;
while ((separator = find(start, end_, 0)) != end_) {
if (result.size() == num)
@ -162,7 +162,7 @@ uint32_t GetWindowsVersion()
void SetAeroEnabled(bool enable)
{
static HRESULT (WINAPI *func)(UINT) = nullptr;
static HRESULT(WINAPI * func)(UINT) = nullptr;
static bool failed = false;
if (!func) {
@ -176,8 +176,8 @@ void SetAeroEnabled(bool enable)
return;
}
func = reinterpret_cast<decltype(func)>(GetProcAddress(dwm,
"DwmEnableComposition"));
func = reinterpret_cast<decltype(func)>(
GetProcAddress(dwm, "DwmEnableComposition"));
if (!func) {
failed = true;
return;
@ -197,7 +197,7 @@ void SetAlwaysOnTop(QWidget *window, bool enable)
{
HWND hwnd = (HWND)window->winId();
SetWindowPos(hwnd, enable ? HWND_TOPMOST : HWND_NOTOPMOST, 0, 0, 0, 0,
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
}
void SetProcessPriority(const char *priority)
@ -208,11 +208,13 @@ void SetProcessPriority(const char *priority)
if (strcmp(priority, "High") == 0)
SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS);
else if (strcmp(priority, "AboveNormal") == 0)
SetPriorityClass(GetCurrentProcess(), ABOVE_NORMAL_PRIORITY_CLASS);
SetPriorityClass(GetCurrentProcess(),
ABOVE_NORMAL_PRIORITY_CLASS);
else if (strcmp(priority, "Normal") == 0)
SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS);
else if (strcmp(priority, "BelowNormal") == 0)
SetPriorityClass(GetCurrentProcess(), BELOW_NORMAL_PRIORITY_CLASS);
SetPriorityClass(GetCurrentProcess(),
BELOW_NORMAL_PRIORITY_CLASS);
else if (strcmp(priority, "Idle") == 0)
SetPriorityClass(GetCurrentProcess(), IDLE_PRIORITY_CLASS);
}
@ -227,16 +229,16 @@ void SetWin32DropStyle(QWidget *window)
bool DisableAudioDucking(bool disable)
{
ComPtr<IMMDeviceEnumerator> devEmum;
ComPtr<IMMDevice> device;
ComPtr<IMMDeviceEnumerator> devEmum;
ComPtr<IMMDevice> device;
ComPtr<IAudioSessionManager2> sessionManager2;
ComPtr<IAudioSessionControl> sessionControl;
ComPtr<IAudioSessionControl> sessionControl;
ComPtr<IAudioSessionControl2> sessionControl2;
HRESULT result = CoCreateInstance(__uuidof(MMDeviceEnumerator),
nullptr, CLSCTX_INPROC_SERVER,
__uuidof(IMMDeviceEnumerator),
(void **)&devEmum);
HRESULT result = CoCreateInstance(__uuidof(MMDeviceEnumerator), nullptr,
CLSCTX_INPROC_SERVER,
__uuidof(IMMDeviceEnumerator),
(void **)&devEmum);
if (FAILED(result))
return false;
@ -245,13 +247,13 @@ bool DisableAudioDucking(bool disable)
return false;
result = device->Activate(__uuidof(IAudioSessionManager2),
CLSCTX_INPROC_SERVER, nullptr,
(void **)&sessionManager2);
CLSCTX_INPROC_SERVER, nullptr,
(void **)&sessionManager2);
if (FAILED(result))
return false;
result = sessionManager2->GetAudioSessionControl(nullptr, 0,
&sessionControl);
&sessionControl);
if (FAILED(result))
return false;

View file

@ -29,8 +29,8 @@
#include "platform.hpp"
using namespace std;
static inline bool check_path(const char* data, const char *path,
string &output)
static inline bool check_path(const char *data, const char *path,
string &output)
{
ostringstream str;
str << path << data;

View file

@ -48,6 +48,7 @@ struct RunOnceMutexData;
class RunOnceMutex {
RunOnceMutexData *data = nullptr;
public:
RunOnceMutex(RunOnceMutexData *data_) : data(data_) {}
RunOnceMutex(const RunOnceMutex &rom) = delete;

File diff suppressed because it is too large Load diff

View file

@ -10,8 +10,7 @@ class OBSPropertiesView;
class QLabel;
typedef obs_properties_t *(*PropertiesReloadCallback)(void *obj);
typedef void (*PropertiesUpdateCallback)(void *obj,
obs_data_t *settings);
typedef void (*PropertiesUpdateCallback)(void *obj, obs_data_t *settings);
/* ------------------------------------------------------------------------- */
@ -22,8 +21,8 @@ class WidgetInfo : public QObject {
private:
OBSPropertiesView *view;
obs_property_t *property;
QWidget *widget;
obs_property_t *property;
QWidget *widget;
void BoolChanged(const char *setting);
void IntChanged(const char *setting);
@ -41,9 +40,10 @@ private:
public:
inline WidgetInfo(OBSPropertiesView *view_, obs_property_t *prop,
QWidget *widget_)
QWidget *widget_)
: view(view_), property(prop), widget(widget_)
{}
{
}
public slots:
@ -72,37 +72,38 @@ class OBSPropertiesView : public VScrollArea {
std::unique_ptr<obs_properties_t, properties_delete_t>;
private:
QWidget *widget = nullptr;
properties_t properties;
OBSData settings;
void *obj = nullptr;
std::string type;
PropertiesReloadCallback reloadCallback;
PropertiesUpdateCallback callback = nullptr;
int minSize;
QWidget *widget = nullptr;
properties_t properties;
OBSData settings;
void *obj = nullptr;
std::string type;
PropertiesReloadCallback reloadCallback;
PropertiesUpdateCallback callback = nullptr;
int minSize;
std::vector<std::unique_ptr<WidgetInfo>> children;
std::string lastFocused;
QWidget *lastWidget = nullptr;
bool deferUpdate;
std::string lastFocused;
QWidget *lastWidget = nullptr;
bool deferUpdate;
QWidget *NewWidget(obs_property_t *prop, QWidget *widget,
const char *signal);
const char *signal);
QWidget *AddCheckbox(obs_property_t *prop);
QWidget *AddText(obs_property_t *prop, QFormLayout *layout,
QLabel *&label);
QLabel *&label);
void AddPath(obs_property_t *prop, QFormLayout *layout, QLabel **label);
void AddInt(obs_property_t *prop, QFormLayout *layout, QLabel **label);
void AddFloat(obs_property_t *prop, QFormLayout *layout,
QLabel**label);
QLabel **label);
QWidget *AddList(obs_property_t *prop, bool &warning);
void AddEditableList(obs_property_t *prop, QFormLayout *layout,
QLabel *&label);
QLabel *&label);
QWidget *AddButton(obs_property_t *prop);
void AddColor(obs_property_t *prop, QFormLayout *layout, QLabel *&label);
void AddColor(obs_property_t *prop, QFormLayout *layout,
QLabel *&label);
void AddFont(obs_property_t *prop, QFormLayout *layout, QLabel *&label);
void AddFrameRate(obs_property_t *prop, bool &warning,
QFormLayout *layout, QLabel *&label);
QFormLayout *layout, QLabel *&label);
void AddGroup(obs_property_t *prop, QFormLayout *layout);
@ -125,15 +126,14 @@ signals:
public:
OBSPropertiesView(OBSData settings, void *obj,
PropertiesReloadCallback reloadCallback,
PropertiesUpdateCallback callback,
int minSize = 0);
PropertiesReloadCallback reloadCallback,
PropertiesUpdateCallback callback, int minSize = 0);
OBSPropertiesView(OBSData settings, const char *type,
PropertiesReloadCallback reloadCallback,
int minSize = 0);
PropertiesReloadCallback reloadCallback,
int minSize = 0);
inline obs_data_t *GetSettings() const {return settings;}
inline obs_data_t *GetSettings() const { return settings; }
inline void UpdateSettings() {callback(obj, settings);}
inline bool DeferUpdate() const {return deferUpdate;}
inline void UpdateSettings() { callback(obj, settings); }
inline bool DeferUpdate() const { return deferUpdate; }
};

View file

@ -15,13 +15,13 @@
#endif
static bool operator!=(const media_frames_per_second &a,
const media_frames_per_second &b)
const media_frames_per_second &b)
{
return a.numerator != b.numerator || a.denominator != b.denominator;
}
static bool operator==(const media_frames_per_second &a,
const media_frames_per_second &b)
const media_frames_per_second &b)
{
return !(a != b);
}
@ -36,27 +36,27 @@ class OBSFrameRatePropertyWidget : public QWidget {
public:
frame_rate_ranges_t fps_ranges;
QComboBox *modeSelect = nullptr;
QStackedWidget *modeDisplay = nullptr;
QComboBox *modeSelect = nullptr;
QStackedWidget *modeDisplay = nullptr;
QWidget *labels = nullptr;
QLabel *currentFPS = nullptr;
QLabel *timePerFrame = nullptr;
QLabel *minLabel = nullptr;
QLabel *maxLabel = nullptr;
QWidget *labels = nullptr;
QLabel *currentFPS = nullptr;
QLabel *timePerFrame = nullptr;
QLabel *minLabel = nullptr;
QLabel *maxLabel = nullptr;
QComboBox *simpleFPS = nullptr;
QComboBox *simpleFPS = nullptr;
QComboBox *fpsRange = nullptr;
QSpinBox *numEdit = nullptr;
QSpinBox *denEdit = nullptr;
QComboBox *fpsRange = nullptr;
QSpinBox *numEdit = nullptr;
QSpinBox *denEdit = nullptr;
bool updating = false;
bool updating = false;
const char *name = nullptr;
obs_data_t *settings = nullptr;
const char *name = nullptr;
obs_data_t *settings = nullptr;
QLabel *warningLabel = nullptr;
QLabel *warningLabel = nullptr;
OBSFrameRatePropertyWidget() = default;
};

View file

@ -8,23 +8,18 @@
static inline long long color_to_int(QColor color)
{
auto shift = [&](unsigned val, int shift)
{
auto shift = [&](unsigned val, int shift) {
return ((val & 0xff) << shift);
};
return shift(color.red(), 0) |
shift(color.green(), 8) |
shift(color.blue(), 16) |
shift(color.alpha(), 24);
return shift(color.red(), 0) | shift(color.green(), 8) |
shift(color.blue(), 16) | shift(color.alpha(), 24);
}
static inline QColor rgba_to_color(uint32_t rgba)
{
return QColor::fromRgb(rgba & 0xFF,
(rgba >> 8) & 0xFF,
(rgba >> 16) & 0xFF,
(rgba >> 24) & 0xFF);
return QColor::fromRgb(rgba & 0xFF, (rgba >> 8) & 0xFF,
(rgba >> 16) & 0xFF, (rgba >> 24) & 0xFF);
}
OBSQTDisplay::OBSQTDisplay(QWidget *parent, Qt::WindowFlags flags)
@ -37,8 +32,7 @@ OBSQTDisplay::OBSQTDisplay(QWidget *parent, Qt::WindowFlags flags)
setAttribute(Qt::WA_DontCreateNativeAncestors);
setAttribute(Qt::WA_NativeWindow);
auto windowVisible = [this] (bool visible)
{
auto windowVisible = [this](bool visible) {
if (!visible)
return;
@ -46,12 +40,12 @@ OBSQTDisplay::OBSQTDisplay(QWidget *parent, Qt::WindowFlags flags)
CreateDisplay();
} else {
QSize size = GetPixelSize(this);
obs_display_resize(display, size.width(), size.height());
obs_display_resize(display, size.width(),
size.height());
}
};
auto sizeChanged = [this] (QScreen*)
{
auto sizeChanged = [this](QScreen *) {
CreateDisplay();
QSize size = GetPixelSize(this);
@ -89,11 +83,11 @@ void OBSQTDisplay::CreateDisplay()
QSize size = GetPixelSize(this);
gs_init_data info = {};
info.cx = size.width();
info.cy = size.height();
info.format = GS_RGBA;
info.zsformat = GS_ZS_NONE;
gs_init_data info = {};
info.cx = size.width();
info.cy = size.height();
info.format = GS_RGBA;
info.zsformat = GS_ZS_NONE;
QTToGSWindow(winId(), info.window);

View file

@ -7,9 +7,9 @@
class OBSQTDisplay : public QWidget {
Q_OBJECT
Q_PROPERTY(QColor displayBackgroundColor MEMBER backgroundColor
READ GetDisplayBackgroundColor
WRITE SetDisplayBackgroundColor)
Q_PROPERTY(QColor displayBackgroundColor MEMBER backgroundColor READ
GetDisplayBackgroundColor WRITE
SetDisplayBackgroundColor)
OBSDisplay display;
@ -24,11 +24,11 @@ signals:
public:
OBSQTDisplay(QWidget *parent = nullptr,
Qt::WindowFlags flags = nullptr);
Qt::WindowFlags flags = nullptr);
virtual QPaintEngine *paintEngine() const override;
inline obs_display_t *GetDisplay() const {return display;}
inline obs_display_t *GetDisplay() const { return display; }
uint32_t backgroundColor = GREY_COLOR_BACKGROUND;

View file

@ -45,20 +45,17 @@ void OBSErrorBox(QWidget *parent, const char *msg, ...)
va_end(args);
}
QMessageBox::StandardButton OBSMessageBox::question(
QWidget *parent,
const QString &title,
const QString &text,
QMessageBox::StandardButtons buttons,
QMessageBox::StandardButton defaultButton)
QMessageBox::StandardButton
OBSMessageBox::question(QWidget *parent, const QString &title,
const QString &text,
QMessageBox::StandardButtons buttons,
QMessageBox::StandardButton defaultButton)
{
QMessageBox mb(QMessageBox::Question,
title, text, buttons,
parent);
QMessageBox mb(QMessageBox::Question, title, text, buttons, parent);
mb.setDefaultButton(defaultButton);
if (buttons & QMessageBox::Ok) \
if (buttons & QMessageBox::Ok)
mb.setButtonText(QMessageBox::Ok, QTStr("OK"));
#define translate_button(x) \
#define translate_button(x) \
if (buttons & QMessageBox::x) \
mb.setButtonText(QMessageBox::x, QTStr(#x));
translate_button(Open);
@ -78,41 +75,31 @@ QMessageBox::StandardButton OBSMessageBox::question(
return (QMessageBox::StandardButton)mb.exec();
}
void OBSMessageBox::information(
QWidget *parent,
const QString &title,
const QString &text)
void OBSMessageBox::information(QWidget *parent, const QString &title,
const QString &text)
{
QMessageBox mb(QMessageBox::Information,
title, text, QMessageBox::Ok,
parent);
QMessageBox mb(QMessageBox::Information, title, text, QMessageBox::Ok,
parent);
mb.setButtonText(QMessageBox::Ok, QTStr("OK"));
mb.exec();
}
void OBSMessageBox::warning(
QWidget *parent,
const QString &title,
const QString &text,
bool enableRichText)
void OBSMessageBox::warning(QWidget *parent, const QString &title,
const QString &text, bool enableRichText)
{
QMessageBox mb(QMessageBox::Warning,
title, text, QMessageBox::Ok,
parent);
QMessageBox mb(QMessageBox::Warning, title, text, QMessageBox::Ok,
parent);
if (enableRichText)
mb.setTextFormat(Qt::RichText);
mb.setButtonText(QMessageBox::Ok, QTStr("OK"));
mb.exec();
}
void OBSMessageBox::critical(
QWidget *parent,
const QString &title,
const QString &text)
void OBSMessageBox::critical(QWidget *parent, const QString &title,
const QString &text)
{
QMessageBox mb(QMessageBox::Critical,
title, text, QMessageBox::Ok,
parent);
QMessageBox mb(QMessageBox::Critical, title, text, QMessageBox::Ok,
parent);
mb.setButtonText(QMessageBox::Ok, QTStr("OK"));
mb.exec();
}
@ -156,13 +143,13 @@ uint32_t TranslateQtKeyboardEventModifiers(Qt::KeyboardModifiers mods)
}
QDataStream &operator<<(QDataStream &out,
const std::vector<std::shared_ptr<OBSSignal>> &)
const std::vector<std::shared_ptr<OBSSignal>> &)
{
return out;
}
QDataStream &operator>>(QDataStream &in,
std::vector<std::shared_ptr<OBSSignal>> &)
std::vector<std::shared_ptr<OBSSignal>> &)
{
return in;
}
@ -186,7 +173,7 @@ QDataStream &operator>>(QDataStream &in, OBSScene &scene)
QDataStream &operator<<(QDataStream &out, const OBSSceneItem &si)
{
obs_scene_t *scene = obs_sceneitem_get_scene(si);
obs_scene_t *scene = obs_sceneitem_get_scene(si);
obs_source_t *source = obs_sceneitem_get_source(si);
return out << QString(obs_source_get_name(obs_scene_get_source(scene)))
<< QString(obs_source_get_name(source));
@ -234,15 +221,12 @@ void DeleteLayout(QLayout *layout)
class QuickThread : public QThread {
public:
explicit inline QuickThread(std::function<void()> func_)
: func(func_)
{}
explicit inline QuickThread(std::function<void()> func_) : func(func_)
{
}
private:
virtual void run() override
{
func();
}
virtual void run() override { func(); }
std::function<void()> func;
};
@ -258,11 +242,10 @@ void ExecuteFuncSafeBlock(std::function<void()> func)
{
QEventLoop eventLoop;
auto wait = [&] ()
{
auto wait = [&]() {
func();
QMetaObject::invokeMethod(&eventLoop, "quit",
Qt::QueuedConnection);
Qt::QueuedConnection);
};
os_atomic_inc_long(&insideEventLoop);
@ -273,10 +256,8 @@ void ExecuteFuncSafeBlock(std::function<void()> func)
os_atomic_dec_long(&insideEventLoop);
}
void ExecuteFuncSafeBlockMsgBox(
std::function<void()> func,
const QString &title,
const QString &text)
void ExecuteFuncSafeBlockMsgBox(std::function<void()> func,
const QString &title, const QString &text)
{
QMessageBox dlg;
dlg.setWindowFlags(dlg.windowFlags() & ~Qt::WindowCloseButtonHint);
@ -284,8 +265,7 @@ void ExecuteFuncSafeBlockMsgBox(
dlg.setText(text);
dlg.setStandardButtons(0);
auto wait = [&] ()
{
auto wait = [&]() {
func();
QMetaObject::invokeMethod(&dlg, "accept", Qt::QueuedConnection);
};
@ -305,10 +285,8 @@ void EnableThreadedMessageBoxes(bool enable)
enable_message_boxes = enable;
}
void ExecThreadedWithoutBlocking(
std::function<void()> func,
const QString &title,
const QString &text)
void ExecThreadedWithoutBlocking(std::function<void()> func,
const QString &title, const QString &text)
{
if (!enable_message_boxes)
ExecuteFuncSafeBlock(func);

View file

@ -38,25 +38,19 @@ struct gs_window;
class OBSMessageBox {
public:
static QMessageBox::StandardButton question(
QWidget *parent,
const QString &title,
const QString &text,
QMessageBox::StandardButtons buttons = QMessageBox::StandardButtons( QMessageBox::Yes | QMessageBox::No ),
QMessageBox::StandardButton defaultButton = QMessageBox::NoButton);
static void information(
QWidget *parent,
const QString &title,
const QString &text);
static void warning(
QWidget *parent,
const QString &title,
const QString &text,
bool enableRichText = false);
static void critical(
QWidget *parent,
const QString &title,
const QString &text);
static QMessageBox::StandardButton
question(QWidget *parent, const QString &title, const QString &text,
QMessageBox::StandardButtons buttons =
QMessageBox::StandardButtons(QMessageBox::Yes |
QMessageBox::No),
QMessageBox::StandardButton defaultButton =
QMessageBox::NoButton);
static void information(QWidget *parent, const QString &title,
const QString &text);
static void warning(QWidget *parent, const QString &title,
const QString &text, bool enableRichText = false);
static void critical(QWidget *parent, const QString &title,
const QString &text);
};
void OBSErrorBox(QWidget *parent, const char *msg, ...);
@ -65,10 +59,11 @@ void QTToGSWindow(WId windowId, gs_window &gswindow);
uint32_t TranslateQtKeyboardEventModifiers(Qt::KeyboardModifiers mods);
QDataStream &operator<<(QDataStream &out,
const std::vector<std::shared_ptr<OBSSignal>> &signal_vec);
QDataStream &
operator<<(QDataStream &out,
const std::vector<std::shared_ptr<OBSSignal>> &signal_vec);
QDataStream &operator>>(QDataStream &in,
std::vector<std::shared_ptr<OBSSignal>> &signal_vec);
std::vector<std::shared_ptr<OBSSignal>> &signal_vec);
QDataStream &operator<<(QDataStream &out, const OBSScene &scene);
QDataStream &operator>>(QDataStream &in, OBSScene &scene);
QDataStream &operator<<(QDataStream &out, const OBSSceneItem &si);
@ -77,18 +72,14 @@ QDataStream &operator>>(QDataStream &in, OBSSceneItem &si);
QThread *CreateQThread(std::function<void()> func);
void ExecuteFuncSafeBlock(std::function<void()> func);
void ExecuteFuncSafeBlockMsgBox(
std::function<void()> func,
const QString &title,
const QString &text);
void ExecuteFuncSafeBlockMsgBox(std::function<void()> func,
const QString &title, const QString &text);
/* allows executing without message boxes if starting up, otherwise with a
* message box */
void EnableThreadedMessageBoxes(bool enable);
void ExecThreadedWithoutBlocking(
std::function<void()> func,
const QString &title,
const QString &text);
void ExecThreadedWithoutBlocking(std::function<void()> func,
const QString &title, const QString &text);
class SignalBlocker {
QWidget *widget;
@ -100,10 +91,7 @@ public:
blocked = widget->blockSignals(true);
}
inline ~SignalBlocker()
{
widget->blockSignals(blocked);
}
inline ~SignalBlocker() { widget->blockSignals(blocked); }
};
void DeleteLayout(QLayout *layout);
@ -111,6 +99,6 @@ void DeleteLayout(QLayout *layout);
static inline Qt::ConnectionType WaitConnection()
{
return QThread::currentThread() == qApp->thread()
? Qt::DirectConnection
: Qt::BlockingQueuedConnection;
? Qt::DirectConnection
: Qt::BlockingQueuedConnection;
}

View file

@ -22,7 +22,7 @@
using namespace std;
static auto curl_deleter = [] (CURL *curl) {curl_easy_cleanup(curl);};
static auto curl_deleter = [](CURL *curl) { curl_easy_cleanup(curl); };
using Curl = unique_ptr<CURL, decltype(curl_deleter)>;
static size_t string_write(char *ptr, size_t size, size_t nmemb, string &str)
@ -53,12 +53,11 @@ void RemoteTextThread::run()
struct curl_slist *header = nullptr;
string str;
header = curl_slist_append(header,
versionString.c_str());
header = curl_slist_append(header, versionString.c_str());
if (!contentTypeString.empty()) {
header = curl_slist_append(header,
contentTypeString.c_str());
contentTypeString.c_str());
}
for (std::string &h : extraHeaders)
@ -66,18 +65,15 @@ void RemoteTextThread::run()
curl_easy_setopt(curl.get(), CURLOPT_URL, url.c_str());
curl_easy_setopt(curl.get(), CURLOPT_ACCEPT_ENCODING, "");
curl_easy_setopt(curl.get(), CURLOPT_HTTPHEADER,
header);
curl_easy_setopt(curl.get(), CURLOPT_ERRORBUFFER,
error);
curl_easy_setopt(curl.get(), CURLOPT_HTTPHEADER, header);
curl_easy_setopt(curl.get(), CURLOPT_ERRORBUFFER, error);
curl_easy_setopt(curl.get(), CURLOPT_WRITEFUNCTION,
string_write);
curl_easy_setopt(curl.get(), CURLOPT_WRITEDATA,
&str);
string_write);
curl_easy_setopt(curl.get(), CURLOPT_WRITEDATA, &str);
if (timeoutSec)
curl_easy_setopt(curl.get(), CURLOPT_TIMEOUT,
timeoutSec);
timeoutSec);
#if LIBCURL_VERSION_NUM >= 0x072400
// A lot of servers don't yet support ALPN
@ -86,7 +82,7 @@ void RemoteTextThread::run()
if (!postData.empty()) {
curl_easy_setopt(curl.get(), CURLOPT_POSTFIELDS,
postData.c_str());
postData.c_str());
}
code = curl_easy_perform(curl.get());
@ -101,7 +97,7 @@ void RemoteTextThread::run()
}
static size_t header_write(char *ptr, size_t size, size_t nmemb,
vector<string> &list)
vector<string> &list)
{
string str;
@ -118,16 +114,10 @@ static size_t header_write(char *ptr, size_t size, size_t nmemb,
return total;
}
bool GetRemoteFile(
const char *url,
std::string &str,
std::string &error,
long *responseCode,
const char *contentType,
const char *postData,
std::vector<std::string> extraHeaders,
std::string *signature,
int timeoutSec)
bool GetRemoteFile(const char *url, std::string &str, std::string &error,
long *responseCode, const char *contentType,
const char *postData, std::vector<std::string> extraHeaders,
std::string *signature, int timeoutSec)
{
vector<string> header_in_list;
char error_in[CURL_ERROR_SIZE];
@ -148,12 +138,11 @@ bool GetRemoteFile(
if (curl) {
struct curl_slist *header = nullptr;
header = curl_slist_append(header,
versionString.c_str());
header = curl_slist_append(header, versionString.c_str());
if (!contentTypeString.empty()) {
header = curl_slist_append(header,
contentTypeString.c_str());
contentTypeString.c_str());
}
for (std::string &h : extraHeaders)
@ -161,24 +150,21 @@ bool GetRemoteFile(
curl_easy_setopt(curl.get(), CURLOPT_URL, url);
curl_easy_setopt(curl.get(), CURLOPT_ACCEPT_ENCODING, "");
curl_easy_setopt(curl.get(), CURLOPT_HTTPHEADER,
header);
curl_easy_setopt(curl.get(), CURLOPT_ERRORBUFFER,
error_in);
curl_easy_setopt(curl.get(), CURLOPT_HTTPHEADER, header);
curl_easy_setopt(curl.get(), CURLOPT_ERRORBUFFER, error_in);
curl_easy_setopt(curl.get(), CURLOPT_WRITEFUNCTION,
string_write);
curl_easy_setopt(curl.get(), CURLOPT_WRITEDATA,
&str);
string_write);
curl_easy_setopt(curl.get(), CURLOPT_WRITEDATA, &str);
if (signature) {
curl_easy_setopt(curl.get(), CURLOPT_HEADERFUNCTION,
header_write);
header_write);
curl_easy_setopt(curl.get(), CURLOPT_HEADERDATA,
&header_in_list);
&header_in_list);
}
if (timeoutSec)
curl_easy_setopt(curl.get(), CURLOPT_TIMEOUT,
timeoutSec);
timeoutSec);
#if LIBCURL_VERSION_NUM >= 0x072400
// A lot of servers don't yet support ALPN
@ -187,13 +173,13 @@ bool GetRemoteFile(
if (postData) {
curl_easy_setopt(curl.get(), CURLOPT_POSTFIELDS,
postData);
postData);
}
code = curl_easy_perform(curl.get());
if (responseCode)
curl_easy_getinfo(curl.get(), CURLINFO_RESPONSE_CODE,
responseCode);
responseCode);
if (code != CURLE_OK) {
error = error_in;

View file

@ -38,38 +38,34 @@ signals:
void Result(const QString &text, const QString &error);
public:
inline RemoteTextThread(
std::string url_,
std::string contentType_ = std::string(),
std::string postData_ = std::string(),
int timeoutSec_ = 0)
: url (url_),
contentType (contentType_),
postData (postData_),
timeoutSec (timeoutSec_)
{}
inline RemoteTextThread(std::string url_,
std::string contentType_ = std::string(),
std::string postData_ = std::string(),
int timeoutSec_ = 0)
: url(url_),
contentType(contentType_),
postData(postData_),
timeoutSec(timeoutSec_)
{
}
inline RemoteTextThread(
std::string url_,
std::vector<std::string> &&extraHeaders_,
std::string contentType_ = std::string(),
std::string postData_ = std::string(),
int timeoutSec_ = 0)
: url (url_),
contentType (contentType_),
postData (postData_),
extraHeaders (std::move(extraHeaders_)),
timeoutSec (timeoutSec_)
{}
inline RemoteTextThread(std::string url_,
std::vector<std::string> &&extraHeaders_,
std::string contentType_ = std::string(),
std::string postData_ = std::string(),
int timeoutSec_ = 0)
: url(url_),
contentType(contentType_),
postData(postData_),
extraHeaders(std::move(extraHeaders_)),
timeoutSec(timeoutSec_)
{
}
};
bool GetRemoteFile(
const char *url,
std::string &str,
std::string &error,
long *responseCode = nullptr,
const char *contentType = nullptr,
const char *url, std::string &str, std::string &error,
long *responseCode = nullptr, const char *contentType = nullptr,
const char *postData = nullptr,
std::vector<std::string> extraHeaders = std::vector<std::string>(),
std::string *signature = nullptr,
int timeoutSec = 0);
std::string *signature = nullptr, int timeoutSec = 0);

View file

@ -1,19 +1,20 @@
#include "slider-absoluteset-style.hpp"
SliderAbsoluteSetStyle::SliderAbsoluteSetStyle(const QString& baseStyle)
:QProxyStyle(baseStyle)
SliderAbsoluteSetStyle::SliderAbsoluteSetStyle(const QString &baseStyle)
: QProxyStyle(baseStyle)
{
}
SliderAbsoluteSetStyle::SliderAbsoluteSetStyle(QStyle* baseStyle)
:QProxyStyle(baseStyle)
SliderAbsoluteSetStyle::SliderAbsoluteSetStyle(QStyle *baseStyle)
: QProxyStyle(baseStyle)
{
}
int SliderAbsoluteSetStyle::styleHint(QStyle::StyleHint hint,
const QStyleOption* option = 0, const QWidget* widget = 0,
QStyleHintReturn* returnData = 0) const
const QStyleOption *option = 0,
const QWidget *widget = 0,
QStyleHintReturn *returnData = 0) const
{
if(hint == QStyle::SH_Slider_AbsoluteSetButtons)
if (hint == QStyle::SH_Slider_AbsoluteSetButtons)
return (Qt::LeftButton | Qt::MidButton);
return QProxyStyle::styleHint(hint, option, widget, returnData);
}

View file

@ -2,11 +2,11 @@
#include <QProxyStyle>
class SliderAbsoluteSetStyle : public QProxyStyle
{
class SliderAbsoluteSetStyle : public QProxyStyle {
public:
SliderAbsoluteSetStyle(const QString& baseStyle);
SliderAbsoluteSetStyle(QStyle* baseStyle = Q_NULLPTR);
int styleHint(QStyle::StyleHint hint, const QStyleOption* option,
const QWidget* widget, QStyleHintReturn* returnData) const;
SliderAbsoluteSetStyle(const QString &baseStyle);
SliderAbsoluteSetStyle(QStyle *baseStyle = Q_NULLPTR);
int styleHint(QStyle::StyleHint hint, const QStyleOption *option,
const QWidget *widget,
QStyleHintReturn *returnData) const;
};

View file

@ -6,7 +6,7 @@ SliderIgnoreScroll::SliderIgnoreScroll(QWidget *parent) : QSlider(parent)
}
SliderIgnoreScroll::SliderIgnoreScroll(Qt::Orientation orientation,
QWidget *parent)
QWidget *parent)
: QSlider(parent)
{
setFocusPolicy(Qt::StrongFocus);

View file

@ -9,7 +9,8 @@ class SliderIgnoreScroll : public QSlider {
public:
SliderIgnoreScroll(QWidget *parent = nullptr);
SliderIgnoreScroll(Qt::Orientation orientation, QWidget *parent = nullptr);
SliderIgnoreScroll(Qt::Orientation orientation,
QWidget *parent = nullptr);
protected:
virtual void wheelEvent(QWheelEvent *event) override;

View file

@ -19,7 +19,7 @@
void OBSSourceLabel::SourceRenamed(void *data, calldata_t *params)
{
auto &label = *static_cast<OBSSourceLabel*>(data);
auto &label = *static_cast<OBSSourceLabel *>(data);
const char *name = calldata_string(params, "new_name");
label.setText(name);
@ -29,13 +29,13 @@ void OBSSourceLabel::SourceRenamed(void *data, calldata_t *params)
void OBSSourceLabel::SourceRemoved(void *data, calldata_t *)
{
auto &label = *static_cast<OBSSourceLabel*>(data);
auto &label = *static_cast<OBSSourceLabel *>(data);
emit label.Removed();
}
void OBSSourceLabel::SourceDestroyed(void *data, calldata_t *)
{
auto &label = *static_cast<OBSSourceLabel*>(data);
auto &label = *static_cast<OBSSourceLabel *>(data);
emit label.Destroyed();
label.destroyedSignal.Disconnect();

View file

@ -28,17 +28,18 @@ public:
OBSSignal removedSignal;
OBSSignal destroyedSignal;
OBSSourceLabel(const obs_source_t *source, QWidget *parent=nullptr,
Qt::WindowFlags f=0)
OBSSourceLabel(const obs_source_t *source, QWidget *parent = nullptr,
Qt::WindowFlags f = 0)
: QLabel(obs_source_get_name(source), parent, f),
renamedSignal(obs_source_get_signal_handler(source), "rename",
&OBSSourceLabel::SourceRenamed, this),
&OBSSourceLabel::SourceRenamed, this),
removedSignal(obs_source_get_signal_handler(source), "remove",
&OBSSourceLabel::SourceRemoved, this),
&OBSSourceLabel::SourceRemoved, this),
destroyedSignal(obs_source_get_signal_handler(source),
"destroy", &OBSSourceLabel::SourceDestroyed,
this)
{}
{
}
protected:
static void SourceRenamed(void *data, calldata_t *params);

View file

@ -25,15 +25,14 @@
static inline OBSScene GetCurrentScene()
{
OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
return main->GetCurrentScene();
}
/* ========================================================================= */
SourceTreeItem::SourceTreeItem(SourceTree *tree_, OBSSceneItem sceneitem_)
: tree (tree_),
sceneitem (sceneitem_)
: tree(tree_), sceneitem(sceneitem_)
{
setAttribute(Qt::WA_TranslucentBackground);
setMouseTracking(true);
@ -98,14 +97,12 @@ SourceTreeItem::SourceTreeItem(SourceTree *tree_, OBSSceneItem sceneitem_)
/* --------------------------------------------------------- */
auto setItemVisible = [this] (bool checked)
{
auto setItemVisible = [this](bool checked) {
SignalBlocker sourcesSignalBlocker(this);
obs_sceneitem_set_visible(sceneitem, checked);
};
auto setItemLocked = [this] (bool checked)
{
auto setItemLocked = [this](bool checked) {
SignalBlocker sourcesSignalBlocker(this);
obs_sceneitem_set_locked(sceneitem, checked);
};
@ -150,59 +147,58 @@ void SourceTreeItem::ReconnectSignals()
/* --------------------------------------------------------- */
auto removeItem = [] (void *data, calldata_t *cd)
{
SourceTreeItem *this_ = reinterpret_cast<SourceTreeItem*>(data);
auto removeItem = [](void *data, calldata_t *cd) {
SourceTreeItem *this_ =
reinterpret_cast<SourceTreeItem *>(data);
obs_sceneitem_t *curItem =
(obs_sceneitem_t*)calldata_ptr(cd, "item");
(obs_sceneitem_t *)calldata_ptr(cd, "item");
if (curItem == this_->sceneitem) {
QMetaObject::invokeMethod(this_->tree,
"Remove",
Q_ARG(OBSSceneItem, curItem));
QMetaObject::invokeMethod(this_->tree, "Remove",
Q_ARG(OBSSceneItem, curItem));
curItem = nullptr;
}
if (!curItem)
QMetaObject::invokeMethod(this_, "Clear");
};
auto itemVisible = [] (void *data, calldata_t *cd)
{
SourceTreeItem *this_ = reinterpret_cast<SourceTreeItem*>(data);
auto itemVisible = [](void *data, calldata_t *cd) {
SourceTreeItem *this_ =
reinterpret_cast<SourceTreeItem *>(data);
obs_sceneitem_t *curItem =
(obs_sceneitem_t*)calldata_ptr(cd, "item");
(obs_sceneitem_t *)calldata_ptr(cd, "item");
bool visible = calldata_bool(cd, "visible");
if (curItem == this_->sceneitem)
QMetaObject::invokeMethod(this_, "VisibilityChanged",
Q_ARG(bool, visible));
Q_ARG(bool, visible));
};
auto itemLocked = [] (void *data, calldata_t *cd)
{
SourceTreeItem *this_ = reinterpret_cast<SourceTreeItem*>(data);
auto itemLocked = [](void *data, calldata_t *cd) {
SourceTreeItem *this_ =
reinterpret_cast<SourceTreeItem *>(data);
obs_sceneitem_t *curItem =
(obs_sceneitem_t*)calldata_ptr(cd, "item");
(obs_sceneitem_t *)calldata_ptr(cd, "item");
bool locked = calldata_bool(cd, "locked");
if (curItem == this_->sceneitem)
QMetaObject::invokeMethod(this_, "LockedChanged",
Q_ARG(bool, locked));
Q_ARG(bool, locked));
};
auto itemDeselect = [] (void *data, calldata_t *cd)
{
SourceTreeItem *this_ = reinterpret_cast<SourceTreeItem*>(data);
auto itemDeselect = [](void *data, calldata_t *cd) {
SourceTreeItem *this_ =
reinterpret_cast<SourceTreeItem *>(data);
obs_sceneitem_t *curItem =
(obs_sceneitem_t*)calldata_ptr(cd, "item");
(obs_sceneitem_t *)calldata_ptr(cd, "item");
if (curItem == this_->sceneitem)
QMetaObject::invokeMethod(this_, "Deselect");
};
auto reorderGroup = [] (void *data, calldata_t*)
{
SourceTreeItem *this_ = reinterpret_cast<SourceTreeItem*>(data);
auto reorderGroup = [](void *data, calldata_t *) {
SourceTreeItem *this_ =
reinterpret_cast<SourceTreeItem *>(data);
QMetaObject::invokeMethod(this_->tree, "ReorderItems");
};
@ -220,27 +216,27 @@ void SourceTreeItem::ReconnectSignals()
signal = obs_source_get_signal_handler(source);
groupReorderSignal.Connect(signal, "reorder", reorderGroup,
this);
this);
}
if (scene != GetCurrentScene())
deselectSignal.Connect(signal, "item_deselect", itemDeselect,
this);
this);
/* --------------------------------------------------------- */
auto renamed = [] (void *data, calldata_t *cd)
{
SourceTreeItem *this_ = reinterpret_cast<SourceTreeItem*>(data);
auto renamed = [](void *data, calldata_t *cd) {
SourceTreeItem *this_ =
reinterpret_cast<SourceTreeItem *>(data);
const char *name = calldata_string(cd, "new_name");
QMetaObject::invokeMethod(this_, "Renamed",
Q_ARG(QString, QT_UTF8(name)));
Q_ARG(QString, QT_UTF8(name)));
};
auto removeSource = [] (void *data, calldata_t *)
{
SourceTreeItem *this_ = reinterpret_cast<SourceTreeItem*>(data);
auto removeSource = [](void *data, calldata_t *) {
SourceTreeItem *this_ =
reinterpret_cast<SourceTreeItem *>(data);
this_->DisconnectSignals();
this_->sceneitem = nullptr;
};
@ -260,7 +256,7 @@ void SourceTreeItem::mouseDoubleClickEvent(QMouseEvent *event)
} else {
obs_source_t *source = obs_sceneitem_get_source(sceneitem);
OBSBasic *main =
reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
if (source) {
main->CreatePropertiesWindow(source);
}
@ -289,7 +285,7 @@ void SourceTreeItem::ExitEditMode(bool save)
if (!editor)
return;
OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
OBSScene scene = main->GetCurrentScene();
std::string newName = QT_TO_UTF8(editor->text());
@ -308,9 +304,8 @@ void SourceTreeItem::ExitEditMode(bool save)
return;
if (newName.empty()) {
OBSMessageBox::information(main,
QTStr("NoNameEntered.Title"),
QTStr("NoNameEntered.Text"));
OBSMessageBox::information(main, QTStr("NoNameEntered.Title"),
QTStr("NoNameEntered.Text"));
return;
}
@ -324,15 +319,13 @@ void SourceTreeItem::ExitEditMode(bool save)
/* ----------------------------------------- */
/* check for existing source */
obs_source_t *existingSource =
obs_get_source_by_name(newName.c_str());
obs_source_t *existingSource = obs_get_source_by_name(newName.c_str());
obs_source_release(existingSource);
bool exists = !!existingSource;
if (exists) {
OBSMessageBox::information(main,
QTStr("NameExists.Title"),
QTStr("NameExists.Text"));
OBSMessageBox::information(main, QTStr("NameExists.Title"),
QTStr("NameExists.Text"));
return;
}
@ -355,22 +348,22 @@ bool SourceTreeItem::eventFilter(QObject *object, QEvent *event)
switch (keyEvent->key()) {
case Qt::Key_Escape:
QMetaObject::invokeMethod(this, "ExitEditMode",
Qt::QueuedConnection,
Q_ARG(bool, false));
Qt::QueuedConnection,
Q_ARG(bool, false));
return true;
case Qt::Key_Tab:
case Qt::Key_Backtab:
case Qt::Key_Enter:
case Qt::Key_Return:
QMetaObject::invokeMethod(this, "ExitEditMode",
Qt::QueuedConnection,
Q_ARG(bool, true));
Qt::QueuedConnection,
Q_ARG(bool, true));
return true;
}
} else if (event->type() == QEvent::FocusOut) {
QMetaObject::invokeMethod(this, "ExitEditMode",
Qt::QueuedConnection,
Q_ARG(bool, true));
Qt::QueuedConnection,
Q_ARG(bool, true));
return true;
}
@ -405,14 +398,14 @@ void SourceTreeItem::Update(bool force)
if (obs_sceneitem_is_group(sceneitem)) {
newType = Type::Group;
/* ------------------------------------------------- */
/* if it's a group sub-item */
/* ------------------------------------------------- */
/* if it's a group sub-item */
} else if (itemScene != scene) {
newType = Type::SubItem;
/* ------------------------------------------------- */
/* if it's a regular item */
/* ------------------------------------------------- */
/* if it's a regular item */
} else {
newType = Type::Item;
@ -448,9 +441,8 @@ void SourceTreeItem::Update(bool force)
} else if (type == Type::Group) {
expand = new SourceTreeSubItemCheckBox();
expand->setSizePolicy(
QSizePolicy::Maximum,
QSizePolicy::Maximum);
expand->setSizePolicy(QSizePolicy::Maximum,
QSizePolicy::Maximum);
expand->setMaximumSize(10, 16);
expand->setMinimumSize(10, 0);
#ifdef __APPLE__
@ -458,14 +450,15 @@ void SourceTreeItem::Update(bool force)
#endif
boxLayout->insertWidget(0, expand);
obs_data_t *data = obs_sceneitem_get_private_settings(sceneitem);
obs_data_t *data =
obs_sceneitem_get_private_settings(sceneitem);
expand->blockSignals(true);
expand->setChecked(obs_data_get_bool(data, "collapsed"));
expand->blockSignals(false);
obs_data_release(data);
connect(expand, &QPushButton::toggled,
this, &SourceTreeItem::ExpandClicked);
connect(expand, &QPushButton::toggled, this,
&SourceTreeItem::ExpandClicked);
} else {
spacer = new QSpacerItem(3, 1);
@ -517,10 +510,10 @@ void SourceTreeModel::Clear()
hasGroups = false;
}
static bool enumItem(obs_scene_t*, obs_sceneitem_t *item, void *ptr)
static bool enumItem(obs_scene_t *, obs_sceneitem_t *item, void *ptr)
{
QVector<OBSSceneItem> &items =
*reinterpret_cast<QVector<OBSSceneItem>*>(ptr);
*reinterpret_cast<QVector<OBSSceneItem> *>(ptr);
if (obs_sceneitem_is_group(item)) {
obs_data_t *data = obs_sceneitem_get_private_settings(item);
@ -556,14 +549,15 @@ void SourceTreeModel::SceneChanged()
bool select = obs_sceneitem_selected(items[i]);
QModelIndex index = createIndex(i, 0);
st->selectionModel()->select(index, select
? QItemSelectionModel::Select
: QItemSelectionModel::Deselect);
st->selectionModel()->select(
index, select ? QItemSelectionModel::Select
: QItemSelectionModel::Deselect);
}
}
/* moves a scene item index (blame linux distros for using older Qt builds) */
static inline void MoveItem(QVector<OBSSceneItem> &items, int oldIdx, int newIdx)
static inline void MoveItem(QVector<OBSSceneItem> &items, int oldIdx,
int newIdx)
{
OBSSceneItem item = items[oldIdx];
items.remove(oldIdx);
@ -637,7 +631,7 @@ void SourceTreeModel::ReorderItems()
/* move items */
beginMoveRows(QModelIndex(), idx1Old, idx1Old + count - 1,
QModelIndex(), idx1New + count);
QModelIndex(), idx1New + count);
for (i = 0; i < count; i++) {
int to = idx1New + count;
if (to > idx1Old)
@ -709,8 +703,7 @@ OBSSceneItem SourceTreeModel::Get(int idx)
}
SourceTreeModel::SourceTreeModel(SourceTree *st_)
: QAbstractListModel (st_),
st (st_)
: QAbstractListModel(st_), st(st_)
{
obs_frontend_add_event_callback(OBSFrontendEvent, this);
}
@ -744,8 +737,7 @@ Qt::ItemFlags SourceTreeModel::flags(const QModelIndex &index) const
obs_sceneitem_t *item = items[index.row()];
bool is_group = obs_sceneitem_is_group(item);
return QAbstractListModel::flags(index) |
Qt::ItemIsEditable |
return QAbstractListModel::flags(index) | Qt::ItemIsEditable |
Qt::ItemIsDragEnabled |
(is_group ? Qt::ItemIsDropEnabled : Qt::NoItemFlags);
}
@ -775,8 +767,8 @@ QString SourceTreeModel::GetNewGroupName()
void SourceTreeModel::AddGroup()
{
QString name = GetNewGroupName();
obs_sceneitem_t *group = obs_scene_add_group(GetCurrentScene(),
QT_TO_UTF8(name));
obs_sceneitem_t *group =
obs_scene_add_group(GetCurrentScene(), QT_TO_UTF8(name));
if (!group)
return;
@ -788,7 +780,7 @@ void SourceTreeModel::AddGroup()
UpdateGroupState(true);
QMetaObject::invokeMethod(st, "Edit", Qt::QueuedConnection,
Q_ARG(int, 0));
Q_ARG(int, 0));
}
void SourceTreeModel::GroupSelectedItems(QModelIndexList &indices)
@ -807,8 +799,7 @@ void SourceTreeModel::GroupSelectedItems(QModelIndexList &indices)
}
obs_sceneitem_t *item = obs_scene_insert_group(
scene, QT_TO_UTF8(name),
item_order.data(), item_order.size());
scene, QT_TO_UTF8(name), item_order.data(), item_order.size());
if (!item) {
return;
}
@ -827,7 +818,7 @@ void SourceTreeModel::GroupSelectedItems(QModelIndexList &indices)
int toIdx = newIdx + i + 1;
if (fromIdx != toIdx) {
beginMoveRows(QModelIndex(), fromIdx, fromIdx,
QModelIndex(), toIdx);
QModelIndex(), toIdx);
MoveItem(items, fromIdx, toIdx);
endMoveRows();
}
@ -839,7 +830,7 @@ void SourceTreeModel::GroupSelectedItems(QModelIndexList &indices)
obs_sceneitem_select(item, true);
QMetaObject::invokeMethod(st, "Edit", Qt::QueuedConnection,
Q_ARG(int, newIdx));
Q_ARG(int, newIdx));
}
void SourceTreeModel::UngroupSelectedGroups(QModelIndexList &indices)
@ -929,20 +920,20 @@ SourceTree::SourceTree(QWidget *parent_) : QListView(parent_)
SourceTreeModel *stm_ = new SourceTreeModel(this);
setModel(stm_);
setStyleSheet(QString(
"*[bgColor=\"1\"]{background-color:rgba(255,68,68,33%);}" \
"*[bgColor=\"2\"]{background-color:rgba(255,255,68,33%);}" \
"*[bgColor=\"3\"]{background-color:rgba(68,255,68,33%);}" \
"*[bgColor=\"4\"]{background-color:rgba(68,255,255,33%);}" \
"*[bgColor=\"5\"]{background-color:rgba(68,68,255,33%);}" \
"*[bgColor=\"6\"]{background-color:rgba(255,68,255,33%);}" \
"*[bgColor=\"7\"]{background-color:rgba(68,68,68,33%);}" \
"*[bgColor=\"1\"]{background-color:rgba(255,68,68,33%);}"
"*[bgColor=\"2\"]{background-color:rgba(255,255,68,33%);}"
"*[bgColor=\"3\"]{background-color:rgba(68,255,68,33%);}"
"*[bgColor=\"4\"]{background-color:rgba(68,255,255,33%);}"
"*[bgColor=\"5\"]{background-color:rgba(68,68,255,33%);}"
"*[bgColor=\"6\"]{background-color:rgba(255,68,255,33%);}"
"*[bgColor=\"7\"]{background-color:rgba(68,68,68,33%);}"
"*[bgColor=\"8\"]{background-color:rgba(255,255,255,33%);}"));
setMouseTracking(true);
UpdateNoSourcesMessage();
connect(App(), &OBSApp::StyleChanged,
this, &SourceTree::UpdateNoSourcesMessage);
connect(App(), &OBSApp::StyleChanged, this,
&SourceTree::UpdateNoSourcesMessage);
}
void SourceTree::ResetWidgets()
@ -994,9 +985,9 @@ void SourceTree::SelectItem(obs_sceneitem_t *sceneitem, bool select)
QModelIndex index = stm->createIndex(i, 0);
if (index.isValid())
selectionModel()->select(index, select
? QItemSelectionModel::Select
: QItemSelectionModel::Deselect);
selectionModel()->select(
index, select ? QItemSelectionModel::Select
: QItemSelectionModel::Deselect);
}
Q_DECLARE_METATYPE(OBSSceneItem);
@ -1040,9 +1031,9 @@ void SourceTree::dropEvent(QDropEvent *event)
obs_sceneitem_t *dropItem = items[row]; /* item being dropped on */
bool itemIsGroup = obs_sceneitem_is_group(dropItem);
obs_sceneitem_t *dropGroup = itemIsGroup
? dropItem
: obs_sceneitem_get_group(scene, dropItem);
obs_sceneitem_t *dropGroup =
itemIsGroup ? dropItem
: obs_sceneitem_get_group(scene, dropItem);
/* not a group if moving above the group */
if (indicator == QAbstractItemView::AboveItem && itemIsGroup)
@ -1056,7 +1047,8 @@ void SourceTree::dropEvent(QDropEvent *event)
bool dropOnCollapsed = false;
if (dropGroup) {
obs_data_t *data = obs_sceneitem_get_private_settings(dropGroup);
obs_data_t *data =
obs_sceneitem_get_private_settings(dropGroup);
dropOnCollapsed = obs_data_get_bool(data, "collapsed");
obs_data_release(data);
}
@ -1086,9 +1078,8 @@ void SourceTree::dropEvent(QDropEvent *event)
/* if dropping a group, detect if it's */
/* below another group */
obs_sceneitem_t *itemBelow = row == stm->items.count()
? nullptr
: stm->items[row];
obs_sceneitem_t *itemBelow =
row == stm->items.count() ? nullptr : stm->items[row];
if (hasGroups) {
if (!itemBelow ||
obs_sceneitem_get_group(scene, itemBelow) != dropGroup) {
@ -1131,8 +1122,8 @@ void SourceTree::dropEvent(QDropEvent *event)
for (int j = items.size() - 1; j >= 0; j--) {
obs_sceneitem_t *subitem = items[j];
obs_sceneitem_t *subitemGroup =
obs_sceneitem_get_group(scene,
subitem);
obs_sceneitem_get_group(
scene, subitem);
if (subitemGroup == item) {
QModelIndex idx =
@ -1167,7 +1158,7 @@ void SourceTree::dropEvent(QDropEvent *event)
if (itemTo != from) {
stm->beginMoveRows(QModelIndex(), from, from,
QModelIndex(), to);
QModelIndex(), to);
MoveItem(items, from, itemTo);
stm->endMoveRows();
}
@ -1186,8 +1177,7 @@ void SourceTree::dropEvent(QDropEvent *event)
obs_sceneitem_t *lastGroup = nullptr;
int insertCollapsedIdx = 0;
auto insertCollapsed = [&] (obs_sceneitem_t *item)
{
auto insertCollapsed = [&](obs_sceneitem_t *item) {
struct obs_sceneitem_order_info info;
info.group = lastGroup;
info.item = item;
@ -1197,25 +1187,23 @@ void SourceTree::dropEvent(QDropEvent *event)
using insertCollapsed_t = decltype(insertCollapsed);
auto preInsertCollapsed = [] (obs_scene_t *, obs_sceneitem_t *item,
void *param)
{
auto preInsertCollapsed = [](obs_scene_t *, obs_sceneitem_t *item,
void *param) {
(*reinterpret_cast<insertCollapsed_t *>(param))(item);
return true;
};
auto insertLastGroup = [&] ()
{
obs_data_t *data = obs_sceneitem_get_private_settings(lastGroup);
auto insertLastGroup = [&]() {
obs_data_t *data =
obs_sceneitem_get_private_settings(lastGroup);
bool collapsed = obs_data_get_bool(data, "collapsed");
obs_data_release(data);
if (collapsed) {
insertCollapsedIdx = 0;
obs_sceneitem_group_enum_items(
lastGroup,
preInsertCollapsed,
&insertCollapsed);
obs_sceneitem_group_enum_items(lastGroup,
preInsertCollapsed,
&insertCollapsed);
}
struct obs_sceneitem_order_info info;
@ -1224,8 +1212,7 @@ void SourceTree::dropEvent(QDropEvent *event)
orderList.insert(0, info);
};
auto updateScene = [&] ()
{
auto updateScene = [&]() {
struct obs_sceneitem_order_info info;
for (int i = 0; i < items.size(); i++) {
@ -1260,14 +1247,13 @@ void SourceTree::dropEvent(QDropEvent *event)
insertLastGroup();
}
obs_scene_reorder_items2(scene,
orderList.data(), orderList.size());
obs_scene_reorder_items2(scene, orderList.data(),
orderList.size());
};
using updateScene_t = decltype(updateScene);
auto preUpdateScene = [] (void *data, obs_scene_t *)
{
auto preUpdateScene = [](void *data, obs_scene_t *) {
(*reinterpret_cast<updateScene_t *>(data))();
};
@ -1314,9 +1300,8 @@ void SourceTree::leaveEvent(QEvent *event)
QListView::leaveEvent(event);
}
void SourceTree::selectionChanged(
const QItemSelection &selected,
const QItemSelection &deselected)
void SourceTree::selectionChanged(const QItemSelection &selected,
const QItemSelection &deselected)
{
{
SignalBlocker sourcesSignalBlocker(this);
@ -1425,7 +1410,7 @@ bool SourceTree::GroupedItemsSelected() const
void SourceTree::Remove(OBSSceneItem item)
{
OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
GetStm()->Remove(item);
main->SaveProject();
@ -1434,9 +1419,9 @@ void SourceTree::Remove(OBSSceneItem item)
obs_source_t *sceneSource = obs_scene_get_source(scene);
obs_source_t *itemSource = obs_sceneitem_get_source(item);
blog(LOG_INFO, "User Removed source '%s' (%s) from scene '%s'",
obs_source_get_name(itemSource),
obs_source_get_id(itemSource),
obs_source_get_name(sceneSource));
obs_source_get_name(itemSource),
obs_source_get_id(itemSource),
obs_source_get_name(sceneSource));
}
}
@ -1465,9 +1450,8 @@ void SourceTree::UpdateNoSourcesMessage()
QColor color = palette().text().color();
bool lightTheme = (color.redF() < 0.5);
QString file = lightTheme
? ":res/images/no_sources.svg"
: darkPath.c_str();
QString file = lightTheme ? ":res/images/no_sources.svg"
: darkPath.c_str();
iconNoSources.load(file);
QTextOption opt(Qt::AlignHCenter);

View file

@ -72,7 +72,7 @@ private:
OBSSignal renameSignal;
OBSSignal removeSignal;
virtual void paintEvent(QPaintEvent* event) override;
virtual void paintEvent(QPaintEvent *event) override;
private slots:
void Clear();
@ -123,7 +123,8 @@ public:
~SourceTreeModel();
virtual int rowCount(const QModelIndex &parent) const override;
virtual QVariant data(const QModelIndex &index, int role) const override;
virtual QVariant data(const QModelIndex &index,
int role) const override;
virtual Qt::ItemFlags flags(const QModelIndex &index) const override;
virtual Qt::DropActions supportedDropActions() const override;
@ -161,12 +162,12 @@ public:
explicit SourceTree(QWidget *parent = nullptr);
inline bool IgnoreReorder() const {return ignoreReorder;}
inline void Clear() {GetStm()->Clear();}
inline bool IgnoreReorder() const { return ignoreReorder; }
inline void Clear() { GetStm()->Clear(); }
inline void Add(obs_sceneitem_t *item) {GetStm()->Add(item);}
inline OBSSceneItem Get(int idx) {return GetStm()->Get(idx);}
inline QString GetNewGroupName() {return GetStm()->GetNewGroupName();}
inline void Add(obs_sceneitem_t *item) { GetStm()->Add(item); }
inline OBSSceneItem Get(int idx) { return GetStm()->Get(idx); }
inline QString GetNewGroupName() { return GetStm()->GetNewGroupName(); }
void SelectItem(obs_sceneitem_t *sceneitem, bool select);
@ -175,7 +176,7 @@ public:
bool GroupedItemsSelected() const;
public slots:
inline void ReorderItems() {GetStm()->ReorderItems();}
inline void ReorderItems() { GetStm()->ReorderItems(); }
void Remove(OBSSceneItem item);
void GroupSelectedItems();
void UngroupSelectedGroups();
@ -189,5 +190,7 @@ protected:
virtual void leaveEvent(QEvent *event) override;
virtual void paintEvent(QPaintEvent *event) override;
virtual void selectionChanged(const QItemSelection &selected, const QItemSelection &deselected) override;
virtual void
selectionChanged(const QItemSelection &selected,
const QItemSelection &deselected) override;
};

View file

@ -8,8 +8,7 @@ class VScrollArea : public QScrollArea {
Q_OBJECT
public:
inline VScrollArea(QWidget *parent = nullptr)
: QScrollArea(parent)
inline VScrollArea(QWidget *parent = nullptr) : QScrollArea(parent)
{
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
}

View file

@ -10,11 +10,11 @@
#include <QLabel>
VisibilityItemWidget::VisibilityItemWidget(obs_source_t *source_)
: source (source_),
enabledSignal (obs_source_get_signal_handler(source), "enable",
OBSSourceEnabled, this),
renamedSignal (obs_source_get_signal_handler(source), "rename",
OBSSourceRenamed, this)
: source(source_),
enabledSignal(obs_source_get_signal_handler(source), "enable",
OBSSourceEnabled, this),
renamedSignal(obs_source_get_signal_handler(source), "rename",
OBSSourceRenamed, this)
{
const char *name = obs_source_get_name(source);
bool enabled = obs_source_enabled(source);
@ -38,15 +38,15 @@ VisibilityItemWidget::VisibilityItemWidget(obs_source_t *source_)
setLayout(itemLayout);
setStyleSheet("background-color: rgba(255, 255, 255, 0);");
connect(vis, SIGNAL(clicked(bool)),
this, SLOT(VisibilityClicked(bool)));
connect(vis, SIGNAL(clicked(bool)), this,
SLOT(VisibilityClicked(bool)));
}
VisibilityItemWidget::VisibilityItemWidget(obs_sceneitem_t *item_)
: item (item_),
source (obs_sceneitem_get_source(item)),
renamedSignal (obs_source_get_signal_handler(source), "rename",
OBSSourceRenamed, this)
: item(item_),
source(obs_sceneitem_get_source(item)),
renamedSignal(obs_source_get_signal_handler(source), "rename",
OBSSourceRenamed, this)
{
const char *name = obs_source_get_name(source);
bool enabled = obs_sceneitem_visible(item);
@ -90,18 +90,15 @@ VisibilityItemWidget::VisibilityItemWidget(obs_sceneitem_t *item_)
signal_handler_t *signal = obs_source_get_signal_handler(sceneSource);
signal_handler_connect(signal, "remove", OBSSceneRemove, this);
signal_handler_connect(signal, "item_remove", OBSSceneItemRemove,
this);
signal_handler_connect(signal, "item_remove", OBSSceneItemRemove, this);
signal_handler_connect(signal, "item_visible", OBSSceneItemVisible,
this);
signal_handler_connect(signal, "item_locked", OBSSceneItemLocked,
this);
this);
signal_handler_connect(signal, "item_locked", OBSSceneItemLocked, this);
connect(vis, SIGNAL(clicked(bool)),
this, SLOT(VisibilityClicked(bool)));
connect(vis, SIGNAL(clicked(bool)), this,
SLOT(VisibilityClicked(bool)));
connect(lock, SIGNAL(clicked(bool)),
this, SLOT(LockClicked(bool)));
connect(lock, SIGNAL(clicked(bool)), this, SLOT(LockClicked(bool)));
}
VisibilityItemWidget::~VisibilityItemWidget()
@ -120,11 +117,11 @@ void VisibilityItemWidget::DisconnectItemSignals()
signal_handler_disconnect(signal, "remove", OBSSceneRemove, this);
signal_handler_disconnect(signal, "item_remove", OBSSceneItemRemove,
this);
this);
signal_handler_disconnect(signal, "item_visible", OBSSceneItemVisible,
this);
this);
signal_handler_disconnect(signal, "item_locked", OBSSceneItemLocked,
this);
this);
sceneRemoved = true;
}
@ -132,7 +129,7 @@ void VisibilityItemWidget::DisconnectItemSignals()
void VisibilityItemWidget::OBSSceneRemove(void *param, calldata_t *data)
{
VisibilityItemWidget *window =
reinterpret_cast<VisibilityItemWidget*>(param);
reinterpret_cast<VisibilityItemWidget *>(param);
window->DisconnectItemSignals();
@ -142,8 +139,8 @@ void VisibilityItemWidget::OBSSceneRemove(void *param, calldata_t *data)
void VisibilityItemWidget::OBSSceneItemRemove(void *param, calldata_t *data)
{
VisibilityItemWidget *window =
reinterpret_cast<VisibilityItemWidget*>(param);
obs_sceneitem_t *item = (obs_sceneitem_t*)calldata_ptr(data, "item");
reinterpret_cast<VisibilityItemWidget *>(param);
obs_sceneitem_t *item = (obs_sceneitem_t *)calldata_ptr(data, "item");
if (item == window->item)
window->DisconnectItemSignals();
@ -152,45 +149,47 @@ void VisibilityItemWidget::OBSSceneItemRemove(void *param, calldata_t *data)
void VisibilityItemWidget::OBSSceneItemVisible(void *param, calldata_t *data)
{
VisibilityItemWidget *window =
reinterpret_cast<VisibilityItemWidget*>(param);
obs_sceneitem_t *curItem = (obs_sceneitem_t*)calldata_ptr(data, "item");
reinterpret_cast<VisibilityItemWidget *>(param);
obs_sceneitem_t *curItem =
(obs_sceneitem_t *)calldata_ptr(data, "item");
bool enabled = calldata_bool(data, "visible");
if (window->item == curItem)
QMetaObject::invokeMethod(window, "SourceEnabled",
Q_ARG(bool, enabled));
Q_ARG(bool, enabled));
}
void VisibilityItemWidget::OBSSceneItemLocked(void *param, calldata_t *data)
{
VisibilityItemWidget *window =
reinterpret_cast<VisibilityItemWidget*>(param);
obs_sceneitem_t *curItem = (obs_sceneitem_t*)calldata_ptr(data, "item");
reinterpret_cast<VisibilityItemWidget *>(param);
obs_sceneitem_t *curItem =
(obs_sceneitem_t *)calldata_ptr(data, "item");
bool locked = calldata_bool(data, "locked");
if (window->item == curItem)
QMetaObject::invokeMethod(window, "SourceLocked",
Q_ARG(bool, locked));
Q_ARG(bool, locked));
}
void VisibilityItemWidget::OBSSourceEnabled(void *param, calldata_t *data)
{
VisibilityItemWidget *window =
reinterpret_cast<VisibilityItemWidget*>(param);
reinterpret_cast<VisibilityItemWidget *>(param);
bool enabled = calldata_bool(data, "enabled");
QMetaObject::invokeMethod(window, "SourceEnabled",
Q_ARG(bool, enabled));
Q_ARG(bool, enabled));
}
void VisibilityItemWidget::OBSSourceRenamed(void *param, calldata_t *data)
{
VisibilityItemWidget *window =
reinterpret_cast<VisibilityItemWidget*>(param);
reinterpret_cast<VisibilityItemWidget *>(param);
const char *name = calldata_string(data, "new_name");
QMetaObject::invokeMethod(window, "SourceRenamed",
Q_ARG(QString, QT_UTF8(name)));
Q_ARG(QString, QT_UTF8(name)));
}
void VisibilityItemWidget::VisibilityClicked(bool visible)
@ -225,8 +224,8 @@ void VisibilityItemWidget::SourceRenamed(QString name)
label->setText(name);
}
void VisibilityItemWidget::SetColor(const QColor &color,
bool active_, bool selected_)
void VisibilityItemWidget::SetColor(const QColor &color, bool active_,
bool selected_)
{
/* Do not update unless the state has actually changed */
if (active_ == active && selected_ == selected)
@ -248,19 +247,19 @@ VisibilityItemDelegate::VisibilityItemDelegate(QObject *parent)
}
void VisibilityItemDelegate::paint(QPainter *painter,
const QStyleOptionViewItem &option,
const QModelIndex &index) const
const QStyleOptionViewItem &option,
const QModelIndex &index) const
{
QStyledItemDelegate::paint(painter, option, index);
QObject *parentObj = parent();
QListWidget *list = qobject_cast<QListWidget*>(parentObj);
QListWidget *list = qobject_cast<QListWidget *>(parentObj);
if (!list)
return;
QListWidgetItem *item = list->item(index.row());
VisibilityItemWidget *widget =
qobject_cast<VisibilityItemWidget*>(list->itemWidget(item));
qobject_cast<VisibilityItemWidget *>(list->itemWidget(item));
if (!widget)
return;
@ -269,8 +268,8 @@ void VisibilityItemDelegate::paint(QPainter *painter,
QPalette palette = list->palette();
#if defined(_WIN32) || defined(__APPLE__)
QPalette::ColorGroup group = active ?
QPalette::Active : QPalette::Inactive;
QPalette::ColorGroup group = active ? QPalette::Active
: QPalette::Inactive;
#else
QPalette::ColorGroup group = QPalette::Active;
#endif
@ -292,7 +291,7 @@ void VisibilityItemDelegate::paint(QPainter *painter,
}
void SetupVisibilityItem(QListWidget *list, QListWidgetItem *item,
obs_source_t *source)
obs_source_t *source)
{
VisibilityItemWidget *baseWidget = new VisibilityItemWidget(source);
@ -301,7 +300,7 @@ void SetupVisibilityItem(QListWidget *list, QListWidgetItem *item,
}
void SetupVisibilityItem(QListWidget *list, QListWidgetItem *item,
obs_sceneitem_t *sceneItem)
obs_sceneitem_t *sceneItem)
{
VisibilityItemWidget *baseWidget = new VisibilityItemWidget(sceneItem);

View file

@ -61,10 +61,10 @@ public:
VisibilityItemDelegate(QObject *parent = nullptr);
void paint(QPainter *painter, const QStyleOptionViewItem &option,
const QModelIndex &index) const override;
const QModelIndex &index) const override;
};
void SetupVisibilityItem(QListWidget *list, QListWidgetItem *item,
obs_source_t *source);
obs_source_t *source);
void SetupVisibilityItem(QListWidget *list, QListWidgetItem *item,
obs_sceneitem_t *sceneItem);
obs_sceneitem_t *sceneItem);

View file

@ -21,35 +21,35 @@ QWeakPointer<VolumeMeterTimer> VolumeMeter::updateTimer;
void VolControl::OBSVolumeChanged(void *data, float db)
{
Q_UNUSED(db);
VolControl *volControl = static_cast<VolControl*>(data);
VolControl *volControl = static_cast<VolControl *>(data);
QMetaObject::invokeMethod(volControl, "VolumeChanged");
}
void VolControl::OBSVolumeLevel(void *data,
const float magnitude[MAX_AUDIO_CHANNELS],
const float peak[MAX_AUDIO_CHANNELS],
const float inputPeak[MAX_AUDIO_CHANNELS])
const float magnitude[MAX_AUDIO_CHANNELS],
const float peak[MAX_AUDIO_CHANNELS],
const float inputPeak[MAX_AUDIO_CHANNELS])
{
VolControl *volControl = static_cast<VolControl*>(data);
VolControl *volControl = static_cast<VolControl *>(data);
volControl->volMeter->setLevels(magnitude, peak, inputPeak);
}
void VolControl::OBSVolumeMuted(void *data, calldata_t *calldata)
{
VolControl *volControl = static_cast<VolControl*>(data);
VolControl *volControl = static_cast<VolControl *>(data);
bool muted = calldata_bool(calldata, "muted");
QMetaObject::invokeMethod(volControl, "VolumeMuted",
Q_ARG(bool, muted));
Q_ARG(bool, muted));
}
void VolControl::VolumeChanged()
{
slider->blockSignals(true);
slider->setValue((int) (obs_fader_get_deflection(obs_fader) *
FADER_PRECISION));
slider->setValue(
(int)(obs_fader_get_deflection(obs_fader) * FADER_PRECISION));
slider->blockSignals(false);
updateText();
@ -75,13 +75,12 @@ void VolControl::SliderChanged(int vol)
void VolControl::updateText()
{
QString db = QString::number(obs_fader_get_db(obs_fader), 'f', 1)
.append(" dB");
.append(" dB");
volLabel->setText(db);
bool muted = obs_source_muted(source);
const char *accTextLookup = muted
? "VolControl.SliderMuted"
: "VolControl.SliderUnmuted";
const char *accTextLookup = muted ? "VolControl.SliderMuted"
: "VolControl.SliderUnmuted";
QString sourceName = obs_source_get_name(source);
QString accText = QTStr(accTextLookup).arg(sourceName, db);
@ -115,16 +114,16 @@ void VolControl::setPeakMeterType(enum obs_peak_meter_type peakMeterType)
}
VolControl::VolControl(OBSSource source_, bool showConfig, bool vertical)
: source (std::move(source_)),
levelTotal (0.0f),
levelCount (0.0f),
obs_fader (obs_fader_create(OBS_FADER_LOG)),
obs_volmeter (obs_volmeter_create(OBS_FADER_LOG)),
vertical (vertical)
: source(std::move(source_)),
levelTotal(0.0f),
levelCount(0.0f),
obs_fader(obs_fader_create(OBS_FADER_LOG)),
obs_volmeter(obs_volmeter_create(OBS_FADER_LOG)),
vertical(vertical)
{
nameLabel = new QLabel();
volLabel = new QLabel();
mute = new MuteCheckBox();
volLabel = new QLabel();
mute = new MuteCheckBox();
QString sourceName = obs_source_get_name(source);
setObjectName(sourceName);
@ -134,15 +133,15 @@ VolControl::VolControl(OBSSource source_, bool showConfig, bool vertical)
config->setProperty("themeID", "configIconSmall");
config->setFlat(true);
config->setSizePolicy(QSizePolicy::Maximum,
QSizePolicy::Maximum);
QSizePolicy::Maximum);
config->setMaximumSize(22, 22);
config->setAutoDefault(false);
config->setAccessibleName(QTStr("VolControl.Properties")
.arg(sourceName));
config->setAccessibleName(
QTStr("VolControl.Properties").arg(sourceName));
connect(config, &QAbstractButton::clicked,
this, &VolControl::EmitConfigClicked);
connect(config, &QAbstractButton::clicked, this,
&VolControl::EmitConfigClicked);
}
QVBoxLayout *mainLayout = new QVBoxLayout;
@ -153,10 +152,10 @@ VolControl::VolControl(OBSSource source_, bool showConfig, bool vertical)
QHBoxLayout *nameLayout = new QHBoxLayout;
QHBoxLayout *controlLayout = new QHBoxLayout;
QHBoxLayout *volLayout = new QHBoxLayout;
QHBoxLayout *meterLayout = new QHBoxLayout;
QHBoxLayout *meterLayout = new QHBoxLayout;
volMeter = new VolumeMeter(nullptr, obs_volmeter, true);
slider = new SliderIgnoreScroll(Qt::Vertical);
volMeter = new VolumeMeter(nullptr, obs_volmeter, true);
slider = new SliderIgnoreScroll(Qt::Vertical);
nameLayout->setAlignment(Qt::AlignCenter);
meterLayout->setAlignment(Qt::AlignCenter);
@ -195,18 +194,18 @@ VolControl::VolControl(OBSSource source_, bool showConfig, bool vertical)
setMaximumWidth(110);
} else {
QHBoxLayout *volLayout = new QHBoxLayout;
QHBoxLayout *volLayout = new QHBoxLayout;
QHBoxLayout *textLayout = new QHBoxLayout;
QHBoxLayout *botLayout = new QHBoxLayout;
QHBoxLayout *botLayout = new QHBoxLayout;
volMeter = new VolumeMeter(nullptr, obs_volmeter, false);
slider = new SliderIgnoreScroll(Qt::Horizontal);
volMeter = new VolumeMeter(nullptr, obs_volmeter, false);
slider = new SliderIgnoreScroll(Qt::Horizontal);
textLayout->setContentsMargins(0, 0, 0, 0);
textLayout->addWidget(nameLabel);
textLayout->addWidget(volLabel);
textLayout->setAlignment(nameLabel, Qt::AlignLeft);
textLayout->setAlignment(volLabel, Qt::AlignRight);
textLayout->setAlignment(volLabel, Qt::AlignRight);
volLayout->addWidget(slider);
volLayout->addWidget(mute);
@ -229,7 +228,7 @@ VolControl::VolControl(OBSSource source_, bool showConfig, bool vertical)
setLayout(mainLayout);
QFont font = nameLabel->font();
font.setPointSize(font.pointSize()-1);
font.setPointSize(font.pointSize() - 1);
nameLabel->setText(sourceName);
nameLabel->setFont(font);
@ -244,13 +243,13 @@ VolControl::VolControl(OBSSource source_, bool showConfig, bool vertical)
obs_fader_add_callback(obs_fader, OBSVolumeChanged, this);
obs_volmeter_add_callback(obs_volmeter, OBSVolumeLevel, this);
signal_handler_connect(obs_source_get_signal_handler(source),
"mute", OBSVolumeMuted, this);
signal_handler_connect(obs_source_get_signal_handler(source), "mute",
OBSVolumeMuted, this);
QWidget::connect(slider, SIGNAL(valueChanged(int)),
this, SLOT(SliderChanged(int)));
QWidget::connect(mute, SIGNAL(clicked(bool)),
this, SLOT(SetMuted(bool)));
QWidget::connect(slider, SIGNAL(valueChanged(int)), this,
SLOT(SliderChanged(int)));
QWidget::connect(mute, SIGNAL(clicked(bool)), this,
SLOT(SetMuted(bool)));
obs_fader_attach_source(obs_fader, source);
obs_volmeter_attach_source(obs_volmeter, source);
@ -276,8 +275,8 @@ VolControl::~VolControl()
obs_fader_remove_callback(obs_fader, OBSVolumeChanged, this);
obs_volmeter_remove_callback(obs_volmeter, OBSVolumeLevel, this);
signal_handler_disconnect(obs_source_get_signal_handler(source),
"mute", OBSVolumeMuted, this);
signal_handler_disconnect(obs_source_get_signal_handler(source), "mute",
OBSVolumeMuted, this);
obs_fader_destroy(obs_fader);
obs_volmeter_destroy(obs_volmeter);
@ -517,34 +516,33 @@ void VolumeMeter::wheelEvent(QWheelEvent *event)
}
VolumeMeter::VolumeMeter(QWidget *parent, obs_volmeter_t *obs_volmeter,
bool vertical)
: QWidget(parent), obs_volmeter(obs_volmeter),
vertical(vertical)
bool vertical)
: QWidget(parent), obs_volmeter(obs_volmeter), vertical(vertical)
{
// Use a font that can be rendered small.
tickFont = QFont("Arial");
tickFont.setPixelSize(7);
// Default meter color settings, they only show if
// there is no stylesheet, do not remove.
backgroundNominalColor.setRgb(0x26, 0x7f, 0x26); // Dark green
backgroundWarningColor.setRgb(0x7f, 0x7f, 0x26); // Dark yellow
backgroundErrorColor.setRgb(0x7f, 0x26, 0x26); // Dark red
foregroundNominalColor.setRgb(0x4c, 0xff, 0x4c); // Bright green
foregroundWarningColor.setRgb(0xff, 0xff, 0x4c); // Bright yellow
foregroundErrorColor.setRgb(0xff, 0x4c, 0x4c); // Bright red
clipColor.setRgb(0xff, 0xff, 0xff); // Bright white
magnitudeColor.setRgb(0x00, 0x00, 0x00); // Black
majorTickColor.setRgb(0xff, 0xff, 0xff); // Black
minorTickColor.setRgb(0xcc, 0xcc, 0xcc); // Black
minimumLevel = -60.0; // -60 dB
warningLevel = -20.0; // -20 dB
errorLevel = -9.0; // -9 dB
clipLevel = -0.5; // -0.5 dB
minimumInputLevel = -50.0; // -50 dB
peakDecayRate = 11.76; // 20 dB / 1.7 sec
magnitudeIntegrationTime = 0.3; // 99% in 300 ms
peakHoldDuration = 20.0; // 20 seconds
inputPeakHoldDuration = 1.0; // 1 second
backgroundNominalColor.setRgb(0x26, 0x7f, 0x26); // Dark green
backgroundWarningColor.setRgb(0x7f, 0x7f, 0x26); // Dark yellow
backgroundErrorColor.setRgb(0x7f, 0x26, 0x26); // Dark red
foregroundNominalColor.setRgb(0x4c, 0xff, 0x4c); // Bright green
foregroundWarningColor.setRgb(0xff, 0xff, 0x4c); // Bright yellow
foregroundErrorColor.setRgb(0xff, 0x4c, 0x4c); // Bright red
clipColor.setRgb(0xff, 0xff, 0xff); // Bright white
magnitudeColor.setRgb(0x00, 0x00, 0x00); // Black
majorTickColor.setRgb(0xff, 0xff, 0xff); // Black
minorTickColor.setRgb(0xcc, 0xcc, 0xcc); // Black
minimumLevel = -60.0; // -60 dB
warningLevel = -20.0; // -20 dB
errorLevel = -9.0; // -9 dB
clipLevel = -0.5; // -0.5 dB
minimumInputLevel = -50.0; // -50 dB
peakDecayRate = 11.76; // 20 dB / 1.7 sec
magnitudeIntegrationTime = 0.3; // 99% in 300 ms
peakHoldDuration = 20.0; // 20 seconds
inputPeakHoldDuration = 1.0; // 1 second
channels = (int)audio_output_get_channels(obs_get_audio());
@ -566,8 +564,8 @@ VolumeMeter::~VolumeMeter()
}
void VolumeMeter::setLevels(const float magnitude[MAX_AUDIO_CHANNELS],
const float peak[MAX_AUDIO_CHANNELS],
const float inputPeak[MAX_AUDIO_CHANNELS])
const float peak[MAX_AUDIO_CHANNELS],
const float inputPeak[MAX_AUDIO_CHANNELS])
{
uint64_t ts = os_gettime_ns();
QMutexLocker locker(&dataMutex);
@ -632,11 +630,12 @@ inline bool VolumeMeter::detectIdle(uint64_t ts)
}
}
inline void VolumeMeter::calculateBallisticsForChannel(int channelNr,
uint64_t ts, qreal timeSinceLastRedraw)
inline void
VolumeMeter::calculateBallisticsForChannel(int channelNr, uint64_t ts,
qreal timeSinceLastRedraw)
{
if (currentPeak[channelNr] >= displayPeak[channelNr] ||
isnan(displayPeak[channelNr])) {
isnan(displayPeak[channelNr])) {
// Attack of peak is immediate.
displayPeak[channelNr] = currentPeak[channelNr];
} else {
@ -645,11 +644,11 @@ inline void VolumeMeter::calculateBallisticsForChannel(int channelNr,
// 24 dB / 2.8 seconds for Slow Profile (Type II PPM)
float decay = float(peakDecayRate * timeSinceLastRedraw);
displayPeak[channelNr] = CLAMP(displayPeak[channelNr] - decay,
currentPeak[channelNr], 0);
currentPeak[channelNr], 0);
}
if (currentPeak[channelNr] >= displayPeakHold[channelNr] ||
!isfinite(displayPeakHold[channelNr])) {
!isfinite(displayPeakHold[channelNr])) {
// Attack of peak-hold is immediate, but keep track
// when it was last updated.
displayPeakHold[channelNr] = currentPeak[channelNr];
@ -657,8 +656,10 @@ inline void VolumeMeter::calculateBallisticsForChannel(int channelNr,
} else {
// The peak and hold falls back to peak
// after 20 seconds.
qreal timeSinceLastPeak = (uint64_t)(ts -
displayPeakHoldLastUpdateTime[channelNr]) * 0.000000001;
qreal timeSinceLastPeak =
(uint64_t)(ts -
displayPeakHoldLastUpdateTime[channelNr]) *
0.000000001;
if (timeSinceLastPeak > peakHoldDuration) {
displayPeakHold[channelNr] = currentPeak[channelNr];
displayPeakHoldLastUpdateTime[channelNr] = ts;
@ -666,21 +667,22 @@ inline void VolumeMeter::calculateBallisticsForChannel(int channelNr,
}
if (currentInputPeak[channelNr] >= displayInputPeakHold[channelNr] ||
!isfinite(displayInputPeakHold[channelNr])) {
!isfinite(displayInputPeakHold[channelNr])) {
// Attack of peak-hold is immediate, but keep track
// when it was last updated.
displayInputPeakHold[channelNr] = currentInputPeak[channelNr];
displayInputPeakHoldLastUpdateTime[channelNr] = ts;
} else {
// The peak and hold falls back to peak after 1 second.
qreal timeSinceLastPeak = (uint64_t)(ts -
displayInputPeakHoldLastUpdateTime[channelNr]) *
qreal timeSinceLastPeak =
(uint64_t)(
ts -
displayInputPeakHoldLastUpdateTime[channelNr]) *
0.000000001;
if (timeSinceLastPeak > inputPeakHoldDuration) {
displayInputPeakHold[channelNr] =
currentInputPeak[channelNr];
displayInputPeakHoldLastUpdateTime[channelNr] =
ts;
displayInputPeakHoldLastUpdateTime[channelNr] = ts;
}
}
@ -692,27 +694,29 @@ inline void VolumeMeter::calculateBallisticsForChannel(int channelNr,
// A VU meter will integrate to the new value to 99% in 300 ms.
// The calculation here is very simplified and is more accurate
// with higher frame-rate.
float attack = float((currentMagnitude[channelNr] -
displayMagnitude[channelNr]) *
(timeSinceLastRedraw /
magnitudeIntegrationTime) * 0.99);
displayMagnitude[channelNr] = CLAMP(displayMagnitude[channelNr]
+ attack, (float)minimumLevel, 0);
float attack =
float((currentMagnitude[channelNr] -
displayMagnitude[channelNr]) *
(timeSinceLastRedraw / magnitudeIntegrationTime) *
0.99);
displayMagnitude[channelNr] =
CLAMP(displayMagnitude[channelNr] + attack,
(float)minimumLevel, 0);
}
}
inline void VolumeMeter::calculateBallistics(uint64_t ts,
qreal timeSinceLastRedraw)
qreal timeSinceLastRedraw)
{
QMutexLocker locker(&dataMutex);
for (int channelNr = 0; channelNr < MAX_AUDIO_CHANNELS; channelNr++)
calculateBallisticsForChannel(channelNr, ts,
timeSinceLastRedraw);
timeSinceLastRedraw);
}
void VolumeMeter::paintInputMeter(QPainter &painter, int x, int y, int width,
int height, float peakHold)
int height, float peakHold)
{
QMutexLocker locker(&dataMutex);
QColor color;
@ -732,7 +736,7 @@ void VolumeMeter::paintInputMeter(QPainter &painter, int x, int y, int width,
}
void VolumeMeter::paintHTicks(QPainter &painter, int x, int y, int width,
int height)
int height)
{
qreal scale = width / minimumLevel;
@ -740,7 +744,7 @@ void VolumeMeter::paintHTicks(QPainter &painter, int x, int y, int width,
painter.setPen(majorTickColor);
// Draw major tick lines and numeric indicators.
for (int i = 0; i >= minimumLevel; i-= 5) {
for (int i = 0; i >= minimumLevel; i -= 5) {
int position = int(x + width - (i * scale) - 1);
QString str = QString::number(i);
@ -768,7 +772,7 @@ void VolumeMeter::paintVTicks(QPainter &painter, int x, int y, int height)
painter.setPen(majorTickColor);
// Draw major tick lines and numeric indicators.
for (int i = 0; i >= minimumLevel; i-= 5) {
for (int i = 0; i >= minimumLevel; i -= 5) {
int position = y + int((i * scale) - 1);
QString str = QString::number(i);
@ -798,22 +802,23 @@ void VolumeMeter::ClipEnding()
}
void VolumeMeter::paintHMeter(QPainter &painter, int x, int y, int width,
int height, float magnitude, float peak, float peakHold)
int height, float magnitude, float peak,
float peakHold)
{
qreal scale = width / minimumLevel;
QMutexLocker locker(&dataMutex);
int minimumPosition = x + 0;
int maximumPosition = x + width;
int magnitudePosition = int(x + width - (magnitude * scale));
int peakPosition = int(x + width - (peak * scale));
int peakHoldPosition = int(x + width - (peakHold * scale));
int warningPosition = int(x + width - (warningLevel * scale));
int errorPosition = int(x + width - (errorLevel * scale));
int minimumPosition = x + 0;
int maximumPosition = x + width;
int magnitudePosition = int(x + width - (magnitude * scale));
int peakPosition = int(x + width - (peak * scale));
int peakHoldPosition = int(x + width - (peakHold * scale));
int warningPosition = int(x + width - (warningLevel * scale));
int errorPosition = int(x + width - (errorLevel * scale));
int nominalLength = warningPosition - minimumPosition;
int warningLength = errorPosition - warningPosition;
int errorLength = maximumPosition - errorPosition;
int nominalLength = warningPosition - minimumPosition;
int warningLength = errorPosition - warningPosition;
int errorLength = maximumPosition - errorPosition;
locker.unlock();
if (clipping) {
@ -822,87 +827,89 @@ void VolumeMeter::paintHMeter(QPainter &painter, int x, int y, int width,
if (peakPosition < minimumPosition) {
painter.fillRect(minimumPosition, y, nominalLength, height,
backgroundNominalColor);
backgroundNominalColor);
painter.fillRect(warningPosition, y, warningLength, height,
backgroundWarningColor);
backgroundWarningColor);
painter.fillRect(errorPosition, y, errorLength, height,
backgroundErrorColor);
backgroundErrorColor);
} else if (peakPosition < warningPosition) {
painter.fillRect(minimumPosition, y, peakPosition -
minimumPosition, height,
foregroundNominalColor);
painter.fillRect(peakPosition, y, warningPosition -
peakPosition, height, backgroundNominalColor);
painter.fillRect(minimumPosition, y,
peakPosition - minimumPosition, height,
foregroundNominalColor);
painter.fillRect(peakPosition, y,
warningPosition - peakPosition, height,
backgroundNominalColor);
painter.fillRect(warningPosition, y, warningLength, height,
backgroundWarningColor);
backgroundWarningColor);
painter.fillRect(errorPosition, y, errorLength, height,
backgroundErrorColor);
backgroundErrorColor);
} else if (peakPosition < errorPosition) {
painter.fillRect(minimumPosition, y, nominalLength, height,
foregroundNominalColor);
foregroundNominalColor);
painter.fillRect(warningPosition, y,
peakPosition - warningPosition, height,
foregroundWarningColor);
painter.fillRect(peakPosition, y, errorPosition -
peakPosition, height, backgroundWarningColor);
peakPosition - warningPosition, height,
foregroundWarningColor);
painter.fillRect(peakPosition, y, errorPosition - peakPosition,
height, backgroundWarningColor);
painter.fillRect(errorPosition, y, errorLength, height,
backgroundErrorColor);
backgroundErrorColor);
} else if (peakPosition < maximumPosition) {
painter.fillRect(minimumPosition, y, nominalLength, height,
foregroundNominalColor);
foregroundNominalColor);
painter.fillRect(warningPosition, y, warningLength, height,
foregroundWarningColor);
foregroundWarningColor);
painter.fillRect(errorPosition, y, peakPosition - errorPosition,
height, foregroundErrorColor);
height, foregroundErrorColor);
painter.fillRect(peakPosition, y,
maximumPosition - peakPosition, height,
backgroundErrorColor);
maximumPosition - peakPosition, height,
backgroundErrorColor);
} else {
if (!clipping) {
QTimer::singleShot(CLIP_FLASH_DURATION_MS, this,
SLOT(ClipEnding()));
SLOT(ClipEnding()));
clipping = true;
}
int end = errorLength + warningLength + nominalLength;
painter.fillRect(minimumPosition, y, end, height,
QBrush(foregroundErrorColor));
QBrush(foregroundErrorColor));
}
if (peakHoldPosition - 3 < minimumPosition)
;// Peak-hold below minimum, no drawing.
; // Peak-hold below minimum, no drawing.
else if (peakHoldPosition < warningPosition)
painter.fillRect(peakHoldPosition - 3, y, 3, height,
foregroundNominalColor);
foregroundNominalColor);
else if (peakHoldPosition < errorPosition)
painter.fillRect(peakHoldPosition - 3, y, 3, height,
foregroundWarningColor);
foregroundWarningColor);
else
painter.fillRect(peakHoldPosition - 3, y, 3, height,
foregroundErrorColor);
foregroundErrorColor);
if (magnitudePosition - 3 >= minimumPosition)
painter.fillRect(magnitudePosition - 3, y, 3, height,
magnitudeColor);
magnitudeColor);
}
void VolumeMeter::paintVMeter(QPainter &painter, int x, int y, int width,
int height, float magnitude, float peak, float peakHold)
int height, float magnitude, float peak,
float peakHold)
{
qreal scale = height / minimumLevel;
QMutexLocker locker(&dataMutex);
int minimumPosition = y + 0;
int maximumPosition = y + height;
int magnitudePosition = int(y + height - (magnitude * scale));
int peakPosition = int(y + height - (peak * scale));
int peakHoldPosition = int(y + height - (peakHold * scale));
int warningPosition = int(y + height - (warningLevel * scale));
int errorPosition = int(y + height - (errorLevel * scale));
int minimumPosition = y + 0;
int maximumPosition = y + height;
int magnitudePosition = int(y + height - (magnitude * scale));
int peakPosition = int(y + height - (peak * scale));
int peakHoldPosition = int(y + height - (peakHold * scale));
int warningPosition = int(y + height - (warningLevel * scale));
int errorPosition = int(y + height - (errorLevel * scale));
int nominalLength = warningPosition - minimumPosition;
int warningLength = errorPosition - warningPosition;
int errorLength = maximumPosition - errorPosition;
int nominalLength = warningPosition - minimumPosition;
int warningLength = errorPosition - warningPosition;
int errorLength = maximumPosition - errorPosition;
locker.unlock();
if (clipping) {
@ -911,65 +918,71 @@ void VolumeMeter::paintVMeter(QPainter &painter, int x, int y, int width,
if (peakPosition < minimumPosition) {
painter.fillRect(x, minimumPosition, width, nominalLength,
backgroundNominalColor);
backgroundNominalColor);
painter.fillRect(x, warningPosition, width, warningLength,
backgroundWarningColor);
backgroundWarningColor);
painter.fillRect(x, errorPosition, width, errorLength,
backgroundErrorColor);
backgroundErrorColor);
} else if (peakPosition < warningPosition) {
painter.fillRect(x, minimumPosition, width, peakPosition -
minimumPosition, foregroundNominalColor);
painter.fillRect(x, peakPosition, width, warningPosition -
peakPosition, backgroundNominalColor);
painter.fillRect(x, minimumPosition, width,
peakPosition - minimumPosition,
foregroundNominalColor);
painter.fillRect(x, peakPosition, width,
warningPosition - peakPosition,
backgroundNominalColor);
painter.fillRect(x, warningPosition, width, warningLength,
backgroundWarningColor);
backgroundWarningColor);
painter.fillRect(x, errorPosition, width, errorLength,
backgroundErrorColor);
backgroundErrorColor);
} else if (peakPosition < errorPosition) {
painter.fillRect(x,minimumPosition, width, nominalLength,
foregroundNominalColor);
painter.fillRect(x, warningPosition, width, peakPosition -
warningPosition, foregroundWarningColor);
painter.fillRect(x, peakPosition, width, errorPosition -
peakPosition, backgroundWarningColor);
painter.fillRect(x, minimumPosition, width, nominalLength,
foregroundNominalColor);
painter.fillRect(x, warningPosition, width,
peakPosition - warningPosition,
foregroundWarningColor);
painter.fillRect(x, peakPosition, width,
errorPosition - peakPosition,
backgroundWarningColor);
painter.fillRect(x, errorPosition, width, errorLength,
backgroundErrorColor);
backgroundErrorColor);
} else if (peakPosition < maximumPosition) {
painter.fillRect(x, minimumPosition, width, nominalLength,
foregroundNominalColor);
foregroundNominalColor);
painter.fillRect(x, warningPosition, width, warningLength,
foregroundWarningColor);
painter.fillRect(x, errorPosition, width, peakPosition -
errorPosition, foregroundErrorColor);
painter.fillRect(x, peakPosition, width, maximumPosition -
peakPosition, backgroundErrorColor);
foregroundWarningColor);
painter.fillRect(x, errorPosition, width,
peakPosition - errorPosition,
foregroundErrorColor);
painter.fillRect(x, peakPosition, width,
maximumPosition - peakPosition,
backgroundErrorColor);
} else {
if (!clipping) {
QTimer::singleShot(CLIP_FLASH_DURATION_MS, this,
SLOT(ClipEnding()));
SLOT(ClipEnding()));
clipping = true;
}
int end = errorLength + warningLength + nominalLength;
painter.fillRect(x, minimumPosition, width, end,
QBrush(foregroundErrorColor));
QBrush(foregroundErrorColor));
}
if (peakHoldPosition - 3 < minimumPosition)
;// Peak-hold below minimum, no drawing.
; // Peak-hold below minimum, no drawing.
else if (peakHoldPosition < warningPosition)
painter.fillRect(x, peakHoldPosition - 3, width, 3,
foregroundNominalColor);
foregroundNominalColor);
else if (peakHoldPosition < errorPosition)
painter.fillRect(x, peakHoldPosition - 3, width, 3,
foregroundWarningColor);
foregroundWarningColor);
else
painter.fillRect(x, peakHoldPosition - 3, width, 3,
foregroundErrorColor);
foregroundErrorColor);
if (magnitudePosition - 3 >= minimumPosition)
painter.fillRect(x, magnitudePosition - 3, width, 3,
magnitudeColor);
magnitudeColor);
}
void VolumeMeter::paintEvent(QPaintEvent *event)
@ -978,7 +991,7 @@ void VolumeMeter::paintEvent(QPaintEvent *event)
qreal timeSinceLastRedraw = (ts - lastRedrawTime) * 0.000000001;
const QRect rect = event->region().boundingRect();
int width = rect.width();
int width = rect.width();
int height = rect.height();
handleChannelCofigurationChange();
@ -992,7 +1005,7 @@ void VolumeMeter::paintEvent(QPaintEvent *event)
else
tickPaintCacheSize = QSize(width, 9);
if (tickPaintCache == nullptr ||
tickPaintCache->size() != tickPaintCacheSize) {
tickPaintCache->size() != tickPaintCacheSize) {
delete tickPaintCache;
tickPaintCache = new QPixmap(tickPaintCacheSize);
@ -1004,11 +1017,11 @@ void VolumeMeter::paintEvent(QPaintEvent *event)
tickPainter.translate(0, height);
tickPainter.scale(1, -1);
paintVTicks(tickPainter, 0, 11,
tickPaintCacheSize.height() - 11);
tickPaintCacheSize.height() - 11);
} else {
paintHTicks(tickPainter, 6, 0,
tickPaintCacheSize.width() - 6,
tickPaintCacheSize.height());
tickPaintCacheSize.width() - 6,
tickPaintCacheSize.height());
}
tickPainter.end();
}
@ -1020,29 +1033,29 @@ void VolumeMeter::paintEvent(QPaintEvent *event)
painter.translate(0, height);
painter.scale(1, -1);
painter.drawPixmap(displayNrAudioChannels * 4 - 1, 7,
*tickPaintCache);
*tickPaintCache);
} else {
painter.drawPixmap(0, height - 9, *tickPaintCache);
}
for (int channelNr = 0; channelNr < displayNrAudioChannels;
channelNr++) {
channelNr++) {
int channelNrFixed = (displayNrAudioChannels == 1 &&
channels > 2)
? 2
: channelNr;
int channelNrFixed =
(displayNrAudioChannels == 1 && channels > 2)
? 2
: channelNr;
if (vertical)
paintVMeter(painter, channelNr * 4, 8, 3, height - 10,
displayMagnitude[channelNrFixed],
displayPeak[channelNrFixed],
displayPeakHold[channelNrFixed]);
displayMagnitude[channelNrFixed],
displayPeak[channelNrFixed],
displayPeakHold[channelNrFixed]);
else
paintHMeter(painter, 5, channelNr * 4, width - 5, 3,
displayMagnitude[channelNrFixed],
displayPeak[channelNrFixed],
displayPeakHold[channelNrFixed]);
displayMagnitude[channelNrFixed],
displayPeak[channelNrFixed],
displayPeakHold[channelNrFixed]);
if (idle)
continue;
@ -1071,7 +1084,7 @@ void VolumeMeterTimer::RemoveVolControl(VolumeMeter *meter)
volumeMeters.removeOne(meter);
}
void VolumeMeterTimer::timerEvent(QTimerEvent*)
void VolumeMeterTimer::timerEvent(QTimerEvent *)
{
for (VolumeMeter *meter : volumeMeters)
meter->update();

View file

@ -11,74 +11,55 @@
class QPushButton;
class VolumeMeterTimer;
class VolumeMeter : public QWidget
{
class VolumeMeter : public QWidget {
Q_OBJECT
Q_PROPERTY(QColor backgroundNominalColor
READ getBackgroundNominalColor
WRITE setBackgroundNominalColor DESIGNABLE true)
Q_PROPERTY(QColor backgroundWarningColor
READ getBackgroundWarningColor
WRITE setBackgroundWarningColor DESIGNABLE true)
Q_PROPERTY(QColor backgroundErrorColor
READ getBackgroundErrorColor
WRITE setBackgroundErrorColor DESIGNABLE true)
Q_PROPERTY(QColor foregroundNominalColor
READ getForegroundNominalColor
WRITE setForegroundNominalColor DESIGNABLE true)
Q_PROPERTY(QColor foregroundWarningColor
READ getForegroundWarningColor
WRITE setForegroundWarningColor DESIGNABLE true)
Q_PROPERTY(QColor foregroundErrorColor
READ getForegroundErrorColor
WRITE setForegroundErrorColor DESIGNABLE true)
Q_PROPERTY(QColor clipColor
READ getClipColor
WRITE setClipColor DESIGNABLE true)
Q_PROPERTY(QColor magnitudeColor
READ getMagnitudeColor
WRITE setMagnitudeColor DESIGNABLE true)
Q_PROPERTY(QColor majorTickColor
READ getMajorTickColor
WRITE setMajorTickColor DESIGNABLE true)
Q_PROPERTY(QColor minorTickColor
READ getMinorTickColor
WRITE setMinorTickColor DESIGNABLE true)
Q_PROPERTY(QColor backgroundNominalColor READ getBackgroundNominalColor
WRITE setBackgroundNominalColor DESIGNABLE true)
Q_PROPERTY(QColor backgroundWarningColor READ getBackgroundWarningColor
WRITE setBackgroundWarningColor DESIGNABLE true)
Q_PROPERTY(QColor backgroundErrorColor READ getBackgroundErrorColor
WRITE setBackgroundErrorColor DESIGNABLE true)
Q_PROPERTY(QColor foregroundNominalColor READ getForegroundNominalColor
WRITE setForegroundNominalColor DESIGNABLE true)
Q_PROPERTY(QColor foregroundWarningColor READ getForegroundWarningColor
WRITE setForegroundWarningColor DESIGNABLE true)
Q_PROPERTY(QColor foregroundErrorColor READ getForegroundErrorColor
WRITE setForegroundErrorColor DESIGNABLE true)
Q_PROPERTY(QColor clipColor READ getClipColor WRITE setClipColor
DESIGNABLE true)
Q_PROPERTY(QColor magnitudeColor READ getMagnitudeColor WRITE
setMagnitudeColor DESIGNABLE true)
Q_PROPERTY(QColor majorTickColor READ getMajorTickColor WRITE
setMajorTickColor DESIGNABLE true)
Q_PROPERTY(QColor minorTickColor READ getMinorTickColor WRITE
setMinorTickColor DESIGNABLE true)
// Levels are denoted in dBFS.
Q_PROPERTY(qreal minimumLevel
READ getMinimumLevel
WRITE setMinimumLevel DESIGNABLE true)
Q_PROPERTY(qreal warningLevel
READ getWarningLevel
WRITE setWarningLevel DESIGNABLE true)
Q_PROPERTY(qreal errorLevel
READ getErrorLevel
WRITE setErrorLevel DESIGNABLE true)
Q_PROPERTY(qreal clipLevel
READ getClipLevel
WRITE setClipLevel DESIGNABLE true)
Q_PROPERTY(qreal minimumInputLevel
READ getMinimumInputLevel
WRITE setMinimumInputLevel DESIGNABLE true)
Q_PROPERTY(qreal minimumLevel READ getMinimumLevel WRITE setMinimumLevel
DESIGNABLE true)
Q_PROPERTY(qreal warningLevel READ getWarningLevel WRITE setWarningLevel
DESIGNABLE true)
Q_PROPERTY(qreal errorLevel READ getErrorLevel WRITE setErrorLevel
DESIGNABLE true)
Q_PROPERTY(qreal clipLevel READ getClipLevel WRITE setClipLevel
DESIGNABLE true)
Q_PROPERTY(qreal minimumInputLevel READ getMinimumInputLevel WRITE
setMinimumInputLevel DESIGNABLE true)
// Rates are denoted in dB/second.
Q_PROPERTY(qreal peakDecayRate
READ getPeakDecayRate
WRITE setPeakDecayRate DESIGNABLE true)
Q_PROPERTY(qreal peakDecayRate READ getPeakDecayRate WRITE
setPeakDecayRate DESIGNABLE true)
// Time in seconds for the VU meter to integrate over.
Q_PROPERTY(qreal magnitudeIntegrationTime
READ getMagnitudeIntegrationTime
WRITE setMagnitudeIntegrationTime DESIGNABLE true)
Q_PROPERTY(
qreal magnitudeIntegrationTime READ getMagnitudeIntegrationTime
WRITE setMagnitudeIntegrationTime DESIGNABLE true)
// Duration is denoted in seconds.
Q_PROPERTY(qreal peakHoldDuration
READ getPeakHoldDuration
WRITE setPeakHoldDuration DESIGNABLE true)
Q_PROPERTY(qreal inputPeakHoldDuration
READ getInputPeakHoldDuration
WRITE setInputPeakHoldDuration DESIGNABLE true)
Q_PROPERTY(qreal peakHoldDuration READ getPeakHoldDuration WRITE
setPeakHoldDuration DESIGNABLE true)
Q_PROPERTY(qreal inputPeakHoldDuration READ getInputPeakHoldDuration
WRITE setInputPeakHoldDuration DESIGNABLE true)
private slots:
void ClipEnding();
@ -92,18 +73,18 @@ private:
inline void handleChannelCofigurationChange();
inline bool detectIdle(uint64_t ts);
inline void calculateBallistics(uint64_t ts,
qreal timeSinceLastRedraw=0.0);
inline void calculateBallisticsForChannel(int channelNr,
uint64_t ts, qreal timeSinceLastRedraw);
qreal timeSinceLastRedraw = 0.0);
inline void calculateBallisticsForChannel(int channelNr, uint64_t ts,
qreal timeSinceLastRedraw);
void paintInputMeter(QPainter &painter, int x, int y, int width,
int height, float peakHold);
int height, float peakHold);
void paintHMeter(QPainter &painter, int x, int y, int width, int height,
float magnitude, float peak, float peakHold);
float magnitude, float peak, float peakHold);
void paintHTicks(QPainter &painter, int x, int y, int width,
int height);
int height);
void paintVMeter(QPainter &painter, int x, int y, int width, int height,
float magnitude, float peak, float peakHold);
float magnitude, float peak, float peakHold);
void paintVTicks(QPainter &painter, int x, int y, int height);
QMutex dataMutex;
@ -150,14 +131,13 @@ private:
public:
explicit VolumeMeter(QWidget *parent = nullptr,
obs_volmeter_t *obs_volmeter = nullptr,
bool vertical = false);
obs_volmeter_t *obs_volmeter = nullptr,
bool vertical = false);
~VolumeMeter();
void setLevels(
const float magnitude[MAX_AUDIO_CHANNELS],
const float peak[MAX_AUDIO_CHANNELS],
const float inputPeak[MAX_AUDIO_CHANNELS]);
void setLevels(const float magnitude[MAX_AUDIO_CHANNELS],
const float peak[MAX_AUDIO_CHANNELS],
const float inputPeak[MAX_AUDIO_CHANNELS]);
QColor getBackgroundNominalColor() const;
void setBackgroundNominalColor(QColor c);
@ -216,7 +196,7 @@ public:
protected:
void timerEvent(QTimerEvent *event) override;
QList<VolumeMeter*> volumeMeters;
QList<VolumeMeter *> volumeMeters;
};
class QLabel;
@ -228,23 +208,23 @@ class VolControl : public QWidget {
private:
OBSSource source;
QLabel *nameLabel;
QLabel *volLabel;
VolumeMeter *volMeter;
QSlider *slider;
MuteCheckBox *mute;
QPushButton *config = nullptr;
float levelTotal;
float levelCount;
obs_fader_t *obs_fader;
obs_volmeter_t *obs_volmeter;
bool vertical;
QLabel *nameLabel;
QLabel *volLabel;
VolumeMeter *volMeter;
QSlider *slider;
MuteCheckBox *mute;
QPushButton *config = nullptr;
float levelTotal;
float levelCount;
obs_fader_t *obs_fader;
obs_volmeter_t *obs_volmeter;
bool vertical;
static void OBSVolumeChanged(void *param, float db);
static void OBSVolumeLevel(void *data,
const float magnitude[MAX_AUDIO_CHANNELS],
const float peak[MAX_AUDIO_CHANNELS],
const float inputPeak[MAX_AUDIO_CHANNELS]);
const float magnitude[MAX_AUDIO_CHANNELS],
const float peak[MAX_AUDIO_CHANNELS],
const float inputPeak[MAX_AUDIO_CHANNELS]);
static void OBSVolumeMuted(void *data, calldata_t *calldata);
void EmitConfigClicked();
@ -262,10 +242,10 @@ signals:
public:
explicit VolControl(OBSSource source, bool showConfig = false,
bool vertical = false);
bool vertical = false);
~VolControl();
inline obs_source_t *GetSource() const {return source;}
inline obs_source_t *GetSource() const { return source; }
QString GetName() const;
void SetName(const QString &newName);

View file

@ -2,10 +2,9 @@
#include "obs-app.hpp"
OBSUpdate::OBSUpdate(QWidget *parent, bool manualUpdate, const QString &text)
: QDialog (parent, Qt::WindowSystemMenuHint |
Qt::WindowTitleHint |
Qt::WindowCloseButtonHint),
ui (new Ui_OBSUpdate)
: QDialog(parent, Qt::WindowSystemMenuHint | Qt::WindowTitleHint |
Qt::WindowCloseButtonHint),
ui(new Ui_OBSUpdate)
{
ui->setupUi(this);
ui->text->setHtml(text);

View file

@ -9,11 +9,7 @@ class OBSUpdate : public QDialog {
Q_OBJECT
public:
enum ReturnVal {
No,
Yes,
Skip
};
enum ReturnVal { No, Yes, Skip };
OBSUpdate(QWidget *parent, bool manualUpdate, const QString &text);

View file

@ -26,7 +26,7 @@ void HashToString(const uint8_t *in, wchar_t *out)
const wchar_t alphabet[] = L"0123456789abcdef";
for (int i = 0; i != BLAKE2_HASH_LENGTH; ++i) {
out[2 * i] = alphabet[in[i] / 16];
out[2 * i] = alphabet[in[i] / 16];
out[2 * i + 1] = alphabet[in[i] % 16];
}
@ -50,7 +50,7 @@ bool CalculateFileHash(const wchar_t *path, BYTE *hash)
return false;
WinHandle handle = CreateFileW(path, GENERIC_READ, FILE_SHARE_READ,
nullptr, OPEN_EXISTING, 0, nullptr);
nullptr, OPEN_EXISTING, 0, nullptr);
if (handle == INVALID_HANDLE_VALUE)
return false;
@ -60,7 +60,7 @@ bool CalculateFileHash(const wchar_t *path, BYTE *hash)
for (;;) {
DWORD read = 0;
if (!ReadFile(handle, buf.data(), (DWORD)buf.size(), &read,
nullptr))
nullptr))
return false;
if (!read)

View file

@ -20,7 +20,7 @@
using namespace std;
#define MAX_BUF_SIZE 262144
#define MAX_BUF_SIZE 262144
#define READ_BUF_SIZE 32768
/* ------------------------------------------------------------------------ */
@ -36,8 +36,8 @@ public:
inflateEnd(&strm);
}
inline operator z_stream*() {return &strm;}
inline z_stream *operator->() {return &strm;}
inline operator z_stream *() { return &strm; }
inline z_stream *operator->() { return &strm; }
inline bool inflate()
{
@ -50,14 +50,15 @@ public:
/* ------------------------------------------------------------------------ */
static bool ReadZippedHTTPData(string &responseBuf, z_stream *strm,
string &zipBuf, const uint8_t *buffer, DWORD outSize)
string &zipBuf, const uint8_t *buffer,
DWORD outSize)
{
strm->avail_in = outSize;
strm->next_in = buffer;
strm->next_in = buffer;
do {
strm->avail_out = (uInt)zipBuf.size();
strm->next_out = (Bytef *)zipBuf.data();
strm->next_out = (Bytef *)zipBuf.data();
int zret = inflate(strm, Z_NO_FLUSH);
if (zret != Z_STREAM_END && zret != Z_OK)
@ -65,7 +66,7 @@ static bool ReadZippedHTTPData(string &responseBuf, z_stream *strm,
try {
responseBuf.append(zipBuf.data(),
zipBuf.size() - strm->avail_out);
zipBuf.size() - strm->avail_out);
} catch (...) {
return false;
}
@ -75,7 +76,7 @@ static bool ReadZippedHTTPData(string &responseBuf, z_stream *strm,
}
static bool ReadHTTPData(string &responseBuf, const uint8_t *buffer,
DWORD outSize)
DWORD outSize)
{
try {
responseBuf.append((const char *)buffer, outSize);
@ -85,19 +86,16 @@ static bool ReadHTTPData(string &responseBuf, const uint8_t *buffer,
return true;
}
bool HTTPPostData(const wchar_t *url,
const BYTE * data,
int dataLen,
const wchar_t *extraHeaders,
int * responseCode,
string & responseBuf)
bool HTTPPostData(const wchar_t *url, const BYTE *data, int dataLen,
const wchar_t *extraHeaders, int *responseCode,
string &responseBuf)
{
HttpHandle hSession;
HttpHandle hConnect;
HttpHandle hRequest;
string zipBuf;
HttpHandle hSession;
HttpHandle hConnect;
HttpHandle hRequest;
string zipBuf;
URL_COMPONENTS urlComponents = {};
bool secure = false;
bool secure = false;
wchar_t hostName[256];
wchar_t path[1024];
@ -113,10 +111,10 @@ bool HTTPPostData(const wchar_t *url,
urlComponents.dwStructSize = sizeof(urlComponents);
urlComponents.lpszHostName = hostName;
urlComponents.lpszHostName = hostName;
urlComponents.dwHostNameLength = _countof(hostName);
urlComponents.lpszUrlPath = path;
urlComponents.lpszUrlPath = path;
urlComponents.dwUrlPathLength = _countof(path);
WinHttpCrackUrl(url, 0, 0, &urlComponents);
@ -128,22 +126,21 @@ bool HTTPPostData(const wchar_t *url,
* connect to server */
hSession = WinHttpOpen(L"OBS Studio Updater/2.1",
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
WINHTTP_NO_PROXY_NAME,
WINHTTP_NO_PROXY_BYPASS,
0);
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS,
0);
if (!hSession) {
*responseCode = -1;
return false;
}
WinHttpSetOption(hSession, WINHTTP_OPTION_SECURE_PROTOCOLS,
(LPVOID)&tlsProtocols, sizeof(tlsProtocols));
(LPVOID)&tlsProtocols, sizeof(tlsProtocols));
hConnect = WinHttpConnect(hSession, hostName,
secure
? INTERNET_DEFAULT_HTTPS_PORT
: INTERNET_DEFAULT_HTTP_PORT, 0);
secure ? INTERNET_DEFAULT_HTTPS_PORT
: INTERNET_DEFAULT_HTTP_PORT,
0);
if (!hConnect) {
*responseCode = -2;
return false;
@ -152,24 +149,19 @@ bool HTTPPostData(const wchar_t *url,
/* -------------------------------------- *
* request data */
hRequest = WinHttpOpenRequest(hConnect,
L"POST",
path,
nullptr,
WINHTTP_NO_REFERER,
acceptTypes,
secure
? WINHTTP_FLAG_SECURE |
WINHTTP_FLAG_REFRESH
: WINHTTP_FLAG_REFRESH);
hRequest = WinHttpOpenRequest(hConnect, L"POST", path, nullptr,
WINHTTP_NO_REFERER, acceptTypes,
secure ? WINHTTP_FLAG_SECURE |
WINHTTP_FLAG_REFRESH
: WINHTTP_FLAG_REFRESH);
if (!hRequest) {
*responseCode = -3;
return false;
}
bool bResults = !!WinHttpSendRequest(hRequest, extraHeaders,
extraHeaders ? -1 : 0,
(void *)data, dataLen, dataLen, 0);
extraHeaders ? -1 : 0,
(void *)data, dataLen, dataLen, 0);
/* -------------------------------------- *
* end request */
@ -185,18 +177,15 @@ bool HTTPPostData(const wchar_t *url,
* get headers */
wchar_t encoding[64];
DWORD encodingLen;
DWORD encodingLen;
wchar_t statusCode[8];
DWORD statusCodeLen;
DWORD statusCodeLen;
statusCodeLen = sizeof(statusCode);
if (!WinHttpQueryHeaders(hRequest,
WINHTTP_QUERY_STATUS_CODE,
WINHTTP_HEADER_NAME_BY_INDEX,
&statusCode,
&statusCodeLen,
WINHTTP_NO_HEADER_INDEX)) {
if (!WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_STATUS_CODE,
WINHTTP_HEADER_NAME_BY_INDEX, &statusCode,
&statusCodeLen, WINHTTP_NO_HEADER_INDEX)) {
*responseCode = -4;
return false;
} else {
@ -204,12 +193,9 @@ bool HTTPPostData(const wchar_t *url,
}
encodingLen = sizeof(encoding);
if (!WinHttpQueryHeaders(hRequest,
WINHTTP_QUERY_CONTENT_ENCODING,
WINHTTP_HEADER_NAME_BY_INDEX,
encoding,
&encodingLen,
WINHTTP_NO_HEADER_INDEX)) {
if (!WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_CONTENT_ENCODING,
WINHTTP_HEADER_NAME_BY_INDEX, encoding,
&encodingLen, WINHTTP_NO_HEADER_INDEX)) {
encoding[0] = 0;
if (GetLastError() != ERROR_WINHTTP_HEADER_NOT_FOUND) {
*responseCode = -5;
@ -238,11 +224,11 @@ bool HTTPPostData(const wchar_t *url,
bool gzip = wcscmp(encoding, L"gzip") == 0;
if (gzip) {
strm->zalloc = Z_NULL;
strm->zfree = Z_NULL;
strm->opaque = Z_NULL;
strm->zalloc = Z_NULL;
strm->zfree = Z_NULL;
strm->opaque = Z_NULL;
strm->avail_in = 0;
strm->next_in = Z_NULL;
strm->next_in = Z_NULL;
if (!strm.inflate())
return false;
@ -278,7 +264,7 @@ bool HTTPPostData(const wchar_t *url,
dwSize = std::min(dwSize, (DWORD)sizeof(buffer));
if (!WinHttpReadData(hRequest, (void *)buffer, dwSize,
&outSize)) {
&outSize)) {
*responseCode = -9;
return false;
}
@ -311,25 +297,23 @@ bool HTTPPostData(const wchar_t *url,
/* ------------------------------------------------------------------------ */
static bool ReadHTTPZippedFile(z_stream *strm, HANDLE updateFile,
string &zipBuf, const uint8_t *buffer, DWORD outSize,
int *responseCode)
string &zipBuf, const uint8_t *buffer,
DWORD outSize, int *responseCode)
{
strm->avail_in = outSize;
strm->next_in = buffer;
strm->next_in = buffer;
do {
strm->avail_out = (uInt)zipBuf.size();
strm->next_out = (Bytef *)zipBuf.data();
strm->next_out = (Bytef *)zipBuf.data();
int zret = inflate(strm, Z_NO_FLUSH);
if (zret != Z_STREAM_END && zret != Z_OK)
return false;
DWORD written;
if (!WriteFile(updateFile,
zipBuf.data(),
MAX_BUF_SIZE - strm->avail_out,
&written,
if (!WriteFile(updateFile, zipBuf.data(),
MAX_BUF_SIZE - strm->avail_out, &written,
nullptr)) {
*responseCode = -10;
return false;
@ -346,7 +330,7 @@ static bool ReadHTTPZippedFile(z_stream *strm, HANDLE updateFile,
}
static bool ReadHTTPFile(HANDLE updateFile, const uint8_t *buffer,
DWORD outSize, int *responseCode)
DWORD outSize, int *responseCode)
{
DWORD written;
if (!WriteFile(updateFile, buffer, outSize, &written, nullptr)) {
@ -363,20 +347,18 @@ static bool ReadHTTPFile(HANDLE updateFile, const uint8_t *buffer,
return true;
}
bool HTTPGetFile(HINTERNET hConnect,
const wchar_t *url,
const wchar_t *outputPath,
const wchar_t *extraHeaders,
int * responseCode)
bool HTTPGetFile(HINTERNET hConnect, const wchar_t *url,
const wchar_t *outputPath, const wchar_t *extraHeaders,
int *responseCode)
{
HttpHandle hRequest;
const wchar_t *acceptTypes[] = {L"*/*", nullptr};
URL_COMPONENTS urlComponents = {};
bool secure = false;
bool secure = false;
string zipBuf;
string zipBuf;
wchar_t hostName[256];
wchar_t path[1024];
@ -385,10 +367,10 @@ bool HTTPGetFile(HINTERNET hConnect,
urlComponents.dwStructSize = sizeof(urlComponents);
urlComponents.lpszHostName = hostName;
urlComponents.lpszHostName = hostName;
urlComponents.dwHostNameLength = _countof(hostName);
urlComponents.lpszUrlPath = path;
urlComponents.lpszUrlPath = path;
urlComponents.dwUrlPathLength = _countof(path);
WinHttpCrackUrl(url, 0, 0, &urlComponents);
@ -399,23 +381,19 @@ bool HTTPGetFile(HINTERNET hConnect,
/* -------------------------------------- *
* request data */
hRequest = WinHttpOpenRequest(hConnect,
L"GET",
path,
nullptr,
WINHTTP_NO_REFERER,
acceptTypes,
secure
? WINHTTP_FLAG_SECURE |
WINHTTP_FLAG_REFRESH
: WINHTTP_FLAG_REFRESH);
hRequest = WinHttpOpenRequest(hConnect, L"GET", path, nullptr,
WINHTTP_NO_REFERER, acceptTypes,
secure ? WINHTTP_FLAG_SECURE |
WINHTTP_FLAG_REFRESH
: WINHTTP_FLAG_REFRESH);
if (!hRequest) {
*responseCode = -3;
return false;
}
bool bResults = !!WinHttpSendRequest(hRequest, extraHeaders,
extraHeaders ? -1 : 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0);
extraHeaders ? -1 : 0,
WINHTTP_NO_REQUEST_DATA, 0, 0, 0);
/* -------------------------------------- *
* end request */
@ -431,18 +409,15 @@ bool HTTPGetFile(HINTERNET hConnect,
* get headers */
wchar_t encoding[64];
DWORD encodingLen;
DWORD encodingLen;
wchar_t statusCode[8];
DWORD statusCodeLen;
DWORD statusCodeLen;
statusCodeLen = sizeof(statusCode);
if (!WinHttpQueryHeaders(hRequest,
WINHTTP_QUERY_STATUS_CODE,
WINHTTP_HEADER_NAME_BY_INDEX,
&statusCode,
&statusCodeLen,
WINHTTP_NO_HEADER_INDEX)) {
if (!WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_STATUS_CODE,
WINHTTP_HEADER_NAME_BY_INDEX, &statusCode,
&statusCodeLen, WINHTTP_NO_HEADER_INDEX)) {
*responseCode = -4;
return false;
} else {
@ -450,12 +425,9 @@ bool HTTPGetFile(HINTERNET hConnect,
}
encodingLen = sizeof(encoding);
if (!WinHttpQueryHeaders(hRequest,
WINHTTP_QUERY_CONTENT_ENCODING,
WINHTTP_HEADER_NAME_BY_INDEX,
encoding,
&encodingLen,
WINHTTP_NO_HEADER_INDEX)) {
if (!WinHttpQueryHeaders(hRequest, WINHTTP_QUERY_CONTENT_ENCODING,
WINHTTP_HEADER_NAME_BY_INDEX, encoding,
&encodingLen, WINHTTP_NO_HEADER_INDEX)) {
encoding[0] = 0;
if (GetLastError() != ERROR_WINHTTP_HEADER_NOT_FOUND) {
*responseCode = -5;
@ -472,11 +444,11 @@ bool HTTPGetFile(HINTERNET hConnect,
bool gzip = wcscmp(encoding, L"gzip") == 0;
if (gzip) {
strm->zalloc = Z_NULL;
strm->zfree = Z_NULL;
strm->opaque = Z_NULL;
strm->zalloc = Z_NULL;
strm->zfree = Z_NULL;
strm->opaque = Z_NULL;
strm->avail_in = 0;
strm->next_in = Z_NULL;
strm->next_in = Z_NULL;
if (!strm.inflate())
return false;
@ -498,12 +470,12 @@ bool HTTPGetFile(HINTERNET hConnect,
if (!bResults || *responseCode != 200)
return true;
BYTE buffer[READ_BUF_SIZE];
BYTE buffer[READ_BUF_SIZE];
DWORD dwSize, outSize;
int lastPosition = 0;
int lastPosition = 0;
WinHandle updateFile = CreateFile(outputPath, GENERIC_WRITE, 0,
nullptr, CREATE_ALWAYS, 0, nullptr);
WinHandle updateFile = CreateFile(outputPath, GENERIC_WRITE, 0, nullptr,
CREATE_ALWAYS, 0, nullptr);
if (!updateFile.Valid()) {
*responseCode = -7;
return false;
@ -520,7 +492,7 @@ bool HTTPGetFile(HINTERNET hConnect,
dwSize = std::min(dwSize, (DWORD)sizeof(buffer));
if (!WinHttpReadData(hRequest, (void *)buffer, dwSize,
&outSize)) {
&outSize)) {
*responseCode = -9;
return false;
} else {
@ -529,21 +501,22 @@ bool HTTPGetFile(HINTERNET hConnect,
if (gzip) {
if (!ReadHTTPZippedFile(strm, updateFile,
zipBuf, buffer,
outSize, responseCode))
zipBuf, buffer, outSize,
responseCode))
return false;
} else {
if (!ReadHTTPFile(updateFile, buffer,
outSize, responseCode))
if (!ReadHTTPFile(updateFile, buffer, outSize,
responseCode))
return false;
}
int position = (int)(((float)completedFileSize /
(float)totalFileSize) * 100.0f);
(float)totalFileSize) *
100.0f);
if (position > lastPosition) {
lastPosition = position;
SendDlgItemMessage(hwndMain, IDC_PROGRESS,
PBM_SETPOS, position, 0);
PBM_SETPOS, position, 0);
}
}

View file

@ -20,16 +20,16 @@
#include <vector>
#ifdef _MSC_VER
# define restrict __restrict
# include <lzma.h>
# undef restrict
#define restrict __restrict
#include <lzma.h>
#undef restrict
#else
# include <lzma.h>
#include <lzma.h>
#endif
using namespace std;
#define MAX_BUF_SIZE 262144
#define MAX_BUF_SIZE 262144
#define READ_BUF_SIZE 32768
/* ------------------------------------------------------------------------ */
@ -48,10 +48,7 @@ public:
inline bool init_decoder()
{
lzma_ret ret = lzma_stream_decoder(
&strm,
200 * 1024 * 1024,
0);
lzma_ret ret = lzma_stream_decoder(&strm, 200 * 1024 * 1024, 0);
initialized = (ret == LZMA_OK);
return initialized;
}
@ -82,7 +79,7 @@ public:
struct bspatch_stream {
void *opaque;
int (*read)(const struct bspatch_stream *stream, void *buffer,
int length);
int length);
};
/* ------------------------------------------------------------------------ */
@ -116,7 +113,7 @@ static int64_t offtin(const uint8_t *buf)
/* ------------------------------------------------------------------------ */
static int bspatch(const uint8_t *old, int64_t oldsize, uint8_t *newp,
int64_t newsize, struct bspatch_stream *stream)
int64_t newsize, struct bspatch_stream *stream)
{
uint8_t buf[8];
int64_t oldpos, newpos;
@ -169,9 +166,9 @@ static int bspatch(const uint8_t *old, int64_t oldsize, uint8_t *newp,
/* ------------------------------------------------------------------------ */
struct patch_data {
HANDLE h;
lzma_stream *strm;
uint8_t buf[READ_BUF_SIZE];
HANDLE h;
lzma_stream *strm;
uint8_t buf[READ_BUF_SIZE];
};
static int read_lzma(const struct bspatch_stream *stream, void *buffer, int len)
@ -179,24 +176,24 @@ static int read_lzma(const struct bspatch_stream *stream, void *buffer, int len)
if (!len)
return 0;
patch_data *data = (patch_data*)stream->opaque;
HANDLE h = data->h;
lzma_stream *strm = data->strm;
patch_data *data = (patch_data *)stream->opaque;
HANDLE h = data->h;
lzma_stream *strm = data->strm;
strm->avail_out = (size_t)len;
strm->next_out = (uint8_t *)buffer;
strm->next_out = (uint8_t *)buffer;
for (;;) {
if (strm->avail_in == 0) {
DWORD read_size;
if (!ReadFile(h, data->buf, READ_BUF_SIZE, &read_size,
nullptr))
nullptr))
return -1;
if (read_size == 0)
return -1;
strm->avail_in = (size_t)read_size;
strm->next_in = data->buf;
strm->next_in = data->buf;
}
lzma_ret ret = lzma_code(strm, LZMA_RUN);
@ -213,25 +210,25 @@ static int read_lzma(const struct bspatch_stream *stream, void *buffer, int len)
int ApplyPatch(const wchar_t *patchFile, const wchar_t *targetFile)
try {
uint8_t header[24];
int64_t newsize;
uint8_t header[24];
int64_t newsize;
struct bspatch_stream stream;
bool success;
bool success;
WinHandle hPatch;
WinHandle hTarget;
WinHandle hPatch;
WinHandle hTarget;
LZMAStream strm;
/* --------------------------------- *
* open patch and file to patch */
hPatch = CreateFile(patchFile, GENERIC_READ, 0, nullptr,
OPEN_EXISTING, 0, nullptr);
hPatch = CreateFile(patchFile, GENERIC_READ, 0, nullptr, OPEN_EXISTING,
0, nullptr);
if (!hPatch.Valid())
throw int(GetLastError());
hTarget = CreateFile(targetFile, GENERIC_READ, 0, nullptr,
OPEN_EXISTING, 0, nullptr);
OPEN_EXISTING, 0, nullptr);
if (!hTarget.Valid())
throw int(GetLastError());
@ -289,14 +286,14 @@ try {
throw int(-10);
patch_data data;
data.h = hPatch;
data.h = hPatch;
data.strm = strm.get();
stream.read = read_lzma;
stream.read = read_lzma;
stream.opaque = &data;
int ret = bspatch(oldData.data(), oldData.size(), newData.data(),
newData.size(), &stream);
newData.size(), &stream);
if (ret != 0)
throw int(-9);
@ -305,14 +302,14 @@ try {
hTarget = nullptr;
hTarget = CreateFile(targetFile, GENERIC_WRITE, 0, nullptr,
CREATE_ALWAYS, 0, nullptr);
CREATE_ALWAYS, 0, nullptr);
if (!hTarget.Valid())
throw int(GetLastError());
DWORD written;
success = !!WriteFile(hTarget, newData.data(), (DWORD)newsize,
&written, nullptr);
success = !!WriteFile(hTarget, newData.data(), (DWORD)newsize, &written,
nullptr);
if (!success || written != newsize)
throw int(GetLastError());

View file

@ -2,20 +2,20 @@
// Microsoft Visual C++ generated include file.
// Used by updater.rc
//
#define IDD_UPDATEDIALOG 101
#define IDI_ICON1 103
#define IDC_PROGRESS 1001
#define IDC_STATUS 1002
#define IDCBUTTON 1004
#define IDC_BUTTON 1004
#define IDD_UPDATEDIALOG 101
#define IDI_ICON1 103
#define IDC_PROGRESS 1001
#define IDC_STATUS 1002
#define IDCBUTTON 1004
#define IDC_BUTTON 1004
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 104
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1005
#define _APS_NEXT_SYMED_VALUE 101
#define _APS_NEXT_RESOURCE_VALUE 104
#define _APS_NEXT_COMMAND_VALUE 40001
#define _APS_NEXT_CONTROL_VALUE 1005
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

File diff suppressed because it is too large Load diff

View file

@ -45,53 +45,44 @@
#define BLAKE2_HASH_STR_LENGTH ((BLAKE2_HASH_LENGTH * 2) + 1)
#if defined _M_IX86
#pragma comment(linker, \
"/manifestdependency:\"type='win32' " \
"name='Microsoft.Windows.Common-Controls' " \
"version='6.0.0.0' " \
"processorArchitecture='x86' " \
"publicKeyToken='6595b64144ccf1df' " \
"language='*'\"")
#pragma comment(linker, "/manifestdependency:\"type='win32' " \
"name='Microsoft.Windows.Common-Controls' " \
"version='6.0.0.0' " \
"processorArchitecture='x86' " \
"publicKeyToken='6595b64144ccf1df' " \
"language='*'\"")
#elif defined _M_IA64
#pragma comment(linker, \
"/manifestdependency:\"type='win32' " \
"name='Microsoft.Windows.Common-Controls' " \
"version='6.0.0.0' " \
"processorArchitecture='ia64' " \
"publicKeyToken='6595b64144ccf1df' " \
"language='*'\"")
#pragma comment(linker, "/manifestdependency:\"type='win32' " \
"name='Microsoft.Windows.Common-Controls' " \
"version='6.0.0.0' " \
"processorArchitecture='ia64' " \
"publicKeyToken='6595b64144ccf1df' " \
"language='*'\"")
#elif defined _M_X64
#pragma comment(linker, \
"/manifestdependency:\"type='win32' " \
"name='Microsoft.Windows.Common-Controls' " \
"version='6.0.0.0' " \
"processorArchitecture='amd64' " \
"publicKeyToken='6595b64144ccf1df' " \
"language='*'\"")
#pragma comment(linker, "/manifestdependency:\"type='win32' " \
"name='Microsoft.Windows.Common-Controls' " \
"version='6.0.0.0' " \
"processorArchitecture='amd64' " \
"publicKeyToken='6595b64144ccf1df' " \
"language='*'\"")
#else
#pragma comment(linker, \
"/manifestdependency:\"type='win32' " \
"name='Microsoft.Windows.Common-Controls' " \
"version='6.0.0.0' processorArchitecture='*' " \
"publicKeyToken='6595b64144ccf1df' " \
"language='*'\"")
#pragma comment(linker, "/manifestdependency:\"type='win32' " \
"name='Microsoft.Windows.Common-Controls' " \
"version='6.0.0.0' processorArchitecture='*' " \
"publicKeyToken='6595b64144ccf1df' " \
"language='*'\"")
#endif
#include <util/windows/WinHandle.hpp>
#include <jansson.h>
#include "resource.h"
bool HTTPGetFile(HINTERNET hConnect,
const wchar_t *url,
const wchar_t *outputPath,
const wchar_t *extraHeaders,
int * responseCode);
bool HTTPPostData(const wchar_t *url,
const BYTE * data,
int dataLen,
const wchar_t *extraHeaders,
int * responseCode,
std::string & response);
bool HTTPGetFile(HINTERNET hConnect, const wchar_t *url,
const wchar_t *outputPath, const wchar_t *extraHeaders,
int *responseCode);
bool HTTPPostData(const wchar_t *url, const BYTE *data, int dataLen,
const wchar_t *extraHeaders, int *responseCode,
std::string &response);
void HashToString(const BYTE *in, wchar_t *out);
void StringToHash(const wchar_t *in, BYTE *out);
@ -100,17 +91,17 @@ bool CalculateFileHash(const wchar_t *path, BYTE *hash);
int ApplyPatch(LPCTSTR patchFile, LPCTSTR targetFile);
extern HWND hwndMain;
extern HWND hwndMain;
extern HCRYPTPROV hProvider;
extern int totalFileSize;
extern int completedFileSize;
extern HANDLE cancelRequested;
extern int totalFileSize;
extern int completedFileSize;
extern HANDLE cancelRequested;
#pragma pack(push, r1, 1)
typedef struct {
BLOBHEADER blobheader;
RSAPUBKEY rsapubkey;
RSAPUBKEY rsapubkey;
} PUBLICKEYHEADER;
#pragma pack(pop, r1)

View file

@ -23,9 +23,9 @@ public:
freefunc(handle);
}
inline T *operator&() {return &handle;}
inline operator T() const {return handle;}
inline T get() const {return handle;}
inline T *operator&() { return &handle; }
inline operator T() const { return handle; }
inline T get() const { return handle; }
inline CustomHandle<T, freefunc> &operator=(T in)
{
@ -35,7 +35,7 @@ public:
return *this;
}
inline bool operator!() const {return !handle;}
inline bool operator!() const { return !handle; }
};
void FreeProvider(HCRYPTPROV prov);
@ -43,8 +43,8 @@ void FreeHash(HCRYPTHASH hash);
void FreeKey(HCRYPTKEY key);
using CryptProvider = CustomHandle<HCRYPTPROV, FreeProvider>;
using CryptHash = CustomHandle<HCRYPTHASH, FreeHash>;
using CryptKey = CustomHandle<HCRYPTKEY, FreeKey>;
using CryptHash = CustomHandle<HCRYPTHASH, FreeHash>;
using CryptKey = CustomHandle<HCRYPTKEY, FreeKey>;
/* ------------------------------------------------------------------------ */
@ -58,13 +58,13 @@ public:
LocalFree(ptr);
}
inline T **operator&() {return &ptr;}
inline operator T() const {return ptr;}
inline T *get() const {return ptr;}
inline T **operator&() { return &ptr; }
inline operator T() const { return ptr; }
inline T *get() const { return ptr; }
inline bool operator!() const {return !ptr;}
inline bool operator!() const { return !ptr; }
inline T *operator->() {return ptr;}
inline T *operator->() { return ptr; }
};
/* ------------------------------------------------------------------------ */
@ -76,9 +76,10 @@ public:
inline Json() : json(nullptr) {}
explicit inline Json(json_t *json_) : json(json_) {}
inline Json(const Json &from) : json(json_incref(from.json)) {}
inline Json(Json &&from) : json(from.json) {from.json = nullptr;}
inline Json(Json &&from) : json(from.json) { from.json = nullptr; }
inline ~Json() {
inline ~Json()
{
if (json)
json_decref(json);
}
@ -106,12 +107,12 @@ public:
return *this;
}
inline operator json_t *() const {return json;}
inline operator json_t *() const { return json; }
inline bool operator!() const {return !json;}
inline bool operator!() const { return !json; }
inline const char *GetString(const char *name,
const char *def = nullptr) const
const char *def = nullptr) const
{
json_t *obj(json_object_get(json, name));
if (!obj)
@ -130,7 +131,7 @@ public:
return json_object_get(json, name);
}
inline json_t *get() const {return json;}
inline json_t *get() const { return json; }
};
/* ------------------------------------------------------------------------ */

View file

@ -42,7 +42,7 @@ static __declspec(thread) HCRYPTPROV provider = 0;
typedef struct {
BLOBHEADER blobheader;
RSAPUBKEY rsapubkey;
RSAPUBKEY rsapubkey;
} PUBLICKEYHEADER;
#pragma pack(pop, r1)
@ -120,8 +120,7 @@ static const unsigned char obs_pub[] = {
0x42, 0x61, 0x35, 0x66, 0x37, 0x4c, 0x6f, 0x4b, 0x38, 0x43, 0x41, 0x77,
0x45, 0x41, 0x41, 0x51, 0x3d, 0x3d, 0x0a, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d,
0x45, 0x4e, 0x44, 0x20, 0x50, 0x55, 0x42, 0x4c, 0x49, 0x43, 0x20, 0x4b,
0x45, 0x59, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a
};
0x45, 0x59, 0x2d, 0x2d, 0x2d, 0x2d, 0x2d, 0x0a};
static const unsigned int obs_pub_len = 800;
/* ------------------------------------------------------------------------ */
@ -132,23 +131,18 @@ try {
if (os_utf8_to_wcs_ptr(file, 0, &w_file) == 0)
return false;
WinHandle handle = CreateFileW(
w_file,
GENERIC_WRITE,
0,
nullptr,
CREATE_ALWAYS,
FILE_FLAG_WRITE_THROUGH,
nullptr);
WinHandle handle = CreateFileW(w_file, GENERIC_WRITE, 0, nullptr,
CREATE_ALWAYS, FILE_FLAG_WRITE_THROUGH,
nullptr);
if (handle == INVALID_HANDLE_VALUE)
throw strprintf("Failed to open file '%s': %lu",
file, GetLastError());
throw strprintf("Failed to open file '%s': %lu", file,
GetLastError());
DWORD written;
if (!WriteFile(handle, data, (DWORD)size, &written, nullptr))
throw strprintf("Failed to write file '%s': %lu",
file, GetLastError());
throw strprintf("Failed to write file '%s': %lu", file,
GetLastError());
return true;
@ -163,26 +157,20 @@ try {
if (os_utf8_to_wcs_ptr(file, 0, &w_file) == 0)
return false;
WinHandle handle = CreateFileW(
w_file,
GENERIC_READ,
FILE_SHARE_READ,
nullptr,
OPEN_EXISTING,
0,
nullptr);
WinHandle handle = CreateFileW(w_file, GENERIC_READ, FILE_SHARE_READ,
nullptr, OPEN_EXISTING, 0, nullptr);
if (handle == INVALID_HANDLE_VALUE)
throw strprintf("Failed to open file '%s': %lu",
file, GetLastError());
throw strprintf("Failed to open file '%s': %lu", file,
GetLastError());
DWORD size = GetFileSize(handle, nullptr);
data.resize(size);
DWORD read;
if (!ReadFile(handle, &data[0], size, &read, nullptr))
throw strprintf("Failed to write file '%s': %lu",
file, GetLastError());
throw strprintf("Failed to write file '%s': %lu", file,
GetLastError());
return true;
@ -196,7 +184,7 @@ static void HashToString(const uint8_t *in, char *out)
const char alphabet[] = "0123456789abcdef";
for (int i = 0; i != BLAKE2_HASH_LENGTH; ++i) {
out[2 * i] = alphabet[in[i] / 16];
out[2 * i] = alphabet[in[i] / 16];
out[2 * i + 1] = alphabet[in[i] % 16];
}
@ -214,10 +202,10 @@ try {
return false;
WinHandle handle = CreateFileW(w_path, GENERIC_READ, FILE_SHARE_READ,
nullptr, OPEN_EXISTING, 0, nullptr);
nullptr, OPEN_EXISTING, 0, nullptr);
if (handle == INVALID_HANDLE_VALUE)
throw strprintf("Failed to open file '%s': %lu",
path, GetLastError());
throw strprintf("Failed to open file '%s': %lu", path,
GetLastError());
vector<BYTE> buf;
buf.resize(65536);
@ -225,9 +213,9 @@ try {
for (;;) {
DWORD read = 0;
if (!ReadFile(handle, buf.data(), (DWORD)buf.size(), &read,
nullptr))
throw strprintf("Failed to read file '%s': %lu",
path, GetLastError());
nullptr))
throw strprintf("Failed to read file '%s': %lu", path,
GetLastError());
if (!read)
break;
@ -249,19 +237,19 @@ try {
/* ------------------------------------------------------------------------ */
static bool VerifyDigitalSignature(uint8_t *buf, size_t len, uint8_t *sig,
size_t sigLen)
size_t sigLen)
{
/* ASN of PEM public key */
BYTE binaryKey[1024];
BYTE binaryKey[1024];
DWORD binaryKeyLen = sizeof(binaryKey);
/* Windows X509 public key info from ASN */
LocalPtr<CERT_PUBLIC_KEY_INFO> publicPBLOB;
DWORD iPBLOBSize;
DWORD iPBLOBSize;
/* RSA BLOB info from X509 public key */
LocalPtr<PUBLICKEYHEADER> rsaPublicBLOB;
DWORD rsaPublicBLOBSize;
DWORD rsaPublicBLOBSize;
/* Handle to public key */
CryptKey keyOut;
@ -272,41 +260,26 @@ static bool VerifyDigitalSignature(uint8_t *buf, size_t len, uint8_t *sig,
/* Signature in little-endian format */
vector<BYTE> reversedSig;
if (!CryptStringToBinaryA((LPCSTR)obs_pub,
obs_pub_len,
CRYPT_STRING_BASE64HEADER,
binaryKey,
&binaryKeyLen,
nullptr,
nullptr))
if (!CryptStringToBinaryA((LPCSTR)obs_pub, obs_pub_len,
CRYPT_STRING_BASE64HEADER, binaryKey,
&binaryKeyLen, nullptr, nullptr))
return false;
if (!CryptDecodeObjectEx(X509_ASN_ENCODING,
X509_PUBLIC_KEY_INFO,
binaryKey,
binaryKeyLen,
CRYPT_ENCODE_ALLOC_FLAG,
nullptr,
&publicPBLOB,
&iPBLOBSize))
if (!CryptDecodeObjectEx(X509_ASN_ENCODING, X509_PUBLIC_KEY_INFO,
binaryKey, binaryKeyLen,
CRYPT_ENCODE_ALLOC_FLAG, nullptr, &publicPBLOB,
&iPBLOBSize))
return false;
if (!CryptDecodeObjectEx(X509_ASN_ENCODING,
RSA_CSP_PUBLICKEYBLOB,
publicPBLOB->PublicKey.pbData,
publicPBLOB->PublicKey.cbData,
CRYPT_ENCODE_ALLOC_FLAG,
nullptr,
&rsaPublicBLOB,
&rsaPublicBLOBSize))
if (!CryptDecodeObjectEx(X509_ASN_ENCODING, RSA_CSP_PUBLICKEYBLOB,
publicPBLOB->PublicKey.pbData,
publicPBLOB->PublicKey.cbData,
CRYPT_ENCODE_ALLOC_FLAG, nullptr,
&rsaPublicBLOB, &rsaPublicBLOBSize))
return false;
if (!CryptImportKey(provider,
(const BYTE *)rsaPublicBLOB.get(),
rsaPublicBLOBSize,
0,
0,
&keyOut))
if (!CryptImportKey(provider, (const BYTE *)rsaPublicBLOB.get(),
rsaPublicBLOBSize, 0, 0, &keyOut))
return false;
if (!CryptCreateHash(provider, CALG_SHA_512, 0, 0, &hash))
@ -321,19 +294,15 @@ static bool VerifyDigitalSignature(uint8_t *buf, size_t len, uint8_t *sig,
for (size_t i = 0; i < sigLen; i++)
reversedSig[i] = sig[sigLen - i - 1];
if (!CryptVerifySignature(hash,
reversedSig.data(),
(DWORD)sigLen,
keyOut,
nullptr,
0))
if (!CryptVerifySignature(hash, reversedSig.data(), (DWORD)sigLen,
keyOut, nullptr, 0))
return false;
return true;
}
static inline void HexToByteArray(const char *hexStr, size_t hexLen,
vector<uint8_t> &out)
vector<uint8_t> &out)
{
char ptr[3];
@ -347,7 +316,7 @@ static inline void HexToByteArray(const char *hexStr, size_t hexLen,
}
static bool CheckDataSignature(const string &data, const char *name,
const char *hexSig, size_t sigLen)
const char *hexSig, size_t sigLen)
try {
if (sigLen == 0 || sigLen > 0xFFFF || (sigLen & 1) != 0)
throw strprintf("Missing or invalid signature for %s", name);
@ -357,10 +326,8 @@ try {
signature.reserve(sigLen);
HexToByteArray(hexSig, sigLen, signature);
if (!VerifyDigitalSignature((uint8_t*)data.data(),
data.size(),
signature.data(),
signature.size()))
if (!VerifyDigitalSignature((uint8_t *)data.data(), data.size(),
signature.data(), signature.size()))
throw strprintf("Signature check failed for %s", name);
return true;
@ -374,12 +341,12 @@ try {
static bool FetchUpdaterModule(const char *url)
try {
long responseCode;
uint8_t updateFileHash[BLAKE2_HASH_LENGTH];
long responseCode;
uint8_t updateFileHash[BLAKE2_HASH_LENGTH];
vector<string> extraHeaders;
BPtr<char> updateFilePath = GetConfigPathPtr(
"obs-studio\\updates\\updater.exe");
BPtr<char> updateFilePath =
GetConfigPathPtr("obs-studio\\updates\\updater.exe");
if (CalculateFileHash(updateFilePath, updateFileHash)) {
char hashString[BLAKE2_HASH_STR_LENGTH];
@ -394,8 +361,8 @@ try {
string error;
string data;
bool success = GetRemoteFile(url, data, error, &responseCode,
nullptr, nullptr, extraHeaders, &signature);
bool success = GetRemoteFile(url, data, error, &responseCode, nullptr,
nullptr, extraHeaders, &signature);
if (!success || (responseCode != 200 && responseCode != 304)) {
if (responseCode == 404)
@ -407,7 +374,7 @@ try {
/* A new file must be digitally signed */
if (responseCode == 200) {
bool valid = CheckDataSignature(data, url, signature.data(),
signature.size());
signature.size());
if (!valid)
throw string("Invalid updater module signature");
@ -425,7 +392,7 @@ try {
/* ------------------------------------------------------------------------ */
static bool ParseUpdateManifest(const char *manifest, bool *updatesAvailable,
string &notes_str, int &updateVer)
string &notes_str, int &updateVer)
try {
json_error_t error;
@ -442,10 +409,8 @@ try {
int patch = root.GetInt("version_patch");
if (major == 0)
throw strprintf("Invalid version number: %d.%d.%d",
major,
minor,
patch);
throw strprintf("Invalid version number: %d.%d.%d", major,
minor, patch);
json_t *notes = json_object_get(root, "notes");
if (!json_is_string(notes))
@ -491,8 +456,8 @@ string GetProgramGUID()
/* NOTE: this is an arbitrary random number that we use to count the
* number of unique OBS installations and is not associated with any
* kind of identifiable information */
const char *pguid = config_get_string(GetGlobalConfig(),
"General", "InstallGUID");
const char *pguid =
config_get_string(GetGlobalConfig(), "General", "InstallGUID");
string guid;
if (pguid)
guid = pguid;
@ -501,9 +466,8 @@ string GetProgramGUID()
GenerateGUID(guid);
if (!guid.empty())
config_set_string(GetGlobalConfig(),
"General", "InstallGUID",
guid.c_str());
config_set_string(GetGlobalConfig(), "General",
"InstallGUID", guid.c_str());
}
return guid;
@ -516,13 +480,12 @@ void AutoUpdateThread::infoMsg(const QString &title, const QString &text)
void AutoUpdateThread::info(const QString &title, const QString &text)
{
QMetaObject::invokeMethod(this, "infoMsg",
Qt::BlockingQueuedConnection,
Q_ARG(QString, title),
Q_ARG(QString, text));
QMetaObject::invokeMethod(this, "infoMsg", Qt::BlockingQueuedConnection,
Q_ARG(QString, title), Q_ARG(QString, text));
}
int AutoUpdateThread::queryUpdateSlot(bool localManualUpdate, const QString &text)
int AutoUpdateThread::queryUpdateSlot(bool localManualUpdate,
const QString &text)
{
OBSUpdate updateDlg(App()->GetMainWindow(), localManualUpdate, text);
return updateDlg.exec();
@ -533,17 +496,17 @@ int AutoUpdateThread::queryUpdate(bool localManualUpdate, const char *text_utf8)
int ret = OBSUpdate::No;
QString text = text_utf8;
QMetaObject::invokeMethod(this, "queryUpdateSlot",
Qt::BlockingQueuedConnection,
Q_RETURN_ARG(int, ret),
Q_ARG(bool, localManualUpdate),
Q_ARG(QString, text));
Qt::BlockingQueuedConnection,
Q_RETURN_ARG(int, ret),
Q_ARG(bool, localManualUpdate),
Q_ARG(QString, text));
return ret;
}
static bool IsFileInUse(const wstring &file)
{
WinHandle f = CreateFile(file.c_str(), GENERIC_WRITE, 0, nullptr,
OPEN_EXISTING, 0, nullptr);
OPEN_EXISTING, 0, nullptr);
if (!f.Valid()) {
int err = GetLastError();
if (err == ERROR_SHARING_VIOLATION ||
@ -557,35 +520,33 @@ static bool IsFileInUse(const wstring &file)
static bool IsGameCaptureInUse()
{
wstring path = L"..\\..\\data\\obs-plugins\\win-capture\\graphics-hook";
return IsFileInUse(path + L"32.dll") ||
IsFileInUse(path + L"64.dll");
return IsFileInUse(path + L"32.dll") || IsFileInUse(path + L"64.dll");
}
void AutoUpdateThread::run()
try {
long responseCode;
long responseCode;
vector<string> extraHeaders;
string text;
string error;
string signature;
CryptProvider localProvider;
BYTE manifestHash[BLAKE2_HASH_LENGTH];
bool updatesAvailable = false;
bool success;
string text;
string error;
string signature;
CryptProvider localProvider;
BYTE manifestHash[BLAKE2_HASH_LENGTH];
bool updatesAvailable = false;
bool success;
struct FinishedTrigger {
inline ~FinishedTrigger()
{
QMetaObject::invokeMethod(App()->GetMainWindow(),
"updateCheckFinished");
"updateCheckFinished");
}
} finishedTrigger;
BPtr<char> manifestPath = GetConfigPathPtr(
"obs-studio\\updates\\manifest.json");
BPtr<char> manifestPath =
GetConfigPathPtr("obs-studio\\updates\\manifest.json");
auto ActiveOrGameCaptureLocked = [this] ()
{
auto ActiveOrGameCaptureLocked = [this]() {
if (obs_video_active()) {
if (manualUpdate)
info(QTStr("Updater.Running.Title"),
@ -611,11 +572,8 @@ try {
/* ----------------------------------- *
* create signature provider */
if (!CryptAcquireContext(&localProvider,
nullptr,
MS_ENH_RSA_AES_PROV,
PROV_RSA_AES,
CRYPT_VERIFYCONTEXT))
if (!CryptAcquireContext(&localProvider, nullptr, MS_ENH_RSA_AES_PROV,
PROV_RSA_AES, CRYPT_VERIFYCONTEXT))
throw strprintf("CryptAcquireContext failed: %lu",
GetLastError());
@ -647,13 +605,14 @@ try {
* get manifest from server */
success = GetRemoteFile(WIN_MANIFEST_URL, text, error, &responseCode,
nullptr, nullptr, extraHeaders, &signature);
nullptr, nullptr, extraHeaders, &signature);
if (!success || (responseCode != 200 && responseCode != 304)) {
if (responseCode == 404)
return;
throw strprintf("Failed to fetch manifest file: %s", error.c_str());
throw strprintf("Failed to fetch manifest file: %s",
error.c_str());
}
/* ----------------------------------- *
@ -661,8 +620,8 @@ try {
/* a new file must be digitally signed */
if (responseCode == 200) {
success = CheckDataSignature(text, "manifest",
signature.data(), signature.size());
success = CheckDataSignature(text, "manifest", signature.data(),
signature.size());
if (!success)
throw string("Invalid manifest signature");
}
@ -687,7 +646,7 @@ try {
int updateVer = 0;
success = ParseUpdateManifest(text.c_str(), &updatesAvailable, notes,
updateVer);
updateVer);
if (!success)
throw string("Failed to parse manifest");
@ -702,7 +661,7 @@ try {
* skip this version if set to skip */
int skipUpdateVer = config_get_int(GetGlobalConfig(), "General",
"SkipUpdateVersion");
"SkipUpdateVersion");
if (!manualUpdate && updateVer == skipUpdateVer)
return;
@ -727,13 +686,13 @@ try {
if (!manualUpdate) {
long long t = (long long)time(nullptr);
config_set_int(GetGlobalConfig(), "General",
"LastUpdateCheck", t);
"LastUpdateCheck", t);
}
return;
} else if (queryResult == OBSUpdate::Skip) {
config_set_int(GetGlobalConfig(), "General",
"SkipUpdateVersion", updateVer);
"SkipUpdateVersion", updateVer);
return;
}
@ -749,8 +708,8 @@ try {
/* ----------------------------------- *
* execute updater */
BPtr<char> updateFilePath = GetConfigPathPtr(
"obs-studio\\updates\\updater.exe");
BPtr<char> updateFilePath =
GetConfigPathPtr("obs-studio\\updates\\updater.exe");
BPtr<wchar_t> wUpdateFilePath;
size_t size = os_utf8_to_wcs_ptr(updateFilePath, 0, &wUpdateFilePath);
@ -773,7 +732,7 @@ try {
execInfo.lpParameters = UPDATE_ARG_SUFFIX;
execInfo.lpDirectory = cwd;
execInfo.nShow = SW_SHOWNORMAL;
execInfo.nShow = SW_SHOWNORMAL;
if (!ShellExecuteEx(&execInfo)) {
QString msg = QTStr("Updater.FailedToLaunch");
@ -787,7 +746,7 @@ try {
config_set_int(GetGlobalConfig(), "General", "LastUpdateCheck", 0);
config_set_int(GetGlobalConfig(), "General", "SkipUpdateVersion", 0);
config_set_string(GetGlobalConfig(), "General", "InstallGUID",
guid.c_str());
guid.c_str());
QMetaObject::invokeMethod(App()->GetMainWindow(), "close");
@ -799,26 +758,23 @@ try {
void WhatsNewInfoThread::run()
try {
long responseCode;
long responseCode;
vector<string> extraHeaders;
string text;
string error;
string signature;
CryptProvider localProvider;
BYTE whatsnewHash[BLAKE2_HASH_LENGTH];
bool success;
string text;
string error;
string signature;
CryptProvider localProvider;
BYTE whatsnewHash[BLAKE2_HASH_LENGTH];
bool success;
BPtr<char> whatsnewPath = GetConfigPathPtr(
"obs-studio\\updates\\whatsnew.json");
BPtr<char> whatsnewPath =
GetConfigPathPtr("obs-studio\\updates\\whatsnew.json");
/* ----------------------------------- *
* create signature provider */
if (!CryptAcquireContext(&localProvider,
nullptr,
MS_ENH_RSA_AES_PROV,
PROV_RSA_AES,
CRYPT_VERIFYCONTEXT))
if (!CryptAcquireContext(&localProvider, nullptr, MS_ENH_RSA_AES_PROV,
PROV_RSA_AES, CRYPT_VERIFYCONTEXT))
throw strprintf("CryptAcquireContext failed: %lu",
GetLastError());
@ -851,7 +807,7 @@ try {
* get json from server */
success = GetRemoteFile(WIN_WHATSNEW_URL, text, error, &responseCode,
nullptr, nullptr, extraHeaders, &signature);
nullptr, nullptr, extraHeaders, &signature);
if (!success || (responseCode != 200 && responseCode != 304)) {
if (responseCode == 404)
@ -865,8 +821,8 @@ try {
* verify file signature */
if (responseCode == 200) {
success = CheckDataSignature(text, "whatsnew",
signature.data(), signature.size());
success = CheckDataSignature(text, "whatsnew", signature.data(),
signature.size());
if (!success)
throw string("Invalid whatsnew signature");
}

View file

@ -9,9 +9,7 @@
using namespace json11;
OBSAbout::OBSAbout(QWidget *parent)
: QDialog(parent),
ui(new Ui::OBSAbout)
OBSAbout::OBSAbout(QWidget *parent) : QDialog(parent), ui(new Ui::OBSAbout)
{
ui->setupUi(this);
@ -20,29 +18,30 @@ OBSAbout::OBSAbout(QWidget *parent)
QString bitness;
QString ver;
if(sizeof(void*) == 4)
if (sizeof(void *) == 4)
bitness = " (32 bit)";
else if(sizeof(void*) == 8)
else if (sizeof(void *) == 8)
bitness = " (64 bit)";
#ifdef HAVE_OBSCONFIG_H
ver += OBS_VERSION;
ver += OBS_VERSION;
#else
ver += LIBOBS_API_MAJOR_VER + "." +
LIBOBS_API_MINOR_VER + "." +
LIBOBS_API_PATCH_VER;
ver += LIBOBS_API_MAJOR_VER + "." + LIBOBS_API_MINOR_VER + "." +
LIBOBS_API_PATCH_VER;
#endif
ui->version->setText(ver + bitness);
ui->contribute->setText(QTStr("About.Contribute"));
ui->donate->setText("&nbsp;&nbsp;<a href='https://obsproject.com/donate'>" +
QTStr("About.Donate") + "</a>");
ui->donate->setText(
"&nbsp;&nbsp;<a href='https://obsproject.com/donate'>" +
QTStr("About.Donate") + "</a>");
ui->donate->setTextInteractionFlags(Qt::TextBrowserInteraction);
ui->donate->setOpenExternalLinks(true);
ui->getInvolved->setText("&nbsp;&nbsp;<a href='https://github.com/obsproject/obs-studio/blob/master/CONTRIBUTING.rst'>" +
QTStr("About.GetInvolved") + "</a>");
ui->getInvolved->setText(
"&nbsp;&nbsp;<a href='https://github.com/obsproject/obs-studio/blob/master/CONTRIBUTING.rst'>" +
QTStr("About.GetInvolved") + "</a>");
ui->getInvolved->setTextInteractionFlags(Qt::TextBrowserInteraction);
ui->getInvolved->setOpenExternalLinks(true);
@ -66,12 +65,14 @@ OBSAbout::OBSAbout(QWidget *parent)
OBSBasic *main = OBSBasic::Get();
if (main->patronJson.empty() && !main->patronJsonThread) {
RemoteTextThread *thread = new RemoteTextThread(
"https://obsproject.com/patreon/about-box.json",
"application/json");
QObject::connect(thread, &RemoteTextThread::Result,
main, &OBSBasic::UpdatePatronJson);
QObject::connect(thread, SIGNAL(Result(const QString &, const QString &)),
this, SLOT(ShowAbout()));
"https://obsproject.com/patreon/about-box.json",
"application/json");
QObject::connect(thread, &RemoteTextThread::Result, main,
&OBSBasic::UpdatePatronJson);
QObject::connect(
thread,
SIGNAL(Result(const QString &, const QString &)), this,
SLOT(ShowAbout()));
main->patronJsonThread.reset(thread);
thread->start();
} else {

View file

@ -16,9 +16,9 @@ Q_DECLARE_METATYPE(OBSSource);
OBSBasicAdvAudio::OBSBasicAdvAudio(QWidget *parent)
: QDialog(parent),
sourceAddedSignal(obs_get_signal_handler(), "source_activate",
OBSSourceAdded, this),
OBSSourceAdded, this),
sourceRemovedSignal(obs_get_signal_handler(), "source_deactivate",
OBSSourceRemoved, this)
OBSSourceRemoved, this)
{
QScrollArea *scrollArea;
QVBoxLayout *vlayout;
@ -55,7 +55,7 @@ OBSBasicAdvAudio::OBSBasicAdvAudio(QWidget *parent)
controlArea = new QWidget;
controlArea->setLayout(mainLayout);
controlArea->setSizePolicy(QSizePolicy::Preferred,
QSizePolicy::Preferred);
QSizePolicy::Preferred);
vlayout = new QVBoxLayout;
vlayout->addWidget(controlArea);
@ -80,7 +80,7 @@ OBSBasicAdvAudio::OBSBasicAdvAudio(QWidget *parent)
vlayout->addLayout(buttonLayout);
setLayout(vlayout);
connect(closeButton, &QPushButton::clicked, [this] () {close();});
connect(closeButton, &QPushButton::clicked, [this]() { close(); });
installEventFilter(CreateShortcutFilter());
@ -97,7 +97,7 @@ OBSBasicAdvAudio::OBSBasicAdvAudio(QWidget *parent)
OBSBasicAdvAudio::~OBSBasicAdvAudio()
{
OBSBasic *main = reinterpret_cast<OBSBasic*>(parent());
OBSBasic *main = reinterpret_cast<OBSBasic *>(parent());
for (size_t i = 0; i < controls.size(); ++i)
delete controls[i];
@ -107,7 +107,7 @@ OBSBasicAdvAudio::~OBSBasicAdvAudio()
bool OBSBasicAdvAudio::EnumSources(void *param, obs_source_t *source)
{
OBSBasicAdvAudio *dialog = reinterpret_cast<OBSBasicAdvAudio*>(param);
OBSBasicAdvAudio *dialog = reinterpret_cast<OBSBasicAdvAudio *>(param);
uint32_t flags = obs_source_get_output_flags(source);
if ((flags & OBS_SOURCE_AUDIO) != 0 && obs_source_active(source))
@ -118,18 +118,18 @@ bool OBSBasicAdvAudio::EnumSources(void *param, obs_source_t *source)
void OBSBasicAdvAudio::OBSSourceAdded(void *param, calldata_t *calldata)
{
OBSSource source((obs_source_t*)calldata_ptr(calldata, "source"));
OBSSource source((obs_source_t *)calldata_ptr(calldata, "source"));
QMetaObject::invokeMethod(reinterpret_cast<OBSBasicAdvAudio*>(param),
"SourceAdded", Q_ARG(OBSSource, source));
QMetaObject::invokeMethod(reinterpret_cast<OBSBasicAdvAudio *>(param),
"SourceAdded", Q_ARG(OBSSource, source));
}
void OBSBasicAdvAudio::OBSSourceRemoved(void *param, calldata_t *calldata)
{
OBSSource source((obs_source_t*)calldata_ptr(calldata, "source"));
OBSSource source((obs_source_t *)calldata_ptr(calldata, "source"));
QMetaObject::invokeMethod(reinterpret_cast<OBSBasicAdvAudio*>(param),
"SourceRemoved", Q_ARG(OBSSource, source));
QMetaObject::invokeMethod(reinterpret_cast<OBSBasicAdvAudio *>(param),
"SourceRemoved", Q_ARG(OBSSource, source));
}
inline void OBSBasicAdvAudio::AddAudioSource(obs_source_t *source)

View file

@ -18,7 +18,7 @@ private:
OBSSignal sourceAddedSignal;
OBSSignal sourceRemovedSignal;
std::vector<OBSAdvAudioCtrl*> controls;
std::vector<OBSAdvAudioCtrl *> controls;
inline void AddAudioSource(obs_source_t *source);

View file

@ -15,7 +15,7 @@
#include "ui_AutoConfigTestPage.h"
#define wiz reinterpret_cast<AutoConfig*>(wizard())
#define wiz reinterpret_cast<AutoConfig *>(wizard())
using namespace std;
@ -31,17 +31,14 @@ class TestMode {
gs_eparam_t *randomvals[3] = {
gs_effect_get_param_by_name(solid, "randomvals1"),
gs_effect_get_param_by_name(solid, "randomvals2"),
gs_effect_get_param_by_name(solid, "randomvals3")
};
gs_effect_get_param_by_name(solid, "randomvals3")};
struct vec4 r;
for (int i = 0; i < 3; i++) {
vec4_set(&r,
rand_float(true) * 100.0f,
rand_float(true) * 100.0f,
rand_float(true) * 50000.0f + 10000.0f,
0.0f);
vec4_set(&r, rand_float(true) * 100.0f,
rand_float(true) * 100.0f,
rand_float(true) * 50000.0f + 10000.0f, 0.0f);
gs_effect_set_vec4(randomvals[i], &r);
}
@ -86,37 +83,37 @@ public:
/* ------------------------------------------------------------------------- */
#define TEST_STR(x) "Basic.AutoConfig.TestPage." x
#define SUBTITLE_TESTING TEST_STR("Subtitle.Testing")
#define SUBTITLE_COMPLETE TEST_STR("Subtitle.Complete")
#define TEST_BW TEST_STR("TestingBandwidth")
#define TEST_BW_CONNECTING TEST_STR("TestingBandwidth.Connecting")
#define TEST_BW_CONNECT_FAIL TEST_STR("TestingBandwidth.ConnectFailed")
#define TEST_BW_SERVER TEST_STR("TestingBandwidth.Server")
#define TEST_RES TEST_STR("TestingRes")
#define TEST_RES_VAL TEST_STR("TestingRes.Resolution")
#define TEST_RES_FAIL TEST_STR("TestingRes.Fail")
#define TEST_SE TEST_STR("TestingStreamEncoder")
#define TEST_RE TEST_STR("TestingRecordingEncoder")
#define TEST_RESULT_SE TEST_STR("Result.StreamingEncoder")
#define TEST_RESULT_RE TEST_STR("Result.RecordingEncoder")
#define TEST_STR(x) "Basic.AutoConfig.TestPage." x
#define SUBTITLE_TESTING TEST_STR("Subtitle.Testing")
#define SUBTITLE_COMPLETE TEST_STR("Subtitle.Complete")
#define TEST_BW TEST_STR("TestingBandwidth")
#define TEST_BW_CONNECTING TEST_STR("TestingBandwidth.Connecting")
#define TEST_BW_CONNECT_FAIL TEST_STR("TestingBandwidth.ConnectFailed")
#define TEST_BW_SERVER TEST_STR("TestingBandwidth.Server")
#define TEST_RES TEST_STR("TestingRes")
#define TEST_RES_VAL TEST_STR("TestingRes.Resolution")
#define TEST_RES_FAIL TEST_STR("TestingRes.Fail")
#define TEST_SE TEST_STR("TestingStreamEncoder")
#define TEST_RE TEST_STR("TestingRecordingEncoder")
#define TEST_RESULT_SE TEST_STR("Result.StreamingEncoder")
#define TEST_RESULT_RE TEST_STR("Result.RecordingEncoder")
void AutoConfigTestPage::StartBandwidthStage()
{
ui->progressLabel->setText(QTStr(TEST_BW));
testThread = std::thread([this] () {TestBandwidthThread();});
testThread = std::thread([this]() { TestBandwidthThread(); });
}
void AutoConfigTestPage::StartStreamEncoderStage()
{
ui->progressLabel->setText(QTStr(TEST_SE));
testThread = std::thread([this] () {TestStreamEncoderThread();});
testThread = std::thread([this]() { TestStreamEncoderThread(); });
}
void AutoConfigTestPage::StartRecordingEncoderStage()
{
ui->progressLabel->setText(QTStr(TEST_RE));
testThread = std::thread([this] () {TestRecordingEncoderThread();});
testThread = std::thread([this]() { TestRecordingEncoderThread(); });
}
void AutoConfigTestPage::GetServers(std::vector<ServerInfo> &servers)
@ -176,21 +173,20 @@ void AutoConfigTestPage::TestBandwidthThread()
*/
QMetaObject::invokeMethod(this, "UpdateMessage",
Q_ARG(QString, QStringLiteral("")));
Q_ARG(QString, QStringLiteral("")));
/* -----------------------------------*/
/* create obs objects */
const char *serverType = wiz->customServer
? "rtmp_custom"
: "rtmp_common";
const char *serverType = wiz->customServer ? "rtmp_custom"
: "rtmp_common";
OBSEncoder vencoder = obs_video_encoder_create("obs_x264",
"test_x264", nullptr, nullptr);
OBSEncoder aencoder = obs_audio_encoder_create("ffmpeg_aac",
"test_aac", nullptr, 0, nullptr);
OBSService service = obs_service_create(serverType,
"test_service", nullptr, nullptr);
OBSEncoder vencoder = obs_video_encoder_create("obs_x264", "test_x264",
nullptr, nullptr);
OBSEncoder aencoder = obs_audio_encoder_create("ffmpeg_aac", "test_aac",
nullptr, 0, nullptr);
OBSService service = obs_service_create(serverType, "test_service",
nullptr, nullptr);
obs_encoder_release(vencoder);
obs_encoder_release(aencoder);
obs_service_release(service);
@ -218,14 +214,14 @@ void AutoConfigTestPage::TestBandwidthThread()
if (wiz->service == AutoConfig::Service::Twitch) {
string_depad_key(key);
key += "?bandwidthtest";
}
else if(wiz->serviceName == "Restream.io" || wiz->serviceName == "Restream.io - RTMP") {
} else if (wiz->serviceName == "Restream.io" ||
wiz->serviceName == "Restream.io - RTMP") {
string_depad_key(key);
key += "?test=true";
}
obs_data_set_string(service_settings, "service",
wiz->serviceName.c_str());
wiz->serviceName.c_str());
obs_data_set_string(service_settings, "key", key.c_str());
obs_data_set_int(vencoder_settings, "bitrate", wiz->startingBitrate);
@ -235,9 +231,9 @@ void AutoConfigTestPage::TestBandwidthThread()
obs_data_set_int(aencoder_settings, "bitrate", 32);
OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
const char *bind_ip = config_get_string(main->Config(), "Output",
"BindIP");
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
const char *bind_ip =
config_get_string(main->Config(), "Output", "BindIP");
obs_data_set_string(output_settings, "bind_ip", bind_ip);
/* -----------------------------------*/
@ -251,12 +247,12 @@ void AutoConfigTestPage::TestBandwidthThread()
/* just use the first server if it only has one alternate server,
* or if using Mixer or Restream due to their "auto" servers */
if (servers.size() < 3 || wiz->serviceName == "Mixer.com - FTL" ||
wiz->serviceName.substr(0, 11)=="Restream.io") {
if (servers.size() < 3 || wiz->serviceName == "Mixer.com - FTL" ||
wiz->serviceName.substr(0, 11) == "Restream.io") {
servers.resize(1);
} else if (wiz->service == AutoConfig::Service::Twitch &&
wiz->twitchAuto) {
wiz->twitchAuto) {
/* if using Twitch and "Auto" is available, test 3 closest
* server */
servers.erase(servers.begin() + 1);
@ -267,8 +263,8 @@ void AutoConfigTestPage::TestBandwidthThread()
/* apply service settings */
obs_service_update(service, service_settings);
obs_service_apply_encoder_settings(service,
vencoder_settings, aencoder_settings);
obs_service_apply_encoder_settings(service, vencoder_settings,
aencoder_settings);
/* -----------------------------------*/
/* create output */
@ -277,18 +273,17 @@ void AutoConfigTestPage::TestBandwidthThread()
if (!output_type)
output_type = "rtmp_output";
OBSOutput output = obs_output_create(output_type,
"test_stream", nullptr, nullptr);
OBSOutput output =
obs_output_create(output_type, "test_stream", nullptr, nullptr);
obs_output_release(output);
obs_output_update(output, output_settings);
const char *audio_codec =
obs_output_get_supported_audio_codecs(output);
const char *audio_codec = obs_output_get_supported_audio_codecs(output);
if (strcmp(audio_codec, "aac") != 0) {
const char *id = FindAudioEncoderFromCodec(audio_codec);
aencoder = obs_audio_encoder_create(id,
"test_audio", nullptr, 0, nullptr);
aencoder = obs_audio_encoder_create(id, "test_audio", nullptr,
0, nullptr);
obs_encoder_release(aencoder);
}
@ -308,16 +303,14 @@ void AutoConfigTestPage::TestBandwidthThread()
/* -----------------------------------*/
/* connect signals */
auto on_started = [&] ()
{
auto on_started = [&]() {
unique_lock<mutex> lock(m);
connected = true;
stopped = false;
cv.notify_one();
};
auto on_stopped = [&] ()
{
auto on_stopped = [&]() {
unique_lock<mutex> lock(m);
connected = false;
stopped = true;
@ -327,17 +320,15 @@ void AutoConfigTestPage::TestBandwidthThread()
using on_started_t = decltype(on_started);
using on_stopped_t = decltype(on_stopped);
auto pre_on_started = [] (void *data, calldata_t *)
{
auto pre_on_started = [](void *data, calldata_t *) {
on_started_t &on_started =
*reinterpret_cast<on_started_t*>(data);
*reinterpret_cast<on_started_t *>(data);
on_started();
};
auto pre_on_stopped = [] (void *data, calldata_t *)
{
auto pre_on_stopped = [](void *data, calldata_t *) {
on_stopped_t &on_stopped =
*reinterpret_cast<on_stopped_t*>(data);
*reinterpret_cast<on_stopped_t *>(data);
on_stopped();
};
@ -358,12 +349,13 @@ void AutoConfigTestPage::TestBandwidthThread()
int per = int((i + 1) * 100 / servers.size());
QMetaObject::invokeMethod(this, "Progress", Q_ARG(int, per));
QMetaObject::invokeMethod(this, "UpdateMessage",
Q_ARG(QString, QTStr(TEST_BW_CONNECTING)
.arg(server.name.c_str())));
QMetaObject::invokeMethod(
this, "UpdateMessage",
Q_ARG(QString, QTStr(TEST_BW_CONNECTING)
.arg(server.name.c_str())));
obs_data_set_string(service_settings, "server",
server.address.c_str());
server.address.c_str());
obs_service_update(service, service_settings);
if (!obs_output_start(output))
@ -385,9 +377,10 @@ void AutoConfigTestPage::TestBandwidthThread()
if (!connected)
continue;
QMetaObject::invokeMethod(this, "UpdateMessage",
Q_ARG(QString, QTStr(TEST_BW_SERVER)
.arg(server.name.c_str())));
QMetaObject::invokeMethod(
this, "UpdateMessage",
Q_ARG(QString,
QTStr(TEST_BW_SERVER).arg(server.name.c_str())));
/* ignore first 2.5 seconds due to possible buffering skewing
* the result */
@ -418,10 +411,10 @@ void AutoConfigTestPage::TestBandwidthThread()
uint64_t total_time = os_gettime_ns() - t_start;
int total_bytes = (int)obs_output_get_total_bytes(output) -
start_bytes;
uint64_t bitrate = (uint64_t)total_bytes * 8
* 1000000000 / total_time / 1000;
int total_bytes =
(int)obs_output_get_total_bytes(output) - start_bytes;
uint64_t bitrate = (uint64_t)total_bytes * 8 * 1000000000 /
total_time / 1000;
if (obs_output_get_frames_dropped(output) ||
(int)bitrate < (wiz->startingBitrate * 75 / 100)) {
@ -436,7 +429,8 @@ void AutoConfigTestPage::TestBandwidthThread()
if (!success) {
QMetaObject::invokeMethod(this, "Failure",
Q_ARG(QString, QTStr(TEST_BW_CONNECT_FAIL)));
Q_ARG(QString,
QTStr(TEST_BW_CONNECT_FAIL)));
return;
}
@ -480,7 +474,8 @@ static long double EstimateMinBitrate(int cx, int cy, int fps_num, int fps_den)
return EstimateBitrateVal(cx, cy, fps_num, fps_den) / val;
}
static long double EstimateUpperBitrate(int cx, int cy, int fps_num, int fps_den)
static long double EstimateUpperBitrate(int cx, int cy, int fps_num,
int fps_den)
{
long double val = EstimateBitrateVal(1280, 720, 30, 1) / 3000.0l;
return EstimateBitrateVal(cx, cy, fps_num, fps_den) / val;
@ -520,17 +515,17 @@ bool AutoConfigTestPage::TestSoftwareEncoding()
{
TestMode testMode;
QMetaObject::invokeMethod(this, "UpdateMessage",
Q_ARG(QString, QStringLiteral("")));
Q_ARG(QString, QStringLiteral("")));
/* -----------------------------------*/
/* create obs objects */
OBSEncoder vencoder = obs_video_encoder_create("obs_x264",
"test_x264", nullptr, nullptr);
OBSEncoder aencoder = obs_audio_encoder_create("ffmpeg_aac",
"test_aac", nullptr, 0, nullptr);
OBSOutput output = obs_output_create("null_output",
"null", nullptr, nullptr);
OBSEncoder vencoder = obs_video_encoder_create("obs_x264", "test_x264",
nullptr, nullptr);
OBSEncoder aencoder = obs_audio_encoder_create("ffmpeg_aac", "test_aac",
nullptr, 0, nullptr);
OBSOutput output =
obs_output_create("null_output", "null", nullptr, nullptr);
obs_output_release(output);
obs_encoder_release(vencoder);
obs_encoder_release(aencoder);
@ -547,7 +542,7 @@ bool AutoConfigTestPage::TestSoftwareEncoding()
if (wiz->type != AutoConfig::Type::Recording) {
obs_data_set_int(vencoder_settings, "keyint_sec", 2);
obs_data_set_int(vencoder_settings, "bitrate",
wiz->idealBitrate);
wiz->idealBitrate);
obs_data_set_string(vencoder_settings, "rate_control", "CBR");
obs_data_set_string(vencoder_settings, "profile", "main");
obs_data_set_string(vencoder_settings, "preset", "veryfast");
@ -573,18 +568,16 @@ bool AutoConfigTestPage::TestSoftwareEncoding()
/* -----------------------------------*/
/* connect signals */
auto on_stopped = [&] ()
{
auto on_stopped = [&]() {
unique_lock<mutex> lock(m);
cv.notify_one();
};
using on_stopped_t = decltype(on_stopped);
auto pre_on_stopped = [] (void *data, calldata_t *)
{
auto pre_on_stopped = [](void *data, calldata_t *) {
on_stopped_t &on_stopped =
*reinterpret_cast<on_stopped_t*>(data);
*reinterpret_cast<on_stopped_t *>(data);
on_stopped();
};
@ -628,9 +621,8 @@ bool AutoConfigTestPage::TestSoftwareEncoding()
int i = 0;
int count = 1;
auto testRes = [&] (long double div, int fps_num, int fps_den,
bool force)
{
auto testRes = [&](long double div, int fps_num, int fps_den,
bool force) {
int per = ++i * 100 / count;
QMetaObject::invokeMethod(this, "Progress", Q_ARG(int, per));
@ -669,13 +661,13 @@ bool AutoConfigTestPage::TestSoftwareEncoding()
QString cxStr = QString::number(cx);
QString cyStr = QString::number(cy);
QString fpsStr = (fps_den > 1)
? QString::number(fps, 'f', 2)
: QString::number(fps, 'g', 2);
QString fpsStr = (fps_den > 1) ? QString::number(fps, 'f', 2)
: QString::number(fps, 'g', 2);
QMetaObject::invokeMethod(this, "UpdateMessage",
Q_ARG(QString, QTStr(TEST_RES_VAL)
.arg(cxStr, cyStr, fpsStr)));
QMetaObject::invokeMethod(
this, "UpdateMessage",
Q_ARG(QString,
QTStr(TEST_RES_VAL).arg(cxStr, cyStr, fpsStr)));
unique_lock<mutex> ul(m);
if (cancel)
@ -683,7 +675,8 @@ bool AutoConfigTestPage::TestSoftwareEncoding()
if (!obs_output_start(output)) {
QMetaObject::invokeMethod(this, "Failure",
Q_ARG(QString, QTStr(TEST_RES_FAIL)));
Q_ARG(QString,
QTStr(TEST_RES_FAIL)));
return false;
}
@ -692,8 +685,8 @@ bool AutoConfigTestPage::TestSoftwareEncoding()
obs_output_stop(output);
cv.wait(ul);
int skipped = (int)video_output_get_skipped_frames(
obs_get_video());
int skipped =
(int)video_output_get_skipped_frames(obs_get_video());
if (force || skipped <= 10)
results.emplace_back(cx, cy, fps_num, fps_den);
@ -702,23 +695,38 @@ bool AutoConfigTestPage::TestSoftwareEncoding()
if (wiz->specificFPSNum && wiz->specificFPSDen) {
count = 5;
if (!testRes(1.0, 0, 0, false)) return false;
if (!testRes(1.5, 0, 0, false)) return false;
if (!testRes(1.0 / 0.6, 0, 0, false)) return false;
if (!testRes(2.0, 0, 0, false)) return false;
if (!testRes(2.25, 0, 0, true)) return false;
if (!testRes(1.0, 0, 0, false))
return false;
if (!testRes(1.5, 0, 0, false))
return false;
if (!testRes(1.0 / 0.6, 0, 0, false))
return false;
if (!testRes(2.0, 0, 0, false))
return false;
if (!testRes(2.25, 0, 0, true))
return false;
} else {
count = 10;
if (!testRes(1.0, 60, 1, false)) return false;
if (!testRes(1.0, 30, 1, false)) return false;
if (!testRes(1.5, 60, 1, false)) return false;
if (!testRes(1.5, 30, 1, false)) return false;
if (!testRes(1.0 / 0.6, 60, 1, false)) return false;
if (!testRes(1.0 / 0.6, 30, 1, false)) return false;
if (!testRes(2.0, 60, 1, false)) return false;
if (!testRes(2.0, 30, 1, false)) return false;
if (!testRes(2.25, 60, 1, false)) return false;
if (!testRes(2.25, 30, 1, true)) return false;
if (!testRes(1.0, 60, 1, false))
return false;
if (!testRes(1.0, 30, 1, false))
return false;
if (!testRes(1.5, 60, 1, false))
return false;
if (!testRes(1.5, 30, 1, false))
return false;
if (!testRes(1.0 / 0.6, 60, 1, false))
return false;
if (!testRes(1.0 / 0.6, 30, 1, false))
return false;
if (!testRes(2.0, 60, 1, false))
return false;
if (!testRes(2.0, 30, 1, false))
return false;
if (!testRes(2.25, 60, 1, false))
return false;
if (!testRes(2.25, 30, 1, true))
return false;
}
/* -----------------------------------*/
@ -744,7 +752,7 @@ bool AutoConfigTestPage::TestSoftwareEncoding()
wiz->idealFPSDen = result.fps_den;
long double fUpperBitrate = EstimateUpperBitrate(
result.cx, result.cy, result.fps_num, result.fps_den);
result.cx, result.cy, result.fps_num, result.fps_den);
int upperBitrate = int(floor(fUpperBitrate / 50.0l) * 50.0l);
@ -776,9 +784,8 @@ void AutoConfigTestPage::FindIdealHardwareResolution()
maxDataRate = 1280 * 720 * 30 + 1000;
}
auto testRes = [&] (long double div, int fps_num, int fps_den,
bool force)
{
auto testRes = [&](long double div, int fps_num, int fps_den,
bool force) {
if (results.size() >= 3)
return;
@ -805,7 +812,8 @@ void AutoConfigTestPage::FindIdealHardwareResolution()
* ratio, so increase the minimum bitrate estimate for them.
* NVENC currently is the exception because of the improvements
* its made to its quality in recent generations. */
if (!nvenc) minBitrate = minBitrate * 114 / 100;
if (!nvenc)
minBitrate = minBitrate * 114 / 100;
if (wiz->type == AutoConfig::Type::Recording)
force = true;
@ -919,9 +927,9 @@ void AutoConfigTestPage::TestRecordingEncoderThread()
#define ENCODER_TEXT(x) "Basic.Settings.Output.Simple.Encoder." x
#define ENCODER_SOFTWARE ENCODER_TEXT("Software")
#define ENCODER_NVENC ENCODER_TEXT("Hardware.NVENC")
#define ENCODER_QSV ENCODER_TEXT("Hardware.QSV")
#define ENCODER_AMD ENCODER_TEXT("Hardware.AMD")
#define ENCODER_NVENC ENCODER_TEXT("Hardware.NVENC")
#define ENCODER_QSV ENCODER_TEXT("Hardware.QSV")
#define ENCODER_AMD ENCODER_TEXT("Hardware.AMD")
#define QUALITY_SAME "Basic.Settings.Output.Simple.RecordingQuality.Stream"
#define QUALITY_HIGH "Basic.Settings.Output.Simple.RecordingQuality.Small"
@ -933,8 +941,7 @@ void AutoConfigTestPage::FinalizeResults()
QFormLayout *form = results;
auto encName = [] (AutoConfig::Encoder enc) -> QString
{
auto encName = [](AutoConfig::Encoder enc) -> QString {
switch (enc) {
case AutoConfig::Encoder::x264:
return QTStr(ENCODER_SOFTWARE);
@ -951,18 +958,16 @@ void AutoConfigTestPage::FinalizeResults()
return QTStr(ENCODER_SOFTWARE);
};
auto newLabel = [this] (const char *str) -> QLabel *
{
auto newLabel = [this](const char *str) -> QLabel * {
return new QLabel(QTStr(str), this);
};
if (wiz->type != AutoConfig::Type::Recording) {
const char *serverType = wiz->customServer
? "rtmp_custom"
: "rtmp_common";
const char *serverType = wiz->customServer ? "rtmp_custom"
: "rtmp_common";
OBSService service = obs_service_create(serverType,
"temp_service", nullptr, nullptr);
OBSService service = obs_service_create(
serverType, "temp_service", nullptr, nullptr);
obs_service_release(service);
OBSData service_settings = obs_data_create();
@ -971,44 +976,45 @@ void AutoConfigTestPage::FinalizeResults()
obs_data_release(vencoder_settings);
obs_data_set_int(vencoder_settings, "bitrate",
wiz->idealBitrate);
wiz->idealBitrate);
obs_data_set_string(service_settings, "service",
wiz->serviceName.c_str());
wiz->serviceName.c_str());
obs_service_update(service, service_settings);
obs_service_apply_encoder_settings(service,
vencoder_settings, nullptr);
obs_service_apply_encoder_settings(service, vencoder_settings,
nullptr);
wiz->idealBitrate = (int)obs_data_get_int(vencoder_settings,
"bitrate");
wiz->idealBitrate =
(int)obs_data_get_int(vencoder_settings, "bitrate");
if (!wiz->customServer)
form->addRow(
newLabel("Basic.AutoConfig.StreamPage.Service"),
new QLabel(wiz->serviceName.c_str(),
ui->finishPage));
ui->finishPage));
form->addRow(newLabel("Basic.AutoConfig.StreamPage.Server"),
new QLabel(wiz->serverName.c_str(), ui->finishPage));
new QLabel(wiz->serverName.c_str(),
ui->finishPage));
form->addRow(newLabel("Basic.Settings.Output.VideoBitrate"),
new QLabel(QString::number(wiz->idealBitrate),
ui->finishPage));
new QLabel(QString::number(wiz->idealBitrate),
ui->finishPage));
form->addRow(newLabel(TEST_RESULT_SE),
new QLabel(encName(wiz->streamingEncoder),
ui->finishPage));
new QLabel(encName(wiz->streamingEncoder),
ui->finishPage));
}
QString baseRes = QString("%1x%2").arg(
QString::number(wiz->baseResolutionCX),
QString::number(wiz->baseResolutionCY));
QString scaleRes = QString("%1x%2").arg(
QString::number(wiz->idealResolutionCX),
QString::number(wiz->idealResolutionCY));
QString baseRes =
QString("%1x%2").arg(QString::number(wiz->baseResolutionCX),
QString::number(wiz->baseResolutionCY));
QString scaleRes =
QString("%1x%2").arg(QString::number(wiz->idealResolutionCX),
QString::number(wiz->idealResolutionCY));
if (wiz->recordingEncoder != AutoConfig::Encoder::Stream ||
wiz->recordingQuality != AutoConfig::Quality::Stream)
form->addRow(newLabel(TEST_RESULT_RE),
new QLabel(encName(wiz->recordingEncoder),
ui->finishPage));
new QLabel(encName(wiz->recordingEncoder),
ui->finishPage));
QString recQuality;
@ -1022,21 +1028,20 @@ void AutoConfigTestPage::FinalizeResults()
}
form->addRow(newLabel("Basic.Settings.Output.Simple.RecordingQuality"),
new QLabel(recQuality, ui->finishPage));
new QLabel(recQuality, ui->finishPage));
long double fps =
(long double)wiz->idealFPSNum / (long double)wiz->idealFPSDen;
QString fpsStr = (wiz->idealFPSDen > 1)
? QString::number(fps, 'f', 2)
: QString::number(fps, 'g', 2);
QString fpsStr = (wiz->idealFPSDen > 1) ? QString::number(fps, 'f', 2)
: QString::number(fps, 'g', 2);
form->addRow(newLabel("Basic.Settings.Video.BaseResolution"),
new QLabel(baseRes, ui->finishPage));
new QLabel(baseRes, ui->finishPage));
form->addRow(newLabel("Basic.Settings.Video.ScaledResolution"),
new QLabel(scaleRes, ui->finishPage));
new QLabel(scaleRes, ui->finishPage));
form->addRow(newLabel("Basic.Settings.Video.FPS"),
new QLabel(fpsStr, ui->finishPage));
new QLabel(fpsStr, ui->finishPage));
}
#define STARTING_SEPARATOR \
@ -1103,8 +1108,7 @@ void AutoConfigTestPage::Progress(int percentage)
}
AutoConfigTestPage::AutoConfigTestPage(QWidget *parent)
: QWizardPage (parent),
ui (new Ui_AutoConfigTestPage)
: QWizardPage(parent), ui(new Ui_AutoConfigTestPage)
{
ui->setupUi(this);
setTitle(QTStr("Basic.AutoConfig.TestPage"));

View file

@ -20,10 +20,10 @@
struct QCef;
struct QCefCookieManager;
extern QCef *cef;
extern QCef *cef;
extern QCefCookieManager *panel_cookies;
#define wiz reinterpret_cast<AutoConfig*>(wizard())
#define wiz reinterpret_cast<AutoConfig *>(wizard())
/* ------------------------------------------------------------------------- */
@ -33,12 +33,12 @@ static OBSData OpenServiceSettings(std::string &type)
{
char serviceJsonPath[512];
int ret = GetProfilePath(serviceJsonPath, sizeof(serviceJsonPath),
SERVICE_PATH);
SERVICE_PATH);
if (ret <= 0)
return OBSData();
OBSData data = obs_data_create_from_json_file_safe(serviceJsonPath,
"bak");
OBSData data =
obs_data_create_from_json_file_safe(serviceJsonPath, "bak");
obs_data_release(data);
obs_data_set_default_string(data, "type", "rtmp_common");
@ -51,7 +51,7 @@ static OBSData OpenServiceSettings(std::string &type)
}
static void GetServiceInfo(std::string &type, std::string &service,
std::string &server, std::string &key)
std::string &server, std::string &key)
{
OBSData settings = OpenServiceSettings(type);
@ -63,8 +63,7 @@ static void GetServiceInfo(std::string &type, std::string &service,
/* ------------------------------------------------------------------------- */
AutoConfigStartPage::AutoConfigStartPage(QWidget *parent)
: QWizardPage (parent),
ui (new Ui_AutoConfigStartPage)
: QWizardPage(parent), ui(new Ui_AutoConfigStartPage)
{
ui->setupUi(this);
setTitle(QTStr("Basic.AutoConfig.StartPage"));
@ -93,16 +92,15 @@ void AutoConfigStartPage::on_prioritizeRecording_clicked()
/* ------------------------------------------------------------------------- */
#define RES_TEXT(x) "Basic.AutoConfig.VideoPage." x
#define RES_USE_CURRENT RES_TEXT("BaseResolution.UseCurrent")
#define RES_USE_DISPLAY RES_TEXT("BaseResolution.Display")
#define FPS_USE_CURRENT RES_TEXT("FPS.UseCurrent")
#define FPS_PREFER_HIGH_FPS RES_TEXT("FPS.PreferHighFPS")
#define FPS_PREFER_HIGH_RES RES_TEXT("FPS.PreferHighRes")
#define RES_TEXT(x) "Basic.AutoConfig.VideoPage." x
#define RES_USE_CURRENT RES_TEXT("BaseResolution.UseCurrent")
#define RES_USE_DISPLAY RES_TEXT("BaseResolution.Display")
#define FPS_USE_CURRENT RES_TEXT("FPS.UseCurrent")
#define FPS_PREFER_HIGH_FPS RES_TEXT("FPS.PreferHighFPS")
#define FPS_PREFER_HIGH_RES RES_TEXT("FPS.PreferHighRes")
AutoConfigVideoPage::AutoConfigVideoPage(QWidget *parent)
: QWizardPage (parent),
ui (new Ui_AutoConfigVideoPage)
: QWizardPage(parent), ui(new Ui_AutoConfigVideoPage)
{
ui->setupUi(this);
@ -115,16 +113,15 @@ AutoConfigVideoPage::AutoConfigVideoPage(QWidget *parent)
long double fpsVal =
(long double)ovi.fps_num / (long double)ovi.fps_den;
QString fpsStr = (ovi.fps_den > 1)
? QString::number(fpsVal, 'f', 2)
: QString::number(fpsVal, 'g', 2);
QString fpsStr = (ovi.fps_den > 1) ? QString::number(fpsVal, 'f', 2)
: QString::number(fpsVal, 'g', 2);
ui->fps->addItem(QTStr(FPS_PREFER_HIGH_FPS),
(int)AutoConfig::FPSType::PreferHighFPS);
(int)AutoConfig::FPSType::PreferHighFPS);
ui->fps->addItem(QTStr(FPS_PREFER_HIGH_RES),
(int)AutoConfig::FPSType::PreferHighRes);
(int)AutoConfig::FPSType::PreferHighRes);
ui->fps->addItem(QTStr(FPS_USE_CURRENT).arg(fpsStr),
(int)AutoConfig::FPSType::UseCurrent);
(int)AutoConfig::FPSType::UseCurrent);
ui->fps->addItem(QStringLiteral("30"), (int)AutoConfig::FPSType::fps30);
ui->fps->addItem(QStringLiteral("60"), (int)AutoConfig::FPSType::fps60);
ui->fps->setCurrentIndex(0);
@ -134,9 +131,9 @@ AutoConfigVideoPage::AutoConfigVideoPage(QWidget *parent)
int encRes = int(ovi.base_width << 16) | int(ovi.base_height);
ui->canvasRes->addItem(QTStr(RES_USE_CURRENT).arg(cxStr, cyStr),
(int)encRes);
(int)encRes);
QList<QScreen*> screens = QGuiApplication::screens();
QList<QScreen *> screens = QGuiApplication::screens();
for (int i = 0; i < screens.size(); i++) {
QScreen *screen = screens[i];
QSize as = screen->size();
@ -144,19 +141,17 @@ AutoConfigVideoPage::AutoConfigVideoPage(QWidget *parent)
encRes = int(as.width() << 16) | int(as.height());
QString str = QTStr(RES_USE_DISPLAY)
.arg(QString::number(i + 1),
QString::number(as.width()),
QString::number(as.height()));
.arg(QString::number(i + 1),
QString::number(as.width()),
QString::number(as.height()));
ui->canvasRes->addItem(str, encRes);
}
auto addRes = [&] (int cx, int cy)
{
auto addRes = [&](int cx, int cy) {
encRes = (cx << 16) | cy;
QString str = QString("%1x%2").arg(
QString::number(cx),
QString::number(cy));
QString str = QString("%1x%2").arg(QString::number(cx),
QString::number(cy));
ui->canvasRes->addItem(str, encRes);
};
@ -174,8 +169,8 @@ AutoConfigVideoPage::~AutoConfigVideoPage()
int AutoConfigVideoPage::nextId() const
{
return wiz->type == AutoConfig::Type::Recording
? AutoConfig::TestPage
: AutoConfig::StreamPage;
? AutoConfig::TestPage
: AutoConfig::StreamPage;
}
bool AutoConfigVideoPage::validatePage()
@ -223,12 +218,11 @@ bool AutoConfigVideoPage::validatePage()
enum class ListOpt : int {
ShowAll = 1,
Custom
Custom,
};
AutoConfigStreamPage::AutoConfigStreamPage(QWidget *parent)
: QWizardPage (parent),
ui (new Ui_AutoConfigStreamPage)
: QWizardPage(parent), ui(new Ui_AutoConfigStreamPage)
{
ui->setupUi(this);
ui->bitrateLabel->setVisible(false);
@ -255,29 +249,29 @@ AutoConfigStreamPage::AutoConfigStreamPage(QWidget *parent)
LoadServices(false);
connect(ui->service, SIGNAL(currentIndexChanged(int)),
this, SLOT(ServiceChanged()));
connect(ui->customServer, SIGNAL(textChanged(const QString &)),
this, SLOT(ServiceChanged()));
connect(ui->doBandwidthTest, SIGNAL(toggled(bool)),
this, SLOT(ServiceChanged()));
connect(ui->service, SIGNAL(currentIndexChanged(int)), this,
SLOT(ServiceChanged()));
connect(ui->customServer, SIGNAL(textChanged(const QString &)), this,
SLOT(ServiceChanged()));
connect(ui->doBandwidthTest, SIGNAL(toggled(bool)), this,
SLOT(ServiceChanged()));
connect(ui->service, SIGNAL(currentIndexChanged(int)),
this, SLOT(UpdateServerList()));
connect(ui->service, SIGNAL(currentIndexChanged(int)), this,
SLOT(UpdateServerList()));
connect(ui->service, SIGNAL(currentIndexChanged(int)),
this, SLOT(UpdateKeyLink()));
connect(ui->service, SIGNAL(currentIndexChanged(int)), this,
SLOT(UpdateKeyLink()));
connect(ui->key, SIGNAL(textChanged(const QString &)),
this, SLOT(UpdateCompleted()));
connect(ui->regionUS, SIGNAL(toggled(bool)),
this, SLOT(UpdateCompleted()));
connect(ui->regionEU, SIGNAL(toggled(bool)),
this, SLOT(UpdateCompleted()));
connect(ui->regionAsia, SIGNAL(toggled(bool)),
this, SLOT(UpdateCompleted()));
connect(ui->regionOther, SIGNAL(toggled(bool)),
this, SLOT(UpdateCompleted()));
connect(ui->key, SIGNAL(textChanged(const QString &)), this,
SLOT(UpdateCompleted()));
connect(ui->regionUS, SIGNAL(toggled(bool)), this,
SLOT(UpdateCompleted()));
connect(ui->regionEU, SIGNAL(toggled(bool)), this,
SLOT(UpdateCompleted()));
connect(ui->regionAsia, SIGNAL(toggled(bool)), this,
SLOT(UpdateCompleted()));
connect(ui->regionOther, SIGNAL(toggled(bool)), this,
SLOT(UpdateCompleted()));
}
AutoConfigStreamPage::~AutoConfigStreamPage()
@ -307,17 +301,16 @@ bool AutoConfigStreamPage::validatePage()
wiz->customServer = IsCustom();
const char *serverType = wiz->customServer
? "rtmp_custom"
: "rtmp_common";
const char *serverType = wiz->customServer ? "rtmp_custom"
: "rtmp_common";
if (!wiz->customServer) {
obs_data_set_string(service_settings, "service",
QT_TO_UTF8(ui->service->currentText()));
QT_TO_UTF8(ui->service->currentText()));
}
OBSService service = obs_service_create(serverType, "temp_service",
service_settings, nullptr);
service_settings, nullptr);
obs_service_release(service);
int bitrate = 10000;
@ -365,9 +358,8 @@ bool AutoConfigStreamPage::validatePage()
if (wiz->service != AutoConfig::Service::Twitch && wiz->bandwidthTest) {
QMessageBox::StandardButton button;
#define WARNING_TEXT(x) QTStr("Basic.AutoConfig.StreamPage.StreamWarning." x)
button = OBSMessageBox::question(this,
WARNING_TEXT("Title"),
WARNING_TEXT("Text"));
button = OBSMessageBox::question(this, WARNING_TEXT("Title"),
WARNING_TEXT("Text"));
#undef WARNING_TEXT
if (button == QMessageBox::No)
@ -391,7 +383,7 @@ void AutoConfigStreamPage::on_show_clicked()
void AutoConfigStreamPage::OnOAuthStreamKeyConnected()
{
#ifdef BROWSER_AVAILABLE
OAuthStreamKey *a = reinterpret_cast<OAuthStreamKey*>(auth.get());
OAuthStreamKey *a = reinterpret_cast<OAuthStreamKey *>(auth.get());
if (a) {
bool validKey = !a->key().empty();
@ -440,9 +432,8 @@ void AutoConfigStreamPage::on_disconnectAccount_clicked()
{
QMessageBox::StandardButton button;
button = OBSMessageBox::question(this,
QTStr(DISCONNECT_COMFIRM_TITLE),
QTStr(DISCONNECT_COMFIRM_TEXT));
button = OBSMessageBox::question(this, QTStr(DISCONNECT_COMFIRM_TITLE),
QTStr(DISCONNECT_COMFIRM_TEXT));
if (button == QMessageBox::No) {
return;
@ -479,14 +470,13 @@ static inline bool is_auth_service(const std::string &service)
void AutoConfigStreamPage::ServiceChanged()
{
bool showMore =
ui->service->currentData().toInt() == (int)ListOpt::ShowAll;
bool showMore = ui->service->currentData().toInt() ==
(int)ListOpt::ShowAll;
if (showMore)
return;
std::string service = QT_TO_UTF8(ui->service->currentText());
bool regionBased = service == "Twitch" ||
service == "Smashcast";
bool regionBased = service == "Twitch" || service == "Smashcast";
bool testBandwidth = ui->doBandwidthTest->isChecked();
bool custom = IsCustom();
@ -496,9 +486,8 @@ void AutoConfigStreamPage::ServiceChanged()
if (cef) {
if (lastService != service.c_str()) {
bool can_auth = is_auth_service(service);
int page = can_auth
? (int)Section::Connect
: (int)Section::StreamKey;
int page = can_auth ? (int)Section::Connect
: (int)Section::StreamKey;
ui->stackedWidget->setCurrentIndex(page);
ui->streamKeyWidget->setVisible(true);
@ -525,7 +514,7 @@ void AutoConfigStreamPage::ServiceChanged()
if (custom) {
ui->streamkeyPageLayout->insertRow(1, ui->serverLabel,
ui->serverStackedWidget);
ui->serverStackedWidget);
ui->region->setVisible(false);
ui->serverStackedWidget->setCurrentIndex(1);
@ -533,8 +522,8 @@ void AutoConfigStreamPage::ServiceChanged()
ui->serverLabel->setVisible(true);
} else {
if (!testBandwidth)
ui->streamkeyPageLayout->insertRow(2, ui->serverLabel,
ui->serverStackedWidget);
ui->streamkeyPageLayout->insertRow(
2, ui->serverLabel, ui->serverStackedWidget);
ui->region->setVisible(regionBased && testBandwidth);
ui->serverStackedWidget->setCurrentIndex(0);
@ -574,13 +563,15 @@ void AutoConfigStreamPage::UpdateKeyLink()
text += " <a href=\"https://";
text += "www.twitch.tv/broadcast/dashboard/streamkey";
text += "\">";
text += QTStr("Basic.AutoConfig.StreamPage.StreamKey.LinkToSite");
text += QTStr(
"Basic.AutoConfig.StreamPage.StreamKey.LinkToSite");
text += "</a>";
} else if (serviceName == "YouTube / YouTube Gaming") {
text += " <a href=\"https://";
text += "www.youtube.com/live_dashboard";
text += "\">";
text += QTStr("Basic.AutoConfig.StreamPage.StreamKey.LinkToSite");
text += QTStr(
"Basic.AutoConfig.StreamPage.StreamKey.LinkToSite");
text += "</a>";
isYoutube = true;
@ -632,9 +623,9 @@ void AutoConfigStreamPage::LoadServices(bool showAll)
QVariant((int)ListOpt::ShowAll));
}
ui->service->insertItem(0,
QTStr("Basic.AutoConfig.StreamPage.Service.Custom"),
QVariant((int)ListOpt::Custom));
ui->service->insertItem(
0, QTStr("Basic.AutoConfig.StreamPage.Service.Custom"),
QVariant((int)ListOpt::Custom));
if (!lastService.isEmpty()) {
int idx = ui->service->findText(lastService);
@ -650,8 +641,8 @@ void AutoConfigStreamPage::LoadServices(bool showAll)
void AutoConfigStreamPage::UpdateServerList()
{
QString serviceName = ui->service->currentText();
bool showMore =
ui->service->currentData().toInt() == (int)ListOpt::ShowAll;
bool showMore = ui->service->currentData().toInt() ==
(int)ListOpt::ShowAll;
if (showMore) {
LoadServices(true);
@ -706,8 +697,7 @@ void AutoConfigStreamPage::UpdateCompleted()
/* ------------------------------------------------------------------------- */
AutoConfig::AutoConfig(QWidget *parent)
: QWizard(parent)
AutoConfig::AutoConfig(QWidget *parent) : QWizard(parent)
{
EnableThreadedMessageBoxes(true);
@ -718,7 +708,7 @@ AutoConfig::AutoConfig(QWidget *parent)
proc_handler_call(ph, "twitch_ingests_refresh", &cd);
calldata_free(&cd);
OBSBasic *main = reinterpret_cast<OBSBasic*>(parent);
OBSBasic *main = reinterpret_cast<OBSBasic *>(parent);
main->EnableOutputs(false);
installEventFilter(CreateShortcutFilter());
@ -805,14 +795,15 @@ AutoConfig::AutoConfig(QWidget *parent)
} else {
streamPage->ui->customServer->setText(server.c_str());
int idx = streamPage->ui->service->findData(
QVariant((int)ListOpt::Custom));
QVariant((int)ListOpt::Custom));
streamPage->ui->service->setCurrentIndex(idx);
}
if (!key.empty())
streamPage->ui->key->setText(key.c_str());
int bitrate = config_get_int(main->Config(), "SimpleOutput", "VBitrate");
int bitrate =
config_get_int(main->Config(), "SimpleOutput", "VBitrate");
streamPage->ui->bitrate->setValue(bitrate);
streamPage->ServiceChanged();
@ -825,13 +816,13 @@ AutoConfig::AutoConfig(QWidget *parent)
* bitrate ratio that if NVENC is available, it makes sense to
* just always prefer hardware encoding by default */
bool preferHardware = nvencAvailable ||
os_get_physical_cores() <= 4;
os_get_physical_cores() <= 4;
streamPage->ui->preferHardware->setChecked(preferHardware);
}
setOptions(0);
setButtonText(QWizard::FinishButton,
QTStr("Basic.AutoConfig.ApplySettings"));
QTStr("Basic.AutoConfig.ApplySettings"));
setButtonText(QWizard::BackButton, QTStr("Back"));
setButtonText(QWizard::NextButton, QTStr("Next"));
setButtonText(QWizard::CancelButton, QTStr("Cancel"));
@ -839,7 +830,7 @@ AutoConfig::AutoConfig(QWidget *parent)
AutoConfig::~AutoConfig()
{
OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
main->EnableOutputs(true);
EnableThreadedMessageBoxes(false);
}
@ -879,13 +870,13 @@ bool AutoConfig::CanTestServer(const char *server)
if (strcmp(server, "Default") == 0) {
return true;
} else if (astrcmp_n(server, "US-West:", 8) == 0 ||
astrcmp_n(server, "US-East:", 8) == 0) {
astrcmp_n(server, "US-East:", 8) == 0) {
return regionUS;
} else if (astrcmp_n(server, "EU-", 3) == 0) {
return regionEU;
} else if (astrcmp_n(server, "South Korea:", 12) == 0 ||
astrcmp_n(server, "Asia:", 5) == 0 ||
astrcmp_n(server, "China:", 6) == 0) {
astrcmp_n(server, "Asia:", 5) == 0 ||
astrcmp_n(server, "China:", 6) == 0) {
return regionAsia;
} else if (regionOther) {
return true;
@ -924,14 +915,12 @@ inline const char *AutoConfig::GetEncoderId(Encoder enc)
void AutoConfig::SaveStreamSettings()
{
OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
/* ---------------------------------- */
/* save service */
const char *service_id = customServer
? "rtmp_custom"
: "rtmp_common";
const char *service_id = customServer ? "rtmp_custom" : "rtmp_common";
obs_service_t *oldService = main->GetService();
OBSData hotkeyData = obs_hotkeys_save_service(oldService);
@ -945,8 +934,8 @@ void AutoConfig::SaveStreamSettings()
obs_data_set_string(settings, "server", server.c_str());
obs_data_set_string(settings, "key", key.c_str());
OBSService newService = obs_service_create(service_id,
"default_service", settings, hotkeyData);
OBSService newService = obs_service_create(
service_id, "default_service", settings, hotkeyData);
obs_service_release(newService);
if (!newService)
@ -962,26 +951,26 @@ void AutoConfig::SaveStreamSettings()
/* save stream settings */
config_set_int(main->Config(), "SimpleOutput", "VBitrate",
idealBitrate);
idealBitrate);
config_set_string(main->Config(), "SimpleOutput", "StreamEncoder",
GetEncoderId(streamingEncoder));
GetEncoderId(streamingEncoder));
config_remove_value(main->Config(), "SimpleOutput", "UseAdvanced");
}
void AutoConfig::SaveSettings()
{
OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
if (recordingEncoder != Encoder::Stream)
config_set_string(main->Config(), "SimpleOutput", "RecEncoder",
GetEncoderId(recordingEncoder));
GetEncoderId(recordingEncoder));
const char *quality = recordingQuality == Quality::High
? "Small"
: "Stream";
const char *quality = recordingQuality == Quality::High ? "Small"
: "Stream";
config_set_string(main->Config(), "Output", "Mode", "Simple");
config_set_string(main->Config(), "SimpleOutput", "RecQuality", quality);
config_set_string(main->Config(), "SimpleOutput", "RecQuality",
quality);
config_set_int(main->Config(), "Video", "BaseCX", baseResolutionCX);
config_set_int(main->Config(), "Video", "BaseCY", baseResolutionCY);
config_set_int(main->Config(), "Video", "OutputCX", idealResolutionCX);
@ -990,7 +979,7 @@ void AutoConfig::SaveSettings()
if (fpsType != FPSType::UseCurrent) {
config_set_uint(main->Config(), "Video", "FPSType", 0);
config_set_string(main->Config(), "Video", "FPSCommon",
std::to_string(idealFPSNum).c_str());
std::to_string(idealFPSNum).c_str());
}
main->ResetVideo();

View file

@ -32,13 +32,13 @@ class AutoConfig : public QWizard {
enum class Type {
Invalid,
Streaming,
Recording
Recording,
};
enum class Service {
Twitch,
Smashcast,
Other
Other,
};
enum class Encoder {
@ -46,12 +46,12 @@ class AutoConfig : public QWizard {
NVENC,
QSV,
AMD,
Stream
Stream,
};
enum class Quality {
Stream,
High
High,
};
enum class FPSType : int {
@ -59,7 +59,7 @@ class AutoConfig : public QWizard {
PreferHighRes,
UseCurrent,
fps30,
fps60
fps60,
};
static inline const char *GetEncoderId(Encoder enc);
@ -119,7 +119,7 @@ public:
StartPage,
VideoPage,
StreamPage,
TestPage
TestPage,
};
};
@ -216,7 +216,7 @@ class AutoConfigTestPage : public QWizardPage {
BandwidthTest,
StreamEncoder,
RecordingEncoder,
Finished
Finished,
};
Stage stage = Stage::Starting;

View file

@ -36,45 +36,39 @@ using namespace std;
Q_DECLARE_METATYPE(OBSSource);
OBSBasicFilters::OBSBasicFilters(QWidget *parent, OBSSource source_)
: QDialog (parent),
ui (new Ui::OBSBasicFilters),
source (source_),
addSignal (obs_source_get_signal_handler(source),
"filter_add",
OBSBasicFilters::OBSSourceFilterAdded,
this),
removeSignal (obs_source_get_signal_handler(source),
"filter_remove",
OBSBasicFilters::OBSSourceFilterRemoved,
this),
reorderSignal (obs_source_get_signal_handler(source),
"reorder_filters",
OBSBasicFilters::OBSSourceReordered,
this),
removeSourceSignal (obs_source_get_signal_handler(source),
"remove",
OBSBasicFilters::SourceRemoved, this),
renameSourceSignal (obs_source_get_signal_handler(source),
"rename",
OBSBasicFilters::SourceRenamed, this),
noPreviewMargin (13)
: QDialog(parent),
ui(new Ui::OBSBasicFilters),
source(source_),
addSignal(obs_source_get_signal_handler(source), "filter_add",
OBSBasicFilters::OBSSourceFilterAdded, this),
removeSignal(obs_source_get_signal_handler(source), "filter_remove",
OBSBasicFilters::OBSSourceFilterRemoved, this),
reorderSignal(obs_source_get_signal_handler(source),
"reorder_filters", OBSBasicFilters::OBSSourceReordered,
this),
removeSourceSignal(obs_source_get_signal_handler(source), "remove",
OBSBasicFilters::SourceRemoved, this),
renameSourceSignal(obs_source_get_signal_handler(source), "rename",
OBSBasicFilters::SourceRenamed, this),
noPreviewMargin(13)
{
main = reinterpret_cast<OBSBasic*>(parent);
main = reinterpret_cast<OBSBasic *>(parent);
ui->setupUi(this);
UpdateFilters();
ui->asyncFilters->setItemDelegate(
new VisibilityItemDelegate(ui->asyncFilters));
new VisibilityItemDelegate(ui->asyncFilters));
ui->effectFilters->setItemDelegate(
new VisibilityItemDelegate(ui->effectFilters));
new VisibilityItemDelegate(ui->effectFilters));
const char *name = obs_source_get_name(source);
setWindowTitle(QTStr("Basic.Filters.Title").arg(QT_UTF8(name)));
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
#ifndef QT_NO_SHORTCUT
ui->actionRemoveFilter->setShortcut(QApplication::translate("OBSBasicFilters", "Del", nullptr));
ui->actionRemoveFilter->setShortcut(
QApplication::translate("OBSBasicFilters", "Del", nullptr));
#endif // QT_NO_SHORTCUT
addAction(ui->actionRemoveFilter);
@ -84,33 +78,33 @@ OBSBasicFilters::OBSBasicFilters(QWidget *parent, OBSSource source_)
installEventFilter(CreateShortcutFilter());
connect(ui->asyncFilters->itemDelegate(),
SIGNAL(closeEditor(QWidget*,
QAbstractItemDelegate::EndEditHint)),
this,
SLOT(AsyncFilterNameEdited(QWidget*,
QAbstractItemDelegate::EndEditHint)));
SIGNAL(closeEditor(QWidget *,
QAbstractItemDelegate::EndEditHint)),
this,
SLOT(AsyncFilterNameEdited(
QWidget *, QAbstractItemDelegate::EndEditHint)));
connect(ui->effectFilters->itemDelegate(),
SIGNAL(closeEditor(QWidget*,
QAbstractItemDelegate::EndEditHint)),
this,
SLOT(EffectFilterNameEdited(QWidget*,
QAbstractItemDelegate::EndEditHint)));
SIGNAL(closeEditor(QWidget *,
QAbstractItemDelegate::EndEditHint)),
this,
SLOT(EffectFilterNameEdited(
QWidget *, QAbstractItemDelegate::EndEditHint)));
QPushButton *close = ui->buttonBox->button(QDialogButtonBox::Close);
connect(close, SIGNAL(clicked()), this, SLOT(close()));
close->setDefault(true);
ui->buttonBox->button(QDialogButtonBox::Reset)->setText(
QTStr("Defaults"));
ui->buttonBox->button(QDialogButtonBox::Reset)
->setText(QTStr("Defaults"));
connect(ui->buttonBox->button(QDialogButtonBox::Reset),
SIGNAL(clicked()), this, SLOT(ResetFilters()));
uint32_t caps = obs_source_get_output_flags(source);
bool audio = (caps & OBS_SOURCE_AUDIO) != 0;
bool audio = (caps & OBS_SOURCE_AUDIO) != 0;
bool audioOnly = (caps & OBS_SOURCE_VIDEO) == 0;
bool async = (caps & OBS_SOURCE_ASYNC) != 0;
bool async = (caps & OBS_SOURCE_ASYNC) != 0;
if (!async && !audio) {
ui->asyncWidget->setVisible(false);
@ -124,22 +118,22 @@ OBSBasicFilters::OBSBasicFilters(QWidget *parent, OBSSource source_)
if (audioOnly || (audio && !async))
ui->asyncLabel->setText(QTStr("Basic.Filters.AudioFilters"));
auto addDrawCallback = [this] ()
{
auto addDrawCallback = [this]() {
obs_display_add_draw_callback(ui->preview->GetDisplay(),
OBSBasicFilters::DrawPreview, this);
OBSBasicFilters::DrawPreview,
this);
};
enum obs_source_type type = obs_source_get_type(source);
bool drawable_type = type == OBS_SOURCE_TYPE_INPUT ||
type == OBS_SOURCE_TYPE_SCENE;
type == OBS_SOURCE_TYPE_SCENE;
if ((caps & OBS_SOURCE_VIDEO) != 0) {
ui->rightLayout->setContentsMargins(0, 0, 0, 0);
ui->preview->show();
if (drawable_type)
connect(ui->preview, &OBSQTDisplay::DisplayCreated,
addDrawCallback);
addDrawCallback);
} else {
ui->rightLayout->setContentsMargins(0, noPreviewMargin, 0, 0);
ui->rightContainerLayout->insertStretch(1);
@ -187,14 +181,14 @@ void OBSBasicFilters::UpdatePropertiesView(int row, bool async)
obs_data_t *settings = obs_source_get_settings(filter);
view = new OBSPropertiesView(settings, filter,
(PropertiesReloadCallback)obs_source_properties,
(PropertiesUpdateCallback)obs_source_update);
view = new OBSPropertiesView(
settings, filter,
(PropertiesReloadCallback)obs_source_properties,
(PropertiesUpdateCallback)obs_source_update);
updatePropertiesSignal.Connect(obs_source_get_signal_handler(filter),
"update_properties",
OBSBasicFilters::UpdateProperties,
this);
"update_properties",
OBSBasicFilters::UpdateProperties, this);
obs_data_release(settings);
@ -206,8 +200,8 @@ void OBSBasicFilters::UpdatePropertiesView(int row, bool async)
void OBSBasicFilters::UpdateProperties(void *data, calldata_t *)
{
QMetaObject::invokeMethod(static_cast<OBSBasicFilters*>(data)->view,
"ReloadProperties");
QMetaObject::invokeMethod(static_cast<OBSBasicFilters *>(data)->view,
"ReloadProperties");
}
void OBSBasicFilters::AddFilter(OBSSource filter)
@ -252,7 +246,7 @@ void OBSBasicFilters::RemoveFilter(OBSSource filter)
const char *filterId = obs_source_get_id(filter);
blog(LOG_INFO, "User removed filter '%s' (%s) from source '%s'",
filterName, filterId, sourceName);
filterName, filterId, sourceName);
main->SaveProject();
}
@ -265,8 +259,8 @@ struct FilterOrderInfo {
inline FilterOrderInfo(OBSBasicFilters *window_) : window(window_) {}
};
void OBSBasicFilters::ReorderFilter(QListWidget *list,
obs_source_t *filter, size_t idx)
void OBSBasicFilters::ReorderFilter(QListWidget *list, obs_source_t *filter,
size_t idx)
{
int count = list->count();
@ -280,10 +274,10 @@ void OBSBasicFilters::ReorderFilter(QListWidget *list,
bool sel = (list->currentRow() == i);
listItem = TakeListItem(list, i);
if (listItem) {
if (listItem) {
list->insertItem((int)idx, listItem);
SetupVisibilityItem(list,
listItem, filterItem);
SetupVisibilityItem(list, listItem,
filterItem);
if (sel)
list->setCurrentRow((int)idx);
@ -299,27 +293,28 @@ void OBSBasicFilters::ReorderFilters()
{
FilterOrderInfo info(this);
obs_source_enum_filters(source,
[] (obs_source_t*, obs_source_t *filter, void *p)
{
FilterOrderInfo *info =
reinterpret_cast<FilterOrderInfo*>(p);
uint32_t flags;
bool async;
obs_source_enum_filters(
source,
[](obs_source_t *, obs_source_t *filter, void *p) {
FilterOrderInfo *info =
reinterpret_cast<FilterOrderInfo *>(p);
uint32_t flags;
bool async;
flags = obs_source_get_output_flags(filter);
async = (flags & OBS_SOURCE_ASYNC) != 0;
flags = obs_source_get_output_flags(filter);
async = (flags & OBS_SOURCE_ASYNC) != 0;
if (async) {
info->window->ReorderFilter(
info->window->ui->asyncFilters,
filter, info->asyncIdx++);
} else {
info->window->ReorderFilter(
info->window->ui->effectFilters,
filter, info->effectIdx++);
}
}, &info);
if (async) {
info->window->ReorderFilter(
info->window->ui->asyncFilters, filter,
info->asyncIdx++);
} else {
info->window->ReorderFilter(
info->window->ui->effectFilters, filter,
info->effectIdx++);
}
},
&info);
}
void OBSBasicFilters::UpdateFilters()
@ -330,33 +325,34 @@ void OBSBasicFilters::UpdateFilters()
ClearListItems(ui->effectFilters);
ClearListItems(ui->asyncFilters);
obs_source_enum_filters(source,
[] (obs_source_t*, obs_source_t *filter, void *p)
{
OBSBasicFilters *window =
reinterpret_cast<OBSBasicFilters*>(p);
obs_source_enum_filters(
source,
[](obs_source_t *, obs_source_t *filter, void *p) {
OBSBasicFilters *window =
reinterpret_cast<OBSBasicFilters *>(p);
window->AddFilter(filter);
}, this);
window->AddFilter(filter);
},
this);
main->SaveProject();
}
static bool filter_compatible(bool async, uint32_t sourceFlags,
uint32_t filterFlags)
uint32_t filterFlags)
{
bool filterVideo = (filterFlags & OBS_SOURCE_VIDEO) != 0;
bool filterAsync = (filterFlags & OBS_SOURCE_ASYNC) != 0;
bool filterAudio = (filterFlags & OBS_SOURCE_AUDIO) != 0;
bool audio = (sourceFlags & OBS_SOURCE_AUDIO) != 0;
bool audioOnly = (sourceFlags & OBS_SOURCE_VIDEO) == 0;
bool audio = (sourceFlags & OBS_SOURCE_AUDIO) != 0;
bool audioOnly = (sourceFlags & OBS_SOURCE_VIDEO) == 0;
bool asyncSource = (sourceFlags & OBS_SOURCE_ASYNC) != 0;
if (async && ((audioOnly && filterVideo) || (!audio && !asyncSource)))
return false;
return (async && (filterAudio || filterAsync)) ||
(!async && !filterAudio && !filterAsync);
(!async && !filterAudio && !filterAsync);
}
QMenu *OBSBasicFilters::CreateAddFilterPopupMenu(bool async)
@ -372,7 +368,8 @@ QMenu *OBSBasicFilters::CreateAddFilterPopupMenu(bool async)
inline FilterInfo(const char *type_, const char *name_)
: type(type_), name(name_)
{}
{
}
};
vector<FilterInfo> types;
@ -396,17 +393,17 @@ QMenu *OBSBasicFilters::CreateAddFilterPopupMenu(bool async)
QMenu *popup = new QMenu(QTStr("Add"), this);
for (FilterInfo &type : types) {
uint32_t filterFlags = obs_get_source_output_flags(
type.type.c_str());
uint32_t filterFlags =
obs_get_source_output_flags(type.type.c_str());
if (!filter_compatible(async, sourceFlags, filterFlags))
continue;
QAction *popupItem = new QAction(QT_UTF8(type.name.c_str()),
this);
QAction *popupItem =
new QAction(QT_UTF8(type.name.c_str()), this);
popupItem->setData(QT_UTF8(type.type.c_str()));
connect(popupItem, SIGNAL(triggered(bool)),
this, SLOT(AddFilterFromAction()));
connect(popupItem, SIGNAL(triggered(bool)), this,
SLOT(AddFilterFromAction()));
popup->addAction(popupItem);
foundValues = true;
@ -426,40 +423,40 @@ void OBSBasicFilters::AddNewFilter(const char *id)
obs_source_t *existing_filter;
string name = obs_source_get_display_name(id);
bool success = NameDialog::AskForName(this,
QTStr("Basic.Filters.AddFilter.Title"),
QTStr("Basic.FIlters.AddFilter.Text"), name,
QT_UTF8(name.c_str()));
bool success = NameDialog::AskForName(
this, QTStr("Basic.Filters.AddFilter.Title"),
QTStr("Basic.FIlters.AddFilter.Text"), name,
QT_UTF8(name.c_str()));
if (!success)
return;
if (name.empty()) {
OBSMessageBox::warning(this,
QTStr("NoNameEntered.Title"),
QTStr("NoNameEntered.Text"));
QTStr("NoNameEntered.Title"),
QTStr("NoNameEntered.Text"));
AddNewFilter(id);
return;
}
existing_filter = obs_source_get_filter_by_name(source,
name.c_str());
existing_filter =
obs_source_get_filter_by_name(source, name.c_str());
if (existing_filter) {
OBSMessageBox::warning(this,
QTStr("NameExists.Title"),
QTStr("NameExists.Text"));
OBSMessageBox::warning(this, QTStr("NameExists.Title"),
QTStr("NameExists.Text"));
obs_source_release(existing_filter);
AddNewFilter(id);
return;
}
obs_source_t *filter = obs_source_create(id, name.c_str(),
nullptr, nullptr);
obs_source_t *filter =
obs_source_create(id, name.c_str(), nullptr, nullptr);
if (filter) {
const char *sourceName = obs_source_get_name(source);
blog(LOG_INFO, "User added filter '%s' (%s) "
"to source '%s'",
name.c_str(), id, sourceName);
blog(LOG_INFO,
"User added filter '%s' (%s) "
"to source '%s'",
name.c_str(), id, sourceName);
obs_source_filter_add(source, filter);
obs_source_release(filter);
@ -469,7 +466,7 @@ void OBSBasicFilters::AddNewFilter(const char *id)
void OBSBasicFilters::AddFilterFromAction()
{
QAction *action = qobject_cast<QAction*>(sender());
QAction *action = qobject_cast<QAction *>(sender());
if (!action)
return;
@ -482,8 +479,8 @@ void OBSBasicFilters::closeEvent(QCloseEvent *event)
if (!event->isAccepted())
return;
obs_display_remove_draw_callback (ui->preview->GetDisplay(),
OBSBasicFilters::DrawPreview, this);
obs_display_remove_draw_callback(ui->preview->GetDisplay(),
OBSBasicFilters::DrawPreview, this);
main->SaveProject();
}
@ -492,26 +489,26 @@ void OBSBasicFilters::closeEvent(QCloseEvent *event)
void OBSBasicFilters::OBSSourceFilterAdded(void *param, calldata_t *data)
{
OBSBasicFilters *window = reinterpret_cast<OBSBasicFilters*>(param);
obs_source_t *filter = (obs_source_t*)calldata_ptr(data, "filter");
OBSBasicFilters *window = reinterpret_cast<OBSBasicFilters *>(param);
obs_source_t *filter = (obs_source_t *)calldata_ptr(data, "filter");
QMetaObject::invokeMethod(window, "AddFilter",
Q_ARG(OBSSource, OBSSource(filter)));
Q_ARG(OBSSource, OBSSource(filter)));
}
void OBSBasicFilters::OBSSourceFilterRemoved(void *param, calldata_t *data)
{
OBSBasicFilters *window = reinterpret_cast<OBSBasicFilters*>(param);
obs_source_t *filter = (obs_source_t*)calldata_ptr(data, "filter");
OBSBasicFilters *window = reinterpret_cast<OBSBasicFilters *>(param);
obs_source_t *filter = (obs_source_t *)calldata_ptr(data, "filter");
QMetaObject::invokeMethod(window, "RemoveFilter",
Q_ARG(OBSSource, OBSSource(filter)));
Q_ARG(OBSSource, OBSSource(filter)));
}
void OBSBasicFilters::OBSSourceReordered(void *param, calldata_t *data)
{
QMetaObject::invokeMethod(reinterpret_cast<OBSBasicFilters*>(param),
"ReorderFilters");
QMetaObject::invokeMethod(reinterpret_cast<OBSBasicFilters *>(param),
"ReorderFilters");
UNUSED_PARAMETER(data);
}
@ -520,8 +517,8 @@ void OBSBasicFilters::SourceRemoved(void *param, calldata_t *data)
{
UNUSED_PARAMETER(data);
QMetaObject::invokeMethod(static_cast<OBSBasicFilters*>(param),
"close");
QMetaObject::invokeMethod(static_cast<OBSBasicFilters *>(param),
"close");
}
void OBSBasicFilters::SourceRenamed(void *param, calldata_t *data)
@ -529,13 +526,13 @@ void OBSBasicFilters::SourceRenamed(void *param, calldata_t *data)
const char *name = calldata_string(data, "new_name");
QString title = QTStr("Basic.Filters.Title").arg(QT_UTF8(name));
QMetaObject::invokeMethod(static_cast<OBSBasicFilters*>(param),
"setWindowTitle", Q_ARG(QString, title));
QMetaObject::invokeMethod(static_cast<OBSBasicFilters *>(param),
"setWindowTitle", Q_ARG(QString, title));
}
void OBSBasicFilters::DrawPreview(void *data, uint32_t cx, uint32_t cy)
{
OBSBasicFilters *window = static_cast<OBSBasicFilters*>(data);
OBSBasicFilters *window = static_cast<OBSBasicFilters *>(data);
if (!window->source)
return;
@ -543,8 +540,8 @@ void OBSBasicFilters::DrawPreview(void *data, uint32_t cx, uint32_t cy)
uint32_t sourceCX = max(obs_source_get_width(window->source), 1u);
uint32_t sourceCY = max(obs_source_get_height(window->source), 1u);
int x, y;
int newCX, newCY;
int x, y;
int newCX, newCY;
float scale;
GetScaleAndCenterPos(sourceCX, sourceCY, cx, cy, x, y, scale);
@ -567,15 +564,15 @@ void OBSBasicFilters::DrawPreview(void *data, uint32_t cx, uint32_t cy)
static bool QueryRemove(QWidget *parent, obs_source_t *source)
{
const char *name = obs_source_get_name(source);
const char *name = obs_source_get_name(source);
QString text = QTStr("ConfirmRemove.Text");
text.replace("$1", QT_UTF8(name));
QMessageBox remove_source(parent);
remove_source.setText(text);
QAbstractButton *Yes = remove_source.addButton(QTStr("Yes"),
QMessageBox::YesRole);
QAbstractButton *Yes =
remove_source.addButton(QTStr("Yes"), QMessageBox::YesRole);
remove_source.addButton(QTStr("No"), QMessageBox::NoRole);
remove_source.setIcon(QMessageBox::Question);
remove_source.setWindowTitle(QTStr("ConfirmRemove.Title"));
@ -612,7 +609,7 @@ void OBSBasicFilters::on_moveAsyncFilterDown_clicked()
OBSSource filter = GetFilter(ui->asyncFilters->currentRow(), true);
if (filter)
obs_source_filter_set_order(source, filter,
OBS_ORDER_MOVE_DOWN);
OBS_ORDER_MOVE_DOWN);
}
void OBSBasicFilters::on_asyncFilters_GotFocus()
@ -654,7 +651,7 @@ void OBSBasicFilters::on_moveEffectFilterDown_clicked()
OBSSource filter = GetFilter(ui->effectFilters->currentRow(), false);
if (filter)
obs_source_filter_set_order(source, filter,
OBS_ORDER_MOVE_DOWN);
OBS_ORDER_MOVE_DOWN);
}
void OBSBasicFilters::on_effectFilters_GotFocus()
@ -704,11 +701,11 @@ void OBSBasicFilters::CustomContextMenu(const QPoint &pos, bool async)
popup.addMenu(addMenu);
if (item) {
const char *renameSlot = async ?
SLOT(RenameAsyncFilter()) : SLOT(RenameEffectFilter());
const char *removeSlot = async ?
SLOT(on_removeAsyncFilter_clicked()) :
SLOT(on_removeEffectFilter_clicked());
const char *renameSlot = async ? SLOT(RenameAsyncFilter())
: SLOT(RenameEffectFilter());
const char *removeSlot =
async ? SLOT(on_removeAsyncFilter_clicked())
: SLOT(on_removeEffectFilter_clicked());
popup.addSeparator();
popup.addAction(QTStr("Rename"), this, renameSlot);
@ -721,9 +718,9 @@ void OBSBasicFilters::CustomContextMenu(const QPoint &pos, bool async)
void OBSBasicFilters::EditItem(QListWidgetItem *item, bool async)
{
Qt::ItemFlags flags = item->flags();
OBSSource filter = item->data(Qt::UserRole).value<OBSSource>();
const char *name = obs_source_get_name(filter);
QListWidget *list = async ? ui->asyncFilters : ui->effectFilters;
OBSSource filter = item->data(Qt::UserRole).value<OBSSource>();
const char *name = obs_source_get_name(filter);
QListWidget *list = async ? ui->asyncFilters : ui->effectFilters;
item->setText(QT_UTF8(name));
item->setFlags(flags | Qt::ItemIsEditable);
@ -733,13 +730,13 @@ void OBSBasicFilters::EditItem(QListWidgetItem *item, bool async)
}
void OBSBasicFilters::on_asyncFilters_customContextMenuRequested(
const QPoint &pos)
const QPoint &pos)
{
CustomContextMenu(pos, true);
}
void OBSBasicFilters::on_effectFilters_customContextMenuRequested(
const QPoint &pos)
const QPoint &pos)
{
CustomContextMenu(pos, false);
}
@ -758,7 +755,7 @@ void OBSBasicFilters::FilterNameEdited(QWidget *editor, QListWidget *list)
{
QListWidgetItem *listItem = list->currentItem();
OBSSource filter = listItem->data(Qt::UserRole).value<OBSSource>();
QLineEdit *edit = qobject_cast<QLineEdit*>(editor);
QLineEdit *edit = qobject_cast<QLineEdit *>(editor);
string name = QT_TO_UTF8(edit->text().trimmed());
const char *prevName = obs_source_get_name(filter);
@ -766,28 +763,29 @@ void OBSBasicFilters::FilterNameEdited(QWidget *editor, QListWidget *list)
obs_source_t *foundFilter = nullptr;
if (!sameName)
foundFilter = obs_source_get_filter_by_name(source,
name.c_str());
foundFilter =
obs_source_get_filter_by_name(source, name.c_str());
if (foundFilter || name.empty() || sameName) {
listItem->setText(QT_UTF8(prevName));
if (foundFilter) {
OBSMessageBox::information(window(),
QTStr("NameExists.Title"),
QTStr("NameExists.Text"));
QTStr("NameExists.Title"),
QTStr("NameExists.Text"));
obs_source_release(foundFilter);
} else if (name.empty()) {
OBSMessageBox::information(window(),
QTStr("NoNameEntered.Title"),
QTStr("NoNameEntered.Text"));
QTStr("NoNameEntered.Title"),
QTStr("NoNameEntered.Text"));
}
} else {
const char *sourceName = obs_source_get_name(source);
blog(LOG_INFO, "User renamed filter '%s' on source '%s' to '%s'",
prevName, sourceName, name.c_str());
blog(LOG_INFO,
"User renamed filter '%s' on source '%s' to '%s'",
prevName, sourceName, name.c_str());
listItem->setText(QT_UTF8(name.c_str()));
obs_source_set_name(filter, name.c_str());
@ -797,15 +795,15 @@ void OBSBasicFilters::FilterNameEdited(QWidget *editor, QListWidget *list)
SetupVisibilityItem(list, listItem, filter);
}
void OBSBasicFilters::AsyncFilterNameEdited(QWidget *editor,
QAbstractItemDelegate::EndEditHint endHint)
void OBSBasicFilters::AsyncFilterNameEdited(
QWidget *editor, QAbstractItemDelegate::EndEditHint endHint)
{
FilterNameEdited(editor, ui->asyncFilters);
UNUSED_PARAMETER(endHint);
}
void OBSBasicFilters::EffectFilterNameEdited(QWidget *editor,
QAbstractItemDelegate::EndEditHint endHint)
void OBSBasicFilters::EffectFilterNameEdited(
QWidget *editor, QAbstractItemDelegate::EndEditHint endHint)
{
FilterNameEdited(editor, ui->effectFilters);
UNUSED_PARAMETER(endHint);

View file

@ -105,9 +105,9 @@ private slots:
void on_actionMoveDown_triggered();
void AsyncFilterNameEdited(QWidget *editor,
QAbstractItemDelegate::EndEditHint endHint);
QAbstractItemDelegate::EndEditHint endHint);
void EffectFilterNameEdited(QWidget *editor,
QAbstractItemDelegate::EndEditHint endHint);
QAbstractItemDelegate::EndEditHint endHint);
public:
OBSBasicFilters(QWidget *parent, OBSSource source_);

View file

@ -29,20 +29,20 @@
using namespace std;
OBSBasicInteraction::OBSBasicInteraction(QWidget *parent, OBSSource source_)
: QDialog (parent),
main (qobject_cast<OBSBasic*>(parent)),
ui (new Ui::OBSBasicInteraction),
source (source_),
removedSignal (obs_source_get_signal_handler(source), "remove",
OBSBasicInteraction::SourceRemoved, this),
renamedSignal (obs_source_get_signal_handler(source), "rename",
OBSBasicInteraction::SourceRenamed, this),
eventFilter (BuildEventFilter())
: QDialog(parent),
main(qobject_cast<OBSBasic *>(parent)),
ui(new Ui::OBSBasicInteraction),
source(source_),
removedSignal(obs_source_get_signal_handler(source), "remove",
OBSBasicInteraction::SourceRemoved, this),
renamedSignal(obs_source_get_signal_handler(source), "rename",
OBSBasicInteraction::SourceRenamed, this),
eventFilter(BuildEventFilter())
{
int cx = (int)config_get_int(App()->GlobalConfig(), "InteractionWindow",
"cx");
"cx");
int cy = (int)config_get_int(App()->GlobalConfig(), "InteractionWindow",
"cy");
"cy");
ui->setupUi(this);
@ -59,10 +59,10 @@ OBSBasicInteraction::OBSBasicInteraction(QWidget *parent, OBSSource source_)
const char *name = obs_source_get_name(source);
setWindowTitle(QTStr("Basic.InteractionWindow").arg(QT_UTF8(name)));
auto addDrawCallback = [this] ()
{
auto addDrawCallback = [this]() {
obs_display_add_draw_callback(ui->preview->GetDisplay(),
OBSBasicInteraction::DrawPreview, this);
OBSBasicInteraction::DrawPreview,
this);
};
connect(ui->preview, &OBSQTDisplay::DisplayCreated, addDrawCallback);
@ -77,34 +77,32 @@ OBSBasicInteraction::~OBSBasicInteraction()
OBSEventFilter *OBSBasicInteraction::BuildEventFilter()
{
return new OBSEventFilter(
[this](QObject *obj, QEvent *event)
{
return new OBSEventFilter([this](QObject *obj, QEvent *event) {
UNUSED_PARAMETER(obj);
switch(event->type()) {
switch (event->type()) {
case QEvent::MouseButtonPress:
case QEvent::MouseButtonRelease:
case QEvent::MouseButtonDblClick:
return this->HandleMouseClickEvent(
static_cast<QMouseEvent *>(event));
static_cast<QMouseEvent *>(event));
case QEvent::MouseMove:
case QEvent::Enter:
case QEvent::Leave:
return this->HandleMouseMoveEvent(
static_cast<QMouseEvent *>(event));
static_cast<QMouseEvent *>(event));
case QEvent::Wheel:
return this->HandleMouseWheelEvent(
static_cast<QWheelEvent *>(event));
static_cast<QWheelEvent *>(event));
case QEvent::FocusIn:
case QEvent::FocusOut:
return this->HandleFocusEvent(
static_cast<QFocusEvent *>(event));
static_cast<QFocusEvent *>(event));
case QEvent::KeyPress:
case QEvent::KeyRelease:
return this->HandleKeyEvent(
static_cast<QKeyEvent *>(event));
static_cast<QKeyEvent *>(event));
default:
return false;
}
@ -113,8 +111,8 @@ OBSEventFilter *OBSBasicInteraction::BuildEventFilter()
void OBSBasicInteraction::SourceRemoved(void *data, calldata_t *params)
{
QMetaObject::invokeMethod(static_cast<OBSBasicInteraction*>(data),
"close");
QMetaObject::invokeMethod(static_cast<OBSBasicInteraction *>(data),
"close");
UNUSED_PARAMETER(params);
}
@ -124,13 +122,13 @@ void OBSBasicInteraction::SourceRenamed(void *data, calldata_t *params)
const char *name = calldata_string(params, "new_name");
QString title = QTStr("Basic.InteractionWindow").arg(QT_UTF8(name));
QMetaObject::invokeMethod(static_cast<OBSBasicProperties*>(data),
"setWindowTitle", Q_ARG(QString, title));
QMetaObject::invokeMethod(static_cast<OBSBasicProperties *>(data),
"setWindowTitle", Q_ARG(QString, title));
}
void OBSBasicInteraction::DrawPreview(void *data, uint32_t cx, uint32_t cy)
{
OBSBasicInteraction *window = static_cast<OBSBasicInteraction*>(data);
OBSBasicInteraction *window = static_cast<OBSBasicInteraction *>(data);
if (!window->source)
return;
@ -138,8 +136,8 @@ void OBSBasicInteraction::DrawPreview(void *data, uint32_t cx, uint32_t cy)
uint32_t sourceCX = max(obs_source_get_width(window->source), 1u);
uint32_t sourceCY = max(obs_source_get_height(window->source), 1u);
int x, y;
int newCX, newCY;
int x, y;
int newCX, newCY;
float scale;
GetScaleAndCenterPos(sourceCX, sourceCY, cx, cy, x, y, scale);
@ -149,8 +147,7 @@ void OBSBasicInteraction::DrawPreview(void *data, uint32_t cx, uint32_t cy)
gs_viewport_push();
gs_projection_push();
gs_ortho(0.0f, float(sourceCX), 0.0f, float(sourceCY),
-100.0f, 100.0f);
gs_ortho(0.0f, float(sourceCX), 0.0f, float(sourceCY), -100.0f, 100.0f);
gs_set_viewport(x, y, newCX, newCY);
obs_source_video_render(window->source);
@ -165,15 +162,18 @@ void OBSBasicInteraction::closeEvent(QCloseEvent *event)
return;
config_set_int(App()->GlobalConfig(), "InteractionWindow", "cx",
width());
width());
config_set_int(App()->GlobalConfig(), "InteractionWindow", "cy",
height());
height());
obs_display_remove_draw_callback(ui->preview->GetDisplay(),
OBSBasicInteraction::DrawPreview, this);
OBSBasicInteraction::DrawPreview,
this);
}
static int TranslateQtKeyboardEventModifiers(QInputEvent *event, bool mouseEvent) {
static int TranslateQtKeyboardEventModifiers(QInputEvent *event,
bool mouseEvent)
{
int obsModifiers = INTERACT_NONE;
if (event->modifiers().testFlag(Qt::ShiftModifier))
@ -200,8 +200,7 @@ static int TranslateQtKeyboardEventModifiers(QInputEvent *event, bool mouseEvent
return obsModifiers;
}
static int TranslateQtMouseEventModifiers(
QMouseEvent *event)
static int TranslateQtMouseEventModifiers(QMouseEvent *event)
{
int modifiers = TranslateQtKeyboardEventModifiers(event, true);
@ -215,19 +214,19 @@ static int TranslateQtMouseEventModifiers(
return modifiers;
}
bool OBSBasicInteraction::GetSourceRelativeXY(
int mouseX, int mouseY, int &relX, int &relY)
bool OBSBasicInteraction::GetSourceRelativeXY(int mouseX, int mouseY, int &relX,
int &relY)
{
QSize size = GetPixelSize(ui->preview);
uint32_t sourceCX = max(obs_source_get_width(source), 1u);
uint32_t sourceCY = max(obs_source_get_height(source), 1u);
int x, y;
int x, y;
float scale;
GetScaleAndCenterPos(sourceCX, sourceCY, size.width(), size.height(),
x, y, scale);
GetScaleAndCenterPos(sourceCX, sourceCY, size.width(), size.height(), x,
y, scale);
if (x > 0) {
relX = int(float(mouseX - x) / scale);
@ -246,8 +245,7 @@ bool OBSBasicInteraction::GetSourceRelativeXY(
return true;
}
bool OBSBasicInteraction::HandleMouseClickEvent(
QMouseEvent *event)
bool OBSBasicInteraction::HandleMouseClickEvent(QMouseEvent *event)
{
bool mouseUp = event->type() == QEvent::MouseButtonRelease;
int clickCount = 1;
@ -271,8 +269,7 @@ bool OBSBasicInteraction::HandleMouseClickEvent(
button = MOUSE_RIGHT;
break;
default:
blog(LOG_WARNING, "unknown button type %d",
event->button());
blog(LOG_WARNING, "unknown button type %d", event->button());
return false;
}
@ -281,11 +278,11 @@ bool OBSBasicInteraction::HandleMouseClickEvent(
// clickCount = 2;
bool insideSource = GetSourceRelativeXY(event->x(), event->y(),
mouseEvent.x, mouseEvent.y);
mouseEvent.x, mouseEvent.y);
if (mouseUp || insideSource)
obs_source_send_mouse_click(source, &mouseEvent, button,
mouseUp, clickCount);
mouseUp, clickCount);
return true;
}
@ -299,7 +296,7 @@ bool OBSBasicInteraction::HandleMouseMoveEvent(QMouseEvent *event)
if (!mouseLeave) {
mouseEvent.modifiers = TranslateQtMouseEventModifiers(event);
mouseLeave = !GetSourceRelativeXY(event->x(), event->y(),
mouseEvent.x, mouseEvent.y);
mouseEvent.x, mouseEvent.y);
}
obs_source_send_mouse_move(source, &mouseEvent, mouseLeave);
@ -329,9 +326,9 @@ bool OBSBasicInteraction::HandleMouseWheelEvent(QWheelEvent *event)
}
if (GetSourceRelativeXY(event->x(), event->y(), mouseEvent.x,
mouseEvent.y))
mouseEvent.y))
obs_source_send_mouse_wheel(source, &mouseEvent, xDelta,
yDelta);
yDelta);
return true;
}

View file

@ -35,12 +35,12 @@ class OBSBasicInteraction : public QDialog {
Q_OBJECT
private:
OBSBasic *main;
OBSBasic *main;
std::unique_ptr<Ui::OBSBasicInteraction> ui;
OBSSource source;
OBSSignal removedSignal;
OBSSignal renamedSignal;
OBSSource source;
OBSSignal removedSignal;
OBSSignal renamedSignal;
std::unique_ptr<OBSEventFilter> eventFilter;
static void SourceRemoved(void *data, calldata_t *params);
@ -69,13 +69,10 @@ protected:
typedef std::function<bool(QObject *, QEvent *)> EventFilterFunc;
class OBSEventFilter : public QObject
{
class OBSEventFilter : public QObject {
Q_OBJECT
public:
OBSEventFilter(EventFilterFunc filter_)
: filter(filter_)
{}
OBSEventFilter(EventFilterFunc filter_) : filter(filter_) {}
protected:
bool eventFilter(QObject *obj, QEvent *event)

View file

@ -30,7 +30,7 @@
struct QCef;
struct QCefCookieManager;
extern QCef *cef;
extern QCef *cef;
extern QCefCookieManager *panel_cookies;
static std::string GenId()
@ -52,7 +52,8 @@ void CheckExistingCookieId()
if (config_has_user_value(main->Config(), "Panels", "CookieId"))
return;
config_set_string(main->Config(), "Panels", "CookieId", GenId().c_str());
config_set_string(main->Config(), "Panels", "CookieId",
GenId().c_str());
}
#ifdef BROWSER_AVAILABLE
@ -66,8 +67,8 @@ static void InitPanelCookieManager()
CheckExistingCookieId();
OBSBasic *main = OBSBasic::Get();
const char *cookie_id = config_get_string(main->Config(),
"Panels", "CookieId");
const char *cookie_id =
config_get_string(main->Config(), "Panels", "CookieId");
std::string sub_path;
sub_path += "obs_profile_cookies/";
@ -102,8 +103,8 @@ void DuplicateCurrentCookieProfile(ConfigFile &config)
#ifdef BROWSER_AVAILABLE
if (cef) {
OBSBasic *main = OBSBasic::Get();
std::string cookie_id = config_get_string(main->Config(),
"Panels", "CookieId");
std::string cookie_id =
config_get_string(main->Config(), "Panels", "CookieId");
std::string src_path;
src_path += "obs_profile_cookies/";
@ -136,9 +137,9 @@ void DuplicateCurrentCookieProfile(ConfigFile &config)
}
config_set_string(config, "Panels", "CookieId",
cookie_id.c_str());
cookie_id.c_str());
config_set_string(main->Config(), "Panels", "CookieId",
new_id.c_str());
new_id.c_str());
}
#else
UNUSED_PARAMETER(config);
@ -155,10 +156,9 @@ void OBSBasic::InitBrowserPanelSafeBlock()
return;
}
ExecThreadedWithoutBlocking(
[] {cef->wait_for_browser_init();},
QTStr("BrowserPanelInit.Title"),
QTStr("BrowserPanelInit.Text"));
ExecThreadedWithoutBlocking([] { cef->wait_for_browser_init(); },
QTStr("BrowserPanelInit.Title"),
QTStr("BrowserPanelInit.Text"));
InitPanelCookieManager();
#endif
}

View file

@ -11,34 +11,29 @@
using namespace std;
static const char *textExtensions[] = {
"txt", "log", nullptr
};
static const char *textExtensions[] = {"txt", "log", nullptr};
static const char *imageExtensions[] = {
"bmp", "tga", "png", "jpg", "jpeg", "gif", nullptr
};
static const char *imageExtensions[] = {"bmp", "tga", "png", "jpg",
"jpeg", "gif", nullptr};
static const char *htmlExtensions[] = {
"htm", "html", nullptr
};
static const char *htmlExtensions[] = {"htm", "html", nullptr};
static const char *mediaExtensions[] = {
"3ga", "669", "a52", "aac", "ac3", "adt", "adts", "aif", "aifc",
"aiff", "amb", "amr", "aob", "ape", "au", "awb", "caf", "dts",
"flac", "it", "kar", "m4a", "m4b", "m4p", "m5p", "mid", "mka",
"mlp", "mod", "mpa", "mp1", "mp2", "mp3", "mpc", "mpga", "mus",
"oga", "ogg", "oma", "opus", "qcp", "ra", "rmi", "s3m", "sid",
"spx", "tak", "thd", "tta", "voc", "vqf", "w64", "wav", "wma",
"wv", "xa", "xm", "3g2", "3gp", "3gp2", "3gpp", "amv", "asf", "avi",
"bik", "crf", "divx", "drc", "dv", "evo", "f4v", "flv", "gvi",
"gxf", "iso", "m1v", "m2v", "m2t", "m2ts", "m4v", "mkv", "mov",
"mp2", "mp2v", "mp4", "mp4v", "mpe", "mpeg", "mpeg1", "mpeg2",
"mpeg4", "mpg", "mpv2", "mts", "mtv", "mxf", "mxg", "nsv", "nuv",
"ogg", "ogm", "ogv", "ogx", "ps", "rec", "rm", "rmvb", "rpl", "thp",
"tod", "ts", "tts", "txd", "vob", "vro", "webm", "wm", "wmv", "wtv",
nullptr
};
"3ga", "669", "a52", "aac", "ac3", "adt", "adts", "aif",
"aifc", "aiff", "amb", "amr", "aob", "ape", "au", "awb",
"caf", "dts", "flac", "it", "kar", "m4a", "m4b", "m4p",
"m5p", "mid", "mka", "mlp", "mod", "mpa", "mp1", "mp2",
"mp3", "mpc", "mpga", "mus", "oga", "ogg", "oma", "opus",
"qcp", "ra", "rmi", "s3m", "sid", "spx", "tak", "thd",
"tta", "voc", "vqf", "w64", "wav", "wma", "wv", "xa",
"xm", "3g2", "3gp", "3gp2", "3gpp", "amv", "asf", "avi",
"bik", "crf", "divx", "drc", "dv", "evo", "f4v", "flv",
"gvi", "gxf", "iso", "m1v", "m2v", "m2t", "m2ts", "m4v",
"mkv", "mov", "mp2", "mp2v", "mp4", "mp4v", "mpe", "mpeg",
"mpeg1", "mpeg2", "mpeg4", "mpg", "mpv2", "mts", "mtv", "mxf",
"mxg", "nsv", "nuv", "ogg", "ogm", "ogv", "ogx", "ps",
"rec", "rm", "rmvb", "rpl", "thp", "tod", "ts", "tts",
"txd", "vob", "vro", "webm", "wm", "wmv", "wtv", nullptr};
static string GenerateSourceName(const char *base)
{
@ -50,7 +45,7 @@ static string GenerateSourceName(const char *base)
if (inc) {
name += " (";
name += to_string(inc+1);
name += to_string(inc + 1);
name += ")";
}
@ -62,7 +57,7 @@ static string GenerateSourceName(const char *base)
void OBSBasic::AddDropSource(const char *data, DropType image)
{
OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
obs_data_t *settings = obs_data_create();
obs_source_t *source = nullptr;
const char *type = nullptr;
@ -115,8 +110,8 @@ void OBSBasic::AddDropSource(const char *data, DropType image)
if (name.isEmpty())
name = obs_source_get_display_name(type);
source = obs_source_create(type,
GenerateSourceName(QT_TO_UTF8(name)).c_str(),
settings, nullptr);
GenerateSourceName(QT_TO_UTF8(name)).c_str(),
settings, nullptr);
if (source) {
OBSScene scene = main->GetCurrentScene();
obs_scene_add(scene, source);
@ -143,7 +138,7 @@ void OBSBasic::dragMoveEvent(QDragMoveEvent *event)
void OBSBasic::dropEvent(QDropEvent *event)
{
const QMimeData* mimeData = event->mimeData();
const QMimeData *mimeData = event->mimeData();
if (mimeData->hasUrls()) {
QList<QUrl> urls = mimeData->urls();
@ -162,20 +157,20 @@ void OBSBasic::dropEvent(QDropEvent *event)
const char **cmp;
#define CHECK_SUFFIX(extensions, type) \
cmp = extensions; \
while (*cmp) { \
if (strcmp(*cmp, suffix) == 0) { \
AddDropSource(QT_TO_UTF8(file), type); \
found = true; \
break; \
} \
\
cmp++; \
} \
\
if (found) \
continue;
#define CHECK_SUFFIX(extensions, type) \
cmp = extensions; \
while (*cmp) { \
if (strcmp(*cmp, suffix) == 0) { \
AddDropSource(QT_TO_UTF8(file), type); \
found = true; \
break; \
} \
\
cmp++; \
} \
\
if (found) \
continue;
CHECK_SUFFIX(textExtensions, DropType_Text);
CHECK_SUFFIX(htmlExtensions, DropType_Html);
@ -188,4 +183,3 @@ if (found) \
AddDropSource(QT_TO_UTF8(mimeData->text()), DropType_RawText);
}
}

File diff suppressed because it is too large Load diff

View file

@ -5,49 +5,49 @@
class OBSBasic;
struct BasicOutputHandler {
OBSOutput fileOutput;
OBSOutput streamOutput;
OBSOutput replayBuffer;
bool streamingActive = false;
bool recordingActive = false;
bool delayActive = false;
bool replayBufferActive = false;
OBSBasic *main;
OBSOutput fileOutput;
OBSOutput streamOutput;
OBSOutput replayBuffer;
bool streamingActive = false;
bool recordingActive = false;
bool delayActive = false;
bool replayBufferActive = false;
OBSBasic *main;
std::string outputType;
std::string lastError;
std::string outputType;
std::string lastError;
OBSSignal startRecording;
OBSSignal stopRecording;
OBSSignal startReplayBuffer;
OBSSignal stopReplayBuffer;
OBSSignal startStreaming;
OBSSignal stopStreaming;
OBSSignal streamDelayStarting;
OBSSignal streamStopping;
OBSSignal recordStopping;
OBSSignal replayBufferStopping;
OBSSignal startRecording;
OBSSignal stopRecording;
OBSSignal startReplayBuffer;
OBSSignal stopReplayBuffer;
OBSSignal startStreaming;
OBSSignal stopStreaming;
OBSSignal streamDelayStarting;
OBSSignal streamStopping;
OBSSignal recordStopping;
OBSSignal replayBufferStopping;
inline BasicOutputHandler(OBSBasic *main_) : main(main_) {}
virtual ~BasicOutputHandler() {};
virtual ~BasicOutputHandler(){};
virtual bool StartStreaming(obs_service_t *service) = 0;
virtual bool StartRecording() = 0;
virtual bool StartReplayBuffer() {return false;}
virtual bool StartReplayBuffer() { return false; }
virtual void StopStreaming(bool force = false) = 0;
virtual void StopRecording(bool force = false) = 0;
virtual void StopReplayBuffer(bool force = false) {(void)force;}
virtual void StopReplayBuffer(bool force = false) { (void)force; }
virtual bool StreamingActive() const = 0;
virtual bool RecordingActive() const = 0;
virtual bool ReplayBufferActive() const {return false;}
virtual bool ReplayBufferActive() const { return false; }
virtual void Update() = 0;
inline bool Active() const
{
return streamingActive || recordingActive || delayActive ||
replayBufferActive;
replayBufferActive;
}
};

View file

@ -30,13 +30,13 @@ extern void DuplicateCurrentCookieProfile(ConfigFile &config);
extern void CheckExistingCookieId();
extern void DeleteCookies();
void EnumProfiles(std::function<bool (const char *, const char *)> &&cb)
void EnumProfiles(std::function<bool(const char *, const char *)> &&cb)
{
char path[512];
os_glob_t *glob;
int ret = GetConfigPath(path, sizeof(path),
"obs-studio/basic/profiles/*");
"obs-studio/basic/profiles/*");
if (ret <= 0) {
blog(LOG_WARNING, "Failed to get profiles config path");
return;
@ -54,8 +54,7 @@ void EnumProfiles(std::function<bool (const char *, const char *)> &&cb)
if (!glob->gl_pathv[i].directory)
continue;
if (strcmp(dirName, ".") == 0 ||
strcmp(dirName, "..") == 0)
if (strcmp(dirName, ".") == 0 || strcmp(dirName, "..") == 0)
continue;
std::string file = filePath;
@ -80,8 +79,7 @@ void EnumProfiles(std::function<bool (const char *, const char *)> &&cb)
static bool ProfileExists(const char *findName)
{
bool found = false;
auto func = [&](const char *name, const char*)
{
auto func = [&](const char *name, const char *) {
if (strcmp(name, findName) == 0) {
found = true;
return false;
@ -94,28 +92,28 @@ static bool ProfileExists(const char *findName)
}
static bool GetProfileName(QWidget *parent, std::string &name,
std::string &file, const char *title, const char *text,
const char *oldName = nullptr)
std::string &file, const char *title,
const char *text, const char *oldName = nullptr)
{
char path[512];
int ret;
for (;;) {
bool success = NameDialog::AskForName(parent, title, text,
name, QT_UTF8(oldName));
bool success = NameDialog::AskForName(parent, title, text, name,
QT_UTF8(oldName));
if (!success) {
return false;
}
if (name.empty()) {
OBSMessageBox::warning(parent,
QTStr("NoNameEntered.Title"),
QTStr("NoNameEntered.Text"));
QTStr("NoNameEntered.Title"),
QTStr("NoNameEntered.Text"));
continue;
}
if (ProfileExists(name.c_str())) {
OBSMessageBox::warning(parent,
QTStr("NameExists.Title"),
QTStr("NameExists.Text"));
QTStr("NameExists.Title"),
QTStr("NameExists.Text"));
continue;
}
break;
@ -123,7 +121,7 @@ static bool GetProfileName(QWidget *parent, std::string &name,
if (!GetFileSafeName(name.c_str(), file)) {
blog(LOG_WARNING, "Failed to create safe file name for '%s'",
name.c_str());
name.c_str());
return false;
}
@ -137,7 +135,7 @@ static bool GetProfileName(QWidget *parent, std::string &name,
if (!GetClosestUnusedFileName(file, nullptr)) {
blog(LOG_WARNING, "Failed to get closest file name for %s",
file.c_str());
file.c_str());
return false;
}
@ -170,13 +168,14 @@ static bool CopyProfile(const char *fromPartial, const char *to)
if (glob->gl_pathv[i].directory)
continue;
ret = snprintf(path, sizeof(path), "%s/%s",
to, strrchr(filePath, '/') + 1);
ret = snprintf(path, sizeof(path), "%s/%s", to,
strrchr(filePath, '/') + 1);
if (ret > 0) {
if (os_copyfile(filePath, path) != 0) {
blog(LOG_WARNING, "CopyProfile: Failed to "
"copy file %s to %s",
filePath, path);
blog(LOG_WARNING,
"CopyProfile: Failed to "
"copy file %s to %s",
filePath, path);
}
}
}
@ -187,7 +186,7 @@ static bool CopyProfile(const char *fromPartial, const char *to)
}
bool OBSBasic::AddProfile(bool create_new, const char *title, const char *text,
const char *init_text, bool rename)
const char *init_text, bool rename)
{
std::string newName;
std::string newDir;
@ -197,12 +196,12 @@ bool OBSBasic::AddProfile(bool create_new, const char *title, const char *text,
if (!GetProfileName(this, newName, newDir, title, text, init_text))
return false;
std::string curDir = config_get_string(App()->GlobalConfig(),
"Basic", "ProfileDir");
std::string curDir =
config_get_string(App()->GlobalConfig(), "Basic", "ProfileDir");
char baseDir[512];
int ret = GetConfigPath(baseDir, sizeof(baseDir),
"obs-studio/basic/profiles/");
"obs-studio/basic/profiles/");
if (ret <= 0) {
blog(LOG_WARNING, "Failed to get profiles config path");
return false;
@ -213,7 +212,7 @@ bool OBSBasic::AddProfile(bool create_new, const char *title, const char *text,
if (os_mkdir(newPath.c_str()) < 0) {
blog(LOG_WARNING, "Failed to create profile directory '%s'",
newDir.c_str());
newDir.c_str());
return false;
}
@ -224,14 +223,14 @@ bool OBSBasic::AddProfile(bool create_new, const char *title, const char *text,
if (config.Open(newPath.c_str(), CONFIG_OPEN_ALWAYS) != 0) {
blog(LOG_ERROR, "Failed to open new config file '%s'",
newDir.c_str());
newDir.c_str());
return false;
}
config_set_string(App()->GlobalConfig(), "Basic", "Profile",
newName.c_str());
newName.c_str());
config_set_string(App()->GlobalConfig(), "Basic", "ProfileDir",
newDir.c_str());
newDir.c_str());
Auth::Save();
if (create_new) {
@ -253,7 +252,7 @@ bool OBSBasic::AddProfile(bool create_new, const char *title, const char *text,
ResetProfileData();
blog(LOG_INFO, "Created profile '%s' (%s, %s)", newName.c_str(),
create_new ? "clean" : "duplicate", newDir.c_str());
create_new ? "clean" : "duplicate", newDir.c_str());
blog(LOG_INFO, "------------------------------------------------");
config_save_safe(App()->GlobalConfig(), "tmp", nullptr);
@ -280,14 +279,14 @@ void OBSBasic::DeleteProfile(const char *profileName, const char *profileDir)
ret = snprintf(profilePath, 512, "%s/%s/*", basePath, profileDir);
if (ret <= 0) {
blog(LOG_WARNING, "Failed to get path for profile dir '%s'",
profileDir);
profileDir);
return;
}
os_glob_t *glob;
if (os_glob(profilePath, 0, &glob) != 0) {
blog(LOG_WARNING, "Failed to glob profile dir '%s'",
profileDir);
profileDir);
return;
}
@ -305,21 +304,20 @@ void OBSBasic::DeleteProfile(const char *profileName, const char *profileDir)
ret = snprintf(profilePath, 512, "%s/%s", basePath, profileDir);
if (ret <= 0) {
blog(LOG_WARNING, "Failed to get path for profile dir '%s'",
profileDir);
profileDir);
return;
}
os_rmdir(profilePath);
blog(LOG_INFO, "------------------------------------------------");
blog(LOG_INFO, "Removed profile '%s' (%s)",
profileName, profileDir);
blog(LOG_INFO, "Removed profile '%s' (%s)", profileName, profileDir);
blog(LOG_INFO, "------------------------------------------------");
}
void OBSBasic::RefreshProfiles()
{
QList<QAction*> menuActions = ui->profileMenu->actions();
QList<QAction *> menuActions = ui->profileMenu->actions();
int count = 0;
for (int i = 0; i < menuActions.count(); i++) {
@ -328,17 +326,16 @@ void OBSBasic::RefreshProfiles()
delete menuActions[i];
}
const char *curName = config_get_string(App()->GlobalConfig(),
"Basic", "Profile");
const char *curName =
config_get_string(App()->GlobalConfig(), "Basic", "Profile");
auto addProfile = [&](const char *name, const char *path)
{
auto addProfile = [&](const char *name, const char *path) {
std::string file = strrchr(path, '/') + 1;
QAction *action = new QAction(QT_UTF8(name), this);
action->setProperty("file_name", QT_UTF8(path));
connect(action, &QAction::triggered,
this, &OBSBasic::ChangeProfile);
connect(action, &QAction::triggered, this,
&OBSBasic::ChangeProfile);
action->setCheckable(true);
action->setChecked(strcmp(name, curName) == 0);
@ -364,15 +361,15 @@ void OBSBasic::ResetProfileData()
/* load audio monitoring */
#if defined(_WIN32) || defined(__APPLE__) || HAVE_PULSEAUDIO
const char *device_name = config_get_string(basicConfig, "Audio",
"MonitoringDeviceName");
const char *device_id = config_get_string(basicConfig, "Audio",
"MonitoringDeviceId");
const char *device_name =
config_get_string(basicConfig, "Audio", "MonitoringDeviceName");
const char *device_id =
config_get_string(basicConfig, "Audio", "MonitoringDeviceId");
obs_set_audio_monitoring_device(device_name, device_id);
blog(LOG_INFO, "Audio monitoring device:\n\tname: %s\n\tid: %s",
device_name, device_id);
device_name, device_id);
#endif
}
@ -388,14 +385,15 @@ void OBSBasic::on_actionDupProfile_triggered()
void OBSBasic::on_actionRenameProfile_triggered()
{
std::string curDir = config_get_string(App()->GlobalConfig(),
"Basic", "ProfileDir");
std::string curName = config_get_string(App()->GlobalConfig(),
"Basic", "Profile");
std::string curDir =
config_get_string(App()->GlobalConfig(), "Basic", "ProfileDir");
std::string curName =
config_get_string(App()->GlobalConfig(), "Basic", "Profile");
/* Duplicate and delete in case there are any issues in the process */
bool success = AddProfile(false, Str("RenameProfile.Title"),
Str("AddProfile.Text"), curName.c_str(), true);
Str("AddProfile.Text"), curName.c_str(),
true);
if (success) {
DeleteProfile(curName.c_str(), curDir.c_str());
RefreshProfiles();
@ -413,13 +411,12 @@ void OBSBasic::on_actionRemoveProfile_triggered()
std::string newPath;
ConfigFile config;
std::string oldDir = config_get_string(App()->GlobalConfig(),
"Basic", "ProfileDir");
std::string oldName = config_get_string(App()->GlobalConfig(),
"Basic", "Profile");
std::string oldDir =
config_get_string(App()->GlobalConfig(), "Basic", "ProfileDir");
std::string oldName =
config_get_string(App()->GlobalConfig(), "Basic", "Profile");
auto cb = [&](const char *name, const char *filePath)
{
auto cb = [&](const char *name, const char *filePath) {
if (strcmp(oldName.c_str(), name) != 0) {
newName = name;
newPath = filePath;
@ -438,8 +435,8 @@ void OBSBasic::on_actionRemoveProfile_triggered()
QString text = QTStr("ConfirmRemove.Text");
text.replace("$1", QT_UTF8(oldName.c_str()));
QMessageBox::StandardButton button = OBSMessageBox::question(this,
QTStr("ConfirmRemove.Title"), text);
QMessageBox::StandardButton button = OBSMessageBox::question(
this, QTStr("ConfirmRemove.Title"), text);
if (button == QMessageBox::No)
return;
@ -448,7 +445,7 @@ void OBSBasic::on_actionRemoveProfile_triggered()
if (config.Open(newPath.c_str(), CONFIG_OPEN_ALWAYS) != 0) {
blog(LOG_ERROR, "ChangeProfile: Failed to load file '%s'",
newPath.c_str());
newPath.c_str());
return;
}
@ -457,9 +454,8 @@ void OBSBasic::on_actionRemoveProfile_triggered()
const char *newDir = strrchr(newPath.c_str(), '/') + 1;
config_set_string(App()->GlobalConfig(), "Basic", "Profile",
newName.c_str());
config_set_string(App()->GlobalConfig(), "Basic", "ProfileDir",
newDir);
newName.c_str());
config_set_string(App()->GlobalConfig(), "Basic", "ProfileDir", newDir);
Auth::Save();
auth.reset();
@ -474,8 +470,8 @@ void OBSBasic::on_actionRemoveProfile_triggered()
RefreshProfiles();
config_save_safe(App()->GlobalConfig(), "tmp", nullptr);
blog(LOG_INFO, "Switched to profile '%s' (%s)",
newName.c_str(), newDir);
blog(LOG_INFO, "Switched to profile '%s' (%s)", newName.c_str(),
newDir);
blog(LOG_INFO, "------------------------------------------------");
UpdateTitleBar();
@ -501,11 +497,8 @@ void OBSBasic::on_actionImportProfile_triggered()
}
QString dir = QFileDialog::getExistingDirectory(
this,
QTStr("Basic.MainMenu.Profile.Import"),
home,
QFileDialog::ShowDirsOnly |
QFileDialog::DontResolveSymlinks);
this, QTStr("Basic.MainMenu.Profile.Import"), home,
QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
if (!dir.isEmpty() && !dir.isNull()) {
QString inputPath = QString::fromUtf8(path);
@ -517,18 +510,18 @@ void OBSBasic::on_actionImportProfile_triggered()
if (!folder.exists()) {
folder.mkpath(profileDir);
QFile::copy(dir + "/basic.ini",
profileDir + "/basic.ini");
profileDir + "/basic.ini");
QFile::copy(dir + "/service.json",
profileDir + "/service.json");
profileDir + "/service.json");
QFile::copy(dir + "/streamEncoder.json",
profileDir + "/streamEncoder.json");
profileDir + "/streamEncoder.json");
QFile::copy(dir + "/recordEncoder.json",
profileDir + "/recordEncoder.json");
profileDir + "/recordEncoder.json");
RefreshProfiles();
} else {
OBSMessageBox::warning(this,
QTStr("Basic.MainMenu.Profile.Import"),
QTStr("Basic.MainMenu.Profile.Exists"));
OBSMessageBox::warning(
this, QTStr("Basic.MainMenu.Profile.Import"),
QTStr("Basic.MainMenu.Profile.Exists"));
}
}
}
@ -539,9 +532,8 @@ void OBSBasic::on_actionExportProfile_triggered()
QString home = QDir::homePath();
QString currentProfile =
QString::fromUtf8(config_get_string(App()->GlobalConfig(),
"Basic", "ProfileDir"));
QString currentProfile = QString::fromUtf8(config_get_string(
App()->GlobalConfig(), "Basic", "ProfileDir"));
int ret = GetConfigPath(path, 512, "obs-studio/basic/profiles/");
if (ret <= 0) {
@ -550,11 +542,8 @@ void OBSBasic::on_actionExportProfile_triggered()
}
QString dir = QFileDialog::getExistingDirectory(
this,
QTStr("Basic.MainMenu.Profile.Export"),
home,
QFileDialog::ShowDirsOnly |
QFileDialog::DontResolveSymlinks);
this, QTStr("Basic.MainMenu.Profile.Export"), home,
QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks);
if (!dir.isEmpty() && !dir.isNull()) {
QString outputDir = dir + "/" + currentProfile;
@ -571,26 +560,28 @@ void OBSBasic::on_actionExportProfile_triggered()
QFile::remove(outputDir + "/service.json");
if (QFile::exists(outputDir + "/streamEncoder.json"))
QFile::remove(outputDir + "/streamEncoder.json");
QFile::remove(outputDir +
"/streamEncoder.json");
if (QFile::exists(outputDir + "/recordEncoder.json"))
QFile::remove(outputDir + "/recordEncoder.json");
QFile::remove(outputDir +
"/recordEncoder.json");
}
QFile::copy(inputPath + currentProfile + "/basic.ini",
outputDir + "/basic.ini");
outputDir + "/basic.ini");
QFile::copy(inputPath + currentProfile + "/service.json",
outputDir + "/service.json");
outputDir + "/service.json");
QFile::copy(inputPath + currentProfile + "/streamEncoder.json",
outputDir + "/streamEncoder.json");
outputDir + "/streamEncoder.json");
QFile::copy(inputPath + currentProfile + "/recordEncoder.json",
outputDir + "/recordEncoder.json");
outputDir + "/recordEncoder.json");
}
}
void OBSBasic::ChangeProfile()
{
QAction *action = reinterpret_cast<QAction*>(sender());
QAction *action = reinterpret_cast<QAction *>(sender());
ConfigFile config;
std::string path;
@ -601,8 +592,8 @@ void OBSBasic::ChangeProfile()
if (path.empty())
return;
const char *oldName = config_get_string(App()->GlobalConfig(),
"Basic", "Profile");
const char *oldName =
config_get_string(App()->GlobalConfig(), "Basic", "Profile");
if (action->text().compare(QT_UTF8(oldName)) == 0) {
action->setChecked(true);
return;
@ -613,7 +604,7 @@ void OBSBasic::ChangeProfile()
if (config.Open(path.c_str(), CONFIG_OPEN_ALWAYS) != 0) {
blog(LOG_ERROR, "ChangeProfile: Failed to load file '%s'",
path.c_str());
path.c_str());
return;
}
@ -623,8 +614,7 @@ void OBSBasic::ChangeProfile()
const char *newDir = strrchr(path.c_str(), '/') + 1;
config_set_string(App()->GlobalConfig(), "Basic", "Profile", newName);
config_set_string(App()->GlobalConfig(), "Basic", "ProfileDir",
newDir);
config_set_string(App()->GlobalConfig(), "Basic", "ProfileDir", newDir);
Auth::Save();
auth.reset();
@ -642,8 +632,7 @@ void OBSBasic::ChangeProfile()
CheckForSimpleModeX264Fallback();
blog(LOG_INFO, "Switched to profile '%s' (%s)",
newName, newDir);
blog(LOG_INFO, "Switched to profile '%s' (%s)", newName, newDir);
blog(LOG_INFO, "------------------------------------------------");
if (api)
@ -652,10 +641,10 @@ void OBSBasic::ChangeProfile()
void OBSBasic::CheckForSimpleModeX264Fallback()
{
const char *curStreamEncoder = config_get_string(basicConfig,
"SimpleOutput", "StreamEncoder");
const char *curRecEncoder = config_get_string(basicConfig,
"SimpleOutput", "RecEncoder");
const char *curStreamEncoder =
config_get_string(basicConfig, "SimpleOutput", "StreamEncoder");
const char *curRecEncoder =
config_get_string(basicConfig, "SimpleOutput", "RecEncoder");
bool qsv_supported = false;
bool amd_supported = false;
bool nve_supported = false;
@ -672,8 +661,7 @@ void OBSBasic::CheckForSimpleModeX264Fallback()
nve_supported = true;
}
auto CheckEncoder = [&] (const char *&name)
{
auto CheckEncoder = [&](const char *&name) {
if (strcmp(name, SIMPLE_ENCODER_QSV) == 0) {
if (!qsv_supported) {
changed = true;
@ -698,13 +686,11 @@ void OBSBasic::CheckForSimpleModeX264Fallback()
};
if (!CheckEncoder(curStreamEncoder))
config_set_string(basicConfig,
"SimpleOutput", "StreamEncoder",
curStreamEncoder);
config_set_string(basicConfig, "SimpleOutput", "StreamEncoder",
curStreamEncoder);
if (!CheckEncoder(curRecEncoder))
config_set_string(basicConfig,
"SimpleOutput", "RecEncoder",
curRecEncoder);
config_set_string(basicConfig, "SimpleOutput", "RecEncoder",
curRecEncoder);
if (changed)
config_save_safe(basicConfig, "tmp", nullptr);
}

View file

@ -28,16 +28,16 @@
using namespace std;
void EnumSceneCollections(std::function<bool (const char *, const char *)> &&cb)
void EnumSceneCollections(std::function<bool(const char *, const char *)> &&cb)
{
char path[512];
os_glob_t *glob;
int ret = GetConfigPath(path, sizeof(path),
"obs-studio/basic/scenes/*.json");
"obs-studio/basic/scenes/*.json");
if (ret <= 0) {
blog(LOG_WARNING, "Failed to get config path for scene "
"collections");
"collections");
return;
}
@ -52,8 +52,8 @@ void EnumSceneCollections(std::function<bool (const char *, const char *)> &&cb)
if (glob->gl_pathv[i].directory)
continue;
obs_data_t *data = obs_data_create_from_json_file_safe(filePath,
"bak");
obs_data_t *data =
obs_data_create_from_json_file_safe(filePath, "bak");
std::string name = obs_data_get_string(data, "name");
/* if no name found, use the file name as the name
@ -75,8 +75,7 @@ void EnumSceneCollections(std::function<bool (const char *, const char *)> &&cb)
static bool SceneCollectionExists(const char *findName)
{
bool found = false;
auto func = [&](const char *name, const char*)
{
auto func = [&](const char *name, const char *) {
if (strcmp(name, findName) == 0) {
found = true;
return false;
@ -90,7 +89,8 @@ static bool SceneCollectionExists(const char *findName)
}
static bool GetSceneCollectionName(QWidget *parent, std::string &name,
std::string &file, const char *oldName = nullptr)
std::string &file,
const char *oldName = nullptr)
{
bool rename = oldName != nullptr;
const char *title;
@ -101,28 +101,28 @@ static bool GetSceneCollectionName(QWidget *parent, std::string &name,
if (rename) {
title = Str("Basic.Main.RenameSceneCollection.Title");
text = Str("Basic.Main.AddSceneCollection.Text");
text = Str("Basic.Main.AddSceneCollection.Text");
} else {
title = Str("Basic.Main.AddSceneCollection.Title");
text = Str("Basic.Main.AddSceneCollection.Text");
text = Str("Basic.Main.AddSceneCollection.Text");
}
for (;;) {
bool success = NameDialog::AskForName(parent, title, text,
name, QT_UTF8(oldName));
bool success = NameDialog::AskForName(parent, title, text, name,
QT_UTF8(oldName));
if (!success) {
return false;
}
if (name.empty()) {
OBSMessageBox::warning(parent,
QTStr("NoNameEntered.Title"),
QTStr("NoNameEntered.Text"));
QTStr("NoNameEntered.Title"),
QTStr("NoNameEntered.Text"));
continue;
}
if (SceneCollectionExists(name.c_str())) {
OBSMessageBox::warning(parent,
QTStr("NameExists.Title"),
QTStr("NameExists.Text"));
QTStr("NameExists.Title"),
QTStr("NameExists.Text"));
continue;
}
break;
@ -130,7 +130,7 @@ static bool GetSceneCollectionName(QWidget *parent, std::string &name,
if (!GetFileSafeName(name.c_str(), file)) {
blog(LOG_WARNING, "Failed to create safe file name for '%s'",
name.c_str());
name.c_str());
return false;
}
@ -145,7 +145,7 @@ static bool GetSceneCollectionName(QWidget *parent, std::string &name,
if (!GetClosestUnusedFileName(file, "json")) {
blog(LOG_WARNING, "Failed to get closest file name for %s",
file.c_str());
file.c_str());
return false;
}
@ -171,9 +171,9 @@ bool OBSBasic::AddSceneCollection(bool create_new, const QString &qname)
SaveProjectNow();
config_set_string(App()->GlobalConfig(), "Basic", "SceneCollection",
name.c_str());
name.c_str());
config_set_string(App()->GlobalConfig(), "Basic", "SceneCollectionFile",
file.c_str());
file.c_str());
if (create_new) {
CreateDefaultScene(false);
}
@ -181,8 +181,7 @@ bool OBSBasic::AddSceneCollection(bool create_new, const QString &qname)
RefreshSceneCollections();
blog(LOG_INFO, "Added scene collection '%s' (%s, %s.json)",
name.c_str(), create_new ? "clean" : "duplicate",
file.c_str());
name.c_str(), create_new ? "clean" : "duplicate", file.c_str());
blog(LOG_INFO, "------------------------------------------------");
UpdateTitleBar();
@ -197,7 +196,7 @@ bool OBSBasic::AddSceneCollection(bool create_new, const QString &qname)
void OBSBasic::RefreshSceneCollections()
{
QList<QAction*> menuActions = ui->sceneCollectionMenu->actions();
QList<QAction *> menuActions = ui->sceneCollectionMenu->actions();
int count = 0;
for (int i = 0; i < menuActions.count(); i++) {
@ -206,18 +205,17 @@ void OBSBasic::RefreshSceneCollections()
delete menuActions[i];
}
const char *cur_name = config_get_string(App()->GlobalConfig(),
"Basic", "SceneCollection");
const char *cur_name = config_get_string(App()->GlobalConfig(), "Basic",
"SceneCollection");
auto addCollection = [&](const char *name, const char *path)
{
auto addCollection = [&](const char *name, const char *path) {
std::string file = strrchr(path, '/') + 1;
file.erase(file.size() - 5, 5);
QAction *action = new QAction(QT_UTF8(name), this);
action->setProperty("file_name", QT_UTF8(path));
connect(action, &QAction::triggered,
this, &OBSBasic::ChangeSceneCollection);
connect(action, &QAction::triggered, this,
&OBSBasic::ChangeSceneCollection);
action->setCheckable(true);
action->setChecked(strcmp(name, cur_name) == 0);
@ -243,7 +241,7 @@ void OBSBasic::RefreshSceneCollections()
ui->actionRemoveSceneCollection->setEnabled(count > 1);
OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
main->ui->actionPasteFilters->setEnabled(false);
main->ui->actionPasteRef->setEnabled(false);
@ -265,19 +263,19 @@ void OBSBasic::on_actionRenameSceneCollection_triggered()
std::string name;
std::string file;
std::string oldFile = config_get_string(App()->GlobalConfig(),
"Basic", "SceneCollectionFile");
const char *oldName = config_get_string(App()->GlobalConfig(),
"Basic", "SceneCollection");
std::string oldFile = config_get_string(App()->GlobalConfig(), "Basic",
"SceneCollectionFile");
const char *oldName = config_get_string(App()->GlobalConfig(), "Basic",
"SceneCollection");
bool success = GetSceneCollectionName(this, name, file, oldName);
if (!success)
return;
config_set_string(App()->GlobalConfig(), "Basic", "SceneCollection",
name.c_str());
name.c_str());
config_set_string(App()->GlobalConfig(), "Basic", "SceneCollectionFile",
file.c_str());
file.c_str());
SaveProjectNow();
char path[512];
@ -295,7 +293,7 @@ void OBSBasic::on_actionRenameSceneCollection_triggered()
blog(LOG_INFO, "------------------------------------------------");
blog(LOG_INFO, "Renamed scene collection to '%s' (%s.json)",
name.c_str(), file.c_str());
name.c_str(), file.c_str());
blog(LOG_INFO, "------------------------------------------------");
UpdateTitleBar();
@ -312,13 +310,12 @@ void OBSBasic::on_actionRemoveSceneCollection_triggered()
std::string newName;
std::string newPath;
std::string oldFile = config_get_string(App()->GlobalConfig(),
"Basic", "SceneCollectionFile");
std::string oldName = config_get_string(App()->GlobalConfig(),
"Basic", "SceneCollection");
std::string oldFile = config_get_string(App()->GlobalConfig(), "Basic",
"SceneCollectionFile");
std::string oldName = config_get_string(App()->GlobalConfig(), "Basic",
"SceneCollection");
auto cb = [&](const char *name, const char *filePath)
{
auto cb = [&](const char *name, const char *filePath) {
if (strcmp(oldName.c_str(), name) != 0) {
newName = name;
newPath = filePath;
@ -337,8 +334,8 @@ void OBSBasic::on_actionRemoveSceneCollection_triggered()
QString text = QTStr("ConfirmRemove.Text");
text.replace("$1", QT_UTF8(oldName.c_str()));
QMessageBox::StandardButton button = OBSMessageBox::question(this,
QTStr("ConfirmRemove.Title"), text);
QMessageBox::StandardButton button = OBSMessageBox::question(
this, QTStr("ConfirmRemove.Title"), text);
if (button == QMessageBox::No)
return;
@ -358,13 +355,13 @@ void OBSBasic::on_actionRemoveSceneCollection_triggered()
Load(newPath.c_str());
RefreshSceneCollections();
const char *newFile = config_get_string(App()->GlobalConfig(),
"Basic", "SceneCollectionFile");
const char *newFile = config_get_string(App()->GlobalConfig(), "Basic",
"SceneCollectionFile");
blog(LOG_INFO, "Removed scene collection '%s' (%s.json), "
"switched to '%s' (%s.json)",
oldName.c_str(), oldFile.c_str(),
newName.c_str(), newFile);
blog(LOG_INFO,
"Removed scene collection '%s' (%s.json), "
"switched to '%s' (%s.json)",
oldName.c_str(), oldFile.c_str(), newName.c_str(), newFile);
blog(LOG_INFO, "------------------------------------------------");
UpdateTitleBar();
@ -388,10 +385,8 @@ void OBSBasic::on_actionImportSceneCollection_triggered()
}
QString qfilePath = QFileDialog::getOpenFileName(
this,
QTStr("Basic.MainMenu.SceneCollection.Import"),
qhome,
"JSON Files (*.json)");
this, QTStr("Basic.MainMenu.SceneCollection.Import"), qhome,
"JSON Files (*.json)");
QFileInfo finfo(qfilePath);
QString qfilename = finfo.fileName();
@ -416,23 +411,25 @@ void OBSBasic::on_actionImportSceneCollection_triggered()
obs_data_set_string(scenedata, "name", name.c_str());
if (!GetFileSafeName(name.c_str(), file)) {
blog(LOG_WARNING, "Failed to create "
"safe file name for '%s'",
name.c_str());
blog(LOG_WARNING,
"Failed to create "
"safe file name for '%s'",
name.c_str());
return;
}
string filePath = path + file;
if (!GetClosestUnusedFileName(filePath, "json")) {
blog(LOG_WARNING, "Failed to get "
"closest file name for %s",
file.c_str());
blog(LOG_WARNING,
"Failed to get "
"closest file name for %s",
file.c_str());
return;
}
obs_data_save_json_safe(scenedata, filePath.c_str(),
"tmp", "bak");
obs_data_save_json_safe(scenedata, filePath.c_str(), "tmp",
"bak");
RefreshSceneCollections();
}
}
@ -445,8 +442,8 @@ void OBSBasic::on_actionExportSceneCollection_triggered()
QString home = QDir::homePath();
QString currentFile = QT_UTF8(config_get_string(App()->GlobalConfig(),
"Basic", "SceneCollectionFile"));
QString currentFile = QT_UTF8(config_get_string(
App()->GlobalConfig(), "Basic", "SceneCollectionFile"));
int ret = GetConfigPath(path, 512, "obs-studio/basic/scenes/");
if (ret <= 0) {
@ -455,10 +452,8 @@ void OBSBasic::on_actionExportSceneCollection_triggered()
}
QString exportFile = QFileDialog::getSaveFileName(
this,
QTStr("Basic.MainMenu.SceneCollection.Export"),
home + "/" + currentFile,
"JSON Files (*.json)");
this, QTStr("Basic.MainMenu.SceneCollection.Export"),
home + "/" + currentFile, "JSON Files (*.json)");
string file = QT_TO_UTF8(exportFile);
@ -472,7 +467,7 @@ void OBSBasic::on_actionExportSceneCollection_triggered()
void OBSBasic::ChangeSceneCollection()
{
QAction *action = reinterpret_cast<QAction*>(sender());
QAction *action = reinterpret_cast<QAction *>(sender());
std::string fileName;
if (!action)
@ -482,8 +477,8 @@ void OBSBasic::ChangeSceneCollection()
if (fileName.empty())
return;
const char *oldName = config_get_string(App()->GlobalConfig(),
"Basic", "SceneCollection");
const char *oldName = config_get_string(App()->GlobalConfig(), "Basic",
"SceneCollection");
if (action->text().compare(QT_UTF8(oldName)) == 0) {
action->setChecked(true);
return;
@ -494,13 +489,13 @@ void OBSBasic::ChangeSceneCollection()
Load(fileName.c_str());
RefreshSceneCollections();
const char *newName = config_get_string(App()->GlobalConfig(),
"Basic", "SceneCollection");
const char *newFile = config_get_string(App()->GlobalConfig(),
"Basic", "SceneCollectionFile");
const char *newName = config_get_string(App()->GlobalConfig(), "Basic",
"SceneCollection");
const char *newFile = config_get_string(App()->GlobalConfig(), "Basic",
"SceneCollectionFile");
blog(LOG_INFO, "Switched to scene collection '%s' (%s.json)",
newName, newFile);
blog(LOG_INFO, "Switched to scene collection '%s' (%s.json)", newName,
newFile);
blog(LOG_INFO, "------------------------------------------------");
UpdateTitleBar();

View file

@ -54,8 +54,8 @@ void OBSBasic::InitDefaultTransitions()
if (!obs_is_source_configurable(id)) {
const char *name = obs_source_get_display_name(id);
obs_source_t *tr = obs_source_create_private(
id, name, NULL);
obs_source_t *tr =
obs_source_create_private(id, name, NULL);
InitTransition(tr);
transitions.emplace_back(tr);
@ -68,7 +68,7 @@ void OBSBasic::InitDefaultTransitions()
for (OBSSource &tr : transitions) {
ui->transitions->addItem(QT_UTF8(obs_source_get_name(tr)),
QVariant::fromValue(OBSSource(tr)));
QVariant::fromValue(OBSSource(tr)));
}
}
@ -79,33 +79,33 @@ void OBSBasic::AddQuickTransitionHotkey(QuickTransition *qt)
dstr_printf(hotkeyId, "OBSBasic.QuickTransition.%d", qt->id);
hotkeyName = QTStr("QuickTransitions.HotkeyName")
.arg(MakeQuickTransitionText(qt));
.arg(MakeQuickTransitionText(qt));
auto quickTransition = [] (void *data, obs_hotkey_id, obs_hotkey_t*,
bool pressed)
{
auto quickTransition = [](void *data, obs_hotkey_id, obs_hotkey_t *,
bool pressed) {
int id = (int)(uintptr_t)data;
OBSBasic *main =
reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
if (pressed)
QMetaObject::invokeMethod(main,
"TriggerQuickTransition",
Qt::QueuedConnection,
Q_ARG(int, id));
"TriggerQuickTransition",
Qt::QueuedConnection,
Q_ARG(int, id));
};
qt->hotkey = obs_hotkey_register_frontend(hotkeyId->array,
QT_TO_UTF8(hotkeyName), quickTransition,
(void*)(uintptr_t)qt->id);
QT_TO_UTF8(hotkeyName),
quickTransition,
(void *)(uintptr_t)qt->id);
}
void QuickTransition::SourceRenamed(void *param, calldata_t *data)
{
QuickTransition *qt = reinterpret_cast<QuickTransition*>(param);
QuickTransition *qt = reinterpret_cast<QuickTransition *>(param);
QString hotkeyName = QTStr("QuickTransitions.HotkeyName")
.arg(MakeQuickTransitionText(qt));
.arg(MakeQuickTransitionText(qt));
obs_hotkey_set_description(qt->hotkey, QT_TO_UTF8(hotkeyName));
@ -135,23 +135,23 @@ void OBSBasic::RemoveQuickTransitionHotkey(QuickTransition *qt)
void OBSBasic::InitTransition(obs_source_t *transition)
{
auto onTransitionStop = [] (void *data, calldata_t*) {
OBSBasic *window = (OBSBasic*)data;
auto onTransitionStop = [](void *data, calldata_t *) {
OBSBasic *window = (OBSBasic *)data;
QMetaObject::invokeMethod(window, "TransitionStopped",
Qt::QueuedConnection);
Qt::QueuedConnection);
};
auto onTransitionFullStop = [] (void *data, calldata_t*) {
OBSBasic *window = (OBSBasic*)data;
auto onTransitionFullStop = [](void *data, calldata_t *) {
OBSBasic *window = (OBSBasic *)data;
QMetaObject::invokeMethod(window, "TransitionFullyStopped",
Qt::QueuedConnection);
Qt::QueuedConnection);
};
signal_handler_t *handler = obs_source_get_signal_handler(transition);
signal_handler_connect(handler, "transition_video_stop",
onTransitionStop, this);
signal_handler_connect(handler, "transition_stop",
onTransitionFullStop, this);
onTransitionStop, this);
signal_handler_connect(handler, "transition_stop", onTransitionFullStop,
this);
}
static inline OBSSource GetTransitionComboItem(QComboBox *combo, int idx)
@ -163,12 +163,12 @@ void OBSBasic::CreateDefaultQuickTransitions()
{
/* non-configurable transitions are always available, so add them
* to the "default quick transitions" list */
quickTransitions.emplace_back(
GetTransitionComboItem(ui->transitions, 0),
300, quickTransitionIdCounter++);
quickTransitions.emplace_back(
GetTransitionComboItem(ui->transitions, 1),
300, quickTransitionIdCounter++);
quickTransitions.emplace_back(GetTransitionComboItem(ui->transitions,
0),
300, quickTransitionIdCounter++);
quickTransitions.emplace_back(GetTransitionComboItem(ui->transitions,
1),
300, quickTransitionIdCounter++);
}
void OBSBasic::LoadQuickTransitions(obs_data_array_t *array)
@ -188,13 +188,14 @@ void OBSBasic::LoadQuickTransitions(obs_data_array_t *array)
obs_source_t *source = FindTransition(name);
if (source) {
quickTransitions.emplace_back(source, duration,
id);
id);
if (quickTransitionIdCounter <= id)
quickTransitionIdCounter = id + 1;
int idx = (int)quickTransitions.size() - 1;
AddQuickTransitionHotkey(&quickTransitions[idx]);
AddQuickTransitionHotkey(
&quickTransitions[idx]);
obs_hotkey_load(quickTransitions[idx].hotkey,
hotkeys);
}
@ -214,7 +215,7 @@ obs_data_array_t *OBSBasic::SaveQuickTransitions()
obs_data_array_t *hotkeys = obs_hotkey_save(qt.hotkey);
obs_data_set_string(data, "name",
obs_source_get_name(qt.source));
obs_source_get_name(qt.source));
obs_data_set_int(data, "duration", qt.duration);
obs_data_set_array(data, "hotkeys", hotkeys);
obs_data_set_int(data, "id", qt.id);
@ -231,8 +232,7 @@ obs_data_array_t *OBSBasic::SaveQuickTransitions()
obs_source_t *OBSBasic::FindTransition(const char *name)
{
for (int i = 0; i < ui->transitions->count(); i++) {
OBSSource tr = ui->transitions->itemData(i)
.value<OBSSource>();
OBSSource tr = ui->transitions->itemData(i).value<OBSSource>();
const char *trName = obs_source_get_name(tr);
if (strcmp(trName, name) == 0)
@ -292,7 +292,7 @@ void OBSBasic::TransitionFullyStopped()
}
void OBSBasic::TransitionToScene(OBSSource source, bool force, bool direct,
bool quickTransition)
bool quickTransition)
{
obs_scene_t *scene = obs_scene_from_source(source);
bool usingPreviewProgram = IsPreviewProgramMode();
@ -317,10 +317,10 @@ void OBSBasic::TransitionToScene(OBSSource source, bool force, bool direct,
}
if (usingPreviewProgram && sceneDuplicationMode) {
scene = obs_scene_duplicate(scene, NULL,
editPropertiesMode ?
OBS_SCENE_DUP_PRIVATE_COPY :
OBS_SCENE_DUP_PRIVATE_REFS);
scene = obs_scene_duplicate(
scene, NULL,
editPropertiesMode ? OBS_SCENE_DUP_PRIVATE_COPY
: OBS_SCENE_DUP_PRIVATE_REFS);
source = obs_scene_get_source(scene);
}
@ -342,8 +342,8 @@ void OBSBasic::TransitionToScene(OBSSource source, bool force, bool direct,
OBSData data = obs_source_get_private_settings(source);
obs_data_release(data);
const char *trOverrideName = obs_data_get_string(data,
"transition");
const char *trOverrideName =
obs_data_get_string(data, "transition");
int duration = ui->transitionDuration->value();
if (trOverrideName && *trOverrideName && !quickTransition) {
@ -351,18 +351,18 @@ void OBSBasic::TransitionToScene(OBSSource source, bool force, bool direct,
if (trOverride) {
transition = trOverride;
obs_data_set_default_int(data,
"transition_duration", 300);
obs_data_set_default_int(
data, "transition_duration", 300);
duration = (int)obs_data_get_int(data,
"transition_duration");
duration = (int)obs_data_get_int(
data, "transition_duration");
OverrideTransition(trOverride);
overridingTransition = true;
}
}
bool success = obs_transition_start(transition,
OBS_TRANSITION_MODE_AUTO, duration, source);
bool success = obs_transition_start(
transition, OBS_TRANSITION_MODE_AUTO, duration, source);
if (!success)
TransitionFullyStopped();
}
@ -432,12 +432,12 @@ void OBSBasic::on_transitions_currentIndexChanged(int)
void OBSBasic::AddTransition()
{
QAction *action = reinterpret_cast<QAction*>(sender());
QAction *action = reinterpret_cast<QAction *>(sender());
QString idStr = action->property("id").toString();
string name;
QString placeHolderText = QT_UTF8(
obs_source_get_display_name(QT_TO_UTF8(idStr)));
QString placeHolderText =
QT_UTF8(obs_source_get_display_name(QT_TO_UTF8(idStr)));
QString format = placeHolderText + " (%1)";
obs_source_t *source = nullptr;
int i = 1;
@ -447,40 +447,41 @@ void OBSBasic::AddTransition()
}
bool accepted = NameDialog::AskForName(this,
QTStr("TransitionNameDlg.Title"),
QTStr("TransitionNameDlg.Text"),
name, placeHolderText);
QTStr("TransitionNameDlg.Title"),
QTStr("TransitionNameDlg.Text"),
name, placeHolderText);
if (accepted) {
if (name.empty()) {
OBSMessageBox::warning(this,
QTStr("NoNameEntered.Title"),
QTStr("NoNameEntered.Text"));
QTStr("NoNameEntered.Title"),
QTStr("NoNameEntered.Text"));
AddTransition();
return;
}
source = FindTransition(name.c_str());
if (source) {
OBSMessageBox::warning(this,
QTStr("NameExists.Title"),
QTStr("NameExists.Text"));
OBSMessageBox::warning(this, QTStr("NameExists.Title"),
QTStr("NameExists.Text"));
AddTransition();
return;
}
source = obs_source_create_private(QT_TO_UTF8(idStr),
name.c_str(), NULL);
name.c_str(), NULL);
InitTransition(source);
ui->transitions->addItem(QT_UTF8(name.c_str()),
QVariant::fromValue(OBSSource(source)));
ui->transitions->addItem(
QT_UTF8(name.c_str()),
QVariant::fromValue(OBSSource(source)));
ui->transitions->setCurrentIndex(ui->transitions->count() - 1);
CreatePropertiesWindow(source);
obs_source_release(source);
if (api)
api->on_event(OBS_FRONTEND_EVENT_TRANSITION_LIST_CHANGED);
api->on_event(
OBS_FRONTEND_EVENT_TRANSITION_LIST_CHANGED);
ClearQuickTransitionWidgets();
RefreshQuickTransitions();
@ -500,8 +501,8 @@ void OBSBasic::on_transitionAdd_clicked()
QAction *action = new QAction(name, this);
action->setProperty("id", id);
connect(action, SIGNAL(triggered()),
this, SLOT(AddTransition()));
connect(action, SIGNAL(triggered()), this,
SLOT(AddTransition()));
menu.addAction(action);
foundConfigurableTransitions = true;
@ -529,7 +530,8 @@ void OBSBasic::on_transitionRemove_clicked()
if (qt.button)
qt.button->deleteLater();
RemoveQuickTransitionHotkey(&qt);
quickTransitions.erase(quickTransitions.begin() + i - 1);
quickTransitions.erase(quickTransitions.begin() + i -
1);
}
}
@ -544,7 +546,7 @@ void OBSBasic::on_transitionRemove_clicked()
void OBSBasic::RenameTransition()
{
QAction *action = reinterpret_cast<QAction*>(sender());
QAction *action = reinterpret_cast<QAction *>(sender());
QVariant variant = action->property("transition");
obs_source_t *transition = variant.value<OBSSource>();
@ -553,24 +555,23 @@ void OBSBasic::RenameTransition()
obs_source_t *source = nullptr;
bool accepted = NameDialog::AskForName(this,
QTStr("TransitionNameDlg.Title"),
QTStr("TransitionNameDlg.Text"),
name, placeHolderText);
QTStr("TransitionNameDlg.Title"),
QTStr("TransitionNameDlg.Text"),
name, placeHolderText);
if (accepted) {
if (name.empty()) {
OBSMessageBox::warning(this,
QTStr("NoNameEntered.Title"),
QTStr("NoNameEntered.Text"));
QTStr("NoNameEntered.Title"),
QTStr("NoNameEntered.Text"));
RenameTransition();
return;
}
source = FindTransition(name.c_str());
if (source) {
OBSMessageBox::warning(this,
QTStr("NameExists.Title"),
QTStr("NameExists.Text"));
OBSMessageBox::warning(this, QTStr("NameExists.Title"),
QTStr("NameExists.Text"));
RenameTransition();
return;
@ -579,10 +580,12 @@ void OBSBasic::RenameTransition()
obs_source_set_name(transition, name.c_str());
int idx = ui->transitions->findData(variant);
if (idx != -1) {
ui->transitions->setItemText(idx, QT_UTF8(name.c_str()));
ui->transitions->setItemText(idx,
QT_UTF8(name.c_str()));
if (api)
api->on_event(OBS_FRONTEND_EVENT_TRANSITION_LIST_CHANGED);
api->on_event(
OBS_FRONTEND_EVENT_TRANSITION_LIST_CHANGED);
ClearQuickTransitionWidgets();
RefreshQuickTransitions();
@ -597,9 +600,7 @@ void OBSBasic::on_transitionProps_clicked()
if (!obs_source_configurable(source))
return;
auto properties = [&] () {
CreatePropertiesWindow(source);
};
auto properties = [&]() { CreatePropertiesWindow(source); };
QMenu menu(this);
@ -643,8 +644,7 @@ void OBSBasic::SetCurrentScene(obs_scene_t *scene, bool force, bool direct)
SetCurrentScene(source, force, direct);
}
template <typename T>
static T GetOBSRef(QListWidgetItem *item)
template<typename T> static T GetOBSRef(QListWidgetItem *item)
{
return item->data(static_cast<int>(QtDataRole::OBSRef)).value<T>();
}
@ -679,7 +679,8 @@ void OBSBasic::SetCurrentScene(OBSSource scene, bool force, bool direct)
ui->scenes->setCurrentItem(item);
ui->scenes->blockSignals(false);
if (api)
api->on_event(OBS_FRONTEND_EVENT_PREVIEW_SCENE_CHANGED);
api->on_event(
OBS_FRONTEND_EVENT_PREVIEW_SCENE_CHANGED);
break;
}
}
@ -689,8 +690,8 @@ void OBSBasic::SetCurrentScene(OBSSource scene, bool force, bool direct)
bool userSwitched = (!force && !disableSaving);
blog(LOG_INFO, "%s to scene '%s'",
userSwitched ? "User switched" : "Switched",
obs_source_get_name(scene));
userSwitched ? "User switched" : "Switched",
obs_source_get_name(scene));
}
void OBSBasic::CreateProgramDisplay()
@ -698,8 +699,8 @@ void OBSBasic::CreateProgramDisplay()
program = new OBSQTDisplay();
program->setContextMenuPolicy(Qt::CustomContextMenu);
connect(program.data(), &QWidget::customContextMenuRequested,
this, &OBSBasic::on_program_customContextMenuRequested);
connect(program.data(), &QWidget::customContextMenuRequested, this,
&OBSBasic::on_program_customContextMenuRequested);
auto displayResize = [this]() {
struct obs_video_info ovi;
@ -708,13 +709,11 @@ void OBSBasic::CreateProgramDisplay()
ResizeProgram(ovi.base_width, ovi.base_height);
};
connect(program.data(), &OBSQTDisplay::DisplayResized,
displayResize);
connect(program.data(), &OBSQTDisplay::DisplayResized, displayResize);
auto addDisplay = [this] (OBSQTDisplay *window)
{
auto addDisplay = [this](OBSQTDisplay *window) {
obs_display_add_draw_callback(window->GetDisplay(),
OBSBasic::RenderProgram, this);
OBSBasic::RenderProgram, this);
struct obs_video_info ovi;
if (obs_get_video_info(&ovi))
@ -723,8 +722,7 @@ void OBSBasic::CreateProgramDisplay()
connect(program.data(), &OBSQTDisplay::DisplayCreated, addDisplay);
program->setSizePolicy(QSizePolicy::Expanding,
QSizePolicy::Expanding);
program->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
}
void OBSBasic::TransitionClicked()
@ -771,16 +769,16 @@ void OBSBasic::CreateProgramOptions()
programOptions->setLayout(layout);
auto onAdd = [this] () {
auto onAdd = [this]() {
QScopedPointer<QMenu> menu(CreateTransitionMenu(this, nullptr));
menu->exec(QCursor::pos());
};
auto onConfig = [this] () {
auto onConfig = [this]() {
QMenu menu(this);
QAction *action;
auto toggleEditProperties = [this] () {
auto toggleEditProperties = [this]() {
editPropertiesMode = !editPropertiesMode;
OBSSource actualScene = OBSGetStrongRef(programScene);
@ -788,11 +786,11 @@ void OBSBasic::CreateProgramOptions()
TransitionToScene(actualScene, true);
};
auto toggleSwapScenesMode = [this] () {
auto toggleSwapScenesMode = [this]() {
swapScenesMode = !swapScenesMode;
};
auto toggleSceneDuplication = [this] () {
auto toggleSceneDuplication = [this]() {
sceneDuplicationMode = !sceneDuplicationMode;
OBSSource actualScene = OBSGetStrongRef(programScene);
@ -800,20 +798,22 @@ void OBSBasic::CreateProgramOptions()
TransitionToScene(actualScene, true);
};
auto showToolTip = [&] () {
auto showToolTip = [&]() {
QAction *act = menu.activeAction();
QToolTip::showText(QCursor::pos(), act->toolTip(),
&menu, menu.actionGeometry(act));
&menu, menu.actionGeometry(act));
};
action = menu.addAction(QTStr("QuickTransitions.DuplicateScene"));
action = menu.addAction(
QTStr("QuickTransitions.DuplicateScene"));
action->setToolTip(QTStr("QuickTransitions.DuplicateSceneTT"));
action->setCheckable(true);
action->setChecked(sceneDuplicationMode);
connect(action, &QAction::triggered, toggleSceneDuplication);
connect(action, &QAction::hovered, showToolTip);
action = menu.addAction(QTStr("QuickTransitions.EditProperties"));
action = menu.addAction(
QTStr("QuickTransitions.EditProperties"));
action->setToolTip(QTStr("QuickTransitions.EditPropertiesTT"));
action->setCheckable(true);
action->setChecked(editPropertiesMode);
@ -831,8 +831,8 @@ void OBSBasic::CreateProgramOptions()
menu.exec(QCursor::pos());
};
connect(transitionButton.data(), &QAbstractButton::clicked,
this, &OBSBasic::TransitionClicked);
connect(transitionButton.data(), &QAbstractButton::clicked, this,
&OBSBasic::TransitionClicked);
connect(addQuickTransition, &QAbstractButton::clicked, onAdd);
connect(configTransitions, &QAbstractButton::clicked, onConfig);
}
@ -868,8 +868,7 @@ QMenu *OBSBasic::CreatePerSceneTransitionMenu()
duration->setSingleStep(50);
duration->setValue(curDuration);
auto setTransition = [this] (QAction *action)
{
auto setTransition = [this](QAction *action) {
int idx = action->property("transition_index").toInt();
OBSSource scene = GetCurrentSceneSource();
OBSData data = obs_source_get_private_settings(scene);
@ -886,8 +885,7 @@ QMenu *OBSBasic::CreatePerSceneTransitionMenu()
obs_data_set_string(data, "transition", name);
};
auto setDuration = [this] (int duration)
{
auto setDuration = [this](int duration) {
OBSSource scene = GetCurrentSceneSource();
OBSData data = obs_source_get_private_settings(scene);
obs_data_release(data);
@ -895,8 +893,8 @@ QMenu *OBSBasic::CreatePerSceneTransitionMenu()
obs_data_set_int(data, "transition_duration", duration);
};
connect(duration, (void (QSpinBox::*)(int))&QSpinBox::valueChanged,
setDuration);
connect(duration, (void (QSpinBox::*)(int)) & QSpinBox::valueChanged,
setDuration);
for (int i = -1; i < ui->transitions->count(); i++) {
const char *name = "";
@ -918,7 +916,7 @@ QMenu *OBSBasic::CreatePerSceneTransitionMenu()
action->setChecked(match);
connect(action, &QAction::triggered,
std::bind(setTransition, action));
std::bind(setTransition, action));
}
QWidgetAction *durationAction = new QWidgetAction(menu);
@ -937,8 +935,8 @@ QMenu *OBSBasic::CreateTransitionMenu(QWidget *parent, QuickTransition *qt)
if (qt) {
action = menu->addAction(QTStr("Remove"));
action->setProperty("id", qt->id);
connect(action, &QAction::triggered,
this, &OBSBasic::QuickTransitionRemoveClicked);
connect(action, &QAction::triggered, this,
&OBSBasic::QuickTransitionRemoveClicked);
menu->addSeparator();
}
@ -953,8 +951,9 @@ QMenu *OBSBasic::CreateTransitionMenu(QWidget *parent, QuickTransition *qt)
duration->setValue(qt ? qt->duration : 300);
if (qt) {
connect(duration, (void (QSpinBox::*)(int))&QSpinBox::valueChanged,
this, &OBSBasic::QuickTransitionChangeDuration);
connect(duration,
(void (QSpinBox::*)(int)) & QSpinBox::valueChanged,
this, &OBSBasic::QuickTransitionChangeDuration);
}
for (int i = 0; i < ui->transitions->count(); i++) {
@ -966,12 +965,13 @@ QMenu *OBSBasic::CreateTransitionMenu(QWidget *parent, QuickTransition *qt)
if (qt) {
action->setProperty("id", qt->id);
connect(action, &QAction::triggered, this,
&OBSBasic::QuickTransitionChange);
&OBSBasic::QuickTransitionChange);
} else {
action->setProperty("duration",
QVariant::fromValue<QWidget*>(duration));
action->setProperty(
"duration",
QVariant::fromValue<QWidget *>(duration));
connect(action, &QAction::triggered, this,
&OBSBasic::AddQuickTransition);
&OBSBasic::AddQuickTransition);
}
}
@ -1004,11 +1004,11 @@ void OBSBasic::AddQuickTransitionId(int id)
/* --------------------------------- */
button->setMenu(buttonMenu);
connect(button, &QAbstractButton::clicked,
this, &OBSBasic::QuickTransitionClicked);
connect(button, &QAbstractButton::clicked, this,
&OBSBasic::QuickTransitionClicked);
QVBoxLayout *programLayout =
reinterpret_cast<QVBoxLayout*>(programOptions->layout());
reinterpret_cast<QVBoxLayout *>(programOptions->layout());
int idx = 3;
for (;; idx++) {
@ -1027,7 +1027,7 @@ void OBSBasic::AddQuickTransitionId(int id)
void OBSBasic::AddQuickTransition()
{
int trIdx = sender()->property("transition_index").toInt();
QSpinBox *duration = sender()->property("duration").value<QSpinBox*>();
QSpinBox *duration = sender()->property("duration").value<QSpinBox *>();
OBSSource transition = GetTransitionComboItem(ui->transitions, trIdx);
int id = quickTransitionIdCounter++;
@ -1048,7 +1048,7 @@ void OBSBasic::ClearQuickTransitions()
return;
QVBoxLayout *programLayout =
reinterpret_cast<QVBoxLayout*>(programOptions->layout());
reinterpret_cast<QVBoxLayout *>(programOptions->layout());
for (int idx = 0;; idx++) {
QLayoutItem *item = programLayout->itemAt(idx);
@ -1118,7 +1118,7 @@ void OBSBasic::ClearQuickTransitionWidgets()
return;
QVBoxLayout *programLayout =
reinterpret_cast<QVBoxLayout*>(programOptions->layout());
reinterpret_cast<QVBoxLayout *>(programOptions->layout());
for (int idx = 0;; idx++) {
QLayoutItem *item = programLayout->itemAt(idx);
@ -1152,7 +1152,7 @@ void OBSBasic::DisableQuickTransitionWidgets()
return;
QVBoxLayout *programLayout =
reinterpret_cast<QVBoxLayout*>(programOptions->layout());
reinterpret_cast<QVBoxLayout *>(programOptions->layout());
for (int idx = 0;; idx++) {
QLayoutItem *item = programLayout->itemAt(idx);
@ -1173,7 +1173,7 @@ void OBSBasic::EnableQuickTransitionWidgets()
return;
QVBoxLayout *programLayout =
reinterpret_cast<QVBoxLayout*>(programOptions->layout());
reinterpret_cast<QVBoxLayout *>(programOptions->layout());
for (int idx = 0;; idx++) {
QLayoutItem *item = programLayout->itemAt(idx);
@ -1209,10 +1209,11 @@ void OBSBasic::SetPreviewProgramMode(bool enabled)
obs_scene_t *dup;
if (sceneDuplicationMode) {
dup = obs_scene_duplicate(curScene, nullptr,
editPropertiesMode ?
OBS_SCENE_DUP_PRIVATE_COPY :
OBS_SCENE_DUP_PRIVATE_REFS);
dup = obs_scene_duplicate(
curScene, nullptr,
editPropertiesMode
? OBS_SCENE_DUP_PRIVATE_COPY
: OBS_SCENE_DUP_PRIVATE_REFS);
} else {
dup = curScene;
obs_scene_addref(dup);
@ -1235,7 +1236,7 @@ void OBSBasic::SetPreviewProgramMode(bool enabled)
programLabel = new QLabel(QTStr("StudioMode.Program"));
programLabel->setSizePolicy(QSizePolicy::Preferred,
QSizePolicy::Preferred);
QSizePolicy::Preferred);
programLabel->setAlignment(Qt::AlignHCenter | Qt::AlignBottom);
programLabel->setProperty("themeID", "previewProgramLabels");
@ -1248,8 +1249,8 @@ void OBSBasic::SetPreviewProgramMode(bool enabled)
programLayout->addWidget(programLabel);
programLayout->addWidget(program);
bool labels = config_get_bool(GetGlobalConfig(),
"BasicWindow", "StudioModeLabels");
bool labels = config_get_bool(GetGlobalConfig(), "BasicWindow",
"StudioModeLabels");
programLabel->setHidden(!labels);
@ -1257,14 +1258,15 @@ void OBSBasic::SetPreviewProgramMode(bool enabled)
ui->previewLayout->addWidget(programOptions);
ui->previewLayout->addWidget(programWidget);
ui->previewLayout->setAlignment(programOptions, Qt::AlignCenter);
ui->previewLayout->setAlignment(programOptions,
Qt::AlignCenter);
if (api)
api->on_event(OBS_FRONTEND_EVENT_STUDIO_MODE_ENABLED);
blog(LOG_INFO, "Switched to Preview/Program mode");
blog(LOG_INFO, "-----------------------------"
"-------------------");
"-------------------");
} else {
OBSSource actualProgramScene = OBSGetStrongRef(programScene);
if (!actualProgramScene)
@ -1299,7 +1301,7 @@ void OBSBasic::SetPreviewProgramMode(bool enabled)
blog(LOG_INFO, "Switched to regular Preview mode");
blog(LOG_INFO, "-----------------------------"
"-------------------");
"-------------------");
}
ResetUI();
@ -1310,7 +1312,7 @@ void OBSBasic::RenderProgram(void *data, uint32_t cx, uint32_t cy)
{
GS_DEBUG_MARKER_BEGIN(GS_DEBUG_COLOR_DEFAULT, "RenderProgram");
OBSBasic *window = static_cast<OBSBasic*>(data);
OBSBasic *window = static_cast<OBSBasic *>(data);
obs_video_info ovi;
obs_get_video_info(&ovi);
@ -1324,9 +1326,9 @@ void OBSBasic::RenderProgram(void *data, uint32_t cx, uint32_t cy)
/* --------------------------------------- */
gs_ortho(0.0f, float(ovi.base_width), 0.0f, float(ovi.base_height),
-100.0f, 100.0f);
gs_set_viewport(window->programX, window->programY,
window->programCX, window->programCY);
-100.0f, 100.0f);
gs_set_viewport(window->programX, window->programY, window->programCX,
window->programCY);
window->DrawBackdrop(float(ovi.base_width), float(ovi.base_height));
@ -1351,9 +1353,9 @@ void OBSBasic::ResizeProgram(uint32_t cx, uint32_t cy)
/* resize program panel to fix to the top section of the window */
targetSize = GetPixelSize(program);
GetScaleAndCenterPos(int(cx), int(cy),
targetSize.width() - PREVIEW_EDGE_SIZE * 2,
targetSize.height() - PREVIEW_EDGE_SIZE * 2,
programX, programY, programScale);
targetSize.width() - PREVIEW_EDGE_SIZE * 2,
targetSize.height() - PREVIEW_EDGE_SIZE * 2,
programX, programY, programScale);
programX += float(PREVIEW_EDGE_SIZE);
programY += float(PREVIEW_EDGE_SIZE);
@ -1371,7 +1373,8 @@ obs_data_array_t *OBSBasic::SaveTransitions()
obs_data_t *sourceData = obs_data_create();
obs_data_t *settings = obs_source_get_settings(tr);
obs_data_set_string(sourceData, "name", obs_source_get_name(tr));
obs_data_set_string(sourceData, "name",
obs_source_get_name(tr));
obs_data_set_string(sourceData, "id", obs_obj_get_id(tr));
obs_data_set_obj(sourceData, "settings", settings);
@ -1394,14 +1397,15 @@ void OBSBasic::LoadTransitions(obs_data_array_t *transitions)
const char *id = obs_data_get_string(item, "id");
obs_data_t *settings = obs_data_get_obj(item, "settings");
obs_source_t *source = obs_source_create_private(id, name,
settings);
obs_source_t *source =
obs_source_create_private(id, name, settings);
if (!obs_obj_invalid(source)) {
InitTransition(source);
ui->transitions->addItem(QT_UTF8(name),
QVariant::fromValue(OBSSource(source)));
ui->transitions->addItem(
QT_UTF8(name),
QVariant::fromValue(OBSSource(source)));
ui->transitions->setCurrentIndex(
ui->transitions->count() - 1);
ui->transitions->count() - 1);
}
obs_data_release(settings);

File diff suppressed because it is too large Load diff

View file

@ -53,16 +53,16 @@ class OBSBasicStats;
#define DESKTOP_AUDIO_1 Str("DesktopAudioDevice1")
#define DESKTOP_AUDIO_2 Str("DesktopAudioDevice2")
#define AUX_AUDIO_1 Str("AuxAudioDevice1")
#define AUX_AUDIO_2 Str("AuxAudioDevice2")
#define AUX_AUDIO_3 Str("AuxAudioDevice3")
#define AUX_AUDIO_4 Str("AuxAudioDevice4")
#define AUX_AUDIO_1 Str("AuxAudioDevice1")
#define AUX_AUDIO_2 Str("AuxAudioDevice2")
#define AUX_AUDIO_3 Str("AuxAudioDevice3")
#define AUX_AUDIO_4 Str("AuxAudioDevice4")
#define SIMPLE_ENCODER_X264 "x264"
#define SIMPLE_ENCODER_X264_LOWCPU "x264_lowcpu"
#define SIMPLE_ENCODER_QSV "qsv"
#define SIMPLE_ENCODER_NVENC "nvenc"
#define SIMPLE_ENCODER_AMD "amd"
#define SIMPLE_ENCODER_X264 "x264"
#define SIMPLE_ENCODER_X264_LOWCPU "x264_lowcpu"
#define SIMPLE_ENCODER_QSV "qsv"
#define SIMPLE_ENCODER_NVENC "nvenc"
#define SIMPLE_ENCODER_AMD "amd"
#define PREVIEW_EDGE_SIZE 10
@ -89,13 +89,14 @@ struct QuickTransition {
inline QuickTransition() {}
inline QuickTransition(OBSSource source_, int duration_, int id_)
: source (source_),
duration (duration_),
id (id_),
renamedSignal (std::make_shared<OBSSignal>(
obs_source_get_signal_handler(source),
"rename", SourceRenamed, this))
{}
: source(source_),
duration(duration_),
id(id_),
renamedSignal(std::make_shared<OBSSignal>(
obs_source_get_signal_handler(source), "rename",
SourceRenamed, this))
{
}
private:
static void SourceRenamed(void *param, calldata_t *data);
@ -124,19 +125,14 @@ class OBSBasic : public OBSMainWindow {
friend class AutoConfigStreamPage;
friend struct OBSStudioAPI;
enum class MoveDir {
Up,
Down,
Left,
Right
};
enum class MoveDir { Up, Down, Left, Right };
enum DropType {
DropType_RawText,
DropType_Text,
DropType_Image,
DropType_Media,
DropType_Html
DropType_Html,
};
private:
@ -144,7 +140,7 @@ private:
std::shared_ptr<Auth> auth;
std::vector<VolControl*> volumes;
std::vector<VolControl *> volumes;
std::vector<OBSSignal> signalHandlers;
@ -172,7 +168,7 @@ private:
QPointer<QDockWidget> statsDock;
QPointer<OBSAbout> about;
QPointer<QTimer> cpuUsageTimer;
QPointer<QTimer> cpuUsageTimer;
os_cpu_usage_info_t *cpuUsageInfo = nullptr;
OBSService service;
@ -188,16 +184,16 @@ private:
gs_vertbuffer_t *boxBottom = nullptr;
gs_vertbuffer_t *circle = nullptr;
bool sceneChanging = false;
bool ignoreSelectionUpdate = false;
bool sceneChanging = false;
bool ignoreSelectionUpdate = false;
int previewX = 0, previewY = 0;
int previewCX = 0, previewCY = 0;
float previewScale = 0.0f;
int previewX = 0, previewY = 0;
int previewCX = 0, previewCY = 0;
float previewScale = 0.0f;
ConfigFile basicConfig;
ConfigFile basicConfig;
std::vector<SavedProjectorInfo*> savedProjectorsArray;
std::vector<SavedProjectorInfo *> savedProjectorsArray;
QPointer<QWidget> projectors[10];
QList<QPointer<QWidget>> windowProjectors;
@ -210,26 +206,26 @@ private:
QPointer<QPushButton> replayBufferButton;
QScopedPointer<QSystemTrayIcon> trayIcon;
QPointer<QAction> sysTrayStream;
QPointer<QAction> sysTrayRecord;
QPointer<QAction> sysTrayReplayBuffer;
QPointer<QAction> showHide;
QPointer<QAction> exit;
QPointer<QMenu> trayMenu;
QPointer<QMenu> previewProjector;
QPointer<QMenu> studioProgramProjector;
QPointer<QMenu> multiviewProjectorMenu;
QPointer<QMenu> previewProjectorSource;
QPointer<QMenu> previewProjectorMain;
QPointer<QMenu> sceneProjectorMenu;
QPointer<QMenu> sourceProjector;
QPointer<QMenu> scaleFilteringMenu;
QPointer<QMenu> colorMenu;
QPointer<QWidgetAction> colorWidgetAction;
QPointer<ColorSelect> colorSelect;
QPointer<QMenu> deinterlaceMenu;
QPointer<QMenu> perSceneTransitionMenu;
QPointer<QObject> shortcutFilter;
QPointer<QAction> sysTrayStream;
QPointer<QAction> sysTrayRecord;
QPointer<QAction> sysTrayReplayBuffer;
QPointer<QAction> showHide;
QPointer<QAction> exit;
QPointer<QMenu> trayMenu;
QPointer<QMenu> previewProjector;
QPointer<QMenu> studioProgramProjector;
QPointer<QMenu> multiviewProjectorMenu;
QPointer<QMenu> previewProjectorSource;
QPointer<QMenu> previewProjectorMain;
QPointer<QMenu> sceneProjectorMenu;
QPointer<QMenu> sourceProjector;
QPointer<QMenu> scaleFilteringMenu;
QPointer<QMenu> colorMenu;
QPointer<QWidgetAction> colorWidgetAction;
QPointer<ColorSelect> colorSelect;
QPointer<QMenu> deinterlaceMenu;
QPointer<QMenu> perSceneTransitionMenu;
QPointer<QObject> shortcutFilter;
QPointer<QWidget> programWidget;
QPointer<QVBoxLayout> programLayout;
@ -238,47 +234,47 @@ private:
QScopedPointer<QThread> patronJsonThread;
std::string patronJson;
void UpdateMultiviewProjectorMenu();
void UpdateMultiviewProjectorMenu();
void DrawBackdrop(float cx, float cy);
void DrawBackdrop(float cx, float cy);
void SetupEncoders();
void SetupEncoders();
void CreateFirstRunSources();
void CreateDefaultScene(bool firstStart);
void CreateFirstRunSources();
void CreateDefaultScene(bool firstStart);
void UpdateVolumeControlsDecayRate();
void UpdateVolumeControlsPeakMeterType();
void ClearVolumeControls();
void UpdateVolumeControlsDecayRate();
void UpdateVolumeControlsPeakMeterType();
void ClearVolumeControls();
void UploadLog(const char *subdir, const char *file);
void UploadLog(const char *subdir, const char *file);
void Save(const char *file);
void Load(const char *file);
void Save(const char *file);
void Load(const char *file);
void InitHotkeys();
void CreateHotkeys();
void ClearHotkeys();
void InitHotkeys();
void CreateHotkeys();
void ClearHotkeys();
bool InitService();
bool InitService();
bool InitBasicConfigDefaults();
void InitBasicConfigDefaults2();
bool InitBasicConfig();
bool InitBasicConfigDefaults();
void InitBasicConfigDefaults2();
bool InitBasicConfig();
void InitOBSCallbacks();
void InitOBSCallbacks();
void InitPrimitives();
void InitPrimitives();
void OnFirstLoad();
void OnFirstLoad();
OBSSceneItem GetSceneItem(QListWidgetItem *item);
OBSSceneItem GetCurrentSceneItem();
OBSSceneItem GetSceneItem(QListWidgetItem *item);
OBSSceneItem GetCurrentSceneItem();
bool QueryRemoveSource(obs_source_t *source);
bool QueryRemoveSource(obs_source_t *source);
void TimedCheckForUpdates();
void CheckForUpdates(bool manualUpdate);
void TimedCheckForUpdates();
void CheckForUpdates(bool manualUpdate);
void GetFPSCommon(uint32_t &num, uint32_t &den) const;
void GetFPSInteger(uint32_t &num, uint32_t &den) const;
@ -293,8 +289,8 @@ private:
void ChangeSceneIndex(bool relative, int idx, int invalidIdx);
void TempFileOutput(const char *path, int vBitrate, int aBitrate);
void TempStreamOutput(const char *url, const char *key,
int vBitrate, int aBitrate);
void TempStreamOutput(const char *url, const char *key, int vBitrate,
int aBitrate);
void CloseDialogs();
void ClearSceneData();
@ -302,7 +298,7 @@ private:
void Nudge(int dist, MoveDir dir);
OBSProjector *OpenProjector(obs_source_t *source, int monitor,
QString title, ProjectorType type);
QString title, ProjectorType type);
void GetAudioSourceFilters();
void GetAudioSourceProperties();
@ -327,8 +323,8 @@ private:
int GetTopSelectedSourceItem();
obs_hotkey_pair_id streamingHotkeys, recordingHotkeys,
replayBufHotkeys, togglePreviewHotkeys;
obs_hotkey_pair_id streamingHotkeys, recordingHotkeys, replayBufHotkeys,
togglePreviewHotkeys;
obs_hotkey_id forceStreamingStopHotkey;
void InitDefaultTransitions();
@ -368,7 +364,7 @@ private:
void SetPreviewProgramMode(bool enabled);
void ResizeProgram(uint32_t cx, uint32_t cy);
void SetCurrentScene(obs_scene_t *scene, bool force = false,
bool direct = false);
bool direct = false);
static void RenderProgram(void *data, uint32_t cx, uint32_t cy);
std::vector<QuickTransition> quickTransitions;
@ -386,8 +382,8 @@ private:
int quickTransitionIdCounter = 1;
bool overridingTransition = false;
int programX = 0, programY = 0;
int programCX = 0, programCY = 0;
int programX = 0, programY = 0;
int programCX = 0, programCY = 0;
float programScale = 0.0f;
int disableOutputsRef = 0;
@ -407,9 +403,9 @@ private:
void EnumDialogs();
QList<QDialog*> visDialogs;
QList<QDialog*> modalDialogs;
QList<QMessageBox*> visMsgBoxes;
QList<QDialog *> visDialogs;
QList<QDialog *> modalDialogs;
QList<QMessageBox *> visMsgBoxes;
QList<QPoint> visDlgPositions;
@ -457,15 +453,15 @@ public slots:
void SetTransition(OBSSource transition);
void TransitionToScene(OBSScene scene, bool force = false,
bool direct = false);
bool direct = false);
void TransitionToScene(OBSSource scene, bool force = false,
bool direct = false, bool quickTransition = false);
bool direct = false,
bool quickTransition = false);
void SetCurrentScene(OBSSource scene, bool force = false,
bool direct = false);
bool direct = false);
bool AddSceneCollection(
bool create_new,
const QString &name = QString());
bool AddSceneCollection(bool create_new,
const QString &name = QString());
void UpdatePatronJson(const QString &text, const QString &error);
@ -575,7 +571,7 @@ public:
}
obs_service_t *GetService();
void SetService(obs_service_t *service);
void SetService(obs_service_t *service);
int GetTransitionDuration();
@ -588,29 +584,26 @@ public:
bool Active() const;
void ResetUI();
int ResetVideo();
int ResetVideo();
bool ResetAudio();
void ResetOutputs();
void ResetAudioDevice(const char *sourceId, const char *deviceId,
const char *deviceDesc, int channel);
const char *deviceDesc, int channel);
void NewProject();
void LoadProject();
inline void GetDisplayRect(int &x, int &y, int &cx, int &cy)
{
x = previewX;
y = previewY;
x = previewX;
y = previewY;
cx = previewCX;
cy = previewCY;
}
inline bool SavingDisabled() const
{
return disableSaving;
}
inline bool SavingDisabled() const { return disableSaving; }
inline double GetCPUUsage() const
{
@ -620,7 +613,7 @@ public:
void SaveService();
bool LoadService();
inline Auth *GetAuth() {return auth.get();}
inline Auth *GetAuth() { return auth.get(); }
inline void EnableOutputs(bool enable)
{
@ -635,7 +628,8 @@ public:
QMenu *AddDeinterlacingMenu(QMenu *menu, obs_source_t *source);
QMenu *AddScaleFilteringMenu(QMenu *menu, obs_sceneitem_t *item);
QMenu *AddBackgroundColorMenu(QMenu *menu, QWidgetAction *widgetAction,
ColorSelect *select, obs_sceneitem_t *item);
ColorSelect *select,
obs_sceneitem_t *item);
void CreateSourcePopupMenu(int idx, bool preview);
void UpdateTitleBar();
@ -691,7 +685,7 @@ private slots:
void on_actionHorizontalCenter_triggered();
void on_scenes_currentItemChanged(QListWidgetItem *current,
QListWidgetItem *prev);
QListWidgetItem *prev);
void on_scenes_customContextMenuRequested(const QPoint &pos);
void on_actionAddScene_triggered();
void on_actionRemoveScene_triggered();
@ -728,8 +722,8 @@ private slots:
void on_preview_customContextMenuRequested(const QPoint &pos);
void on_program_customContextMenuRequested(const QPoint &pos);
void on_previewDisabledLabel_customContextMenuRequested(
const QPoint &pos);
void
on_previewDisabledLabel_customContextMenuRequested(const QPoint &pos);
void on_actionNewSceneCollection_triggered();
void on_actionDupSceneCollection_triggered();
@ -779,7 +773,7 @@ private slots:
void EditSceneItemName();
void SceneNameEdited(QWidget *editor,
QAbstractItemDelegate::EndEditHint endHint);
QAbstractItemDelegate::EndEditHint endHint);
void OpenSceneFilters();
void OpenFilters();
@ -825,8 +819,8 @@ public:
virtual config_t *Config() const override;
virtual int GetProfilePath(char *path, size_t size, const char *file)
const override;
virtual int GetProfilePath(char *path, size_t size,
const char *file) const override;
static void InitBrowserPanelSafeBlock();
@ -839,8 +833,8 @@ class SceneRenameDelegate : public QStyledItemDelegate {
public:
SceneRenameDelegate(QObject *parent);
virtual void setEditorData(QWidget *editor, const QModelIndex &index)
const override;
virtual void setEditorData(QWidget *editor,
const QModelIndex &index) const override;
protected:
virtual bool eventFilter(QObject *editor, QEvent *event) override;

View file

@ -11,7 +11,7 @@
#include "obs-app.hpp"
#include "platform.hpp"
#define HANDLE_RADIUS 4.0f
#define HANDLE_RADIUS 4.0f
#define HANDLE_SEL_RADIUS (HANDLE_RADIUS * 1.5f)
#if QT_VERSION >= QT_VERSION_CHECK(5, 6, 0)
#define SUPPORTS_FRACTIONAL_SCALING
@ -37,7 +37,7 @@ OBSBasicPreview::~OBSBasicPreview()
vec2 OBSBasicPreview::GetMouseEventPos(QMouseEvent *event)
{
OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
#ifdef SUPPORTS_FRACTIONAL_SCALING
float pixelRatio = main->devicePixelRatioF();
#else
@ -46,28 +46,28 @@ vec2 OBSBasicPreview::GetMouseEventPos(QMouseEvent *event)
float scale = pixelRatio / main->previewScale;
vec2 pos;
vec2_set(&pos,
(float(event->x()) - main->previewX / pixelRatio) * scale,
(float(event->y()) - main->previewY / pixelRatio) * scale);
(float(event->x()) - main->previewX / pixelRatio) * scale,
(float(event->y()) - main->previewY / pixelRatio) * scale);
return pos;
}
struct SceneFindData {
const vec2 &pos;
const vec2 &pos;
OBSSceneItem item;
bool selectBelow;
bool selectBelow;
obs_sceneitem_t *group = nullptr;
SceneFindData(const SceneFindData &) = delete;
SceneFindData(SceneFindData &&) = delete;
SceneFindData& operator=(const SceneFindData &) = delete;
SceneFindData& operator=(SceneFindData &&) = delete;
SceneFindData &operator=(const SceneFindData &) = delete;
SceneFindData &operator=(SceneFindData &&) = delete;
inline SceneFindData(const vec2 &pos_, bool selectBelow_)
: pos (pos_),
selectBelow (selectBelow_)
{}
: pos(pos_), selectBelow(selectBelow_)
{
}
};
static bool SceneItemHasVideo(obs_sceneitem_t *item)
@ -77,21 +77,21 @@ static bool SceneItemHasVideo(obs_sceneitem_t *item)
return (flags & OBS_SOURCE_VIDEO) != 0;
}
static bool CloseFloat(float a, float b, float epsilon=0.01)
static bool CloseFloat(float a, float b, float epsilon = 0.01)
{
using std::abs;
return abs(a-b) <= epsilon;
return abs(a - b) <= epsilon;
}
static bool FindItemAtPos(obs_scene_t *scene, obs_sceneitem_t *item,
void *param)
void *param)
{
SceneFindData *data = reinterpret_cast<SceneFindData*>(param);
matrix4 transform;
matrix4 invTransform;
vec3 transformedPos;
vec3 pos3;
vec3 pos3_;
SceneFindData *data = reinterpret_cast<SceneFindData *>(param);
matrix4 transform;
matrix4 invTransform;
vec3 transformedPos;
vec3 pos3;
vec3 pos3_;
if (!SceneItemHasVideo(item))
return true;
@ -147,54 +147,50 @@ static inline vec2 GetOBSScreenSize()
vec3 OBSBasicPreview::GetSnapOffset(const vec3 &tl, const vec3 &br)
{
OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
vec2 screenSize = GetOBSScreenSize();
vec3 clampOffset;
vec3_zero(&clampOffset);
const bool snap = config_get_bool(GetGlobalConfig(),
"BasicWindow", "SnappingEnabled");
const bool snap = config_get_bool(GetGlobalConfig(), "BasicWindow",
"SnappingEnabled");
if (snap == false)
return clampOffset;
const bool screenSnap = config_get_bool(GetGlobalConfig(),
"BasicWindow", "ScreenSnapping");
const bool centerSnap = config_get_bool(GetGlobalConfig(),
"BasicWindow", "CenterSnapping");
const bool screenSnap = config_get_bool(
GetGlobalConfig(), "BasicWindow", "ScreenSnapping");
const bool centerSnap = config_get_bool(
GetGlobalConfig(), "BasicWindow", "CenterSnapping");
const float clampDist = config_get_double(GetGlobalConfig(),
"BasicWindow", "SnapDistance") / main->previewScale;
"BasicWindow",
"SnapDistance") /
main->previewScale;
const float centerX = br.x - (br.x - tl.x) / 2.0f;
const float centerY = br.y - (br.y - tl.y) / 2.0f;
// Left screen edge.
if (screenSnap &&
fabsf(tl.x) < clampDist)
if (screenSnap && fabsf(tl.x) < clampDist)
clampOffset.x = -tl.x;
// Right screen edge.
if (screenSnap &&
fabsf(clampOffset.x) < EPSILON &&
if (screenSnap && fabsf(clampOffset.x) < EPSILON &&
fabsf(screenSize.x - br.x) < clampDist)
clampOffset.x = screenSize.x - br.x;
// Horizontal center.
if (centerSnap &&
fabsf(screenSize.x - (br.x - tl.x)) > clampDist &&
if (centerSnap && fabsf(screenSize.x - (br.x - tl.x)) > clampDist &&
fabsf(screenSize.x / 2.0f - centerX) < clampDist)
clampOffset.x = screenSize.x / 2.0f - centerX;
// Top screen edge.
if (screenSnap &&
fabsf(tl.y) < clampDist)
if (screenSnap && fabsf(tl.y) < clampDist)
clampOffset.y = -tl.y;
// Bottom screen edge.
if (screenSnap &&
fabsf(clampOffset.y) < EPSILON &&
if (screenSnap && fabsf(clampOffset.y) < EPSILON &&
fabsf(screenSize.y - br.y) < clampDist)
clampOffset.y = screenSize.y - br.y;
// Vertical center.
if (centerSnap &&
fabsf(screenSize.y - (br.y - tl.y)) > clampDist &&
if (centerSnap && fabsf(screenSize.y - (br.y - tl.y)) > clampDist &&
fabsf(screenSize.y / 2.0f - centerY) < clampDist)
clampOffset.y = screenSize.y / 2.0f - centerY;
@ -203,7 +199,7 @@ vec3 OBSBasicPreview::GetSnapOffset(const vec3 &tl, const vec3 &br)
OBSSceneItem OBSBasicPreview::GetItemAtPos(const vec2 &pos, bool selectBelow)
{
OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
OBSScene scene = main->GetCurrentScene();
if (!scene)
@ -215,12 +211,12 @@ OBSSceneItem OBSBasicPreview::GetItemAtPos(const vec2 &pos, bool selectBelow)
}
static bool CheckItemSelected(obs_scene_t *scene, obs_sceneitem_t *item,
void *param)
void *param)
{
SceneFindData *data = reinterpret_cast<SceneFindData*>(param);
matrix4 transform;
vec3 transformedPos;
vec3 pos3;
SceneFindData *data = reinterpret_cast<SceneFindData *>(param);
matrix4 transform;
vec3 transformedPos;
vec3 pos3;
if (!SceneItemHasVideo(item))
return true;
@ -240,7 +236,8 @@ static bool CheckItemSelected(obs_scene_t *scene, obs_sceneitem_t *item,
if (data->group) {
matrix4 parent_transform;
obs_sceneitem_get_draw_transform(data->group, &parent_transform);
obs_sceneitem_get_draw_transform(data->group,
&parent_transform);
matrix4_mul(&transform, &transform, &parent_transform);
}
@ -261,7 +258,7 @@ static bool CheckItemSelected(obs_scene_t *scene, obs_sceneitem_t *item,
bool OBSBasicPreview::SelectedAtPos(const vec2 &pos)
{
OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
OBSScene scene = main->GetCurrentScene();
if (!scene)
@ -273,46 +270,45 @@ bool OBSBasicPreview::SelectedAtPos(const vec2 &pos)
}
struct HandleFindData {
const vec2 &pos;
const float radius;
matrix4 parent_xform;
const vec2 &pos;
const float radius;
matrix4 parent_xform;
OBSSceneItem item;
ItemHandle handle = ItemHandle::None;
ItemHandle handle = ItemHandle::None;
HandleFindData(const HandleFindData &) = delete;
HandleFindData(HandleFindData &&) = delete;
HandleFindData& operator=(const HandleFindData &) = delete;
HandleFindData& operator=(HandleFindData &&) = delete;
HandleFindData &operator=(const HandleFindData &) = delete;
HandleFindData &operator=(HandleFindData &&) = delete;
inline HandleFindData(const vec2 &pos_, float scale)
: pos (pos_),
radius (HANDLE_SEL_RADIUS / scale)
: pos(pos_), radius(HANDLE_SEL_RADIUS / scale)
{
matrix4_identity(&parent_xform);
}
inline HandleFindData(const HandleFindData &hfd,
obs_sceneitem_t *parent)
: pos (hfd.pos),
radius (hfd.radius),
item (hfd.item),
handle (hfd.handle)
obs_sceneitem_t *parent)
: pos(hfd.pos),
radius(hfd.radius),
item(hfd.item),
handle(hfd.handle)
{
obs_sceneitem_get_draw_transform(parent, &parent_xform);
}
};
static bool FindHandleAtPos(obs_scene_t *scene, obs_sceneitem_t *item,
void *param)
void *param)
{
HandleFindData &data = *reinterpret_cast<HandleFindData*>(param);
HandleFindData &data = *reinterpret_cast<HandleFindData *>(param);
if (!obs_sceneitem_selected(item)) {
if (obs_sceneitem_is_group(item)) {
HandleFindData newData(data, item);
obs_sceneitem_group_enum_items(item, FindHandleAtPos,
&newData);
&newData);
data.item = newData.item;
data.handle = newData.handle;
}
@ -320,16 +316,15 @@ static bool FindHandleAtPos(obs_scene_t *scene, obs_sceneitem_t *item,
return true;
}
matrix4 transform;
vec3 pos3;
float closestHandle = data.radius;
matrix4 transform;
vec3 pos3;
float closestHandle = data.radius;
vec3_set(&pos3, data.pos.x, data.pos.y, 0.0f);
obs_sceneitem_get_box_transform(item, &transform);
auto TestHandle = [&] (float x, float y, ItemHandle handle)
{
auto TestHandle = [&](float x, float y, ItemHandle handle) {
vec3 handlePos = GetTransformedPos(x, y, transform);
vec3_transform(&handlePos, &handlePos, &data.parent_xform);
@ -337,8 +332,8 @@ static bool FindHandleAtPos(obs_scene_t *scene, obs_sceneitem_t *item,
if (dist < data.radius) {
if (dist < closestHandle) {
closestHandle = dist;
data.handle = handle;
data.item = item;
data.handle = handle;
data.item = item;
}
}
};
@ -370,10 +365,12 @@ static vec2 GetItemSize(obs_sceneitem_t *item)
obs_sceneitem_get_scale(item, &scale);
obs_sceneitem_get_crop(item, &crop);
size.x = float(obs_source_get_width(source) -
crop.left - crop.right) * scale.x;
size.y = float(obs_source_get_height(source) -
crop.top - crop.bottom) * scale.y;
size.x = float(obs_source_get_width(source) - crop.left -
crop.right) *
scale.x;
size.y = float(obs_source_get_height(source) - crop.top -
crop.bottom) *
scale.y;
}
return size;
@ -381,7 +378,7 @@ static vec2 GetItemSize(obs_sceneitem_t *item)
void OBSBasicPreview::GetStretchHandleData(const vec2 &pos)
{
OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
OBSScene scene = main->GetCurrentScene();
if (!scene)
@ -397,13 +394,13 @@ void OBSBasicPreview::GetStretchHandleData(const vec2 &pos)
HandleFindData data(scaled_pos, scale);
obs_scene_enum_items(scene, FindHandleAtPos, &data);
stretchItem = std::move(data.item);
stretchHandle = data.handle;
stretchItem = std::move(data.item);
stretchHandle = data.handle;
if (stretchHandle != ItemHandle::None) {
matrix4 boxTransform;
vec3 itemUL;
float itemRot;
vec3 itemUL;
float itemRot;
stretchItemSize = GetItemSize(stretchItem);
@ -413,32 +410,31 @@ void OBSBasicPreview::GetStretchHandleData(const vec2 &pos)
/* build the item space conversion matrices */
matrix4_identity(&itemToScreen);
matrix4_rotate_aa4f(&itemToScreen, &itemToScreen,
0.0f, 0.0f, 1.0f, RAD(itemRot));
matrix4_translate3f(&itemToScreen, &itemToScreen,
itemUL.x, itemUL.y, 0.0f);
matrix4_rotate_aa4f(&itemToScreen, &itemToScreen, 0.0f, 0.0f,
1.0f, RAD(itemRot));
matrix4_translate3f(&itemToScreen, &itemToScreen, itemUL.x,
itemUL.y, 0.0f);
matrix4_identity(&screenToItem);
matrix4_translate3f(&screenToItem, &screenToItem,
-itemUL.x, -itemUL.y, 0.0f);
matrix4_rotate_aa4f(&screenToItem, &screenToItem,
0.0f, 0.0f, 1.0f, RAD(-itemRot));
matrix4_translate3f(&screenToItem, &screenToItem, -itemUL.x,
-itemUL.y, 0.0f);
matrix4_rotate_aa4f(&screenToItem, &screenToItem, 0.0f, 0.0f,
1.0f, RAD(-itemRot));
obs_sceneitem_get_crop(stretchItem, &startCrop);
obs_sceneitem_get_pos(stretchItem, &startItemPos);
obs_source_t *source = obs_sceneitem_get_source(stretchItem);
cropSize.x = float(obs_source_get_width(source) -
startCrop.left - startCrop.right);
startCrop.left - startCrop.right);
cropSize.y = float(obs_source_get_height(source) -
startCrop.top - startCrop.bottom);
startCrop.top - startCrop.bottom);
stretchGroup = obs_sceneitem_get_group(scene, stretchItem);
if (stretchGroup) {
obs_sceneitem_get_draw_transform(stretchGroup,
&invGroupTransform);
matrix4_inv(&invGroupTransform,
&invGroupTransform);
&invGroupTransform);
matrix4_inv(&invGroupTransform, &invGroupTransform);
obs_sceneitem_defer_group_resize_begin(stretchGroup);
}
}
@ -480,8 +476,8 @@ void OBSBasicPreview::keyReleaseEvent(QKeyEvent *event)
void OBSBasicPreview::wheelEvent(QWheelEvent *event)
{
if (scrollMode && IsFixedScaling()
&& event->orientation() == Qt::Vertical) {
if (scrollMode && IsFixedScaling() &&
event->orientation() == Qt::Vertical) {
if (event->delta() > 0)
SetScalingLevel(scalingLevel + 1);
else if (event->delta() < 0)
@ -512,7 +508,7 @@ void OBSBasicPreview::mousePressEvent(QMouseEvent *event)
return;
}
OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
#ifdef SUPPORTS_FRACTIONAL_SCALING
float pixelRatio = main->devicePixelRatioF();
#else
@ -549,7 +545,7 @@ void OBSBasicPreview::mousePressEvent(QMouseEvent *event)
static bool select_one(obs_scene_t *scene, obs_sceneitem_t *item, void *param)
{
obs_sceneitem_t *selectedItem =
reinterpret_cast<obs_sceneitem_t*>(param);
reinterpret_cast<obs_sceneitem_t *>(param);
if (obs_sceneitem_is_group(item))
obs_sceneitem_group_enum_items(item, select_one, param);
@ -561,12 +557,12 @@ static bool select_one(obs_scene_t *scene, obs_sceneitem_t *item, void *param)
void OBSBasicPreview::DoSelect(const vec2 &pos)
{
OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
OBSScene scene = main->GetCurrentScene();
OBSSceneItem item = GetItemAtPos(pos, true);
OBSScene scene = main->GetCurrentScene();
OBSSceneItem item = GetItemAtPos(pos, true);
obs_scene_enum_items(scene, select_one, (obs_sceneitem_t*)item);
obs_scene_enum_items(scene, select_one, (obs_sceneitem_t *)item);
}
void OBSBasicPreview::DoCtrlSelect(const vec2 &pos)
@ -609,11 +605,11 @@ void OBSBasicPreview::mouseReleaseEvent(QMouseEvent *event)
obs_sceneitem_defer_group_resize_end(stretchGroup);
}
stretchItem = nullptr;
stretchItem = nullptr;
stretchGroup = nullptr;
mouseDown = false;
mouseMoved = false;
cropping = false;
mouseDown = false;
mouseMoved = false;
cropping = false;
OBSSceneItem item = GetItemAtPos(pos, true);
hoveredPreviewItem = item;
@ -626,13 +622,13 @@ struct SelectedItemBounds {
};
static bool AddItemBounds(obs_scene_t *scene, obs_sceneitem_t *item,
void *param)
void *param)
{
SelectedItemBounds *data = reinterpret_cast<SelectedItemBounds*>(param);
SelectedItemBounds *data =
reinterpret_cast<SelectedItemBounds *>(param);
vec3 t[4];
auto add_bounds = [data, &t] ()
{
auto add_bounds = [data, &t]() {
for (const vec3 &v : t) {
if (data->first) {
vec3_copy(&data->tl, &v);
@ -686,9 +682,9 @@ struct OffsetData {
};
static bool GetSourceSnapOffset(obs_scene_t *scene, obs_sceneitem_t *item,
void *param)
void *param)
{
OffsetData *data = reinterpret_cast<OffsetData*>(param);
OffsetData *data = reinterpret_cast<OffsetData *>(param);
if (obs_sceneitem_selected(item))
return true;
@ -696,12 +692,10 @@ static bool GetSourceSnapOffset(obs_scene_t *scene, obs_sceneitem_t *item,
matrix4 boxTransform;
obs_sceneitem_get_box_transform(item, &boxTransform);
vec3 t[4] = {
GetTransformedPos(0.0f, 0.0f, boxTransform),
GetTransformedPos(1.0f, 0.0f, boxTransform),
GetTransformedPos(0.0f, 1.0f, boxTransform),
GetTransformedPos(1.0f, 1.0f, boxTransform)
};
vec3 t[4] = {GetTransformedPos(0.0f, 0.0f, boxTransform),
GetTransformedPos(1.0f, 0.0f, boxTransform),
GetTransformedPos(0.0f, 1.0f, boxTransform),
GetTransformedPos(1.0f, 1.0f, boxTransform)};
bool first = true;
vec3 tl, br;
@ -719,15 +713,15 @@ static bool GetSourceSnapOffset(obs_scene_t *scene, obs_sceneitem_t *item,
}
// Snap to other source edges
#define EDGE_SNAP(l, r, x, y) \
do { \
double dist = fabsf(l.x - data->r.x); \
if (dist < data->clampDist && \
fabsf(data->offset.x) < EPSILON && \
data->tl.y < br.y && \
data->br.y > tl.y && \
(fabsf(data->offset.x) > dist || data->offset.x < EPSILON)) \
data->offset.x = l.x - data->r.x; \
#define EDGE_SNAP(l, r, x, y) \
do { \
double dist = fabsf(l.x - data->r.x); \
if (dist < data->clampDist && \
fabsf(data->offset.x) < EPSILON && data->tl.y < br.y && \
data->br.y > tl.y && \
(fabsf(data->offset.x) > dist || \
data->offset.x < EPSILON)) \
data->offset.x = l.x - data->r.x; \
} while (false)
EDGE_SNAP(tl, br, x, y);
@ -742,7 +736,7 @@ static bool GetSourceSnapOffset(obs_scene_t *scene, obs_sceneitem_t *item,
void OBSBasicPreview::SnapItemMovement(vec2 &offset)
{
OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
OBSScene scene = main->GetCurrentScene();
SelectedItemBounds data;
@ -755,10 +749,10 @@ void OBSBasicPreview::SnapItemMovement(vec2 &offset)
vec3 snapOffset = GetSnapOffset(data.tl, data.br);
const bool snap = config_get_bool(GetGlobalConfig(),
"BasicWindow", "SnappingEnabled");
const bool sourcesSnap = config_get_bool(GetGlobalConfig(),
"BasicWindow", "SourceSnapping");
const bool snap = config_get_bool(GetGlobalConfig(), "BasicWindow",
"SnappingEnabled");
const bool sourcesSnap = config_get_bool(
GetGlobalConfig(), "BasicWindow", "SourceSnapping");
if (snap == false)
return;
if (sourcesSnap == false) {
@ -768,7 +762,9 @@ void OBSBasicPreview::SnapItemMovement(vec2 &offset)
}
const float clampDist = config_get_double(GetGlobalConfig(),
"BasicWindow", "SnapDistance") / main->previewScale;
"BasicWindow",
"SnapDistance") /
main->previewScale;
OffsetData offsetData;
offsetData.clampDist = clampDist;
@ -794,7 +790,7 @@ static bool move_items(obs_scene_t *scene, obs_sceneitem_t *item, void *param)
return true;
bool selected = obs_sceneitem_selected(item);
vec2 *offset = reinterpret_cast<vec2*>(param);
vec2 *offset = reinterpret_cast<vec2 *>(param);
if (obs_sceneitem_is_group(item) && !selected) {
matrix4 transform;
@ -822,7 +818,7 @@ static bool move_items(obs_scene_t *scene, obs_sceneitem_t *item, void *param)
void OBSBasicPreview::MoveItems(const vec2 &pos)
{
Qt::KeyboardModifiers modifiers = QGuiApplication::keyboardModifiers();
OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
OBSScene scene = main->GetCurrentScene();
vec2 offset, moveOffset;
@ -862,14 +858,14 @@ vec3 OBSBasicPreview::CalculateStretchPos(const vec3 &tl, const vec3 &br)
}
void OBSBasicPreview::ClampAspect(vec3 &tl, vec3 &br, vec2 &size,
const vec2 &baseSize)
const vec2 &baseSize)
{
float baseAspect = baseSize.x / baseSize.y;
float aspect = size.x / size.y;
float baseAspect = baseSize.x / baseSize.y;
float aspect = size.x / size.y;
uint32_t stretchFlags = (uint32_t)stretchHandle;
if (stretchHandle == ItemHandle::TopLeft ||
stretchHandle == ItemHandle::TopRight ||
if (stretchHandle == ItemHandle::TopLeft ||
stretchHandle == ItemHandle::TopRight ||
stretchHandle == ItemHandle::BottomLeft ||
stretchHandle == ItemHandle::BottomRight) {
if (aspect < baseAspect) {
@ -887,7 +883,7 @@ void OBSBasicPreview::ClampAspect(vec3 &tl, vec3 &br, vec2 &size,
}
} else if (stretchHandle == ItemHandle::TopCenter ||
stretchHandle == ItemHandle::BottomCenter) {
stretchHandle == ItemHandle::BottomCenter) {
if ((size.y >= 0.0f && size.x >= 0.0f) ||
(size.y <= 0.0f && size.x <= 0.0f))
size.x = size.y * baseAspect;
@ -895,7 +891,7 @@ void OBSBasicPreview::ClampAspect(vec3 &tl, vec3 &br, vec2 &size,
size.x = size.y * baseAspect * -1.0f;
} else if (stretchHandle == ItemHandle::CenterLeft ||
stretchHandle == ItemHandle::CenterRight) {
stretchHandle == ItemHandle::CenterRight) {
if ((size.y >= 0.0f && size.x >= 0.0f) ||
(size.y <= 0.0f && size.x <= 0.0f))
size.y = size.x / baseAspect;
@ -920,12 +916,12 @@ void OBSBasicPreview::ClampAspect(vec3 &tl, vec3 &br, vec2 &size,
void OBSBasicPreview::SnapStretchingToScreen(vec3 &tl, vec3 &br)
{
uint32_t stretchFlags = (uint32_t)stretchHandle;
vec3 newTL = GetTransformedPos(tl.x, tl.y, itemToScreen);
vec3 newTR = GetTransformedPos(br.x, tl.y, itemToScreen);
vec3 newBL = GetTransformedPos(tl.x, br.y, itemToScreen);
vec3 newBR = GetTransformedPos(br.x, br.y, itemToScreen);
vec3 boundingTL;
vec3 boundingBR;
vec3 newTL = GetTransformedPos(tl.x, tl.y, itemToScreen);
vec3 newTR = GetTransformedPos(br.x, tl.y, itemToScreen);
vec3 newBL = GetTransformedPos(tl.x, br.y, itemToScreen);
vec3 newBR = GetTransformedPos(br.x, br.y, itemToScreen);
vec3 boundingTL;
vec3 boundingBR;
vec3_copy(&boundingTL, &newTL);
vec3_min(&boundingTL, &boundingTL, &newTR);
@ -984,14 +980,12 @@ void OBSBasicPreview::CropItem(const vec2 &pos)
vec2 max_tl;
vec2 max_br;
vec2_set(&max_tl,
float(-crop.left) * scale.x,
float(-crop.top) * scale.y);
vec2_set(&max_br,
stretchItemSize.x + crop.right * scale.x,
stretchItemSize.y + crop.bottom * scale.y);
vec2_set(&max_tl, float(-crop.left) * scale.x,
float(-crop.top) * scale.y);
vec2_set(&max_br, stretchItemSize.x + crop.right * scale.x,
stretchItemSize.y + crop.bottom * scale.y);
typedef std::function<float (float, float)> minmax_func_t;
typedef std::function<float(float, float)> minmax_func_t;
minmax_func_t min_x = scale.x < 0.0f ? maxfunc : minfunc;
minmax_func_t min_y = scale.y < 0.0f ? maxfunc : minfunc;
@ -1021,8 +1015,8 @@ void OBSBasicPreview::CropItem(const vec2 &pos)
pos3.y = br.y = max_y(pos3.y, minY);
}
#define ALIGN_X (ITEM_LEFT|ITEM_RIGHT)
#define ALIGN_Y (ITEM_TOP|ITEM_BOTTOM)
#define ALIGN_X (ITEM_LEFT | ITEM_RIGHT)
#define ALIGN_Y (ITEM_TOP | ITEM_BOTTOM)
vec3 newPos;
vec3_zero(&newPos);
@ -1049,12 +1043,14 @@ void OBSBasicPreview::CropItem(const vec2 &pos)
if (stretchFlags & ITEM_LEFT)
crop.left += int(std::round(tl.x / scale.x));
else if (stretchFlags & ITEM_RIGHT)
crop.right += int(std::round((stretchItemSize.x - br.x) / scale.x));
crop.right +=
int(std::round((stretchItemSize.x - br.x) / scale.x));
if (stretchFlags & ITEM_TOP)
crop.top += int(std::round(tl.y / scale.y));
else if (stretchFlags & ITEM_BOTTOM)
crop.bottom += int(std::round((stretchItemSize.y - br.y) / scale.y));
crop.bottom +=
int(std::round((stretchItemSize.y - br.y) / scale.y));
vec3_transform(&newPos, &newPos, &itemToScreen);
newPos.x = std::round(newPos.x);
@ -1075,7 +1071,7 @@ void OBSBasicPreview::CropItem(const vec2 &pos)
obs_sceneitem_defer_update_begin(stretchItem);
obs_sceneitem_set_crop(stretchItem, &crop);
if (boundsType == OBS_BOUNDS_NONE)
obs_sceneitem_set_pos(stretchItem, (vec2*)&newPos);
obs_sceneitem_set_pos(stretchItem, (vec2 *)&newPos);
obs_sceneitem_defer_update_end(stretchItem);
}
@ -1109,19 +1105,20 @@ void OBSBasicPreview::StretchItem(const vec2 &pos)
obs_source_t *source = obs_sceneitem_get_source(stretchItem);
vec2 baseSize;
vec2_set(&baseSize,
float(obs_source_get_width(source)),
float(obs_source_get_height(source)));
vec2_set(&baseSize, float(obs_source_get_width(source)),
float(obs_source_get_height(source)));
vec2 size;
vec2_set(&size,br. x - tl.x, br.y - tl.y);
vec2_set(&size, br.x - tl.x, br.y - tl.y);
if (boundsType != OBS_BOUNDS_NONE) {
if (shiftDown)
ClampAspect(tl, br, size, baseSize);
if (tl.x > br.x) std::swap(tl.x, br.x);
if (tl.y > br.y) std::swap(tl.y, br.y);
if (tl.x > br.x)
std::swap(tl.x, br.x);
if (tl.y > br.y)
std::swap(tl.y, br.y);
vec2_abs(&size, &size);
@ -1177,16 +1174,16 @@ void OBSBasicPreview::mouseMoveEvent(QMouseEvent *event)
pos.y = std::round(pos.y);
if (stretchHandle != ItemHandle::None) {
OBSBasic *main = reinterpret_cast<OBSBasic*>(
App()->GetMainWindow());
OBSBasic *main = reinterpret_cast<OBSBasic *>(
App()->GetMainWindow());
OBSScene scene = main->GetCurrentScene();
obs_sceneitem_t *group = obs_sceneitem_get_group(
scene, stretchItem);
obs_sceneitem_t *group =
obs_sceneitem_get_group(scene, stretchItem);
if (group) {
vec3 group_pos;
vec3_set(&group_pos, pos.x, pos.y, 0.0f);
vec3_transform(&group_pos, &group_pos,
&invGroupTransform);
&invGroupTransform);
pos.x = group_pos.x;
pos.y = group_pos.y;
}
@ -1230,13 +1227,13 @@ static void DrawSquareAtPos(float x, float y)
gs_matrix_translate(&pos);
gs_matrix_translate3f(-HANDLE_RADIUS, -HANDLE_RADIUS, 0.0f);
gs_matrix_scale3f(HANDLE_RADIUS*2, HANDLE_RADIUS*2, 1.0f);
gs_matrix_scale3f(HANDLE_RADIUS * 2, HANDLE_RADIUS * 2, 1.0f);
gs_draw(GS_TRISTRIP, 0, 0);
gs_matrix_pop();
}
static void DrawLine(float x1, float y1, float x2, float y2, float thickness,
vec2 scale)
vec2 scale)
{
float ySide = (y1 == y2) ? (y1 < 0.5f ? 1.0f : -1.0f) : 0.0f;
float xSide = (x1 == x2) ? (x1 < 0.5f ? 1.0f : -1.0f) : 0.0f;
@ -1245,9 +1242,9 @@ static void DrawLine(float x1, float y1, float x2, float y2, float thickness,
gs_vertex2f(x1, y1);
gs_vertex2f(x1 + (xSide * (thickness / scale.x)),
y1 + (ySide * (thickness / scale.y)));
y1 + (ySide * (thickness / scale.y)));
gs_vertex2f(x2 + (xSide * (thickness / scale.x)),
y2 + (ySide * (thickness / scale.y)));
y2 + (ySide * (thickness / scale.y)));
gs_vertex2f(x2, y2);
gs_vertex2f(x1, y1);
@ -1292,14 +1289,12 @@ static void DrawRect(float thickness, vec2 scale)
static inline bool crop_enabled(const obs_sceneitem_crop *crop)
{
return crop->left > 0 ||
crop->top > 0 ||
crop->right > 0 ||
return crop->left > 0 || crop->top > 0 || crop->right > 0 ||
crop->bottom > 0;
}
bool OBSBasicPreview::DrawSelectedOverflow(obs_scene_t *scene,
obs_sceneitem_t *item, void *param)
obs_sceneitem_t *item, void *param)
{
if (obs_sceneitem_locked(item))
return true;
@ -1308,7 +1303,7 @@ bool OBSBasicPreview::DrawSelectedOverflow(obs_scene_t *scene,
return true;
bool select = config_get_bool(GetGlobalConfig(), "BasicWindow",
"OverflowSelectionHidden");
"OverflowSelectionHidden");
if (!select && !obs_sceneitem_visible(item))
return true;
@ -1319,17 +1314,18 @@ bool OBSBasicPreview::DrawSelectedOverflow(obs_scene_t *scene,
gs_matrix_push();
gs_matrix_mul(&mat);
obs_sceneitem_group_enum_items(item, DrawSelectedOverflow, param);
obs_sceneitem_group_enum_items(item, DrawSelectedOverflow,
param);
gs_matrix_pop();
}
bool always = config_get_bool(GetGlobalConfig(), "BasicWindow",
"OverflowAlwaysVisible");
"OverflowAlwaysVisible");
if (!always && !obs_sceneitem_selected(item))
return true;
OBSBasicPreview *prev = reinterpret_cast<OBSBasicPreview*>(param);
OBSBasicPreview *prev = reinterpret_cast<OBSBasicPreview *>(param);
matrix4 boxTransform;
matrix4 invBoxTransform;
@ -1343,14 +1339,13 @@ bool OBSBasicPreview::DrawSelectedOverflow(obs_scene_t *scene,
{{{1.f, 1.f, 0.f}}},
};
bool visible = std::all_of(std::begin(bounds), std::end(bounds),
[&](const vec3 &b)
{
vec3 pos;
vec3_transform(&pos, &b, &boxTransform);
vec3_transform(&pos, &pos, &invBoxTransform);
return CloseFloat(pos.x, b.x) && CloseFloat(pos.y, b.y);
});
bool visible = std::all_of(
std::begin(bounds), std::end(bounds), [&](const vec3 &b) {
vec3 pos;
vec3_transform(&pos, &b, &boxTransform);
vec3_transform(&pos, &pos, &invBoxTransform);
return CloseFloat(pos.x, b.x) && CloseFloat(pos.y, b.y);
});
if (!visible)
return true;
@ -1360,9 +1355,9 @@ bool OBSBasicPreview::DrawSelectedOverflow(obs_scene_t *scene,
obs_transform_info info;
obs_sceneitem_get_info(item, &info);
gs_effect_t *solid = obs_get_base_effect(OBS_EFFECT_REPEAT);
gs_eparam_t *image = gs_effect_get_param_by_name(solid, "image");
gs_eparam_t *scale = gs_effect_get_param_by_name(solid, "scale");
gs_effect_t *solid = obs_get_base_effect(OBS_EFFECT_REPEAT);
gs_eparam_t *image = gs_effect_get_param_by_name(solid, "image");
gs_eparam_t *scale = gs_effect_get_param_by_name(solid, "scale");
vec2 s;
vec2_set(&s, boxTransform.x.x / 96, boxTransform.y.y / 96);
@ -1389,7 +1384,7 @@ bool OBSBasicPreview::DrawSelectedOverflow(obs_scene_t *scene,
}
bool OBSBasicPreview::DrawSelectedItem(obs_scene_t *scene,
obs_sceneitem_t *item, void *param)
obs_sceneitem_t *item, void *param)
{
if (obs_sceneitem_locked(item))
return true;
@ -1407,11 +1402,11 @@ bool OBSBasicPreview::DrawSelectedItem(obs_scene_t *scene,
gs_matrix_pop();
}
OBSBasicPreview *prev = reinterpret_cast<OBSBasicPreview*>(param);
OBSBasicPreview *prev = reinterpret_cast<OBSBasicPreview *>(param);
OBSBasic *main = OBSBasic::Get();
bool hovered = prev->hoveredPreviewItem == item ||
prev->hoveredListItem == item;
prev->hoveredListItem == item;
bool selected = obs_sceneitem_selected(item);
if (!selected && !hovered)
@ -1437,14 +1432,13 @@ bool OBSBasicPreview::DrawSelectedItem(obs_scene_t *scene,
vec4_set(&green, 0.0f, 1.0f, 0.0f, 1.0f);
vec4_set(&blue, 0.0f, 0.5f, 1.0f, 1.0f);
bool visible = std::all_of(std::begin(bounds), std::end(bounds),
[&](const vec3 &b)
{
vec3 pos;
vec3_transform(&pos, &b, &boxTransform);
vec3_transform(&pos, &pos, &invBoxTransform);
return CloseFloat(pos.x, b.x) && CloseFloat(pos.y, b.y);
});
bool visible = std::all_of(
std::begin(bounds), std::end(bounds), [&](const vec3 &b) {
vec3 pos;
vec3_transform(&pos, &b, &boxTransform);
vec3_transform(&pos, &pos, &invBoxTransform);
return CloseFloat(pos.x, b.x) && CloseFloat(pos.y, b.y);
});
if (!visible)
return true;
@ -1471,17 +1465,17 @@ bool OBSBasicPreview::DrawSelectedItem(obs_scene_t *scene,
gs_eparam_t *colParam = gs_effect_get_param_by_name(eff, "color");
if (info.bounds_type == OBS_BOUNDS_NONE && crop_enabled(&crop)) {
#define DRAW_SIDE(side, x1, y1, x2, y2) \
if (hovered && !selected) \
gs_effect_set_vec4(colParam, &blue); \
else if (crop.side > 0) \
gs_effect_set_vec4(colParam, &green); \
DrawLine(x1, y1, x2, y2, HANDLE_RADIUS / 2, boxScale); \
gs_effect_set_vec4(colParam, &red);
#define DRAW_SIDE(side, x1, y1, x2, y2) \
if (hovered && !selected) \
gs_effect_set_vec4(colParam, &blue); \
else if (crop.side > 0) \
gs_effect_set_vec4(colParam, &green); \
DrawLine(x1, y1, x2, y2, HANDLE_RADIUS / 2, boxScale); \
gs_effect_set_vec4(colParam, &red);
DRAW_SIDE(left, 0.0f, 0.0f, 0.0f, 1.0f);
DRAW_SIDE(top, 0.0f, 0.0f, 1.0f, 0.0f);
DRAW_SIDE(right, 1.0f, 0.0f, 1.0f, 1.0f);
DRAW_SIDE(left, 0.0f, 0.0f, 0.0f, 1.0f);
DRAW_SIDE(top, 0.0f, 0.0f, 1.0f, 0.0f);
DRAW_SIDE(right, 1.0f, 0.0f, 1.0f, 1.0f);
DRAW_SIDE(bottom, 0.0f, 1.0f, 1.0f, 1.0f);
#undef DRAW_SIDE
} else {
@ -1522,7 +1516,7 @@ void OBSBasicPreview::DrawOverflow()
return;
bool hidden = config_get_bool(GetGlobalConfig(), "BasicWindow",
"OverflowHidden");
"OverflowHidden");
if (hidden)
return;
@ -1535,7 +1529,7 @@ void OBSBasicPreview::DrawOverflow()
overflow = gs_texture_create_from_file(path.c_str());
}
OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
OBSScene scene = main->GetCurrentScene();
@ -1558,10 +1552,10 @@ void OBSBasicPreview::DrawSceneEditing()
GS_DEBUG_MARKER_BEGIN(GS_DEBUG_COLOR_DEFAULT, "DrawSceneEditing");
OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
OBSBasic *main = reinterpret_cast<OBSBasic *>(App()->GetMainWindow());
gs_effect_t *solid = obs_get_base_effect(OBS_EFFECT_SOLID);
gs_technique_t *tech = gs_effect_get_technique(solid, "Solid");
gs_effect_t *solid = obs_get_base_effect(OBS_EFFECT_SOLID);
gs_technique_t *tech = gs_effect_get_technique(solid, "Solid");
vec4 color;
vec4_set(&color, 1.0f, 0.0f, 0.0f, 1.0f);
@ -1592,13 +1586,16 @@ void OBSBasicPreview::ResetScrollingOffset()
vec2_zero(&scrollingOffset);
}
void OBSBasicPreview::SetScalingLevel(int32_t newScalingLevelVal) {
float newScalingAmountVal = pow(ZOOM_SENSITIVITY, float(newScalingLevelVal));
void OBSBasicPreview::SetScalingLevel(int32_t newScalingLevelVal)
{
float newScalingAmountVal =
pow(ZOOM_SENSITIVITY, float(newScalingLevelVal));
scalingLevel = newScalingLevelVal;
SetScalingAmount(newScalingAmountVal);
}
void OBSBasicPreview::SetScalingAmount(float newScalingAmountVal) {
void OBSBasicPreview::SetScalingAmount(float newScalingAmountVal)
{
scrollingOffset.x *= newScalingAmountVal / scalingAmount;
scrollingOffset.y *= newScalingAmountVal / scalingAmount;
scalingAmount = newScalingAmountVal;

View file

@ -9,23 +9,23 @@
class OBSBasic;
class QMouseEvent;
#define ITEM_LEFT (1<<0)
#define ITEM_RIGHT (1<<1)
#define ITEM_TOP (1<<2)
#define ITEM_BOTTOM (1<<3)
#define ITEM_LEFT (1 << 0)
#define ITEM_RIGHT (1 << 1)
#define ITEM_TOP (1 << 2)
#define ITEM_BOTTOM (1 << 3)
#define ZOOM_SENSITIVITY 1.125f
enum class ItemHandle : uint32_t {
None = 0,
TopLeft = ITEM_TOP | ITEM_LEFT,
TopCenter = ITEM_TOP,
TopRight = ITEM_TOP | ITEM_RIGHT,
CenterLeft = ITEM_LEFT,
CenterRight = ITEM_RIGHT,
BottomLeft = ITEM_BOTTOM | ITEM_LEFT,
None = 0,
TopLeft = ITEM_TOP | ITEM_LEFT,
TopCenter = ITEM_TOP,
TopRight = ITEM_TOP | ITEM_RIGHT,
CenterLeft = ITEM_LEFT,
CenterRight = ITEM_RIGHT,
BottomLeft = ITEM_BOTTOM | ITEM_LEFT,
BottomCenter = ITEM_BOTTOM,
BottomRight = ITEM_BOTTOM | ITEM_RIGHT
BottomRight = ITEM_BOTTOM | ITEM_RIGHT,
};
class OBSBasicPreview : public OBSQTDisplay {
@ -35,40 +35,40 @@ class OBSBasicPreview : public OBSQTDisplay {
private:
obs_sceneitem_crop startCrop;
vec2 startItemPos;
vec2 cropSize;
vec2 startItemPos;
vec2 cropSize;
OBSSceneItem stretchGroup;
OBSSceneItem stretchItem;
ItemHandle stretchHandle = ItemHandle::None;
vec2 stretchItemSize;
matrix4 screenToItem;
matrix4 itemToScreen;
matrix4 invGroupTransform;
ItemHandle stretchHandle = ItemHandle::None;
vec2 stretchItemSize;
matrix4 screenToItem;
matrix4 itemToScreen;
matrix4 invGroupTransform;
gs_texture_t *overflow = nullptr;
vec2 startPos;
vec2 lastMoveOffset;
vec2 scrollingFrom;
vec2 scrollingOffset;
bool mouseDown = false;
bool mouseMoved = false;
bool mouseOverItems = false;
bool cropping = false;
bool locked = false;
bool scrollMode = false;
bool fixedScaling = false;
int32_t scalingLevel = 0;
float scalingAmount = 1.0f;
vec2 startPos;
vec2 lastMoveOffset;
vec2 scrollingFrom;
vec2 scrollingOffset;
bool mouseDown = false;
bool mouseMoved = false;
bool mouseOverItems = false;
bool cropping = false;
bool locked = false;
bool scrollMode = false;
bool fixedScaling = false;
int32_t scalingLevel = 0;
float scalingAmount = 1.0f;
obs_sceneitem_t *hoveredPreviewItem = nullptr;
obs_sceneitem_t *hoveredListItem = nullptr;
obs_sceneitem_t *hoveredListItem = nullptr;
static vec2 GetMouseEventPos(QMouseEvent *event);
static bool DrawSelectedOverflow(obs_scene_t *scene,
obs_sceneitem_t *item, void *param);
obs_sceneitem_t *item, void *param);
static bool DrawSelectedItem(obs_scene_t *scene, obs_sceneitem_t *item,
void *param);
void *param);
static OBSSceneItem GetItemAtPos(const vec2 &pos, bool selectBelow);
static bool SelectedAtPos(const vec2 &pos);
@ -110,11 +110,14 @@ public:
void DrawOverflow();
void DrawSceneEditing();
inline void SetLocked(bool newLockedVal) {locked = newLockedVal;}
inline void ToggleLocked() {locked = !locked;}
inline bool Locked() const {return locked;}
inline void SetLocked(bool newLockedVal) { locked = newLockedVal; }
inline void ToggleLocked() { locked = !locked; }
inline bool Locked() const { return locked; }
inline void SetFixedScaling(bool newFixedScalingVal) { fixedScaling = newFixedScalingVal; }
inline void SetFixedScaling(bool newFixedScalingVal)
{
fixedScaling = newFixedScalingVal;
}
inline bool IsFixedScaling() const { return fixedScaling; }
void SetScalingLevel(int32_t newScalingLevelVal);
@ -123,14 +126,17 @@ public:
inline float GetScalingAmount() const { return scalingAmount; }
void ResetScrollingOffset();
inline void SetScrollingOffset(float x, float y) {vec2_set(&scrollingOffset, x, y);}
inline float GetScrollX() const {return scrollingOffset.x;}
inline float GetScrollY() const {return scrollingOffset.y;}
inline void SetScrollingOffset(float x, float y)
{
vec2_set(&scrollingOffset, x, y);
}
inline float GetScrollX() const { return scrollingOffset.x; }
inline float GetScrollY() const { return scrollingOffset.y; }
/* use libobs allocator for alignment because the matrices itemToScreen
* and screenToItem may contain SSE data, which will cause SSE
* instructions to crash if the data is not aligned to at least a 16
* byte boundary. */
static inline void* operator new(size_t size) {return bmalloc(size);}
static inline void operator delete(void* ptr) {bfree(ptr);}
static inline void *operator new(size_t size) { return bmalloc(size); }
static inline void operator delete(void *ptr) { bfree(ptr); }
};

Some files were not shown because too many files have changed in this diff Show more