comparison src/ui.c @ 2270:917fff7bc09d vim73

Fixes for time in clipboard request. Also fix ownership. (David Fries)
author Bram Moolenaar <bram@vim.org>
date Tue, 22 Jun 2010 06:07:12 +0200
parents 1bac28a53fae
children ccda151dde4e
comparison
equal deleted inserted replaced
2269:fb627e94e6c6 2270:917fff7bc09d
465 { 465 {
466 /* 466 /*
467 * Also want to check somehow that we are reading from the keyboard rather 467 * Also want to check somehow that we are reading from the keyboard rather
468 * than a mapping etc. 468 * than a mapping etc.
469 */ 469 */
470 if (!cbd->owned && cbd->available) 470 #ifdef FEAT_X11
471 { 471 /* Always own the selection, we might have lost it without being
472 * notified. */
473 if (cbd->available)
474 {
475 int was_owned = cbd->owned;
476
472 cbd->owned = (clip_gen_own_selection(cbd) == OK); 477 cbd->owned = (clip_gen_own_selection(cbd) == OK);
473 #ifdef FEAT_X11 478 if (!was_owned && cbd == &clip_star)
474 if (cbd == &clip_star)
475 { 479 {
476 /* May have to show a different kind of highlighting for the 480 /* May have to show a different kind of highlighting for the
477 * selected area. There is no specific redraw command for this, 481 * selected area. There is no specific redraw command for this,
478 * just redraw all windows on the current buffer. */ 482 * just redraw all windows on the current buffer. */
479 if (cbd->owned 483 if (cbd->owned
481 || get_real_state() == SELECTMODE) 485 || get_real_state() == SELECTMODE)
482 && clip_isautosel() 486 && clip_isautosel()
483 && hl_attr(HLF_V) != hl_attr(HLF_VNC)) 487 && hl_attr(HLF_V) != hl_attr(HLF_VNC))
484 redraw_curbuf_later(INVERTED_ALL); 488 redraw_curbuf_later(INVERTED_ALL);
485 } 489 }
486 #endif 490 }
487 } 491 #else
492 /* Only own the clibpard when we didn't own it yet. */
493 if (!cbd->owned && cbd->available)
494 cbd->owned = (clip_gen_own_selection(cbd) == OK);
495 #endif
488 } 496 }
489 497
490 void 498 void
491 clip_lose_selection(cbd) 499 clip_lose_selection(cbd)
492 VimClipboard *cbd; 500 VimClipboard *cbd;
1965 static Atom vimenc_atom; /* Vim's extended selection format */ 1973 static Atom vimenc_atom; /* Vim's extended selection format */
1966 #endif 1974 #endif
1967 static Atom compound_text_atom; 1975 static Atom compound_text_atom;
1968 static Atom text_atom; 1976 static Atom text_atom;
1969 static Atom targets_atom; 1977 static Atom targets_atom;
1978 static Atom timestamp_atom; /* Used to get a timestamp */
1970 1979
1971 void 1980 void
1972 x11_setup_atoms(dpy) 1981 x11_setup_atoms(dpy)
1973 Display *dpy; 1982 Display *dpy;
1974 { 1983 {
1976 #ifdef FEAT_MBYTE 1985 #ifdef FEAT_MBYTE
1977 vimenc_atom = XInternAtom(dpy, VIMENC_ATOM_NAME,False); 1986 vimenc_atom = XInternAtom(dpy, VIMENC_ATOM_NAME,False);
1978 #endif 1987 #endif
1979 compound_text_atom = XInternAtom(dpy, "COMPOUND_TEXT", False); 1988 compound_text_atom = XInternAtom(dpy, "COMPOUND_TEXT", False);
1980 text_atom = XInternAtom(dpy, "TEXT", False); 1989 text_atom = XInternAtom(dpy, "TEXT", False);
1981 targets_atom = XInternAtom(dpy, "TARGETS", False); 1990 targets_atom = XInternAtom(dpy, "TARGETS", False);
1982 clip_star.sel_atom = XA_PRIMARY; 1991 clip_star.sel_atom = XA_PRIMARY;
1983 clip_plus.sel_atom = XInternAtom(dpy, "CLIPBOARD", False); 1992 clip_plus.sel_atom = XInternAtom(dpy, "CLIPBOARD", False);
1993 timestamp_atom = XInternAtom(dpy, "TIMESTAMP", False);
1984 } 1994 }
1985 1995
1986 /* 1996 /*
1987 * X Selection stuff, for cutting and pasting text to other windows. 1997 * X Selection stuff, for cutting and pasting text to other windows.
1988 */ 1998 */
1999
2000 static Boolean clip_x11_convert_selection_cb __ARGS((Widget, Atom *, Atom *, Atom *, XtPointer *, long_u *, int *));
2001
2002 static void clip_x11_lose_ownership_cb __ARGS((Widget, Atom *));
2003
2004 static void clip_x11_timestamp_cb __ARGS((Widget w, XtPointer n, XEvent *event, Boolean *cont));
2005
2006 /*
2007 * Property callback to get a timestamp for XtOwnSelection.
2008 */
2009 static void
2010 clip_x11_timestamp_cb(w, n, event, cont)
2011 Widget w;
2012 XtPointer n UNUSED;
2013 XEvent *event;
2014 Boolean *cont UNUSED;
2015 {
2016 Atom actual_type;
2017 int format;
2018 unsigned long nitems, bytes_after;
2019 unsigned char *prop=NULL;
2020 XPropertyEvent *xproperty=&event->xproperty;
2021
2022 /* Must be a property notify, state can't be Delete (True), has to be
2023 * one of the supported selection types. */
2024 if (event->type != PropertyNotify || xproperty->state
2025 || (xproperty->atom != clip_star.sel_atom
2026 && xproperty->atom != clip_plus.sel_atom))
2027 return;
2028
2029 if (XGetWindowProperty(xproperty->display, xproperty->window,
2030 xproperty->atom, 0, 0, False, timestamp_atom, &actual_type, &format,
2031 &nitems, &bytes_after, &prop))
2032 return;
2033
2034 if (prop)
2035 XFree(prop);
2036
2037 /* Make sure the property type is "TIMESTAMP" and it's 32 bits. */
2038 if (actual_type != timestamp_atom || format != 32)
2039 return;
2040
2041 /* Get the selection, using the event timestamp. */
2042 XtOwnSelection(w, xproperty->atom, xproperty->time,
2043 clip_x11_convert_selection_cb, clip_x11_lose_ownership_cb, NULL);
2044 }
2045
2046 void
2047 x11_setup_selection(w)
2048 Widget w;
2049 {
2050 XtAddEventHandler(w, PropertyChangeMask, False,
2051 /*(XtEventHandler)*/clip_x11_timestamp_cb, (XtPointer)NULL);
2052 }
1989 2053
1990 static void clip_x11_request_selection_cb __ARGS((Widget, XtPointer, Atom *, Atom *, XtPointer, long_u *, int *)); 2054 static void clip_x11_request_selection_cb __ARGS((Widget, XtPointer, Atom *, Atom *, XtPointer, long_u *, int *));
1991 2055
1992 static void 2056 static void
1993 clip_x11_request_selection_cb(w, success, sel_atom, type, value, length, 2057 clip_x11_request_selection_cb(w, success, sel_atom, type, value, length,
2184 2248
2185 /* Final fallback position - use the X CUT_BUFFER0 store */ 2249 /* Final fallback position - use the X CUT_BUFFER0 store */
2186 yank_cut_buffer0(dpy, cbd); 2250 yank_cut_buffer0(dpy, cbd);
2187 } 2251 }
2188 2252
2189 static Boolean clip_x11_convert_selection_cb __ARGS((Widget, Atom *, Atom *, Atom *, XtPointer *, long_u *, int *));
2190
2191 static Boolean 2253 static Boolean
2192 clip_x11_convert_selection_cb(w, sel_atom, target, type, value, length, format) 2254 clip_x11_convert_selection_cb(w, sel_atom, target, type, value, length, format)
2193 Widget w UNUSED; 2255 Widget w UNUSED;
2194 Atom *sel_atom; 2256 Atom *sel_atom;
2195 Atom *target; 2257 Atom *target;
2313 *format = 8; /* 8 bits per char */ 2375 *format = 8; /* 8 bits per char */
2314 vim_free(string); 2376 vim_free(string);
2315 return True; 2377 return True;
2316 } 2378 }
2317 2379
2318 static void clip_x11_lose_ownership_cb __ARGS((Widget, Atom *));
2319
2320 static void 2380 static void
2321 clip_x11_lose_ownership_cb(w, sel_atom) 2381 clip_x11_lose_ownership_cb(w, sel_atom)
2322 Widget w UNUSED; 2382 Widget w UNUSED;
2323 Atom *sel_atom; 2383 Atom *sel_atom;
2324 { 2384 {
2339 int 2399 int
2340 clip_x11_own_selection(myShell, cbd) 2400 clip_x11_own_selection(myShell, cbd)
2341 Widget myShell; 2401 Widget myShell;
2342 VimClipboard *cbd; 2402 VimClipboard *cbd;
2343 { 2403 {
2344 if (XtOwnSelection(myShell, cbd->sel_atom, CurrentTime, 2404 /* Get the time by a zero-length append, clip_x11_timestamp_cb will be
2345 clip_x11_convert_selection_cb, clip_x11_lose_ownership_cb, 2405 * called with the current timestamp. */
2346 NULL) == False) 2406 if (!XChangeProperty(XtDisplay(myShell), XtWindow(myShell), cbd->sel_atom,
2407 timestamp_atom, 32, PropModeAppend, NULL, 0))
2347 return FAIL; 2408 return FAIL;
2409 /* Flush is required in a terminal as nothing else is doing it. */
2410 XFlush(XtDisplay(myShell));
2348 return OK; 2411 return OK;
2349 } 2412 }
2350 2413
2351 /* 2414 /*
2352 * Send the current selection to the clipboard. Do nothing for X because we 2415 * Send the current selection to the clipboard. Do nothing for X because we