Commit 279f3549 authored by runge's avatar runge

x11vnc: support for video4linux webcams & tv-tuners, -24to32 bpp option, -rawfb console.

parent 0d734ad8
2006-05-06 Karl Runge <runge@karlrunge.com>
* configure.ac: add linux/videodev.h and linux/fb.h detection.
2006-05-04 Steven Carr <scarr@jsa-usa.com>
* rfbEncodingSupportedEncodings - What encodings are supported?
* rfbEncodingSupportedMessages - What message types are supported?
......
......@@ -60,6 +60,8 @@ AH_TEMPLATE(HAVE_RECORD, [RECORD extension build environment present])
AH_TEMPLATE(HAVE_SOLARIS_XREADSCREEN, [Solaris XReadScreen available])
AH_TEMPLATE(HAVE_IRIX_XREADDISPLAY, [IRIX XReadDisplay available])
AH_TEMPLATE(HAVE_FBPM, [FBPM extension build environment present])
AH_TEMPLATE(HAVE_LINUX_VIDEODEV_H, [video4linux build environment present])
AH_TEMPLATE(HAVE_LINUX_FB_H, [linux fb device build environment present])
AC_ARG_WITH(xkeyboard,
[ --without-xkeyboard disable xkeyboard extension support],,)
......@@ -77,6 +79,10 @@ AC_ARG_WITH(xrecord,
[ --without-xrecord disable xrecord extension support],,)
AC_ARG_WITH(fbpm,
[ --without-fbpm disable fbpm extension support],,)
AC_ARG_WITH(v4l,
[ --without-v4l disable video4linux support],,)
AC_ARG_WITH(fbdev,
[ --without-fbdev disable linux fb device support],,)
if test "$X_CFLAGS" != "-DX_DISPLAY_MISSING"; then
AC_CHECK_LIB(X11, XGetImage, HAVE_X="true",
......@@ -223,6 +229,15 @@ if test "$X_CFLAGS" != "-DX_DISPLAY_MISSING"; then
fi
fi
if test "x$with_v4l" != "xno"; then
AC_CHECK_HEADER(linux/videodev.h,
[AC_DEFINE(HAVE_LINUX_VIDEODEV_H)],,)
fi
if test "x$with_fbdev" != "xno"; then
AC_CHECK_HEADER(linux/fb.h,
[AC_DEFINE(HAVE_LINUX_FB_H)],,)
fi
X_LIBS="$X_LIBS $X_PRELIBS -lX11 $X_EXTRA_LIBS"
fi
fi
......@@ -237,7 +252,8 @@ Make sure any required X development packages are installed. If they are
installed in non-standard locations, one can use the --x-includes=DIR
and --x-libraries=DIR configure options or set the CPPFLAGS and LDFLAGS
environment variables to indicate where the X window system header files
and libraries may be found.
and libraries may be found. On 64+32 bit machines you may need to point
to lib64 or lib32 directories to pick up the correct word size.
==========================================================================
])
fi
......
......@@ -70,6 +70,8 @@ static void set_root_cmap(void) {
static XColor color[NCOLOR];
int redo = 0;
RAWFB_RET_VOID
if (now > last_set + 10) {
redo = 1;
}
......@@ -134,6 +136,8 @@ static int check_pointer_in_depth24(void) {
c = window;
RAWFB_RET(0)
if (now > last_keyboard_time + 1.0 && now > last_pointer_time + 1.0) {
return 0;
}
......@@ -251,6 +255,8 @@ void check_for_multivis(void) {
double now = dnow();
double delay;
RAWFB_RET_VOID
if (now > last_parse + 1.0) {
last_parse = now;
parse_cmap8to24();
......@@ -743,6 +749,7 @@ if (db24 > 1) fprintf(stderr, " ------------ 0x%lx i=%d\n", windows_8bp
}
static XImage *p_xi(XImage *xi, Visual *visual, int win_depth, int *w) {
RAWFB_RET(NULL)
if (xi == NULL || *w < dpy_x) {
char *d;
if (xi) {
......@@ -782,6 +789,8 @@ static int poll_line(int x1, int x2, int y1, int n, sraRegionPtr mod) {
int mx1, mx2, my1, my2;
int ns = NSCAN/2;
RAWFB_RET(1)
if (win == None) {
return 1;
}
......@@ -1269,6 +1278,8 @@ static int get_cmap(int j, Colormap cmap) {
int i, ncells;
XErrorHandler old_handler = NULL;
RAWFB_RET(0)
if (0) {
/* not working properly for depth 24... */
X_LOCK;
......@@ -1401,7 +1412,7 @@ static XImage *cmap_xi(XImage *xi, Window win, int win_depth) {
if (xi) {
XDestroyImage(xi);
}
if (! valid_window(win, &attr, 1)) {
if (! dpy || ! valid_window(win, &attr, 1)) {
return (XImage *) NULL;
}
if (attr.depth != win_depth) {
......@@ -1434,6 +1445,8 @@ static void transform_rect(sraRect rect, Window win, int win_depth, int cm) {
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
/* now transform the pixels in this rectangle: */
n_off = main_bytes_per_line * rect.y1 + pixelsize * rect.x1;
......@@ -1653,6 +1666,8 @@ void bpp8to24(int x1, int y1, int x2, int y2) {
double now;
double dt, d0 = 0.0, t2;
RAWFB_RET_VOID
if (! cmap8to24 || ! cmap8to24_fb) {
/* hmmm, why were we called? */
return;
......@@ -1877,6 +1892,8 @@ void mark_8bpp(int mode) {
int i, cnt = 0;
Window top = None;
RAWFB_RET_VOID
if (! cmap8to24 || !cmap8to24_fb) {
return;
}
......
2006-05-06 Karl Runge <runge@karlrunge.com>
* x11vnc: improved support for webcams and tv tuners with
video4linux /dev/video: -rawfb video, -freqtab etc.
Convenience option for linux VT's: -rawfb cons (LinuxVNC
method). -pipeinput builtins for video and console.
-24to32 option to avoid 24bpp problems. "snap:" method for
-rawfb.
2006-04-26 Karl Runge <runge@karlrunge.com>
* x11vnc: skip exit in check_openssl() if not compiled with
libssl. set SKIP_HELP (again) in small footprint builds.
......
......@@ -13,7 +13,7 @@ endif
if HAVE_X
bin_PROGRAMS=x11vnc
x11vnc_SOURCES = 8to24.c cleanup.c connections.c cursor.c gui.c help.c inet.c keyboard.c options.c pm.c pointer.c rates.c remote.c scan.c screen.c selection.c solid.c sslcmds.c sslhelper.c unixpw.c user.c userinput.c util.c win_utils.c x11vnc.c x11vnc_defs.c xdamage.c xevents.c xinerama.c xkb_bell.c xrandr.c xrecord.c xwrappers.c 8to24.h allowed_input_t.h blackout_t.h cleanup.h connections.h cursor.h enums.h gui.h help.h inet.h keyboard.h options.h params.h pm.h pointer.h rates.h remote.h scan.h screen.h scrollevent_t.h selection.h solid.h sslcmds.h sslhelper.h ssltools.h tkx11vnc.h unixpw.h user.h userinput.h util.h win_utils.h winattr_t.h x11vnc.h xdamage.h xevents.h xinerama.h xkb_bell.h xrandr.h xrecord.h xwrappers.h
x11vnc_SOURCES = 8to24.c cleanup.c connections.c cursor.c gui.c help.c inet.c keyboard.c linuxfb.c options.c pm.c pointer.c rates.c remote.c scan.c screen.c selection.c solid.c sslcmds.c sslhelper.c unixpw.c user.c userinput.c util.c v4l.c win_utils.c x11vnc.c x11vnc_defs.c xdamage.c xevents.c xinerama.c xkb_bell.c xrandr.c xrecord.c xwrappers.c 8to24.h allowed_input_t.h blackout_t.h cleanup.h connections.h cursor.h enums.h gui.h help.h inet.h keyboard.h linuxfb.h options.h params.h pm.h pointer.h rates.h remote.h scan.h screen.h scrollevent_t.h selection.h solid.h sslcmds.h sslhelper.h ssltools.h tkx11vnc.h unixpw.h user.h userinput.h util.h v4l.h win_utils.h winattr_t.h x11vnc.h xdamage.h xevents.h xinerama.h xkb_bell.h xrandr.h xrecord.h xwrappers.h
INCLUDES=@X_CFLAGS@
x11vnc_LDADD=$(LDADD) @X_LIBS@ $(LD_CYGIPC)
endif
......
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -13,6 +13,7 @@
#include "scan.h"
#include "sslcmds.h"
#include "sslhelper.h"
#include "xwrappers.h"
/*
* routines for handling incoming, outgoing, etc connections
......@@ -864,7 +865,7 @@ static unsigned char t2x2_bits[] = {
KeyCode key_o;
if (raw_fb && ! dpy) return 0; /* raw_fb hack */
RAWFB_RET(0)
if (! accept) {
sprintf(str_y, "OK");
......@@ -951,7 +952,7 @@ static unsigned char t2x2_bits[] = {
XSetDashes(dpy, gc, 0, dash_list, list_length);
XMapWindow(dpy, awin);
XFlush(dpy);
XFlush_wr(dpy);
if (accept) {
snprintf(strh, 100, "x11vnc: accept connection from %s?", addr);
......@@ -1107,7 +1108,7 @@ static unsigned char t2x2_bits[] = {
XUnmapWindow(dpy, awin);
XFreeGC(dpy, gc);
XDestroyWindow(dpy, awin);
XFlush(dpy);
XFlush_wr(dpy);
break;
}
}
......@@ -1438,7 +1439,12 @@ static void check_connect_file(char *file) {
} else {
rfbLog("read connect file: %s\n", str);
}
client_connect = str;
if (!strcmp(str, "cmd=stop") &&
dnow() - x11vnc_start < 3.0) {
rfbLog("ignoring stale cmd=stop\n");
} else {
client_connect = str;
}
}
}
}
......@@ -1586,11 +1592,13 @@ void reverse_connect(char *str) {
* for changes. The vncconnect(1) will set it on our X display.
*/
void set_vnc_connect_prop(char *str) {
RAWFB_RET_VOID
XChangeProperty(dpy, rootwin, vnc_connect_prop, XA_STRING, 8,
PropModeReplace, (unsigned char *)str, strlen(str));
}
void set_x11vnc_remote_prop(char *str) {
RAWFB_RET_VOID
XChangeProperty(dpy, rootwin, x11vnc_remote_prop, XA_STRING, 8,
PropModeReplace, (unsigned char *)str, strlen(str));
}
......@@ -1609,6 +1617,7 @@ void read_vnc_connect_prop(int nomsg) {
/* not active or problem with VNC_CONNECT atom */
return;
}
RAWFB_RET_VOID
/* read the property value into vnc_connect_str: */
do {
......@@ -1654,6 +1663,7 @@ void read_x11vnc_remote_prop(int nomsg) {
/* not active or problem with X11VNC_REMOTE atom */
return;
}
RAWFB_RET_VOID
/* read the property value into x11vnc_remote_str: */
do {
......
......@@ -824,6 +824,8 @@ static void tree_descend_cursor(int *depth, Window *w, win_str_info_t *winfo) {
int nm_info = 1;
XErrorHandler old_handler;
RAWFB_RET_VOID
X_LOCK;
if (!strcmp(s, "default") || !strcmp(s, "X") || !strcmp(s, "arrow")) {
......@@ -1208,7 +1210,7 @@ static int get_xfixes_cursor(int init) {
return -1;
}
if (xfixes_present) {
if (xfixes_present && dpy) {
#if LIBVNCSERVER_HAVE_LIBXFIXES
int use, oldest, i;
time_t oldtime, now;
......@@ -1388,6 +1390,7 @@ void initialize_cursors_mode(void) {
int get_which_cursor(void) {
int which = CURS_ARROW;
int db = 0;
if (show_multiple_cursors) {
int depth;
......@@ -1416,6 +1419,7 @@ int get_which_cursor(void) {
}
if (mode == 3 && xfixes_present && use_xfixes) {
if (db) fprintf(stderr, "get_which_cursor call get_xfixes_cursor\n");
return get_xfixes_cursor(0);
}
......@@ -1444,7 +1448,7 @@ int get_which_cursor(void) {
int which0 = which;
/* apply crude heuristics to choose a cursor... */
if (win) {
if (win && dpy) {
int ratio = 10, x, y;
unsigned int w, h, bw, d;
Window r;
......@@ -1495,6 +1499,7 @@ int get_which_cursor(void) {
}
}
}
if (db) fprintf(stderr, "get_which_cursor which: %d\n", which);
return which;
}
......@@ -1768,7 +1773,7 @@ int check_x11_pointer(void) {
int x, y;
unsigned int mask;
if (raw_fb && ! dpy) return 0; /* raw_fb hack */
RAWFB_RET(0)
if (unixpw_in_progress) return 0;
......
......@@ -70,6 +70,8 @@ int tray_embed(Window iconwin, int remove) {
long info[2] = {XEMBED_VERSION, XEMBED_MAPPED};
long data = 0;
RAWFB_RET(0)
if (remove) {
if (!valid_window(iconwin, &attr, 1)) {
return 0;
......@@ -156,6 +158,8 @@ static int tray_manager_running(Display *d, Window *manager) {
Atom tray_manager;
Window tray_win;
RAWFB_RET(0)
if (manager) {
*manager = None;
}
......
This diff is collapsed.
......@@ -11,6 +11,8 @@
#include "cleanup.h"
#include "allowed_input_t.h"
#include "unixpw.h"
#include "v4l.h"
#include "linuxfb.h"
void get_keystate(int *keystate);
void clear_modifiers(int init);
......@@ -54,6 +56,8 @@ static void pipe_keyboard(rfbBool down, rfbKeySym keysym, rfbClientPtr client);
void get_keystate(int *keystate) {
int i, k;
char keys[32];
RAWFB_RET_VOID
/* n.b. caller decides to X_LOCK or not. */
XQueryKeymap(dpy, keys);
......@@ -85,6 +89,8 @@ void clear_modifiers(int init) {
KeySym keysym;
KeyCode keycode;
RAWFB_RET_VOID
/* n.b. caller decides to X_LOCK or not. */
if (first) {
/*
......@@ -134,7 +140,7 @@ void clear_modifiers(int init) {
}
XTestFakeKeyEvent_wr(dpy, keycode, False, CurrentTime);
}
XFlush(dpy);
XFlush_wr(dpy);
}
static KeySym simple_mods[] = {
......@@ -211,6 +217,8 @@ int track_mod_state(rfbKeySym keysym, rfbBool down, rfbBool set) {
*/
void clear_keys(void) {
int k, keystate[256];
RAWFB_RET_VOID
/* n.b. caller decides to X_LOCK or not. */
get_keystate(keystate);
......@@ -221,7 +229,7 @@ void clear_keys(void) {
XTestFakeKeyEvent_wr(dpy, keycode, False, CurrentTime);
}
}
XFlush(dpy);
XFlush_wr(dpy);
}
/*
......@@ -238,6 +246,9 @@ static int save_auto_repeat = -1;
int get_autorepeat_state(void) {
XKeyboardState kstate;
RAWFB_RET(0)
X_LOCK;
XGetKeyboardControl(dpy, &kstate);
X_UNLOCK;
......@@ -255,7 +266,7 @@ void autorepeat(int restore, int bequiet) {
int global_auto_repeat;
XKeyboardControl kctrl;
if (raw_fb && ! dpy) return; /* raw_fb hack */
RAWFB_RET_VOID
if (restore) {
if (save_auto_repeat < 0) {
......@@ -271,7 +282,7 @@ void autorepeat(int restore, int bequiet) {
kctrl.auto_repeat_mode = save_auto_repeat;
XChangeKeyboardControl(dpy, KBAutoRepeatMode, &kctrl);
XFlush(dpy);
XFlush_wr(dpy);
X_UNLOCK;
if (! bequiet && ! quiet) {
......@@ -291,7 +302,7 @@ void autorepeat(int restore, int bequiet) {
X_LOCK;
kctrl.auto_repeat_mode = AutoRepeatModeOff;
XChangeKeyboardControl(dpy, KBAutoRepeatMode, &kctrl);
XFlush(dpy);
XFlush_wr(dpy);
X_UNLOCK;
if (! bequiet && ! quiet) {
......@@ -352,7 +363,7 @@ int add_keysym(KeySym keysym) {
first = 0;
}
if (raw_fb && ! dpy) return 0; /* raw_fb hack */
RAWFB_RET(0)
if (keysym == NoSymbol) {
return 0;
......@@ -419,7 +430,7 @@ int add_keysym(KeySym keysym) {
}
}
XFlush(dpy);
XFlush_wr(dpy);
added_keysyms[kc] = keysym;
ret = kc;
break;
......@@ -434,7 +445,7 @@ static void delete_keycode(KeyCode kc, int bequiet) {
KeySym ksym, new[8];
char *str;
if (raw_fb && ! dpy) return; /* raw_fb hack */
RAWFB_RET_VOID
XDisplayKeycodes(dpy, &minkey, &maxkey);
keymap = XGetKeyboardMapping(dpy, minkey, (maxkey - minkey + 1),
......@@ -454,7 +465,7 @@ static void delete_keycode(KeyCode kc, int bequiet) {
}
XFree(keymap);
XFlush(dpy);
XFlush_wr(dpy);
}
static int count_added_keycodes(void) {
......@@ -599,7 +610,7 @@ static void add_dead_keysyms(char *str) {
inmap = 1;
}
#if LIBVNCSERVER_HAVE_XKEYBOARD
if (! inmap && xkb_present) {
if (! inmap && xkb_present && dpy) {
int kc, grp, lvl;
for (kc = 0; kc < 0x100; kc++) {
for (grp = 0; grp < 4; grp++) {
......@@ -753,6 +764,8 @@ int sloppy_key_check(int key, rfbBool down, rfbKeySym keysym, int *new) {
if (!sloppy_keys) {
return 0;
}
RAWFB_RET(0)
if (!down && !keycode_state[key] && !IsModifierKey(keysym)) {
int i, cnt = 0, downkey = -1;
......@@ -863,6 +876,7 @@ void switch_to_xkb_if_better(void) {
/* already using it */
return;
}
RAWFB_RET_VOID
XDisplayKeycodes(dpy, &minkey, &maxkey);
......@@ -1110,6 +1124,8 @@ xkbmodifiers[] For the KeySym bound to this (keycode,group,level) store
*
*/
RAWFB_RET_VOID
/* initialize all the arrays: */
for (kc = 0; kc < 0x100; kc++) {
multi_key[kc] = 0;
......@@ -1414,6 +1430,8 @@ static void xkb_tweak_keyboard(rfbBool down, rfbKeySym keysym,
if (client) {} /* unused vars warning: */
RAWFB_RET_VOID
X_LOCK;
if (debug_keyboard) {
......@@ -2144,6 +2162,8 @@ void initialize_modtweak(void) {
keycodes[i] = NoSymbol;
}
RAWFB_RET_VOID
X_LOCK;
XDisplayKeycodes(dpy, &minkey, &maxkey);
......@@ -2230,6 +2250,8 @@ static void tweak_mod(signed char mod, rfbBool down) {
Bool dn = (Bool) down;
KeyCode altgr = altgr_code;
RAWFB_RET_VOID
if (mod < 0) {
if (debug_keyboard) {
rfbLog("tweak_mod: Skip: down=%d index=%d\n", down,
......@@ -2281,6 +2303,8 @@ static void modifier_tweak_keyboard(rfbBool down, rfbKeySym keysym,
KeyCode k;
int tweak = 0;
RAWFB_RET_VOID
if (use_xkb_modtweak) {
xkb_tweak_keyboard(down, keysym, client);
return;
......@@ -2344,7 +2368,7 @@ static void modifier_tweak_keyboard(rfbBool down, rfbKeySym keysym,
void initialize_keyboard_and_pointer(void) {
if (raw_fb && ! dpy) return; /* raw_fb hack */
RAWFB_RET_VOID
if (use_modifier_tweak) {
initialize_modtweak();
......@@ -2417,6 +2441,12 @@ static void pipe_keyboard(rfbBool down, rfbKeySym keysym, rfbClientPtr client) {
char *name;
ClientData *cd = (ClientData *) client->clientData;
if (pipeinput_int == PIPEINPUT_VID) {
v4l_key_command(down, keysym, client);
}
if (pipeinput_int == PIPEINPUT_CONS) {
console_key_command(down, keysym, client);
}
if (pipeinput_fh == NULL) {
return;
}
......@@ -2698,7 +2728,7 @@ void keyboard(rfbBool down, rfbKeySym keysym, rfbClientPtr client) {
skipped_last_down = 0;
last_rfb_key_accepted = TRUE;
if (pipeinput_fh != NULL) {
if (pipeinput_fh != NULL || pipeinput_int) {
pipe_keyboard(down, keysym, client);
if (! pipeinput_tee) {
if (! view_only || raw_fb) { /* raw_fb hack */
......@@ -2742,7 +2772,7 @@ void keyboard(rfbBool down, rfbKeySym keysym, rfbClientPtr client) {
got_user_input++;
got_keyboard_input++;
if (raw_fb && ! dpy) return; /* raw_fb hack */
RAWFB_RET_VOID
if (keyremaps) {
keyremap_t *remap = keyremaps;
......@@ -2810,7 +2840,7 @@ void keyboard(rfbBool down, rfbKeySym keysym, rfbClientPtr client) {
do_button_mask_change(mask, button); /* down */
mask = 0;
do_button_mask_change(mask, button); /* up */
XFlush(dpy);
XFlush_wr(dpy);
X_UNLOCK;
return;
}
......@@ -2818,7 +2848,7 @@ void keyboard(rfbBool down, rfbKeySym keysym, rfbClientPtr client) {
if (use_modifier_tweak) {
modifier_tweak_keyboard(down, keysym, client);
X_LOCK;
XFlush(dpy);
XFlush_wr(dpy);
X_UNLOCK;
return;
}
......@@ -2842,7 +2872,7 @@ void keyboard(rfbBool down, rfbKeySym keysym, rfbClientPtr client) {
if ( k != NoSymbol ) {
XTestFakeKeyEvent_wr(dpy, k, (Bool) down, CurrentTime);
XFlush(dpy);
XFlush_wr(dpy);
}
X_UNLOCK;
......
/* -- linuxfb.c -- */
#include "x11vnc.h"
#include "cleanup.h"
#include "scan.h"
#include "xinerama.h"
#include "screen.h"
#include "pointer.h"
#if LIBVNCSERVER_HAVE_SYS_IOCTL_H
#include <sys/ioctl.h>
#endif
#if LIBVNCSERVER_HAVE_LINUX_FB_H
#include <linux/fb.h>
#endif
char *console_guess(char *str, int *fd);
void console_key_command(rfbBool down, rfbKeySym keysym, rfbClientPtr client);
void console_pointer_command(int mask, int x, int y, rfbClientPtr client);
char *console_guess(char *str, int *fd) {
char *q, *in = strdup(str);
char *atparms = NULL, *file = NULL;
int tty = -1;
if (strstr(in, "/dev/fb") == in) {
free(in);
in = (char *) malloc(strlen("cons:") + strlen(str) + 1);
sprintf(in, "cons:%s", str);
} else if (strstr(in, "fb") == in) {
free(in);
in = (char *) malloc(strlen("cons:/dev/") + strlen(str) + 1);
sprintf(in, "cons:/dev/%s", str);
}
if (strstr(in, "cons") != in) {
rfbLog("console_guess: unrecognized console/fb format: %s\n", str);
free(in);
return NULL;
}
q = strrchr(in, '@');
if (q) {
atparms = strdup(q+1);
*q = '\0';
}
q = strrchr(in, ':');
if (q) {
file = strdup(q+1);
*q = '\0';
}
if (! file || file[0] == '\0') {
file = strdup("/dev/fb");
}
if (strstr(file, "fb") == file) {
q = (char *) malloc(strlen("/dev/") + strlen(file) + 1);
sprintf(q, "/dev/%s", file);
free(file);
file = q;
}
if (!strcmp(file, "/dev/fb")) {
/* sometimes no sylink fb -> fb0 */
struct stat sbuf;
if (stat(file, &sbuf) != 0) {
free(file);
file = strdup("/dev/fb0");
}
}
rfbLog("console_guess: file is %s\n", file);
if (!strcmp(in, "cons") || !strcmp(in, "console")) {
/* current active VT: */
tty = 0;
} else {
int n;
if (sscanf(in, "cons%d", &n) == 1) {
tty = n;
} else if (sscanf(in, "console%d", &n) != 1) {
tty = n;
}
}
if (tty >=0 && tty < 64) {
if (pipeinput_str == NULL) {
pipeinput_str = (char *) malloc(10);
sprintf(pipeinput_str, "CONS%d", tty);
rfbLog("console_guess: file pipeinput %s\n", pipeinput_str);
initialize_pipeinput();
}
}
if (! atparms) {
#if LIBVNCSERVER_HAVE_LINUX_FB_H
#if LIBVNCSERVER_HAVE_SYS_IOCTL_H
struct fb_var_screeninfo var_info;
int d = open(file, O_RDWR);
if (d >= 0) {
int w, h, b;
unsigned long rm = 0, gm = 0, bm = 0;
if (ioctl(d, FBIOGET_VSCREENINFO, &var_info) != -1) {
w = (int) var_info.xres;
h = (int) var_info.yres;
b = (int) var_info.bits_per_pixel;
rm = (1 << var_info.red.length) - 1;
gm = (1 << var_info.green.length) - 1;
bm = (1 << var_info.blue.length) - 1;
rm = rm << var_info.red.offset;
gm = gm << var_info.green.offset;
bm = bm << var_info.blue.offset;
if (b == 8 && rm == 0xff && gm == 0xff && bm == 0xff) {
/* I don't believe it... */
rm = 0x07;
gm = 0x38;
bm = 0xc0;
}
/* @66666x66666x32:0xffffffff:... */
atparms = (char *) malloc(200);
sprintf(atparms, "%dx%dx%d:%lx/%lx/%lx",
w, h, b, rm, gm, bm);
*fd = d;
} else {
perror("ioctl");
close(d);
}
} else {
rfbLog("could not open: %s\n", file);
perror("open");
close(d);
}
#endif
#endif
}
if (! atparms) {
rfbLog("console_guess: could not get @ parameters.\n");
return NULL;
}
q = (char *) malloc(strlen("map:") + strlen(file) + 1 + strlen(atparms) + 1);
sprintf(q, "map:%s@%s", file, atparms);
return q;
}
void console_key_command(rfbBool down, rfbKeySym keysym, rfbClientPtr client) {
static int control = 0;
if (debug_keyboard) fprintf(stderr, "console_key_command: %d %s\n", (int) keysym, down ? "down" : "up");
if (pipeinput_cons_fd < 0) {
return;
}
/* From LinuxVNC.c: */
if (keysym == XK_Control_L || keysym == XK_Control_R) {
if (! down) {
if (control > 0) {
control--;
}
} else {
control++;
}
return;
}
if (!down) {
return;
}
if (keysym == XK_Escape) {
keysym = 27;
}
if (control) {
if (keysym >= 'a' && keysym <= 'z') {
keysym -= ('a' - 1);
} else if (keysym >= 'A' && keysym <= 'Z') {
keysym -= ('A' - 1);
} else {
keysym = 0xffff;
}
}
if (keysym == XK_Tab) {
keysym = '\t';
} else if (keysym == XK_Return) {
keysym = '\r';
} else if (keysym == XK_BackSpace) {
keysym = 8;
} else if (keysym == XK_Home || keysym == XK_KP_Home) {
keysym = 1;
} else if (keysym == XK_End || keysym == XK_KP_End) {
keysym = 5;
} else if (keysym == XK_Up || keysym == XK_KP_Up) {
keysym = 16;
} else if (keysym == XK_Down || keysym == XK_KP_Down) {
keysym = 14;
} else if (keysym == XK_Right || keysym == XK_KP_Right) {
keysym = 6;
} else if (keysym == XK_Next || keysym == XK_KP_Next) {
keysym = 6;
} else if (keysym == XK_Left || keysym == XK_KP_Left) {
keysym = 2;
} else if (keysym == XK_Prior || keysym == XK_KP_Prior) {
keysym = 2;
}
#if LIBVNCSERVER_HAVE_SYS_IOCTL_H && defined(TIOCSTI)
if (keysym < 0x100) {
if (ioctl(pipeinput_cons_fd, TIOCSTI, &keysym) != -1) {
return;
}
perror("ioctl");
close(pipeinput_cons_fd);
pipeinput_cons_fd = -1;
if (! pipeinput_cons_dev) {
return;
}
pipeinput_cons_fd = open(pipeinput_cons_dev, O_WRONLY);
if (pipeinput_cons_fd < 0) {
rfbLog("pipeinput: could not reopen %s\n",
pipeinput_cons_dev);
perror("open");
return;
}
if (ioctl(pipeinput_cons_fd, TIOCSTI, &keysym) == -1) {
perror("ioctl");
close(pipeinput_cons_fd);
pipeinput_cons_fd = -1;
rfbLog("pipeinput: could not reopen %s\n",
pipeinput_cons_dev);
}
}
#endif
if (client) {}
}
void console_pointer_command(int mask, int x, int y, rfbClientPtr client) {
if (mask || x || y || client) {}
}
#ifndef _X11VNC_LINUXFB_H
#define _X11VNC_LINUXFB_H
/* -- linuxfb.h -- */
extern char *console_guess(char *str, int *fd);
extern void console_key_command(rfbBool down, rfbKeySym keysym, rfbClientPtr client);
extern void console_pointer_command(int mask, int x, int y, rfbClientPtr client);
#endif /* _X11VNC_LINUXFB_H */
......@@ -11,6 +11,7 @@ int debug = 0;
char *use_dpy = NULL; /* -display */
char *auth_file = NULL; /* -auth/-xauth */
char *visual_str = NULL; /* -visual */
int set_visual_str_to_something = 0;
char *logfile = NULL; /* -o, -logfile */
int logfile_append = 0;
char *flagfile = NULL; /* -flag */
......@@ -102,6 +103,7 @@ int flash_cmap = 0; /* follow installed colormaps */
int shift_cmap = 0; /* ncells < 256 and needs shift of pixel values */
int force_indexed_color = 0; /* whether to force indexed color for 8bpp */
int cmap8to24 = 0; /* -8to24 */
int xform24to32 = 0; /* -24to32 */
char *cmap8to24_str = NULL;
int launch_gui = 0; /* -gui */
......@@ -110,10 +112,15 @@ int use_iso_level3 = 0; /* ISO_Level3_Shift instead of Mode_switch */
int clear_mods = 0; /* -clear_mods (1) and -clear_keys (2) */
int nofb = 0; /* do not send any fb updates */
char *raw_fb_str = NULL; /* used under -rawfb */
char *raw_fb_pixfmt = NULL;
char *freqtab = NULL;
char *pipeinput_str = NULL; /* -pipeinput [tee,reopen,keycodes:]cmd */
char *pipeinput_opts = NULL;
FILE *pipeinput_fh = NULL;
int pipeinput_tee = 0;
int pipeinput_int = 0;
int pipeinput_cons_fd = -1;
char *pipeinput_cons_dev = NULL;
unsigned long subwin = 0x0; /* -id, -sid */
int subwin_wait_mapped = 0;
......
......@@ -11,6 +11,7 @@ extern int debug;
extern char *use_dpy;
extern char *auth_file;
extern char *visual_str;
extern int set_visual_str_to_something;
extern char *logfile;
extern int logfile_append;
extern char *flagfile;
......@@ -78,6 +79,7 @@ extern int shift_cmap;
extern int force_indexed_color;
extern int cmap8to24;
extern char *cmap8to24_str;
extern int xform24to32;
extern int launch_gui;
extern int use_modifier_tweak;
......@@ -85,10 +87,15 @@ extern int use_iso_level3;
extern int clear_mods;
extern int nofb;
extern char *raw_fb_str;
extern char *raw_fb_pixfmt;
extern char *freqtab;
extern char *pipeinput_str;
extern char *pipeinput_opts;
extern FILE *pipeinput_fh;
extern int pipeinput_tee;
extern int pipeinput_int;
extern int pipeinput_cons_fd;
extern char *pipeinput_cons_dev;
extern unsigned long subwin;
extern int subwin_wait_mapped;
......
......@@ -35,4 +35,8 @@
#define MAXN 256
#define PIPEINPUT_NONE 0x0
#define PIPEINPUT_VID 0x1
#define PIPEINPUT_CONS 0x2
#endif /* _X11VNC_PARAMS_H */
......@@ -25,7 +25,7 @@ static void check_fbpm(void) {
CARD16 level;
BOOL enabled;
if (raw_fb && ! dpy) return; /* raw_fb hack */
RAWFB_RET_VOID
if (! init_fbpm) {
if (FBPMCapable(dpy)) {
......@@ -83,7 +83,7 @@ static void check_fbpm(void) {
if (db) fprintf(stderr, "FBPMInfo failed.\n");
}
#else
if (raw_fb && ! dpy) return; /* raw_fb hack */
RAWFB_RET_VOID
if (! init_fbpm) {
rfbLog("X FBPM extension not supported.\n");
init_fbpm = 1;
......
......@@ -11,6 +11,8 @@
#include "connections.h"
#include "cleanup.h"
#include "unixpw.h"
#include "v4l.h"
#include "linuxfb.h"
int pointer_queued_sent = 0;
......@@ -26,7 +28,6 @@ static void update_x11_pointer_position(int x, int y);
static void update_x11_pointer_mask(int mask);
static void pipe_pointer(int mask, int x, int y, rfbClientPtr client);
/*
* pointer event (motion and button click) handling routines.
*/
......@@ -116,7 +117,7 @@ static void buttonparse(int from, char **s) {
"keysym: %s\n", t);
n--;
}
} else {
} else if (dpy) {
/*
* XXX may not work with -modtweak or -xkb
*/
......@@ -214,9 +215,13 @@ void initialize_pointer_map(char *pointer_remap) {
* from -buttonmap option.
*/
X_LOCK;
num_buttons = XGetPointerMapping(dpy, map, MAX_BUTTONS);
X_UNLOCK;
if (!raw_fb_str) {
X_LOCK;
num_buttons = XGetPointerMapping(dpy, map, MAX_BUTTONS);
X_UNLOCK;
} else {
num_buttons = 5;
}
if (num_buttons < 0) {
num_buttons = 0;
......@@ -284,7 +289,7 @@ void initialize_pointer_map(char *pointer_remap) {
static void update_x11_pointer_position(int x, int y) {
int rc;
if (raw_fb && ! dpy) return; /* raw_fb hack */
RAWFB_RET_VOID
X_LOCK;
if (use_xwarppointer) {
......@@ -358,7 +363,7 @@ void do_button_mask_change(int mask, int button) {
/* do not send keysym on button up */
continue;
}
if (debug_pointer) {
if (debug_pointer && dpy) {
rfbLog("pointer(): sending button %d "
"down as keycode 0x%x (event %d)\n",
i+1, key, k+1);
......@@ -387,7 +392,7 @@ static void update_x11_pointer_mask(int mask) {
last_event = last_input = last_pointer_input = time(0);
if (raw_fb && ! dpy) return; /* raw_fb hack */
RAWFB_RET_VOID
if (mask != button_mask) {
last_pointer_click_time = dnow();
......@@ -513,6 +518,12 @@ static void pipe_pointer(int mask, int x, int y, rfbClientPtr client) {
ClientData *cd = (ClientData *) client->clientData;
char hint[MAX_BUTTONS * 20];
if (pipeinput_int == PIPEINPUT_VID) {
v4l_pointer_command(mask, x, y, client);
}
if (pipeinput_int == PIPEINPUT_CONS) {
console_pointer_command(mask, x, y, client);
}
if (pipeinput_fh == NULL) {
return;
}
......@@ -795,7 +806,7 @@ void pointer(int mask, int x, int y, rfbClientPtr client) {
"%.4f\n", dnow() - x11vnc_start);
}
X_LOCK;
XFlush(dpy);
XFlush_wr(dpy);
X_UNLOCK;
}
}
......@@ -828,13 +839,15 @@ void pointer(int mask, int x, int y, rfbClientPtr client) {
sent = 1;
}
if (nofb && sent) {
if (! dpy) {
;
} else if (nofb && sent) {
/*
* nofb is for, e.g. Win2VNC, where fastest pointer
* updates are desired.
*/
X_LOCK;
XFlush(dpy);
XFlush_wr(dpy);
X_UNLOCK;
} else if (buffer_it) {
if (debug_pointer) {
......@@ -842,7 +855,7 @@ void pointer(int mask, int x, int y, rfbClientPtr client) {
"%.4f\n", dnow() - x11vnc_start);
}
X_LOCK;
XFlush(dpy);
XFlush_wr(dpy);
X_UNLOCK;
}
}
......@@ -899,6 +912,33 @@ void initialize_pipeinput(void) {
} else {
p = pipeinput_str;
}
if (0) fprintf(stderr, "initialize_pipeinput: %s -- %s\n", pipeinput_str, p);
if (!strcmp(p, "VID")) {
pipeinput_int = PIPEINPUT_VID;
return;
}
if (strstr(p, "CONS") == p) {
int tty = 0, n;
char dev[32];
if (sscanf(p, "CONS%d", &n) == 1) {
tty = n;
}
sprintf(dev, "/dev/tty%d", tty);
pipeinput_cons_fd = open(dev, O_WRONLY);
if (pipeinput_cons_fd >= 0) {
rfbLog("pipeinput: using linux console: %s\n", dev);
if (pipeinput_cons_dev) {
free(pipeinput_cons_dev);
}
pipeinput_cons_dev = strdup(dev);
pipeinput_int = PIPEINPUT_CONS;
} else {
rfbLog("pipeinput: could not open: %s\n", dev);
rfbLogPerror("open");
}
return;
}
set_child_info();
if (no_external_cmds) {
......
......@@ -209,9 +209,7 @@ void initialize_speeds(void) {
int n = 0;
double dt, timer;
dtime0(&timer);
if (0 && raw_fb && ! dpy) { /* raw_fb hack */
n = 0;
} else if (fullscreen) {
if (fullscreen) {
copy_image(fullscreen, 0, 0, 0, 0);
n = fullscreen->bytes_per_line * fullscreen->height;
} else if (scanline) {
......
......@@ -74,7 +74,9 @@ int send_remote_cmd(char *cmd, int query, int wait) {
fprintf(stderr, ">>> sending remote command: \"%s\" via"
" X11VNC_REMOTE X property.\n", cmd);
set_x11vnc_remote_prop(cmd);
XFlush(dpy);
if (dpy) {
XFlush_wr(dpy);
}
}
if (query || wait) {
......@@ -724,9 +726,16 @@ char *process_remote_cmd(char *cmd, int stringonly) {
if (!strcmp(p, "stop") || !strcmp(p, "quit") ||
!strcmp(p, "exit") || !strcmp(p, "shutdown")) {
NOTAPP
close_all_clients();
if (client_connect_file) {
FILE *in = fopen(client_connect_file, "w");
if (in) {
fprintf(in, "cmd=noop\n");
fclose(in);
}
}
rfbLog("remote_cmd: setting shut_down flag\n");
shut_down = 1;
close_all_clients();
} else if (!strcmp(p, "ping")) {
query = 1;
......@@ -1063,6 +1072,34 @@ char *process_remote_cmd(char *cmd, int stringonly) {
rfbLog("remote_cmd: set cmap8to24_str to: %s\n", cmap8to24_str);
do_new_fb(0);
} else if (!strcmp(p, "24to32")) {
if (query) {
snprintf(buf, bufn, "ans=%s:%d", p, xform24to32);
goto qry;
}
rfbLog("remote_cmd: turning on -24to32 mode.\n");
xform24to32 = 1;
do_new_fb(1);
} else if (!strcmp(p, "no24to32")) {
if (query) {
snprintf(buf, bufn, "ans=%s:%d", p, !xform24to32);
goto qry;
}
rfbLog("remote_cmd: turning off -24to32 mode.\n");
if (set_visual_str_to_something) {
if (visual_str) {
rfbLog("unsetting: %d %d/%d\n", visual_str,
(int) visual_id, visual_depth);
free(visual_str);
}
visual_str = NULL;
visual_id = (VisualID) 0;
visual_depth = 0;
}
xform24to32 = 0;
do_new_fb(1);
} else if (strstr(p, "visual") == p) {
COLON_CHECK("visual:")
if (query) {
......@@ -1579,7 +1616,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
rfbLog("remote_cmd: turning on flipbyteorder mode.\n");
flip_byte_order = 1;
if (orig != flip_byte_order) {
if (! using_shm) {
if (! using_shm || xform24to32) {
do_new_fb(1);
} else {
rfbLog(" using shm, not resetting fb\n");
......@@ -1594,7 +1631,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
rfbLog("remote_cmd: turning off flipbyteorder mode.\n");
flip_byte_order = 0;
if (orig != flip_byte_order) {
if (! using_shm) {
if (! using_shm || xform24to32) {
do_new_fb(1);
} else {
rfbLog(" using shm, not resetting fb\n");
......@@ -3282,6 +3319,19 @@ char *process_remote_cmd(char *cmd, int stringonly) {
if (*raw_fb_str == '\0') {
free(raw_fb_str);
raw_fb_str = NULL;
if (raw_fb_mmap) {
munmap(raw_fb_addr, raw_fb_mmap);
}
if (raw_fb_fd >= 0) {
close(raw_fb_fd);
}
raw_fb_fd = -1;
raw_fb = NULL;
raw_fb_addr = NULL;
raw_fb_offset = 0;
raw_fb_shm = 0;
raw_fb_mmap = 0;
raw_fb_seek = 0;
rfbLog("restoring per-rawfb settings...\n");
set_raw_fb_params(1);
}
......@@ -3976,7 +4026,7 @@ char *process_remote_cmd(char *cmd, int stringonly) {
} else {
if (dpy) { /* raw_fb hack */
set_x11vnc_remote_prop(buf);
XFlush(dpy);
XFlush_wr(dpy);
}
}
#endif
......
......@@ -11,6 +11,7 @@
#include "pointer.h"
#include "cleanup.h"
#include "unixpw.h"
#include "screen.h"
/*
* routines for scanning and reading the X11 display for changes, and
......@@ -223,7 +224,7 @@ static int shm_create(XShmSegmentInfo *shm, XImage **ximg_ptr, int w, int h,
X_LOCK;
if (! using_shm) {
if (! using_shm || xform24to32 || raw_fb) {
/* we only need the XImage created */
xim = XCreateImage_wr(dpy, default_visual, depth, ZPixmap,
0, NULL, w, h, raw_fb ? 32 : BitmapPad(dpy), 0);
......@@ -260,6 +261,11 @@ static int shm_create(XShmSegmentInfo *shm, XImage **ximg_ptr, int w, int h,
return 1;
}
if (! dpy) {
X_UNLOCK;
return 0;
}
xim = XShmCreateImage_wr(dpy, default_visual, depth, ZPixmap, NULL,
shm, w, h);
......@@ -347,7 +353,20 @@ void shm_clean(XShmSegmentInfo *shm, XImage *xim) {
}
#endif
if (xim != NULL) {
XDestroyImage(xim);
#if 0
/*
* This would be needed if you want to crazily switch
* back and forth between rawfb and X. You will also
* need to supply -noviewonly. xim->f is public ABI,
* but we choose not to use it. One could also
* clean up the switch.
*/
if (xim->f.destroy_image) {
#else
{
#endif
XDestroyImage(xim);
}
xim = NULL;
}
X_UNLOCK;
......@@ -444,7 +463,7 @@ void initialize_polling_images(void) {
}
}
if (!quiet) {
if (using_shm) {
if (using_shm && ! xform24to32) {
rfbLog("created %d tile_row shm polling images.\n",
tile_shm_count);
} else {
......@@ -1959,6 +1978,7 @@ int copy_screen(void) {
if (! main_fb) {
return 0;
}
fbp = main_fb;
y = 0;
......@@ -1986,13 +2006,106 @@ int copy_screen(void) {
return 0;
}
int copy_snap(void) {
static void snap_all_rawfb(void) {
int pixelsize = bpp/8;
int n, sz;
char *dst;
static char *unclipped_dst = NULL;
static int unclipped_len = 0;
dst = snap->data;
if (xform24to32 && bpp == 32) {
pixelsize = 3;
}
sz = dpy_x * dpy_y * pixelsize;
if (wdpy_x > dpy_x || wdpy_y > dpy_y) {
sz = wdpy_x * wdpy_y * pixelsize;
if (sz > unclipped_len || unclipped_dst == NULL) {
if (unclipped_dst) {
free(unclipped_dst);
}
unclipped_dst = (char *) malloc(sz+4);
unclipped_len = sz;
}
dst = unclipped_dst;
}
if (! raw_fb_seek) {
memcpy(dst, raw_fb_addr + raw_fb_offset, sz);
} else {
int len = sz, del = 0;
off_t off = (off_t) raw_fb_offset;
lseek(raw_fb_fd, off, SEEK_SET);
while (len > 0) {
n = read(raw_fb_fd, dst + del, len);
if (n > 0) {
del += n;
len -= n;
} else if (n == 0) {
break;
} else if (errno != EINTR && errno != EAGAIN) {
break;
}
}
}
if (dst == unclipped_dst) {
char *src;
int h;
int x = off_x + coff_x;
int y = off_y + coff_y;
src = unclipped_dst + y * wdpy_x * pixelsize +
x * pixelsize;
dst = snap->data;
for (h = 0; h < dpy_y; h++) {
memcpy(dst, src, dpy_x * pixelsize);
src += wdpy_x * pixelsize;
dst += dpy_x * pixelsize;
}
}
}
int copy_snap(void) {
int db = 1, pixelsize = bpp/8;
char *fbp;
int i, y, block_size;
double dt;
static int first = 1;
static int first = 1, snapcnt = 0;
if (raw_fb_str) {
int read_all_at_once = 1;
double start = dnow();
if (rawfb_reset < 0) {
if (getenv("SNAPFB_RAWFB_RESET")) {
rawfb_reset = 1;
} else {
rawfb_reset = 0;
}
}
if (snap_fb == NULL || snap == NULL) {
rfbLog("copy_snap: rawfb mode and null snap fb\n");
clean_up_exit(1);
}
if (rawfb_reset) {
initialize_raw_fb(1);
}
if (read_all_at_once) {
snap_all_rawfb();
} else {
/* this goes line by line, XXX not working for video */
copy_raw_fb(snap, 0, 0, dpy_x, dpy_y);
}
if (db && snapcnt++ < 5) rfbLog("rawfb copy_snap took: %.5f secs\n", dnow() - start);
return 0;
}
if (! fs_factor) {
return 0;
}
......@@ -2005,6 +2118,7 @@ int copy_snap(void) {
fbp = snap_fb;
y = 0;
dtime0(&dt);
X_LOCK;
......
This diff is collapsed.
......@@ -3,6 +3,9 @@
/* -- screen.h -- */
extern void set_greyscale_colormap(void);
extern void set_hi240_colormap(void);
extern void unset_colormap(void);
extern void set_colormap(int reset);
extern void set_nofb_params(int restore);
extern void set_raw_fb_params(int restore);
......@@ -11,10 +14,14 @@ extern void free_old_fb(char *old_main, char *old_rfb, char *old_8to24);
extern void check_padded_fb(void);
extern void install_padded_fb(char *geom);
extern XImage *initialize_xdisplay_fb(void);
extern XImage *initialize_raw_fb(int);
extern void parse_scale_string(char *str, double *factor, int *scaling, int *blend,
int *nomult4, int *pad, int *interpolate, int *numer, int *denom);
extern int scale_round(int len, double fac);
extern void initialize_screen(int *argc, char **argv, XImage *fb);
extern void set_vnc_desktop_name(void);
extern int rawfb_reset;
extern int rawfb_dev_video;
#endif /* _X11VNC_SCREEN_H */
......@@ -4,6 +4,7 @@
#include "cleanup.h"
#include "connections.h"
#include "unixpw.h"
#include "xwrappers.h"
/*
* Selection/Cutbuffer/Clipboard handlers.
......@@ -57,7 +58,11 @@ void selection_request(XEvent *ev, char *type) {
unsigned int length;
unsigned char *data;
#ifndef XA_LENGTH
unsigned long XA_LENGTH = XInternAtom(dpy, "LENGTH", True);
unsigned long XA_LENGTH;
#endif
RAWFB_RET_VOID
#ifndef XA_LENGTH
XA_LENGTH = XInternAtom(dpy, "LENGTH", True);
#endif
req_event = &(ev->xselectionrequest);
......@@ -128,7 +133,7 @@ void selection_request(XEvent *ev, char *type) {
XSetErrorHandler(old_handler);
trapped_xerror = 0;
XFlush(dpy);
XFlush_wr(dpy);
}
int check_sel_direction(char *dir, char *label, char *sel, int len) {
......@@ -179,6 +184,7 @@ void cutbuffer_send(void) {
cutbuffer_str[0] = '\0';
slen = 0;
RAWFB_RET_VOID
/* read the property value into cutbuffer_str: */
do {
......@@ -248,6 +254,7 @@ void selection_send(XEvent *ev) {
unsigned char* data = NULL;
char *selection_str;
RAWFB_RET_VOID
/*
* remember info about our last value of PRIMARY (or CUT_BUFFER0)
* so we can check for any changes below.
......
......@@ -2,6 +2,7 @@
#include "x11vnc.h"
#include "win_utils.h"
#include "xwrappers.h"
char *guess_desktop(void);
void solid_bg(int restore);
......@@ -46,6 +47,8 @@ static void usr_bin_path(int restore) {
static int dt_cmd(char *cmd) {
int rc;
RAWFB_RET(0)
if (!cmd || *cmd == '\0') {
return 0;
}
......@@ -117,6 +120,8 @@ static void solid_root(char *color) {
XColor cdef;
Colormap cmap;
RAWFB_RET_VOID
if (subwin || window != rootwin) {
rfbLog("cannot set subwin to solid color, must be rootwin\n");
return;
......@@ -159,7 +164,7 @@ static void solid_root(char *color) {
XSetWindowBackgroundPixmap(dpy, window, pixmap);
XFreePixmap(dpy, pixmap);
XClearWindow(dpy, window);
XFlush(dpy);
XFlush_wr(dpy);
/* generate exposures */
XMapWindow(dpy, expose);
......@@ -228,6 +233,8 @@ static void solid_cde(char *color) {
Colormap cmap;
int n;
RAWFB_RET_VOID
if (subwin || window != rootwin) {
rfbLog("cannot set subwin to solid color, must be rootwin\n");
return;
......@@ -282,7 +289,7 @@ static void solid_cde(char *color) {
XSetWindowBackgroundPixmap(dpy, twin, pixmap);
XFreePixmap(dpy, pixmap);
XClearWindow(dpy, twin);
XFlush(dpy);
XFlush_wr(dpy);
}
/* generate exposures */
......@@ -481,6 +488,8 @@ static void solid_gnome(char *color) {
static char *orig_color = NULL;
static char *orig_option = NULL;
char *cmd;
RAWFB_RET_VOID
if (! color) {
if (! orig_color) {
......@@ -555,6 +564,8 @@ static void solid_kde(char *color) {
char *cmd, *user = NULL;
int len;
RAWFB_RET_VOID
user = get_user_name();
if (strstr(user, "'") != NULL) {
rfbLog("invalid user: %s\n", user);
......@@ -595,6 +606,8 @@ static void solid_kde(char *color) {
char *guess_desktop(void) {
Atom prop;
RAWFB_RET("root")
if (wmdt_str && *wmdt_str != '\0') {
char *s = wmdt_str;
lowercase(s);
......@@ -647,6 +660,8 @@ void solid_bg(int restore) {
static char *prev_str;
char *dtname, *color;
RAWFB_RET_VOID
if (started_as_root == 1 && users_list) {
/* we are still root, don't try. */
return;
......
......@@ -1028,7 +1028,7 @@ if (db) fprintf(stderr, "tv_sec: %d - %s\n", (int) tv.tv_sec, last_get);
return 1;
}
#define BSIZE 16384
#define ABSIZE 16384
static int watch_for_http_traffic(char *buf_a, int *n_a) {
int is_http, err, n, n2;
char *buf;
......@@ -1038,13 +1038,13 @@ static int watch_for_http_traffic(char *buf_a, int *n_a) {
* if it is http or not. if we read them OK, we must read the
* rest of the available data otherwise we may deadlock.
* what has be read is returned in buf_a and n_a.
* *buf_a is BSIZE+1 long and zeroed.
* *buf_a is ABSIZE+1 long and zeroed.
*/
if (getenv("ACCEPT_OPENSSL_DEBUG")) {
db = atoi(getenv("ACCEPT_OPENSSL_DEBUG"));
}
buf = (char *) calloc(sizeof(BSIZE+1), 1);
buf = (char *) calloc(sizeof(ABSIZE+1), 1);
*n_a = 0;
n = SSL_read(ssl, buf, 2);
......@@ -1075,7 +1075,7 @@ static int watch_for_http_traffic(char *buf_a, int *n_a) {
* better read all we can and fwd it along to avoid blocking
* in ssl_xfer().
*/
n2 = SSL_read(ssl, buf + n, BSIZE - n);
n2 = SSL_read(ssl, buf + n, ABSIZE - n);
if (n2 >= 0) {
n += n2;
}
......@@ -1376,8 +1376,8 @@ void accept_openssl(int mode) {
char *iface = NULL;
char *buf, *tbuf;
buf = (char *) calloc((BSIZE+1), 1);
tbuf = (char *) calloc((2*BSIZE+1), 1);
buf = (char *) calloc((ABSIZE+1), 1);
tbuf = (char *) calloc((2*ABSIZE+1), 1);
if (mode == OPENSSL_HTTPS) {
/*
......@@ -1857,7 +1857,7 @@ if (db > 1) write(2, buf, n);
static void ssl_xfer(int csock, int s_in, int s_out, int is_https) {
int dbxfer = 0, db = 0, check_pending, fdmax, nfd, n, i, err;
char cbuf[BSIZE], sbuf[BSIZE];
char cbuf[ABSIZE], sbuf[ABSIZE];
int cptr, sptr, c_rd, c_wr, s_rd, s_wr;
fd_set rd, wr;
struct timeval tv;
......@@ -1905,7 +1905,7 @@ static void ssl_xfer(int csock, int s_in, int s_out, int is_https) {
* cbuf[] is data from csock that we have read but not passed on to ssl
* sbuf[] is data from ssl that we have read but not passed on to csock
*/
for (i=0; i<BSIZE; i++) {
for (i=0; i<ABSIZE; i++) {
cbuf[i] = '\0';
sbuf[i] = '\0';
}
......@@ -1927,7 +1927,7 @@ static void ssl_xfer(int csock, int s_in, int s_out, int is_https) {
s_rd = 1; /* ssl data (remote client) socket open for reading */
s_wr = 1; /* ssl data (remote client) socket open for writing */
cptr = 0; /* offsets into BSIZE buffers */
cptr = 0; /* offsets into ABSIZE buffers */
sptr = 0;
while (1) {
......@@ -1966,7 +1966,7 @@ static void ssl_xfer(int csock, int s_in, int s_out, int is_https) {
FD_ZERO(&rd);
if (c_rd && cptr < BSIZE) {
if (c_rd && cptr < ABSIZE) {
/* we could read more from C since cbuf is not full */
FD_SET(csock, &rd);
}
......@@ -1976,7 +1976,7 @@ static void ssl_xfer(int csock, int s_in, int s_out, int is_https) {
* OR ssl is waiting for more BIO to be able to
* read and we have some C data still buffered.
*/
if (sptr < BSIZE || (cptr > 0 && SSL_want_read(ssl))) {
if (sptr < ABSIZE || (cptr > 0 && SSL_want_read(ssl))) {
FD_SET(s_in, &rd);
}
}
......@@ -1993,7 +1993,7 @@ static void ssl_xfer(int csock, int s_in, int s_out, int is_https) {
* OR ssl is waiting for more BIO to be able
* write and we haven't filled up sbuf yet.
*/
if (cptr > 0 || (sptr < BSIZE && SSL_want_write(ssl))) {
if (cptr > 0 || (sptr < ABSIZE && SSL_want_write(ssl))) {
FD_SET(s_out, &wr);
}
}
......@@ -2050,7 +2050,7 @@ static void ssl_xfer(int csock, int s_in, int s_out, int is_https) {
} else {
/* shift over the data in sbuf by n */
memmove(sbuf, sbuf + n, sptr - n);
if (sptr == BSIZE) {
if (sptr == ABSIZE) {
check_pending = 1;
}
sptr -= n;
......@@ -2111,7 +2111,7 @@ static void ssl_xfer(int csock, int s_in, int s_out, int is_https) {
/* try to read some data from C into our cbuf */
n = read(csock, cbuf + cptr, BSIZE - cptr);
n = read(csock, cbuf + cptr, ABSIZE - cptr);
if (n < 0) {
if (errno != EINTR) {
......@@ -2135,13 +2135,13 @@ static void ssl_xfer(int csock, int s_in, int s_out, int is_https) {
}
if (s_rd) {
if ((sptr < BSIZE && FD_ISSET(s_in, &rd)) ||
if ((sptr < ABSIZE && FD_ISSET(s_in, &rd)) ||
(SSL_want_write(ssl) && FD_ISSET(s_out, &wr)) ||
(check_pending && SSL_pending(ssl))) {
/* try to read some data from S into our sbuf */
n = SSL_read(ssl, sbuf + sptr, BSIZE - sptr);
n = SSL_read(ssl, sbuf + sptr, ABSIZE - sptr);
err = SSL_get_error(ssl, n);
if (err == SSL_ERROR_NONE) {
......
......@@ -178,6 +178,7 @@ Screen
visual:
rawfb:
pipeinput:
24to32
=GAL LOFF
Keyboard
......
......@@ -189,6 +189,7 @@ char gui_code[] = "";
" visual:\n"
" rawfb:\n"
" pipeinput:\n"
" 24to32\n"
" =GAL LOFF\n"
"\n"
"Keyboard\n"
......
......@@ -67,6 +67,8 @@ static int db = 0;
static int white(void) {
static unsigned long black_pix = 0, white_pix = 1, set = 0;
RAWFB_RET(0xffffff)
if (depth <= 8 && ! set) {
X_LOCK;
black_pix = BlackPixel(dpy, scr);
......
......@@ -445,10 +445,13 @@ void lurk_loop(char *str) {
}
static int guess_user_and_switch(char *str, int fb_mode) {
char *dstr, *d = DisplayString(dpy);
char *dstr, *d;
char *p, *tstr = NULL, *allowed = NULL, *logins, **users = NULL;
int dpy1, ret = 0;
RAWFB_RET(0)
d = DisplayString(dpy);
/* pick out ":N" */
dstr = strchr(d, ':');
if (! dstr) {
......@@ -639,7 +642,7 @@ static int switch_user_env(uid_t uid, char *name, char *home, int fb_mode) {
* OK tricky here, we need to free the shm... otherwise
* we won't be able to delete it as the other user...
*/
if (fb_mode == 1 && using_shm) {
if (fb_mode == 1 && (using_shm && ! xform24to32)) {
reset_fb = 1;
clean_shm(0);
free_tiles();
......
......@@ -96,6 +96,8 @@ int get_wm_frame_pos(int *px, int *py, int *x, int *y, int *w, int *h,
int rootx, rooty, wx, wy;
unsigned int mask;
RAWFB_RET(0)
ret = XQueryPointer(dpy, rootwin, &r, &c, &rootx, &rooty, &wx, &wy,
&mask);
......@@ -2140,6 +2142,9 @@ static int check_xrecord_keys(void) {
double set_repeat_in;
static double set_repeat = 0.0;
RAWFB_RET(0)
set_repeat_in = set_repeat;
set_repeat = 0.0;
......@@ -2222,7 +2227,7 @@ if (db) fprintf(stderr, "check_xrecord_keys: BEGIN LOOP: scr_ev_cnt: "
X_LOCK;
flush1 = 1;
XFlush(dpy);
XFlush_wr(dpy);
X_UNLOCK;
if (set_repeat_in > 0.0) {
......@@ -2253,7 +2258,7 @@ if (0 || db) fprintf(stderr, "check_xrecord: more keys: %.3f 0x%x "
" %.4f %s %s\n", spin, last_rfb_keysym, last_rfb_keytime - x11vnc_start,
last_rfb_down ? "down":"up ", last_rfb_key_accepted ? "accept":"skip");
flush2 = 1;
XFlush(dpy);
XFlush_wr(dpy);
}
#if LIBVNCSERVER_HAVE_RECORD
SCR_LOCK;
......@@ -2383,6 +2388,8 @@ static int check_xrecord_mouse(void) {
int btn4 = (1<<3);
int btn5 = (1<<4);
RAWFB_RET(0)
get_out = 1;
if (button_mask) {
get_out = 0;
......@@ -2540,7 +2547,7 @@ if (db) fprintf(stderr, "check_xrecord: BUTTON_UP_SCROLL: %.3f\n", spin);
if (! already_down || (!scr_cnt && spin>flush1_time)) {
flush1 = 1;
X_LOCK;
XFlush(dpy);
XFlush_wr(dpy);
X_UNLOCK;
dtime0(&last_flush);
}
......@@ -2624,7 +2631,7 @@ if (db) fprintf(stderr, "check_xrecord: BUTTON-UP-KEEP-GOING: %.3f/%.3f %d/%d %
if (doflush) {
flush1 = 1;
X_LOCK;
XFlush(dpy);
XFlush_wr(dpy);
X_UNLOCK;
dtime0(&last_flush);
}
......@@ -2679,8 +2686,8 @@ if (db) fprintf(stderr, " we decide to send ret=3\n");
if (flush2) {
X_LOCK;
XFlush(dpy);
XFlush(rdpy_ctrl);
XFlush_wr(dpy);
XFlush_wr(rdpy_ctrl);
X_UNLOCK;
flush2 = 1;
......@@ -2708,6 +2715,8 @@ int check_xrecord(void) {
int watch_keys = 0, watch_mouse = 0, consider_mouse;
static int mouse_wants_back_in = 0;
RAWFB_RET(0)
if (! use_xrecord) {
return 0;
}
......@@ -3291,6 +3300,8 @@ int check_wireframe(void) {
int try_it = 0;
DB_SET
RAWFB_RET(0)
if (unixpw_in_progress) return 0;
if (nofb) {
return 0;
......@@ -3439,7 +3450,7 @@ if (db) fprintf(stderr, "INTERIOR\n");
while (1) {
X_LOCK;
XFlush(dpy);
XFlush_wr(dpy);
X_UNLOCK;
/* try do induce/waitfor some more user input */
......@@ -3504,7 +3515,7 @@ if (db) fprintf(stderr, " ++pointer event!! [%02d] dt: %.3f x: %d y: %d mas
g = got_pointer_input;
X_LOCK;
XFlush(dpy);
XFlush_wr(dpy);
X_UNLOCK;
/* periodically try to let the wm get moving: */
......@@ -3849,7 +3860,7 @@ static void check_user_input2(double dt) {
X_LOCK;
do_flush = 0;
if (0) fprintf(stderr, "check_user_input2-A: XFlush %.4f\n", tm);
XFlush(dpy);
XFlush_wr(dpy);
X_UNLOCK;
if (eaten < max_eat) {
continue;
......@@ -3864,7 +3875,7 @@ if (0) fprintf(stderr, "check_user_input2-A: XFlush %.4f\n", tm);
if (do_flush) {
X_LOCK;
if (0) fprintf(stderr, "check_user_input2-B: XFlush %.4f\n", tm);
XFlush(dpy);
XFlush_wr(dpy);
X_UNLOCK;
}
......@@ -3922,7 +3933,7 @@ if (0) fprintf(stderr, "check_user_input2-B: XFlush %.4f\n", tm);
}
X_LOCK;
if (0) fprintf(stderr, "check_user_input2-C: XFlush %.4f\n", tm);
XFlush(dpy);
XFlush_wr(dpy);
X_UNLOCK;
miss = 0;
} else {
......@@ -4020,7 +4031,7 @@ static void check_user_input3(double dt, double dtr, int tile_diffs) {
got_input = 1;
g = got_pointer_input;
X_LOCK;
XFlush(dpy);
XFlush_wr(dpy);
X_UNLOCK;
} else if (--allowed_misses <= 0) {
/* too many misses */
......@@ -4172,7 +4183,7 @@ static void check_user_input4(double dt, double dtr, int tile_diffs) {
}
if (iter) {
X_LOCK;
XFlush(dpy);
XFlush_wr(dpy);
X_UNLOCK;
}
push_frame = 0;
......@@ -4256,7 +4267,7 @@ static void check_user_input4(double dt, double dtr, int tile_diffs) {
got_input = 1;
g = got_pointer_input;
X_LOCK;
XFlush(dpy);
XFlush_wr(dpy);
X_UNLOCK;
} else if (consecutive_misses >= 2) {
......@@ -4296,7 +4307,7 @@ static void check_user_input4(double dt, double dtr, int tile_diffs) {
int check_user_input(double dt, double dtr, int tile_diffs, int *cnt) {
if (raw_fb && ! dpy) return 0; /* raw_fb hack */
RAWFB_RET(0)
if (use_xrecord) {
int rc = check_xrecord();
......@@ -4328,7 +4339,7 @@ if (debug_scroll && rc > 1) fprintf(stderr, " CXR: check_user_input ret %d\n",
/* every ui_skip-th drops thru to scan */
*cnt++;
X_LOCK;
XFlush(dpy);
XFlush_wr(dpy);
X_UNLOCK;
return 1; /* short circuit watch_loop */
} else {
......
This diff is collapsed.
#ifndef _X11VNC_V4L_H
#define _X11VNC_V4L_H
/* -- v4l.h -- */
extern char *v4l_guess(char *str, int *fd);
extern void v4l_key_command(rfbBool down, rfbKeySym keysym, rfbClientPtr client);
extern void v4l_pointer_command(int mask, int x, int y, rfbClientPtr client);
#endif /* _X11VNC_V4L_H */
......@@ -4,6 +4,7 @@
#include "xinerama.h"
#include "winattr_t.h"
#include "cleanup.h"
#include "xwrappers.h"
winattr_t *stack_list = NULL;
int stack_list_len = 0;
......@@ -32,6 +33,7 @@ Window parent_window(Window win, char **name) {
if (name != NULL) {
*name = NULL;
}
RAWFB_RET(None)
old_handler = XSetErrorHandler(trap_xerror);
trapped_xerror = 0;
......@@ -68,6 +70,7 @@ int valid_window(Window win, XWindowAttributes *attr_ret, int bequiet) {
if (win == None) {
return 0;
}
RAWFB_RET(0)
old_handler = XSetErrorHandler(trap_xerror);
trapped_xerror = 0;
......@@ -92,6 +95,8 @@ Bool xtranslate(Window src, Window dst, int src_x, int src_y, int *dst_x,
XErrorHandler old_handler;
Bool ok = False;
RAWFB_RET(False)
trapped_xerror = 0;
old_handler = XSetErrorHandler(trap_xerror);
if (XTranslateCoordinates(dpy, src, dst, src_x, src_y, dst_x,
......@@ -157,6 +162,8 @@ void snapshot_stack_list(int free_only, double allowed_age) {
stack_list_num = 0;
last_free = now;
RAWFB_RET_VOID
X_LOCK;
/* no need to trap error since rootwin */
rc = XQueryTree(dpy, rootwin, &r, &w, &list, &ui);
......@@ -261,6 +268,7 @@ Window query_pointer(Window start) {
Window r, c;
int rx, ry, wx, wy;
unsigned int mask;
RAWFB_RET(None)
if (start == None) {
start = rootwin;
}
......@@ -276,6 +284,8 @@ int pick_windowid(unsigned long *num) {
int ok = 0, n = 0, msec = 10, secmax = 15;
FILE *p;
RAWFB_RET(0)
if (use_dpy) {
set_env("DISPLAY", use_dpy);
}
......@@ -319,7 +329,7 @@ int pick_windowid(unsigned long *num) {
* note this rfbPE takes about 30ms too:
*/
rfbPE(-1);
XFlush(dpy);
XFlush_wr(dpy);
continue;
}
}
......@@ -353,6 +363,8 @@ Window descend_pointer(int depth, Window start, char *name_info, int len) {
static int nm_cache_len = 0;
static Window prev_start = None;
RAWFB_RET(None)
if (! classhint) {
classhint = XAllocClassHint();
}
......
This diff is collapsed.
......@@ -524,7 +524,7 @@ if (debug_scroll) fprintf(stderr, "watch_loop: LOOP-BACK: %d\n", ret);
* screen, but do flush the X11 display.
*/
X_LOCK;
XFlush(dpy);
XFlush_wr(dpy);
X_UNLOCK;
dt = 0.0;
} else {
......@@ -540,7 +540,7 @@ if (debug_scroll) fprintf(stderr, "watch_loop: LOOP-BACK: %d\n", ret);
}
dtime0(&tm);
if (use_snapfb) {
int t, tries = 5;
int t, tries = 3;
copy_snap();
for (t =0; t < tries; t++) {
tile_diffs = scan_for_updates(0);
......@@ -599,7 +599,7 @@ static char *choose_title(char *display) {
strncat(title, display, MAXN - strlen(title));
if (subwin && valid_window(subwin, NULL, 0)) {
char *name;
if (XFetchName(dpy, subwin, &name)) {
if (dpy && XFetchName(dpy, subwin, &name)) {
strncat(title, " ", MAXN - strlen(title));
strncat(title, name, MAXN - strlen(title));
}
......@@ -1030,6 +1030,7 @@ static void print_settings(int try_http, int bg, char *gui_str) {
fprintf(stderr, " cmap8to24: %d\n", cmap8to24);
fprintf(stderr, " 8to24_opts: %s\n", cmap8to24_str ? cmap8to24_str
: "null");
fprintf(stderr, " 24to32: %d\n", xform24to32);
fprintf(stderr, " visual: %s\n", visual_str ? visual_str
: "null");
fprintf(stderr, " overlay: %d\n", overlay);
......@@ -1521,6 +1522,8 @@ int main(int argc, char* argv[]) {
}
}
#endif
} else if (!strcmp(arg, "-24to32")) {
xform24to32 = 1;
} else if (!strcmp(arg, "-visual")) {
CHECK_ARGC
visual_str = strdup(argv[++i]);
......@@ -2111,6 +2114,9 @@ int main(int argc, char* argv[]) {
} else if (!strcmp(arg, "-rawfb")) {
CHECK_ARGC
raw_fb_str = strdup(argv[++i]);
} else if (!strcmp(arg, "-freqtab")) {
CHECK_ARGC
freqtab = strdup(argv[++i]);
} else if (!strcmp(arg, "-pipeinput")) {
CHECK_ARGC
pipeinput_str = strdup(argv[++i]);
......@@ -2782,7 +2788,7 @@ int main(int argc, char* argv[]) {
if (remote_cmd || query_cmd) {
int rc = do_remote_query(remote_cmd, query_cmd, remote_sync,
query_default);
XFlush(dpy);
XFlush_wr(dpy);
fflush(stderr);
fflush(stdout);
usleep(30 * 1000); /* still needed? */
......
......@@ -310,6 +310,9 @@ extern int xfixes_base_event_type;
#endif
extern int xdamage_base_event_type;
#define RAWFB_RET(y) if (raw_fb && ! dpy) return y;
#define RAWFB_RET_VOID if (raw_fb && ! dpy) return;
extern char lastmod[];
/* X display info */
......
......@@ -15,7 +15,7 @@ int xtrap_base_event_type = 0;
int xdamage_base_event_type = 0;
/* date +'lastmod: %Y-%m-%d' */
char lastmod[] = "0.8.1 lastmod: 2006-04-25";
char lastmod[] = "0.8.1 lastmod: 2006-05-06";
/* X display info */
......
......@@ -169,6 +169,8 @@ void clear_xdamage_mark_region(sraRegionPtr markregion, int flush) {
sraRegionPtr tmpregion;
int count = 0;
RAWFB_RET_VOID
if (! xdamage_present || ! use_xdamage) {
return;
}
......@@ -182,7 +184,7 @@ void clear_xdamage_mark_region(sraRegionPtr markregion, int flush) {
X_LOCK;
if (flush) {
XFlush(dpy);
XFlush_wr(dpy);
}
while (XCheckTypedEvent(dpy, xdamage_base_event_type+XDamageNotify, &ev)) {
count++;
......@@ -225,6 +227,8 @@ int collect_xdamage(int scancnt, int call) {
int dup_x[DUPSZ], dup_y[DUPSZ], dup_w[DUPSZ], dup_h[DUPSZ];
double tm, dt;
RAWFB_RET(0)
if (scancnt) {} /* unused vars warning: */
if (! xdamage_present || ! use_xdamage) {
......@@ -252,7 +256,7 @@ int collect_xdamage(int scancnt, int call) {
X_LOCK;
if (0) XFlush(dpy);
if (0) XFlush_wr(dpy);
if (0) XEventsQueued(dpy, QueuedAfterFlush);
while (XCheckTypedEvent(dpy, xdamage_base_event_type+XDamageNotify, &ev)) {
/*
......@@ -472,7 +476,7 @@ void initialize_xdamage(void) {
void create_xdamage_if_needed(void) {
if (raw_fb && ! dpy) return; /* raw_fb hack */
RAWFB_RET_VOID
#if LIBVNCSERVER_HAVE_LIBXDAMAGE
if (! xdamage) {
......@@ -487,14 +491,14 @@ void create_xdamage_if_needed(void) {
void destroy_xdamage_if_needed(void) {
if (raw_fb && ! dpy) return; /* raw_fb hack */
RAWFB_RET_VOID
#if LIBVNCSERVER_HAVE_LIBXDAMAGE
if (xdamage) {
XEvent ev;
X_LOCK;
XDamageDestroy(dpy, xdamage);
XFlush(dpy);
XFlush_wr(dpy);
if (xdamage_base_event_type) {
while (XCheckTypedEvent(dpy,
xdamage_base_event_type+XDamageNotify, &ev)) {
......
This diff is collapsed.
......@@ -240,7 +240,7 @@ static void initialize_xinerama (void) {
char *bstr, *tstr;
int ev, er, i, n, rcnt;
if (raw_fb && ! dpy) return; /* raw_fb hack */
RAWFB_RET_VOID
if (! XineramaQueryExtension(dpy, &ev, &er)) {
rfbLog("Xinerama: disabling: display does not support it.\n");
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -17,6 +17,8 @@ extern int clipshift;
extern int guess_bits_per_color(int bits_per_pixel);
extern int XFlush_wr(Display *disp);
extern Status XShmGetImage_wr(Display *disp, Drawable d, XImage *image, int x, int y,
unsigned long mask);
extern XImage *XShmCreateImage_wr(Display* disp, Visual* vis, unsigned int depth,
......@@ -38,6 +40,7 @@ extern XImage *XCreateImage_wr(Display *disp, Visual *visual, unsigned int depth
int format, int offset, char *data, unsigned int width,
unsigned int height, int bitmap_pad, int bytes_per_line);
extern void copy_image(XImage *dest, int x, int y, unsigned int w, unsigned int h);
extern void copy_raw_fb(XImage *dest, int x, int y, unsigned int w, unsigned int h);
extern void init_track_keycode_state(void);
extern void XTRAP_FakeKeyEvent_wr(Display* dpy, KeyCode key, Bool down,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment