summaryrefslogtreecommitdiffstats
path: root/x11vnc/8to24.c
diff options
context:
space:
mode:
Diffstat (limited to 'x11vnc/8to24.c')
-rw-r--r--x11vnc/8to24.c1065
1 files changed, 790 insertions, 275 deletions
diff --git a/x11vnc/8to24.c b/x11vnc/8to24.c
index 873ba25..bfe9292 100644
--- a/x11vnc/8to24.c
+++ b/x11vnc/8to24.c
@@ -10,17 +10,25 @@ int multivis_24count = 0;
void check_for_multivis(void);
void bpp8to24(int, int, int, int);
-void mark_8bpp(void);
+void mark_8bpp(int);
static void set_root_cmap(void);
-static void check_pointer_in_depth24(void);
+static int check_pointer_in_depth24(void);
static void parse_cmap8to24(void);
+static void set_poll_fb(void);
static int check_depth(Window win, Window top, int doall);
static int check_depth_win(Window win, Window top, XWindowAttributes attr);
-static int get_8pp_region(sraRegionPtr region8bpp, sraRegionPtr rect,
- int validate);
+static XImage *p_xi(XImage *xi, Visual *visual, int win_depth, int *w);
+static int poll_line(int x1, int x2, int y1, int n, sraRegionPtr mod);
+static void poll_line_complement(int x1, int x2, int y1, sraRegionPtr mod);
+static int poll_8bpp(sraRegionPtr, int);
+static void poll_8bpp_complement(sraRegionPtr);
+static void mark_rgn_rects(sraRegionPtr mod);
+static int get_8bpp_regions(int validate);
static int get_cmap(int j, Colormap cmap);
-static void do_8bpp_region(sraRect rect);
+static void do_8bpp_region(int n, sraRegionPtr mark);
+static XImage *cmap_xi(XImage *xi, Visual *visual, int win_depth);
+static void transform_rect(sraRect rect, Window win, int win_depth, int cm);
/* struct for keeping info about the 8bpp windows: */
typedef struct window8 {
@@ -33,9 +41,17 @@ typedef struct window8 {
Colormap cmap;
Bool map_installed;
int fetched;
+ sraRegionPtr clip_region;
} window8bpp_t;
+enum mark_8bpp_modes {
+ MARK_8BPP_ALL = 0,
+ MARK_8BPP_POINTER,
+ MARK_8BPP_TOP
+};
+
static Colormap root_cmap = 0;
+
static void set_root_cmap(void) {
static time_t last_set = 0;
time_t now = time(0);
@@ -59,11 +75,10 @@ static void set_root_cmap(void) {
static window8bpp_t windows_8bpp[MAX_8BPP_WINDOWS];
static int db24 = 0;
-static int xgetimage_8to24 = 0;
-static int do_hibits = 0;
-static double poll_8to24_delay = 0.0;
+static int xgetimage_8to24 = 1;
+static double poll_8to24_delay = POLL_8TO24_DELAY;
-static void check_pointer_in_depth24(void) {
+static int check_pointer_in_depth24(void) {
int tries = 0, in_24 = 0;
XWindowAttributes attr;
Window c, w;
@@ -72,7 +87,7 @@ static void check_pointer_in_depth24(void) {
c = window;
if (now > last_keyboard_time + 1.0 && now > last_pointer_time + 1.0) {
- return;
+ return 0;
}
X_LOCK;
@@ -95,27 +110,32 @@ static void check_pointer_in_depth24(void) {
y2 = y1 + attr.height;
x1 = nfix(x1, dpy_x);
y1 = nfix(y1, dpy_y);
- x2 = nfix(x2, dpy_x);
- y2 = nfix(y2, dpy_y);
-if (db24 > 1) fprintf(stderr, "check_pointer_in_depth24 %d %d %d %d\n", x1, y1, x2, y2);
+ x2 = nfix(x2, dpy_x+1);
+ y2 = nfix(y2, dpy_y+1);
mark_rect_as_modified(x1, y1, x2, y2, 0);
+
+if (db24 > 1) fprintf(stderr, "check_pointer_in_depth24 %d %d %d %d\n", x1, y1, x2, y2);
+
+ return 1;
}
+ return 0;
}
static void parse_cmap8to24(void) {
if (cmap8to24_str) {
char *p, *str = strdup(cmap8to24_str);
p = strtok(str, ",");
+ /* defaults: */
db24 = 0;
- xgetimage_8to24 = 0;
- do_hibits = 0;
+ xgetimage_8to24 = 1;
+ poll_8to24_delay = POLL_8TO24_DELAY;
while (p) {
if (strstr(p, "dbg=") == p) {
db24 = atoi(p + strlen("dbg="));
- } else if (!strcmp(p, "highbits")) {
- do_hibits = 1;
- } else if (!strcmp(p, "getimage")) {
- xgetimage_8to24 = 1;
+ } else if (strstr(p, "poll=") == p) {
+ poll_8to24_delay = atof(p + strlen("poll="));
+ } else if (!strcmp(p, "nogetimage")) {
+ xgetimage_8to24 = 0;
}
p = strtok(NULL, ",");
}
@@ -124,17 +144,35 @@ static void parse_cmap8to24(void) {
if (getenv("DEBUG_8TO24") != NULL) {
db24 = atoi(getenv("DEBUG_8TO24"));
}
- if (getenv("XGETIMAGE_8TO24") != NULL) {
- xgetimage_8to24 = 1;
+ if (getenv("NOXGETIMAGE_8TO24") != NULL) {
+ xgetimage_8to24 = 0;
}
- if (getenv("HIGHBITS_8TO24") != NULL) {
- do_hibits = 1;
+ }
+}
+
+static char *poll8_fb = NULL, *poll24_fb = NULL;
+static int poll8_fb_w = 0, poll8_fb_h = 0;
+static int poll24_fb_w = 0, poll24_fb_h = 0;
+
+static void pfb(int fac, char **fb, int *w, int *h) {
+ if (! *fb || *w != dpy_x || *h != dpy_y) {
+ if (*fb) {
+ free(*fb);
}
+ *fb = (char *) calloc(fac * dpy_x * dpy_y, 1);
+ *w = dpy_x;
+ *h = dpy_y;
}
}
-void poll_8bpp(void) {
-
+static void set_poll_fb(void) {
+ /* create polling framebuffers or recreate if too small. */
+
+ if (! xgetimage_8to24) {
+ return; /* this saves a bit of RAM */
+ }
+ pfb(4, &poll24_fb, &poll24_fb_w, &poll24_fb_h);
+ pfb(1, &poll8_fb, &poll8_fb_w, &poll8_fb_h);
}
void check_for_multivis(void) {
@@ -142,13 +180,23 @@ void check_for_multivis(void) {
int doall = 0;
int k, i, cnt, diff;
static int first = 1;
+ static Window *stack_old = NULL;
+ static int stack_old_len = 0;
static double last_parse = 0.0;
static double last_update = 0.0;
static double last_clear = 0.0;
static double last_poll = 0.0;
+ static double last_fixup = 0.0;
+ static double last_call = 0.0;
+ static double last_query = 0.0;
double now = dnow();
- static Window *stack_old = NULL;
- static int stack_old_len = 0;
+
+ if (now > last_parse + 0.75) {
+ last_parse = now;
+ parse_cmap8to24();
+ }
+if (db24 > 2) fprintf(stderr, " check_for_multivis: %.4f\n", now - last_call);
+ last_call = now;
if (first) {
int i;
@@ -159,16 +207,14 @@ void check_for_multivis(void) {
windows_8bpp[i].map_state = IsUnmapped;
windows_8bpp[i].cmap = (Colormap) 0;
windows_8bpp[i].fetched = 0;
+ windows_8bpp[i].clip_region = NULL;
}
+ set_poll_fb();
+
first = 0;
doall = 1; /* fetch everything first time */
}
- if (now > last_parse + 0.75) {
- last_parse = now;
- parse_cmap8to24();
- }
-
set_root_cmap();
/*
@@ -197,8 +243,8 @@ void check_for_multivis(void) {
}
/* snapshot + update the current stacking order: */
- snapshot_stack_list(0, 0.25);
- if (doall || now > last_update + 0.25) {
+ if (doall || now > last_update + 0.15) {
+ snapshot_stack_list(0, 0.0);
update_stack_list();
last_update = now;
}
@@ -207,7 +253,8 @@ void check_for_multivis(void) {
diff = 0;
cnt = 0;
for (k=0; k < stack_list_num; k++) {
- if (stack_list[k].valid && stack_list[k].map_state == IsViewable) {
+ if (stack_list[k].valid && stack_list[k].map_state ==
+ IsViewable) {
if (stack_old[cnt] != stack_list[k].win) {
diff = 1;
break;
@@ -216,26 +263,6 @@ void check_for_multivis(void) {
}
}
- if (poll_8to24_delay > 0.0 && now > last_poll + poll_8to24_delay) {
- last_poll = now;
- }
-
- /*
- * if there are 8bpp visible and a stacking order change
- * refresh vnc with coverage of the 8bpp regions:
- */
- if (diff && multivis_count) {
-if (db24) fprintf(stderr, "check_for_multivis stack diff: mark_all %f\n", now - x11vnc_start);
- mark_8bpp();
-
- } else if (depth == 8 && multivis_24count) {
- static double last_check = 0.0;
- if (now > last_check + 0.25) {
- last_check = now;
- check_pointer_in_depth24();
- }
- }
-
multivis_count = 0;
multivis_24count = 0;
@@ -248,7 +275,6 @@ if (db24) fprintf(stderr, "check_for_multivis stack diff: mark_all %f\n", now -
X_LOCK;
for (i=0; i < MAX_8BPP_WINDOWS; i++) {
Window w = windows_8bpp[i].win;
-if ((db24) && w != None) fprintf(stderr, " windows_8bpp: 0x%lx i=%02d ms: %d dep=%d\n", windows_8bpp[i].win, i, windows_8bpp[i].map_state, windows_8bpp[i].depth);
if (! valid_window(w, &attr, 1)) {
/* catch windows that went away: */
windows_8bpp[i].win = None;
@@ -271,6 +297,10 @@ if ((db24) && w != None) fprintf(stderr, " windows_8bpp: 0x%lx i=%02d ms: %d d
Window win = stack_list[k].win;
+ if (now < last_query + 0.05) {
+ break;
+ }
+
if (win == None) {
continue;
}
@@ -291,7 +321,7 @@ if ((db24) && w != None) fprintf(stderr, " windows_8bpp: 0x%lx i=%02d ms: %d d
if (check_depth(win, win, doall)) {
/*
- * returns 1 if no need to recurse down e.g. IT
+ * returns 1 if no need to recurse down e.g. It
* is 8bpp and we assume all lower one are too.
*/
continue;
@@ -342,6 +372,50 @@ if ((db24) && w != None) fprintf(stderr, " windows_8bpp: 0x%lx i=%02d ms: %d d
X_UNLOCK;
}
}
+ last_query = dnow();
+
+ if (screen_fixup_8 > 0.0 && now > last_fixup + screen_fixup_8) {
+ last_fixup = now;
+ mark_8bpp(MARK_8BPP_ALL);
+ last_poll = now;
+
+ } else if (poll_8to24_delay > 0.0) {
+ int area = -1;
+ int validate = 0;
+
+ if (diff && multivis_count) {
+ validate = 1;
+ }
+ if (now > last_poll + poll_8to24_delay) {
+ sraRegionPtr mod;
+
+ last_poll = now;
+ mod = sraRgnCreate();
+ area = poll_8bpp(mod, validate);
+ if (depth == 24) {
+ poll_8bpp_complement(mod);
+ }
+ mark_rgn_rects(mod);
+ sraRgnDestroy(mod);
+ }
+ if (0 && area < dpy_x * dpy_y / 2 && diff && multivis_count) {
+ mark_8bpp(MARK_8BPP_POINTER);
+ last_poll = now;
+ }
+
+ } else if (diff && multivis_count) {
+ mark_8bpp(MARK_8BPP_ALL);
+ last_poll = now;
+
+ } else if (depth == 8 && multivis_24count) {
+ static double last_check = 0.0;
+ if (now > last_check + 0.4) {
+ last_check = now;
+ if (check_pointer_in_depth24()) {
+ last_poll = now;
+ }
+ }
+ }
}
static int check_depth(Window win, Window top, int doall) {
@@ -356,9 +430,9 @@ static int check_depth(Window win, Window top, int doall) {
X_UNLOCK;
if (! doall && attr.map_state != IsViewable) {
/*
- * store results anyway... this may lead to table filling up,
- * but currently this allows us to update state of onetime mapped
- * windows.
+ * store results anyway... this may lead to table
+ * filling up, but currently this allows us to update
+ * state of onetime mapped windows.
*/
check_depth_win(win, top, attr);
return 1; /* indicate done */
@@ -372,8 +446,8 @@ static int check_depth(Window win, Window top, int doall) {
static int check_depth_win(Window win, Window top, XWindowAttributes attr) {
int store_it = 0;
/*
- * only store windows with depth not equal to the default visual's depth
- * note some windows can have depth == 0 ... (skip them).
+ * only store windows with depth not equal to the default visual's
+ * depth note some windows can have depth == 0 ... (skip them).
*/
if (attr.depth > 0) {
set_root_cmap();
@@ -384,8 +458,8 @@ static int check_depth_win(Window win, Window top, XWindowAttributes attr) {
store_it = 1;
}
}
- if (store_it) {
+ if (store_it) {
int i, j = -1, none = -1, nomap = -1;
int new = 0;
if (attr.map_state == IsViewable) {
@@ -450,6 +524,7 @@ if (db24 > 1) fprintf(stderr, "multivis: STORE 0x%lx j: %3d ms: %d dep=%d\n", wi
windows_8bpp[j].map_installed = attr.map_installed;
windows_8bpp[j].w = attr.width;
windows_8bpp[j].h = attr.height;
+ windows_8bpp[j].fetched = 1;
/* translate x y to be WRT the root window (not parent) */
X_LOCK;
@@ -458,8 +533,6 @@ if (db24 > 1) fprintf(stderr, "multivis: STORE 0x%lx j: %3d ms: %d dep=%d\n", wi
windows_8bpp[j].x = x;
windows_8bpp[j].y = y;
- windows_8bpp[j].fetched = 1;
-
if (new || now_vis) {
if (db24) fprintf(stderr, "new/now_vis: 0x%lx %d/%d\n", win, new, now_vis);
/* mark it immediately if a new one: */
@@ -482,12 +555,354 @@ if (db24 > 1) fprintf(stderr, " ------------ 0x%lx i=%d\n", windows_8bp
return 0;
}
+static XImage *p_xi(XImage *xi, Visual *visual, int win_depth, int *w) {
+ if (xi == NULL || *w < dpy_x) {
+ char *d;
+ if (xi) {
+ XDestroyImage(xi);
+ }
+ if (win_depth == 8) {
+ d = (char *) malloc(dpy_x * 1);
+ } else {
+ d = (char *) malloc(dpy_x * 4);
+ }
+ *w = dpy_x;
+ xi = XCreateImage(dpy, visual, win_depth, ZPixmap, 0, d,
+ dpy_x, 1, 8, 0);
+ }
+ return xi;
+}
+
+static int poll_line(int x1, int x2, int y1, int n, sraRegionPtr mod) {
+ int fac, n_off, w, xo, yo;
+ char *poll_fb, *dst, *src;
+ int w2, xl, xh, stride = 32;
+ int inrun = 0, rx1 = -1, rx2 = -1;
+
+ static XImage *xi8 = NULL, *xi24 = NULL, *xi_r;
+ static int xi8_w = 0, xi24_w = 0;
+
+ XErrorHandler old_handler = NULL;
+ XWindowAttributes attr;
+ XImage *xi;
+ Window c, win = windows_8bpp[n].win;
+
+ sraRegionPtr rect;
+ int mx1, mx2, my1, my2;
+ int ns = NSCAN/2;
+
+ if (win == None) {
+ return 1;
+ }
+ if (windows_8bpp[n].map_state != IsViewable) {
+ return 1;
+ }
+ if (! xgetimage_8to24) {
+ return 1;
+ }
+
+ X_LOCK;
+ if (! valid_window(windows_8bpp[n].win, &attr, 1)) {
+ X_UNLOCK;
+ return 0;
+ }
+
+ if (attr.depth != 8 && attr.depth != 24) {
+ X_UNLOCK;
+ return 1;
+ } else if (attr.depth == 8) {
+ xi = xi8 = p_xi(xi8, attr.visual, 8, &xi8_w);
+
+ poll_fb = poll8_fb;
+ fac = 1;
+ n_off = poll8_fb_w * y1 + x1;
+ } else {
+ xi = xi24 = p_xi(xi24, attr.visual, 24, &xi24_w);
+
+ poll_fb = poll24_fb;
+ fac = 4;
+ n_off = poll24_fb_w * y1 + x1;
+ }
+
+ xtranslate(win, window, 0, 0, &xo, &yo, &c, 1);
+ xo = x1 - xo;
+ yo = y1 - yo;
+ w = x2 - x1;
+
+ if (xo < 0 || yo < 0 || xo + w > attr.width) {
+if (db24 > 2) fprintf(stderr, "avoid bad match...\n");
+ X_UNLOCK;
+ return 0;
+ }
+
+ trapped_xerror = 0;
+ old_handler = XSetErrorHandler(trap_xerror);
+ xi_r = XGetSubImage(dpy, win, xo, yo, w, 1, AllPlanes, ZPixmap, xi,
+ 0, 0);
+ XSetErrorHandler(old_handler);
+ X_UNLOCK;
+
+ if (! xi_r || trapped_xerror) {
+ trapped_xerror = 0;
+ return 0;
+ }
+ trapped_xerror = 0;
+
+ src = xi->data;
+ dst = poll_fb + fac * n_off;
+
+ inrun = 0;
+
+ xl = x1;
+ while (xl < x2) {
+ xh = xl + stride;
+ if (xh > x2) {
+ xh = x2;
+ }
+ w2 = xh - xl;
+ if (memcmp(dst, src, fac * w2)) {
+ if (inrun) {
+ rx2 = xh;
+ } else {
+ rx1 = xl;
+ rx2 = xh;
+ inrun = 1;
+ }
+ } else {
+ if (inrun) {
+ mx1 = rx1;
+ mx2 = rx2;
+ my1 = nfix(y1 - ns, dpy_y);
+ my2 = nfix(y1 + ns, dpy_y+1);
+
+ rect = sraRgnCreateRect(mx1, my1, mx2, my2);
+ sraRgnOr(mod, rect);
+ sraRgnDestroy(rect);
+ inrun = 0;
+ }
+ }
+
+ xl += stride;
+ dst += fac * stride;
+ src += fac * stride;
+ }
+
+ if (inrun) {
+ mx1 = rx1;
+ mx2 = rx2;
+ my1 = nfix(y1 - ns, dpy_y);
+ my2 = nfix(y1 + ns, dpy_y+1);
+
+ rect = sraRgnCreateRect(mx1, my1, mx2, my2);
+ sraRgnOr(mod, rect);
+ sraRgnDestroy(rect);
+ }
+ return 1;
+}
+
+static void poll_line_complement(int x1, int x2, int y1, sraRegionPtr mod) {
+ int n_off, w, xl, xh, stride = 32;
+ char *dst, *src;
+ int inrun = 0, rx1 = -1, rx2 = -1;
+ sraRegionPtr rect;
+ int mx1, mx2, my1, my2;
+ int ns = NSCAN/2;
+
+ if (depth != 24) {
+ return;
+ }
+ if (! cmap8to24_fb) {
+ return;
+ }
+ if (! xgetimage_8to24) {
+ return;
+ }
+
+ n_off = main_bytes_per_line * y1 + 4 * x1;
+
+ src = main_fb + n_off;
+ dst = cmap8to24_fb + n_off;
+
+ inrun = 0;
+
+ xl = x1;
+ while (xl < x2) {
+ xh = xl + stride;
+ if (xh > x2) {
+ xh = x2;
+ }
+ w = xh - xl;
+ if (memcmp(dst, src, 4 * w)) {
+ if (inrun) {
+ rx2 = xh;
+ } else {
+ rx1 = xl;
+ rx2 = xh;
+ inrun = 1;
+ }
+ } else {
+ if (inrun) {
+ mx1 = rx1;
+ mx2 = rx2;
+ my1 = nfix(y1 - ns, dpy_y);
+ my2 = nfix(y1 + ns, dpy_y+1);
+
+ rect = sraRgnCreateRect(mx1, my1, mx2, my2);
+ sraRgnOr(mod, rect);
+ sraRgnDestroy(rect);
+
+ inrun = 0;
+ }
+ }
+
+ xl += stride;
+ dst += 4 * stride;
+ src += 4 * stride;
+ }
+
+ if (inrun) {
+ mx1 = rx1;
+ mx2 = rx2;
+ my1 = nfix(y1 - ns, dpy_y);
+ my2 = nfix(y1 + ns, dpy_y+1);
+
+ rect = sraRgnCreateRect(mx1, my1, mx2, my2);
+ sraRgnOr(mod, rect);
+ sraRgnDestroy(rect);
+
+ inrun = 0;
+ }
+}
+
#define CMAPMAX 64
-Colormap cmaps[CMAPMAX];
-int ncmaps;
+static Colormap cmaps[CMAPMAX];
+static int ncmaps;
+
+static int poll_8bpp(sraRegionPtr mod, int validate) {
+ int i, y, ysh, map_count;
+ static int ycnt = 0;
+ sraRegionPtr line;
+ sraRect rect;
+ sraRectangleIterator *iter;
+ int br = 0, area = 0;
+ static double last_call = 0.0;
+
+ map_count = get_8bpp_regions(validate);
+
+if (db24 > 1) fprintf(stderr, "poll_8bpp mc: %d\n", map_count);
+
+ if (! map_count) {
+ return 0;
+ }
+
+ set_poll_fb();
+
+ ysh = scanlines[(ycnt++) % NSCAN];
+if (db24 > 2) fprintf(stderr, "poll_8bpp: ysh: %2d %.4f\n", ysh, dnow() - last_call);
+ last_call = dnow();
+
+ for (i=0; i < MAX_8BPP_WINDOWS; i++) {
+ sraRegionPtr reg = windows_8bpp[i].clip_region;
+
+ if (! reg || sraRgnEmpty(reg)) {
+ continue;
+ }
+ y = ysh;
+ while (y < dpy_y) {
+ line = sraRgnCreateRect(0, y, dpy_x, y+1);
+
+ if (sraRgnAnd(line, reg)) {
+ iter = sraRgnGetIterator(line);
+ while (sraRgnIteratorNext(iter, &rect)) {
+ if (! poll_line(rect.x1, rect.x2,
+ rect.y1, i, mod)) {
+ br = 1;
+ break; /* exception */
+ }
+ }
+ sraRgnReleaseIterator(iter);
+ }
+
+ sraRgnDestroy(line);
+ y += NSCAN;
+ if (br) break;
+ }
+ if (br) break;
+ }
+
+ iter = sraRgnGetIterator(mod);
+ while (sraRgnIteratorNext(iter, &rect)) {
+ area += nabs((rect.x2 - rect.x1)*(rect.y2 - rect.y1));
+ }
+ sraRgnReleaseIterator(iter);
+
+ return area;
+}
+
+static void poll_8bpp_complement(sraRegionPtr mod) {
+ int i, y, ysh;
+ static int ycnt = 0;
+ sraRegionPtr disp, line;
+ sraRect rect;
+ sraRectangleIterator *iter;
+
+ disp = sraRgnCreateRect(0, 0, dpy_x, dpy_y);
+
+ ysh = scanlines[(ycnt++) % NSCAN];
+
+ for (i=0; i < MAX_8BPP_WINDOWS; i++) {
+ sraRegionPtr reg = windows_8bpp[i].clip_region;
+
+ if (! reg) {
+ continue;
+ }
+ if (windows_8bpp[i].map_state != IsViewable) {
+ continue;
+ }
+ sraRgnSubtract(disp, reg);
+ }
-static int get_8pp_region(sraRegionPtr region8bpp, sraRegionPtr rect,
- int validate) {
+ y = ysh;
+ while (y < dpy_y) {
+ line = sraRgnCreateRect(0, y, dpy_x, y+1);
+
+ if (sraRgnAnd(line, disp)) {
+ iter = sraRgnGetIterator(line);
+ while (sraRgnIteratorNext(iter, &rect)) {
+ poll_line_complement(rect.x1, rect.x2,
+ rect.y1, mod);
+ }
+ sraRgnReleaseIterator(iter);
+ }
+
+ sraRgnDestroy(line);
+
+ y += NSCAN;
+ }
+
+ sraRgnDestroy(disp);
+}
+
+static void mark_rgn_rects(sraRegionPtr mod) {
+ sraRect rect;
+ sraRectangleIterator *iter;
+ int area = 0;
+
+ if (sraRgnEmpty(mod)) {
+ return;
+ }
+
+ iter = sraRgnGetIterator(mod);
+ while (sraRgnIteratorNext(iter, &rect)) {
+ mark_rect_as_modified(rect.x1, rect.y1, rect.x2, rect.y2, 0);
+ area += nabs((rect.x2 - rect.x1)*(rect.y2 - rect.y1));
+ }
+ sraRgnReleaseIterator(iter);
+
+if (db24 > 1) fprintf(stderr, " mark_rgn_rects area: %d\n", area);
+}
+
+static int get_8bpp_regions(int validate) {
XWindowAttributes attr;
int i, k, mapcount = 0;
@@ -504,15 +919,16 @@ static int get_8pp_region(sraRegionPtr region8bpp, sraRegionPtr rect,
Window c, w = windows_8bpp[i].win;
int x, y;
- if (wireframe_in_progress) {
- break; /* skip updates during wireframe drag */
+ if (windows_8bpp[i].clip_region) {
+ sraRgnDestroy(windows_8bpp[i].clip_region);
}
+ windows_8bpp[i].clip_region = NULL;
if (w == None) {
continue;
}
-if (db24 > 1) fprintf(stderr, "get_8pp_region: 0x%lx ms=%d dep=%d i=%d\n", w, windows_8bpp[i].map_state, windows_8bpp[i].depth, i);
+if (db24 > 1) fprintf(stderr, "get_8bpp_regions: 0x%lx ms=%d dep=%d i=%d\n", w, windows_8bpp[i].map_state, windows_8bpp[i].depth, i);
if (validate) {
/*
* this could be slow: validating 8bpp windows each
@@ -530,6 +946,15 @@ if (db24 > 1) fprintf(stderr, "get_8pp_region: 0x%lx ms=%d dep=%d i=%d\n", w, wi
continue;
}
X_UNLOCK;
+
+ windows_8bpp[i].depth = attr.depth;
+ windows_8bpp[i].map_state = attr.map_state;
+ windows_8bpp[i].cmap = attr.colormap;
+ windows_8bpp[i].map_installed = attr.map_installed;
+ windows_8bpp[i].w = attr.width;
+ windows_8bpp[i].h = attr.height;
+ windows_8bpp[i].fetched = 1;
+
if (attr.map_state != IsViewable) {
continue;
}
@@ -537,34 +962,30 @@ if (db24 > 1) fprintf(stderr, "get_8pp_region: 0x%lx ms=%d dep=%d i=%d\n", w, wi
X_LOCK;
xtranslate(w, window, 0, 0, &x, &y, &c, 1);
X_UNLOCK;
+ windows_8bpp[i].x = x;
+ windows_8bpp[i].y = y;
} else {
/* this will be faster: no call to X server: */
if (windows_8bpp[i].map_state != IsViewable) {
continue;
}
- x = windows_8bpp[i].x;
- y = windows_8bpp[i].y;
- attr.width = windows_8bpp[i].w;
- attr.height = windows_8bpp[i].h;
+ attr.depth = windows_8bpp[i].depth;
attr.map_state = windows_8bpp[i].map_state;
attr.colormap = windows_8bpp[i].cmap;
+ attr.map_installed = windows_8bpp[i].map_installed;
+ attr.width = windows_8bpp[i].w;
+ attr.height = windows_8bpp[i].h;
+
+ x = windows_8bpp[i].x;
+ y = windows_8bpp[i].y;
}
mapcount++;
/* tmp region for this 8bpp rectangle: */
tmp_reg = sraRgnCreateRect(nfix(x, dpy_x), nfix(y, dpy_y),
- nfix(x + attr.width, dpy_x), nfix(y + attr.height, dpy_y));
-
- /* find overlap with mark region in rect: */
- sraRgnAnd(tmp_reg, rect);
-
- if (sraRgnEmpty(tmp_reg)) {
- /* skip if no overlap: */
- sraRgnDestroy(tmp_reg);
- continue;
- }
+ nfix(x + attr.width, dpy_x+1), nfix(y + attr.height, dpy_y+1));
/* loop over all toplevels, top to bottom clipping: */
for (k = stack_list_num - 1; k >= 0; k--) {
@@ -574,7 +995,7 @@ if (db24 > 1) fprintf(stderr, "get_8pp_region: 0x%lx ms=%d dep=%d i=%d\n", w, wi
if (db24 > 1 && stack_list[k].map_state == IsViewable) fprintf(stderr, "Stack win: 0x%lx %d iv=%d\n", swin, k, stack_list[k].map_state);
if (swin == windows_8bpp[i].top) {
- /* found our top level: we clip the rest. */
+ /* found our top level: we skip the rest. */
if (db24 > 1) fprintf(stderr, "found top: 0x%lx %d iv=%d\n", swin, k, stack_list[k].map_state);
break;
}
@@ -592,39 +1013,41 @@ if (db24 > 1) fprintf(stderr, "found top: 0x%lx %d iv=%d\n", swin, k, stack_list
if (db24 > 1) fprintf(stderr, "subtract: 0x%lx %d -- %d %d %d %d\n", swin, k, sx, sy, sw, sh);
tmp_reg2 = sraRgnCreateRect(nfix(sx, dpy_x),
- nfix(sy, dpy_y), nfix(sx + sw, dpy_x),
- nfix(sy + sh, dpy_y));
+ nfix(sy, dpy_y), nfix(sx + sw, dpy_x+1),
+ nfix(sy + sh, dpy_y+1));
/* subtract it from the 8bpp window region */
sraRgnSubtract(tmp_reg, tmp_reg2);
+
sraRgnDestroy(tmp_reg2);
+
+ if (sraRgnEmpty(tmp_reg)) {
+ break;
+ }
}
if (sraRgnEmpty(tmp_reg)) {
/* skip this 8bpp if completely clipped away: */
sraRgnDestroy(tmp_reg);
-if (db24 > 1) fprintf(stderr, "Empty tmp_reg\n");
continue;
}
/* otherwise, store any new colormaps: */
if (ncmaps < CMAPMAX && attr.colormap != (Colormap) 0) {
- int m, sawit = 0;
+ int m, seen = 0;
for (m=0; m < ncmaps; m++) {
if (cmaps[m] == attr.colormap) {
- sawit = 1;
+ seen = 1;
break;
}
}
- if (! sawit && attr.depth == 8) {
+ if (! seen && attr.depth == 8) {
/* store only new ones: */
cmaps[ncmaps++] = attr.colormap;
}
}
- /* now include this region with the full 8bpp region: */
- sraRgnOr(region8bpp, tmp_reg);
- sraRgnDestroy(tmp_reg);
+ windows_8bpp[i].clip_region = tmp_reg;
}
return mapcount;
@@ -701,131 +1124,125 @@ if (db24 > 2) fprintf(stderr, " cmap[%02d][%03d]: %03d %03d %03d 0x%08x \n", j,
green = green << main_green_shift;
blue = blue << main_blue_shift;
+ /* store it in the array to be used later */
rgb[j][i] = red | green | blue;
}
return 1;
}
-static void do_8bpp_region(sraRect rect) {
-
- char *src, *dst;
- unsigned int *ui;
- unsigned char *uc;
- int ps, pixelsize = bpp/8;
-
- int do_getimage = xgetimage_8to24;
- int line, n_off, j, h, w, vw;
- unsigned int hi, idx;
- XWindowAttributes attr;
- XErrorHandler old_handler = NULL;
-
- double score, max_score = -1.0;
- int m, best, best_depth = 0;
- Window best_win = None;
+static void do_8bpp_region(int n, sraRegionPtr mark) {
+ int k, cm = -1, failed = 0;
+ sraRectangleIterator *iter;
+ sraRegionPtr clip;
+ sraRect rect;
+ if (! windows_8bpp[n].clip_region) {
+ return;
+ }
+ if (windows_8bpp[n].win == None) {
+ return;
+ }
+ if (windows_8bpp[n].map_state != IsViewable) {
+ return;
+ }
if (db24 > 1) fprintf(stderr, "ncmaps: %d\n", ncmaps);
- /*
- * try to pick the "best" colormap to use for
- * this rectangle (often wrong... let them
- * iconify or move the trouble windows, etc.)
- */
- best = -1;
-
- for (m=0; m < MAX_8BPP_WINDOWS; m++) {
- int mx1, my1, mx2, my2;
- int k, failed = 0;
- if (windows_8bpp[m].win == None) {
- continue;
- }
- if (windows_8bpp[m].map_state != IsViewable) {
- continue;
- }
-
- /* see if XQueryColors failed: */
- for (k=0; k<ncmaps; k++) {
- if (windows_8bpp[m].cmap == cmaps[k] && cmap_failed[k]) {
+ /* see if XQueryColors failed: */
+ for (k=0; k<ncmaps; k++) {
+ if (windows_8bpp[n].cmap == cmaps[k]) {
+ cm = k;
+ if (cmap_failed[k]) {
failed = 1;
}
+ break;
}
- if (windows_8bpp[m].depth == 8 && failed) {
- continue;
- }
+ }
- /* rectangle coords for this 8bpp win: */
- mx1 = windows_8bpp[m].x;
- my1 = windows_8bpp[m].y;
- mx2 = windows_8bpp[m].x + windows_8bpp[m].w;
- my2 = windows_8bpp[m].y + windows_8bpp[m].h;
+ if (windows_8bpp[n].depth == 8) { /* 24 won't have a cmap */
+ if (failed || cm == -1) {
+ return;
+ }
+ }
- /* use overlap as score: */
- score = rect_overlap(mx1, my1, mx2, my2, rect.x1, rect.y1,
- rect.x2, rect.y2);
+ clip = sraRgnCreateRgn(mark);
+ sraRgnAnd(clip, windows_8bpp[n].clip_region);
- if (score > max_score) {
- max_score = score;
- best = m;
- best_win = windows_8bpp[m].win;
- best_depth = windows_8bpp[m].depth;
+ /* loop over the rectangles making up region */
+ iter = sraRgnGetIterator(clip);
+ while (sraRgnIteratorNext(iter, &rect)) {
+ if (rect.x1 > rect.x2) {
+ int tmp = rect.x2;
+ rect.x2 = rect.x1;
+ rect.x1 = tmp;
+ }
+ if (rect.y1 > rect.y2) {
+ int tmp = rect.y2;
+ rect.y2 = rect.y1;
+ rect.y1 = tmp;
}
-if (db24 > 1) fprintf(stderr, "cmap_score: 0x%x %.3f %.3f\n", (int) windows_8bpp[m].cmap, score, max_score);
+ transform_rect(rect, windows_8bpp[n].win,
+ windows_8bpp[n].depth, cm);
}
+ sraRgnReleaseIterator(iter);
+ sraRgnDestroy(clip);
+}
- if (best < 0) {
- /* hmmm, use the first one then... */
- best = 0;
+static XImage *cmap_xi(XImage *xi, Visual *visual, int win_depth) {
+ char *d;
+ if (xi) {
+ XDestroyImage(xi);
+ }
+ if (win_depth == 8) {
+ d = (char *) malloc(dpy_x * dpy_y * 1);
+ } else if (win_depth == 24) {
+ d = (char *) malloc(dpy_x * dpy_y * 4);
} else {
- int ok = 0;
- /*
- * find the cmap corresponding to best window
- * note we reset best from the windows_8bpp
- * index to the cmaps[].
- */
- for (m=0; m < ncmaps; m++) {
- if (cmaps[m] == windows_8bpp[best].cmap) {
- ok = 1;
- best = m;
- }
- }
- if (! ok) {
- best = 0;
- }
+ return (XImage *) NULL;
}
+ return XCreateImage(dpy, visual, win_depth, ZPixmap, 0, d, dpy_x,
+ dpy_y, 8, 0);
+}
+
+
+static void transform_rect(sraRect rect, Window win, int win_depth, int cm) {
+
+ char *src, *dst, *poll;
+ unsigned int *ui;
+ unsigned char *uc;
+ int ps, pixelsize = bpp/8;
+ int poll_Bpl;
+ int do_getimage = xgetimage_8to24;
+ int line, n_off, j, h, w, vw;
+ unsigned int hi, idx;
+ XWindowAttributes attr;
+ XErrorHandler old_handler = NULL;
-if (db24 > 1) fprintf(stderr, "transform %d %d %d %d\n", rect.x1, rect.y1, rect.x2, rect.y2);
+if (db24 > 1) fprintf(stderr, "transform %4d %4d %4d %4d cm: %d\n", rect.x1, rect.y1, rect.x2, rect.y2, cm);
- /* now tranform the pixels in this rectangle: */
+ /* now transform the pixels in this rectangle: */
n_off = main_bytes_per_line * rect.y1 + pixelsize * rect.x1;
h = rect.y2 - rect.y1;
w = rect.x2 - rect.x1;
if (depth == 8) {
- /*
- * need to fetch depth 24 data. might need for
- * best_depth == 8 too... (hi | ... failure).
- */
- if (best_depth == 24) {
- do_getimage = 1;
- } else if (! do_hibits) {
- do_getimage = 1;
- }
+ /* need to fetch depth 24 data. */
+ do_getimage = 1;
}
if (do_getimage) {
X_LOCK;
- vw = valid_window(best_win, &attr, 1);
+ vw = valid_window(win, &attr, 1);
X_UNLOCK;
}
if (do_getimage && vw) {
static XImage *xi_8 = NULL;
static XImage *xi_24 = NULL;
- XImage *xi = NULL;
+ XImage *xi = NULL, *xi_r;
Window c;
- char *d;
unsigned int wu, hu;
int xo, yo;
@@ -833,7 +1250,7 @@ if (db24 > 1) fprintf(stderr, "transform %d %d %d %d\n", rect.x1, rect.y1, rect.
hu = (unsigned int) h;
X_LOCK;
- xtranslate(best_win, window, 0, 0, &xo, &yo, &c, 1);
+ xtranslate(win, window, 0, 0, &xo, &yo, &c, 1);
xo = rect.x1 - xo;
yo = rect.y1 - yo;
@@ -847,46 +1264,34 @@ if (db24 > 1) fprintf(stderr, "skipping due to potential bad match...\n");
#define GETSUBIMAGE
#ifdef GETSUBIMAGE
- if (best_depth == 8) {
- if (xi_8 == NULL || xi_8->width != dpy_x || xi_8->height != dpy_y) {
- if (xi_8) {
- XDestroyImage(xi_8);
+ if (win_depth == 8) {
+ if (xi_8 == NULL || xi_8->width != dpy_x ||
+ xi_8->height != dpy_y) {
+ xi_8 = cmap_xi(xi_8, attr.visual, attr.depth);
}
- d = (char *) malloc(dpy_x * dpy_y * attr.depth/8);
- xi_8 = XCreateImage(dpy, attr.visual, attr.depth,
- ZPixmap, 0, d, dpy_x, dpy_y, 8, 0);
-if (db24) fprintf(stderr, "xi_8: %p\n", (void *) xi_8);
- }
- xi = xi_8;
- } else if (best_depth == 24) {
- if (xi_24 == NULL || xi_24->width != dpy_x || xi_24->height != dpy_y) {
- if (xi_24) {
- XDestroyImage(xi_24);
+ xi = xi_8;
+ } else if (win_depth == 24) {
+ if (xi_24 == NULL || xi_24->width != dpy_x ||
+ xi_24->height != dpy_y) {
+ xi_24 = cmap_xi(xi_24, attr.visual, attr.depth);
}
- d = (char *) malloc(dpy_x * dpy_y * attr.depth/8);
- xi_24 = XCreateImage(dpy, attr.visual, attr.depth,
- ZPixmap, 0, d, dpy_x, dpy_y, 8, 0);
-if (db24) fprintf(stderr, "xi_24: %p\n", (void *) xi_24);
- }
- xi = xi_24;
+ xi = xi_24;
}
#endif
-
trapped_xerror = 0;
old_handler = XSetErrorHandler(trap_xerror);
- /* FIXME: XGetSubImage? */
#ifndef GETSUBIMAGE
- xi = XGetImage(dpy, best_win, xo, yo, wu, hu,
- AllPlanes, ZPixmap);
+ xi = XGetImage(dpy, win, xo, yo, wu, hu, AllPlanes, ZPixmap);
+ xi_r = xi;
#else
- XGetSubImage(dpy, best_win, xo, yo, wu, hu, AllPlanes,
+ xi_r = XGetSubImage(dpy, win, xo, yo, wu, hu, AllPlanes,
ZPixmap, xi, 0, 0);
#endif
XSetErrorHandler(old_handler);
X_UNLOCK;
- if (! xi || trapped_xerror) {
+ if (! xi_r || trapped_xerror) {
trapped_xerror = 0;
if (db24 > 1) fprintf(stderr, "xi-fail: 0x%p trap=%d %d %d %d %d\n", (void *)xi, trapped_xerror, xo, yo, w, h);
return;
@@ -905,6 +1310,8 @@ if (db24) fprintf(stderr, "xi: wrong depth: %d\n", xi->depth);
return;
}
+ set_poll_fb();
+
if (xi->depth == 8) {
int ps1, ps2, fac;
@@ -921,6 +1328,8 @@ if (db24) fprintf(stderr, "xi: wrong depth: %d\n", xi->depth);
src = xi->data;
dst = cmap8to24_fb + fac * n_off;
+ poll = poll8_fb + poll8_fb_w * rect.y1 + rect.x1;
+ poll_Bpl = poll8_fb_w * 1;
/* line by line ... */
for (line = 0; line < h; line++) {
@@ -932,10 +1341,13 @@ if (db24) fprintf(stderr, "xi: wrong depth: %d\n", xi->depth);
idx = (int) (*uc);
- *ui = rgb[best][idx];
+ *ui = rgb[cm][idx];
+
+ *(poll + ps1 * j) = *uc;
}
src += xi->bytes_per_line;
dst += main_bytes_per_line * fac;
+ poll += poll_Bpl;
}
} else if (xi->depth == 24) {
/* line by line ... */
@@ -943,16 +1355,22 @@ if (db24) fprintf(stderr, "xi: wrong depth: %d\n", xi->depth);
if (depth == 8) {
fac = 4;
} else {
- fac = 1; /* should not happen */
+ fac = 1; /* will not happen */
}
src = xi->data;
dst = cmap8to24_fb + fac * n_off;
+ poll = poll24_fb + (poll24_fb_w * rect.y1 + rect.x1)*4;
+ poll_Bpl = poll24_fb_w * 4;
+
for (line = 0; line < h; line++) {
- memcpy(dst, src, w * ps1);
+ memcpy(dst, src, w * ps1);
+ memcpy(poll, src, w * ps1);
+
src += xi->bytes_per_line;
dst += main_bytes_per_line * fac;
+ poll += poll_Bpl;
}
}
@@ -963,11 +1381,11 @@ if (db24) fprintf(stderr, "xi: wrong depth: %d\n", xi->depth);
#endif
} else if (! do_getimage) {
- /* normal mode. */
int fac;
if (depth == 8) {
/* cooked up depth 24 TrueColor */
+ /* but currently disabled (high bits no useful?) */
ps = 4;
fac = 4;
src = cmap8to24_fb + 4 * n_off;
@@ -990,7 +1408,7 @@ if (db24) fprintf(stderr, "xi: wrong depth: %d\n", xi->depth);
/* map to lookup index; rewrite pixel */
idx = hi >> 24;
- *ui = hi | rgb[best][idx];
+ *ui = hi | rgb[cm][idx];
}
src += main_bytes_per_line * fac;
}
@@ -1001,55 +1419,44 @@ void bpp8to24(int x1, int y1, int x2, int y2) {
char *src, *dst;
unsigned char *uc;
unsigned int *ui;
- unsigned int hi;
int idx, pixelsize = bpp/8;
- int line, i, j, h, w;
+ int line, k, i, j, h, w;
int n_off;
-
- sraRegionPtr rect, disp, region8bpp;
-
+ sraRegionPtr rect;
int validate = 1;
static int last_map_count = 0, call_count = 0;
+ static double last_get_8bpp_validate = 0.0;
+ static double last_snapshot = 0.0;
+ double now, dt, d0;
- if (! cmap8to24 || !cmap8to24_fb) {
+ if (! cmap8to24 || ! cmap8to24_fb) {
/* hmmm, why were we called? */
return;
}
+ now = dnow();
+if (db24 > 1) fprintf(stderr, "bpp8to24 %d %d %d %d %.4f\n", x1, y1, x2, y2, now - last_get_8bpp_validate);
+
call_count++;
/* clip to display just in case: */
x1 = nfix(x1, dpy_x);
y1 = nfix(y1, dpy_y);
- x2 = nfix(x2, dpy_x);
- y2 = nfix(y2, dpy_y);
+ x2 = nfix(x2, dpy_x+1);
+ y2 = nfix(y2, dpy_y+1);
- /* create regions for finding overlap, etc. */
- disp = sraRgnCreateRect(0, 0, dpy_x, dpy_y);
- rect = sraRgnCreateRect(x1, y1, x2, y2);
- region8bpp = sraRgnCreate();
+ if (wireframe_in_progress) {
+ /*
+ * draw_box() manages cmap8to24_fb for us so we get out as
+ * soon as we can. No need to cp main_fb -> cmap8to24_fb.
+ */
+ return;
+ }
X_LOCK;
XFlush(dpy); /* make sure X server is up to date WRT input, etc */
X_UNLOCK;
- if (last_map_count > MAX_8BPP_WINDOWS/4) {
- /* table is filling up... skip validating sometimes: */
- int skip = 3;
- if (last_map_count > MAX_8BPP_WINDOWS/2) {
- skip = 6;
- } else if (last_map_count > 3*MAX_8BPP_WINDOWS/4) {
- skip = 12;
- }
- if (call_count % skip != 0) {
- validate = 0;
- }
- }
-
-if (db24 > 2) {for(i=0;i<256;i++){histo[i]=0;}}
-
- last_map_count = get_8pp_region(region8bpp, rect, validate);
-
/* copy from main_fb to cmap8to24_fb regardless of 8bpp windows: */
h = y2 - y1;
@@ -1058,6 +1465,7 @@ if (db24 > 2) {for(i=0;i<256;i++){histo[i]=0;}}
if (depth == 8) {
/* need to cook up to depth 24 TrueColor */
/* pixelsize = 1 */
+ int tcm = CMAPMAX - 1;
n_off = main_bytes_per_line * y1 + pixelsize * x1;
@@ -1065,8 +1473,11 @@ if (db24 > 2) {for(i=0;i<256;i++){histo[i]=0;}}
dst = cmap8to24_fb + 4 * n_off;
set_root_cmap();
- if (get_cmap(0, root_cmap)) {
+ if (get_cmap(tcm, root_cmap)) {
int ps1 = 1, ps2 = 4;
+#if 0
+ unsigned int hi;
+#endif
/* line by line ... */
for (line = 0; line < h; line++) {
@@ -1078,12 +1489,14 @@ if (db24 > 2) {for(i=0;i<256;i++){histo[i]=0;}}
idx = (int) (*uc);
+#if 0
if (do_hibits) {
hi = idx << 24;
*ui = hi | rgb[0][idx];
} else {
- *ui = rgb[0][idx];
}
+#endif
+ *ui = rgb[tcm][idx];
if (db24 > 2) histo[idx]++;
}
src += main_bytes_per_line;
@@ -1106,17 +1519,64 @@ if (db24 > 2) histo[idx]++;
}
}
+ if (last_map_count > MAX_8BPP_WINDOWS/4) {
+ /* table is filling up... skip validating sometimes: */
+ int skip = 3;
+ if (last_map_count > MAX_8BPP_WINDOWS/2) {
+ skip = 6;
+ } else if (last_map_count > 3*MAX_8BPP_WINDOWS/4) {
+ skip = 12;
+ }
+ if (call_count % skip != 0) {
+ validate = 0;
+ }
+ }
+
+if (db24 > 2) {for(i=0;i<256;i++){histo[i]=0;}}
+
+ dt = now - last_get_8bpp_validate;
+ d0 = dnow();
+ if (dt < 0.0025) {
+ ; /* XXX does this still give painting errors? */
+ } else {
+ int snapit = 0;
+ if (dt < 0.04) {
+ validate = 0;
+ }
+ if (last_map_count) {
+ if (now > last_snapshot + 0.05) {
+ snapit = 1;
+ }
+ } else {
+ if (now > last_snapshot + 0.4) {
+ snapit = 1;
+ }
+ }
+
+ if (snapit) {
+ /* less problems if we update the stack frequently */
+ snapshot_stack_list(0, 0.0);
+ update_stack_list();
+ last_snapshot = now;
+ }
+
+ last_map_count = get_8bpp_regions(validate);
+ if (validate) {
+ last_get_8bpp_validate = now;
+ }
+ }
+
if (db24 > 1) fprintf(stderr, "bpp8to24 w=%d h=%d m=%p c=%p r=%p ncmaps=%d\n", w, h, main_fb, cmap8to24_fb, rfb_fb, ncmaps);
/*
- * now go back and tranform and 8bpp regions to TrueColor in
- * cmap8to24_fb. we have to guess the best colormap to use if
- * there is more than one...
+ * now go back and transform and 8bpp regions to TrueColor in
+ * cmap8to24_fb.
*/
- if (! sraRgnEmpty(region8bpp) && (ncmaps || depth == 8)) {
- sraRectangleIterator *iter;
- sraRect rect;
- int j;
+ if (last_map_count && (ncmaps || depth == 8)) {
+ int i, j;
+ int win[MAX_8BPP_WINDOWS];
+ int did[MAX_8BPP_WINDOWS];
+ int count = 0;
/*
* first, grab all of the associated colormaps from the
@@ -1128,42 +1588,81 @@ if (db24 > 1) fprintf(stderr, "bpp8to24 w=%d h=%d m=%p c=%p r=%p ncmaps=%d\n", w
} else {
cmap_failed[j] = 0;
}
-if (db24 > 1) fprintf(stderr, "cmap %d\n", (int) cmaps[j]);
+if (db24 > 2) fprintf(stderr, "cmap %d %.4f\n", (int) cmaps[j], dnow() - d0);
+ }
+ for (i=0; i < MAX_8BPP_WINDOWS; i++) {
+ sraRegionPtr reg = windows_8bpp[i].clip_region;
+ if (reg) {
+ rect = sraRgnCreateRect(x1, y1, x2, y2);
+ if (sraRgnAnd(rect, reg)) {
+ win[count] = i;
+ did[count++] = 0;
+ }
+ sraRgnDestroy(rect);
+ }
}
- /* loop over the rectangles making up region8bpp */
- iter = sraRgnGetIterator(region8bpp);
- while (sraRgnIteratorNext(iter, &rect)) {
- if (rect.x1 > rect.x2) {
- int tmp = rect.x2;
- rect.x2 = rect.x1;
- rect.x1 = tmp;
+ if (count) {
+
+ rect = sraRgnCreateRect(x1, y1, x2, y2);
+ /* try to apply lower windows first */
+ for (k=0; k < stack_list_num; k++) {
+ Window swin = stack_list[k].win;
+ for (j=0; j<count; j++) {
+ i = win[j];
+ if (did[j]) {
+ continue;
+ }
+ if (windows_8bpp[i].top == swin) {
+ do_8bpp_region(i, rect);
+ did[j] = 1;
+ break;
+ }
+ }
}
- if (rect.y1 > rect.y2) {
- int tmp = rect.y2;
- rect.y2 = rect.y1;
- rect.y1 = tmp;
+ for (j=0; j<count; j++) {
+ if (! did[j]) {
+ i = win[j];
+ do_8bpp_region(i, rect);
+ did[j] = 1;
+ }
}
-
- do_8bpp_region(rect);
+ sraRgnDestroy(rect);
}
- sraRgnReleaseIterator(iter);
}
if (db24 > 2) {for(i=0; i<256;i++) {fprintf(stderr, " cmap histo[%03d] %d\n", i, histo[i]);}}
-
- /* cleanup */
- sraRgnDestroy(disp);
- sraRgnDestroy(rect);
- sraRgnDestroy(region8bpp);
}
-void mark_8bpp(void) {
+void mark_8bpp(int mode) {
int i, cnt = 0;
+ Window top = None;
if (! cmap8to24 || !cmap8to24_fb) {
return;
}
+
+ if (mode == MARK_8BPP_TOP) {
+ int k;
+ for (k = stack_list_num - 1; k >= 0; k--) {
+ Window swin = stack_list[k].win;
+ for (i=0; i < MAX_8BPP_WINDOWS; i++) {
+ if (windows_8bpp[i].win == None) {
+ continue;
+ }
+ if (windows_8bpp[i].map_state != IsViewable) {
+ continue;
+ }
+ if (swin == windows_8bpp[i].top) {
+ top = swin;
+ break;
+ }
+ }
+ if (top != None) {
+ break;
+ }
+ }
+ }
/* for each mapped 8bpp window, mark it changed: */
@@ -1175,6 +1674,11 @@ void mark_8bpp(void) {
if (windows_8bpp[i].win == None) {
continue;
}
+ if (mode == MARK_8BPP_TOP) {
+ if (windows_8bpp[i].top != top) {
+ continue;
+ }
+ }
if (windows_8bpp[i].map_state != IsViewable) {
XWindowAttributes attr;
int vw;
@@ -1196,13 +1700,24 @@ void mark_8bpp(void) {
w = windows_8bpp[i].w;
h = windows_8bpp[i].h;
- /* apply a fuzz f around each one... constrain to screen */
x2 = x1 + w;
y2 = y1 + h;
+
+ if (mode == MARK_8BPP_POINTER) {
+ int b = 32; /* apply some fuzz for wm border */
+ if (cursor_x < x1 - b || cursor_y < y1 - b) {
+ continue;
+ }
+ if (cursor_x > x2 + b || cursor_y > y2 + b) {
+ continue;
+ }
+ }
+
+ /* apply fuzz f around each one; constrain to screen */
x1 = nfix(x1 - f, dpy_x);
y1 = nfix(y1 - f, dpy_y);
- x2 = nfix(x2 + f, dpy_x);
- y2 = nfix(y2 + f, dpy_y);
+ x2 = nfix(x2 + f, dpy_x+1);
+ y2 = nfix(y2 + f, dpy_y+1);
if (db24 > 1) fprintf(stderr, "mark_8bpp: 0x%lx %d %d %d %d\n", windows_8bpp[i].win, x1, y1, x2, y2);