diff --git a/src/wsi/wsi_monitor.h b/src/wsi/wsi_monitor.h new file mode 100644 index 000000000..c7e33578e --- /dev/null +++ b/src/wsi/wsi_monitor.h @@ -0,0 +1,127 @@ +#pragma once + +#include + +#include +#include + +namespace dxvk::wsi { + + /** + * \brief Rational number. Eg. 2/3 + */ + struct WsiRational { + uint32_t numerator; + uint32_t denominator; + }; + + /** + * \brief Display mode + */ + struct WsiMode { + uint32_t width; + uint32_t height; + WsiRational refreshRate; + uint32_t bitsPerPixel; + bool interlaced; + }; + + /** + * \brief Default monitor + * + * \returns The monitor of given index + */ + HMONITOR getDefaultMonitor(); + + /** + * \brief Enumerators monitors on the system + * + * \returns The monitor of given index + */ + HMONITOR enumMonitors(uint32_t index); + + /** + * \brief Get the GDI name of a HMONITOR + * + * Get the GDI Device Name of a HMONITOR to + * return to the end user. + * + * This typically looks like \.\\DISPLAY1 + * and has a maximum length of 32 chars. + * + * \param [in] hMonitor The monitor + * \param [out] Name The GDI display name + * \returns \c true on success, \c false if an error occured + */ + bool getDisplayName( + HMONITOR hMonitor, + WCHAR (&Name)[32]); + + /** + * \brief Get the encompassing coords of a monitor + */ + bool getDesktopCoordinates( + HMONITOR hMonitor, + RECT* pRect); + + /** + * \brief Get the nth display mode + * + * \param [in] hMonitor The monitor + * \param [in] modeNumber The nth mode + * \param [out] pMode The resultant mode + * \returns \c true on success, \c false if the mode could not be found + */ + bool getDisplayMode( + HMONITOR hMonitor, + uint32_t modeNumber, + WsiMode* pMode); + + /** + * \brief Get the current display mode + * + * This is the display mode right now. + * + * \param [in] hMonitor The monitor + * \param [out] pMode The resultant mode + * \returns \c true on success, \c false on failure + */ + bool getCurrentDisplayMode( + HMONITOR hMonitor, + WsiMode* pMode); + + /** + * \brief Get the current display mode + * + * This is the display mode of the user's + * default desktop. + * + * \param [in] hMonitor The monitor + * \param [out] pMode The resultant mode + * \returns \c true on success, \c false on failure + */ + bool getDesktopDisplayMode( + HMONITOR hMonitor, + WsiMode* pMode); + + /** + * \brief Get the size of a monitor + * + * Helper function to grab the size of a monitor + * using getDesktopCoordinates to mirror the window code. + */ + inline void getMonitorClientSize( + HMONITOR hMonitor, + UINT* pWidth, + UINT* pHeight) { + RECT rect = { }; + getDesktopCoordinates(hMonitor, &rect); + + if (pWidth) + *pWidth = rect.right - rect.left; + + if (pHeight) + *pHeight = rect.bottom - rect.top; + } + +} diff --git a/src/wsi/wsi_window.h b/src/wsi/wsi_window.h new file mode 100644 index 000000000..7471d50cd --- /dev/null +++ b/src/wsi/wsi_window.h @@ -0,0 +1,135 @@ +#pragma once + +#include + +#include "wsi_monitor.h" + +#include "../vulkan/vulkan_loader.h" + +namespace dxvk::wsi { + + /** + * \brief Impl-dependent state + */ + struct DxvkWindowState { +#ifdef DXVK_WSI_WIN32 + LONG style = 0; + LONG exstyle = 0; + RECT rect = { 0, 0, 0, 0 }; +#endif + }; + + /** + * \brief The size of the window + * + * \param [in] hWindow The window + * \param [out] pWidth The width (optional) + * \param [out] pHeight The height (optional) + */ + void getWindowSize( + HWND hWindow, + uint32_t* pWidth, + uint32_t* pWeight); + + /** + * \brief Resize a window + * + * \param [in] hWindow The window + * \param [in] pState The swapchain's window state + * \param [in] width The new width + * \param [in] height The new height + */ + void resizeWindow( + HWND hWindow, + DxvkWindowState* pState, + uint32_t width, + uint32_t weight); + + /** + * \brief Sets the display mode for a window/monitor + * + * \param [in] hMonitor The monitor + * \param [in] hWindow The window (may be unused on some platforms) + * \param [in] mode The mode + * \returns \c true on success, \c false on failure + */ + bool setWindowMode( + HMONITOR hMonitor, + HWND hWindow, + const WsiMode& mode); + + /** + * \brief Enter fullscreen mode for a window & monitor + * + * \param [in] hMonitor The monitor + * \param [in] hWindow The window (may be unused on some platforms) + * \param [in] pState The swapchain's window state + * \param [in] modeSwitch Whether mode switching is allowed + * \returns \c true on success, \c false on failure + */ + bool enterFullscreenMode( + HMONITOR hMonitor, + HWND hWindow, + DxvkWindowState* pState, + [[maybe_unused]] + bool modeSwitch); + + /** + * \brief Exit fullscreen mode for a window + * + * \param [in] hWindow The window + * \param [in] pState The swapchain's window state + * \returns \c true on success, \c false on failure + */ + bool leaveFullscreenMode( + HWND hWindow, + DxvkWindowState* pState); + + /** + * \brief Restores the display mode if necessary + * + * \returns \c true on success, \c false on failure + */ + bool restoreDisplayMode(); + + /** + * \brief The monitor a window is on + * + * \param [in] hWindow The window + * \returns The monitor the window is on + */ + HMONITOR getWindowMonitor(HWND hWindow); + + /** + * \brief Is a HWND a window? + * + * \param [in] hWindow The window + * \returns Is it a window? + */ + bool isWindow(HWND hWindow); + + /** + * \brief Update a fullscreen window's position/size + * + * \param [in] hMonitor The monitor + * \param [in] hWindow The window + * \param [in] forceTopmost Whether to force the window to become topmost again (D3D9 behaviour) + */ + void updateFullscreenWindow( + HMONITOR hMonitor, + HWND hWindow, + bool forceTopmost); + + /** + * \brief Create a surface for a window + * + * \param [in] hWindow The window + * \param [in] vki The instance + * \param [out] pSurface The surface + */ + VkResult createSurface( + HWND hWindow, + const Rc& vki, + VkSurfaceKHR* pSurface); + +}