Cygwin: clipboard: Add workaround for setting clipboard failure.

- OpenClipboard() just after CloseClipboard() sometimes fails. Due
  to this, /dev/clipboard sometimes fails to set CF_UNICODETEXT
  data. This patch add a workaround for this issue.
This commit is contained in:
Takashi Yano 2022-07-02 12:08:51 +09:00
parent 1db7cf5ce6
commit 9193f6efde
1 changed files with 34 additions and 13 deletions

View File

@ -20,6 +20,27 @@ details. */
#include <sys/clipboard.h>
#include <unistd.h>
/* Opening clipboard immediately after CloseClipboard()
sometimes fails. Therefore use retry-loop. */
static inline bool
open_clipboard ()
{
const int max_retry = 10;
for (int i = 0; i < max_retry; i++)
{
if (OpenClipboard (NULL))
return true;
Sleep (1);
}
return false;
}
static inline bool
close_clipboard ()
{
return CloseClipboard ();
}
/*
* Robert Collins:
* FIXME: should we use GetClipboardSequenceNumber to tell if the clipboard has
@ -30,9 +51,9 @@ fhandler_dev_clipboard::fhandler_dev_clipboard ()
: fhandler_base (), pos (0), membuffer (NULL), msize (0)
{
/* FIXME: check for errors and loop until we can open the clipboard */
OpenClipboard (NULL);
open_clipboard ();
cygnativeformat = RegisterClipboardFormatW (CYGWIN_NATIVE);
CloseClipboard ();
close_clipboard ();
}
/*
@ -54,7 +75,7 @@ fhandler_dev_clipboard::set_clipboard (const void *buf, size_t len)
{
HGLOBAL hmem;
/* Native CYGWIN format */
if (OpenClipboard (NULL))
if (open_clipboard ())
{
cygcb_t *clipbuf;
@ -62,7 +83,7 @@ fhandler_dev_clipboard::set_clipboard (const void *buf, size_t len)
if (!hmem)
{
__seterrno ();
CloseClipboard ();
close_clipboard ();
return -1;
}
clipbuf = (cygcb_t *) GlobalLock (hmem);
@ -74,7 +95,7 @@ fhandler_dev_clipboard::set_clipboard (const void *buf, size_t len)
GlobalUnlock (hmem);
EmptyClipboard ();
HANDLE ret = SetClipboardData (cygnativeformat, hmem);
CloseClipboard ();
close_clipboard ();
/* According to MSDN, hmem must not be free'd after transferring the
data to the clipboard via SetClipboardData. */
/* GlobalFree (hmem); */
@ -92,7 +113,7 @@ fhandler_dev_clipboard::set_clipboard (const void *buf, size_t len)
set_errno (EILSEQ);
return -1;
}
if (OpenClipboard (NULL))
if (open_clipboard ())
{
PWCHAR clipbuf;
@ -100,14 +121,14 @@ fhandler_dev_clipboard::set_clipboard (const void *buf, size_t len)
if (!hmem)
{
__seterrno ();
CloseClipboard ();
close_clipboard ();
return -1;
}
clipbuf = (PWCHAR) GlobalLock (hmem);
sys_mbstowcs (clipbuf, len + 1, (const char *) buf);
GlobalUnlock (hmem);
HANDLE ret = SetClipboardData (CF_UNICODETEXT, hmem);
CloseClipboard ();
close_clipboard ();
/* According to MSDN, hmem must not be free'd after transferring the
data to the clipboard via SetClipboardData. */
/* GlobalFree (hmem); */
@ -161,7 +182,7 @@ fhandler_dev_clipboard::fstat (struct stat *buf)
buf->st_ctim.tv_nsec = 0L;
buf->st_birthtim = buf->st_atim = buf->st_mtim = buf->st_ctim;
if (OpenClipboard (NULL))
if (open_clipboard ())
{
UINT formatlist[1] = { cygnativeformat };
int format;
@ -176,7 +197,7 @@ fhandler_dev_clipboard::fstat (struct stat *buf)
buf->st_size = clipbuf->cb_size;
GlobalUnlock (hglb);
}
CloseClipboard ();
close_clipboard ();
}
return 0;
@ -192,7 +213,7 @@ fhandler_dev_clipboard::read (void *ptr, size_t& len)
LPVOID cb_data;
int rach;
if (!OpenClipboard (NULL))
if (!open_clipboard ())
{
len = 0;
return;
@ -203,7 +224,7 @@ fhandler_dev_clipboard::read (void *ptr, size_t& len)
|| !(hglb = GetClipboardData (format))
|| !(cb_data = GlobalLock (hglb)))
{
CloseClipboard ();
close_clipboard ();
len = 0;
return;
}
@ -290,7 +311,7 @@ fhandler_dev_clipboard::read (void *ptr, size_t& len)
}
}
GlobalUnlock (hglb);
CloseClipboard ();
close_clipboard ();
len = ret;
}