add more advances region support using pixman

This commit is contained in:
Jay Sorg 2016-08-08 20:02:10 -07:00
parent 660132a49d
commit 58c777783b
9 changed files with 2762 additions and 258 deletions

View File

@ -1,3 +1,11 @@
EXTRA_FILES =
if XRDP_PIXMAN
else
EXTRA_FILES += pixman-region16.c pixman-region.h
endif
AM_CPPFLAGS = \
-DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
-DXRDP_SBIN_PATH=\"${sbindir}\" \
@ -36,7 +44,8 @@ libcommon_la_SOURCES = \
trans.h \
xrdp_client_info.h \
xrdp_constants.h \
xrdp_rail.h
xrdp_rail.h \
$(EXTRA_FILES)
libcommon_la_LIBADD = \
-lcrypto \

2549
common/pixman-region.c Normal file

File diff suppressed because it is too large Load Diff

73
common/pixman-region.h Normal file
View File

@ -0,0 +1,73 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2016
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* region, from pixman.h
*/
#if !defined(PIXMAN_PIXMAN_H__)
#define PIXMAN_PIXMAN_H__
typedef int pixman_bool_t;
struct pixman_region16_data
{
long size;
long numRects;
};
struct pixman_box16
{
signed short x1, y1, x2, y2;
};
struct pixman_region16
{
struct pixman_box16 extents;
struct pixman_region16_data *data;
};
enum _pixman_region_overlap_t
{
PIXMAN_REGION_OUT,
PIXMAN_REGION_IN,
PIXMAN_REGION_PART
};
typedef enum _pixman_region_overlap_t pixman_region_overlap_t;
typedef struct pixman_region16_data pixman_region16_data_t;
typedef struct pixman_box16 pixman_box16_t;
typedef struct pixman_region16 pixman_region16_t;
/* creation/destruction */
void pixman_region_init (pixman_region16_t *region);
void pixman_region_init_rect (pixman_region16_t *region,
int x,
int y,
unsigned int width,
unsigned int height);
void pixman_region_fini (pixman_region16_t *region);
pixman_bool_t pixman_region_union (pixman_region16_t *new_reg,
pixman_region16_t *reg1,
pixman_region16_t *reg2);
pixman_bool_t pixman_region_subtract (pixman_region16_t *reg_d,
pixman_region16_t *reg_m,
pixman_region16_t *reg_s);
pixman_box16_t * pixman_region_rectangles (pixman_region16_t *region,
int *n_rects);
#endif

67
common/pixman-region16.c Normal file
View File

@ -0,0 +1,67 @@
/*
* Copyright © 2008 Red Hat, Inc.
*
* Permission to use, copy, modify, distribute, and sell this software
* and its documentation for any purpose is hereby granted without
* fee, provided that the above copyright notice appear in all copies
* and that both that copyright notice and this permission notice
* appear in supporting documentation, and that the name of
* Red Hat, Inc. not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior
* permission. Red Hat, Inc. makes no representations about the
* suitability of this software for any purpose. It is provided "as
* is" without express or implied warranty.
*
* RED HAT, INC. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS, IN NO EVENT SHALL RED HAT, INC. BE LIABLE FOR ANY SPECIAL,
* INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
* RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
* IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Author: Soren Sandmann <sandmann@redhat.com>
*/
/* taken from pixman 0.34
altered to compile without all of pixman */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "pixman-region.h"
#define UINT32_MAX (4294967295U)
#define INT16_MIN (-32767-1)
#define INT16_MAX (32767)
#define PIXMAN_EXPORT
#define FALSE 0
#define TRUE 1
#define MIN(x1, x2) ((x1) < (x2) ? (x1) : (x2))
#define MAX(x1, x2) ((x1) > (x2) ? (x1) : (x2))
typedef int pixman_bool_t;
typedef pixman_box16_t box_type_t;
typedef pixman_region16_data_t region_data_type_t;
typedef pixman_region16_t region_type_t;
typedef signed int overflow_int_t;
#define PREFIX(x) pixman_region##x
#define PIXMAN_REGION_MAX INT16_MAX
#define PIXMAN_REGION_MIN INT16_MIN
#define FUNC "func"
#define critical_if_fail(expr)
int _pixman_log_error(const char *func, const char *format, ...)
{
return 0;
}
#include "pixman-region.c"

