summaryrefslogtreecommitdiffstats
path: root/x11vnc/xdamage.c
diff options
context:
space:
mode:
Diffstat (limited to 'x11vnc/xdamage.c')
-rw-r--r--x11vnc/xdamage.c840
1 files changed, 0 insertions, 840 deletions
diff --git a/x11vnc/xdamage.c b/x11vnc/xdamage.c
deleted file mode 100644
index 3eb12f5..0000000
--- a/x11vnc/xdamage.c
+++ /dev/null
@@ -1,840 +0,0 @@
-/*
- Copyright (C) 2002-2010 Karl J. Runge <runge@karlrunge.com>
- All rights reserved.
-
-This file is part of x11vnc.
-
-x11vnc is free software; you can redistribute it and/or modify
-it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2 of the License, or (at
-your option) any later version.
-
-x11vnc is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with x11vnc; if not, write to the Free Software
-Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA
-or see <http://www.gnu.org/licenses/>.
-
-In addition, as a special exception, Karl J. Runge
-gives permission to link the code of its release of x11vnc with the
-OpenSSL project's "OpenSSL" library (or with modified versions of it
-that use the same license as the "OpenSSL" library), and distribute
-the linked executables. You must obey the GNU General Public License
-in all respects for all of the code used other than "OpenSSL". If you
-modify this file, you may extend this exception to your version of the
-file, but you are not obligated to do so. If you do not wish to do
-so, delete this exception statement from your version.
-*/
-
-/* -- xdamage.c -- */
-
-#include "x11vnc.h"
-#include "xwrappers.h"
-#include "userinput.h"
-#include "unixpw.h"
-
-#if LIBVNCSERVER_HAVE_LIBXDAMAGE
-Damage xdamage = 0;
-#endif
-
-#ifndef XDAMAGE
-#define XDAMAGE 1
-#endif
-int use_xdamage = XDAMAGE; /* use the xdamage rects for scanline hints */
-int xdamage_present = 0;
-
-#ifdef MACOSX
-int xdamage_max_area = 50000;
-#else
-int xdamage_max_area = 20000; /* pixels */
-#endif
-
-double xdamage_memory = 1.0; /* in units of NSCAN */
-int xdamage_tile_count = 0, xdamage_direct_count = 0;
-double xdamage_scheduled_mark = 0.0;
-double xdamage_crazy_time = 0.0;
-double xdamage_crazy_delay = 300.0;
-sraRegionPtr xdamage_scheduled_mark_region = NULL;
-sraRegionPtr *xdamage_regions = NULL;
-int xdamage_ticker = 0;
-int XD_skip = 0, XD_tot = 0, XD_des = 0; /* for stats */
-
-void add_region_xdamage(sraRegionPtr new_region);
-void clear_xdamage_mark_region(sraRegionPtr markregion, int flush);
-int collect_non_X_xdamage(int x_in, int y_in, int w_in, int h_in, int call);
-int collect_xdamage(int scancnt, int call);
-int xdamage_hint_skip(int y);
-void initialize_xdamage(void);
-void create_xdamage_if_needed(int force);
-void destroy_xdamage_if_needed(void);
-void check_xdamage_state(void);
-
-static void record_desired_xdamage_rect(int x, int y, int w, int h);
-
-
-static void record_desired_xdamage_rect(int x, int y, int w, int h) {
- /*
- * Unfortunately we currently can't trust an xdamage event
- * to correspond to real screen damage. E.g. focus-in for
- * mozilla (depending on wm) will mark the whole toplevel
- * area as damaged, when only the border has changed.
- * Similar things for terminal windows.
- *
- * This routine uses some heuristics to detect small enough
- * damage regions that we will not have a performance problem
- * if we believe them even though they are wrong. We record
- * the corresponding tiles the damage regions touch.
- */
- int dt_x, dt_y, nt_x1, nt_y1, nt_x2, nt_y2, nt;
- int ix, iy, cnt = 0;
- int area = w*h, always_accept = 0;
- /*
- * XXX: not working yet, slow and overlaps with scan_display()
- * probably slow because tall skinny rectangles very inefficient
- * in general and in direct_fb_copy() (100X slower then horizontal).
- */
- int use_direct_fb_copy = 0;
- int wh_min, wh_max;
- static int first = 1, udfb = 0;
-
- /* compiler warning: */
- nt_x1 = 0; nt_y1 = 0; nt_x2 = 0; nt_y2 = 0;
-
- if (first) {
- if (getenv("XD_DFC")) {
- udfb = 1;
- }
- first = 0;
- }
- if (udfb) {
- use_direct_fb_copy = 1;
- }
-
- if (xdamage_max_area <= 0) {
- always_accept = 1;
- }
-
- if (!always_accept && area > xdamage_max_area) {
- return;
- }
-
- dt_x = w / tile_x;
- dt_y = h / tile_y;
-
- if (w < h) {
- wh_min = w;
- wh_max = h;
- } else {
- wh_min = h;
- wh_max = w;
- }
-
- if (!always_accept && dt_y >= 3 && area > 4000) {
- /*
- * if it is real it should be caught by a normal scanline
- * poll, but we might as well keep if small (tall line?).
- */
- return;
- }
-
- if (use_direct_fb_copy) {
- X_UNLOCK;
- direct_fb_copy(x, y, x + w, y + h, 1);
- xdamage_direct_count++;
- X_LOCK;
- } else if (0 && wh_min < tile_x/4 && wh_max > 30 * wh_min) {
- /* try it for long, skinny rects, XXX still no good */
- X_UNLOCK;
- direct_fb_copy(x, y, x + w, y + h, 1);
- xdamage_direct_count++;
- X_LOCK;
- } else {
-
- if (ntiles_x == 0 || ntiles_y == 0) {
- /* too early. */
- return;
- }
- nt_x1 = nfix( (x)/tile_x, ntiles_x);
- nt_x2 = nfix((x+w)/tile_x, ntiles_x);
- nt_y1 = nfix( (y)/tile_y, ntiles_y);
- nt_y2 = nfix((y+h)/tile_y, ntiles_y);
-
- /*
- * loop over the rectangle of tiles (1 tile for a small
- * input rect).
- */
- for (ix = nt_x1; ix <= nt_x2; ix++) {
- for (iy = nt_y1; iy <= nt_y2; iy++) {
- nt = ix + iy * ntiles_x;
- cnt++;
- if (! tile_has_xdamage_diff[nt]) {
- XD_des++;
- tile_has_xdamage_diff[nt] = 1;
- }
- /* not used: */
- tile_row_has_xdamage_diff[iy] = 1;
- xdamage_tile_count++;
- }
- }
- }
- if (debug_xdamage > 1) {
- fprintf(stderr, "xdamage: desired: %dx%d+%d+%d\tA: %6d tiles="
- "%02d-%02d/%02d-%02d tilecnt: %d\n", w, h, x, y,
- w * h, nt_x1, nt_x2, nt_y1, nt_y2, cnt);
- }
-}
-
-void add_region_xdamage(sraRegionPtr new_region) {
- sraRegionPtr reg;
- int prev_tick, nreg;
-
- if (! xdamage_regions) {
- return;
- }
-
- nreg = (xdamage_memory * NSCAN) + 1;
- prev_tick = xdamage_ticker - 1;
- if (prev_tick < 0) {
- prev_tick = nreg - 1;
- }
-
- reg = xdamage_regions[prev_tick];
- if (reg != NULL && new_region != NULL) {
-if (debug_xdamage > 1) fprintf(stderr, "add_region_xdamage: prev_tick: %d reg %p new_region %p\n", prev_tick, (void *)reg, (void *)new_region);
- sraRgnOr(reg, new_region);
- }
-}
-
-void clear_xdamage_mark_region(sraRegionPtr markregion, int flush) {
-#if LIBVNCSERVER_HAVE_LIBXDAMAGE
- XEvent ev;
- sraRegionPtr tmpregion;
- int count = 0;
-
- RAWFB_RET_VOID
-
- if (! xdamage_present || ! use_xdamage) {
- return;
- }
- if (! xdamage) {
- return;
- }
- if (! xdamage_base_event_type) {
- return;
- }
- if (unixpw_in_progress) return;
-
- X_LOCK;
- if (flush) {
- XFlush_wr(dpy);
- }
- while (XCheckTypedEvent(dpy, xdamage_base_event_type+XDamageNotify, &ev)) {
- count++;
- }
- /* clear the whole damage region */
- XDamageSubtract(dpy, xdamage, None, None);
- X_UNLOCK;
-
- if (debug_tiles || debug_xdamage) {
- fprintf(stderr, "clear_xdamage_mark_region: %d\n", count);
- }
-
- if (! markregion) {
- /* NULL means mark the whole display */
- tmpregion = sraRgnCreateRect(0, 0, dpy_x, dpy_y);
- add_region_xdamage(tmpregion);
- sraRgnDestroy(tmpregion);
- } else {
- add_region_xdamage(markregion);
- }
-#else
- if (0) flush++; /* compiler warnings */
- if (0) markregion = NULL;
-#endif
-}
-
-int collect_non_X_xdamage(int x_in, int y_in, int w_in, int h_in, int call) {
- sraRegionPtr tmpregion;
- sraRegionPtr reg;
- static int rect_count = 0;
- int nreg, ccount = 0, dcount = 0, ecount = 0;
- static time_t last_rpt = 0;
- time_t now;
- double tm, dt;
- int x, y, w, h, x2, y2;
-
-if (call && debug_xdamage > 1) fprintf(stderr, "collect_non_X_xdamage: %d %d %d %d - %d / %d\n", x_in, y_in, w_in, h_in, call, use_xdamage);
-
- if (! use_xdamage) {
- return 0;
- }
- if (! xdamage_regions) {
- return 0;
- }
-
- dtime0(&tm);
-
- nreg = (xdamage_memory * NSCAN) + 1;
-
- if (call == 0) {
- xdamage_ticker = (xdamage_ticker+1) % nreg;
- xdamage_direct_count = 0;
- reg = xdamage_regions[xdamage_ticker];
- if (reg != NULL) {
- sraRgnMakeEmpty(reg);
- }
- } else {
- if (xdamage_ticker < 0) {
- xdamage_ticker = 0;
- }
- reg = xdamage_regions[xdamage_ticker];
- }
- if (reg == NULL) {
- return 0;
- }
-
- if (x_in < 0) {
- return 0;
- }
-
-
- x = x_in;
- y = y_in;
- w = w_in;
- h = h_in;
-
- /* translate if needed */
- if (clipshift) {
- /* set coords relative to fb origin */
- if (0 && rootshift) {
- /*
- * Note: not needed because damage is
- * relative to subwin, not rootwin.
- */
- x = x - off_x;
- y = y - off_y;
- }
- if (clipshift) {
- x = x - coff_x;
- y = y - coff_y;
- }
-
- x2 = x + w; /* upper point */
- x = nfix(x, dpy_x); /* place both in fb area */
- x2 = nfix(x2, dpy_x+1);
- w = x2 - x; /* recompute w */
-
- y2 = y + h;
- y = nfix(y, dpy_y);
- y2 = nfix(y2, dpy_y+1);
- h = y2 - y;
-
- if (w <= 0 || h <= 0) {
- return 0;
- }
- }
- if (debug_xdamage > 2) {
- fprintf(stderr, "xdamage: -> event %dx%d+%d+%d area:"
- " %d dups: %d %s reg: %p\n", w, h, x, y, w*h, dcount,
- (w*h > xdamage_max_area) ? "TOO_BIG" : "", (void *)reg);
- }
-
- record_desired_xdamage_rect(x, y, w, h);
-
- tmpregion = sraRgnCreateRect(x, y, x + w, y + h);
- sraRgnOr(reg, tmpregion);
- sraRgnDestroy(tmpregion);
- rect_count++;
- ccount++;
-
- if (0 && xdamage_direct_count) {
- fb_push();
- }
-
- dt = dtime(&tm);
- if ((debug_tiles > 1 && ecount) || (debug_tiles && ecount > 200)
- || debug_xdamage > 1) {
- fprintf(stderr, "collect_non_X_xdamage(%d): %.4f t: %.4f ev/dup/accept"
- "/direct %d/%d/%d/%d\n", call, dt, tm - x11vnc_start, ecount,
- dcount, ccount, xdamage_direct_count);
- }
- now = time(NULL);
- if (! last_rpt) {
- last_rpt = now;
- }
- if (now > last_rpt + 15) {
- double rat = -1.0;
-
- if (XD_tot) {
- rat = ((double) XD_skip)/XD_tot;
- }
- if (debug_tiles || debug_xdamage) {
- fprintf(stderr, "xdamage: == scanline skip/tot: "
- "%04d/%04d =%.3f rects: %d desired: %d\n",
- XD_skip, XD_tot, rat, rect_count, XD_des);
- }
-
- XD_skip = 0;
- XD_tot = 0;
- XD_des = 0;
- rect_count = 0;
- last_rpt = now;
- }
- return 0;
-}
-
-int collect_xdamage(int scancnt, int call) {
-#if LIBVNCSERVER_HAVE_LIBXDAMAGE
- XDamageNotifyEvent *dev;
- XEvent ev;
- sraRegionPtr tmpregion;
- sraRegionPtr reg;
- static int rect_count = 0;
- int nreg, ccount = 0, dcount = 0, ecount = 0;
- static time_t last_rpt = 0;
- time_t now;
- int x, y, w, h, x2, y2;
- int i, dup, next = 0, dup_max = 0;
-#define DUPSZ 32
- int dup_x[DUPSZ], dup_y[DUPSZ], dup_w[DUPSZ], dup_h[DUPSZ];
- double tm, dt;
- int mark_all = 0, retries = 0, too_many = 1000, tot_ev = 0;
-
- RAWFB_RET(0)
-
- if (scancnt) {} /* unused vars warning: */
-
- if (! xdamage_present || ! use_xdamage) {
- return 0;
- }
- if (! xdamage) {
- return 0;
- }
- if (! xdamage_base_event_type) {
- return 0;
- }
- if (! xdamage_regions) {
- return 0;
- }
-
- dtime0(&tm);
-
- nreg = (xdamage_memory * NSCAN) + 1;
-
- if (call == 0) {
- xdamage_ticker = (xdamage_ticker+1) % nreg;
- xdamage_direct_count = 0;
- reg = xdamage_regions[xdamage_ticker];
- if (reg != NULL) {
- sraRgnMakeEmpty(reg);
- }
- } else {
- if (xdamage_ticker < 0) {
- xdamage_ticker = 0;
- }
- reg = xdamage_regions[xdamage_ticker];
- }
- if (reg == NULL) {
- return 0;
- }
-
-
- X_LOCK;
-if (0) XFlush_wr(dpy);
-if (0) XEventsQueued(dpy, QueuedAfterFlush);
-
- come_back_for_more:
-
- while (XCheckTypedEvent(dpy, xdamage_base_event_type+XDamageNotify, &ev)) {
- /*
- * TODO max cut off time in this loop?
- * Could check QLength and if huge just mark the whole
- * screen.
- */
- ecount++;
- tot_ev++;
-
- if (mark_all) {
- continue;
- }
- if (ecount == too_many) {
- int nqa = XEventsQueued(dpy, QueuedAlready);
- if (nqa >= too_many) {
- static double last_msg = 0.0;
- tmpregion = sraRgnCreateRect(0, 0, dpy_x, dpy_y);
- sraRgnOr(reg, tmpregion);
- sraRgnDestroy(tmpregion);
- if (dnow() > last_msg + xdamage_crazy_delay) {
- rfbLog("collect_xdamage: too many xdamage events %d+%d\n", ecount, nqa);
- last_msg = dnow();
- }
- mark_all = 1;
- }
- }
-
- if (ev.type != xdamage_base_event_type + XDamageNotify) {
- break;
- }
- dev = (XDamageNotifyEvent *) &ev;
- if (dev->damage != xdamage) {
- continue; /* not ours! */
- }
-
- x = dev->area.x;
- y = dev->area.y;
- w = dev->area.width;
- h = dev->area.height;
-
- /*
- * we try to manually remove some duplicates because
- * certain activities can lead to many 10's of dups
- * in a row. The region work can be costly and reg is
- * later used in xdamage_hint_skip loops, so it is good
- * to skip them if possible.
- */
- dup = 0;
- for (i=0; i < dup_max; i++) {
- if (dup_x[i] == x && dup_y[i] == y && dup_w[i] == w &&
- dup_h[i] == h) {
- dup = 1;
- break;
- }
- }
- if (dup) {
- dcount++;
- continue;
- }
- if (dup_max < DUPSZ) {
- next = dup_max;
- dup_max++;
- } else {
- next = (next+1) % DUPSZ;
- }
- dup_x[next] = x;
- dup_y[next] = y;
- dup_w[next] = w;
- dup_h[next] = h;
-
- /* translate if needed */
- if (clipshift) {
- /* set coords relative to fb origin */
- if (0 && rootshift) {
- /*
- * Note: not needed because damage is
- * relative to subwin, not rootwin.
- */
- x = x - off_x;
- y = y - off_y;
- }
- if (clipshift) {
- x = x - coff_x;
- y = y - coff_y;
- }
-
- x2 = x + w; /* upper point */
- x = nfix(x, dpy_x); /* place both in fb area */
- x2 = nfix(x2, dpy_x+1);
- w = x2 - x; /* recompute w */
-
- y2 = y + h;
- y = nfix(y, dpy_y);
- y2 = nfix(y2, dpy_y+1);
- h = y2 - y;
-
- if (w <= 0 || h <= 0) {
- continue;
- }
- }
- if (debug_xdamage > 2) {
- fprintf(stderr, "xdamage: -> event %dx%d+%d+%d area:"
- " %d dups: %d %s\n", w, h, x, y, w*h, dcount,
- (w*h > xdamage_max_area) ? "TOO_BIG" : "");
- }
-
- record_desired_xdamage_rect(x, y, w, h);
-
- tmpregion = sraRgnCreateRect(x, y, x + w, y + h);
- sraRgnOr(reg, tmpregion);
- sraRgnDestroy(tmpregion);
- rect_count++;
- ccount++;
- }
-
- if (mark_all) {
- if (ecount + XEventsQueued(dpy, QueuedAlready) >= 3 * too_many && retries < 3) {
- retries++;
- XFlush_wr(dpy);
- usleep(20 * 1000);
- XFlush_wr(dpy);
- ecount = 0;
- goto come_back_for_more;
- }
- }
-
- /* clear the whole damage region for next time. XXX check */
- if (call == 1) {
- XDamageSubtract(dpy, xdamage, None, None);
- }
- X_UNLOCK;
-
- if (tot_ev > 20 * too_many) {
- rfbLog("collect_xdamage: xdamage has gone crazy (screensaver or game?) ev: %d ret: %d\n", tot_ev, retries);
- rfbLog("collect_xdamage: disabling xdamage for %d seconds.\n", (int) xdamage_crazy_delay);
- destroy_xdamage_if_needed();
- X_LOCK;
- XSync(dpy, False);
- while (XCheckTypedEvent(dpy, xdamage_base_event_type+XDamageNotify, &ev)) {
- ;
- }
- X_UNLOCK;
- xdamage_crazy_time = dnow();
- }
-
- if (0 && xdamage_direct_count) {
- fb_push();
- }
-
- dt = dtime(&tm);
- if ((debug_tiles > 1 && ecount) || (debug_tiles && ecount > 200)
- || debug_xdamage > 1) {
- fprintf(stderr, "collect_xdamage(%d): %.4f t: %.4f ev/dup/accept"
- "/direct %d/%d/%d/%d\n", call, dt, tm - x11vnc_start, ecount,
- dcount, ccount, xdamage_direct_count);
- }
- now = time(NULL);
- if (! last_rpt) {
- last_rpt = now;
- }
- if (now > last_rpt + 15) {
- double rat = -1.0;
-
- if (XD_tot) {
- rat = ((double) XD_skip)/XD_tot;
- }
- if (debug_tiles || debug_xdamage) {
- fprintf(stderr, "xdamage: == scanline skip/tot: "
- "%04d/%04d =%.3f rects: %d desired: %d\n",
- XD_skip, XD_tot, rat, rect_count, XD_des);
- }
-
- XD_skip = 0;
- XD_tot = 0;
- XD_des = 0;
- rect_count = 0;
- last_rpt = now;
- }
-#else
- if (0) scancnt++; /* compiler warnings */
- if (0) call++;
- if (0) record_desired_xdamage_rect(0, 0, 0, 0);
-#endif
- return 0;
-}
-
-int xdamage_hint_skip(int y) {
- static sraRegionPtr scanline = NULL;
- static sraRegionPtr tmpl_y = NULL;
- int fast_tmpl = 1;
- sraRegionPtr reg, tmpl;
- int ret, i, n, nreg;
-#ifndef NO_NCACHE
- static int ncache_no_skip = 0;
- static double last_ncache_no_skip = 0.0;
- static double last_ncache_no_skip_long = 0.0, ncache_fac = 0.25;
-#endif
-
- if (! xdamage_present || ! use_xdamage) {
- return 0; /* cannot skip */
- }
- if (! xdamage_regions) {
- return 0; /* cannot skip */
- }
-
- if (! scanline) {
- /* keep it around to avoid malloc etc, recreate */
- scanline = sraRgnCreate();
- }
- if (! tmpl_y) {
- tmpl_y = sraRgnCreateRect(0, 0, dpy_x, 1);
- }
-
- nreg = (xdamage_memory * NSCAN) + 1;
-
-#ifndef NO_NCACHE
- if (ncache > 0) {
- if (ncache_no_skip == 0) {
- double now = g_now;
- if (now > last_ncache_no_skip + 8.0) {
- ncache_no_skip = 1;
- } else if (now < last_bs_restore + 0.5) {
- ncache_no_skip = 1;
- } else if (now < last_su_restore + 0.5) {
- ncache_no_skip = 1;
- } else if (now < last_copyrect + 0.5) {
- ncache_no_skip = 1;
- }
- if (ncache_no_skip) {
- last_ncache_no_skip = dnow();
- if (now > last_ncache_no_skip_long + 60.0) {
- ncache_fac = 2.0;
- last_ncache_no_skip_long = now;
- } else {
- ncache_fac = 0.25;
- }
- return 0;
- }
- } else {
- if (ncache_no_skip++ >= ncache_fac*nreg + 4) {
- ncache_no_skip = 0;
- } else {
- return 0;
- }
- }
- }
-#endif
-
- if (fast_tmpl) {
- sraRgnOffset(tmpl_y, 0, y);
- tmpl = tmpl_y;
- } else {
- tmpl = sraRgnCreateRect(0, y, dpy_x, y+1);
- }
-
- ret = 1;
- for (i=0; i<nreg; i++) {
- /* go back thru the history starting at most recent */
- n = (xdamage_ticker + nreg - i) % nreg;
- reg = xdamage_regions[n];
- if (reg == NULL) {
- continue;
- }
- if (sraRgnEmpty(reg)) {
- /* checking for emptiness is very fast */
- continue;
- }
- sraRgnMakeEmpty(scanline);
- sraRgnOr(scanline, tmpl);
- if (sraRgnAnd(scanline, reg)) {
- ret = 0;
- break;
- }
- }
- if (fast_tmpl) {
- sraRgnOffset(tmpl_y, 0, -y);
- } else {
- sraRgnDestroy(tmpl);
- }
-if (0) fprintf(stderr, "xdamage_hint_skip: %d -> %d\n", y, ret);
-
- return ret;
-}
-
-void initialize_xdamage(void) {
- sraRegionPtr *ptr;
- int i, nreg;
-
- if (! xdamage_present) {
- use_xdamage = 0;
- }
- if (xdamage_regions) {
- ptr = xdamage_regions;
- while (*ptr != NULL) {
- sraRgnDestroy(*ptr);
- ptr++;
- }
- free(xdamage_regions);
- xdamage_regions = NULL;
- }
- if (use_xdamage) {
- nreg = (xdamage_memory * NSCAN) + 2;
- xdamage_regions = (sraRegionPtr *)
- malloc(nreg * sizeof(sraRegionPtr));
- for (i = 0; i < nreg; i++) {
- ptr = xdamage_regions+i;
- if (i == nreg - 1) {
- *ptr = NULL;
- } else {
- *ptr = sraRgnCreate();
- sraRgnMakeEmpty(*ptr);
- }
- }
- /* set so will be 0 in first collect_xdamage call */
- xdamage_ticker = -1;
- }
-}
-
-void create_xdamage_if_needed(int force) {
-
- RAWFB_RET_VOID
-
- if (force) {}
-
-#if LIBVNCSERVER_HAVE_LIBXDAMAGE
- if (! xdamage || force) {
- X_LOCK;
- xdamage = XDamageCreate(dpy, window, XDamageReportRawRectangles);
- XDamageSubtract(dpy, xdamage, None, None);
- X_UNLOCK;
- rfbLog("created xdamage object: 0x%lx\n", xdamage);
- }
-#endif
-}
-
-void destroy_xdamage_if_needed(void) {
-
- RAWFB_RET_VOID
-
-#if LIBVNCSERVER_HAVE_LIBXDAMAGE
- if (xdamage) {
- XEvent ev;
- X_LOCK;
- XDamageDestroy(dpy, xdamage);
- XFlush_wr(dpy);
- if (xdamage_base_event_type) {
- while (XCheckTypedEvent(dpy,
- xdamage_base_event_type+XDamageNotify, &ev)) {
- ;
- }
- }
- X_UNLOCK;
- rfbLog("destroyed xdamage object: 0x%lx\n", xdamage);
- xdamage = 0;
- }
-#endif
-}
-
-void check_xdamage_state(void) {
- if (! xdamage_present) {
- return;
- }
- /*
- * Create or destroy the Damage object as needed, we don't want
- * one if no clients are connected.
- */
- if (xdamage_crazy_time > 0.0 && dnow() < xdamage_crazy_time + xdamage_crazy_delay) {
- return;
- }
- if (client_count && use_xdamage) {
- create_xdamage_if_needed(0);
- if (xdamage_scheduled_mark > 0.0 && dnow() >
- xdamage_scheduled_mark) {
- if (xdamage_scheduled_mark_region) {
- mark_region_for_xdamage(
- xdamage_scheduled_mark_region);
- sraRgnDestroy(xdamage_scheduled_mark_region);
- xdamage_scheduled_mark_region = NULL;
- } else {
- mark_for_xdamage(0, 0, dpy_x, dpy_y);
- }
- xdamage_scheduled_mark = 0.0;
- }
- } else {
- destroy_xdamage_if_needed();
- }
-}
-
-
OpenPOWER on IntegriCloud