tdevdraw: update OS X snarf for 32-bit Rune (again) - plan9port - [fork] Plan 9 from user space
 (HTM) git clone git://src.adamsgaard.dk/plan9port
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 5d0dfbb05a25a953250dde523f1f68fcc1469750
 (DIR) parent dd73705611ada36019e58fdd8f27fa59aae7e975
 (HTM) Author: Russ Cox <rsc@swtch.com>
       Date:   Sat, 12 Sep 2009 19:50:55 -0400
       
       devdraw: update OS X snarf for 32-bit Rune (again)
       
       fixes #29 http://code.swtch.com/plan9port/issues/29/
       
       The accidental resubmission of the patch caused
       patch(1) to revert the patch.  Thanks, patch authors!
       
       http://codereview.appspot.com/117057
       
       Diffstat:
         M src/cmd/devdraw/osx-screen.c        |      49 +++++++++++++++++++++++++------
       
       1 file changed, 40 insertions(+), 9 deletions(-)
       ---
 (DIR) diff --git a/src/cmd/devdraw/osx-screen.c b/src/cmd/devdraw/osx-screen.c
       t@@ -732,7 +732,7 @@ struct {
        char*
        getsnarf(void)
        {
       -        char *s, *t;
       +        char *s;
                CFArrayRef flavors;
                CFDataRef data;
                CFIndex nflavor, ndata, j;
       t@@ -741,6 +741,9 @@ getsnarf(void)
                PasteboardItemID id;
                PasteboardSyncFlags flags;
                UInt32 i;
       +        u16int *u;
       +        Fmt fmt;
       +        Rune r;
        
        /*        fprint(2, "applegetsnarf\n"); */
                qlock(&clip.lk);
       t@@ -775,15 +778,26 @@ getsnarf(void)
                                        continue;
                                if(PasteboardCopyItemFlavorData(clip.apple, id, type, &data) != noErr)
                                        continue;
       -                        ndata = CFDataGetLength(data);
                                qunlock(&clip.lk);
       -                        s = smprint("%.*S", ndata/2, (Rune*)CFDataGetBytePtr(data));
       +                        ndata = CFDataGetLength(data)/2;
       +                        u = (u16int*)CFDataGetBytePtr(data);
       +                        fmtstrinit(&fmt);
       +                        // decode utf-16.  what was apple thinking?
       +                        for(i=0; i<ndata; i++) {
       +                                r = u[i];
       +                                if(0xd800 <= r && r < 0xdc00 && i+1 < ndata && 0xdc00 <= u[i+1] && u[i+1] < 0xe000) {
       +                                        r = (((r - 0xd800)<<10) |  (u[i+1] - 0xdc00)) + 0x10000;
       +                                        i++;
       +                                }
       +                                else if(0xd800 <= r && r < 0xe000)
       +                                        r = Runeerror;
       +                                if(r == '\r')
       +                                        r = '\n';
       +                                fmtrune(&fmt, r);
       +                        }
                                CFRelease(flavors);
                                CFRelease(data);
       -                        for(t=s; *t; t++)
       -                                if(*t == '\r')
       -                                        *t = '\n';
       -                        return s;
       +                        return fmtstrflush(&fmt);
                        }
                        CFRelease(flavors);
                }
       t@@ -796,6 +810,9 @@ putsnarf(char *s)
        {
                CFDataRef cfdata;
                PasteboardSyncFlags flags;
       +        u16int *u, *p;
       +        Rune r;
       +        int i;
        
        /*        fprint(2, "appleputsnarf\n"); */
        
       t@@ -816,9 +833,23 @@ putsnarf(char *s)
                        qunlock(&clip.lk);
                        return;
                }
       -        assert(sizeof(clip.rbuf[0]) == 2);
       +        u = malloc(runestrlen(clip.rbuf)*4);
       +        p = u;
       +        for(i=0; clip.rbuf[i]; i++) {
       +                r = clip.rbuf[i];
       +                // convert to utf-16
       +                if(0xd800 <= r && r < 0xe000)
       +                        r = Runeerror;
       +                if(r >= 0x10000) {
       +                        r -= 0x10000;
       +                        *p++ = 0xd800 + (r>>10);
       +                        *p++ = 0xdc00 + (r & ((1<<10)-1));
       +                } else
       +                        *p++ = r;
       +        }
                cfdata = CFDataCreate(kCFAllocatorDefault, 
       -                (uchar*)clip.rbuf, runestrlen(clip.rbuf)*2);
       +                (uchar*)u, (p-u)*2);
       +        free(u);
                if(cfdata == nil){
                        fprint(2, "apple pasteboard cfdatacreate failed\n");
                        qunlock(&clip.lk);