Mercurial > vim
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 |