/** * xrdp: A Remote Desktop Protocol server. * * Copyright (C) Jay Sorg 2004-2014 * * 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 */ #include "xrdp.h" /*****************************************************************************/ struct xrdp_region *APP_CC xrdp_region_create(struct xrdp_wm *wm) { struct xrdp_region *self; self = (struct xrdp_region *)g_malloc(sizeof(struct xrdp_region), 1); self->wm = wm; self->rects = list_create(); self->rects->auto_free = 1; return self; } /*****************************************************************************/ void APP_CC xrdp_region_delete(struct xrdp_region *self) { if (self == 0) { return; } list_delete(self->rects); g_free(self); } /*****************************************************************************/ int APP_CC xrdp_region_add_rect(struct xrdp_region *self, struct xrdp_rect *rect) { struct xrdp_rect *r; 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--) { 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"); } } return 0; } /*****************************************************************************/ int APP_CC xrdp_region_get_rect(struct xrdp_region *self, int index, struct xrdp_rect *rect) { struct xrdp_rect *r; r = (struct xrdp_rect *)list_get_item(self->rects, index); if (r == 0) { return 1; } *rect = *r; return 0; }