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/selection.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/selection.c')
-rw-r--r-- | x11vnc/selection.c | 106 |
1 files changed, 83 insertions, 23 deletions
diff --git a/x11vnc/selection.c b/x11vnc/selection.c index 8097057..599be08 100644 --- a/x11vnc/selection.c +++ b/x11vnc/selection.c @@ -9,19 +9,24 @@ * Selection/Cutbuffer/Clipboard handlers. */ -int own_selection = 0; /* whether we currently own PRIMARY or not */ +int own_primary = 0; /* whether we currently own PRIMARY or not */ +int set_primary = 1; +int own_clipboard = 0; /* whether we currently own CLIPBOARD or not */ +int set_clipboard = 1; int set_cutbuffer = 0; /* to avoid bouncing the CutText right back */ int sel_waittime = 15; /* some seconds to skip before first send */ Window selwin; /* special window for our selection */ +Atom clipboard_atom = None; /* * This is where we keep our selection: the string sent TO us from VNC * clients, and the string sent BY us to requesting X11 clients. */ -char *xcut_str = NULL; +char *xcut_str_primary = NULL; +char *xcut_str_clipboard = NULL; -void selection_request(XEvent *ev); +void selection_request(XEvent *ev, char *type); int check_sel_direction(char *dir, char *label, char *sel, int len); void cutbuffer_send(void); void selection_send(XEvent *ev); @@ -29,14 +34,14 @@ void selection_send(XEvent *ev); /* * Our callbacks instruct us to check for changes in the cutbuffer - * and PRIMARY selection on the local X11 display. + * and PRIMARY and CLIPBOARD selection on the local X11 display. * - * We store the new cutbuffer and/or PRIMARY selection data in this - * constant sized array selection_str[]. * TODO: check if malloc does not cause performance issues (esp. WRT * SelectionNotify handling). */ -static char selection_str[PROP_MAX+1]; +static char cutbuffer_str[PROP_MAX+1]; +static char primary_str[PROP_MAX+1]; +static char clipboard_str[PROP_MAX+1]; /* * An X11 (not VNC) client on the local display has requested the selection @@ -44,10 +49,11 @@ static char selection_str[PROP_MAX+1]; * * n.b.: our caller already has the X_LOCK. */ -void selection_request(XEvent *ev) { +void selection_request(XEvent *ev, char *type) { XSelectionEvent notify_event; XSelectionRequestEvent *req_event; XErrorHandler old_handler; + char *str; unsigned int length; unsigned char *data; #ifndef XA_LENGTH @@ -67,11 +73,24 @@ void selection_request(XEvent *ev) { } else { notify_event.property = req_event->property; } - if (xcut_str) { - length = strlen(xcut_str); + + if (!strcmp(type, "PRIMARY")) { + str = xcut_str_primary; + } else if (!strcmp(type, "CLIPBOARD")) { + str = xcut_str_clipboard; + } else { + return; + } + if (str) { + length = strlen(str); } else { length = 0; } + if (debug_sel) { + rfbLog("%s\trequest event: owner=0x%x requestor=0x%x sel=%03d targ=%d prop=%d\n", + type, req_event->owner, req_event->requestor, req_event->selection, + req_event->target, req_event->property); + } /* the window may have gone away, so trap errors */ trapped_xerror = 0; @@ -89,7 +108,7 @@ void selection_request(XEvent *ev) { } else { /* data request */ - data = (unsigned char *)xcut_str; + data = (unsigned char *)str; XChangeProperty(ev->xselectionrequest.display, ev->xselectionrequest.requestor, @@ -104,7 +123,7 @@ void selection_request(XEvent *ev) { } if (trapped_xerror) { rfbLog("selection_request: ignored XError while sending " - "PRIMARY selection to 0x%x.\n", req_event->requestor); + "%s selection to 0x%x.\n", type, req_event->requestor); } XSetErrorHandler(old_handler); trapped_xerror = 0; @@ -114,6 +133,9 @@ void selection_request(XEvent *ev) { int check_sel_direction(char *dir, char *label, char *sel, int len) { int db = 0, ok = 1; + if (debug_sel) { + db = 1; + } if (sel_direction) { if (strstr(sel_direction, "debug")) { db = 1; @@ -132,7 +154,7 @@ int check_sel_direction(char *dir, char *label, char *sel, int len) { if (len < n) { str[len] = '\0'; } - rfbLog("%s: %s...\n", label, str); + rfbLog("%s: '%s'\n", label, str); if (ok) { rfbLog("%s: %s-ing it.\n", label, dir); } else { @@ -154,10 +176,11 @@ void cutbuffer_send(void) { unsigned long nitems = 0, bytes_after = 0; unsigned char* data = NULL; - selection_str[0] = '\0'; + cutbuffer_str[0] = '\0'; slen = 0; - /* read the property value into selection_str: */ + + /* read the property value into cutbuffer_str: */ do { if (XGetWindowProperty(dpy, DefaultRootWindow(dpy), XA_CUT_BUFFER0, nitems/4, PROP_MAX/16, False, @@ -172,14 +195,18 @@ void cutbuffer_send(void) { XFree(data); break; } - memcpy(selection_str+slen, data, dlen); + memcpy(cutbuffer_str+slen, data, dlen); slen += dlen; - selection_str[slen] = '\0'; + cutbuffer_str[slen] = '\0'; XFree(data); } } while (bytes_after > 0); - selection_str[PROP_MAX] = '\0'; + cutbuffer_str[PROP_MAX] = '\0'; + + if (debug_sel) { + rfbLog("cutbuffer_send: '%s'\n", cutbuffer_str); + } if (! all_clients_initialized()) { rfbLog("cutbuffer_send: no send: uninitialized clients\n"); @@ -193,9 +220,9 @@ void cutbuffer_send(void) { if (!screen) { return; } - len = strlen(selection_str); - if (check_sel_direction("send", "cutbuffer_send", selection_str, len)) { - rfbSendServerCutText(screen, selection_str, len); + len = strlen(cutbuffer_str); + if (check_sel_direction("send", "cutbuffer_send", cutbuffer_str, len)) { + rfbSendServerCutText(screen, cutbuffer_str, len); } } @@ -219,18 +246,41 @@ void selection_send(XEvent *ev) { char before[CHKSZ], after[CHKSZ]; unsigned long nitems = 0, bytes_after = 0; unsigned char* data = NULL; + char *selection_str; /* * remember info about our last value of PRIMARY (or CUT_BUFFER0) * so we can check for any changes below. */ + if (ev->xselection.selection == XA_PRIMARY) { + if (! watch_primary) { + return; + } + selection_str = primary_str; + if (debug_sel) { + rfbLog("selection_send: event PRIMARY prop: %d requestor: 0x%x atom: %d\n", + ev->xselection.property, ev->xselection.requestor, ev->xselection.selection); + } + } else if (clipboard_atom && ev->xselection.selection == clipboard_atom) { + if (! watch_clipboard) { + return; + } + selection_str = clipboard_str; + if (debug_sel) { + rfbLog("selection_send: event CLIPBOARD prop: %d requestor: 0x%x atom: %d\n", + ev->xselection.property, ev->xselection.requestor, ev->xselection.selection); + } + } else { + return; + } + oldlen = strlen(selection_str); strncpy(before, selection_str, CHKSZ); selection_str[0] = '\0'; slen = 0; - /* read in the current value of PRIMARY: */ + /* read in the current value of PRIMARY or CLIPBOARD: */ do { if (XGetWindowProperty(dpy, ev->xselection.requestor, ev->xselection.property, nitems/4, PROP_MAX/16, True, @@ -248,9 +298,11 @@ void selection_send(XEvent *ev) { err = 5; } rfbLog("warning: truncating large PRIMARY" - " selection > %d bytes.\n", PROP_MAX); + "/CLIPBOARD selection > %d bytes.\n", + PROP_MAX); break; } +if (debug_sel) fprintf(stderr, "selection_send: data: '%s' dlen: %d nitems: %d ba: %d\n", data, dlen, nitems, bytes_after); memcpy(selection_str+slen, data, dlen); slen += dlen; selection_str[slen] = '\0'; @@ -269,6 +321,11 @@ void selection_send(XEvent *ev) { oldlen = -1; sent_one = 1; } + if (debug_sel) { + rfbLog("selection_send: %s '%s'\n", + ev->xselection.selection == XA_PRIMARY ? "PRIMARY " : "CLIPBOARD", + selection_str); + } /* look for changes in the new value */ newlen = strlen(selection_str); @@ -276,6 +333,9 @@ void selection_send(XEvent *ev) { if (oldlen == newlen && strncmp(before, after, CHKSZ) == 0) { /* evidently no change */ + if (debug_sel) { + rfbLog("selection_send: no change.\n"); + } return; } if (newlen == 0) { |