summaryrefslogtreecommitdiffstats
path: root/x11vnc/8to24.c
diff options
context:
space:
mode:
Diffstat (limited to 'x11vnc/8to24.c')
-rw-r--r--x11vnc/8to24.c2155
1 files changed, 0 insertions, 2155 deletions
diff --git a/x11vnc/8to24.c b/x11vnc/8to24.c
deleted file mode 100644
index 30c3da2..0000000
--- a/x11vnc/8to24.c
+++ /dev/null
@@ -1,2155 +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.
-*/
-
-/* -- 8to24.c -- */
-#include "x11vnc.h"
-#include "cleanup.h"
-#include "scan.h"
-#include "util.h"
-#include "win_utils.h"
-#include "xwrappers.h"
-
-int multivis_count = 0;
-int multivis_24count = 0;
-
-void check_for_multivis(void);
-void bpp8to24(int, int, int, int);
-void mark_8bpp(int);
-
-#if SKIP_8TO24
-void check_for_multivis(void) {}
-void bpp8to24(int x, int y, int z, int t) {}
-void mark_8bpp(int x) {}
-#else
-/* lots... */
-
-static void set_root_cmap(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 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(int n, sraRegionPtr mark);
-static XImage *cmap_xi(XImage *xi, Window win, 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 {
- Window win;
- Window top;
- int depth;
- int x, y;
- int w, h;
- int map_state;
- Colormap cmap;
- Bool map_installed;
- int fetched;
- double last_fetched;
- sraRegionPtr clip_region;
-} window8bpp_t;
-
-enum mark_8bpp_modes {
- MARK_8BPP_ALL = 0,
- MARK_8BPP_POINTER,
- MARK_8BPP_TOP
-};
-
-
-#define NCOLOR 256
-
-static Colormap root_cmap = 0;
-static unsigned int *root_rgb = NULL;
-
-static void set_root_cmap(void) {
-#if NO_X11
- RAWFB_RET_VOID
- return;
-#else
- static time_t last_set = 0;
- time_t now = time(NULL);
- XWindowAttributes attr;
- static XColor *color = NULL;
- int redo = 0;
- int ncolor = 0;
-
- RAWFB_RET_VOID
-
- if (depth > 16) {
- ncolor = NCOLOR;
- } else if (depth > 8) {
- ncolor = 1 << depth;
- } else {
- ncolor = NCOLOR;
- }
-
- if (!root_rgb) {
- root_rgb = (unsigned int *) malloc(ncolor * sizeof(unsigned int));
- }
- if (!color) {
- color = (XColor *) malloc(ncolor * sizeof(XColor));
- }
-
- if (now > last_set + 10) {
- redo = 1;
- }
- if (! root_cmap || redo) {
- X_LOCK;
- if (! valid_window(window, &attr, 1)) {
- X_UNLOCK;
- return;
- }
- if (attr.colormap) {
- int i, ncells = ncolor;
-
- if (depth < 8) {
- ncells = CellsOfScreen(ScreenOfDisplay(dpy, scr));
- }
- for (i=0; i < ncells; i++) {
- color[i].pixel = i;
- color[i].pad = 0;
- }
- last_set = now;
- root_cmap = attr.colormap;
- XQueryColors(dpy, root_cmap, color, ncells);
- for (i=0; i < ncells; i++) {
- unsigned int red, green, blue;
- /* strip out highest 8 bits of values: */
- red = (color[i].red & 0xff00) >> 8;
- green = (color[i].green & 0xff00) >> 8;
- blue = (color[i].blue & 0xff00) >> 8;
-
- /*
- * the maxes should be at 255 already,
- * but just in case...
- */
- red = (main_red_max * red )/255;
- green = (main_green_max * green)/255;
- blue = (main_blue_max * blue )/255;
-
- /* shift them over and or together for value */
- red = red << main_red_shift;
- green = green << main_green_shift;
- blue = blue << main_blue_shift;
-
- /* store it in the array to be used later */
- root_rgb[i] = red | green | blue;
- }
- }
- X_UNLOCK;
- }
-#endif /* NO_X11 */
-}
-
-/* fixed size array. Will primarily hold visible 8bpp windows */
-#define MAX_8BPP_WINDOWS 64
-static window8bpp_t windows_8bpp[MAX_8BPP_WINDOWS];
-
-static int db24 = 0;
-static int xgetimage_8to24 = 1;
-static double poll_8to24_delay = POLL_8TO24_DELAY;
-static double cache_win = 0.0;
-static int level2_8to24 = 0;
-
-static int check_pointer_in_depth24(void) {
- int tries = 0, in_24 = 0;
- XWindowAttributes attr;
- Window c, w;
- double now = dnow();
-
- c = window;
-
- RAWFB_RET(0)
-
- if (now > last_keyboard_time + 1.0 && now > last_pointer_time + 1.0) {
- return 0;
- }
-
- X_LOCK;
- while (c && tries++ < 3) {
- c = query_pointer(c);
- if (valid_window(c, &attr, 1)) {
- if (attr.depth == 24) {
- in_24 = 1;
- break;
- }
- }
- }
- X_UNLOCK;
- if (in_24) {
- int x1, y1, x2, y2;
- X_LOCK;
- xtranslate(c, window, 0, 0, &x1, &y1, &w, 1);
- X_UNLOCK;
- x2 = x1 + attr.width;
- y2 = y1 + attr.height;
- x1 = nfix(x1, dpy_x);
- y1 = nfix(y1, dpy_y);
- 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 = 1;
- poll_8to24_delay = POLL_8TO24_DELAY;
- level2_8to24 = 0;
- cache_win = 0.0;
- while (p) {
- if (strstr(p, "dbg=") == p) {
- db24 = atoi(p + strlen("dbg="));
- } else if (strstr(p, "poll=") == p) {
- poll_8to24_delay = atof(p + strlen("poll="));
- } else if (strstr(p, "cachewin=") == p) {
- cache_win = atof(p + strlen("cachewin="));
- } else if (!strcmp(p, "nogetimage")) {
- xgetimage_8to24 = 0;
- } else if (!strcmp(p, "level2")) {
- level2_8to24 = 1;
- }
- p = strtok(NULL, ",");
- }
- free(str);
- } else {
- if (getenv("DEBUG_8TO24") != NULL) {
- db24 = atoi(getenv("DEBUG_8TO24"));
- }
- if (getenv("NOXGETIMAGE_8TO24") != NULL) {
- xgetimage_8to24 = 0;
- }
- }
-}
-
-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;
- }
-}
-
-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);
- if (depth > 8 && depth <= 16) {
- pfb(2, &poll8_fb, &poll8_fb_w, &poll8_fb_h); /* 2X for rare 16bpp colormap case */
- } else {
- pfb(1, &poll8_fb, &poll8_fb_w, &poll8_fb_h);
- }
-}
-
-int MV_glob = 0;
-int MV_count;
-int MV_hit;
-double MV_start;
-
-void check_for_multivis(void) {
-#if NO_X11
- RAWFB_RET_VOID
- return;
-#else
- XWindowAttributes attr;
- 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();
- double delay;
-
- RAWFB_RET_VOID
-
- if (now > last_parse + 1.0) {
- 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;
- /* initialize 8bpp window table: */
- for (i=0; i < MAX_8BPP_WINDOWS; i++) {
- windows_8bpp[i].win = None;
- windows_8bpp[i].top = None;
- windows_8bpp[i].map_state = IsUnmapped;
- windows_8bpp[i].cmap = (Colormap) 0;
- windows_8bpp[i].fetched = 0;
- windows_8bpp[i].last_fetched = -1.0;
- windows_8bpp[i].clip_region = NULL;
- }
- set_poll_fb();
-
- first = 0;
- doall = 1; /* fetch everything first time */
- }
-
- if (wireframe_in_progress) {
- return;
- }
-
- set_root_cmap();
-
- /*
- * allocate an "old stack" list of all toplevels. we compare
- * this to the current stack to guess stacking order changes.
- */
- if (!stack_old || stack_old_len < stack_list_len) {
- int n = stack_list_len;
- if (n < 256) {
- n = 256;
- }
- if (stack_old) {
- free(stack_old);
- }
- stack_old = (Window *) calloc(n*sizeof(Window), 1);
- stack_old_len = n;
- }
-
- /* fill the old stack with visible windows: */
- cnt = 0;
- for (k=0; k < stack_list_num; k++) {
- if (stack_list[k].valid &&
- stack_list[k].map_state == IsViewable) {
- stack_old[cnt++] = stack_list[k].win;
- }
- }
-
- /* snapshot + update the current stacking order: */
- /* TUNABLE */
- if (poll_8to24_delay >= POLL_8TO24_DELAY) {
- delay = 3.0 * poll_8to24_delay;
- } else {
- delay = 3.0 * POLL_8TO24_DELAY; /* 0.15 */
- }
- if (doall || now > last_update + delay) {
- snapshot_stack_list(0, 0.0);
- update_stack_list();
- last_update = now;
- }
-
- /* look for differences in the visible toplevels: */
- 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_old[cnt] != stack_list[k].win) {
- diff = 1;
- break;
- }
- cnt++;
- }
- }
-
- multivis_count = 0;
- multivis_24count = 0;
-
- /*
- * every 10 seconds we try to clean out and also refresh the window
- * info in the 8bpp window table:
- */
- if (now > last_clear + 10) {
- last_clear = now;
- X_LOCK;
- for (i=0; i < MAX_8BPP_WINDOWS; i++) {
- Window w = windows_8bpp[i].win;
- if (! valid_window(w, &attr, 1)) {
- /* catch windows that went away: */
- windows_8bpp[i].win = None;
- windows_8bpp[i].top = None;
- windows_8bpp[i].map_state = IsUnmapped;
- windows_8bpp[i].cmap = (Colormap) 0;
- windows_8bpp[i].fetched = 0;
- windows_8bpp[i].last_fetched = -1.0;
- }
- }
- X_UNLOCK;
- }
-
- MV_count = 0;
- MV_hit = 0;
- MV_start = dnow();
-
- set_root_cmap();
-
- /* loop over all toplevels, both 8 and 24 depths: */
-
- X_LOCK; /* a giant lock around the whole activity */
-
- for (k=0; k < stack_list_num; k++) {
- Window r, parent;
- Window *list0;
- Status rc;
- unsigned int nc0;
- int i1;
- XErrorHandler old_handler;
- double delay;
-
- Window win = stack_list[k].win;
-
- /* TUNABLE */
- if (poll_8to24_delay >= POLL_8TO24_DELAY) {
- delay = 1.5 * poll_8to24_delay;
- } else {
- delay = 1.5 * POLL_8TO24_DELAY; /* 0.075 */
- }
-
- if (now < last_query + delay) {
- break;
- }
-
- if (win == None) {
- continue;
- }
-
- if (stack_list[k].map_state != IsViewable) {
- int i;
- /*
- * if the toplevel became unmapped, mark it
- * for the children as well...
- */
- for (i=0; i < MAX_8BPP_WINDOWS; i++) {
- if (windows_8bpp[i].top == win) {
- windows_8bpp[i].map_state =
- stack_list[k].map_state;
- }
- }
- }
-
- if (check_depth(win, win, doall)) {
- /*
- * returns 1 if no need to recurse down e.g. It
- * is 8bpp and we assume all lower ones are too.
- */
- continue;
- }
-
- /* we recurse up to two levels down from stack_list windows */
-
- old_handler = XSetErrorHandler(trap_xerror);
- trapped_xerror = 0;
- rc = XQueryTree_wr(dpy, win, &r, &parent, &list0, &nc0);
- XSetErrorHandler(old_handler);
-
- if (! rc || trapped_xerror) {
- trapped_xerror = 0;
- continue;
- }
- trapped_xerror = 0;
-
- /* loop over grandchildren of rootwin: */
- for (i1=0; i1 < (int) nc0; i1++) {
- Window win1 = list0[i1];
- Window *list1;
- unsigned int nc1;
- int i2;
-
- if (check_depth(win1, win, doall)) {
- continue;
- }
-
- if (level2_8to24) {
- continue;
- }
-
- old_handler = XSetErrorHandler(trap_xerror);
- trapped_xerror = 0;
- rc = XQueryTree_wr(dpy, win1, &r, &parent, &list1, &nc1);
- XSetErrorHandler(old_handler);
-
- if (! rc || trapped_xerror) {
- trapped_xerror = 0;
- continue;
- }
- trapped_xerror = 0;
-
- /* loop over great-grandchildren of rootwin: */
- for (i2=0; i2< (int) nc1; i2++) {
- Window win2 = list1[i2];
-
- if (check_depth(win2, win, doall)) {
- continue;
- }
- /* more? Which wm does this? */
- }
- if (nc1) {
- XFree_wr(list1);
- }
- }
- if (nc0) {
- XFree_wr(list0);
- }
- }
- X_UNLOCK;
-
- last_query = dnow();
-
-MV_glob += MV_count;
-if (0) fprintf(stderr, "MV_count: %d hit: %d %.4f %10.2f\n", MV_count, MV_hit, last_query - MV_start, MV_glob / (last_query - x11vnc_start));
-
- 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 <= 16 && 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;
- }
- }
- }
-if (0) fprintf(stderr, "done: %.4f\n", dnow() - last_query);
-#endif /* NO_X11 */
-}
-
-#define VW_CACHE_MAX 1024
-static XWindowAttributes vw_cache_attr[VW_CACHE_MAX];
-static Window vw_cache_win[VW_CACHE_MAX];
-
-static void set_attr(XWindowAttributes *attr, int j) {
- memcpy((void *) (vw_cache_attr+j), (void *) attr,
- sizeof(XWindowAttributes));
-}
-#if 0
-static int get_attr(XWindowAttributes *attr, int j) {
- memcpy((void *) attr, (void *) (vw_cache_attr+j),
- sizeof(XWindowAttributes));
- return 1;
-}
-#endif
-
-static XWindowAttributes wattr;
-
-static XWindowAttributes *vw_lookup(Window win) {
- static double last_purge = 0.0;
- double now;
- int i, j, k;
-
- if (win == None) {
- return NULL;
- }
-
- now = dnow();
- if (now > last_purge + cache_win) {
- last_purge = now;
- for (i=0; i<VW_CACHE_MAX; i++) {
- vw_cache_win[i] = None;
- }
- }
-
- j = -1;
- k = -1;
- for (i=0; i<VW_CACHE_MAX; i++) {
- if (vw_cache_win[i] == win) {
- j = i;
- break;
- } else if (vw_cache_win[i] == None) {
- k = i;
- break;
- }
- }
-
- if (j >= 0) {
-MV_hit++;
- return vw_cache_attr+j;
-
- } else if (k >= 0) {
- XWindowAttributes attr2;
- int rc = valid_window(win, &attr2, 1);
- if (rc) {
- vw_cache_win[k] = win;
- set_attr(&attr2, k);
- return vw_cache_attr+k;
- } else {
- return NULL;
- }
- } else {
- /* Full */
- int rc = valid_window(win, &wattr, 1);
- if (rc) {
- return &wattr;
- } else {
- return NULL;
- }
- }
-}
-
-static int check_depth(Window win, Window top, int doall) {
- XWindowAttributes attr, *pattr;
-
- /* first see if it is (still) a valid window: */
-MV_count++;
-
- if (cache_win > 0.0) {
- pattr = vw_lookup(win);
- if (pattr == NULL) {
- return 1; /* indicate done */
- }
- } else {
- if (! valid_window(win, &attr, 1)) {
- return 1; /* indicate done */
- }
- pattr = &attr;
- }
-
- if (! doall && pattr->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.
- */
- check_depth_win(win, top, pattr);
- return 1; /* indicate done */
- } else if (check_depth_win(win, top, pattr)) {
- return 1; /* indicate done */
- } else {
- return 0; /* indicate not done */
- }
-}
-
-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).
- */
- if (attr->depth > 0) {
- if (depth == 24 && attr->depth != 24) {
- store_it = 1;
- } else if (depth <= 16 && root_cmap && attr->colormap != root_cmap) {
- store_it = 1;
- }
- }
-
- if (store_it) {
- int i, j = -1, none = -1, nomap = -1;
- int newc = 0;
- if (attr->map_state == IsViewable) {
- /* count the visible ones: */
- multivis_count++;
- if (attr->depth == 24) {
- multivis_24count++;
- }
-if (db24 > 1) fprintf(stderr, "multivis: 0x%lx %d\n", win, attr->depth);
- }
-
- /* try to find a table slot for this window: */
- for (i=0; i < MAX_8BPP_WINDOWS; i++) {
- if (none < 0 && windows_8bpp[i].win == None) {
- /* found first None */
- none = i;
- }
- if (windows_8bpp[i].win == win) {
- /* found myself */
- j = i;
- break;
- }
- if (nomap < 0 && windows_8bpp[i].win != None &&
- windows_8bpp[i].map_state != IsViewable) {
- /* found first unmapped */
- nomap = i;
- }
- }
- if (j < 0) {
- if (attr->map_state != IsViewable) {
- /* no slot and not visible: not worth keeping */
- return 1;
- } else if (none >= 0) {
- /* put it in the first None slot */
- j = none;
- newc = 1;
- } else if (nomap >=0) {
- /* put it in the first unmapped slot */
- j = nomap;
- }
- /* otherwise we cannot store it... */
- }
-
-if (db24 > 1) fprintf(stderr, "multivis: 0x%lx ms: %d j: %d no: %d nm: %d dep=%d\n", win, attr->map_state, j, none, nomap, attr->depth);
-
- /* store if if we found a slot j: */
- if (j >= 0) {
- Window w;
- int x, y;
- int now_vis = 0;
-
- if (attr->map_state == IsViewable &&
- windows_8bpp[j].map_state != IsViewable) {
- now_vis = 1;
- }
-if (db24 > 1) fprintf(stderr, "multivis: STORE 0x%lx j: %3d ms: %d dep=%d\n", win, j, attr->map_state, attr->depth);
- windows_8bpp[j].win = win;
- windows_8bpp[j].top = top;
- windows_8bpp[j].depth = attr->depth;
- windows_8bpp[j].map_state = attr->map_state;
- windows_8bpp[j].cmap = attr->colormap;
- 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;
- windows_8bpp[j].last_fetched = dnow();
-
- /* translate x y to be WRT the root window (not parent) */
- xtranslate(win, window, 0, 0, &x, &y, &w, 1);
- windows_8bpp[j].x = x;
- windows_8bpp[j].y = y;
-
- if (newc || now_vis) {
-if (db24) fprintf(stderr, "new/now_vis: 0x%lx %d/%d\n", win, newc, now_vis);
- /* mark it immediately if a new one: */
- X_UNLOCK; /* dont forget the giant lock */
- mark_rect_as_modified(x, y, x + attr->width,
- y + attr->height, 0);
- X_LOCK;
- }
- } else {
- /*
- * Error: could not find a slot.
- * perhaps keep age and expire old ones??
- */
-if (db24) fprintf(stderr, "multivis: CANNOT STORE 0x%lx j=%d\n", win, j);
- for (i=0; i < MAX_8BPP_WINDOWS; i++) {
-if (db24 > 1) fprintf(stderr, " ------------ 0x%lx i=%d\n", windows_8bpp[i].win, i);
- }
-
- }
- return 1;
- }
- return 0;
-}
-
-/* polling line XImage */
-static XImage *p_xi(XImage *xi, Visual *visual, int win_depth, int *w) {
- RAWFB_RET(NULL)
-
-#if NO_X11
- if (!xi || !visual || !win_depth || !w) {}
- return NULL;
-#else
- if (xi == NULL || *w < dpy_x) {
- char *d;
- if (xi) {
- XDestroyImage(xi);
- }
- if (win_depth != 24) {
- if (win_depth > 8) {
- d = (char *) malloc(dpy_x * 2);
- } else {
- 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;
-#endif /* NO_X11 */
-}
-
-static int poll_line(int x1, int x2, int y1, int n, sraRegionPtr mod) {
-#if NO_X11
- RAWFB_RET(1)
- if (!x1 || !x2 || !y1 || !n || !mod) {}
- return 1;
-#else
- 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;
- XImage *xi;
- Window c, win = windows_8bpp[n].win;
-
- static XWindowAttributes attr;
- static Window last_win = None;
- static double last_time = 0.0;
- double now;
-
- sraRegionPtr rect;
- int mx1, mx2, my1, my2;
- int ns = NSCAN/2;
-
- RAWFB_RET(1)
-
- if (win == None) {
- return 1;
- }
- if (windows_8bpp[n].map_state != IsViewable) {
- return 1;
- }
- if (! xgetimage_8to24) {
- return 1;
- }
-
- X_LOCK;
- now = dnow();
- if (last_win != None && win == last_win && now < last_time + 0.5) {
- ; /* use previous attr */
- } else {
- if (! valid_window(win, &attr, 1)) {
- X_UNLOCK;
- last_win = None;
- return 0;
- }
- last_time = now;
- last_win = win;
- }
-
- if (attr.depth > 16 && attr.depth != 24) {
- X_UNLOCK;
- return 1;
- } else if (attr.depth <= 16) {
- xi = xi8 = p_xi(xi8, attr.visual, attr.depth, &xi8_w);
-
- poll_fb = poll8_fb;
- if (attr.depth > 8) {
- fac = 2;
- } else {
- 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;
- }
-
- old_handler = XSetErrorHandler(trap_xerror);
- trapped_xerror = 0;
-
- /* xtranslate() not used to save two XSetErrorHandler calls */
- XTranslateCoordinates(dpy, win, window, 0, 0, &xo, &yo, &c);
-
- xo = x1 - xo;
- yo = y1 - yo;
- w = x2 - x1;
-
- if (trapped_xerror || xo < 0 || yo < 0 || xo + w > attr.width) {
-if (db24 > 2) fprintf(stderr, "avoid bad match...\n");
- XSetErrorHandler(old_handler);
- trapped_xerror = 0;
- X_UNLOCK;
- return 0;
- }
-
- trapped_xerror = 0;
- 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;
-#endif /* NO_X11 */
-}
-
-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
-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);
- }
-
- 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;
-
- /* initialize color map list */
- ncmaps = 0;
- for (i=0; i < CMAPMAX; i++) {
- cmaps[i] = (Colormap) 0;
- }
-
- /* loop over the table of 8bpp windows: */
- for (i=0; i < MAX_8BPP_WINDOWS; i++) {
- sraRegionPtr tmp_reg, tmp_reg2;
- Window c, w = windows_8bpp[i].win;
- int x, y;
-
- 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_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
- * time...
- */
-
- X_LOCK;
- if (! valid_window(w, &attr, 1)) {
- X_UNLOCK;
- windows_8bpp[i].win = None;
- windows_8bpp[i].top = None;
- windows_8bpp[i].map_state = IsUnmapped;
- windows_8bpp[i].cmap = (Colormap) 0;
- windows_8bpp[i].fetched = 0;
- windows_8bpp[i].last_fetched = -1.0;
- 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;
- windows_8bpp[i].last_fetched = dnow();
-
- if (attr.map_state != IsViewable) {
- continue;
- }
-
- 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;
- }
- 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+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--) {
- Window swin = stack_list[k].win;
- int sx, sy, sw, sh;
-
-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 skip the rest. */
-if (db24 > 1) fprintf(stderr, "found top: 0x%lx %d iv=%d\n", swin, k, stack_list[k].map_state);
- break;
- }
- if (stack_list[k].map_state != IsViewable) {
- /* skip unmapped ones: */
- continue;
- }
-
- /* make a temp rect for this toplevel: */
- sx = stack_list[k].x;
- sy = stack_list[k].y;
- sw = stack_list[k].width;
- sh = stack_list[k].height;
-
-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+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);
- continue;
- }
-
- /* otherwise, store any new colormaps: */
- if (ncmaps < CMAPMAX && attr.colormap != (Colormap) 0) {
- int m, seen = 0;
- for (m=0; m < ncmaps; m++) {
- if (cmaps[m] == attr.colormap) {
- seen = 1;
- break;
- }
- }
- if (!seen && attr.depth <= 16) {
- /* store only new ones: */
- cmaps[ncmaps++] = attr.colormap;
- }
- }
-
- windows_8bpp[i].clip_region = tmp_reg;
- }
-
- return mapcount;
-}
-
-static XColor *color[CMAPMAX];
-static unsigned int *rgb[CMAPMAX];
-static int cmap_failed[CMAPMAX];
-static int color_init = 0;
-int histo[65536];
-
-static int get_cmap(int j, Colormap cmap) {
-#if NO_X11
- RAWFB_RET(0)
- if (!j || !cmap) {}
- return 0;
-#else
- int i, ncells, ncolor;
- XErrorHandler old_handler = NULL;
-
- RAWFB_RET(0)
-
- if (depth > 16) {
- /* 24 */
- ncolor = NCOLOR;
- } else if (depth > 8) {
- ncolor = 1 << depth;
- } else {
- ncolor = NCOLOR;
- }
- if (!color_init) {
- int cm;
- for (cm = 0; cm < CMAPMAX; cm++) {
- color[cm] = (XColor *) malloc(ncolor * sizeof(XColor));
- rgb[cm] = (unsigned int *) malloc(ncolor * sizeof(unsigned int));
- }
- color_init = 1;
- }
-
- if (depth <= 16) {
- /* not working properly for depth 24... */
- X_LOCK;
- ncells = CellsOfScreen(ScreenOfDisplay(dpy, scr));
- X_UNLOCK;
- } else {
- ncells = NCOLOR;
- }
-
- if (depth > 16) {
- ;
- } else if (ncells > ncolor) {
- ncells = ncolor;
- } else if (ncells == 8 && depth != 3) {
- /* XXX. see set_colormap() */
- ncells = 1 << depth;
- }
-
- /* initialize XColor array: */
- for (i=0; i < ncells; i++) {
- color[j][i].pixel = i;
- color[j][i].pad = 0;
- }
-if (db24 > 1) fprintf(stderr, "get_cmap: %d 0x%x ncolor=%d ncells=%d\n", j, (unsigned int) cmap, ncolor, ncells);
-
- /* try to query the colormap, trap errors */
- X_LOCK;
- trapped_xerror = 0;
- old_handler = XSetErrorHandler(trap_xerror);
- XQueryColors(dpy, cmap, color[j], ncells);
- XSetErrorHandler(old_handler);
- X_UNLOCK;
-
- if (trapped_xerror) {
- trapped_xerror = 0;
- return 0;
- }
- trapped_xerror = 0;
-
- /* now map each index to depth 24 RGB */
- for (i=0; i < ncells; i++) {
- unsigned int red, green, blue;
- /* strip out highest 8 bits of values: */
- red = (color[j][i].red & 0xff00) >> 8;
- green = (color[j][i].green & 0xff00) >> 8;
- blue = (color[j][i].blue & 0xff00) >> 8;
-
- /*
- * the maxes should be at 255 already,
- * but just in case...
- */
- red = (main_red_max * red )/255;
- green = (main_green_max * green)/255;
- blue = (main_blue_max * blue )/255;
-
-if (db24 > 2) fprintf(stderr, " cmap[%02d][%03d]: %03d %03d %03d 0x%08x \n", j, i, red, green, blue, ( red << main_red_shift | green << main_green_shift | blue << main_blue_shift));
-
- /* shift them over and or together for value */
- red = red << main_red_shift;
- 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;
-#endif /* NO_X11 */
-}
-
-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);
-
- /* 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[n].depth != 24) { /* 24 won't have a cmap */
- if (failed || cm == -1) {
- return;
- }
- }
-
- clip = sraRgnCreateRgn(mark);
- sraRgnAnd(clip, windows_8bpp[n].clip_region);
-
- /* 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;
- }
-
- transform_rect(rect, windows_8bpp[n].win,
- windows_8bpp[n].depth, cm);
- }
- sraRgnReleaseIterator(iter);
- sraRgnDestroy(clip);
-}
-
-static XImage *cmap_xi(XImage *xi, Window win, int win_depth) {
-#if NO_X11
- if (!xi || !win || !win_depth) {}
- return NULL;
-#else
- XWindowAttributes attr;
- char *d;
-
- if (xi) {
- XDestroyImage(xi);
- }
- if (! dpy || ! valid_window(win, &attr, 1)) {
- return (XImage *) NULL;
- }
- if (win_depth == 24) {
- d = (char *) malloc(dpy_x * dpy_y * 4);
- } else if (win_depth <= 16) {
- if (win_depth > 8) {
- d = (char *) malloc(dpy_x * dpy_y * 2);
- } else {
- d = (char *) malloc(dpy_x * dpy_y * 1);
- }
- } else {
- return (XImage *) NULL;
- }
- return XCreateImage(dpy, attr.visual, win_depth, ZPixmap, 0, d, dpy_x, dpy_y, 8, 0);
-#endif /* NO_X11 */
-}
-
-
-static void transform_rect(sraRect rect, Window win, int win_depth, int cm) {
-#if NO_X11
- RAWFB_RET_VOID
- if (!rect.x1 || !win || !win_depth || !cm) {}
- return;
-#else
-
- char *src, *dst, *poll;
- unsigned int *ui;
- unsigned short *us;
- unsigned char *uc;
- int ps, pixelsize = bpp/8;
- int poll_Bpl;
-
- int do_getimage = xgetimage_8to24;
- int line, n_off, j, h, w;
- unsigned int hi, idx;
- XWindowAttributes attr;
- XErrorHandler old_handler = NULL;
-
-if (db24 > 1) fprintf(stderr, "transform %4d %4d %4d %4d cm: %d\n", rect.x1, rect.y1, rect.x2, rect.y2, cm);
-
- RAWFB_RET_VOID
-
- attr.width = 0;
- attr.height = 0;
-
- /* 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 != 24) {
- /* need to fetch depth 24 data. */
- do_getimage = 1;
- }
-
-#if 0
- if (do_getimage) {
- X_LOCK;
- vw = valid_window(win, &attr, 1);
- X_UNLOCK;
- }
-
- if (do_getimage && vw) {
-#else
- if (do_getimage) {
-#endif
- static XImage *xi_8 = NULL;
- static XImage *xi_24 = NULL;
- XImage *xi = NULL, *xi_r;
- Window c;
- unsigned int wu, hu;
- int xo, yo;
-
- wu = (unsigned int) w;
- hu = (unsigned int) h;
-
- X_LOCK;
-#define GETSUBIMAGE
-#ifdef GETSUBIMAGE
- if (win_depth == 24) {
- if (xi_24 == NULL || xi_24->width != dpy_x ||
- xi_24->height != dpy_y) {
- xi_24 = cmap_xi(xi_24, win, 24);
- }
- xi = xi_24;
- } else if (win_depth <= 16) {
- if (xi_8 == NULL || xi_8->width != dpy_x ||
- xi_8->height != dpy_y) {
- if (win_depth > 8) {
- /* XXX */
- xi_8 = cmap_xi(xi_8, win, 16);
- } else {
- xi_8 = cmap_xi(xi_8, win, 8);
- }
- }
- xi = xi_8;
- }
-#endif
-
- if (xi == NULL) {
- rfbLog("transform_rect: xi is NULL\n");
- X_UNLOCK;
- clean_up_exit(1);
- }
-
- old_handler = XSetErrorHandler(trap_xerror);
- trapped_xerror = 0;
-
- XTranslateCoordinates(dpy, win, window, 0, 0, &xo, &yo, &c);
-
- xo = rect.x1 - xo;
- yo = rect.y1 - yo;
-
-if (db24 > 1) fprintf(stderr, "xywh: %d %d %d %d vs. %d %d\n", xo, yo, w, h, attr.width, attr.height);
-
- if (trapped_xerror || xo < 0 || yo < 0) {
- /* w > attr.width || h > attr.height */
- XSetErrorHandler(old_handler);
- X_UNLOCK;
- trapped_xerror = 0;
-if (db24 > 1) fprintf(stderr, "skipping due to potential bad match...\n");
- return;
- }
- trapped_xerror = 0;
-
-#ifndef GETSUBIMAGE
- xi = XGetImage(dpy, win, xo, yo, wu, hu, AllPlanes, ZPixmap);
- xi_r = xi;
-#else
- xi_r = XGetSubImage(dpy, win, xo, yo, wu, hu, AllPlanes,
- ZPixmap, xi, 0, 0);
-#endif
- XSetErrorHandler(old_handler);
-
- X_UNLOCK;
-
- 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;
- } else {
-if (db24 > 1) fprintf(stderr, "xi: 0x%p %d %d %d %d -- %d %d\n", (void *)xi, xo, yo, w, h, xi->width, xi->height);
- }
- trapped_xerror = 0;
-
- if (xi->depth > 16 && xi->depth != 24) {
-#ifndef GETSUBIMAGE
- X_LOCK;
- XDestroyImage(xi);
- X_UNLOCK;
-#endif
-if (db24) fprintf(stderr, "xi: wrong depth: %d\n", xi->depth);
- return;
- }
-
- set_poll_fb();
-
- if (xi->depth == 24) {
- /* line by line ... */
- int ps1 = 4, fac;
- if (depth <= 8) {
- fac = 4;
- } else if (depth <= 16) {
- fac = 2;
- } else {
- fac = 1; /* will not happen 24 on 24 */
- }
-
- 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(poll, src, w * ps1);
-
- src += xi->bytes_per_line;
- dst += main_bytes_per_line * fac;
- poll += poll_Bpl;
- }
- } else if (xi->depth <= 16) {
- int ps1, ps2, fac;
-
- if (depth <= 8) {
- ps1 = 1;
- ps2 = 4;
- fac = 4;
- } else if (depth <= 16) {
- ps1 = 2;
- ps2 = 4;
- fac = 4;
- } else {
- /* should be 24 case */
- ps1 = 1;
- ps2 = pixelsize;
- fac = 1;
- }
-
- src = xi->data;
- dst = cmap8to24_fb + (fac/ps1) * n_off;
-
- poll = poll8_fb + poll8_fb_w * rect.y1 * ps1 + rect.x1 * ps1;
- poll_Bpl = poll8_fb_w * ps1;
-
- /* line by line ... */
- for (line = 0; line < h; line++) {
- /* pixel by pixel... */
- for (j = 0; j < w; j++) {
- if (ps1 == 2) {
- unsigned short *ptmp;
- us = (unsigned short *) (src + ps1 * j);
- idx = (int) (*us);
- ptmp = (unsigned short *) (poll + ps1 * j);
- *ptmp = *us;
- } else {
- uc = (unsigned char *) (src + ps1 * j);
- idx = (int) (*uc);
- *(poll + ps1 * j) = *uc;
- }
- ui = (unsigned int *) (dst + ps2 * j);
- *ui = rgb[cm][idx];
-
- }
- src += xi->bytes_per_line;
- dst += main_bytes_per_line * (fac/ps1);
- poll += poll_Bpl;
- }
- }
-
-#ifndef GETSUBIMAGE
- X_LOCK;
- XDestroyImage(xi);
- X_UNLOCK;
-#endif
-
- } else if (! do_getimage) {
- int fac;
-
- if (depth <= 16) {
- /* cooked up depth 24 TrueColor */
- /* but currently disabled (high bits no useful?) */
- ps = 4;
- fac = 4;
- /* XXX not correct for depth > 8, but do we ever come here in that case? */
- src = cmap8to24_fb + 4 * n_off;
- } else {
- ps = pixelsize;
- fac = 1;
- src = cmap8to24_fb + n_off;
- }
-
- /* line by line ... */
- for (line = 0; line < h; line++) {
- /* pixel by pixel... */
- for (j = 0; j < w; j++) {
-
- /* grab 32 bit value */
- ui = (unsigned int *) (src + ps * j);
-
- /* extract top 8 bits (FIXME: masks?) */
- hi = (*ui) & 0xff000000;
-
- /* map to lookup index; rewrite pixel */
- idx = hi >> 24;
- *ui = hi | rgb[cm][idx];
- }
- src += main_bytes_per_line * fac;
- }
- }
-#endif /* NO_X11 */
-}
-
-void bpp8to24(int x1, int y1, int x2, int y2) {
- char *src, *dst;
- unsigned char *uc;
- unsigned short *us;
- unsigned int *ui;
- int idx, pixelsize = bpp/8;
- int line, k, i, j, h, w;
- int n_off;
- 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;
- double dt, d0 = 0.0, t2;
-
- RAWFB_RET_VOID
-
- if (! cmap8to24 || ! cmap8to24_fb) {
- /* hmmm, why were we called? */
- return;
- }
-
-if (db24 > 1) fprintf(stderr, "bpp8to24 %d %d %d %d %.4f\n", x1, y1, x2, y2, dnow() - last_get_8bpp_validate);
-
- call_count++;
-
- /* clip to display just in case: */
- if (!ncache) {
- x1 = nfix(x1, dpy_x);
- y1 = nfix(y1, dpy_y);
- x2 = nfix(x2, dpy_x+1);
- y2 = nfix(y2, dpy_y+1);
- }
-
- 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;
- }
-
- /* copy from main_fb to cmap8to24_fb regardless of 8bpp windows: */
-
- h = y2 - y1;
- w = x2 - x1;
-
- if (depth == 24) {
- /* pixelsize = 4 */
- n_off = main_bytes_per_line * y1 + pixelsize * x1;
-
- src = main_fb + n_off;
- dst = cmap8to24_fb + n_off;
-
- /* otherwise, the pixel data as is */
- for (line = 0; line < h; line++) {
- memcpy(dst, src, w * pixelsize);
- src += main_bytes_per_line;
- dst += main_bytes_per_line;
- }
- } else if (depth <= 16) {
- /* need to cook up to depth 24 TrueColor */
- int ps1 = 1, ps2 = 4;
- if (depth > 8) {
- ps1 = 2;
- }
-
- /* pixelsize = 1, 2 */
- n_off = main_bytes_per_line * y1 + pixelsize * x1;
-
- src = main_fb + n_off;
- dst = cmap8to24_fb + (4/ps1) * n_off;
-
- set_root_cmap();
- if (root_cmap) {
-#if 0
- unsigned int hi;
-#endif
-
- /* line by line ... */
- for (line = 0; line < h; line++) {
- /* pixel by pixel... */
- for (j = 0; j < w; j++) {
- if (ps1 == 2) {
- us = (unsigned short *) (src + ps1 * j);
- idx = (int) (*us);
- } else {
- uc = (unsigned char *) (src + ps1 * j);
- idx = (int) (*uc);
- }
- ui = (unsigned int *) (dst + ps2 * j);
-
-if (0 && line % 100 == 0 && j % 32 == 0) fprintf(stderr, "%d %d %u x1=%d y1=%d\n", line, j, root_rgb[idx], x1, y1);
-#if 0
- if (do_hibits) {
- hi = idx << 24;
- *ui = hi | rgb[0][idx];
- } else {
- }
-#endif
- *ui = root_rgb[idx];
-if (db24 > 2) histo[idx]++;
- }
- src += main_bytes_per_line;
- dst += main_bytes_per_line * (4/ps1);
- }
- }
-
- }
-
- 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;}}
-
- now = dnow();
- dt = now - last_get_8bpp_validate;
- /* TUNABLES */
- if (dt < 0.003) {
- ; /* XXX does this still give painting errors? */
- } else {
- int snapit = 0;
- double delay1, delay2, delay3;
- if (poll_8to24_delay >= POLL_8TO24_DELAY) {
- delay1 = 1.0 * poll_8to24_delay;
- delay2 = 2.0 * poll_8to24_delay;
- delay3 = 10. * poll_8to24_delay;
- } else {
- delay1 = 1.0 * POLL_8TO24_DELAY; /* 0.05 */
- delay2 = 2.0 * POLL_8TO24_DELAY; /* 0.1 */
- delay3 = 10. * POLL_8TO24_DELAY; /* 0.5 */
- }
- if (cache_win > 1.0) {
- delay2 *= 2;
- delay3 *= 2;
- }
- if (dt < delay1) {
- validate = 0;
- }
- if (last_map_count) {
- if (now > last_snapshot + delay2) {
- snapit = 1;
- }
- } else {
- if (now > last_snapshot + delay3) {
- snapit = 1;
- }
- }
-
- if (snapit) {
- /* less problems if we update the stack frequently */
- snapshot_stack_list(0, 0.0);
-if (0) fprintf(stderr, "SNAP time: %.4f\n", dnow() - now);
- update_stack_list();
- last_snapshot = dnow();
-if (0) fprintf(stderr, "UPDA time: %.4f\n", last_snapshot - now);
- }
-
-if (0) t2 = dnow();
- last_map_count = get_8bpp_regions(validate);
- if (validate) {
- last_get_8bpp_validate = dnow();
- }
-if (0) fprintf(stderr, "get8bpp-%d: %.4f\n", validate, dnow() - t2);
- }
-if (db24) d0 = dnow();
-
-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 transform and 8bpp regions to TrueColor in
- * cmap8to24_fb.
- */
- if (last_map_count && (ncmaps || depth <= 16)) {
- 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
- * X server. Hopefully just 1 or 2...
- */
- for (j=0; j<ncmaps; j++) {
- if (! get_cmap(j, cmaps[j])) {
- cmap_failed[j] = 1;
- } else {
- cmap_failed[j] = 0;
- }
-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);
- }
- }
-
- 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;
- }
- }
- }
- for (j=0; j<count; j++) {
- if (! did[j]) {
- i = win[j];
- do_8bpp_region(i, rect);
- did[j] = 1;
- }
- }
- sraRgnDestroy(rect);
- }
- }
-if (0) fprintf(stderr, "done time: %.4f\n", dnow() - d0);
-
-if (db24 > 2) {for(i=0; i<256;i++) {fprintf(stderr, " cmap histo[%03d] %d\n", i, histo[i]);}}
-}
-
-void mark_8bpp(int mode) {
- int i, cnt = 0;
- Window top = None;
-
- RAWFB_RET_VOID
-
- 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: */
-
- for (i=0; i < MAX_8BPP_WINDOWS; i++) {
- int x1, y1, x2, y2, w, h, f = 32;
-
- f = 0; /* skip fuzz, may bring in other windows... */
-
- 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 = 0;
-
- X_LOCK;
- vw = valid_window(windows_8bpp[i].win, &attr, 1);
- X_UNLOCK;
- if (vw) {
- if (attr.map_state != IsViewable) {
- continue;
- }
- } else {
- continue;
- }
- }
-
- x1 = windows_8bpp[i].x;
- y1 = windows_8bpp[i].y;
- w = windows_8bpp[i].w;
- h = windows_8bpp[i].h;
-
- 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+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);
-
- mark_rect_as_modified(x1, y1, x2, y2, 0);
- cnt++;
- }
- if (cnt) {
- /* push it to viewers if possible. */
- rfbPE(-1);
- }
-}
-
-#endif /* SKIP_8TO24 */
-
OpenPOWER on IntegriCloud