1 /* fhandler_dev_clipboard: code to access /dev/clipboard
3 Copyright 2000, 2001, 2002, 2003, 2004, 2005 Red Hat, Inc
5 Written by Charles Wilson (cwilson@ece.gatech.edu)
7 This file is part of Cygwin.
9 This software is a copyrighted work licensed under the terms of the
10 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
27 * FIXME: should we use GetClipboardSequenceNumber to tell if the clipboard has
28 * changed? How does /dev/clipboard operate under (say) linux?
31 static const NO_COPY char *CYGWIN_NATIVE = "CYGWIN_NATIVE_CLIPBOARD";
32 /* this is MT safe because windows format id's are atomic */
33 static int cygnativeformat;
35 fhandler_dev_clipboard::fhandler_dev_clipboard ()
36 : fhandler_base (), pos (0), membuffer (NULL), msize (0),
39 /* FIXME: check for errors and loop until we can open the clipboard */
41 cygnativeformat = RegisterClipboardFormat (CYGWIN_NATIVE);
46 * Special clipboard dup to duplicate input and output
51 fhandler_dev_clipboard::dup (fhandler_base * child)
53 fhandler_dev_clipboard *fhc = (fhandler_dev_clipboard *) child;
55 if (!fhc->open (get_flags (), 0))
56 system_printf ("error opening clipboard, %E");
58 fhc->membuffer = membuffer;
66 fhandler_dev_clipboard::open (int flags, mode_t)
68 set_flags (flags | O_TEXT);
75 cygnativeformat = RegisterClipboardFormat (CYGWIN_NATIVE);
82 set_clipboard (const void *buf, size_t len)
85 unsigned char *clipbuf;
86 /* Native CYGWIN format */
88 hmem = GlobalAlloc (GMEM_MOVEABLE, len + sizeof (size_t));
91 system_printf ("Couldn't allocate global buffer for write");
94 clipbuf = (unsigned char *) GlobalLock (hmem);
95 memcpy (clipbuf + sizeof (size_t), buf, len);
96 *(size_t *) (clipbuf) = len;
100 cygnativeformat = RegisterClipboardFormat (CYGWIN_NATIVE);
101 if (!SetClipboardData (cygnativeformat, hmem))
104 ("Couldn't write native format to the clipboard %04x %x",
105 cygnativeformat, hmem);
106 /* FIXME: return an appriate error code &| set_errno(); */
110 if (GlobalFree (hmem))
113 ("Couldn't free global buffer after write to the clipboard");
114 /* FIXME: return an appriate error code &| set_errno(); */
118 /* CF_TEXT/CF_OEMTEXT for copying to wordpad and the like */
121 hmem = GlobalAlloc (GMEM_MOVEABLE, len + 2);
124 system_printf ("Couldn't allocate global buffer for write");
127 clipbuf = (unsigned char *) GlobalLock (hmem);
128 memcpy (clipbuf, buf, len);
129 *(clipbuf + len) = '\0';
130 *(clipbuf + len + 1) = '\0';
132 if (!SetClipboardData
133 ((current_codepage == ansi_cp ? CF_TEXT : CF_OEMTEXT), hmem))
135 system_printf ("Couldn't write to the clipboard");
136 /* FIXME: return an appriate error code &| set_errno(); */
140 if (GlobalFree (hmem))
143 ("Couldn't free global buffer after write to the clipboard");
144 /* FIXME: return an appriate error code &| set_errno(); */
149 /* FIXME: arbitrary seeking is not handled */
151 fhandler_dev_clipboard::write (const void *buf, size_t len)
155 /* write to our membuffer */
156 size_t cursize = msize;
157 void *tempbuffer = realloc (membuffer, cursize + len);
160 system_printf ("Couldn't realloc() clipboard buffer for write");
163 membuffer = tempbuffer;
164 msize = cursize + len;
165 memcpy ((unsigned char *) membuffer + cursize, buf, len);
167 /* now pass to windows */
168 if (set_clipboard (membuffer, msize))
170 /* FIXME: membuffer is now out of sync with pos, but msize is used above */
182 /* FIXME: return 0 bytes written, file not open */
188 fhandler_dev_clipboard::read (void *ptr, size_t& len)
198 formatlist[0] = cygnativeformat;
199 formatlist[1] = current_codepage == ansi_cp ? CF_TEXT : CF_OEMTEXT;
201 if ((format = GetPriorityClipboardFormat (formatlist, 2)) <= 0)
205 system_printf ("a non-accepted format! %d", format);
211 hglb = GetClipboardData (format);
212 if (format == cygnativeformat)
214 unsigned char *buf = (unsigned char *) GlobalLock (hglb);
215 size_t buflen = (*(size_t *) buf);
216 ret = ((len > (buflen - pos)) ? (buflen - pos) : len);
217 memcpy (ptr, buf + sizeof (size_t)+ pos , ret);
219 if (pos + len - ret >= buflen)
226 lpstr = (LPSTR) GlobalLock (hglb);
228 ret = ((len > (strlen (lpstr) - pos)) ? (strlen (lpstr) - pos)
231 memcpy (ptr, lpstr + pos, ret);
232 //ret = snprintf((char *) ptr, len, "%s", lpstr);//+pos);
234 if (pos + len - ret >= strlen (lpstr))
245 fhandler_dev_clipboard::lseek (_off64_t offset, int whence)
247 /* On reads we check this at read time, not seek time.
248 * On writes we use this to decide how to write - empty and write, or open, copy, empty
252 /* treat seek like rewind */
260 fhandler_dev_clipboard::close ()
277 fhandler_dev_clipboard::fixup_after_exec ()