diff -ur tigervnc-1.0.90-20100115svn3945.ori/common/rfb/CMsgReader.cxx tigervnc-1.0.90-20100115svn3945/common/rfb/CMsgReader.cxx
--- tigervnc-1.0.90-20100115svn3945.ori/common/rfb/CMsgReader.cxx	2009-03-20 11:02:31.000000000 +0100
+++ tigervnc-1.0.90-20100115svn3945/common/rfb/CMsgReader.cxx	2011-09-21 10:01:09.667788407 +0200
@@ -61,11 +61,14 @@
 {
   is->skip(3);
   rdr::U32 len = is->readU32();
+  /*
+  // FIXME: should find a way to configure the max cut&paste size here
   if (len > 256*1024) {
     is->skip(len);
     fprintf(stderr,"cut text too long (%d bytes) - ignoring\n",len);
     return;
   }
+  */
   CharArray ca(len+1);
   ca.buf[len] = 0;
   is->readBytes(ca.buf, len);
diff -ur tigervnc-1.0.90-20100115svn3945.ori/common/rfb/SMsgReader.cxx tigervnc-1.0.90-20100115svn3945/common/rfb/SMsgReader.cxx
--- tigervnc-1.0.90-20100115svn3945.ori/common/rfb/SMsgReader.cxx	2009-03-05 12:57:11.000000000 +0100
+++ tigervnc-1.0.90-20100115svn3945/common/rfb/SMsgReader.cxx	2011-09-21 09:54:59.275840880 +0200
@@ -28,7 +28,7 @@
 
 static LogWriter vlog("SMsgReader");
 
-static IntParameter maxCutText("MaxCutText", "Maximum permitted length of an incoming clipboard update", 256*1024);
+static IntParameter maxCutText("MaxCutText", "Maximum permitted length of an incoming clipboard update", 1024*1024);
 
 SMsgReader::SMsgReader(SMsgHandler* handler_, rdr::InStream* is_)
   : handler(handler_), is(is_)
diff -ur tigervnc-1.0.90-20100115svn3945.ori/unix/tx/TXWindow.cxx tigervnc-1.0.90-20100115svn3945/unix/tx/TXWindow.cxx
--- tigervnc-1.0.90-20100115svn3945.ori/unix/tx/TXWindow.cxx	2009-09-04 12:57:20.000000000 +0200
+++ tigervnc-1.0.90-20100115svn3945/unix/tx/TXWindow.cxx	2011-09-21 12:02:04.231858887 +0200
@@ -30,7 +30,7 @@
 
 Atom wmProtocols, wmDeleteWindow, wmTakeFocus;
 Atom xaTIMESTAMP, xaTARGETS, xaSELECTION_TIME, xaSELECTION_STRING;
-Atom xaCLIPBOARD;
+Atom xaCLIPBOARD, xaINCR;
 unsigned long TXWindow::black, TXWindow::white;
 unsigned long TXWindow::defaultFg, TXWindow::defaultBg;
 unsigned long TXWindow::lightBg, TXWindow::darkBg;
@@ -57,6 +57,7 @@
   xaSELECTION_TIME = XInternAtom(dpy, "SELECTION_TIME", False);
   xaSELECTION_STRING = XInternAtom(dpy, "SELECTION_STRING", False);
   xaCLIPBOARD = XInternAtom(dpy, "CLIPBOARD", False);
+  xaINCR = XInternAtom(dpy, "INCR", False);
   XColor cols[6];
   cols[0].red = cols[0].green = cols[0].blue = 0x0000;
   cols[1].red = cols[1].green = cols[1].blue = 0xbbbb;
@@ -412,18 +413,66 @@
     if (ev->xselection.property != None) {
       Atom type;
       int format;
-      unsigned long nitems, after;
-      unsigned char *data;
-      XGetWindowProperty(dpy, win(), ev->xselection.property, 0, 16384, True,
-                         AnyPropertyType, &type, &format,
-                         &nitems, &after, &data);
+      unsigned long nitems = 0, after;
+      unsigned char *data = 0;
+
+      XGetWindowProperty(dpy, win(), ev->xselection.property, 
+          0, 0, False,
+          AnyPropertyType, &type, &format,
+          &nitems, &after, &data);
+      XFree(data);
+      data = 0;
+
+      // dont get the INCR values
+      if (type != None && type != xaINCR && after) {
+        XGetWindowProperty(dpy, win(), ev->xselection.property, 
+            0, (after + 3) / 4, False,
+            AnyPropertyType, &type, &format,
+            &nitems, &after, &data);
+      }
+
       if (type != None) {
         selectionNotify(&ev->xselection, type, format, nitems, data);
-        XFree(data);
-        break;
       }
+
+      XFree(data);
+      XDeleteProperty(dpy, win(), ev->xselection.property);
+      XFlush(dpy);
+    }
+    else {
+      selectionNotify(&ev->xselection, 0, 0, 0, 0);
+    }
+    break;
+
+  case PropertyNotify:
+    if (ev->xproperty.state == PropertyNewValue) {
+      Atom type;
+      int format;
+      unsigned long nitems = 0, after;
+      unsigned char *data = 0;
+
+      XGetWindowProperty(dpy, win(), ev->xproperty.atom, 
+          0, 0, False,
+          AnyPropertyType, &type, &format,
+          &nitems, &after, &data);
+      XFree(data);
+      data = 0;
+
+      if (type != None && type != xaINCR && after) {
+        XGetWindowProperty(dpy, win(), ev->xproperty.atom, 
+            0, (after + 3) / 4, False,
+            AnyPropertyType, &type, &format,
+            &nitems, &after, &data);
+      }
+
+      if (type != None) {
+        propertyNotify(&ev->xproperty, type, format, nitems, 
+            data);
+      }
+      XFree(data);
+      XDeleteProperty(dpy, win(), ev->xproperty.atom);
+      XFlush(dpy);
     }
-    selectionNotify(&ev->xselection, 0, 0, 0, 0);
     break;
 
   case SelectionRequest:
diff -ur tigervnc-1.0.90-20100115svn3945.ori/unix/tx/TXWindow.h tigervnc-1.0.90-20100115svn3945/unix/tx/TXWindow.h
--- tigervnc-1.0.90-20100115svn3945.ori/unix/tx/TXWindow.h	2011-09-15 18:31:10.217081043 +0200
+++ tigervnc-1.0.90-20100115svn3945/unix/tx/TXWindow.h	2011-09-21 10:03:35.950851421 +0200
@@ -136,6 +136,11 @@
   // window manager.
   virtual void takeFocus(Time time) {}
 
+  // propertyNotify() is called when the selection owner has replied to a
+  // request for information about a selection from the selection owner.
+  virtual void propertyNotify(XPropertyEvent* ev, Atom type, int format,
+                              int nitems, void* data) {}
+
   // selectionNotify() is called when the selection owner has replied to a
   // request for information about a selection from the selection owner.
   virtual void selectionNotify(XSelectionEvent* ev, Atom type, int format,
@@ -209,6 +214,6 @@
 
 extern Atom wmProtocols, wmDeleteWindow, wmTakeFocus;
 extern Atom xaTIMESTAMP, xaTARGETS, xaSELECTION_TIME, xaSELECTION_STRING;
-extern Atom xaCLIPBOARD;
+extern Atom xaCLIPBOARD, xaINCR;
 
 #endif
diff -ur tigervnc-1.0.90-20100115svn3945.ori/unix/vncconfig/vncconfig.cxx tigervnc-1.0.90-20100115svn3945/unix/vncconfig/vncconfig.cxx
--- tigervnc-1.0.90-20100115svn3945.ori/unix/vncconfig/vncconfig.cxx	2006-05-18 13:08:21.000000000 +0200
+++ tigervnc-1.0.90-20100115svn3945/unix/vncconfig/vncconfig.cxx	2011-09-21 17:20:37.632865858 +0200
@@ -94,6 +94,8 @@
   {
     selection[0] = selection[1] = 0;
     selectionLen[0] = selectionLen[1] = 0;
+    incremental[0] = incremental[1] = false;
+    converting = false;
     int y = yPad;
     acceptClipboard.move(xPad, y);
     acceptClipboard.checked(getBoolParam(dpy, ACCEPT_CUT_TEXT));
@@ -107,10 +109,12 @@
     y += sendPrimaryCB.height();
     setEventHandler(this);
     toplevel("VNC config", this, 0, 0, 0, iconic);
+    XSelectInput(dpy, win(), PropertyChangeMask);
     XVncExtSelectInput(dpy, win(),
                        VncExtClientCutTextMask|
                        VncExtSelectionChangeMask|
                        VncExtQueryConnectMask);
+    converting = true;
     XConvertSelection(dpy, XA_PRIMARY, XA_STRING,
                       XA_PRIMARY, win(), CurrentTime);
     XConvertSelection(dpy, xaCLIPBOARD, XA_STRING,
@@ -142,6 +146,8 @@
           delete [] selection[1];
           selection[0] = selection[1] = 0;
           selectionLen[0] = selectionLen[1] = 0;
+          incremental[0] = incremental[1] = false;
+          converting = false;
         }
       }
     }
@@ -151,9 +157,12 @@
         XVncExtSelectionChangeEvent* selEv = (XVncExtSelectionChangeEvent*)ev;
         if (selEv->selection == xaCLIPBOARD ||
             (selEv->selection == XA_PRIMARY && sendPrimaryCB.checked())) {
-          if (!selectionOwner(selEv->selection))
-            XConvertSelection(dpy, selEv->selection, XA_STRING,
-                              selEv->selection, win(), CurrentTime);
+          if (!selectionOwner(selEv->selection) && !converting) {
+            // dont perform two conversions at the same time
+            converting = true;
+            XConvertSelection(dpy, selEv->selection, XA_STRING, selEv->selection,
+                win(), CurrentTime);
+          }
         }
       }
     }