View File

@ -112,6 +112,10 @@ AC_ARG_ENABLE(mp3lame, AS_HELP_STRING([--enable-mp3lame],
[Build lame mp3(audio codec) (default: no)]),
[], [enable_mp3lame=no])
AM_CONDITIONAL(XRDP_MP3LAME, [test x$enable_mp3lame = xyes])
AC_ARG_ENABLE(pixman, AS_HELP_STRING([--enable-pixman],
[Use pixman library (default: no)]),
[], [enable_pimanno])
AM_CONDITIONAL(XRDP_PIXMAN, [test x$enable_pixman = xyes])
# checking for openssl
AC_CHECK_HEADER([openssl/rc4.h], [],
@ -191,6 +195,8 @@ then
[AC_MSG_ERROR([please install libmp3lame-dev or lamemp3-devel])])
fi
AS_IF( [test "x$enable_pixman" = "xyes"] , [PKG_CHECK_MODULES(XRDP_PIXMAN, pixman-1 >= 0.1.0)] )
# checking for TurboJPEG
if test "x$enable_tjpeg" = "xyes"
then

View File

@ -14,6 +14,12 @@ EXTRA_INCLUDES += -I$(top_srcdir)/librfxcodec/include
EXTRA_LIBS += $(top_srcdir)/librfxcodec/src/librfxencode.a
endif
if XRDP_PIXMAN
EXTRA_DEFINES += -DXRDP_PIXMAN
EXTRA_INCLUDES += $(XRDP_PIXMAN_CFLAGS)
EXTRA_LIBS += $(XRDP_PIXMAN_LIBS)
endif
AM_CPPFLAGS = \
-DXRDP_CFG_PATH=\"${sysconfdir}/xrdp\" \
-DXRDP_SBIN_PATH=\"${sbindir}\" \

View File

@ -175,9 +175,6 @@ xrdp_region_delete(struct xrdp_region* self);
int APP_CC
xrdp_region_add_rect(struct xrdp_region* self, struct xrdp_rect* rect);
int APP_CC
xrdp_region_insert_rect(struct xrdp_region* self, int i, int left,
int top, int right, int bottom);
int APP_CC
xrdp_region_subtract_rect(struct xrdp_region* self,
struct xrdp_rect* rect);
int APP_CC

View File

