Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
L
libvncserver
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
rasky
libvncserver
Commits
598c460c
Commit
598c460c
authored
Aug 19, 2002
by
dscho
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
unwarn compilation
parent
fde8958d
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
927 additions
and
924 deletions
+927
-924
Makefile
Makefile
+2
-2
auth.c
auth.c
+1
-1
cursor.c
cursor.c
+2
-2
example.c
example.c
+7
-7
httpd.c
httpd.c
+2
-2
main.c
main.c
+5
-3
pnmshow.c
pnmshow.c
+1
-1
rfb.h
rfb.h
+7
-6
rfbserver.c
rfbserver.c
+8
-0
sraRegion.c
sraRegion.c
+829
-829
sraRegion.h
sraRegion.h
+60
-60
tight.c
tight.c
+2
-11
vncauth.c
vncauth.c
+1
-0
No files found.
Makefile
View file @
598c460c
...
...
@@ -2,7 +2,7 @@ INCLUDES=-I.
VNCSERVERLIB
=
-L
.
-lvncserver
-L
/usr/local/lib
-lz
-ljpeg
# for Solaris
#
CC=gcc
CC
=
gcc
#EXTRALIBS=-lsocket -lnsl -L/usr/X/lib
# for FreeBSD
...
...
@@ -16,7 +16,7 @@ VNCSERVERLIB=-L. -lvncserver -L/usr/local/lib -lz -ljpeg
# The code for 3 Bytes/Pixel is not very efficient!
FLAG24
=
-DALLOW24BPP
OPTFLAGS
=
-g
-Wall
OPTFLAGS
=
-g
-Wall
-pedantic
#OPTFLAGS=-O2 -Wall
CFLAGS
=
$(OPTFLAGS)
$(PTHREADDEF)
$(FLAG24)
$(INCLUDES)
$(EXTRAINCLUDES)
-DBACKCHANNEL
RANLIB
=
ranlib
...
...
auth.c
View file @
598c460c
...
...
@@ -84,7 +84,7 @@ rfbAuthProcessClientMessage(cl)
return
;
}
if
(
!
cl
->
screen
->
passwordCheck
(
cl
,
response
,
CHALLENGESIZE
))
{
if
(
!
cl
->
screen
->
passwordCheck
(
cl
,
(
const
char
*
)
response
,
CHALLENGESIZE
))
{
rfbLog
(
"rfbAuthProcessClientMessage: password check failed
\n
"
);
authResult
=
Swap32IfLE
(
rfbVncAuthFailed
);
if
(
WriteExact
(
cl
,
(
char
*
)
&
authResult
,
4
)
<
0
)
{
...
...
cursor.c
View file @
598c460c
...
...
@@ -143,7 +143,7 @@ rfbSendCursorShape(cl)
bpp2
=
cl
->
format
.
bitsPerPixel
/
8
;
(
*
cl
->
translateFn
)(
cl
->
translateLookupTable
,
&
(
cl
->
screen
->
rfbServerFormat
),
&
cl
->
format
,
pCursor
->
richSource
,
&
cl
->
format
,
(
char
*
)
pCursor
->
richSource
,
&
cl
->
updateBuf
[
cl
->
ublen
],
pCursor
->
width
*
bpp1
,
pCursor
->
width
,
pCursor
->
height
);
...
...
@@ -241,7 +241,7 @@ rfbCursorPtr rfbMakeXCursor(int width,int height,char* cursorString,char* maskSt
for
(
i
=
0
,
bit
=
0x80
;
i
<
width
;
i
++
,
bit
=
(
bit
&
1
)
?
0x80
:
bit
>>
1
,
cp
++
)
if
(
*
cp
!=
' '
)
cursor
->
mask
[
j
*
w
+
i
/
8
]
|=
bit
;
}
else
cursor
->
mask
=
(
unsigned
char
*
)
rfbMakeMaskForXCursor
(
width
,
height
,
cursor
->
source
);
cursor
->
mask
=
(
unsigned
char
*
)
rfbMakeMaskForXCursor
(
width
,
height
,
(
char
*
)
cursor
->
source
);
return
(
cursor
);
}
...
...
example.c
View file @
598c460c
...
...
@@ -79,14 +79,14 @@ enum rfbNewClientAction newclient(rfbClientPtr cl)
void
newframebuffer
(
rfbScreenInfoPtr
screen
,
int
width
,
int
height
)
{
char
*
oldfb
,
*
newfb
;
unsigned
char
*
oldfb
,
*
newfb
;
maxx
=
width
;
maxy
=
height
;
oldfb
=
screen
->
frameBuffer
;
newfb
=
(
char
*
)
malloc
(
maxx
*
maxy
*
bpp
);
oldfb
=
(
unsigned
char
*
)
screen
->
frameBuffer
;
newfb
=
(
unsigned
char
*
)
malloc
(
maxx
*
maxy
*
bpp
);
initBuffer
(
newfb
);
rfbNewFramebuffer
(
screen
,
newfb
,
maxx
,
maxy
,
8
,
3
,
bpp
);
rfbNewFramebuffer
(
screen
,
(
char
*
)
newfb
,
maxx
,
maxy
,
8
,
3
,
bpp
);
free
(
oldfb
);
/*** FIXME: Re-install cursor. ***/
...
...
@@ -133,7 +133,7 @@ void doptr(int buttonMask,int x,int y,rfbClientPtr cl)
int
i
,
j
,
x1
,
x2
,
y1
,
y2
;
if
(
cd
->
oldButton
==
buttonMask
)
{
/* draw a line */
drawline
(
cl
->
screen
->
frameBuffer
,
cl
->
screen
->
paddedWidthInBytes
,
bpp
,
drawline
(
(
unsigned
char
*
)
cl
->
screen
->
frameBuffer
,
cl
->
screen
->
paddedWidthInBytes
,
bpp
,
x
,
y
,
cd
->
oldx
,
cd
->
oldy
);
rfbMarkRectAsModified
(
cl
->
screen
,
x
,
y
,
cd
->
oldx
,
cd
->
oldy
);
}
else
{
/* draw a point (diameter depends on button) */
...
...
@@ -174,7 +174,7 @@ void dokey(Bool down,KeySym key,rfbClientPtr cl)
else
if
(
key
==
XK_Page_Up
)
{
if
(
cl
->
screen
->
cursorIsDrawn
)
rfbUndrawCursor
(
cl
->
screen
);
initBuffer
(
cl
->
screen
->
frameBuffer
);
initBuffer
(
(
unsigned
char
*
)
cl
->
screen
->
frameBuffer
);
rfbMarkRectAsModified
(
cl
->
screen
,
0
,
0
,
maxx
,
maxy
);
}
else
if
(
key
==
XK_Up
)
{
if
(
maxx
<
1024
)
{
...
...
@@ -283,7 +283,7 @@ int main(int argc,char** argv)
rfbScreen
->
newClientHook
=
newclient
;
rfbScreen
->
httpDir
=
"./classes"
;
initBuffer
(
rfbScreen
->
frameBuffer
);
initBuffer
(
(
unsigned
char
*
)
rfbScreen
->
frameBuffer
);
rfbDrawString
(
rfbScreen
,
&
radonFont
,
20
,
100
,
"Hello, World!"
,
0xffffff
);
/* This call creates a mask and then a cursor: */
...
...
httpd.c
View file @
598c460c
...
...
@@ -22,6 +22,7 @@
*/
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#ifdef WIN32
#include <winsock.h>
...
...
@@ -68,7 +69,6 @@ FILE* httpFP = NULL;
static
char
buf
[
BUF_SIZE
];
static
size_t
buf_filled
=
0
;
/*
* httpInitSockets sets up the TCP socket to listen for HTTP connections.
*/
...
...
@@ -303,7 +303,7 @@ httpProcessInput(rfbScreenInfoPtr rfbScreen)
/* Open the file */
if
((
fd
=
fopen
(
fullFname
,
"r"
))
<
=
0
)
{
if
((
fd
=
fopen
(
fullFname
,
"r"
))
=
=
0
)
{
rfbLogPerror
(
"httpProcessInput: open"
);
WriteExact
(
&
cl
,
NOT_FOUND_STR
,
strlen
(
NOT_FOUND_STR
));
httpCloseSock
(
rfbScreen
);
...
...
main.c
View file @
598c460c
...
...
@@ -32,7 +32,9 @@
#include "rfb.h"
#include "sraRegion.h"
#ifdef HAVE_PTHREADS
MUTEX
(
logMutex
);
#endif
int
rfbEnableLogging
=
1
;
...
...
@@ -380,11 +382,11 @@ void defaultSetXCutText(char* text, int len, rfbClientPtr cl)
/* TODO: add a nice VNC or RFB cursor */
#if defined(WIN32) || defined(sparc)
#if defined(WIN32) || defined(sparc)
|| !defined(NO_STRICT_ANSI)
static
rfbCursor
myCursor
=
{
"
\000\102\044\030\044\102\000
"
,
"
\347\347\176\074\176\347\347
"
,
(
unsigned
char
*
)
"
\000\102\044\030\044\102\000
"
,
(
unsigned
char
*
)
"
\347\347\176\074\176\347\347
"
,
8
,
7
,
3
,
3
,
0
,
0
,
0
,
0xffff
,
0xffff
,
0xffff
,
...
...
pnmshow.c
View file @
598c460c
...
...
@@ -12,7 +12,7 @@ int main(int argc,char** argv)
{
FILE
*
in
=
stdin
;
int
i
,
j
,
k
,
width
,
height
,
paddedWidth
;
unsigned
char
buffer
[
1024
];
char
buffer
[
1024
];
rfbScreenInfoPtr
rfbScreen
;
if
(
argc
>
1
)
{
...
...
rfb.h
View file @
598c460c
...
...
@@ -45,12 +45,9 @@ typedef CARD32 Pixel;
/* typedef CARD32 KeySym; */
typedef
unsigned
long
KeySym
;
#define SIGNED signed
/* for some strange reason, "typedef signed char Bool;" yields a four byte
signed int on IRIX, but only for rfbserver.o!!! */
#ifdef Bool
#undef Bool
#endif
#define Bool signed char
typedef
signed
char
Bool
;
#undef FALSE
#define FALSE 0
#undef TRUE
...
...
@@ -90,6 +87,10 @@ typedef unsigned long KeySym;
#include <sys/endian.h>
#endif
#ifdef __sgi__
typedef
int
socklen_t
;
#endif
#ifndef _BYTE_ORDER
#define _BYTE_ORDER __BYTE_ORDER
#endif
...
...
rfbserver.c
View file @
598c460c
...
...
@@ -25,6 +25,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "rfb.h"
#include "sraRegion.h"
#ifdef WIN32
...
...
@@ -76,7 +77,9 @@ void rfbIncrClientRef(rfbClientPtr cl) {}
void
rfbDecrClientRef
(
rfbClientPtr
cl
)
{}
#endif
#ifdef HAVE_PTHREADS
MUTEX
(
rfbClientListMutex
);
#endif
struct
rfbClientIterator
{
rfbClientPtr
next
;
...
...
@@ -86,6 +89,11 @@ struct rfbClientIterator {
void
rfbClientListInit
(
rfbScreenInfoPtr
rfbScreen
)
{
if
(
sizeof
(
Bool
)
!=
1
)
{
/* a sanity check */
fprintf
(
stderr
,
"Bool's size is not 1 (%d)!
\n
"
,
sizeof
(
Bool
));
exit
(
1
);
}
rfbScreen
->
rfbClientHead
=
NULL
;
INIT_MUTEX
(
rfbClientListMutex
);
}
...
...
sraRegion.c
View file @
598c460c
/* -=- 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"
#include <stdlib.h>
#include <stdio.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
(
"
\n
true [(10-50)[(10-600)](50-200)[(10-40)(350-600)](200-300)[(10-600)]]
\n\n
"
);
sraRgnOr
(
region
,
region2
);
printf
(
"%ld
\n
6
\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
(
"
\n
20x10+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
(
"
\n
20x10+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
(
"
\n
590x100+10+200 250x150+350+50 30x150+10+50 590x10+10+40 600x30+0+10 20x10+0+0
\n\n
"
);
return
(
0
);
}
#endif
/* -=- 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"
#include <stdlib.h>
#include <stdio.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
(
"
\n
true [(10-50)[(10-600)](50-200)[(10-40)(350-600)](200-300)[(10-600)]]
\n\n
"
);
sraRgnOr
(
region
,
region2
);
printf
(
"%ld
\n
6
\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
(
"
\n
20x10+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
(
"
\n
20x10+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
(
"
\n
590x100+10+200 250x150+350+50 30x150+10+50 590x10+10+40 600x30+0+10 20x10+0+0
\n\n
"
);
return
(
0
);
}
#endif
sraRegion.h
View file @
598c460c
#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
#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
tight.c
View file @
598c460c
...
...
@@ -429,12 +429,7 @@ ExtendSolidArea(cl, x, y, w, h, colorValue, x_ptr, y_ptr, w_ptr, h_ptr)
*
w_ptr
+=
cx
-
(
*
x_ptr
+
*
w_ptr
);
}
static
Bool
CheckSolidTile
(
cl
,
x
,
y
,
w
,
h
,
colorPtr
,
needSameColor
)
rfbClientPtr
cl
;
int
x
,
y
,
w
,
h
;
CARD32
*
colorPtr
;
Bool
needSameColor
;
static
Bool
CheckSolidTile
(
rfbClientPtr
cl
,
int
x
,
int
y
,
int
w
,
int
h
,
CARD32
*
colorPtr
,
Bool
needSameColor
)
{
switch
(
cl
->
screen
->
rfbServerFormat
.
bitsPerPixel
)
{
case
32
:
...
...
@@ -449,11 +444,7 @@ CheckSolidTile(cl, x, y, w, h, colorPtr, needSameColor)
#define DEFINE_CHECK_SOLID_FUNCTION(bpp) \
\
static Bool \
CheckSolidTile##bpp(cl, x, y, w, h, colorPtr, needSameColor) \
rfbClientPtr cl; \
int x, y, w, h; \
CARD32 *colorPtr; \
Bool needSameColor; \
CheckSolidTile##bpp(rfbClientPtr cl, int x, int y, int w, int h, CARD32* colorPtr, Bool needSameColor) \
{ \
CARD##bpp *fbptr; \
CARD##bpp colorValue; \
...
...
vncauth.c
View file @
598c460c
...
...
@@ -24,6 +24,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <time.h>
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment