2015-04-04 00:37:02 -07:00
|
|
|
#include <QAction>
|
2016-10-03 23:50:13 -07:00
|
|
|
#include <QGuiApplication>
|
2015-04-13 14:31:36 -07:00
|
|
|
#include <QMouseEvent>
|
|
|
|
#include <QMenu>
|
2016-10-03 23:50:13 -07:00
|
|
|
#include <QScreen>
|
2015-04-04 00:37:02 -07:00
|
|
|
#include "window-projector.hpp"
|
|
|
|
#include "display-helpers.hpp"
|
|
|
|
#include "qt-wrappers.hpp"
|
|
|
|
#include "platform.hpp"
|
2015-04-13 14:31:36 -07:00
|
|
|
#include "obs-app.hpp"
|
2015-04-04 00:37:02 -07:00
|
|
|
|
2017-03-01 20:08:49 -08:00
|
|
|
OBSProjector::OBSProjector(QWidget *widget, obs_source_t *source_, bool window)
|
2015-04-04 00:37:02 -07:00
|
|
|
: OBSQTDisplay (widget,
|
2017-03-01 20:08:49 -08:00
|
|
|
Qt::Window),
|
2015-04-04 00:37:02 -07:00
|
|
|
source (source_),
|
|
|
|
removedSignal (obs_source_get_signal_handler(source),
|
2016-04-25 14:37:20 -07:00
|
|
|
"remove", OBSSourceRemoved, this)
|
2015-04-04 00:37:02 -07:00
|
|
|
{
|
2017-03-01 20:08:49 -08:00
|
|
|
if (!window) {
|
|
|
|
setWindowFlags(Qt::FramelessWindowHint |
|
|
|
|
Qt::X11BypassWindowManagerHint);
|
|
|
|
}
|
|
|
|
|
2015-04-04 00:37:02 -07:00
|
|
|
setAttribute(Qt::WA_DeleteOnClose, true);
|
2014-11-01 13:48:58 -07:00
|
|
|
|
2017-01-25 12:46:41 -08:00
|
|
|
//disable application quit when last window closed
|
|
|
|
setAttribute(Qt::WA_QuitOnClose, false);
|
|
|
|
|
2014-11-01 13:48:58 -07:00
|
|
|
installEventFilter(CreateShortcutFilter());
|
2015-08-02 00:25:08 -07:00
|
|
|
|
|
|
|
auto addDrawCallback = [this] ()
|
|
|
|
{
|
|
|
|
obs_display_add_draw_callback(GetDisplay(), OBSRender, this);
|
|
|
|
obs_display_set_background_color(GetDisplay(), 0x000000);
|
|
|
|
};
|
|
|
|
|
|
|
|
connect(this, &OBSQTDisplay::DisplayCreated, addDrawCallback);
|
2015-11-16 09:08:55 -08:00
|
|
|
|
2016-06-27 14:47:42 -07:00
|
|
|
bool hideCursor = config_get_bool(GetGlobalConfig(),
|
|
|
|
"BasicWindow", "HideProjectorCursor");
|
2017-03-01 20:08:49 -08:00
|
|
|
if (hideCursor && !window) {
|
2016-06-27 14:47:42 -07:00
|
|
|
QPixmap empty(16, 16);
|
|
|
|
empty.fill(Qt::transparent);
|
|
|
|
setCursor(QCursor(empty));
|
|
|
|
}
|
|
|
|
|
2015-11-16 09:08:55 -08:00
|
|
|
App()->IncrementSleepInhibition();
|
2017-03-01 20:08:49 -08:00
|
|
|
resize(480, 270);
|
2015-04-04 00:37:02 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
OBSProjector::~OBSProjector()
|
|
|
|
{
|
|
|
|
if (source)
|
|
|
|
obs_source_dec_showing(source);
|
2015-11-16 09:08:55 -08:00
|
|
|
App()->DecrementSleepInhibition();
|
2015-04-04 00:37:02 -07:00
|
|
|
}
|
|
|
|
|
2017-03-01 20:08:49 -08:00
|
|
|
void OBSProjector::Init(int monitor, bool window, QString title)
|
2015-04-04 00:37:02 -07:00
|
|
|
{
|
2016-10-03 23:50:13 -07:00
|
|
|
QScreen *screen = QGuiApplication::screens()[monitor];
|
2016-12-29 07:21:53 -08:00
|
|
|
|
2017-03-01 20:08:49 -08:00
|
|
|
if (!window)
|
|
|
|
setGeometry(screen->geometry());
|
2015-04-04 00:37:02 -07:00
|
|
|
|
2016-08-21 16:11:32 -07:00
|
|
|
bool alwaysOnTop = config_get_bool(GetGlobalConfig(),
|
|
|
|
"BasicWindow", "ProjectorAlwaysOnTop");
|
2017-03-01 20:08:49 -08:00
|
|
|
if (alwaysOnTop && !window)
|
2016-08-21 16:11:32 -07:00
|
|
|
SetAlwaysOnTop(this, true);
|
|
|
|
|
2017-03-01 20:08:49 -08:00
|
|
|
if (window)
|
|
|
|
setWindowTitle(title);
|
|
|
|
|
2015-04-04 00:37:02 -07:00
|
|
|
show();
|
|
|
|
|
|
|
|
if (source)
|
|
|
|
obs_source_inc_showing(source);
|
|
|
|
|
2017-03-01 20:08:49 -08:00
|
|
|
if (!window) {
|
|
|
|
QAction *action = new QAction(this);
|
|
|
|
action->setShortcut(Qt::Key_Escape);
|
|
|
|
addAction(action);
|
|
|
|
connect(action, SIGNAL(triggered()), this,
|
|
|
|
SLOT(EscapeTriggered()));
|
|
|
|
}
|
2016-12-29 07:21:53 -08:00
|
|
|
|
|
|
|
savedMonitor = monitor;
|
2017-03-01 20:08:49 -08:00
|
|
|
isWindow = window;
|
2015-04-04 00:37:02 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
void OBSProjector::OBSRender(void *data, uint32_t cx, uint32_t cy)
|
|
|
|
{
|
|
|
|
OBSProjector *window = reinterpret_cast<OBSProjector*>(data);
|
|
|
|
|
|
|
|
uint32_t targetCX;
|
|
|
|
uint32_t targetCY;
|
|
|
|
int x, y;
|
|
|
|
int newCX, newCY;
|
|
|
|
float scale;
|
|
|
|
|
|
|
|
if (window->source) {
|
|
|
|
targetCX = std::max(obs_source_get_width(window->source), 1u);
|
|
|
|
targetCY = std::max(obs_source_get_height(window->source), 1u);
|
|
|
|
} else {
|
|
|
|
struct obs_video_info ovi;
|
|
|
|
obs_get_video_info(&ovi);
|
|
|
|
targetCX = ovi.base_width;
|
|
|
|
targetCY = ovi.base_height;
|
|
|
|
}
|
|
|
|
|
|
|
|
GetScaleAndCenterPos(targetCX, targetCY, cx, cy, x, y, scale);
|
|
|
|
|
|
|
|
newCX = int(scale * float(targetCX));
|
|
|
|
newCY = int(scale * float(targetCY));
|
|
|
|
|
|
|
|
gs_viewport_push();
|
|
|
|
gs_projection_push();
|
|
|
|
gs_ortho(0.0f, float(targetCX), 0.0f, float(targetCY), -100.0f, 100.0f);
|
|
|
|
gs_set_viewport(x, y, newCX, newCY);
|
|
|
|
|
|
|
|
if (window->source)
|
|
|
|
obs_source_video_render(window->source);
|
|
|
|
else
|
|
|
|
obs_render_main_view();
|
|
|
|
|
|
|
|
gs_projection_pop();
|
|
|
|
gs_viewport_pop();
|
|
|
|
}
|
|
|
|
|
|
|
|
void OBSProjector::OBSSourceRemoved(void *data, calldata_t *params)
|
|
|
|
{
|
|
|
|
OBSProjector *window = reinterpret_cast<OBSProjector*>(data);
|
2016-12-29 07:21:53 -08:00
|
|
|
|
2015-04-04 00:37:02 -07:00
|
|
|
window->deleteLater();
|
|
|
|
|
|
|
|
UNUSED_PARAMETER(params);
|
|
|
|
}
|
|
|
|
|
2015-04-13 14:31:36 -07:00
|
|
|
void OBSProjector::mousePressEvent(QMouseEvent *event)
|
|
|
|
{
|
|
|
|
OBSQTDisplay::mousePressEvent(event);
|
|
|
|
|
|
|
|
if (event->button() == Qt::RightButton) {
|
|
|
|
QMenu popup(this);
|
|
|
|
popup.addAction(QTStr("Close"), this, SLOT(EscapeTriggered()));
|
|
|
|
popup.exec(QCursor::pos());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-04 00:37:02 -07:00
|
|
|
void OBSProjector::EscapeTriggered()
|
|
|
|
{
|
2017-03-01 20:08:49 -08:00
|
|
|
if (!isWindow) {
|
|
|
|
OBSBasic *main =
|
|
|
|
reinterpret_cast<OBSBasic*>(App()->GetMainWindow());
|
|
|
|
|
|
|
|
main->RemoveSavedProjectors(savedMonitor);
|
|
|
|
}
|
2016-12-29 07:21:53 -08:00
|
|
|
|
2015-04-04 00:37:02 -07:00
|
|
|
deleteLater();
|
|
|
|
}
|