From fd96c5e835cfb64e454e189e4b481b0a7292f5e3 Mon Sep 17 00:00:00 2001
From: dscho <dscho>
Date: Sun, 9 Feb 2003 17:20:15 +0000
Subject: renamed sraRegion to rfbregion and put it in include/; will be
 installed now

---
 Makefile.am           |   7 +-
 examples/Makefile.am  |   2 +-
 examples/regiontest.c |   3 +
 examples/sratest.c    |   2 -
 include/rfbregion.h   |  60 ++++
 main.c                |   2 +-
 rfbregion.c           | 826 ++++++++++++++++++++++++++++++++++++++++++++++++++
 rfbserver.c           |   2 +-
 sraRegion.c           | 826 --------------------------------------------------
 sraRegion.h           |  60 ----
 translate.c           |   2 +-
 11 files changed, 896 insertions(+), 896 deletions(-)
 create mode 100644 examples/regiontest.c
 delete mode 100644 examples/sratest.c
 create mode 100755 include/rfbregion.h
 create mode 100755 rfbregion.c
 delete mode 100755 sraRegion.c
 delete mode 100755 sraRegion.h

diff --git a/Makefile.am b/Makefile.am
index 5390433..2981f51 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -4,10 +4,9 @@ DIST_SUBDIRS=examples contrib
 bin_SCRIPTS = libvncserver-config
 
 include_HEADERS=include/rfb.h include/rfbconfig.h include/rfbint.h include/rfbproto.h \
-	include/keysym.h
+	include/keysym.h include/rfbregion.h
 
-noinst_HEADERS=sraRegion.h d3des.h zrleDecode.h zrleEncode.h \
-	include/default8x16.h \
+noinst_HEADERS=d3des.h zrleDecode.h zrleEncode.h include/default8x16.h \
 	rdr/Exception.h rdr/FdInStream.h rdr/FdOutStream.h \
 	rdr/FixedMemOutStream.h rdr/InStream.h rdr/MemInStream.h \
 	rdr/MemOutStream.h rdr/NullOutStream.h rdr/OutStream.h \
@@ -19,7 +18,7 @@ ZRLE_SRCS=zrle.cxx rdr/FdInStream.cxx rdr/FdOutStream.cxx rdr/InStream.cxx \
 EXTRA_DIST=tableinit24.c tableinittctemplate.c tabletranstemplate.c \
 	tableinitcmtemplate.c tabletrans24template.c $(ZRLE_SRCS)
 
-LIB_SRCS = main.c rfbserver.c sraRegion.c auth.c sockets.c \
+LIB_SRCS = main.c rfbserver.c rfbregion.c auth.c sockets.c \
 	stats.c corre.c hextile.c rre.c translate.c cutpaste.c \
 	zlib.c tight.c httpd.c cursor.c font.c \
 	draw.c selbox.c d3des.c vncauth.c cargs.c
diff --git a/examples/Makefile.am b/examples/Makefile.am
index 98a4647..4dc1498 100644
--- a/examples/Makefile.am
+++ b/examples/Makefile.am
@@ -4,7 +4,7 @@ endif
 
 noinst_HEADERS=radon.h
 
-noinst_PROGRAMS=example pnmshow sratest pnmshow24 fontsel \
+noinst_PROGRAMS=example pnmshow regiontest pnmshow24 fontsel \
 	vncev storepasswd $(BACKGROUND_TEST)
 
 LDADD = -L.. -lvncserver
diff --git a/examples/regiontest.c b/examples/regiontest.c
new file mode 100644
index 0000000..176fd26
--- /dev/null
+++ b/examples/regiontest.c
@@ -0,0 +1,3 @@
+#define SRA_TEST
+#include "../rfbregion.c"
+
diff --git a/examples/sratest.c b/examples/sratest.c
deleted file mode 100644
index faa2218..0000000
--- a/examples/sratest.c
+++ /dev/null
@@ -1,2 +0,0 @@
-#define SRA_TEST
-#include "../sraRegion.c"
diff --git a/include/rfbregion.h b/include/rfbregion.h
new file mode 100755
index 0000000..1bbedf6
--- /dev/null
+++ b/include/rfbregion.h
@@ -0,0 +1,60 @@
+#ifndef SRAREGION_H
+#define SRAREGION_H
+
+/* -=- SRA - Simple Region Algorithm
+ * A simple rectangular region implementation.
+ * Copyright (c) 2001 James "Wez" Weatherall, Johannes E. Schindelin
+ */
+
+/* -=- sraRect */
+
+typedef struct _rect {
+	int x1;
+	int y1;
+	int x2;
+	int y2;
+} sraRect;
+
+typedef struct sraRegion sraRegion;
+
+/* -=- Region manipulation functions */
+
+extern sraRegion *sraRgnCreate();
+extern sraRegion *sraRgnCreateRect(int x1, int y1, int x2, int y2);
+extern sraRegion *sraRgnCreateRgn(const sraRegion *src);
+
+extern void sraRgnDestroy(sraRegion *rgn);
+extern void sraRgnMakeEmpty(sraRegion *rgn);
+extern Bool sraRgnAnd(sraRegion *dst, const sraRegion *src);
+extern void sraRgnOr(sraRegion *dst, const sraRegion *src);
+extern Bool sraRgnSubtract(sraRegion *dst, const sraRegion *src);
+
+extern void sraRgnOffset(sraRegion *dst, int dx, int dy);
+
+extern Bool sraRgnPopRect(sraRegion *region, sraRect *rect,
+			  unsigned long flags);
+
+extern unsigned long sraRgnCountRects(const sraRegion *rgn);
+extern Bool sraRgnEmpty(const sraRegion *rgn);
+
+/* -=- rectangle iterator */
+
+typedef struct sraRectangleIterator {
+  Bool reverseX,reverseY;
+  int ptrSize,ptrPos;
+  struct sraSpan** sPtrs;
+} sraRectangleIterator;
+
+extern sraRectangleIterator *sraRgnGetIterator(sraRegion *s);
+extern sraRectangleIterator *sraRgnGetReverseIterator(sraRegion *s,Bool reverseX,Bool reverseY);
+extern Bool sraRgnIteratorNext(sraRectangleIterator *i,sraRect *r);
+extern void sraRgnReleaseIterator(sraRectangleIterator *i);
+
+void sraRgnPrint(const sraRegion *s);
+
+/* -=- Rectangle clipper (for speed) */
+
+extern Bool sraClipRect(int *x, int *y, int *w, int *h,
+			int cx, int cy, int cw, int ch);
+
+#endif
diff --git a/main.c b/main.c
index f56199c..340be3b 100644
--- a/main.c
+++ b/main.c
@@ -11,7 +11,7 @@
  */
 
 #include "rfb.h"
-#include "sraRegion.h"
+#include "rfbregion.h"
 
 #include <stdarg.h>
 #include <errno.h>
