qt-display.cpp 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. #include "qt-display.hpp"
  2. #include "qt-wrappers.hpp"
  3. #include "display-helpers.hpp"
  4. #include <QWindow>
  5. #include <QScreen>
  6. #include <QResizeEvent>
  7. #include <QShowEvent>
  8. static inline long long color_to_int(QColor color)
  9. {
  10. auto shift = [&](unsigned val, int shift) {
  11. return ((val & 0xff) << shift);
  12. };
  13. return shift(color.red(), 0) | shift(color.green(), 8) |
  14. shift(color.blue(), 16) | shift(color.alpha(), 24);
  15. }
  16. static inline QColor rgba_to_color(uint32_t rgba)
  17. {
  18. return QColor::fromRgb(rgba & 0xFF, (rgba >> 8) & 0xFF,
  19. (rgba >> 16) & 0xFF, (rgba >> 24) & 0xFF);
  20. }
  21. OBSQTDisplay::OBSQTDisplay(QWidget *parent, Qt::WindowFlags flags)
  22. : QWidget(parent, flags)
  23. {
  24. setAttribute(Qt::WA_PaintOnScreen);
  25. setAttribute(Qt::WA_StaticContents);
  26. setAttribute(Qt::WA_NoSystemBackground);
  27. setAttribute(Qt::WA_OpaquePaintEvent);
  28. setAttribute(Qt::WA_DontCreateNativeAncestors);
  29. setAttribute(Qt::WA_NativeWindow);
  30. auto windowVisible = [this](bool visible) {
  31. if (!visible)
  32. return;
  33. if (!display) {
  34. CreateDisplay();
  35. } else {
  36. QSize size = GetPixelSize(this);
  37. obs_display_resize(display, size.width(),
  38. size.height());
  39. }
  40. };
  41. auto sizeChanged = [this](QScreen *) {
  42. CreateDisplay();
  43. QSize size = GetPixelSize(this);
  44. obs_display_resize(display, size.width(), size.height());
  45. };
  46. connect(windowHandle(), &QWindow::visibleChanged, windowVisible);
  47. connect(windowHandle(), &QWindow::screenChanged, sizeChanged);
  48. }
  49. QColor OBSQTDisplay::GetDisplayBackgroundColor() const
  50. {
  51. return rgba_to_color(backgroundColor);
  52. }
  53. void OBSQTDisplay::SetDisplayBackgroundColor(const QColor &color)
  54. {
  55. uint32_t newBackgroundColor = (uint32_t)color_to_int(color);
  56. if (newBackgroundColor != backgroundColor) {
  57. backgroundColor = newBackgroundColor;
  58. UpdateDisplayBackgroundColor();
  59. }
  60. }
  61. void OBSQTDisplay::UpdateDisplayBackgroundColor()
  62. {
  63. obs_display_set_background_color(display, backgroundColor);
  64. }
  65. void OBSQTDisplay::CreateDisplay()
  66. {
  67. if (display || !windowHandle()->isExposed())
  68. return;
  69. QSize size = GetPixelSize(this);
  70. gs_init_data info = {};
  71. info.cx = size.width();
  72. info.cy = size.height();
  73. info.format = GS_RGBA;
  74. info.zsformat = GS_ZS_NONE;
  75. QTToGSWindow(winId(), info.window);
  76. display = obs_display_create(&info, backgroundColor);
  77. emit DisplayCreated(this);
  78. }
  79. void OBSQTDisplay::resizeEvent(QResizeEvent *event)
  80. {
  81. QWidget::resizeEvent(event);
  82. CreateDisplay();
  83. if (isVisible() && display) {
  84. QSize size = GetPixelSize(this);
  85. obs_display_resize(display, size.width(), size.height());
  86. }
  87. emit DisplayResized();
  88. }
  89. void OBSQTDisplay::paintEvent(QPaintEvent *event)
  90. {
  91. CreateDisplay();
  92. QWidget::paintEvent(event);
  93. }
  94. QPaintEngine *OBSQTDisplay::paintEngine() const
  95. {
  96. return nullptr;
  97. }