diff options
Diffstat (limited to 'lpdamage.c')
-rw-r--r-- | lpdamage.c | 126 |
1 files changed, 126 insertions, 0 deletions
diff --git a/lpdamage.c b/lpdamage.c new file mode 100644 index 0000000..d87c66a --- /dev/null +++ b/lpdamage.c @@ -0,0 +1,126 @@ +/* + * $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 = 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 = 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 +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; + } +} + +void +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); + update_region (lpw, + lpw->public.damage.x, + lpw->public.damage.y, + lpw->public.damage.width, + lpw->public.damage.height); + XSync (lpw->display, False); + } +} + +void +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; +} + +light_pipe_window * +find_damaged (Display *display) +{ + light_pipe_display *lpd; + + lpd = find_display (display); + return lpd->damaged; +} |