From fd96c5e835cfb64e454e189e4b481b0a7292f5e3 Mon Sep 17 00:00:00 2001 From: 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 #include 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 #include "rfb.h" -#include "sraRegion.h" +#include "rfbregion.h" #ifdef HAVE_FCNTL_H #include 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