diff --git a/rfbregion.c b/rfbregion.c
new file mode 100755
index 0000000..59b76c5
--- /dev/null
+++ b/rfbregion.c
@@ -0,0 +1,826 @@
+/* -=- sraRegion.c
+ * Copyright (c) 2001 James "Wez" Weatherall, Johannes E. Schindelin
+ *
+ * A general purpose region clipping library
+ * Only deals with rectangular regions, though.
+ */
+
+#include "rfb.h"
+#include "rfbregion.h"
+
+/* -=- Internal Span structure */
+
+struct sraRegion;
+
+typedef struct sraSpan {
+  struct sraSpan *_next;
+  struct sraSpan *_prev;
+  int start;
+  int end;
+  struct sraRegion *subspan;
+} sraSpan;
+
+typedef struct sraRegion {
+  sraSpan front;
+  sraSpan back;
+} sraSpanList;
+
+/* -=- Span routines */
+
+sraSpanList *sraSpanListDup(const sraSpanList *src);
+void sraSpanListDestroy(sraSpanList *list);
+
+sraSpan *
+sraSpanCreate(int start, int end, const sraSpanList *subspan) {
+  sraSpan *item = (sraSpan*)malloc(sizeof(sraSpan));
+  item->_next = item->_prev = NULL;
+  item->start = start;
+  item->end = end;
+  item->subspan = sraSpanListDup(subspan);
+  return item;
+}
+
+sraSpan *
+sraSpanDup(const sraSpan *src) {
+  sraSpan *span;
+  if (!src) return NULL;
+  span = sraSpanCreate(src->start, src->end, src->subspan);
+  return span;
+}
+
+void
+sraSpanInsertAfter(sraSpan *newspan, sraSpan *after) {
+  newspan->_next = after->_next;
+  newspan->_prev = after;
+  after->_next->_prev = newspan;
+  after->_next = newspan;
+}
+
+void
+sraSpanInsertBefore(sraSpan *newspan, sraSpan *before) {
+  newspan->_next = before;
+  newspan->_prev = before->_prev;
+  before->_prev->_next = newspan;
+  before->_prev = newspan;
+}
+
+void
+sraSpanRemove(sraSpan *span) {
+  span->_prev->_next = span->_next;
+  span->_next->_prev = span->_prev;
+}
+
+void
+sraSpanDestroy(sraSpan *span) {
+  if (span->subspan) sraSpanListDestroy(span->subspan);
+  free(span);
+}
+
+void
+sraSpanCheck(const sraSpan *span, const char *text) {
+  /* Check the span is valid! */
+  if (span->start == span->end) {
+    printf(text); 
+    printf(":%d-%d\n", span->start, span->end);
+    exit(0);
+  }
+}
+
+/* -=- SpanList routines */
+
+void sraSpanPrint(const sraSpan *s);
+
+void
+sraSpanListPrint(const sraSpanList *l) {
+  sraSpan *curr;
+  if (!l) {
+	  printf("NULL");
+	  return;
+  }
+  curr = l->front._next;
+  printf("[");
+  while (curr != &(l->back)) {
+    sraSpanPrint(curr);
+    curr = curr->_next;
+  }
+  printf("]");
+}
+
+void
+sraSpanPrint(const sraSpan *s) {
+  printf("(%d-%d)", (s->start), (s->end));
+  if (s->subspan)
+    sraSpanListPrint(s->subspan);
+}
+
+sraSpanList *
+sraSpanListCreate() {
+  sraSpanList *item = (sraSpanList*)malloc(sizeof(sraSpanList));
+  item->front._next = &(item->back);
+  item->front._prev = NULL;
+  item->back._prev = &(item->front);
+  item->back._next = NULL;
+  return item;
+}
+
+sraSpanList *
+sraSpanListDup(const sraSpanList *src) {
+  sraSpanList *newlist;
+  sraSpan *newspan, *curr;
+
+  if (!src) return NULL;
+  newlist = sraSpanListCreate();
+  curr = src->front._next;
+  while (curr != &(src->back)) {
+    newspan = sraSpanDup(curr);
+    sraSpanInsertBefore(newspan, &(newlist->back));
+    curr = curr->_next;
+  }
+
+  return newlist;
+}
+
+void
+sraSpanListDestroy(sraSpanList *list) {
+  sraSpan *curr, *next;
+  while (list->front._next != &(list->back)) {
+    curr = list->front._next;
+    next = curr->_next;
+    sraSpanRemove(curr);
+    sraSpanDestroy(curr);
+    curr = next;
+  }
+  free(list);
+}
+
+void
+sraSpanListMakeEmpty(sraSpanList *list) {
+  sraSpan *curr, *next;
+  while (list->front._next != &(list->back)) {
+    curr = list->front._next;
+    next = curr->_next;
+    sraSpanRemove(curr);
+    sraSpanDestroy(curr);
+    curr = next;
+  }
+  list->front._next = &(list->back);
+  list->front._prev = NULL;
+  list->back._prev = &(list->front);
+  list->back._next = NULL;
+}
+
+Bool
+sraSpanListEqual(const sraSpanList *s1, const sraSpanList *s2) {
+  sraSpan *sp1, *sp2;
+
+  if (!s1) {
+    if (!s2) {
+      return 1;
+    } else {
+      printf("sraSpanListEqual:incompatible spans (only one NULL!)\n");
+      exit(1);
+    }
+  }
+
+  sp1 = s1->front._next;
+  sp2 = s2->front._next;
+  while ((sp1 != &(s1->back)) &&
+	 (sp2 != &(s2->back))) {
+    if ((sp1->start != sp2->start) ||
+	(sp1->end != sp2->end) ||
+	(!sraSpanListEqual(sp1->subspan, sp2->subspan))) {
+      return 0;
+    }
+    sp1 = sp1->_next;
+    sp2 = sp2->_next;
+  }
+
+  if ((sp1 == &(s1->back)) && (sp2 == &(s2->back))) {
+    return 1;
+  } else {
+    return 0;
+  }    
+}
+
+Bool
+sraSpanListEmpty(const sraSpanList *list) {
+  return (list->front._next == &(list->back));
+}
+
+unsigned long
+sraSpanListCount(const sraSpanList *list) {
+  sraSpan *curr = list->front._next;
+  unsigned long count = 0;
+  while (curr != &(list->back)) {
+    if (curr->subspan) {
+      count += sraSpanListCount(curr->subspan);
+    } else {
+      count += 1;
+    }
+    curr = curr->_next;
+  }
+  return count;
+}
+
+void
+sraSpanMergePrevious(sraSpan *dest) {
+  sraSpan *prev = dest->_prev;
+  while ((prev->end == dest->start) &&
+	 (prev->_prev) &&
+	 (sraSpanListEqual(prev->subspan, dest->subspan))) {
+    /*
+    printf("merge_prev:");
+    sraSpanPrint(prev);
+    printf(" & ");
+    sraSpanPrint(dest);
+    printf("\n");
+    */
+    dest->start = prev->start;
+    sraSpanRemove(prev);
+    sraSpanDestroy(prev);
+    prev = dest->_prev;
+  }
+}    
+
+void
+sraSpanMergeNext(sraSpan *dest) {
+  sraSpan *next = dest->_next;
+  while ((next->start == dest->end) &&
+	 (next->_next) &&
+	 (sraSpanListEqual(next->subspan, dest->subspan))) {
+/*
+	  printf("merge_next:");
+    sraSpanPrint(dest);
+    printf(" & ");
+    sraSpanPrint(next);
+    printf("\n");
+	*/
+    dest->end = next->end;
+    sraSpanRemove(next);
+    sraSpanDestroy(next);
+    next = dest->_next;
+  }
+}
+
+void
+sraSpanListOr(sraSpanList *dest, const sraSpanList *src) {
+  sraSpan *d_curr, *s_curr;
+  int s_start, s_end;
+
+  if (!dest) {
+    if (!src) {
+      return;
+    } else {
+      printf("sraSpanListOr:incompatible spans (only one NULL!)\n");
+      exit(1);
+    }
+  }
+
+  d_curr = dest->front._next;
+  s_curr = src->front._next;
+  s_start = s_curr->start;
+  s_end = s_curr->end;
+  while (s_curr != &(src->back)) {
+
+    /* - If we are at end of destination list OR
+       If the new span comes before the next destination one */
+    if ((d_curr == &(dest->back)) ||
+		(d_curr->start >= s_end)) {
+      /* - Add the span */
+      sraSpanInsertBefore(sraSpanCreate(s_start, s_end,
+					s_curr->subspan),
+			  d_curr);
+      if (d_curr != &(dest->back))
+	sraSpanMergePrevious(d_curr);
+      s_curr = s_curr->_next;
+      s_start = s_curr->start;
+      s_end = s_curr->end;
+    } else {
+
+      /* - If the new span overlaps the existing one */
+      if ((s_start < d_curr->end) &&
+	  (s_end > d_curr->start)) {
+
+	/* - Insert new span before the existing destination one? */
+	if (s_start < d_curr->start) {
+	  sraSpanInsertBefore(sraSpanCreate(s_start,
+					    d_curr->start,
+					    s_curr->subspan),
+			      d_curr);
+	  sraSpanMergePrevious(d_curr);
+	}
+
+	/* Split the existing span if necessary */
+	if (s_end < d_curr->end) {
+	  sraSpanInsertAfter(sraSpanCreate(s_end,
+					   d_curr->end,
+					   d_curr->subspan),
+			     d_curr);
+	  d_curr->end = s_end;
+	}
+	if (s_start > d_curr->start) {
+	  sraSpanInsertBefore(sraSpanCreate(d_curr->start,
+					    s_start,
+					    d_curr->subspan),
+			      d_curr);
+	  d_curr->start = s_start;
+	}
+
+	/* Recursively OR subspans */
+	sraSpanListOr(d_curr->subspan, s_curr->subspan);
+
+	/* Merge this span with previous or next? */
+	if (d_curr->_prev != &(dest->front))
+	  sraSpanMergePrevious(d_curr);
+	if (d_curr->_next != &(dest->back))
+	  sraSpanMergeNext(d_curr);
+
+	/* Move onto the next pair to compare */
+	if (s_end > d_curr->end) {
+	  s_start = d_curr->end;
+	  d_curr = d_curr->_next;
+	} else {
+	  s_curr = s_curr->_next;
+	  s_start = s_curr->start;
+	  s_end = s_curr->end;
+	}
+      } else {
+	/* - No overlap.  Move to the next destination span */
+	d_curr = d_curr->_next;
+      }
+    }
+  }
+}
+
+Bool
+sraSpanListAnd(sraSpanList *dest, const sraSpanList *src) {
+  sraSpan *d_curr, *s_curr, *d_next;
+
+  if (!dest) {
+    if (!src) {
+      return 1;
+    } else {
+      printf("sraSpanListAnd:incompatible spans (only one NULL!)\n");
+      exit(1);
+    }
+  }
+
+  d_curr = dest->front._next;
+  s_curr = src->front._next;
+  while ((s_curr != &(src->back)) && (d_curr != &(dest->back))) {
+
+    /* - If we haven't reached a destination span yet then move on */
+    if (d_curr->start >= s_curr->end) {
+      s_curr = s_curr->_next;
+      continue;
+    }
+
+    /* - If we are beyond the current destination span then remove it */
+    if (d_curr->end <= s_curr->start) {
+      sraSpan *next = d_curr->_next;
+      sraSpanRemove(d_curr);
+      sraSpanDestroy(d_curr);
+      d_curr = next;
+      continue;
+    }
+
+    /* - If we partially overlap a span then split it up or remove bits */
+    if (s_curr->start > d_curr->start) {
+      /* - The top bit of the span does not match */
+      d_curr->start = s_curr->start;
+    }
+    if (s_curr->end < d_curr->end) {
+      /* - The end of the span does not match */
+      sraSpanInsertAfter(sraSpanCreate(s_curr->end,
+				       d_curr->end,
+				       d_curr->subspan),
+			 d_curr);
+      d_curr->end = s_curr->end;
+    }
+
+    /* - Now recursively process the affected span */
+    if (!sraSpanListAnd(d_curr->subspan, s_curr->subspan)) {
+      /* - The destination subspan is now empty, so we should remove it */
+		sraSpan *next = d_curr->_next;
+      sraSpanRemove(d_curr);
+      sraSpanDestroy(d_curr);
+      d_curr = next;
+    } else {
+      /* Merge this span with previous or next? */
+      if (d_curr->_prev != &(dest->front))
+	sraSpanMergePrevious(d_curr);
+
+      /* - Move on to the next span */
+      d_next = d_curr;
+      if (s_curr->end >= d_curr->end) {
+	d_next = d_curr->_next;
+      }
+      if (s_curr->end <= d_curr->end) {
+	s_curr = s_curr->_next;
+      }
+      d_curr = d_next;
+    }
+  }
+
+  while (d_curr != &(dest->back)) {
+    sraSpan *next = d_curr->_next;
+    sraSpanRemove(d_curr);
+    sraSpanDestroy(d_curr);
+    d_curr=next;
+  }
+
+  return !sraSpanListEmpty(dest);
+}
+
+Bool
+sraSpanListSubtract(sraSpanList *dest, const sraSpanList *src) {
+  sraSpan *d_curr, *s_curr;
+
+  if (!dest) {
+    if (!src) {
+      return 1;
+    } else {
+      printf("sraSpanListSubtract:incompatible spans (only one NULL!)\n");
+      exit(1);
+    }
+  }
+
+  d_curr = dest->front._next;
+  s_curr = src->front._next;
+  while ((s_curr != &(src->back)) && (d_curr != &(dest->back))) {
+
+    /* - If we haven't reached a destination span yet then move on */
+    if (d_curr->start >= s_curr->end) {
+      s_curr = s_curr->_next;
+      continue;
+    }
+
+    /* - If we are beyond the current destination span then skip it */
+    if (d_curr->end <= s_curr->start) {
+      d_curr = d_curr->_next;
+      continue;
+    }
+
+    /* - If we partially overlap the current span then split it up */
+    if (s_curr->start > d_curr->start) {
+      sraSpanInsertBefore(sraSpanCreate(d_curr->start,
+					s_curr->start,
+					d_curr->subspan),
+			  d_curr);
+      d_curr->start = s_curr->start;
+    }
+    if (s_curr->end < d_curr->end) {
+      sraSpanInsertAfter(sraSpanCreate(s_curr->end,
+				       d_curr->end,
+				       d_curr->subspan),
+			 d_curr);
+      d_curr->end = s_curr->end;
+    }
+
+    /* - Now recursively process the affected span */
+    if ((!d_curr->subspan) || !sraSpanListSubtract(d_curr->subspan, s_curr->subspan)) {
+      /* - The destination subspan is now empty, so we should remove it */
+      sraSpan *next = d_curr->_next;
+      sraSpanRemove(d_curr);
+      sraSpanDestroy(d_curr);
+      d_curr = next;
+    } else {
+      /* Merge this span with previous or next? */
+      if (d_curr->_prev != &(dest->front))
+	sraSpanMergePrevious(d_curr);
+      if (d_curr->_next != &(dest->back))
+	sraSpanMergeNext(d_curr);
+
+      /* - Move on to the next span */
+      if (s_curr->end > d_curr->end) {
+	d_curr = d_curr->_next;
+      } else {
+	s_curr = s_curr->_next;
+      }
+    }
+  }
+
+  return !sraSpanListEmpty(dest);
+}
+
+/* -=- Region routines */
+
+sraRegion *
+sraRgnCreate() {
+  return (sraRegion*)sraSpanListCreate();
+}
+
+sraRegion *
+sraRgnCreateRect(int x1, int y1, int x2, int y2) {
+  sraSpanList *vlist, *hlist;
+  sraSpan *vspan, *hspan;
+
+  /* - Build the horizontal portion of the span */
+  hlist = sraSpanListCreate();
+  hspan = sraSpanCreate(x1, x2, NULL);
+  sraSpanInsertAfter(hspan, &(hlist->front));
+
+  /* - Build the vertical portion of the span */
+  vlist = sraSpanListCreate();
+  vspan = sraSpanCreate(y1, y2, hlist);
+  sraSpanInsertAfter(vspan, &(vlist->front));
+
+  sraSpanListDestroy(hlist);
+
+  return (sraRegion*)vlist;
+}
+
+sraRegion *
+sraRgnCreateRgn(const sraRegion *src) {
+  return (sraRegion*)sraSpanListDup((sraSpanList*)src);
+}
+
+void
+sraRgnDestroy(sraRegion *rgn) {
+  sraSpanListDestroy((sraSpanList*)rgn);
+}
+
+void
+sraRgnMakeEmpty(sraRegion *rgn) {
+  sraSpanListMakeEmpty((sraSpanList*)rgn);
+}
+
+/* -=- Boolean Region ops */
+
+Bool
+sraRgnAnd(sraRegion *dst, const sraRegion *src) {
+  return sraSpanListAnd((sraSpanList*)dst, (sraSpanList*)src);
+}
+
+void
+sraRgnOr(sraRegion *dst, const sraRegion *src) {
+  sraSpanListOr((sraSpanList*)dst, (sraSpanList*)src);
+}
+
+Bool
+sraRgnSubtract(sraRegion *dst, const sraRegion *src) {
+  return sraSpanListSubtract((sraSpanList*)dst, (sraSpanList*)src);
+}
+
+void
+sraRgnOffset(sraRegion *dst, int dx, int dy) {
+  sraSpan *vcurr, *hcurr;
+
+  vcurr = ((sraSpanList*)dst)->front._next;
+  while (vcurr != &(((sraSpanList*)dst)->back)) {
+    vcurr->start += dy;
+    vcurr->end += dy;
+    
+    hcurr = vcurr->subspan->front._next;
+    while (hcurr != &(vcurr->subspan->back)) {
+      hcurr->start += dx;
+      hcurr->end += dx;
+      hcurr = hcurr->_next;
+    }
+
+    vcurr = vcurr->_next;
+  }
+}
+
+Bool
+sraRgnPopRect(sraRegion *rgn, sraRect *rect, unsigned long flags) {
+  sraSpan *vcurr, *hcurr;
+  sraSpan *vend, *hend;
+  Bool right2left = flags & 2;
+  Bool bottom2top = flags & 1;
+
+  /* - Pick correct order */
+  if (bottom2top) {
+    vcurr = ((sraSpanList*)rgn)->back._prev;
+    vend = &(((sraSpanList*)rgn)->front);
+  } else {
+    vcurr = ((sraSpanList*)rgn)->front._next;
+    vend = &(((sraSpanList*)rgn)->back);
+  }
+
+  if (vcurr != vend) {
+    rect->y1 = vcurr->start;
+    rect->y2 = vcurr->end;
+
+    /* - Pick correct order */
+    if (right2left) {
+      hcurr = vcurr->subspan->back._prev;
+      hend = &(vcurr->subspan->front);
+    } else {
+      hcurr = vcurr->subspan->front._next;
+      hend = &(vcurr->subspan->back);
+    }
+
+    if (hcurr != hend) {
+      rect->x1 = hcurr->start;
+      rect->x2 = hcurr->end;
+
+      sraSpanRemove(hcurr);
+      sraSpanDestroy(hcurr);
+      
+      if (sraSpanListEmpty(vcurr->subspan)) {
+	sraSpanRemove(vcurr);
+	sraSpanDestroy(vcurr);
+      }
+
+#if 0
+      printf("poprect:(%dx%d)-(%dx%d)\n",
+	     rect->x1, rect->y1, rect->x2, rect->y2);
+#endif
+      return 1;
+    }
+  }
+
+  return 0;
+}
+
+unsigned long
+sraRgnCountRects(const sraRegion *rgn) {
+  unsigned long count = sraSpanListCount((sraSpanList*)rgn);
+  return count;
+}
+
+Bool
+sraRgnEmpty(const sraRegion *rgn) {
+  return sraSpanListEmpty((sraSpanList*)rgn);
+}
+
+/* iterator stuff */
+sraRectangleIterator *sraRgnGetIterator(sraRegion *s)
+{
+  /* these values have to be multiples of 4 */
+#define DEFSIZE 4
+#define DEFSTEP 8
+  sraRectangleIterator *i =
+    (sraRectangleIterator*)malloc(sizeof(sraRectangleIterator));
+  if(!i)
+    return(0);
+
+  /* we have to recurse eventually. So, the first sPtr is the pointer to
+     the sraSpan in the first level. the second sPtr is the pointer to
+     the sraRegion.back. The third and fourth sPtr are for the second
+     recursion level and so on. */
+  i->sPtrs = (sraSpan**)malloc(sizeof(sraSpan*)*DEFSIZE);
+  if(!i->sPtrs) {
+    free(i);
+    return(0);
+  }
+  i->ptrSize = DEFSIZE;
+  i->sPtrs[0] = &(s->front);
+  i->sPtrs[1] = &(s->back);
+  i->ptrPos = 0;
+  i->reverseX = 0;
+  i->reverseY = 0;
+  return(i);
+}
+
+sraRectangleIterator *sraRgnGetReverseIterator(sraRegion *s,Bool reverseX,Bool reverseY)
+{
+  sraRectangleIterator *i = sraRgnGetIterator(s);
+  if(reverseY) {
+    i->sPtrs[1] = &(s->front);
+    i->sPtrs[0] = &(s->back);
+  }
+  i->reverseX = reverseX;
+  i->reverseY = reverseY;
+  return(i);
+}
+
+Bool sraReverse(sraRectangleIterator *i)
+{
+  return( ((i->ptrPos&2) && i->reverseX) ||
+     (!(i->ptrPos&2) && i->reverseY));
+}
+
+sraSpan* sraNextSpan(sraRectangleIterator *i)
+{
+  if(sraReverse(i))
+    return(i->sPtrs[i->ptrPos]->_prev);
+  else
+    return(i->sPtrs[i->ptrPos]->_next);
+}
+
+Bool sraRgnIteratorNext(sraRectangleIterator* i,sraRect* r)
+{
+  /* is the subspan finished? */
+  while(sraNextSpan(i) == i->sPtrs[i->ptrPos+1]) {
+    i->ptrPos -= 2;
+    if(i->ptrPos < 0) /* the end */
+      return(0);
+  }
+
+  i->sPtrs[i->ptrPos] = sraNextSpan(i);
+
+  /* is this a new subspan? */
+  while(i->sPtrs[i->ptrPos]->subspan) {
+    if(i->ptrPos+2 > i->ptrSize) { /* array is too small */
+      i->ptrSize += DEFSTEP;
+      i->sPtrs = (sraSpan**)realloc(i->sPtrs, sizeof(sraSpan*)*i->ptrSize);
+    }
+    i->ptrPos =+ 2;
+    if(sraReverse(i)) {
+      i->sPtrs[i->ptrPos]   =   i->sPtrs[i->ptrPos-2]->subspan->back._prev;
+      i->sPtrs[i->ptrPos+1] = &(i->sPtrs[i->ptrPos-2]->subspan->front);
+    } else {
+      i->sPtrs[i->ptrPos]   =   i->sPtrs[i->ptrPos-2]->subspan->front._next;
+      i->sPtrs[i->ptrPos+1] = &(i->sPtrs[i->ptrPos-2]->subspan->back);
+    }
+  }
+
+  if((i->ptrPos%4)!=2) {
+    fprintf(stderr,"sraRgnIteratorNext: offset is wrong (%d%%4!=2)\n",i->ptrPos);
+    exit(-1);
+  }
+
+  r->y1 = i->sPtrs[i->ptrPos-2]->start;
+  r->y2 = i->sPtrs[i->ptrPos-2]->end;
+  r->x1 = i->sPtrs[i->ptrPos]->start;
+  r->x2 = i->sPtrs[i->ptrPos]->end;
+
+  return(-1);
+}
+
+void sraRgnReleaseIterator(sraRectangleIterator* i)
+{
+  free(i->sPtrs);
+  free(i);
+}
+
+void
+sraRgnPrint(const sraRegion *rgn) {
+	sraSpanListPrint((sraSpanList*)rgn);
+}
+
+Bool
+sraClipRect(int *x, int *y, int *w, int *h,
+	    int cx, int cy, int cw, int ch) {
+  if (*x < cx) {
+    *w -= (cx-*x);
+    *x = cx;
+  }
+  if (*y < cy) {
+    *h -= (cy-*y);
+    *y = cy;
+  }
+  if (*x+*w > cx+cw) {
+    *w = (cx+cw)-*x;
+  }
+  if (*y+*h > cy+ch) {
+    *h = (cy+ch)-*y;
+  }
+  return (*w>0) && (*h>0);
+}
+
+/* test */
+
+#ifdef SRA_TEST
+/* pipe the output to sort|uniq -u and you'll get the errors. */
+int main(int argc, char** argv)
+{
+  sraRegionPtr region, region1, region2;
+  sraRectangleIterator* i;
+  sraRect rect;
+  Bool b;
+
+  region = sraRgnCreateRect(10, 10, 600, 300);
+  region1 = sraRgnCreateRect(40, 50, 350, 200);
+  region2 = sraRgnCreateRect(0, 0, 20, 40);
+
+  sraRgnPrint(region);
+  printf("\n[(10-300)[(10-600)]]\n\n");
+
+  b = sraRgnSubtract(region, region1);
+  printf("%s ",b?"true":"false");
+  sraRgnPrint(region);
+  printf("\ntrue [(10-50)[(10-600)](50-200)[(10-40)(350-600)](200-300)[(10-600)]]\n\n");
+
+  sraRgnOr(region, region2);
+  printf("%ld\n6\n\n", sraRgnCountRects(region));
+
+  i = sraRgnGetIterator(region);
+  while(sraRgnIteratorNext(i, &rect))
+    printf("%dx%d+%d+%d ",
+	   rect.x2-rect.x1,rect.y2-rect.y1,
+	   rect.x1,rect.y1);
+  sraRgnReleaseIterator(i);
+  printf("\n20x10+0+0 600x30+0+10 590x10+10+40 30x150+10+50 250x150+350+50 590x100+10+200\n\n");
+
+  i = sraRgnGetReverseIterator(region,1,0);
+  while(sraRgnIteratorNext(i, &rect))
+    printf("%dx%d+%d+%d ",
+	   rect.x2-rect.x1,rect.y2-rect.y1,
+	   rect.x1,rect.y1);
+  sraRgnReleaseIterator(i);
+  printf("\n20x10+0+0 600x30+0+10 590x10+10+40 250x150+350+50 30x150+10+50 590x100+10+200\n\n");
+
+  i = sraRgnGetReverseIterator(region,1,1);
+  while(sraRgnIteratorNext(i, &rect))
+    printf("%dx%d+%d+%d ",
+	   rect.x2-rect.x1,rect.y2-rect.y1,
+	   rect.x1,rect.y1);
+  sraRgnReleaseIterator(i);
+  printf("\n590x100+10+200 250x150+350+50 30x150+10+50 590x10+10+40 600x30+0+10 20x10+0+0\n\n");
+
+  return(0);
+}
+#endif
diff --git a/rfbserver.c b/rfbserver.c
index 68a7649..9f79b47 100644
--- a/rfbserver.c
+++ b/rfbserver.c
@@ -26,7 +26,7 @@
 
 #include <string.h>
 #include "rfb.h"