@@ -197,30 +206,111 @@
   void selectionNotify(XSelectionEvent* ev, Atom type, int format,
                        int nitems, void* data)
   {
-    if (ev->requestor != win() || ev->target != XA_STRING)
+    int i = (ev->property == XA_PRIMARY ? 0 : 1);
+    // incremental data come through propertyNotify
+    if (ev->requestor != win() || ev->target != XA_STRING || incremental[i])
       return;
 
-    if (data && format == 8) {
-      int i = (ev->selection == XA_PRIMARY ? 0 : 1);
-      if (selectionLen[i] == nitems && memcmp(selection[i], data, nitems) == 0)
+    if (type == xaINCR) {
+      // switch to incremental mode
+      if (selection[i])
+      {
+        delete [] selection[i];
+        selection[i] = 0;
+      }
+      selectionLen[i] = 0;
+      incremental[i] = true;
+      return;
+    }
+
+    if (data && format == 8 ) {
+      incremental[i] = false;
+
+      if (selectionLen[i] == nitems && memcmp(selection[i], data, nitems) == 0) {
+        vlog.debug("ignoring duplicate cut text");
+        converting = false;
         return;
+      }
+
       delete [] selection[i];
       selection[i] = new char[nitems];
       memcpy(selection[i], data, nitems);
       selectionLen[i] = nitems;
-      if (cutTextLen == nitems && memcmp(cutText, data, nitems) == 0) {
-        vlog.debug("ignoring duplicate cut text");
-        return;
-      }
+
       if (cutText)
         XFree(cutText);
       cutText = (char*)malloc(nitems); // assuming XFree() same as free()
       memcpy(cutText, data, nitems);
       cutTextLen = nitems;
+
       vlog.debug("sending %s selection as server cut text: '%.*s%s'",
-                 selectionName(ev->selection),cutTextLen<9?cutTextLen:8,
-                 cutText, cutTextLen<9?"":"...");
+          selectionName(ev->selection),cutTextLen<9?cutTextLen:8,
+          cutText, cutTextLen<9?"":"...");
       XVncExtSetServerCutText(dpy, cutText, cutTextLen);
+      // done with this conversion
+      converting = false;
+    }
+    else if (type == None)
+        converting = false;
+  }
+
+  // property update
+  void propertyNotify(XPropertyEvent* ev, Atom type, int format,
+                       int nitems, void* data)
+  {
+    int i = (ev->atom == XA_PRIMARY ? 0 : 1);
+
+    if (ev->window != win() || (ev->atom != XA_PRIMARY && ev->atom != xaCLIPBOARD))
+      return;
+
+    if (type == xaINCR) {
+      // switch to incremental mode
+      if (selection[i])
+      {
+        delete [] selection[i];
+        selection[i] = 0;
+      }
+      selectionLen[i] = 0;
+      incremental[i] = true;
+      return;
+    }
+
+    if (format == 8 ) {
+      // continued?
+      if (data && nitems) {
+        char * newselection = new char[selectionLen[i] + nitems];
+
+        if (selection[i])
+        {
+          if (incremental[i])
+            memcpy(newselection, selection[i], selectionLen[i]);
+          else
+            selectionLen[i] = 0;
+          delete [] selection[i];
+        }
+
+        memcpy(newselection + selectionLen[i], data, nitems);
+        selection[i] = newselection;
+        selectionLen[i] += nitems;
+      } else {
+        // end of mode
+        incremental[i] = false;
+      }
+
+      if (!incremental[i]) {
+        if (cutText)
+          XFree(cutText);
+        cutText = (char*)malloc(selectionLen[i]); // assuming XFree() same as free()
+        memcpy(cutText, selection[i], selectionLen[i]);
+        cutTextLen = selectionLen[i];
+
+        vlog.debug("sending %s selection as server cut text: '%.*s%s'",
+            selectionName(ev->atom),cutTextLen<9?cutTextLen:8,
+            cutText, cutTextLen<9?"":"...");
+        XVncExtSetServerCutText(dpy, cutText, cutTextLen);
+        // done with this conversion
+        converting = false;
+      }
     }
   }
 
