summaryrefslogtreecommitdiffstats
path: root/x11vnc/xwrappers.c
diff options
context:
space:
mode:
Diffstat (limited to 'x11vnc/xwrappers.c')
-rw-r--r--x11vnc/xwrappers.c224
1 files changed, 203 insertions, 21 deletions
diff --git a/x11vnc/xwrappers.c b/x11vnc/xwrappers.c
index 40fd8fa..181c4f1 100644
--- a/x11vnc/xwrappers.c
+++ b/x11vnc/xwrappers.c
@@ -18,6 +18,8 @@ int clipshift = 0;
int guess_bits_per_color(int bits_per_pixel);
+int XFlush_wr(Display *disp);
+
Status XShmGetImage_wr(Display *disp, Drawable d, XImage *image, int x, int y,
unsigned long mask);
XImage *XShmCreateImage_wr(Display* disp, Visual* vis, unsigned int depth,
@@ -66,11 +68,9 @@ void disable_grabserver(Display *in_dpy, int change);
Bool XRecordQueryVersion_wr(Display *dpy, int *maj, int *min);
-
-static void copy_raw_fb(XImage *dest, int x, int y, unsigned int w, unsigned int h);
+void copy_raw_fb(XImage *dest, int x, int y, unsigned int w, unsigned int h);
static void upup_downdown_warning(KeyCode key, Bool down);
-
/*
* used in rfbGetScreen and rfbNewFramebuffer: and estimate to the number
* of bits per color, of course for some visuals, e.g. 565, the number
@@ -96,6 +96,14 @@ int guess_bits_per_color(int bits_per_pixel) {
return bits_per_color;
}
+int XFlush_wr(Display *disp) {
+ if (disp) {
+ return XFlush(disp);
+ } else {
+ return 1;
+ }
+}
+
/*
* Kludge to interpose image gets and limit to a subset rectangle of
* the rootwin. This is the -sid option trying to work around invisible
@@ -277,17 +285,161 @@ XImage *XCreateImage_wr(Display *disp, Visual *visual, unsigned int depth,
width, height, bitmap_pad, bytes_per_line);
}
-static void copy_raw_fb(XImage *dest, int x, int y, unsigned int w, unsigned int h) {
+static void copy_raw_fb_24_to_32(XImage *dest, int x, int y, unsigned int w,
+ unsigned int h) {
+ /*
+ * kludge to read 1 byte at a time and dynamically transform
+ * 24bpp -> 32bpp by inserting a extra 0 byte into dst.
+ */
+ char *src, *dst;
+ unsigned int line;
+ static char *buf = NULL;
+ static int buflen = -1;
+ int bpl = wdpy_x * 3; /* pixelsize == 3 */
+ int LE, n, stp, len, del, sz = w * 3;
+ int insert_zeroes = 1;
+
+#define INSERT_ZEROES \
+ len = sz; \
+ del = 0; \
+ stp = 0; \
+ while (len > 0) { \
+ if (insert_zeroes && (del - LE) % 4 == 0) { \
+ *(dst + del) = 0; \
+ del++; \
+ } \
+ *(dst + del) = *(buf + stp); \
+ del++; \
+ len--; \
+ stp++; \
+ }
+
+ if (rfbEndianTest) {
+ LE = 3; /* little endian */
+ } else {
+ LE = 0; /* big endian */
+ }
+
+ if (sz > buflen || buf == NULL) {
+ if (buf) {
+ free(buf);
+ }
+ buf = (char *) malloc(4*(sz + 1000));
+ }
+
+ if (clipshift && ! use_snapfb) {
+ x += coff_x;
+ y += coff_y;
+ }
+
+ if (use_snapfb && dest != snap) {
+ /* snapfb src */
+ src = snap->data + snap->bytes_per_line*y + 3*x;
+ dst = dest->data;
+ for (line = 0; line < h; line++) {
+ memcpy(buf, src, sz);
+
+ INSERT_ZEROES
+
+ src += snap->bytes_per_line;
+ dst += dest->bytes_per_line;
+ }
+
+ } else if (! raw_fb_seek) {
+ /* mmap */
+ src = raw_fb_addr + raw_fb_offset + bpl*y + 3*x;
+ dst = dest->data;
+
+ if (use_snapfb && dest == snap) {
+ /*
+ * writing *to* snap_fb: need the x,y offset,
+ * and also do not do inserts.
+ */
+ dst += bpl*y + 3*x;
+ insert_zeroes = 0;
+ }
+
+ for (line = 0; line < h; line++) {
+ memcpy(buf, src, sz);
+
+ INSERT_ZEROES
+
+ src += bpl;
+ dst += dest->bytes_per_line;
+ }
+
+ } else {
+ /* lseek */
+ off_t off = (off_t) (raw_fb_offset + bpl*y + 3*x);
+
+ lseek(raw_fb_fd, off, SEEK_SET);
+ dst = dest->data;
+
+ if (use_snapfb && dest == snap) {
+ /*
+ * writing *to* snap_fb: need the x,y offset,
+ * and also do not do inserts.
+ */
+ dst += bpl*y + 3*x;
+ insert_zeroes = 0;
+ }
+
+ for (line = 0; line < h; line++) {
+ len = sz;
+ del = 0;
+ while (len > 0) {
+ n = read(raw_fb_fd, buf + del, len);
+
+ if (n > 0) {
+ del += n;
+ len -= n;
+ } else if (n == 0) {
+ break;
+ } else if (errno != EINTR && errno != EAGAIN) {
+ break;
+ }
+ }
+
+ INSERT_ZEROES
+
+ if (bpl > sz) {
+ off = (off_t) (bpl - sz);
+ lseek(raw_fb_fd, off, SEEK_CUR);
+ }
+ dst += dest->bytes_per_line;
+ }
+ }
+}
+
+void copy_raw_fb(XImage *dest, int x, int y, unsigned int w, unsigned int h) {
char *src, *dst;
unsigned int line;
int pixelsize = bpp/8;
int bpl = wdpy_x * pixelsize;
- if (clipshift) {
+ if (xform24to32) {
+ copy_raw_fb_24_to_32(dest, x, y, w, h);
+ return;
+ }
+
+ if (clipshift && ! use_snapfb) {
x += coff_x;
y += coff_y;
}
- if (! raw_fb_seek) {
+
+ if (use_snapfb && dest != snap) {
+ /* snapfb src */
+ src = snap->data + snap->bytes_per_line*y + pixelsize*x;
+ dst = dest->data;
+
+ for (line = 0; line < h; line++) {
+ memcpy(dst, src, w * pixelsize);
+ src += snap->bytes_per_line;
+ dst += dest->bytes_per_line;
+ }
+
+ } else if (! raw_fb_seek) {
+ /* mmap */
src = raw_fb_addr + raw_fb_offset + bpl*y + pixelsize*x;
dst = dest->data;
@@ -296,32 +448,35 @@ static void copy_raw_fb(XImage *dest, int x, int y, unsigned int w, unsigned int
src += bpl;
dst += dest->bytes_per_line;
}
- } else{
+
+ } else {
+ /* lseek */
int n, len, del, sz = w * pixelsize;
off_t off = (off_t) (raw_fb_offset + bpl*y + pixelsize*x);
lseek(raw_fb_fd, off, SEEK_SET);
dst = dest->data;
+if (0) fprintf(stderr, "lseek 0 ps: %d sz: %d off: %d bpl: %d\n", pixelsize, sz, (int) off, bpl);
+
for (line = 0; line < h; line++) {
len = sz;
del = 0;
while (len > 0) {
n = read(raw_fb_fd, dst + del, len);
+if (0) fprintf(stderr, "len: %d n: %d\n", len, n);
if (n > 0) {
del += n;
len -= n;
} else if (n == 0) {
break;
- } else {
- /* overkill... */
- if (errno != EINTR && errno != EAGAIN) {
- break;
- }
+ } else if (errno != EINTR && errno != EAGAIN) {
+ break;
}
}
if (bpl > sz) {
+if (0) fprintf(stderr, "bpl>sz %d %d\n", bpl, sz);
off = (off_t) (bpl - sz);
lseek(raw_fb_fd, off, SEEK_CUR);
}
@@ -332,6 +487,9 @@ static void copy_raw_fb(XImage *dest, int x, int y, unsigned int w, unsigned int
void copy_image(XImage *dest, int x, int y, unsigned int w, unsigned int h) {
/* default (w=0, h=0) is the fill the entire XImage */
+ if (dest == NULL) {
+ return;
+ }
if (w < 1) {
w = dest->width;
}
@@ -339,7 +497,10 @@ void copy_image(XImage *dest, int x, int y, unsigned int w, unsigned int h) {
h = dest->height;
}
- if (use_snapfb && snap_fb && dest != snaprect) {
+ if (raw_fb) {
+ copy_raw_fb(dest, x, y, w, h);
+
+ } else if (use_snapfb && snap_fb && dest != snaprect) {
char *src, *dst;
unsigned int line;
int pixelsize = bpp/8;
@@ -352,10 +513,7 @@ void copy_image(XImage *dest, int x, int y, unsigned int w, unsigned int h) {
dst += dest->bytes_per_line;
}
- } else if (raw_fb) {
- copy_raw_fb(dest, x, y, w, h);
-
- } else if (using_shm && (int) w == dest->width &&
+ } else if ((using_shm && ! xform24to32) && (int) w == dest->width &&
(int) h == dest->height) {
XShmGetImage_wr(dpy, window, dest, x, y, AllPlanes);
@@ -379,6 +537,8 @@ void init_track_keycode_state(void) {
}
static void upup_downdown_warning(KeyCode key, Bool down) {
+ RAWFB_RET_VOID
+
if ((down ? 1:0) == keycode_state[(int) key]) {
rfbLog("XTestFakeKeyEvent: keycode=0x%x \"%s\" is *already* "
"%s\n", key, XKeysymToString(XKeycodeToKeysym(dpy, key, 0)),
@@ -394,12 +554,14 @@ static void upup_downdown_warning(KeyCode key, Bool down) {
void XTRAP_FakeKeyEvent_wr(Display* dpy, KeyCode key, Bool down,
unsigned long delay) {
+ RAWFB_RET_VOID
+
if (! xtrap_present) {
DEBUG_SKIPPED_INPUT(debug_keyboard, "keyboard: no-XTRAP");
return;
}
/* unused vars warning: */
- if (dpy || key || down || delay) {}
+ if (key || down || delay) {}
#if LIBVNCSERVER_HAVE_LIBXTRAP
XESimulateXEventRequest(trap_ctx, down ? KeyPress : KeyRelease,
@@ -416,6 +578,9 @@ void XTRAP_FakeKeyEvent_wr(Display* dpy, KeyCode key, Bool down,
void XTestFakeKeyEvent_wr(Display* dpy, KeyCode key, Bool down,
unsigned long delay) {
static int first = 1;
+
+ RAWFB_RET_VOID
+
if (debug_keyboard) {
rfbLog("XTestFakeKeyEvent(dpy, keycode=0x%x \"%s\", %s)\n",
key, XKeysymToString(XKeycodeToKeysym(dpy, key, 0)),
@@ -456,12 +621,14 @@ void XTestFakeKeyEvent_wr(Display* dpy, KeyCode key, Bool down,
void XTRAP_FakeButtonEvent_wr(Display* dpy, unsigned int button, Bool is_press,
unsigned long delay) {
+ RAWFB_RET_VOID
+
if (! xtrap_present) {
DEBUG_SKIPPED_INPUT(debug_keyboard, "button: no-XTRAP");
return;
}
/* unused vars warning: */
- if (dpy || button || is_press || delay) {}
+ if (button || is_press || delay) {}
#if LIBVNCSERVER_HAVE_LIBXTRAP
XESimulateXEventRequest(trap_ctx,
@@ -474,6 +641,8 @@ void XTRAP_FakeButtonEvent_wr(Display* dpy, unsigned int button, Bool is_press,
void XTestFakeButtonEvent_wr(Display* dpy, unsigned int button, Bool is_press,
unsigned long delay) {
+ RAWFB_RET_VOID
+
if (xtrap_input) {
XTRAP_FakeButtonEvent_wr(dpy, button, is_press, delay);
return;
@@ -495,6 +664,8 @@ void XTestFakeButtonEvent_wr(Display* dpy, unsigned int button, Bool is_press,
void XTRAP_FakeMotionEvent_wr(Display* dpy, int screen, int x, int y,
unsigned long delay) {
+ RAWFB_RET_VOID
+
if (! xtrap_present) {
DEBUG_SKIPPED_INPUT(debug_keyboard, "motion: no-XTRAP");
return;
@@ -512,6 +683,8 @@ void XTRAP_FakeMotionEvent_wr(Display* dpy, int screen, int x, int y,
void XTestFakeMotionEvent_wr(Display* dpy, int screen, int x, int y,
unsigned long delay) {
+ RAWFB_RET_VOID
+
if (xtrap_input) {
XTRAP_FakeMotionEvent_wr(dpy, screen, x, y, delay);
return;
@@ -530,6 +703,8 @@ Bool XTestCompareCurrentCursorWithWindow_wr(Display* dpy, Window w) {
if (! xtest_present) {
return False;
}
+ RAWFB_RET(False)
+
#if LIBVNCSERVER_HAVE_XTEST
return XTestCompareCurrentCursorWithWindow(dpy, w);
#else
@@ -541,6 +716,7 @@ Bool XTestCompareCursorWithWindow_wr(Display* dpy, Window w, Cursor cursor) {
if (! xtest_present) {
return False;
}
+ RAWFB_RET(False)
#if LIBVNCSERVER_HAVE_XTEST
return XTestCompareCursorWithWindow(dpy, w, cursor);
#else
@@ -550,6 +726,7 @@ Bool XTestCompareCursorWithWindow_wr(Display* dpy, Window w, Cursor cursor) {
Bool XTestQueryExtension_wr(Display *dpy, int *ev, int *er, int *maj,
int *min) {
+ RAWFB_RET(False)
#if LIBVNCSERVER_HAVE_XTEST
return XTestQueryExtension(dpy, ev, er, maj, min);
#else
@@ -561,18 +738,20 @@ void XTestDiscard_wr(Display *dpy) {
if (! xtest_present) {
return;
}
+ RAWFB_RET_VOID
#if LIBVNCSERVER_HAVE_XTEST
XTestDiscard(dpy);
#endif
}
Bool XETrapQueryExtension_wr(Display *dpy, int *ev, int *er, int *op) {
+ RAWFB_RET(False)
#if LIBVNCSERVER_HAVE_LIBXTRAP
return XETrapQueryExtension(dpy, (INT32 *)ev, (INT32 *)er,
(INT32 *)op);
#else
/* unused vars warning: */
- if (dpy || ev || er || op) {}
+ if (ev || er || op) {}
return False;
#endif
}
@@ -581,6 +760,7 @@ int XTestGrabControl_wr(Display *dpy, Bool impervious) {
if (! xtest_present) {
return 0;
}
+ RAWFB_RET(0)
#if LIBVNCSERVER_HAVE_XTEST && LIBVNCSERVER_HAVE_XTESTGRABCONTROL
XTestGrabControl(dpy, impervious);
return 1;
@@ -595,6 +775,7 @@ int XTRAP_GrabControl_wr(Display *dpy, Bool impervious) {
if (dpy || impervious) {}
return 0;
}
+ RAWFB_RET(0)
#if LIBVNCSERVER_HAVE_LIBXTRAP
else {
ReqFlags requests;
@@ -685,10 +866,11 @@ void disable_grabserver(Display *in_dpy, int change) {
rfbLog("* DEADLOCK if your window manager calls XGrabServer !!! *\n");
rfbLog("*********************************************************\n");
}
- XFlush(in_dpy);
+ XFlush_wr(in_dpy);
}
Bool XRecordQueryVersion_wr(Display *dpy, int *maj, int *min) {
+ RAWFB_RET(False)
#if LIBVNCSERVER_HAVE_RECORD
return XRecordQueryVersion(dpy, maj, min);
#else