Skip to content

Commit

Permalink
Further optimize clipboard access
Browse files Browse the repository at this point in the history
  • Loading branch information
Kaldaien committed Aug 26, 2024
1 parent dc0fbce commit f0afd58
Show file tree
Hide file tree
Showing 3 changed files with 136 additions and 97 deletions.
12 changes: 11 additions & 1 deletion src/SKIV.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3061,7 +3061,17 @@ wWinMain ( _In_ HINSTANCE hInstance,
// duplicate the same processing we're already doing in viewer.cpp
if (hotkeyCtrlV && ! ImGui::IsAnyItemActive ( )) // && ! ImGui::IsAnyItemFocused ( )
{
if (OpenClipboard (SKIF_ImGui_hWnd))
bool clipboard_open = false;

for (UINT i = 0 ; i < 5 ; ++i)
{
clipboard_open = OpenClipboard (SKIF_ImGui_hWnd);

if (! clipboard_open)
Sleep (2);
}

if (clipboard_open)
{
ClipboardData cbd = ClipboardData_None;

Expand Down
207 changes: 113 additions & 94 deletions src/utility/image.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1017,32 +1017,43 @@ SKIV_PNG_CopyToClipboard (const DirectX::Image& image, const void *pData, size_t
std::ignore = image;
std::ignore = data_size; // It's a string, we can compute the size trivially

if (OpenClipboard (SKIF_ImGui_hWnd))
{
int clpSize = sizeof (DROPFILES);
int clpSize = sizeof (DROPFILES);

clpSize += sizeof (wchar_t) * static_cast <int> (wcslen ((wchar_t *)pData) + 1);
clpSize += sizeof (wchar_t);

HDROP hdrop =
(HDROP)GlobalAlloc (GHND, clpSize);

clpSize += sizeof (wchar_t) * static_cast <int> (wcslen ((wchar_t *)pData) + 1);
clpSize += sizeof (wchar_t);
DROPFILES* df =
(DROPFILES *)GlobalLock (hdrop);

HDROP hdrop =
(HDROP)GlobalAlloc (GHND, clpSize);
df->pFiles = sizeof (DROPFILES);
df->fWide = TRUE;

DROPFILES* df =
(DROPFILES *)GlobalLock (hdrop);
wcscpy ((wchar_t*)&df [1], (const wchar_t *)pData);

df->pFiles = sizeof (DROPFILES);
df->fWide = TRUE;
bool clipboard_open = false;
for (UINT i = 0 ; i < 5 ; ++i)
{
clipboard_open = OpenClipboard (SKIF_ImGui_hWnd);

wcscpy ((wchar_t*)&df [1], (const wchar_t *)pData);
if (! clipboard_open)
Sleep (2);
}

GlobalUnlock (hdrop);
if (clipboard_open)
{
EmptyClipboard ();
SetClipboardData (CF_HDROP, hdrop);
CloseClipboard ();
GlobalUnlock (hdrop);

return true;
}

GlobalUnlock (hdrop);

return false;
}

Expand Down Expand Up @@ -1132,99 +1143,107 @@ using namespace DirectX;
PLOG_INFO << "SKIV_Image_TonemapToSDR ( ): FAILED!";
}

if (OpenClipboard (SKIF_ImGui_hWnd))
const int
_bpc =
(int)(DirectX::BitsPerPixel (pImage->format)),
_width =
(int)( pImage->width),
_height =
(int)( pImage->height);

DirectX::ScratchImage swizzled_sdr;
// Swizzle the image and handle gamma if necessary
if (pImage->format != DXGI_FORMAT_B8G8R8X8_UNORM_SRGB)
{
const int
_bpc =
(int)(DirectX::BitsPerPixel (pImage->format)),
_width =
(int)( pImage->width),
_height =
(int)( pImage->height);

DirectX::ScratchImage swizzled_sdr;
// Swizzle the image and handle gamma if necessary
if (pImage->format != DXGI_FORMAT_B8G8R8X8_UNORM_SRGB)
if (SUCCEEDED (DirectX::Convert (*pImage, DXGI_FORMAT_B8G8R8X8_UNORM_SRGB, DirectX::TEX_FILTER_DEFAULT, 0.0f, swizzled_sdr)))
{
if (SUCCEEDED (DirectX::Convert (*pImage, DXGI_FORMAT_B8G8R8X8_UNORM_SRGB, DirectX::TEX_FILTER_DEFAULT, 0.0f, swizzled_sdr)))
{
pImage = swizzled_sdr.GetImage (0,0,0);
}
pImage = swizzled_sdr.GetImage (0,0,0);
}
////SK_ReleaseAssert (pImage->format == DXGI_FORMAT_B8G8R8X8_UNORM ||
//// pImage->format == DXGI_FORMAT_B8G8R8A8_UNORM ||
//// pImage->format == DXGI_FORMAT_B8G8R8X8_UNORM_SRGB);

HBITMAP hBitmapCopy =
CreateBitmap (
_width, _height, 1,
_bpc, pImage->pixels
);

BITMAPINFOHEADER
bmh = { };
bmh.biSize = sizeof (BITMAPINFOHEADER);
bmh.biWidth = _width;
bmh.biHeight = -_height;
bmh.biPlanes = 1;
bmh.biBitCount = (WORD)_bpc;
bmh.biCompression = BI_RGB;
bmh.biXPelsPerMeter = 10;
bmh.biYPelsPerMeter = 10;

BITMAPINFO
bmi = { };
bmi.bmiHeader = bmh;

HDC hdcDIB =
CreateCompatibleDC (GetDC (nullptr));

void* bitplane = nullptr;

HBITMAP
hBitmap =
CreateDIBSection ( hdcDIB, &bmi, DIB_RGB_COLORS,
&bitplane, nullptr, 0 );
memcpy ( bitplane,
pImage->pixels,
static_cast <size_t> (_bpc / 8) *
static_cast <size_t> (_width ) *
static_cast <size_t> (_height )
);

HDC hdcSrc = CreateCompatibleDC (GetDC (nullptr));
HDC hdcDst = CreateCompatibleDC (GetDC (nullptr));

if ( hBitmap != nullptr &&
hBitmapCopy != nullptr )
{
auto hbmpSrc = (HBITMAP)SelectObject (hdcSrc, hBitmap);
auto hbmpDst = (HBITMAP)SelectObject (hdcDst, hBitmapCopy);
}
////SK_ReleaseAssert (pImage->format == DXGI_FORMAT_B8G8R8X8_UNORM ||
//// pImage->format == DXGI_FORMAT_B8G8R8A8_UNORM ||
//// pImage->format == DXGI_FORMAT_B8G8R8X8_UNORM_SRGB);

HBITMAP hBitmapCopy =
CreateBitmap (
_width, _height, 1,
_bpc, pImage->pixels
);

BITMAPINFOHEADER
bmh = { };
bmh.biSize = sizeof (BITMAPINFOHEADER);
bmh.biWidth = _width;
bmh.biHeight = -_height;
bmh.biPlanes = 1;
bmh.biBitCount = (WORD)_bpc;
bmh.biCompression = BI_RGB;
bmh.biXPelsPerMeter = 10;
bmh.biYPelsPerMeter = 10;

BITMAPINFO
bmi = { };
bmi.bmiHeader = bmh;

HDC hdcDIB =
CreateCompatibleDC (GetDC (nullptr));

void* bitplane = nullptr;

HBITMAP
hBitmap =
CreateDIBSection ( hdcDIB, &bmi, DIB_RGB_COLORS,
&bitplane, nullptr, 0 );
memcpy ( bitplane,
pImage->pixels,
static_cast <size_t> (_bpc / 8) *
static_cast <size_t> (_width ) *
static_cast <size_t> (_height )
);

HDC hdcSrc = CreateCompatibleDC (GetDC (nullptr));
HDC hdcDst = CreateCompatibleDC (GetDC (nullptr));

if ( hBitmap != nullptr &&
hBitmapCopy != nullptr )
{
auto hbmpSrc = (HBITMAP)SelectObject (hdcSrc, hBitmap);
auto hbmpDst = (HBITMAP)SelectObject (hdcDst, hBitmapCopy);

BitBlt (hdcDst, 0, 0, _width,
_height, hdcSrc, 0, 0, SRCCOPY);
BitBlt (hdcDst, 0, 0, _width,
_height, hdcSrc, 0, 0, SRCCOPY);

SelectObject (hdcSrc, hbmpSrc);
SelectObject (hdcDst, hbmpDst);
SelectObject (hdcSrc, hbmpSrc);
SelectObject (hdcDst, hbmpDst);

bool clipboard_open = false;
for (UINT i = 0 ; i < 5 ; ++i)
{
clipboard_open = OpenClipboard (SKIF_ImGui_hWnd);

if (! clipboard_open)
Sleep (2);
}

if (clipboard_open)
{
EmptyClipboard ();
SetClipboardData (CF_BITMAP, hBitmapCopy);
CloseClipboard ();
}
}

CloseClipboard ();

DeleteDC (hdcSrc);
DeleteDC (hdcDst);
DeleteDC (hdcDIB);
DeleteDC (hdcSrc);
DeleteDC (hdcDst);
DeleteDC (hdcDIB);

if ( hBitmap != nullptr &&
hBitmapCopy != nullptr )
{
DeleteBitmap (hBitmap);
DeleteBitmap (hBitmapCopy);
if ( hBitmap != nullptr &&
hBitmapCopy != nullptr )
{
DeleteBitmap (hBitmap);
DeleteBitmap (hBitmapCopy);

return true;
}
return true;
}
}

Expand Down
14 changes: 12 additions & 2 deletions src/utility/utility.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2336,7 +2336,17 @@ SKIF_Util_SetClipboardData (const std::wstring_view& data)
{
bool result = false;

if (OpenClipboard (SKIF_ImGui_hWnd))
bool clipboard_open = false;

for (UINT i = 0 ; i < 5 ; ++i)
{
clipboard_open = OpenClipboard (SKIF_ImGui_hWnd);

if (! clipboard_open)
Sleep (2);
}

if (clipboard_open)
{
HGLOBAL hGlobal = GlobalAlloc (GMEM_MOVEABLE, (data.size() + 1) * sizeof (wchar_t));

Expand All @@ -2347,10 +2357,10 @@ SKIF_Util_SetClipboardData (const std::wstring_view& data)
if (pszDestination != nullptr)
{
memcpy (pszDestination, data.data(), (data.length() + 1) * sizeof (wchar_t));
GlobalUnlock (hGlobal);

EmptyClipboard ( );
result = SetClipboardData (CF_UNICODETEXT, hGlobal);
GlobalUnlock (hGlobal);
}

if (! result)
Expand Down

0 comments on commit f0afd58

Please sign in to comment.