/* * $Id$ * * Copyright © 2004 Keith Packard * * 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 Keith Packard not be used in * advertising or publicity pertaining to distribution of the software without * specific, written prior permission. Keith Packard makes no * representations about the suitability of this software for any purpose. It * is provided "as is" without express or implied warranty. * * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO * EVENT SHALL KEITH PACKARD 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. */ #include "lpint.h" static void add_damage (light_pipe_window *lpw) { light_pipe_display *lpd = _xlightpipe_find_display (lpw->display); light_pipe_window **prev; if (!lpd) return; for (prev = &lpd->damaged; *prev; prev = &(*prev)->next_damaged) if ((*prev) == lpw) return; lpw->next_damaged = *prev; *prev = lpw; } static void remove_damage (light_pipe_window *lpw) { light_pipe_display *lpd = _xlightpipe_find_display (lpw->display); light_pipe_window **prev; if (!lpd) return; for (prev = &lpd->damaged; *prev; prev = &(*prev)->next_damaged) if ((*prev) == lpw) { *prev = lpw->next_damaged; break; } } void _xlightpipe_damage_window (light_pipe_window *lpw, int x, int y, int width, int height) { add_damage (lpw); if (lpw->public.damage.width == 0) { lpw->public.damage.x = x; lpw->public.damage.y = y; lpw->public.damage.width = width; lpw->public.damage.height = height; } else { int old_x2 = lpw->public.damage.x + lpw->public.damage.width; int old_y2 = lpw->public.damage.y + lpw->public.damage.height; int new_x2 = x + width; int new_y2 = y + height; if (x < lpw->public.damage.x) lpw->public.damage.x = x; if (new_x2 > old_x2) old_x2 = new_x2; lpw->public.damage.width = old_x2 - lpw->public.damage.x; if (y < lpw->public.damage.y) lpw->public.damage.y = y; if (new_y2 > old_y2) old_y2 = new_y2; lpw->public.damage.height = old_y2 - lpw->public.damage.y; } if (lpw->public.damage_region) { XRectangle r; r.x = x; r.y = y; r.width = width; r.height = height; XUnionRectWithRegion (&r, lpw->public.damage_region, lpw->public.damage_region); } } void _xlightpipe_update_window (light_pipe_window *lpw) { if (lpw->public.damage.width && lpw->public.damage.height) { XFixesSetRegion (lpw->display, lpw->repair, &lpw->public.damage, 1); XDamageSubtract (lpw->display, lpw->damage, lpw->repair, None); _xlightpipe_update_region (lpw, lpw->public.damage.x, lpw->public.damage.y, lpw->public.damage.width, lpw->public.damage.height); XSync (lpw->display, False); } } void _xlightpipe_undamage_window (light_pipe_window *lpw) { remove_damage (lpw); lpw->public.damage.x = lpw->public.damage.y = 0; lpw->public.damage.width = lpw->public.damage.height = 0; if (lpw->public.damage_region) { Region empty = XCreateRegion (); XIntersectRegion (lpw->public.damage_region, empty, lpw->public.damage_region); XDestroyRegion (empty); } } light_pipe_window * _xlightpipe_find_damaged (Display *display) { light_pipe_display *lpd; lpd = _xlightpipe_find_display (display); return lpd->damaged; }