d3d9: Implement d3d9_GetAdapterDisplayModeEx().
This commit is contained in:
parent
a1bfd0988f
commit
2c8834dffd
|
@ -197,7 +197,7 @@ static HRESULT WINAPI d3d8_GetAdapterDisplayMode(IDirect3D8 *iface, UINT adapter
|
|||
iface, adapter, mode);
|
||||
|
||||
wined3d_mutex_lock();
|
||||
hr = wined3d_get_adapter_display_mode(d3d8->wined3d, adapter, &wined3d_mode);
|
||||
hr = wined3d_get_adapter_display_mode(d3d8->wined3d, adapter, &wined3d_mode, NULL);
|
||||
wined3d_mutex_unlock();
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
|
|
|
@ -208,7 +208,7 @@ static HRESULT WINAPI d3d9_GetAdapterDisplayMode(IDirect3D9Ex *iface, UINT adapt
|
|||
TRACE("iface %p, adapter %u, mode %p.\n", iface, adapter, mode);
|
||||
|
||||
wined3d_mutex_lock();
|
||||
hr = wined3d_get_adapter_display_mode(d3d9->wined3d, adapter, &wined3d_mode);
|
||||
hr = wined3d_get_adapter_display_mode(d3d9->wined3d, adapter, &wined3d_mode, NULL);
|
||||
wined3d_mutex_unlock();
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
|
@ -494,10 +494,31 @@ static HRESULT WINAPI d3d9_EnumAdapterModesEx(IDirect3D9Ex *iface,
|
|||
static HRESULT WINAPI d3d9_GetAdapterDisplayModeEx(IDirect3D9Ex *iface,
|
||||
UINT adapter, D3DDISPLAYMODEEX *mode, D3DDISPLAYROTATION *rotation)
|
||||
{
|
||||
FIXME("iface %p, adapter %u, mode %p, rotation %p stub!\n",
|
||||
struct d3d9 *d3d9 = impl_from_IDirect3D9Ex(iface);
|
||||
struct wined3d_display_mode wined3d_mode;
|
||||
HRESULT hr;
|
||||
|
||||
TRACE("iface %p, adapter %u, mode %p, rotation %p.\n",
|
||||
iface, adapter, mode, rotation);
|
||||
|
||||
return E_NOTIMPL;
|
||||
if (mode->Size != sizeof(*mode))
|
||||
return D3DERR_INVALIDCALL;
|
||||
|
||||
wined3d_mutex_lock();
|
||||
hr = wined3d_get_adapter_display_mode(d3d9->wined3d, adapter, &wined3d_mode,
|
||||
(enum wined3d_display_rotation *)rotation);
|
||||
wined3d_mutex_unlock();
|
||||
|
||||
if (SUCCEEDED(hr))
|
||||
{
|
||||
mode->Width = wined3d_mode.width;
|
||||
mode->Height = wined3d_mode.height;
|
||||
mode->RefreshRate = wined3d_mode.refresh_rate;
|
||||
mode->Format = d3dformat_from_wined3dformat(wined3d_mode.format_id);
|
||||
mode->ScanLineOrdering = wined3d_mode.scanline_ordering;
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
static HRESULT WINAPI DECLSPEC_HOTPATCH d3d9_CreateDeviceEx(IDirect3D9Ex *iface,
|
||||
|
|
|
@ -327,29 +327,33 @@ static void test_get_adapter_displaymode_ex(void)
|
|||
/*now that orientation has changed start tests for GetAdapterDisplayModeEx: invalid Size*/
|
||||
memset(&mode_ex, 0, sizeof(mode_ex));
|
||||
hr = IDirect3D9Ex_GetAdapterDisplayModeEx(d3d9ex, D3DADAPTER_DEFAULT, &mode_ex, &rotation);
|
||||
todo_wine ok(hr == D3DERR_INVALIDCALL, "GetAdapterDisplayModeEx returned %#x instead of D3DERR_INVALIDCALL\n", hr);
|
||||
ok(hr == D3DERR_INVALIDCALL, "GetAdapterDisplayModeEx returned %#x instead of D3DERR_INVALIDCALL\n", hr);
|
||||
|
||||
mode_ex.Size = sizeof(D3DDISPLAYMODEEX);
|
||||
/* invalid count*/
|
||||
hr = IDirect3D9Ex_GetAdapterDisplayModeEx(d3d9ex, count + 1, &mode_ex, &rotation);
|
||||
todo_wine ok(hr == D3DERR_INVALIDCALL, "GetAdapterDisplayModeEx returned %#x instead of D3DERR_INVALIDCALL\n", hr);
|
||||
ok(hr == D3DERR_INVALIDCALL, "GetAdapterDisplayModeEx returned %#x instead of D3DERR_INVALIDCALL\n", hr);
|
||||
/*valid count and valid Size*/
|
||||
hr = IDirect3D9Ex_GetAdapterDisplayModeEx(d3d9ex, D3DADAPTER_DEFAULT, &mode_ex, &rotation);
|
||||
todo_wine ok(SUCCEEDED(hr), "GetAdapterDisplayModeEx failed, hr %#x.\n", hr);
|
||||
ok(SUCCEEDED(hr), "GetAdapterDisplayModeEx failed, hr %#x.\n", hr);
|
||||
|
||||
/* Compare what GetAdapterDisplayMode returns with what GetAdapterDisplayModeEx returns*/
|
||||
hr = IDirect3D9_GetAdapterDisplayMode(d3d9, D3DADAPTER_DEFAULT, &mode);
|
||||
ok(SUCCEEDED(hr), "GetAdapterDisplayMode failed, hr %#x.\n", hr);
|
||||
|
||||
ok(mode_ex.Size == sizeof(D3DDISPLAYMODEEX), "size is %d\n", mode_ex.Size);
|
||||
todo_wine ok(mode_ex.Width == mode.Width, "width is %d instead of %d\n", mode_ex.Width, mode.Width);
|
||||
todo_wine ok(mode_ex.Height == mode.Height, "height is %d instead of %d\n", mode_ex.Height, mode.Height);
|
||||
todo_wine ok(mode_ex.RefreshRate == mode.RefreshRate, "RefreshRate is %d instead of %d\n", mode_ex.RefreshRate, mode.RefreshRate);
|
||||
todo_wine ok(mode_ex.Format == mode.Format, "format is %x instead of %x\n", mode_ex.Format, mode.Format);
|
||||
/* don't know yet how to test for ScanLineOrdering, just testing that it is set to a value by GetAdapterDisplayModeEx*/
|
||||
todo_wine ok(mode_ex.ScanLineOrdering != 0, "ScanLineOrdering returned 0\n");
|
||||
/* check that orientation is returned correctly by GetAdapterDisplayModeEx and EnumDisplaySettingsEx*/
|
||||
todo_wine ok(S2(U1(startmode)).dmDisplayOrientation == DMDO_180 && rotation == D3DDISPLAYROTATION_180, "rotation is %d instead of %d\n", rotation, S2(U1(startmode)).dmDisplayOrientation);
|
||||
ok(mode_ex.Width == mode.Width, "width is %d instead of %d\n", mode_ex.Width, mode.Width);
|
||||
ok(mode_ex.Height == mode.Height, "height is %d instead of %d\n", mode_ex.Height, mode.Height);
|
||||
ok(mode_ex.RefreshRate == mode.RefreshRate, "RefreshRate is %d instead of %d\n",
|
||||
mode_ex.RefreshRate, mode.RefreshRate);
|
||||
ok(mode_ex.Format == mode.Format, "format is %x instead of %x\n", mode_ex.Format, mode.Format);
|
||||
/* Don't know yet how to test for ScanLineOrdering, just testing that it
|
||||
* is set to a value by GetAdapterDisplayModeEx(). */
|
||||
ok(mode_ex.ScanLineOrdering != 0, "ScanLineOrdering returned 0\n");
|
||||
/* Check that orientation is returned correctly by GetAdapterDisplayModeEx
|
||||
* and EnumDisplaySettingsEx(). */
|
||||
todo_wine ok(S2(U1(startmode)).dmDisplayOrientation == DMDO_180 && rotation == D3DDISPLAYROTATION_180,
|
||||
"rotation is %d instead of %d\n", rotation, S2(U1(startmode)).dmDisplayOrientation);
|
||||
|
||||
trace("GetAdapterDisplayModeEx returned Width = %d,Height = %d, RefreshRate = %d, Format = %x, ScanLineOrdering = %x, rotation = %d\n",
|
||||
mode_ex.Width, mode_ex.Height, mode_ex.RefreshRate, mode_ex.Format, mode_ex.ScanLineOrdering, rotation);
|
||||
|
@ -359,15 +363,17 @@ static void test_get_adapter_displaymode_ex(void)
|
|||
mode_ex.Size = sizeof(D3DDISPLAYMODEEX);
|
||||
|
||||
hr = IDirect3D9Ex_GetAdapterDisplayModeEx(d3d9ex, D3DADAPTER_DEFAULT, &mode_ex, NULL);
|
||||
todo_wine ok(SUCCEEDED(hr), "GetAdapterDisplayModeEx failed, hr %#x.\n", hr);
|
||||
ok(SUCCEEDED(hr), "GetAdapterDisplayModeEx failed, hr %#x.\n", hr);
|
||||
|
||||
ok(mode_ex.Size == sizeof(D3DDISPLAYMODEEX), "size is %d\n", mode_ex.Size);
|
||||
todo_wine ok(mode_ex.Width == mode.Width, "width is %d instead of %d\n", mode_ex.Width, mode.Width);
|
||||
todo_wine ok(mode_ex.Height == mode.Height, "height is %d instead of %d\n", mode_ex.Height, mode.Height);
|
||||
todo_wine ok(mode_ex.RefreshRate == mode.RefreshRate, "RefreshRate is %d instead of %d\n", mode_ex.RefreshRate, mode.RefreshRate);
|
||||
todo_wine ok(mode_ex.Format == mode.Format, "format is %x instead of %x\n", mode_ex.Format, mode.Format);
|
||||
/* don't know yet how to test for ScanLineOrdering, just testing that it is set to a value by GetAdapterDisplayModeEx*/
|
||||
todo_wine ok(mode_ex.ScanLineOrdering != 0, "ScanLineOrdering returned 0\n");
|
||||
ok(mode_ex.Width == mode.Width, "width is %d instead of %d\n", mode_ex.Width, mode.Width);
|
||||
ok(mode_ex.Height == mode.Height, "height is %d instead of %d\n", mode_ex.Height, mode.Height);
|
||||
ok(mode_ex.RefreshRate == mode.RefreshRate, "RefreshRate is %d instead of %d\n",
|
||||
mode_ex.RefreshRate, mode.RefreshRate);
|
||||
ok(mode_ex.Format == mode.Format, "format is %x instead of %x\n", mode_ex.Format, mode.Format);
|
||||
/* Don't know yet how to test for ScanLineOrdering, just testing that it
|
||||
* is set to a value by GetAdapterDisplayModeEx(). */
|
||||
ok(mode_ex.ScanLineOrdering != 0, "ScanLineOrdering returned 0\n");
|
||||
|
||||
/* return to the default mode */
|
||||
pChangeDisplaySettingsExA(NULL, NULL, NULL, 0, NULL);
|
||||
|
|
|
@ -670,7 +670,7 @@ static HRESULT ddraw_create_swapchain(struct ddraw *ddraw, HWND window, BOOL win
|
|||
struct wined3d_display_mode mode;
|
||||
HRESULT hr = WINED3D_OK;
|
||||
|
||||
if (FAILED(hr = wined3d_get_adapter_display_mode(ddraw->wined3d, WINED3DADAPTER_DEFAULT, &mode)))
|
||||
if (FAILED(hr = wined3d_get_adapter_display_mode(ddraw->wined3d, WINED3DADAPTER_DEFAULT, &mode, NULL)))
|
||||
{
|
||||
ERR("Failed to get display mode.\n");
|
||||
return hr;
|
||||
|
@ -886,7 +886,7 @@ static HRESULT WINAPI ddraw7_SetCooperativeLevel(IDirectDraw7 *iface, HWND hwnd,
|
|||
{
|
||||
struct wined3d_display_mode display_mode;
|
||||
|
||||
wined3d_get_adapter_display_mode(This->wined3d, WINED3DADAPTER_DEFAULT, &display_mode);
|
||||
wined3d_get_adapter_display_mode(This->wined3d, WINED3DADAPTER_DEFAULT, &display_mode, NULL);
|
||||
wined3d_device_setup_fullscreen_window(This->wined3d_device, hwnd,
|
||||
display_mode.width, display_mode.height);
|
||||
}
|
||||
|
@ -1422,7 +1422,7 @@ static HRESULT WINAPI ddraw7_GetDisplayMode(IDirectDraw7 *iface, DDSURFACEDESC2
|
|||
return DDERR_INVALIDPARAMS;
|
||||
}
|
||||
|
||||
if (FAILED(hr = wined3d_get_adapter_display_mode(ddraw->wined3d, WINED3DADAPTER_DEFAULT, &mode)))
|
||||
if (FAILED(hr = wined3d_get_adapter_display_mode(ddraw->wined3d, WINED3DADAPTER_DEFAULT, &mode, NULL)))
|
||||
{
|
||||
ERR("Failed to get display mode, hr %#x.\n", hr);
|
||||
wined3d_mutex_unlock();
|
||||
|
@ -1514,7 +1514,7 @@ static HRESULT WINAPI ddraw7_GetFourCCCodes(IDirectDraw7 *iface, DWORD *NumCodes
|
|||
|
||||
TRACE("iface %p, codes_count %p, codes %p.\n", iface, NumCodes, Codes);
|
||||
|
||||
if (FAILED(hr = wined3d_get_adapter_display_mode(ddraw->wined3d, WINED3DADAPTER_DEFAULT, &mode)))
|
||||
if (FAILED(hr = wined3d_get_adapter_display_mode(ddraw->wined3d, WINED3DADAPTER_DEFAULT, &mode, NULL)))
|
||||
{
|
||||
ERR("Failed to get display mode, hr %#x.\n", hr);
|
||||
return hr;
|
||||
|
@ -1961,7 +1961,7 @@ static HRESULT WINAPI ddraw7_GetScanLine(IDirectDraw7 *iface, DWORD *Scanline)
|
|||
}
|
||||
|
||||
wined3d_mutex_lock();
|
||||
hr = wined3d_get_adapter_display_mode(ddraw->wined3d, WINED3DADAPTER_DEFAULT, &mode);
|
||||
hr = wined3d_get_adapter_display_mode(ddraw->wined3d, WINED3DADAPTER_DEFAULT, &mode, NULL);
|
||||
wined3d_mutex_unlock();
|
||||
if (FAILED(hr))
|
||||
{
|
||||
|
@ -2893,7 +2893,7 @@ static HRESULT CreateSurface(struct ddraw *ddraw, DDSURFACEDESC2 *DDSD,
|
|||
desc2.u4.ddpfPixelFormat.dwSize=sizeof(DDPIXELFORMAT); /* Just to be sure */
|
||||
|
||||
/* Get the video mode from WineD3D - we will need it */
|
||||
if (FAILED(hr = wined3d_get_adapter_display_mode(ddraw->wined3d, WINED3DADAPTER_DEFAULT, &mode)))
|
||||
if (FAILED(hr = wined3d_get_adapter_display_mode(ddraw->wined3d, WINED3DADAPTER_DEFAULT, &mode, NULL)))
|
||||
{
|
||||
ERR("Failed to get display mode, hr %#x.\n", hr);
|
||||
|
||||
|
@ -4643,7 +4643,7 @@ static HRESULT WINAPI d3d7_EnumZBufferFormats(IDirect3D7 *iface, REFCLSID device
|
|||
* not like that we'll have to find some workaround, like iterating over
|
||||
* all imaginable formats and collecting all the depth stencil formats we
|
||||
* can get. */
|
||||
if (FAILED(hr = wined3d_get_adapter_display_mode(ddraw->wined3d, WINED3DADAPTER_DEFAULT, &mode)))
|
||||
if (FAILED(hr = wined3d_get_adapter_display_mode(ddraw->wined3d, WINED3DADAPTER_DEFAULT, &mode, NULL)))
|
||||
{
|
||||
ERR("Failed to get display mode, hr %#x.\n", hr);
|
||||
wined3d_mutex_unlock();
|
||||
|
|
|
@ -1068,7 +1068,7 @@ static HRESULT d3d_device7_EnumTextureFormats(IDirect3DDevice7 *iface,
|
|||
wined3d_mutex_lock();
|
||||
|
||||
memset(&mode, 0, sizeof(mode));
|
||||
if (FAILED(hr = wined3d_get_adapter_display_mode(device->ddraw->wined3d, WINED3DADAPTER_DEFAULT, &mode)))
|
||||
if (FAILED(hr = wined3d_get_adapter_display_mode(device->ddraw->wined3d, WINED3DADAPTER_DEFAULT, &mode, NULL)))
|
||||
{
|
||||
wined3d_mutex_unlock();
|
||||
WARN("Cannot get the current adapter format\n");
|
||||
|
@ -1198,7 +1198,7 @@ static HRESULT WINAPI d3d_device2_EnumTextureFormats(IDirect3DDevice2 *iface,
|
|||
wined3d_mutex_lock();
|
||||
|
||||
memset(&mode, 0, sizeof(mode));
|
||||
if (FAILED(hr = wined3d_get_adapter_display_mode(device->ddraw->wined3d, WINED3DADAPTER_DEFAULT, &mode)))
|
||||
if (FAILED(hr = wined3d_get_adapter_display_mode(device->ddraw->wined3d, WINED3DADAPTER_DEFAULT, &mode, NULL)))
|
||||
{
|
||||
wined3d_mutex_unlock();
|
||||
WARN("Cannot get the current adapter format\n");
|
||||
|
|
|
@ -4811,7 +4811,7 @@ HRESULT CDECL wined3d_device_set_cursor_properties(struct wined3d_device *device
|
|||
return WINED3DERR_INVALIDCALL;
|
||||
}
|
||||
|
||||
if (FAILED(hr = wined3d_get_adapter_display_mode(device->wined3d, device->adapter->ordinal, &mode)))
|
||||
if (FAILED(hr = wined3d_get_adapter_display_mode(device->wined3d, device->adapter->ordinal, &mode, NULL)))
|
||||
{
|
||||
ERR("Failed to get display mode, hr %#x.\n", hr);
|
||||
return WINED3DERR_INVALIDCALL;
|
||||
|
|
|
@ -3024,11 +3024,12 @@ HRESULT CDECL wined3d_enum_adapter_modes(const struct wined3d *wined3d, UINT ada
|
|||
}
|
||||
|
||||
HRESULT CDECL wined3d_get_adapter_display_mode(const struct wined3d *wined3d, UINT adapter_idx,
|
||||
struct wined3d_display_mode *mode)
|
||||
struct wined3d_display_mode *mode, enum wined3d_display_rotation *rotation)
|
||||
{
|
||||
const struct wined3d_adapter *adapter;
|
||||
|
||||
TRACE("wined3d %p, adapter_idx %u, display_mode %p.\n", wined3d, adapter_idx, mode);
|
||||
TRACE("wined3d %p, adapter_idx %u, display_mode %p, rotation %p.\n",
|
||||
wined3d, adapter_idx, mode, rotation);
|
||||
|
||||
if (!mode || adapter_idx >= wined3d->adapter_count)
|
||||
return WINED3DERR_INVALIDCALL;
|
||||
|
@ -3068,6 +3069,29 @@ HRESULT CDECL wined3d_get_adapter_display_mode(const struct wined3d *wined3d, UI
|
|||
mode->scanline_ordering = WINED3D_SCANLINE_ORDERING_INTERLACED;
|
||||
else
|
||||
mode->scanline_ordering = WINED3D_SCANLINE_ORDERING_PROGRESSIVE;
|
||||
|
||||
if (rotation)
|
||||
{
|
||||
switch (DevModeW.u1.s2.dmDisplayOrientation)
|
||||
{
|
||||
case DMDO_DEFAULT:
|
||||
*rotation = WINED3D_DISPLAY_ROTATION_0;
|
||||
break;
|
||||
case DMDO_90:
|
||||
*rotation = WINED3D_DISPLAY_ROTATION_90;
|
||||
break;
|
||||
case DMDO_180:
|
||||
*rotation = WINED3D_DISPLAY_ROTATION_180;
|
||||
break;
|
||||
case DMDO_270:
|
||||
*rotation = WINED3D_DISPLAY_ROTATION_270;
|
||||
break;
|
||||
default:
|
||||
FIXME("Unhandled display rotation %#x.\n", DevModeW.u1.s2.dmDisplayOrientation);
|
||||
*rotation = WINED3D_DISPLAY_ROTATION_UNSPECIFIED;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -3120,7 +3144,7 @@ HRESULT CDECL wined3d_set_adapter_display_mode(struct wined3d *wined3d,
|
|||
}
|
||||
|
||||
/* Only change the mode if necessary. */
|
||||
if (FAILED(hr = wined3d_get_adapter_display_mode(wined3d, adapter_idx, ¤t_mode)))
|
||||
if (FAILED(hr = wined3d_get_adapter_display_mode(wined3d, adapter_idx, ¤t_mode, NULL)))
|
||||
{
|
||||
ERR("Failed to get current display mode, hr %#x.\n", hr);
|
||||
}
|
||||
|
|
|
@ -267,7 +267,8 @@ HRESULT CDECL wined3d_swapchain_get_display_mode(const struct wined3d_swapchain
|
|||
|
||||
TRACE("swapchain %p, mode %p.\n", swapchain, mode);
|
||||
|
||||
hr = wined3d_get_adapter_display_mode(swapchain->device->wined3d, swapchain->device->adapter->ordinal, mode);
|
||||
hr = wined3d_get_adapter_display_mode(swapchain->device->wined3d,
|
||||
swapchain->device->adapter->ordinal, mode, NULL);
|
||||
|
||||
TRACE("Returning w %u, h %u, refresh rate %u, format %s.\n",
|
||||
mode->width, mode->height, mode->refresh_rate, debug_d3dformat(mode->format_id));
|
||||
|
@ -905,7 +906,7 @@ static HRESULT swapchain_init(struct wined3d_swapchain *swapchain, enum wined3d_
|
|||
swapchain->win_handle = window;
|
||||
swapchain->device_window = window;
|
||||
|
||||
wined3d_get_adapter_display_mode(device->wined3d, adapter->ordinal, &mode);
|
||||
wined3d_get_adapter_display_mode(device->wined3d, adapter->ordinal, &mode, NULL);
|
||||
swapchain->orig_width = mode.width;
|
||||
swapchain->orig_height = mode.height;
|
||||
swapchain->orig_fmt = mode.format_id;
|
||||
|
|
|
@ -774,6 +774,15 @@ enum wined3d_scanline_ordering
|
|||
WINED3D_SCANLINE_ORDERING_INTERLACED = 2,
|
||||
};
|
||||
|
||||
enum wined3d_display_rotation
|
||||
{
|
||||
WINED3D_DISPLAY_ROTATION_UNSPECIFIED = 0,
|
||||
WINED3D_DISPLAY_ROTATION_0 = 1,
|
||||
WINED3D_DISPLAY_ROTATION_90 = 2,
|
||||
WINED3D_DISPLAY_ROTATION_180 = 3,
|
||||
WINED3D_DISPLAY_ROTATION_270 = 4,
|
||||
};
|
||||
|
||||
#define WINED3DCOLORWRITEENABLE_RED (1 << 0)
|
||||
#define WINED3DCOLORWRITEENABLE_GREEN (1 << 1)
|
||||
#define WINED3DCOLORWRITEENABLE_BLUE (1 << 2)
|
||||
|
@ -2031,7 +2040,7 @@ HRESULT __cdecl wined3d_enum_adapter_modes(const struct wined3d *wined3d, UINT a
|
|||
enum wined3d_format_id format_id, UINT mode_idx, struct wined3d_display_mode *mode);
|
||||
UINT __cdecl wined3d_get_adapter_count(const struct wined3d *wined3d);
|
||||
HRESULT __cdecl wined3d_get_adapter_display_mode(const struct wined3d *wined3d, UINT adapter_idx,
|
||||
struct wined3d_display_mode *mode);
|
||||
struct wined3d_display_mode *mode, enum wined3d_display_rotation *rotation);
|
||||
HRESULT __cdecl wined3d_get_adapter_identifier(const struct wined3d *wined3d, UINT adapter_idx,
|
||||
DWORD flags, struct wined3d_adapter_identifier *identifier);
|
||||
UINT __cdecl wined3d_get_adapter_mode_count(const struct wined3d *wined3d,
|
||||
|
|
Loading…
Reference in New Issue