diff options
author | runge <runge> | 2006-03-08 17:52:23 +0000 |
---|---|---|
committer | runge <runge> | 2006-03-08 17:52:23 +0000 |
commit | 5e72609631a1893acfe6a31d0129553ed3044a20 (patch) | |
tree | b75197718dc94f26c56cdfbb39d069c79f1cd767 /x11vnc/xevents.c | |
parent | c997e901c4c268438d063a78bdb121b8f5e8d585 (diff) | |
download | libtdevnc-5e72609631a1893acfe6a31d0129553ed3044a20.tar.gz libtdevnc-5e72609631a1893acfe6a31d0129553ed3044a20.zip |
x11vnc: do CLIPBOARD, reverse conn require passwds, -usepw, -debug_sel, -storepasswd homedir.
Diffstat (limited to 'x11vnc/xevents.c')
-rw-r--r-- | x11vnc/xevents.c | 188 |
1 files changed, 150 insertions, 38 deletions
diff --git a/x11vnc/xevents.c b/x11vnc/xevents.c index 3e9401b..69c332f 100644 --- a/x11vnc/xevents.c +++ b/x11vnc/xevents.c @@ -19,6 +19,7 @@ int sync_tod_delay = 3; void initialize_vnc_connect_prop(void); void initialize_x11vnc_remote_prop(void); +void initialize_clipboard_atom(void); void spawn_grab_buster(void); void sync_tod_with_servertime(void); void check_keycode_state(void); @@ -45,11 +46,25 @@ void initialize_x11vnc_remote_prop(void) { x11vnc_remote_prop = XInternAtom(dpy, "X11VNC_REMOTE", False); } +void initialize_clipboard_atom(void) { + clipboard_atom = XInternAtom(dpy, "CLIPBOARD", False); + if (clipboard_atom == None) { + if (! quiet) rfbLog("could not find atom CLIPBOARD\n"); + if (watch_clipboard) { + watch_clipboard = 0; + } + if (set_clipboard) { + set_clipboard = 0; + } + } +} + static void initialize_xevents(void) { static int did_xselect_input = 0; static int did_xcreate_simple_window = 0; static int did_vnc_connect_prop = 0; static int did_x11vnc_remote_prop = 0; + static int did_clipboard_atom = 0; static int did_xfixes = 0; static int did_xdamage = 0; static int did_xrandr = 0; @@ -90,6 +105,10 @@ static void initialize_xevents(void) { kill(run_gui_pid, SIGUSR1); run_gui_pid = 0; } + if (!did_clipboard_atom) { + initialize_clipboard_atom(); + did_clipboard_atom = 1; + } if (xfixes_present && use_xfixes && !did_xfixes) { initialize_xfixes(); did_xfixes = 1; @@ -662,13 +681,13 @@ void check_xevents(void) { XEvent xev; int tmp, have_clients = 0; static int sent_some_sel = 0; - static time_t last_request = 0; static time_t last_call = 0; static time_t last_bell = 0; static time_t last_init_check = 0; static time_t last_sync = 0; static time_t last_time_sync = 0; time_t now = time(0); + static double last_request = 0.0; if (raw_fb && ! dpy) return; /* raw_fb hack */ @@ -798,56 +817,119 @@ void check_xevents(void) { #endif /* check for our PRIMARY request notification: */ - if (watch_primary) { + if (watch_primary || watch_clipboard) { + int doprimary = 1, doclipboard = 2, which, own; + double delay = 1.0; + Atom atom; + char *req; + if (XCheckTypedEvent(dpy, SelectionNotify, &xev)) { if (xev.type == SelectionNotify && xev.xselection.requestor == selwin && - xev.xselection.selection == XA_PRIMARY && xev.xselection.property != None && xev.xselection.target == XA_STRING) { - - /* go retrieve PRIMARY and check it */ - if (now > last_client + sel_waittime - || sent_some_sel) { - selection_send(&xev); + Atom s = xev.xselection.selection; + if (s == XA_PRIMARY || s == clipboard_atom) { + /* go retrieve it and check it */ + if (now > last_client + sel_waittime + || sent_some_sel) { + selection_send(&xev); + } } } } - if (now > last_request) { + /* + * Every second or so, request PRIMARY or CLIPBOARD, + * unless we already own it or there is no owner or we + * have no clients. + * TODO: even at this low rate we should look into + * and performance problems in odds cases (large text, + * modem, etc.) + */ + which = 0; + if (watch_primary && watch_clipboard && ! own_clipboard && + ! own_primary) { + delay = 0.6; + } + if (dnow() > last_request + delay) { /* - * Every second or two, request PRIMARY, unless we - * already own it or there is no owner or we have - * no clients. - * TODO: even at this low rate we should look into - * and performance problems in odds cases, etc. + * It is not a good idea to do both at the same + * time so we must choose one: */ - last_request = now; - if (! own_selection && have_clients && - XGetSelectionOwner(dpy, XA_PRIMARY) != None) { - XConvertSelection(dpy, XA_PRIMARY, XA_STRING, - XA_STRING, selwin, CurrentTime); + if (watch_primary && watch_clipboard) { + static int count = 0; + if (own_clipboard) { + which = doprimary; + } else if (own_primary) { + which = doclipboard; + } else if (count++ % 3 == 0) { + which = doclipboard; + } else { + which = doprimary; + } + } else if (watch_primary) { + which = doprimary; + } else if (watch_clipboard) { + which = doclipboard; + } + last_request = dnow(); + } + atom = None; + req = "none"; + if (which == doprimary) { + own = own_primary; + atom = XA_PRIMARY; + req = "PRIMARY"; + } else if (which == doclipboard) { + own = own_clipboard; + atom = clipboard_atom; + req = "CLIPBOARD"; + } + if (which != 0 && ! own && have_clients && + XGetSelectionOwner(dpy, atom) != None) { + XConvertSelection(dpy, atom, XA_STRING, XA_STRING, + selwin, CurrentTime); + if (debug_sel) { + rfbLog("request %s\n", req); } } } - if (own_selection) { - /* we own PRIMARY, see if someone requested it: */ + if (own_primary || own_clipboard) { + /* we own PRIMARY or CLIPBOARD, see if someone requested it: */ if (XCheckTypedEvent(dpy, SelectionRequest, &xev)) { - if (xev.type == SelectionRequest && + if (own_primary && xev.type == SelectionRequest && xev.xselectionrequest.selection == XA_PRIMARY) { - selection_request(&xev); + selection_request(&xev, "PRIMARY"); + } + if (own_clipboard && xev.type == SelectionRequest && + xev.xselectionrequest.selection == clipboard_atom) { + selection_request(&xev, "CLIPBOARD"); } } - /* we own PRIMARY, see if we no longer own it: */ + /* we own PRIMARY or CLIPBOARD, see if we no longer own it: */ if (XCheckTypedEvent(dpy, SelectionClear, &xev)) { - if (xev.type == SelectionClear && + if (own_primary && xev.type == SelectionClear && xev.xselectionclear.selection == XA_PRIMARY) { - - own_selection = 0; - if (xcut_str) { - free(xcut_str); - xcut_str = NULL; + own_primary = 0; + if (xcut_str_primary) { + free(xcut_str_primary); + xcut_str_primary = NULL; + } + if (debug_sel) { + rfbLog("Released PRIMARY.\n"); + } + } + if (own_clipboard && xev.type == SelectionClear && + xev.xselectionclear.selection == clipboard_atom) { + own_clipboard = 0; + if (xcut_str_clipboard) { + free(xcut_str_clipboard); + xcut_str_clipboard = NULL; + } + if (debug_sel) { + rfbLog("Released CLIPBOARD.\n"); } } } @@ -986,21 +1068,51 @@ void xcut_receive(char *text, int len, rfbClientPtr cl) { X_LOCK; /* associate this text with PRIMARY (and SECONDARY...) */ - if (! own_selection) { - own_selection = 1; + if (set_primary && ! own_primary) { + own_primary = 1; /* we need to grab the PRIMARY selection */ XSetSelectionOwner(dpy, XA_PRIMARY, selwin, CurrentTime); XFlush(dpy); + if (debug_sel) { + rfbLog("Own PRIMARY.\n"); + } + } + + if (set_clipboard && ! own_clipboard && clipboard_atom != None) { + own_clipboard = 1; + /* we need to grab the CLIPBOARD selection */ + XSetSelectionOwner(dpy, clipboard_atom, selwin, CurrentTime); + XFlush(dpy); + if (debug_sel) { + rfbLog("Own CLIPBOARD.\n"); + } } /* duplicate the text string for our own use. */ - if (xcut_str != NULL) { - free(xcut_str); - xcut_str = NULL; + if (set_primary) { + if (xcut_str_primary != NULL) { + free(xcut_str_primary); + xcut_str_primary = NULL; + } + xcut_str_primary = (char *) malloc((size_t) (len+1)); + strncpy(xcut_str_primary, text, len); + xcut_str_primary[len] = '\0'; /* make sure null terminated */ + if (debug_sel) { + rfbLog("Set PRIMARY '%s'\n", xcut_str_primary); + } + } + if (set_clipboard) { + if (xcut_str_clipboard != NULL) { + free(xcut_str_clipboard); + xcut_str_clipboard = NULL; + } + xcut_str_clipboard = (char *) malloc((size_t) (len+1)); + strncpy(xcut_str_clipboard, text, len); + xcut_str_clipboard[len] = '\0'; /* make sure null terminated */ + if (debug_sel) { + rfbLog("Set CLIPBOARD '%s'\n", xcut_str_clipboard); + } } - xcut_str = (char *) malloc((size_t) (len+1)); - strncpy(xcut_str, text, len); - xcut_str[len] = '\0'; /* make sure null terminated */ /* copy this text to CUT_BUFFER0 as well: */ XChangeProperty(dpy, rootwin, XA_CUT_BUFFER0, XA_STRING, 8, |