0
0
mirror of https://github.com/obsproject/obs-studio.git synced 2024-09-20 13:08:50 +02:00
obs-studio/UI/window-projector.cpp
Warren Turkal f3eb8aacfe UI: Use Qt lib for screen info instead of x11 libs
All of the monitor discovery logic can be implemented with Qt. This
change removes all the x11 implementations in favor of Qt and removes a
fair amount of platform specific code.
2016-10-03 23:50:13 -07:00

134 lines
3.2 KiB
C++

#include <QAction>
#include <QGuiApplication>
#include <QMouseEvent>
#include <QMenu>
#include <QScreen>
#include "window-projector.hpp"
#include "display-helpers.hpp"
#include "qt-wrappers.hpp"
#include "platform.hpp"
#include "obs-app.hpp"
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();
}
OBSProjector::~OBSProjector()
{
if (source)
obs_source_dec_showing(source);
App()->DecrementSleepInhibition();
}
void OBSProjector::Init(int monitor)
{
QScreen *screen = QGuiApplication::screens()[monitor];
setGeometry(screen->availableGeometry());
bool alwaysOnTop = config_get_bool(GetGlobalConfig(),
"BasicWindow", "ProjectorAlwaysOnTop");
if (alwaysOnTop)
SetAlwaysOnTop(this, true);
show();
if (source)
obs_source_inc_showing(source);
QAction *action = new QAction(this);
action->setShortcut(Qt::Key_Escape);
addAction(action);
connect(action, SIGNAL(triggered()), this, SLOT(EscapeTriggered()));
}
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);
window->deleteLater();
UNUSED_PARAMETER(params);
}
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());
}
}
void OBSProjector::EscapeTriggered()
{
deleteLater();
}