@@ -265,6 +355,8 @@
   int cutTextLen;
   char* selection[2];
   int selectionLen[2];
+  bool incremental[2];
+  bool converting;
   TXCheckbox acceptClipboard, sendClipboard, sendPrimaryCB;
   rfb::Timer pollTimer;
 
diff -ur tigervnc-1.0.90-20100115svn3945.ori/unix/vncconfig/vncExt.c tigervnc-1.0.90-20100115svn3945/unix/vncconfig/vncExt.c
--- tigervnc-1.0.90-20100115svn3945.ori/unix/vncconfig/vncExt.c	2006-05-18 13:08:21.000000000 +0200
+++ tigervnc-1.0.90-20100115svn3945/unix/vncconfig/vncExt.c	2011-09-16 19:16:54.390851131 +0200
@@ -208,6 +208,7 @@
 Bool XVncExtSetServerCutText(Display* dpy, const char* str, int len)
 {
   xVncExtSetServerCutTextReq* req;
+  int words;
 
   if (!checkExtension(dpy)) return False;
 
@@ -215,8 +216,9 @@
   GetReq(VncExtSetServerCutText, req);
   req->reqType = codes->major_opcode;
   req->vncExtReqType = X_VncExtSetServerCutText;
-  req->length += (len + 3) >> 2;
   req->textLen = len;
+  words = (len + 3) >> 2;
+  SetReqLen(req, words, 0);
   Data(dpy, str, len);
   UnlockDisplay(dpy);
   SyncHandle();
