diff options
Diffstat (limited to 'winsup/cygwin/fhandler_clipboard.cc')
-rw-r--r-- | winsup/cygwin/fhandler_clipboard.cc | 129 |
1 files changed, 72 insertions, 57 deletions
diff --git a/winsup/cygwin/fhandler_clipboard.cc b/winsup/cygwin/fhandler_clipboard.cc index 86f126c24..203af58bb 100644 --- a/winsup/cygwin/fhandler_clipboard.cc +++ b/winsup/cygwin/fhandler_clipboard.cc @@ -41,7 +41,8 @@ typedef struct } cygcb_t; fhandler_dev_clipboard::fhandler_dev_clipboard () - : fhandler_base (), pos (0), membuffer (NULL), msize (0) + : fhandler_base (), pos (0), membuffer (NULL), msize (0), + eof (true) { /* FIXME: check for errors and loop until we can open the clipboard */ OpenClipboard (NULL); @@ -68,6 +69,7 @@ int fhandler_dev_clipboard::open (int flags, mode_t) { set_flags (flags | O_TEXT); + eof = false; pos = 0; if (membuffer) free (membuffer); @@ -156,28 +158,38 @@ set_clipboard (const void *buf, size_t len) ssize_t __stdcall fhandler_dev_clipboard::write (const void *buf, size_t len) { - /* write to our membuffer */ - size_t cursize = msize; - void *tempbuffer = realloc (membuffer, cursize + len); - if (!tempbuffer) + if (!eof) { - debug_printf ("Couldn't realloc() clipboard buffer for write"); - return -1; - } - membuffer = tempbuffer; - msize = cursize + len; - memcpy ((unsigned char *) membuffer + cursize, buf, len); + /* write to our membuffer */ + size_t cursize = msize; + void *tempbuffer = realloc (membuffer, cursize + len); + if (!tempbuffer) + { + debug_printf ("Couldn't realloc() clipboard buffer for write"); + return -1; + } + membuffer = tempbuffer; + msize = cursize + len; + memcpy ((unsigned char *) membuffer + cursize, buf, len); - /* now pass to windows */ - if (set_clipboard (membuffer, msize)) + /* now pass to windows */ + if (set_clipboard (membuffer, msize)) + { + /* FIXME: membuffer is now out of sync with pos, but msize + is used above */ + return -1; + } + + pos = msize; + + eof = false; + return len; + } + else { - /* FIXME: membuffer is now out of sync with pos, but msize - is used above */ - return -1; + /* FIXME: return 0 bytes written, file not open */ + return 0; } - - pos = msize; - return len; } int __stdcall @@ -218,65 +230,66 @@ void __stdcall fhandler_dev_clipboard::read (void *ptr, size_t& len) { HGLOBAL hglb; - size_t ret = 0; + size_t ret; UINT formatlist[2]; int format; - LPVOID cb_data; + size_t plen = len; + len = 0; + if (eof) + return; if (!OpenClipboard (NULL)) + return; + formatlist[0] = cygnativeformat; + formatlist[1] = CF_UNICODETEXT; + if ((format = GetPriorityClipboardFormat (formatlist, 2)) <= 0) { - len = 0; + CloseClipboard (); return; } - formatlist[0] = cygnativeformat; - formatlist[1] = CF_UNICODETEXT; - if ((format = GetPriorityClipboardFormat (formatlist, 2)) <= 0 - || !(hglb = GetClipboardData (format)) - || !(cb_data = GlobalLock (hglb))) + if (!(hglb = GetClipboardData (format))) { CloseClipboard (); - len = 0; return; } if (format == cygnativeformat) { - cygcb_t *clipbuf = (cygcb_t *) cb_data; + cygcb_t *clipbuf; - if (pos < clipbuf->len) - { - ret = ((len > (clipbuf->len - pos)) ? (clipbuf->len - pos) : len); - memcpy (ptr, clipbuf->data + pos , ret); - pos += ret; + if (!(clipbuf = (cygcb_t *) GlobalLock (hglb))) + { + CloseClipboard (); + return; } + ret = ((plen > (clipbuf->len - pos)) ? (clipbuf->len - pos) : plen); + memcpy (ptr, clipbuf->data + pos , ret); + pos += ret; + if (pos + plen - ret >= clipbuf->len) + eof = true; } else { - wchar_t *buf = (wchar_t *) cb_data; + int wret; + PWCHAR buf; - size_t glen = GlobalSize (hglb) / sizeof (WCHAR) - 1; - if (pos < glen) + if (!(buf = (PWCHAR) GlobalLock (hglb))) { - /* Comparing apples and oranges here, but the below loop could become - extremly slow otherwise. We rather return a few bytes less than - possible instead of being even more slow than usual... */ - if (glen > pos + len) - glen = pos + len; - /* This loop is necessary because the number of bytes returned by - sys_wcstombs does not indicate the number of wide chars used for - it, so we could potentially drop wide chars. */ - while ((ret = sys_wcstombs (NULL, 0, buf + pos, glen - pos)) - != (size_t) -1 - && ret > len) - --glen; - if (ret == (size_t) -1) - ret = 0; - else - { - ret = sys_wcstombs ((char *) ptr, (size_t) -1, - buf + pos, glen - pos); - pos = glen; - } + CloseClipboard (); + return; } + size_t glen = GlobalSize (hglb) / sizeof (WCHAR) - 1; + /* This loop is necessary because the number of bytes returned by + sys_wcstombs does not indicate the number of wide chars used for + it, so we could potentially drop wide chars. */ + if (glen - pos > plen) + glen = pos + plen; + while ((wret = sys_wcstombs (NULL, 0, buf + pos, glen - pos)) != -1 + && (size_t) wret > plen) + --glen; + ret = sys_wcstombs ((char *) ptr, plen, buf + pos, glen - pos); + pos += ret; + if (pos + plen - ret >= wcslen (buf)) + eof = true; } GlobalUnlock (hglb); CloseClipboard (); @@ -303,6 +316,7 @@ fhandler_dev_clipboard::close () { if (!have_execed) { + eof = true; pos = 0; if (membuffer) { @@ -319,6 +333,7 @@ fhandler_dev_clipboard::fixup_after_exec () { if (!close_on_exec ()) { + eof = false; pos = msize = 0; membuffer = NULL; } |