@ -20,6 +20,12 @@
#include "xrdp.h"
#if defined(XRDP_PIXMAN)
#include <pixman.h>
#else
#include "pixman-region.h"
#endif
/*****************************************************************************/
struct xrdp_region *APP_CC
xrdp_region_create(struct xrdp_wm *wm)
@ -28,8 +34,9 @@ xrdp_region_create(struct xrdp_wm *wm)
self = (struct xrdp_region *)g_malloc(sizeof(struct xrdp_region), 1);
self->wm = wm;
self->rects = list_create();
self->rects->auto_free = 1;
self->reg = (struct pixman_region16 *)
g_malloc(sizeof(struct pixman_region16), 1);
pixman_region_init(self->reg);
return self;
}
@ -41,276 +48,66 @@ xrdp_region_delete(struct xrdp_region *self)
{
return;
}
list_delete(self->rects);
pixman_region_fini(self->reg);
g_free(self->reg);
g_free(self);
}
/*****************************************************************************/
/* returns error */
int APP_CC
xrdp_region_add_rect(struct xrdp_region *self, struct xrdp_rect *rect)
{
struct xrdp_rect *r;
struct pixman_region16 lreg;
r = (struct xrdp_rect *)g_malloc(sizeof(struct xrdp_rect), 1);
*r = *rect;
list_add_item(self->rects, (long)r);
return 0;
}
/*****************************************************************************/
int APP_CC
xrdp_region_insert_rect(struct xrdp_region *self, int i, int left,
int top, int right, int bottom)
{
struct xrdp_rect *r;
r = (struct xrdp_rect *)g_malloc(sizeof(struct xrdp_rect), 1);
r->left = left;
r->top = top;
r->right = right;
r->bottom = bottom;
list_insert_item(self->rects, i, (long)r);
return 0;
}
/*****************************************************************************/
int APP_CC
xrdp_region_subtract_rect(struct xrdp_region *self,
struct xrdp_rect *rect)
{
struct xrdp_rect *r;
struct xrdp_rect rect1;
int i;
for (i = self->rects->count - 1; i >= 0; i--)
pixman_region_init_rect(&lreg, rect->left, rect->top,
rect->right - rect->left,
rect->bottom - rect->top);
if (!pixman_region_union(self->reg, self->reg, &lreg))
{
r = (struct xrdp_rect *)list_get_item(self->rects, i);
rect1 = *r;
r = &rect1;
if (rect->left <= r->left &&
rect->top <= r->top &&
rect->right >= r->right &&
rect->bottom >= r->bottom)
{
/* rect is not visible */
list_remove_item(self->rects, i);
}
else if (rect->right < r->left ||
rect->bottom < r->top ||
rect->top > r->bottom ||
rect->left > r->right)
{
/* rect are not related */
}
else if (rect->left <= r->left &&
rect->right >= r->right &&
rect->bottom < r->bottom &&
rect->top <= r->top)
{
/* partially covered(whole top) */
list_remove_item(self->rects, i);
xrdp_region_insert_rect(self, i, r->left, rect->bottom,
r->right, r->bottom);
}
else if (rect->top <= r->top &&
rect->bottom >= r->bottom &&
rect->right < r->right &&
rect->left <= r->left)
{
/* partially covered(left) */
list_remove_item(self->rects, i);
xrdp_region_insert_rect(self, i, rect->right, r->top,
r->right, r->bottom);
}
else if (rect->left <= r->left &&
rect->right >= r->right &&
rect->top > r->top &&
rect->bottom >= r->bottom)
{
/* partially covered(bottom) */
list_remove_item(self->rects, i);
xrdp_region_insert_rect(self, i, r->left, r->top,
r->right, rect->top);
}
else if (rect->top <= r->top &&
rect->bottom >= r->bottom &&
rect->left > r->left &&
rect->right >= r->right)
{
/* partially covered(right) */
list_remove_item(self->rects, i);
xrdp_region_insert_rect(self, i, r->left, r->top,
rect->left, r->bottom);
}
else if (rect->left <= r->left &&
rect->top <= r->top &&
rect->right < r->right &&
rect->bottom < r->bottom)
{
/* partially covered(top left) */
list_remove_item(self->rects, i);
xrdp_region_insert_rect(self, i, rect->right, r->top,
r->right, rect->bottom);
xrdp_region_insert_rect(self, i, r->left, rect->bottom,
r->right, r->bottom);
}
else if (rect->left <= r->left &&
rect->bottom >= r->bottom &&
rect->right < r->right &&
rect->top > r->top)
{
/* partially covered(bottom left) */
list_remove_item(self->rects, i);
xrdp_region_insert_rect(self, i, r->left, r->top,
r->right, rect->top);
xrdp_region_insert_rect(self, i, rect->right, rect->top,
r->right, r->bottom);
}
else if (rect->left > r->left &&
rect->right >= r->right &&
rect->top <= r->top &&
rect->bottom < r->bottom)
{
/* partially covered(top right) */
list_remove_item(self->rects, i);
xrdp_region_insert_rect(self, i, r->left, r->top,
rect->left, r->bottom);
xrdp_region_insert_rect(self, i, rect->left, rect->bottom,
r->right, r->bottom);
}
else if (rect->left > r->left &&
rect->right >= r->right &&
rect->top > r->top &&
rect->bottom >= r->bottom)
{
/* partially covered(bottom right) */
list_remove_item(self->rects, i);
xrdp_region_insert_rect(self, i, r->left, r->top,
r->right, rect->top);
xrdp_region_insert_rect(self, i, r->left, rect->top,
rect->left, r->bottom);
}
else if (rect->left > r->left &&
rect->top <= r->top &&
rect->right < r->right &&
rect->bottom >= r->bottom)
{
/* 2 rects, one on each end */
list_remove_item(self->rects, i);
xrdp_region_insert_rect(self, i, r->left, r->top,
rect->left, r->bottom);
xrdp_region_insert_rect(self, i, rect->right, r->top,
r->right, r->bottom);
}
else if (rect->left <= r->left &&
rect->top > r->top &&
rect->right >= r->right &&
rect->bottom < r->bottom)
{
/* 2 rects, one on each end */
list_remove_item(self->rects, i);
xrdp_region_insert_rect(self, i, r->left, r->top,
r->right, rect->top);
xrdp_region_insert_rect(self, i, r->left, rect->bottom,
r->right, r->bottom);
}
else if (rect->left > r->left &&
rect->right < r->right &&
rect->top <= r->top &&
rect->bottom < r->bottom)
{
/* partially covered(top) */
list_remove_item(self->rects, i);
xrdp_region_insert_rect(self, i, r->left, r->top,
rect->left, r->bottom);
xrdp_region_insert_rect(self, i, rect->left, rect->bottom,
rect->right, r->bottom);
xrdp_region_insert_rect(self, i, rect->right, r->top,
r->right, r->bottom);
}
else if (rect->top > r->top &&
rect->bottom < r->bottom &&
rect->left <= r->left &&
rect->right < r->right)
{
/* partially covered(left) */
list_remove_item(self->rects, i);
xrdp_region_insert_rect(self, i, r->left, r->top,
r->right, rect->top);
xrdp_region_insert_rect(self, i, rect->right, rect->top,
r->right, rect->bottom);
xrdp_region_insert_rect(self, i, r->left, rect->bottom,
r->right, r->bottom);
}
else if (rect->left > r->left &&
rect->right < r->right &&
rect->bottom >= r->bottom &&
rect->top > r->top)
{
/* partially covered(bottom) */
list_remove_item(self->rects, i);
xrdp_region_insert_rect(self, i, r->left, r->top,
rect->left, r->bottom);
xrdp_region_insert_rect(self, i, rect->left, r->top,
rect->right, rect->top);
xrdp_region_insert_rect(self, i, rect->right, r->top,
r->right, r->bottom);
}
else if (rect->top > r->top &&
rect->bottom < r->bottom &&
rect->right >= r->right &&
rect->left > r->left)
{
/* partially covered(right) */
list_remove_item(self->rects, i);
xrdp_region_insert_rect(self, i, r->left, r->top,
r->right, rect->top);
xrdp_region_insert_rect(self, i, r->left, rect->top,
rect->left, rect->bottom);
xrdp_region_insert_rect(self, i, r->left, rect->bottom,
r->right, r->bottom);
}
else if (rect->left > r->left &&
rect->top > r->top &&
rect->right < r->right &&
rect->bottom < r->bottom)
{
/* totally contained, 4 rects */
list_remove_item(self->rects, i);
xrdp_region_insert_rect(self, i, r->left, r->top,
r->right, rect->top);
xrdp_region_insert_rect(self, i, r->left, rect->top,
rect->left, rect->bottom);
xrdp_region_insert_rect(self, i, r->left, rect->bottom,
r->right, r->bottom);
xrdp_region_insert_rect(self, i, rect->right, rect->top,
r->right, rect->bottom);
}
else
{
g_writeln("error in xrdp_region_subtract_rect");
}
pixman_region_fini(&lreg);
return 1;
}
pixman_region_fini(&lreg);
return 0;
}
/*****************************************************************************/
/* returns error */
int APP_CC
xrdp_region_subtract_rect(struct xrdp_region *self, struct xrdp_rect *rect)
{
struct pixman_region16 lreg;
pixman_region_init_rect(&lreg, rect->left, rect->top,
rect->right - rect->left,
rect->bottom - rect->top);
if (!pixman_region_subtract(self->reg, self->reg, &lreg))
{
pixman_region_fini(&lreg);
return 1;
}
pixman_region_fini(&lreg);
return 0;
}
/*****************************************************************************/
/* returns error */
int APP_CC
xrdp_region_get_rect(struct xrdp_region *self, int index,
struct xrdp_rect *rect)
{
struct xrdp_rect *r;
struct pixman_box16 *box;
int count;
r = (struct xrdp_rect *)list_get_item(self->rects, index);
if (r == 0)
box = pixman_region_rectangles(self->reg, &count);
if ((box != 0) && (index >= 0) && (index < count))
{
return 1;
rect->left = box[index].x1;
rect->top = box[index].y1;
rect->right = box[index].x2;
rect->bottom = box[index].y2;
return 0;
}
*rect = *r;
return 0;
return 1;
}

View File

@ -411,7 +411,7 @@ struct xrdp_listen
struct xrdp_region
{
struct xrdp_wm* wm; /* owner */
struct list* rects;
struct pixman_region16 *reg;
};
/* painter */