Do explict sync after XShmPutImage()

The complex logic waiting for events didn't result in any added
performance, so use the simpler approach.
diff --git a/tests/fbperf.cxx b/tests/fbperf.cxx
index 53334a6..4759a2f 100644
--- a/tests/fbperf.cxx
+++ b/tests/fbperf.cxx
@@ -136,9 +136,6 @@
 
   startTimeCounter();
 
-  while (fb->isRendering())
-    Fl::wait();
-
   changefb();
 
   r = fb->getDamage();
diff --git a/vncviewer/CConn.cxx b/vncviewer/CConn.cxx
index baf01d4..cc35626 100644
--- a/vncviewer/CConn.cxx
+++ b/vncviewer/CConn.cxx
@@ -346,9 +346,6 @@
 // one.
 void CConn::framebufferUpdateStart()
 {
-  ModifiablePixelBuffer* pb;
-  PlatformPixelBuffer* ppb;
-
   CConnection::framebufferUpdateStart();
 
   // Note: This might not be true if sync fences are supported
@@ -356,22 +353,6 @@
 
   requestNewUpdate();
 
-  // We might still be rendering the previous update
-  pb = getFramebuffer();
-  assert(pb != NULL);
-  ppb = dynamic_cast<PlatformPixelBuffer*>(pb);
-  assert(ppb != NULL);
-  if (ppb->isRendering()) {
-    // Need to stop monitoring the socket or we'll just busy loop
-    assert(sock != NULL);
-    Fl::remove_fd(sock->getFd());
-
-    while (ppb->isRendering())
-      run_mainloop();
-
-    Fl::add_fd(sock->getFd(), FL_READ | FL_EXCEPT, socketEvent, this);
-  }
-
   // Update the screen prematurely for very slow updates
   Fl::add_timeout(1.0, handleUpdateTimeout, this);
 }
diff --git a/vncviewer/PlatformPixelBuffer.cxx b/vncviewer/PlatformPixelBuffer.cxx
index 876ab94..522bad3 100644
--- a/vncviewer/PlatformPixelBuffer.cxx
+++ b/vncviewer/PlatformPixelBuffer.cxx
@@ -44,8 +44,3 @@
 
   return r;
 }
-
-bool PlatformPixelBuffer::isRendering(void)
-{
-  return false;
-}
diff --git a/vncviewer/PlatformPixelBuffer.h b/vncviewer/PlatformPixelBuffer.h
index 9f0e3b1..795273a 100644
--- a/vncviewer/PlatformPixelBuffer.h
+++ b/vncviewer/PlatformPixelBuffer.h
@@ -34,8 +34,6 @@
   virtual void draw(int src_x, int src_y, int x, int y, int w, int h) = 0;
   rfb::Rect getDamage(void);
 
-  virtual bool isRendering(void);
-
 protected:
   os::Mutex mutex;
   rfb::Region damage;
diff --git a/vncviewer/X11PixelBuffer.cxx b/vncviewer/X11PixelBuffer.cxx
index a1d7687..4f52cad 100644
--- a/vncviewer/X11PixelBuffer.cxx
+++ b/vncviewer/X11PixelBuffer.cxx
@@ -37,8 +37,6 @@
 
 static rfb::LogWriter vlog("X11PixelBuffer");
 
-std::list<X11PixelBuffer*> X11PixelBuffer::shmList;
-
 static PixelFormat display_pf()
 {
   int i;
@@ -101,7 +99,7 @@
 
 X11PixelBuffer::X11PixelBuffer(int width, int height) :
   PlatformPixelBuffer(display_pf(), width, height, NULL, 0),
-  shminfo(NULL), xim(NULL), pendingPutImage(0), pendingDrawable(0)
+  shminfo(NULL), xim(NULL)
 {
   // Might not be open at this point
   fl_open_display();
@@ -128,8 +126,6 @@
 {
   if (shminfo) {
     vlog.debug("Freeing shared memory XImage");
-    shmList.remove(this);
-    Fl::remove_system_handler(handleSystemEvent);
     shmdt(shminfo->shmaddr);
     shmctl(shminfo->shmid, IPC_RMID, 0);
     delete shminfo;
@@ -146,20 +142,15 @@
 void X11PixelBuffer::draw(int src_x, int src_y, int x, int y, int w, int h)
 {
   if (shminfo) {
-    XShmPutImage(fl_display, fl_window, fl_gc, xim, src_x, src_y, x, y, w, h, True);
-    pendingPutImage++;
-    assert((pendingPutImage == 1) || (pendingDrawable == fl_window));
-    pendingDrawable = fl_window;
+    XShmPutImage(fl_display, fl_window, fl_gc, xim, src_x, src_y, x, y, w, h, False);
+    // Need to make sure the X server has finished reading the
+    // shared memory before we return
+    XSync(fl_display, False);
   } else {
     XPutImage(fl_display, fl_window, fl_gc, xim, src_x, src_y, x, y, w, h);
   }
 }
 
-bool X11PixelBuffer::isRendering(void)
-{
-  return pendingPutImage > 0;
-}
-
 static bool caughtError;
 
 static int XShmAttachErrorHandler(Display *dpy, XErrorEvent *error)
@@ -218,11 +209,6 @@
   if (caughtError)
     goto free_shmaddr;
 
-  // FLTK is a bit stupid and unreliable if you register the same
-  // callback with different data values.
-  Fl::add_system_handler(handleSystemEvent, NULL);
-  shmList.push_back(this);
-
   vlog.debug("Using shared memory XImage");
 
   return 1;
@@ -243,39 +229,3 @@
 
   return 0;
 }
-
-int X11PixelBuffer::handleSystemEvent(void* event, void* data)
-{
-  XEvent* xevent;
-  XShmCompletionEvent* shmevent;
-
-  std::list<X11PixelBuffer*>::iterator iter;
-
-  xevent = (XEvent*)event;
-  assert(xevent);
-
-  if (xevent->type != XShmGetEventBase(fl_display) + ShmCompletion)
-    return 0;
-
-  shmevent = (XShmCompletionEvent*)event;
-
-  if (shmevent->send_event)
-    return 0;
-
-  for (iter = shmList.begin();iter != shmList.end();++iter) {
-    if (shmevent->shmseg != (*iter)->shminfo->shmseg)
-      continue;
-
-    /* HP has a buggy X server on their thin clients that sends bogus
-     * extra events with an incorrect drawable id */
-    if (shmevent->drawable != (*iter)->pendingDrawable)
-      continue;
-
-    (*iter)->pendingPutImage--;
-    assert((*iter)->pendingPutImage >= 0);
-
-    return 1;
-  }
-
-  return 0;
-}
diff --git a/vncviewer/X11PixelBuffer.h b/vncviewer/X11PixelBuffer.h
index a616672..fdd88b7 100644
--- a/vncviewer/X11PixelBuffer.h
+++ b/vncviewer/X11PixelBuffer.h
@@ -35,20 +35,12 @@
 
   virtual void draw(int src_x, int src_y, int x, int y, int w, int h);
 
-  virtual bool isRendering(void);
-
 protected:
   int setupShm();
 
-  static int handleSystemEvent(void* event, void* data);
-
 protected:
   XShmSegmentInfo *shminfo;
   XImage *xim;
-  int pendingPutImage;
-  Drawable pendingDrawable;
-
-  static std::list<X11PixelBuffer*> shmList;
 };