-#include "sraRegion.h"
+#include "rfbregion.h"
 
 #ifdef HAVE_FCNTL_H
 #include <fcntl.h>
diff --git a/sraRegion.c b/sraRegion.c
deleted file mode 100755
index d62a404..0000000
--- a/sraRegion.c
+++ /dev/null
@@ -1,826 +0,0 @@
-/* -=- sraRegion.c
- * Copyright (c) 2001 James "Wez" Weatherall, Johannes E. Schindelin
- *
- * A general purpose region clipping library
- * Only deals with rectangular regions, though.
- */
-
-#include "rfb.h"
-#include "sraRegion.h"
-
-/* -=- Internal Span structure */
-
-struct sraRegion;
-
-typedef struct sraSpan {
-  struct sraSpan *_next;
-  struct sraSpan *_prev;
-  int start;
-  int end;
-  struct sraRegion *subspan;
-} sraSpan;
-
-typedef struct sraRegion {
-  sraSpan front;
-  sraSpan back;
-} sraSpanList;
-
-/* -=- Span routines */
-
-sraSpanList *sraSpanListDup(const sraSpanList *src);
-void sraSpanListDestroy(sraSpanList *list);
-
-sraSpan *
-sraSpanCreate(int start, int end, const sraSpanList *subspan) {
-  sraSpan *item = (sraSpan*)malloc(sizeof(sraSpan));
-  item->_next = item->_prev = NULL;
-  item->start = start;
-  item->end = end;
-  item->subspan = sraSpanListDup(subspan);
-  return item;
-}
-
-sraSpan *
-sraSpanDup(const sraSpan *src) {
-  sraSpan *span;
-  if (!src) return NULL;
-  span = sraSpanCreate(src->start, src->end, src->subspan);
-  return span;
-}
-
-void
-sraSpanInsertAfter(sraSpan *newspan, sraSpan *after) {
-  newspan->_next = after->_next;
-  newspan->_prev = after;
-  after->_next->_prev = newspan;
-  after->_next = newspan;
-}
-
-void
-sraSpanInsertBefore(sraSpan *newspan, sraSpan *before) {
-  newspan->_next = before;
-  newspan->_prev = before->_prev;
-  before->_prev->_next = newspan;
-  before->_prev = newspan;
-}
-
-void
-sraSpanRemove(sraSpan *span) {
-  span->_prev->_next = span->_next;
-  span->_next->_prev = span->_prev;
-}
-
-void
-sraSpanDestroy(sraSpan *span) {
-  if (span->subspan) sraSpanListDestroy(span->subspan);
-  free(span);
-}
-
-void
-sraSpanCheck(const sraSpan *span, const char *text) {
-  /* Check the span is valid! */
-  if (span->start == span->end) {
-    printf(text); 
-    printf(":%d-%d\n", span->start, span->end);
-    exit(0);
-  }
-}
-
-/* -=- SpanList routines */
-
-void sraSpanPrint(const sraSpan *s);
-
-void
-sraSpanListPrint(const sraSpanList *l) {
-  sraSpan *curr;
-  if (!l) {
-	  printf("NULL");
-	  return;
-  }
-  curr = l->front._next;
-  printf("[");
-  while (curr != &(l->back)) {
-    sraSpanPrint(curr);
-    curr = curr->_next;
-  }
-  printf("]");
-}
-
-void
-sraSpanPrint(const sraSpan *s) {
-  printf("(%d-%d)", (s->start), (s->end));
-  if (s->subspan)
-    sraSpanListPrint(s->subspan);
-}
-
-sraSpanList *
-sraSpanListCreate() {
-  sraSpanList *item = (sraSpanList*)malloc(sizeof(sraSpanList));
-  item->front._next = &(item->back);
-  item->front._prev = NULL;
-  item->back._prev = &(item->front);
-  item->back._next = NULL;
-  return item;
-}
-
-sraSpanList *
-sraSpanListDup(const sraSpanList *src) {
-  sraSpanList *newlist;
-  sraSpan *newspan, *curr;
-
-  if (!src) return NULL;
-  newlist = sraSpanListCreate();
-  curr = src->front._next;
-  while (curr != &(src->back)) {
-    newspan = sraSpanDup(curr);
-    sraSpanInsertBefore(newspan, &(newlist->back));
-    curr = curr->_next;
-  }
-
-  return newlist;
-}
-
-void
-sraSpanListDestroy(sraSpanList *list) {
-  sraSpan *curr, *next;
-  while (list->front._next != &(list->back)) {
-    curr = list->front._next;
-    next = curr->_next;
-    sraSpanRemove(curr);
-    sraSpanDestroy(curr);
-    curr = next;
-  }
-  free(list);
-}
-
-void
-sraSpanListMakeEmpty(sraSpanList *list) {
-  sraSpan *curr, *next;
-  while (list->front._next != &(list->back)) {
-    curr = list->front._next;
-    next = curr->_next;
-    sraSpanRemove(curr);
-    sraSpanDestroy(curr);
-    curr = next;
-  }
-  list->front._next = &(list->back);
-  list->front._prev = NULL;
-  list->back._prev = &(list->front);
-  list->back._next = NULL;
-}
-
-Bool
-sraSpanListEqual(const sraSpanList *s1, const sraSpanList *s2) {
-  sraSpan *sp1, *sp2;
-
-  if (!s1) {
-    if (!s2) {
-      return 1;
-    } else {
-      printf("sraSpanListEqual:incompatible spans (only one NULL!)\n");
-      exit(1);
-    }
-  }
-
-  sp1 = s1->front._next;
-  sp2 = s2->front._next;
-  while ((sp1 != &(s1->back)) &&
-	 (sp2 != &(s2->back))) {
-    if ((sp1->start != sp2->start) ||
-	(sp1->end != sp2->end) ||
-	(!sraSpanListEqual(sp1->subspan, sp2->subspan))) {
-      return 0;
-    }
-    sp1 = sp1->_next;
-    sp2 = sp2->_next;
-  }
-
-  if ((sp1 == &(s1->back)) && (sp2 == &(s2->back))) {
-    return 1;
-  } else {
-    return 0;
-  }    
-}
-
-Bool
-sraSpanListEmpty(const sraSpanList *list) {
-  return (list->front._next == &(list->back));
-}
-
-unsigned long
-sraSpanListCount(const sraSpanList *list) {
-  sraSpan *curr = list->front._next;
-  unsigned long count = 0;
-  while (curr != &(list->back)) {
-    if (curr->subspan) {
-      count += sraSpanListCount(curr->subspan);
-    } else {
-      count += 1;
-    }
-    curr = curr->_next;
-  }
-  return count;
-}
-
-void
-sraSpanMergePrevious(sraSpan *dest) {
-  sraSpan *prev = dest->_prev;
-  while ((prev->end == dest->start) &&
-	 (prev->_prev) &&
-	 (sraSpanListEqual(prev->subspan, dest->subspan))) {
-    /*
-    printf("merge_prev:");
-    sraSpanPrint(prev);
-    printf(" & ");
-    sraSpanPrint(dest);
-    printf("\n");
-    */
-    dest->start = prev->start;
-    sraSpanRemove(prev);
-    sraSpanDestroy(prev);
-    prev = dest->_prev;
-  }
-}    
-
-void
-sraSpanMergeNext(sraSpan *dest) {
-  sraSpan *next = dest->_next;
-  while ((next->start == dest->end) &&
-	 (next->_next) &&
-	 (sraSpanListEqual(next->subspan, dest->subspan))) {
-/*
-	  printf("merge_next:");
-    sraSpanPrint(dest);
-    printf(" & ");
-    sraSpanPrint(next);
-    printf("\n");
-	*/
-    dest->end = next->end;
-    sraSpanRemove(next);
-    sraSpanDestroy(next);
-    next = dest->_next;
-  }
-}
-
-void
-sraSpanListOr(sraSpanList *dest, const sraSpanList *src) {
-  sraSpan *d_curr, *s_curr;
-  int s_start, s_end;
-
-  if (!dest) {
-    if (!src) {
-      return;
-    } else {
-      printf("sraSpanListOr:incompatible spans (only one NULL!)\n");
-      exit(1);
-    }
-  }
-
-  d_curr = dest->front._next;
-  s_curr = src->front._next;
-  s_start = s_curr->start;
-  s_end = s_curr->end;
-  while (s_curr != &(src->back)) {
-
-    /* - If we are at end of destination list OR
-       If the new span comes before the next destination one */
-    if ((d_curr == &(dest->back)) ||
-		(d_curr->start >= s_end)) {
-      /* - Add the span */
-      sraSpanInsertBefore(sraSpanCreate(s_start, s_end,
-					s_curr->subspan),
-			  d_curr);
-      if (d_curr != &(dest->back))
-	sraSpanMergePrevious(d_curr);
-      s_curr = s_curr->_next;
-      s_start = s_curr->start;
-      s_end = s_curr->end;
-    } else {
-
-      /* - If the new span overlaps the existing one */
-      if ((s_start < d_curr->end) &&
-	  (s_end > d_curr->start)) {
-
-	/* - Insert new span before the existing destination one? */
-	if (s_start < d_curr->start) {
-	  sraSpanInsertBefore(sraSpanCreate(s_start,
-					    d_curr->start,
-					    s_curr->subspan),
-			      d_curr);
-	  sraSpanMergePrevious(d_curr);
-	}
-
-	/* Split the existing span if necessary */
-	if (s_end < d_curr->end) {
-	  sraSpanInsertAfter(sraSpanCreate(s_end,
-					   d_curr->end,
-					   d_curr->subspan),
-			     d_curr);
-	  d_curr->end = s_end;
-	}
-	if (s_start > d_curr->start) {
-	  sraSpanInsertBefore(sraSpanCreate(d_curr->start,
-					    s_start,
-					    d_curr->subspan),
-			      d_curr);
-	  d_curr->start = s_start;
-	}
-
-	/* Recursively OR subspans */
-	sraSpanListOr(d_curr->subspan, s_curr->subspan);
-
-	/* Merge this span with previous or next? */
-	if (d_curr->_prev != &(dest->front))
-	  sraSpanMergePrevious(d_curr);
-	if (d_curr->_next != &(dest->back))
-	  sraSpanMergeNext(d_curr);
-
-	/* Move onto the next pair to compare */
-	if (s_end > d_curr->end) {
-	  s_start = d_curr->end;
-	  d_curr = d_curr->_next;
-	} else {
-	  s_curr = s_curr->_next;
-	  s_start = s_curr->start;
-	  s_end = s_curr->end;
-	}
-      } else {
-	/* - No overlap.  Move to the next destination span */
-	d_curr = d_curr->_next;
-      }
-    }
-  }
-}
-
-Bool
-sraSpanListAnd(sraSpanList *dest, const sraSpanList *src) {
-  sraSpan *d_curr, *s_curr, *d_next;
-
-  if (!dest) {
-    if (!src) {
-      return 1;
-    } else {
-      printf("sraSpanListAnd:incompatible spans (only one NULL!)\n");
-      exit(1);
-    }
-  }
-
-  d_curr = dest->front._next;
-  s_curr = src->front._next;
-  while ((s_curr != &(src->back)) && (d_curr != &(dest->back))) {
-
-    /* - If we haven't reached a destination span yet then move on */
-    if (d_curr->start >= s_curr->end) {
-      s_curr = s_curr->_next;
-      continue;
-    }
-
-    /* - If we are beyond the current destination span then remove it */
-    if (d_curr->end <= s_curr->start) {
-      sraSpan *next = d_curr->_next;
-      sraSpanRemove(d_curr);
-      sraSpanDestroy(d_curr);
-      d_curr = next;
-      continue;
-    }
-
-    /* - If we partially overlap a span then split it up or remove bits */
-    if (s_curr->start > d_curr->start) {
-      /* - The top bit of the span does not match */
-      d_curr->start = s_curr->start;
-    }
-    if (s_curr->end < d_curr->end) {
-      /* - The end of the span does not match */
-      sraSpanInsertAfter(sraSpanCreate(s_curr->end,
-				       d_curr->end,
-				       d_curr->subspan),
-			 d_curr);
-      d_curr->end = s_curr->end;
-    }
-
-    /* - Now recursively process the affected span */
-    if (!sraSpanListAnd(d_curr->subspan, s_curr->subspan)) {
-      /* - The destination subspan is now empty, so we should remove it */
-		sraSpan *next = d_curr->_next;
-      sraSpanRemove(d_curr);
-      sraSpanDestroy(d_curr);
-      d_curr = next;
-    } else {
-      /* Merge this span with previous or next? */
-      if (d_curr->_prev != &(dest->front))
-	sraSpanMergePrevious(d_curr);
-
-      /* - Move on to the next span */
-      d_next = d_curr;
-      if (s_curr->end >= d_curr->end) {
-	d_next = d_curr->_next;
-      }
-      if (s_curr->end <= d_curr->end) {
-	s_curr = s_curr->_next;
-      }
-      d_curr = d_next;
-    }
-  }
-
-  while (d_curr != &(dest->back)) {
-    sraSpan *next = d_curr->_next;
-    sraSpanRemove(d_curr);
-    sraSpanDestroy(d_curr);
-    d_curr=next;
-  }
-
-  return !sraSpanListEmpty(dest);
-}
-
-Bool
-sraSpanListSubtract(sraSpanList *dest, const sraSpanList *src) {
-  sraSpan *d_curr, *s_curr;
-
-  if (!dest) {
-    if (!src) {
-      return 1;
-    } else {
-      printf("sraSpanListSubtract:incompatible spans (only one NULL!)\n");
-      exit(1);
-    }
-  }
-
-  d_curr = dest->front._next;
-  s_curr = src->front._next;
-  while ((s_curr != &(src->back)) && (d_curr != &(dest->back))) {
-
-    /* - If we haven't reached a destination span yet then move on */
-    if (d_curr->start >= s_curr->end) {
-      s_curr = s_curr->_next;
-      continue;
-    }
-
-    /* - If we are beyond the current destination span then skip it */
-    if (d_curr->end <= s_curr->start) {
-      d_curr = d_curr->_next;
-      continue;
-    }
-
-    /* - If we partially overlap the current span then split it up */
-    if (s_curr->start > d_curr->start) {
-      sraSpanInsertBefore(sraSpanCreate(d_curr->start,
-					s_curr->start,
-					d_curr->subspan),
-			  d_curr);
-      d_curr->start = s_curr->start;
-    }
-    if (s_curr->end < d_curr->end) {
-      sraSpanInsertAfter(sraSpanCreate(s_curr->end,
-				       d_curr->end,
-				       d_curr->subspan),
-			 d_curr);
-      d_curr->end = s_curr->end;
-    }
-
-    /* - Now recursively process the affected span */
-    if ((!d_curr->subspan) || !sraSpanListSubtract(d_curr->subspan, s_curr->subspan)) {
-      /* - The destination subspan is now empty, so we should remove it */
-      sraSpan *next = d_curr->_next;
-      sraSpanRemove(d_curr);
-      sraSpanDestroy(d_curr);
-      d_curr = next;
-    } else {
-      /* Merge this span with previous or next? */
-      if (d_curr->_prev != &(dest->front))
-	sraSpanMergePrevious(d_curr);
-      if (d_curr->_next != &(dest->back))
-	sraSpanMergeNext(d_curr);
-
-      /* - Move on to the next span */
-      if (s_curr->end > d_curr->end) {
-	d_curr = d_curr->_next;
-      } else {
-	s_curr = s_curr->_next;
-      }
-    }
-  }
-
-  return !sraSpanListEmpty(dest);
-}
-
-/* -=- Region routines */
-
-sraRegion *
-sraRgnCreate() {
-  return (sraRegion*)sraSpanListCreate();
-}
-
-sraRegion *
-sraRgnCreateRect(int x1, int y1, int x2, int y2) {
-  sraSpanList *vlist, *hlist;
-  sraSpan *vspan, *hspan;
-
-  /* - Build the horizontal portion of the span */
-  hlist = sraSpanListCreate();
-  hspan = sraSpanCreate(x1, x2, NULL);
-  sraSpanInsertAfter(hspan, &(hlist->front));
-
-  /* - Build the vertical portion of the span */
-  vlist = sraSpanListCreate();
-  vspan = sraSpanCreate(y1, y2, hlist);
-  sraSpanInsertAfter(vspan, &(vlist->front));
-
-  sraSpanListDestroy(hlist);
-
-  return (sraRegion*)vlist;
-}
-
-sraRegion *
-sraRgnCreateRgn(const sraRegion *src) {
-  return (sraRegion*)sraSpanListDup((sraSpanList*)src);
-}
-
-void
-sraRgnDestroy(sraRegion *rgn) {
-  sraSpanListDestroy((sraSpanList*)rgn);
-}
-
-void
-sraRgnMakeEmpty(sraRegion *rgn) {
-  sraSpanListMakeEmpty((sraSpanList*)rgn);
-}
-
-/* -=- Boolean Region ops */
-
-Bool
-sraRgnAnd(sraRegion *dst, const sraRegion *src) {
-  return sraSpanListAnd((sraSpanList*)dst, (sraSpanList*)src);
-}
-
-void
-sraRgnOr(sraRegion *dst, const sraRegion *src) {
-  sraSpanListOr((sraSpanList*)dst, (sraSpanList*)src);
-}
-
-Bool
-sraRgnSubtract(sraRegion *dst, const sraRegion *src) {
-  return sraSpanListSubtract((sraSpanList*)dst, (sraSpanList*)src);
-}
-
-void
-sraRgnOffset(sraRegion *dst, int dx, int dy) {
-  sraSpan *vcurr, *hcurr;
-
-  vcurr = ((sraSpanList*)dst)->front._next;
-  while (vcurr != &(((sraSpanList*)dst)->back)) {
-    vcurr->start += dy;
-    vcurr->end += dy;
-    
-    hcurr = vcurr->subspan->front._next;
-    while (hcurr != &(vcurr->subspan->back)) {
-      hcurr->start += dx;
-      hcurr->end += dx;
-      hcurr = hcurr->_next;
-    }
-
-    vcurr = vcurr->_next;
-  }
-}
-
-Bool
-sraRgnPopRect(sraRegion *rgn, sraRect *rect, unsigned long flags) {
-  sraSpan *vcurr, *hcurr;
-  sraSpan *vend, *hend;
-  Bool right2left = flags & 2;
-  Bool bottom2top = flags & 1;
-
-  /* - Pick correct order */
-  if (bottom2top) {
-    vcurr = ((sraSpanList*)rgn)->back._prev;
-    vend = &(((sraSpanList*)rgn)->front);
-  } else {
-    vcurr = ((sraSpanList*)rgn)->front._next;
-    vend = &(((sraSpanList*)rgn)->back);
-  }
-
-  if (vcurr != vend) {
-    rect->y1 = vcurr->start;
-    rect->y2 = vcurr->end;
-
-    /* - Pick correct order */
-    if (right2left) {
-      hcurr = vcurr->subspan->back._prev;
-      hend = &(vcurr->subspan->front);
-    } else {
-      hcurr = vcurr->subspan->front._next;
-      hend = &(vcurr->subspan->back);
-    }
-
-    if (hcurr != hend) {
-      rect->x1 = hcurr->start;
-      rect->x2 = hcurr->end;
-
-      sraSpanRemove(hcurr);
-      sraSpanDestroy(hcurr);
-      
-      if (sraSpanListEmpty(vcurr->subspan)) {
-	sraSpanRemove(vcurr);
-	sraSpanDestroy(vcurr);
-      }
-
-#if 0
-      printf("poprect:(%dx%d)-(%dx%d)\n",
-	     rect->x1, rect->y1, rect->x2, rect->y2);
-#endif
-      return 1;
-    }
-  }
-
-  return 0;
-}
-
-unsigned long
-sraRgnCountRects(const sraRegion *rgn) {
-  unsigned long count = sraSpanListCount((sraSpanList*)rgn);
-  return count;
-}
-
-Bool
-sraRgnEmpty(const sraRegion *rgn) {
-  return sraSpanListEmpty((sraSpanList*)rgn);
-}
-
-/* iterator stuff */
-sraRectangleIterator *sraRgnGetIterator(sraRegion *s)
-{
-  /* these values have to be multiples of 4 */
-#define DEFSIZE 4
-#define DEFSTEP 8
-  sraRectangleIterator *i =
-    (sraRectangleIterator*)malloc(sizeof(sraRectangleIterator));
-  if(!i)
-    return(0);
-
-  /* we have to recurse eventually. So, the first sPtr is the pointer to
-     the sraSpan in the first level. the second sPtr is the pointer to
-     the sraRegion.back. The third and fourth sPtr are for the second
-     recursion level and so on. */
-  i->sPtrs = (sraSpan**)malloc(sizeof(sraSpan*)*DEFSIZE);
-  if(!i->sPtrs) {
-    free(i);
-    return(0);
-  }
-  i->ptrSize = DEFSIZE;
-  i->sPtrs[0] = &(s->front);
-  i->sPtrs[1] = &(s->back);
-  i->ptrPos = 0;
-  i->reverseX = 0;
-  i->reverseY = 0;
-  return(i);
-}
-
-sraRectangleIterator *sraRgnGetReverseIterator(sraRegion *s,Bool reverseX,Bool reverseY)
-{
-  sraRectangleIterator *i = sraRgnGetIterator(s);
-  if(reverseY) {
-    i->sPtrs[1] = &(s->front);
-    i->sPtrs[0] = &(s->back);
-  }
-  i->reverseX = reverseX;
-  i->reverseY = reverseY;
-  return(i);
-}
-
-Bool sraReverse(sraRectangleIterator *i)
-{
-  return( ((i->ptrPos&2) && i->reverseX) ||
-     (!(i->ptrPos&2) && i->reverseY));
-}
-
-sraSpan* sraNextSpan(sraRectangleIterator *i)
-{
-  if(sraReverse(i))
-    return(i->sPtrs[i->ptrPos]->_prev);
-  else
-    return(i->sPtrs[i->ptrPos]->_next);
-}
-
-Bool sraRgnIteratorNext(sraRectangleIterator* i,sraRect* r)
-{
-  /* is the subspan finished? */
-  while(sraNextSpan(i) == i->sPtrs[i->ptrPos+1]) {
-    i->ptrPos -= 2;
-    if(i->ptrPos < 0) /* the end */
-      return(0);
-  }
-
-  i->sPtrs[i->ptrPos] = sraNextSpan(i);
-
-  /* is this a new subspan? */
-  while(i->sPtrs[i->ptrPos]->subspan) {
-    if(i->ptrPos+2 > i->ptrSize) { /* array is too small */
-      i->ptrSize += DEFSTEP;
-      i->sPtrs = (sraSpan**)realloc(i->sPtrs, sizeof(sraSpan*)*i->ptrSize);
-    }
-    i->ptrPos =+ 2;
-    if(sraReverse(i)) {
-      i->sPtrs[i->ptrPos]   =   i->sPtrs[i->ptrPos-2]->subspan->back._prev;
-      i->sPtrs[i->ptrPos+1] = &(i->sPtrs[i->ptrPos-2]->subspan->front);
-    } else {
-      i->sPtrs[i->ptrPos]   =   i->sPtrs[i->ptrPos-2]->subspan->front._next;
-      i->sPtrs[i->ptrPos+1] = &(i->sPtrs[i->ptrPos-2]->subspan->back);
-    }
-  }
-
-  if((i->ptrPos%4)!=2) {
-    fprintf(stderr,"sraRgnIteratorNext: offset is wrong (%d%%4!=2)\n",i->ptrPos);
-    exit(-1);
-  }
-
-  r->y1 = i->sPtrs[i->ptrPos-2]->start;
-  r->y2 = i->sPtrs[i->ptrPos-2]->end;
-  r->x1 = i->sPtrs[i->ptrPos]->start;
-  r->x2 = i->sPtrs[i->ptrPos]->end;
-
-  return(-1);
-}
-
-void sraRgnReleaseIterator(sraRectangleIterator* i)
-{
-  free(i->sPtrs);
-  free(i);
-}
-
-void
-sraRgnPrint(const sraRegion *rgn) {
-	sraSpanListPrint((sraSpanList*)rgn);
-}
-
-Bool
-sraClipRect(int *x, int *y, int *w, int *h,
-	    int cx, int cy, int cw, int ch) {
-  if (*x < cx) {
-    *w -= (cx-*x);
-    *x = cx;
-  }
-  if (*y < cy) {
-    *h -= (cy-*y);
-    *y = cy;
-  }
-  if (*x+*w > cx+cw) {
-    *w = (cx+cw)-*x;
-  }
-  if (*y+*h > cy+ch) {
-    *h = (cy+ch)-*y;
-  }
-  return (*w>0) && (*h>0);
-}
-
-/* test */
-
-#ifdef SRA_TEST
-/* pipe the output to sort|uniq -u and you'll get the errors. */
-int main(int argc, char** argv)
-{
-  sraRegionPtr region, region1, region2;
-  sraRectangleIterator* i;
-  sraRect rect;
-  Bool b;
-
-  region = sraRgnCreateRect(10, 10, 600, 300);
-  region1 = sraRgnCreateRect(40, 50, 350, 200);
-  region2 = sraRgnCreateRect(0, 0, 20, 40);
-
-  sraRgnPrint(region);
-  printf("\n[(10-300)[(10-600)]]\n\n");
-
-  b = sraRgnSubtract(region, region1);
-  printf("%s ",b?"true":"false");
-  sraRgnPrint(region);
-  printf("\ntrue [(10-50)[(10-600)](50-200)[(10-40)(350-600)](200-300)[(10-600)]]\n\n");
-
-  sraRgnOr(region, region2);
-  printf("%ld\n6\n\n", sraRgnCountRects(region));
-
-  i = sraRgnGetIterator(region);
-  while(sraRgnIteratorNext(i, &rect))
-    printf("%dx%d+%d+%d ",
-	   rect.x2-rect.x1,rect.y2-rect.y1,
-	   rect.x1,rect.y1);
-  sraRgnReleaseIterator(i);
-  printf("\n20x10+0+0 600x30+0+10 590x10+10+40 30x150+10+50 250x150+350+50 590x100+10+200\n\n");
-
-  i = sraRgnGetReverseIterator(region,1,0);
-  while(sraRgnIteratorNext(i, &rect))
-    printf("%dx%d+%d+%d ",
-	   rect.x2-rect.x1,rect.y2-rect.y1,
-	   rect.x1,rect.y1);
-  sraRgnReleaseIterator(i);
-  printf("\n20x10+0+0 600x30+0+10 590x10+10+40 250x150+350+50 30x150+10+50 590x100+10+200\n\n");
-
-  i = sraRgnGetReverseIterator(region,1,1);
-  while(sraRgnIteratorNext(i, &rect))
-    printf("%dx%d+%d+%d ",
-	   rect.x2-rect.x1,rect.y2-rect.y1,
-	   rect.x1,rect.y1);
-  sraRgnReleaseIterator(i);
-  printf("\n590x100+10+200 250x150+350+50 30x150+10+50 590x10+10+40 600x30+0+10 20x10+0+0\n\n");
-
-  return(0);
-}
-#endif
diff --git a/sraRegion.h b/sraRegion.h
deleted file mode 100755
index 1bbedf6..0000000
--- a/sraRegion.h
+++ /dev/null
@@ -1,60 +0,0 @@
-#ifndef SRAREGION_H
-#define SRAREGION_H
-
-/* -=- SRA - Simple Region Algorithm
- * A simple rectangular region implementation.
- * Copyright (c) 2001 James "Wez" Weatherall, Johannes E. Schindelin
- */
-
-/* -=- sraRect */
-
-typedef struct _rect {
-	int x1;
-	int y1;
-	int x2;
-	int y2;
-} sraRect;
-
-typedef struct sraRegion sraRegion;
-
-/* -=- Region manipulation functions */
-
-extern sraRegion *sraRgnCreate();
-extern sraRegion *sraRgnCreateRect(int x1, int y1, int x2, int y2);
-extern sraRegion *sraRgnCreateRgn(const sraRegion *src);
-
-extern void sraRgnDestroy(sraRegion *rgn);
-extern void sraRgnMakeEmpty(sraRegion *rgn);
-extern Bool sraRgnAnd(sraRegion *dst, const sraRegion *src);
-extern void sraRgnOr(sraRegion *dst, const sraRegion *src);
-extern Bool sraRgnSubtract(sraRegion *dst, const sraRegion *src);
-
-extern void sraRgnOffset(sraRegion *dst, int dx, int dy);
-
-extern Bool sraRgnPopRect(sraRegion *region, sraRect *rect,
-			  unsigned long flags);
-
-extern unsigned long sraRgnCountRects(const sraRegion *rgn);
-extern Bool sraRgnEmpty(const sraRegion *rgn);
-
-/* -=- rectangle iterator */
-
-typedef struct sraRectangleIterator {
-  Bool reverseX,reverseY;
-  int ptrSize,ptrPos;
-  struct sraSpan** sPtrs;
-} sraRectangleIterator;
-
-extern sraRectangleIterator *sraRgnGetIterator(sraRegion *s);
-extern sraRectangleIterator *sraRgnGetReverseIterator(sraRegion *s,Bool reverseX,Bool reverseY);
-extern Bool sraRgnIteratorNext(sraRectangleIterator *i,sraRect *r);
-extern void sraRgnReleaseIterator(sraRectangleIterator *i);
-
-void sraRgnPrint(const sraRegion *s);
-
-/* -=- Rectangle clipper (for speed) */
-
-extern Bool sraClipRect(int *x, int *y, int *w, int *h,
-			int cx, int cy, int cw, int ch);
-
-#endif
diff --git a/translate.c b/translate.c
index 54a8e1b..7f665c2 100644
--- a/translate.c
+++ b/translate.c
@@ -24,7 +24,7 @@
  */
 
 #include "rfb.h"
-#include "sraRegion.h"
+#include "rfbregion.h"
 
 static void PrintPixelFormat(rfbPixelFormat *pf);
 static Bool rfbSetClientColourMapBGR233(rfbClientPtr cl);
-- 
cgit v1.2.3

