* fhandler.h (class fhandler_dev_clipboard): Add fstat method.

* fhandler_clipboard.cc (cygcb_t): New type for Cygwin-specific
	clipboard format.
	(set_clipboard): Use new clipboard format to allow setting a timestamp.
	(fhandler_dev_clipboard::fstat): New method.  Read modification and
	access timestamp as well as length from clipboard data.
	(fhandler_dev_clipboard::read): Use new clipboard format.
This commit is contained in:
Corinna Vinschen 2012-03-26 11:24:51 +00:00
parent 33c789303f
commit c2c7860fff
3 changed files with 72 additions and 14 deletions

View File

@ -1,3 +1,13 @@
2012-03-26 Corinna Vinschen <corinna@vinschen.de>
* fhandler.h (class fhandler_dev_clipboard): Add fstat method.
* fhandler_clipboard.cc (cygcb_t): New type for Cygwin-specific
clipboard format.
(set_clipboard): Use new clipboard format to allow setting a timestamp.
(fhandler_dev_clipboard::fstat): New method. Read modification and
access timestamp as well as length from clipboard data.
(fhandler_dev_clipboard::read): Use new clipboard format.
2012-03-26 Corinna Vinschen <corinna@vinschen.de>
* hires.h (hires_ms::dmsecs): Drop unused method.

View File

@ -1685,6 +1685,7 @@ class fhandler_dev_clipboard: public fhandler_base
fhandler_dev_clipboard ();
int is_windows () { return 1; }
int open (int flags, mode_t mode = 0);
int __stdcall fstat (struct __stat64 *buf) __attribute__ ((regparm (2)));
ssize_t __stdcall write (const void *ptr, size_t len);
void __stdcall read (void *ptr, size_t& len) __attribute__ ((regparm (3)));
_off64_t lseek (_off64_t offset, int whence);

View File

@ -1,6 +1,7 @@
/* fhandler_dev_clipboard: code to access /dev/clipboard
Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009, 2011 Red Hat, Inc
Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2008, 2009, 2011,
2012 Red Hat, Inc
Written by Charles Wilson (cwilson@ece.gatech.edu)
@ -32,6 +33,13 @@ static const NO_COPY WCHAR *CYGWIN_NATIVE = L"CYGWIN_NATIVE_CLIPBOARD";
/* this is MT safe because windows format id's are atomic */
static int cygnativeformat;
typedef struct
{
timestruc_t timestamp;
size_t len;
char data[1];
} cygcb_t;
fhandler_dev_clipboard::fhandler_dev_clipboard ()
: fhandler_base (), pos (0), membuffer (NULL), msize (0),
eof (true)
@ -77,20 +85,24 @@ static int
set_clipboard (const void *buf, size_t len)
{
HGLOBAL hmem;
void *clipbuf;
/* Native CYGWIN format */
if (OpenClipboard (NULL))
{
hmem = GlobalAlloc (GMEM_MOVEABLE, len + sizeof (size_t));
cygcb_t *clipbuf;
hmem = GlobalAlloc (GMEM_MOVEABLE, sizeof (cygcb_t) + len);
if (!hmem)
{
__seterrno ();
CloseClipboard ();
return -1;
}
clipbuf = GlobalLock (hmem);
memcpy ((unsigned char *) clipbuf + sizeof (size_t), buf, len);
*(size_t *) (clipbuf) = len;
clipbuf = (cygcb_t *) GlobalLock (hmem);
clock_gettime (CLOCK_REALTIME, &clipbuf->timestamp);
clipbuf->len = len;
memcpy (clipbuf->data, buf, len);
GlobalUnlock (hmem);
EmptyClipboard ();
if (!cygnativeformat)
@ -116,6 +128,8 @@ set_clipboard (const void *buf, size_t len)
}
if (OpenClipboard (NULL))
{
PWCHAR clipbuf;
hmem = GlobalAlloc (GMEM_MOVEABLE, (len + 1) * sizeof (WCHAR));
if (!hmem)
{
@ -123,8 +137,8 @@ set_clipboard (const void *buf, size_t len)
CloseClipboard ();
return -1;
}
clipbuf = GlobalLock (hmem);
sys_mbstowcs ((PWCHAR) clipbuf, len + 1, (const char *) buf);
clipbuf = (PWCHAR) GlobalLock (hmem);
sys_mbstowcs (clipbuf, len + 1, (const char *) buf);
GlobalUnlock (hmem);
HANDLE ret = SetClipboardData (CF_UNICODETEXT, hmem);
CloseClipboard ();
@ -178,6 +192,40 @@ fhandler_dev_clipboard::write (const void *buf, size_t len)
}
}
int __stdcall
fhandler_dev_clipboard::fstat (struct __stat64 *buf)
{
buf->st_mode = S_IFCHR | STD_RBITS | STD_WBITS | S_IWGRP | S_IWOTH;
buf->st_uid = geteuid32 ();
buf->st_gid = getegid32 ();
buf->st_nlink = 1;
buf->st_blksize = PREFERRED_IO_BLKSIZE;
buf->st_ctim.tv_sec = 1164931200L; /* Arbitrary value: 2006-12-01 */
buf->st_ctim.tv_nsec = 0L;
buf->st_birthtim = buf->st_atim = buf->st_mtim = buf->st_ctim;
if (OpenClipboard (NULL))
{
UINT formatlist[1] = { cygnativeformat };
int format;
HGLOBAL hglb;
cygcb_t *clipbuf;
if ((format = GetPriorityClipboardFormat (formatlist, 1)) > 0
&& (hglb = GetClipboardData (format))
&& (clipbuf = (cygcb_t *) GlobalLock (hglb)))
{
buf->st_atim = buf->st_mtim = clipbuf->timestamp;
buf->st_size = clipbuf->len;
GlobalUnlock (hglb);
}
CloseClipboard ();
}
return 0;
}
void __stdcall
fhandler_dev_clipboard::read (void *ptr, size_t& len)
{
@ -206,18 +254,17 @@ fhandler_dev_clipboard::read (void *ptr, size_t& len)
}
if (format == cygnativeformat)
{
unsigned char *buf;
cygcb_t *clipbuf;
if (!(buf = (unsigned char *) GlobalLock (hglb)))
if (!(clipbuf = (cygcb_t *) GlobalLock (hglb)))
{
CloseClipboard ();
return;
}
size_t buflen = (*(size_t *) buf);
ret = ((plen > (buflen - pos)) ? (buflen - pos) : plen);
memcpy (ptr, buf + sizeof (size_t)+ pos , ret);
ret = ((plen > (clipbuf->len - pos)) ? (clipbuf->len - pos) : plen);
memcpy (ptr, clipbuf->data + pos , ret);
pos += ret;
if (pos + plen - ret >= buflen)
if (pos + plen - ret >= clipbuf->len)
eof = true;
}
else