Hi, attached is the patch to introduce unicode support to the Win32::Clipboard module, which I happen to implement for my needs and now intent to share.
I decided not to support $CLIPB->... interface for these 2 new functions, because I dislike the concept of fake OO. Also, the patch increments the module version number. Thanks in advance for considering this, regards, Vadim.
diff -bur Win32-Clipboard-0.56/ChangeLog Win32-Clipboard-0.57/ChangeLog --- Win32-Clipboard-0.56/ChangeLog Fri Jan 14 04:58:15 2011 +++ Win32-Clipboard-0.57/ChangeLog Sat Mar 17 23:20:22 2012 @@ -1,3 +1,7 @@ +2012-03-17 + - version 0.57 + - deal with unicode text: UGet(), USet($s), IsUText() + 2011-01-13 - version 0.56 - include file <wchar.h> needed for MinGW/Cygwin compilation diff -bur Win32-Clipboard-0.56/Clipboard.pm Win32-Clipboard-0.57/Clipboard.pm --- Win32-Clipboard-0.56/Clipboard.pm Fri Jan 14 04:58:32 2011 +++ Win32-Clipboard-0.57/Clipboard.pm Sat Mar 17 22:00:41 2012 @@ -3,13 +3,15 @@ # # Win32::Clipboard - Interaction with the Windows clipboard # -# Version: 0.56 +# Version: 0.57 # Author: Aldo Calpini <d...@perl.it> # # Modified by: Hideyo Imazu <him...@gmail.com> # ####################################################################### +$VERSION = "0.57"; + require Exporter; require DynaLoader; @@ -53,8 +55,6 @@ } -$VERSION = "0.56"; - sub new { my($class, $value) = @_; my $self = "I'm the Clipboard!"; @@ -62,9 +62,6 @@ return bless(\$self); } -sub Version { - return $VERSION; -} sub Get { if( IsBitmap() ) { return GetBitmap(); } @@ -175,7 +172,9 @@ All the functions can be used either with their full name (eg. B<Win32::Clipboard::Get>) or as methods of a C<Win32::Clipboard> -object. For the syntax, refer to L</SYNOPSIS> above. Note also that +object. Except for these two: C<Win32::Clipboard::UGet()> and +C<Win32::Clipboard::USet($s)>. +For the syntax, refer to L</SYNOPSIS> above. Note also that you can create a clipboard object and set its content at the same time with: @@ -223,7 +222,7 @@ elsif( IsFiles() ) { return GetFiles(); } else { return GetText(); } -See also IsBitmap(), IsFiles(), IsText(), EnumFormats() and +See also IsBitmap(), IsFiles(), IsText(), IsUText(), EnumFormats() and IsFormatAvailable() to check the clipboard format before getting data. =item GetAs(FORMAT) @@ -240,6 +239,9 @@ $text = $clip->GetAs(CF_UNICODETEXT); $text = Encode::decode("UTF16-LE", $text); +Alternatively, you can use C<UGet()> function, which does required conversion +internally, and also C<USet(...)> function for the reverse operation. + =item GetBitmap() Returns the clipboard content as an image, or C<undef> on errors. @@ -259,6 +261,21 @@ Returns the clipboard content as a string, or C<undef> on errors. +=item UGet() + +Returns the clipboard content as unicode string, or C<undef> on errors. +Resulting string have UTF8 bit on. +Call it as C<Win32::Clipboard::UGet()>, the OO interface C<<$CLIP->...>> +not supported. + +=item USet(string) + +Sets the clipboard content as unicode string, or C<undef> on errors. +Internally, this function will convert string to wide-char windows +encoding. +Call it as C<Win32::Clipboard::USet($s)>, the OO interface C<<$CLIP->...>> +not supported. + =item IsBitmap() Returns a boolean value indicating if the clipboard contains an image. @@ -279,6 +296,11 @@ Returns a boolean value indicating if the clipboard contains text. See also GetText(). + +=item IsUText() + +Returns a boolean value indicating if the clipboard contains Unicode text. +See also USet(), UGet(). =item Set(VALUE) diff -bur Win32-Clipboard-0.56/Clipboard.xs Win32-Clipboard-0.57/Clipboard.xs --- Win32-Clipboard-0.56/Clipboard.xs Fri Jan 14 04:59:21 2011 +++ Win32-Clipboard-0.57/Clipboard.xs Sat Mar 17 23:20:04 2012 @@ -3,7 +3,7 @@ # # Win32::Clipboard - Interaction with the Windows clipboard # -# Version: 0.56 +# Version: 0.57 # Created: 19 Nov 96 # Author: Aldo Calpini <d...@perl.it> # @@ -469,6 +469,34 @@ } void +UGet() +PPCODE: + HANDLE myhandle; + if(OpenClipboard(NULL)) { + EXTEND(SP,1); + if(myhandle = GetClipboardData(CF_UNICODETEXT)) { + /* here we decode UTF16-LE into UTF8, using perl API */ + wchar_t *wcmyh = (wchar_t*)myhandle; + int i, len = wcslen(wcmyh); + SV *sv = newSV(len * UTF8_MAXBYTES +1); + SvPOK_on(sv); + U8 *e = (U8*) SvPVX(sv), *e0 = e; + for (i=0; i<len; i++) { + e = uvuni_to_utf8(e, wcmyh[i]); + } + *e = 0; + SvCUR_set(sv, e-e0); + SvUTF8_on(sv); + ST(0) = sv_2mortal(sv); + } else + XST_mNO(0); + CloseClipboard(); + XSRETURN(1); + } else { + XSRETURN_NO; + } + +void GetFiles(...) PPCODE: HANDLE myhandle; @@ -652,6 +680,58 @@ } void +USet(text) + SV *text +PPCODE: + HANDLE myhandle; + HGLOBAL hGlobal; + STRLEN leng; + U8 *str = (U8*) SvPV(text, leng); + + if ( hGlobal = GlobalAlloc(GMEM_DDESHARE, (leng+2)*sizeof(char)*2) ) { + /* here we encode UTF16-LE from UTF8, using perl API */ + wchar_t *szString = (wchar_t *) GlobalLock(hGlobal); + + if(SvUTF8(text)) { + /* indeed, we have utf8 data */ + U8 * const send = str + leng; + STRLEN ulen; + while (str < send) { + *szString++ = (wchar_t)utf8_to_uvchr(str, &ulen); + str += ulen; + } + } else { + /* we have raw data, no encoding to UTF8, so converting + * binarily means appending waw '\0' to each char */ + U8 * const send = str + leng; + while (str < send) { + *szString++ = (wchar_t) *str++; + } + } + *szString = '\0'; + + GlobalUnlock(hGlobal); + + if ( OpenClipboard(NULL) ) { + EmptyClipboard(); + myhandle = SetClipboardData(CF_UNICODETEXT, (HANDLE) hGlobal); + CloseClipboard(); + + if ( myhandle ) { + XSRETURN_YES; + } else { + XSRETURN_NO; + } + } else { + GlobalFree(hGlobal); + XSRETURN_NO; + } + + } else { + XSRETURN_NO; + } + +void Empty(...) PPCODE: if(OpenClipboard(NULL)) { @@ -697,6 +777,13 @@ IsText(...) CODE: RETVAL = (long) IsClipboardFormatAvailable(CF_TEXT); +OUTPUT: + RETVAL + +long +IsUText(...) +CODE: + RETVAL = (long) IsClipboardFormatAvailable(CF_UNICODETEXT); OUTPUT: RETVAL diff -bur Win32-Clipboard-0.56/META.yml Win32-Clipboard-0.57/META.yml --- Win32-Clipboard-0.56/META.yml Fri Jan 14 05:00:16 2011 +++ Win32-Clipboard-0.57/META.yml Sat Mar 17 23:18:32 2012 @@ -1,11 +1,12 @@ --- #YAML:1.0 name: Win32-Clipboard -version: 0.56 +version: 0.57 abstract: Interaction with the Windows clipboard author: - Aldo Calpini <d...@perl.it> - Hideyo Imazu <him...@gmail.com> - Jan Dubois <j...@activestate.com> + - Vadim Konovalov <m...@vadrer.org> license: perl distribution_type: module configure_requires: diff -bur Win32-Clipboard-0.56/README Win32-Clipboard-0.57/README --- Win32-Clipboard-0.56/README Fri Jan 14 04:59:31 2011 +++ Win32-Clipboard-0.57/README Sat Mar 17 23:21:35 2012 @@ -4,10 +4,12 @@ # # Author: Aldo Calpini <d...@perl.it> # Modified by: Hideyo Imazu <h...@imazu.net> -# Version: 0.56 +# Modified by: Vadim Konovalov <m...@vadrer.org> +# Version: 0.57 # Info: # http://dada.perl.it # http://www.perl.com/CPAN/authors/Aldo_Calpini +# https://libwin32.googlecode.com/svn/trunk/Win32-Clipboard # ####################################################################### @@ -18,10 +20,11 @@ changes. This version supports 3 formats for getting clipboard data: - simple text + - unicode text - bitmaps - list of files -...and only simple text for putting data to the clipboard. +...and only simple/unicode text for putting data to the clipboard. SYNOPSIS diff -bur Win32-Clipboard-0.56/t/test.t Win32-Clipboard-0.57/t/test.t --- Win32-Clipboard-0.56/t/test.t Wed Nov 26 02:58:00 2008 +++ Win32-Clipboard-0.57/t/test.t Sat Mar 17 22:24:54 2012 @@ -7,7 +7,7 @@ ######################### We start with some black magic to print on failure. -BEGIN { $| = 1; print "1..9\n"; } +BEGIN { $| = 1; print "1..12\n"; } END {print "not ok 1\n" unless $loaded;} use Win32::Clipboard; $loaded = 1; @@ -50,3 +50,18 @@ $clip = "Win32::Clipboard test"; print "not " unless tied($clip)->IsText(); print "ok 9\n"; + +# unicode clipboard checks +use utf8; + +Win32::Clipboard::USet("qwerty"); +my $s = Win32::Clipboard::UGet(); +print "not " unless $s eq "qwerty"; +print "ok 10\n"; + +print +(utf8::is_utf8($s)? '' : "not ") . "ok 11\n"; + +Win32::Clipboard::USet("пÑоба пеÑа"); +print "not " unless Win32::Clipboard::UGet() eq "пÑоба пеÑа"; +print "ok 12\n"; +