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),
		  removedSignal(obs_source_get_signal_handler(source), "remove",
				  &OBSSourceLabel::SourceRemoved, this),
		  destroyedSignal(obs_source_get_signal_handler(source),
				  "destroy", &OBSSourceLabel::SourceDestroyed,
				  this)
	{}
Esempio n. 2
0
static void *scene_create(obs_data_t *settings, struct obs_source *source)
{
	pthread_mutexattr_t attr;
	struct obs_scene *scene = bmalloc(sizeof(struct obs_scene));
	scene->source     = source;
	scene->first_item = NULL;

	signal_handler_add_array(obs_source_get_signal_handler(source),
			obs_scene_signals);

	if (pthread_mutexattr_init(&attr) != 0)
		goto fail;
	if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE) != 0)
		goto fail;
	if (pthread_mutex_init(&scene->audio_mutex, &attr) != 0) {
		blog(LOG_ERROR, "scene_create: Couldn't initialize audio "
				"mutex");
		goto fail;
	}
	if (pthread_mutex_init(&scene->video_mutex, &attr) != 0) {
		blog(LOG_ERROR, "scene_create: Couldn't initialize video "
				"mutex");
		goto fail;
	}

	UNUSED_PARAMETER(settings);
	return scene;

fail:
	pthread_mutexattr_destroy(&attr);
	bfree(scene);
	return NULL;
}
Esempio n. 3
0
OBSProjector::OBSProjector(QWidget *widget, obs_source_t *source_)
	: OBSQTDisplay                 (widget,
	                                Qt::Window | Qt::FramelessWindowHint |
					Qt::X11BypassWindowManagerHint),
	  source                       (source_),
	  removedSignal                (obs_source_get_signal_handler(source),
	                                "remove", OBSSourceRemoved, this)
{
	setAttribute(Qt::WA_DeleteOnClose, true);

	installEventFilter(CreateShortcutFilter());

	auto addDrawCallback = [this] ()
	{
		obs_display_add_draw_callback(GetDisplay(), OBSRender, this);
		obs_display_set_background_color(GetDisplay(), 0x000000);
	};

	connect(this, &OBSQTDisplay::DisplayCreated, addDrawCallback);

	bool hideCursor = config_get_bool(GetGlobalConfig(),
			"BasicWindow", "HideProjectorCursor");
	if (hideCursor) {
		QPixmap empty(16, 16);
		empty.fill(Qt::transparent);
		setCursor(QCursor(empty));
	}

	App()->IncrementSleepInhibition();
}
BiliSceneWidgetItem::BiliSceneWidgetItem(const char* name, obs_scene_t* pScene, obs_sceneitem_t* pSceneItem)
	: scene(pScene), sceneItem(pSceneItem), itemLabelFullText(name)
{
	setStyleSheet(
		"QWidget { background-color: transparent; } \n"
		"QLabel { background-color: transparent; } \n"
		"QCheckBox { background-color: transparent; } \n"
		);

	setMaximumHeight(28);
	setMinimumHeight(28);

	QHBoxLayout *itemLayout = new QHBoxLayout();
	itemLayout->setContentsMargins(10, 2, 3, 2);

	itemCheckBox = new QCheckBox();
	itemCheckBox->setObjectName("sceneItemWidgetCheckBox");
	itemLabel = new QLabel();

	//itemMoveUpBtn->setStyleSheet(
	//	"QPushButton { background-position: center; background-repeat: no-repeat; background-image: url(:/FucBtn/MoveUp); } \n"
	//	"QPushButton:hover { background-image: url(:/FucBtn/MoveUpHS); } \n"
	//	);
	//itemMoveDownBtn->setStyleSheet(
	//	"QPushButton { background-position: center; background-repeat: no-repeat; background-image: url(:/FucBtn/MoveDown); } \n"
	//	"QPushButton:hover { background-image: url(:/FucBtn/MoveDownHS); } \n"
	//	);

	itemCheckBox->setMaximumSize(24, 24);
	itemCheckBox->setMinimumSize(24, 24);

	itemLayout->addWidget(itemCheckBox);
	itemLayout->addWidget(itemLabel);

	//itemLabel->setText(name);
	limitLabelContext(itemLabel, itemLabelFullText, label_context_length_restriction, QStringLiteral("бн"));

	setLayout(itemLayout);

	sourceVisibleSignal.Connect(obs_source_get_signal_handler(obs_scene_get_source(scene)), "item_visible", &BiliSceneWidgetItem::OnItemVisibleChanged, this);
	QObject::connect(itemCheckBox, SIGNAL(stateChanged(int)), this, SLOT(onCheckStateChanged(int)));
}
void OBSBasicTransform::SetScene(OBSScene scene)
{
	transformSignal.Disconnect();
	selectSignal.Disconnect();
	deselectSignal.Disconnect();
	removeSignal.Disconnect();

	if (scene) {
		OBSSource source = obs_scene_get_source(scene);
		signal_handler_t *signal = obs_source_get_signal_handler(source);

		transformSignal.Connect(signal, "item_transform",
				OBSSceneItemTransform, this);
		removeSignal.Connect(signal, "item_remove",
				OBSSceneItemRemoved, this);
		selectSignal.Connect(signal, "item_select",
				OBSSceneItemSelect, this);
		deselectSignal.Connect(signal, "item_deselect",
				OBSSceneItemDeselect, this);
	}
}
Esempio n. 6
0
void obs_fader_detach_source(obs_fader_t *fader)
{
	signal_handler_t *sh;

	if (!fader)
		return;

	pthread_mutex_lock(&fader->mutex);

	if (!fader->source)
		goto exit;

	sh = obs_source_get_signal_handler(fader->source);
	signal_handler_disconnect(sh, "volume",
			fader_source_volume_changed, fader);
	signal_handler_disconnect(sh, "destroy",
			fader_source_destroyed, fader);

	fader->source = NULL;

exit:
	pthread_mutex_unlock(&fader->mutex);
}
Esempio n. 7
0
bool obs_fader_attach_source(obs_fader_t *fader, obs_source_t *source)
{
	signal_handler_t *sh;

	if (!fader || !source)
		return false;

	obs_fader_detach_source(fader);

	pthread_mutex_lock(&fader->mutex);

	sh = obs_source_get_signal_handler(source);
	signal_handler_connect(sh, "volume",
			fader_source_volume_changed, fader);
	signal_handler_connect(sh, "destroy",
			fader_source_destroyed, fader);

	fader->source = source;
	fader->cur_db = mul_to_db(obs_source_get_volume(source));

	pthread_mutex_unlock(&fader->mutex);

	return true;
}
Esempio n. 8
0
OBSProjector::OBSProjector(QWidget *widget, obs_source_t *source_, int monitor,
		QString title, ProjectorType type_)
	: OBSQTDisplay                 (widget,
	                                Qt::Window),
	  source                       (source_),
	  removedSignal                (obs_source_get_signal_handler(source),
	                                "remove", OBSSourceRemoved, this)
{
	projectorTitle = std::move(title);
	savedMonitor   = monitor;
	isWindow       = savedMonitor < 0;
	type           = type_;

	if (isWindow) {
		setWindowIcon(QIcon::fromTheme("obs",
				QIcon(":/res/images/obs.png")));

		UpdateProjectorTitle(projectorTitle);
		windowedProjectors.push_back(this);

		resize(480, 270);
	} else {
		setWindowFlags(Qt::FramelessWindowHint |
				Qt::X11BypassWindowManagerHint);

		QScreen *screen = QGuiApplication::screens()[savedMonitor];
		setGeometry(screen->geometry());

		QAction *action = new QAction(this);
		action->setShortcut(Qt::Key_Escape);
		addAction(action);
		connect(action, SIGNAL(triggered()), this,
				SLOT(EscapeTriggered()));
	}

	SetAlwaysOnTop(this, config_get_bool(GetGlobalConfig(),
			"BasicWindow", "ProjectorAlwaysOnTop"));

	setAttribute(Qt::WA_DeleteOnClose, true);

	//disable application quit when last window closed
	setAttribute(Qt::WA_QuitOnClose, false);

	installEventFilter(CreateShortcutFilter());

	auto addDrawCallback = [this] ()
	{
		bool isMultiview = type == ProjectorType::Multiview;
		obs_display_add_draw_callback(GetDisplay(),
				isMultiview ? OBSRenderMultiview : OBSRender,
				this);
		obs_display_set_background_color(GetDisplay(), 0x000000);
	};

	connect(this, &OBSQTDisplay::DisplayCreated, addDrawCallback);

	bool hideCursor = config_get_bool(GetGlobalConfig(),
			"BasicWindow", "HideProjectorCursor");
	if (hideCursor && !isWindow) {
		QPixmap empty(16, 16);
		empty.fill(Qt::transparent);
		setCursor(QCursor(empty));
	}

	if (type == ProjectorType::Multiview) {
		obs_enter_graphics();

		// All essential action should be placed inside this area
		gs_render_start(true);
		gs_vertex2f(actionSafePercentage, actionSafePercentage);
		gs_vertex2f(actionSafePercentage, 1 - actionSafePercentage);
		gs_vertex2f(1 - actionSafePercentage, 1 - actionSafePercentage);
		gs_vertex2f(1 - actionSafePercentage, actionSafePercentage);
		gs_vertex2f(actionSafePercentage, actionSafePercentage);
		actionSafeMargin = gs_render_save();

		// All graphics should be placed inside this area
		gs_render_start(true);
		gs_vertex2f(graphicsSafePercentage, graphicsSafePercentage);
		gs_vertex2f(graphicsSafePercentage, 1 - graphicsSafePercentage);
		gs_vertex2f(1 - graphicsSafePercentage,
				1 - graphicsSafePercentage);
		gs_vertex2f(1 - graphicsSafePercentage, graphicsSafePercentage);
		gs_vertex2f(graphicsSafePercentage, graphicsSafePercentage);
		graphicsSafeMargin = gs_render_save();

		// 4:3 safe area for widescreen
		gs_render_start(true);
		gs_vertex2f(fourByThreeSafePercentage, graphicsSafePercentage);
		gs_vertex2f(1 - fourByThreeSafePercentage,
				graphicsSafePercentage);
		gs_vertex2f(1 - fourByThreeSafePercentage, 1 -
				graphicsSafePercentage);
		gs_vertex2f(fourByThreeSafePercentage,
				1 - graphicsSafePercentage);
		gs_vertex2f(fourByThreeSafePercentage, graphicsSafePercentage);
		fourByThreeSafeMargin = gs_render_save();

		gs_render_start(true);
		gs_vertex2f(0.0f, 0.5f);
		gs_vertex2f(lineLength, 0.5f);
		leftLine = gs_render_save();

		gs_render_start(true);
		gs_vertex2f(0.5f, 0.0f);
		gs_vertex2f(0.5f, lineLength);
		topLine = gs_render_save();

		gs_render_start(true);
		gs_vertex2f(1.0f, 0.5f);
		gs_vertex2f(1 - lineLength, 0.5f);
		rightLine = gs_render_save();
		obs_leave_graphics();

		solid = obs_get_base_effect(OBS_EFFECT_SOLID);
		color = gs_effect_get_param_by_name(solid, "color");

		UpdateMultiview();

		multiviewProjectors.push_back(this);
	}

	App()->IncrementSleepInhibition();

	if (source)
		obs_source_inc_showing(source);

	ready = true;

	show();

	// We need it here to allow keyboard input in X11 to listen to Escape
	if (!isWindow)
		activateWindow();
}
Esempio n. 9
0
OBSAdvAudioCtrl::OBSAdvAudioCtrl(QGridLayout *, obs_source_t *source_)
	: source(source_)
{
	QHBoxLayout *hlayout;
	signal_handler_t *handler = obs_source_get_signal_handler(source);
	const char *sourceName = obs_source_get_name(source);
	float vol = obs_source_get_volume(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();
#if defined(_WIN32) || defined(__APPLE__) || HAVE_PULSEAUDIO
	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();

	volChangedSignal.Connect(handler, "volume", OBSSourceVolumeChanged,
			this);
	syncOffsetSignal.Connect(handler, "audio_sync", OBSSourceSyncChanged,
			this);
	flagsSignal.Connect(handler, "update_flags", OBSSourceFlagsChanged,
			this);
	mixersSignal.Connect(handler, "audio_mixers", OBSSourceMixersChanged,
			this);

	hlayout = new QHBoxLayout();
	hlayout->setContentsMargins(0, 0, 0, 0);
	forceMonoContainer->setLayout(hlayout);
	hlayout = new QHBoxLayout();
	hlayout->setContentsMargins(0, 0, 0, 0);
	mixerContainer->setLayout(hlayout);
	hlayout = new QHBoxLayout();
	hlayout->setContentsMargins(0, 0, 0, 0);
	balanceContainer->setLayout(hlayout);
	balanceContainer->setMinimumWidth(100);

	labelL->setText("L");

	labelR->setText("R");

	nameLabel->setMinimumWidth(170);
	nameLabel->setText(QT_UTF8(sourceName));
	nameLabel->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);

	volume->setMinimum(MIN_DB - 0.1);
	volume->setMaximum(MAX_DB);
	volume->setSingleStep(0.1);
	volume->setDecimals(1);
	volume->setSuffix(" dB");
	volume->setValue(obs_mul_to_db(vol));

	if (volume->value() < MIN_DB)
		volume->setSpecialValueText("-inf dB");

	forceMono->setChecked((flags & OBS_SOURCE_FLAG_FORCE_MONO) != 0);

	forceMonoContainer->layout()->addWidget(forceMono);
	forceMonoContainer->layout()->setAlignment(forceMono,
			Qt::AlignHCenter | Qt::AlignVCenter);

	balance->setOrientation(Qt::Horizontal);
	balance->setMinimum(0);
	balance->setMaximum(100);
	balance->setTickPosition(QSlider::TicksAbove);
	balance->setTickInterval(50);

	OBSBasic *main = reinterpret_cast<OBSBasic*>(App()->GetMainWindow());

	const char *speakers = config_get_string(main->Config(), "Audio",
			"ChannelSetup");

	if (strcmp(speakers, "Mono") == 0)
		balance->setEnabled(false);
	else
		balance->setEnabled(true);

	float bal = obs_source_get_balance_value(source) * 100.0f;
	balance->setValue((int)bal);

	int64_t cur_sync = obs_source_get_sync_offset(source);
	syncOffset->setMinimum(-950);
	syncOffset->setMaximum(20000);
	syncOffset->setValue(int(cur_sync / NSEC_PER_MSEC));

	int idx;
#if defined(_WIN32) || defined(__APPLE__) || HAVE_PULSEAUDIO
	monitoringType->addItem(QTStr("Basic.AdvAudio.Monitoring.None"),
			(int)OBS_MONITORING_TYPE_NONE);
	monitoringType->addItem(QTStr("Basic.AdvAudio.Monitoring.MonitorOnly"),
			(int)OBS_MONITORING_TYPE_MONITOR_ONLY);
	monitoringType->addItem(QTStr("Basic.AdvAudio.Monitoring.Both"),
			(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));
	mixer2->setText("2");
	mixer2->setChecked(mixers & (1<<1));
	mixer3->setText("3");
	mixer3->setChecked(mixers & (1<<2));
	mixer4->setText("4");
	mixer4->setChecked(mixers & (1<<3));
	mixer5->setText("5");
	mixer5->setChecked(mixers & (1<<4));
	mixer6->setText("6");
	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);
		balanceContainer->layout()->addWidget(labelR);
		balanceContainer->setMaximumWidth(170);
	}

	mixerContainer->layout()->addWidget(mixer1);
	mixerContainer->layout()->addWidget(mixer2);
	mixerContainer->layout()->addWidget(mixer3);
	mixerContainer->layout()->addWidget(mixer4);
	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)));
#if defined(_WIN32) || defined(__APPLE__) || HAVE_PULSEAUDIO
	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)));

	setObjectName(sourceName);
}