You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

fltk-1_v6.3.x-clipboard-x11.patch 11KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355
  1. diff -up fltk-1.3.2/CMakeLists.txt.clp-x11 fltk-1.3.2/CMakeLists.txt
  2. --- fltk-1.3.2/CMakeLists.txt.clp-x11 2012-09-13 16:19:01.000000000 +0200
  3. +++ fltk-1.3.2/CMakeLists.txt 2013-01-30 15:56:25.810663430 +0100
  4. @@ -515,6 +515,20 @@ else()
  5. endif(OPTION_USE_XINERAMA)
  6. #######################################################################
  7. +if(X11_Xfixes_FOUND)
  8. + option(OPTION_USE_XFIXES "use lib XFIXES" ON)
  9. +endif(X11_Xfixes_FOUND)
  10. +
  11. +if(OPTION_USE_XFIXES)
  12. + set(HAVE_XFIXES ${X11_Xfixes_FOUND})
  13. + include_directories(${X11_Xfixes_INCLUDE_PATH})
  14. + list(APPEND FLTK_LDLIBS -lXfixes)
  15. + set(FLTK_XFIXES_FOUND TRUE)
  16. +else()
  17. + set(FLTK_XFIXES_FOUND FALSE)
  18. +endif(OPTION_USE_XFIXES)
  19. +
  20. +#######################################################################
  21. if(X11_Xft_FOUND)
  22. option(OPTION_USE_XFT "use lib Xft" ON)
  23. endif(X11_Xft_FOUND)
  24. diff -up fltk-1.3.2/configh.cmake.in.clp-x11 fltk-1.3.2/configh.cmake.in
  25. --- fltk-1.3.2/configh.cmake.in.clp-x11 2011-07-19 06:49:30.000000000 +0200
  26. +++ fltk-1.3.2/configh.cmake.in 2013-01-30 15:56:25.810663430 +0100
  27. @@ -108,6 +108,14 @@
  28. #define USE_XDBE HAVE_XDBE
  29. /*
  30. + * HAVE_XFIXES:
  31. + *
  32. + * Do we have the X fixes extension?
  33. + */
  34. +
  35. +#cmakedefine01 HAVE_XFIXES
  36. +
  37. +/*
  38. * __APPLE_QUARTZ__:
  39. *
  40. * If __APPLE_QUARTZ__ is defined, FLTK will be
  41. diff -up fltk-1.3.2/configh.in.clp-x11 fltk-1.3.2/configh.in
  42. --- fltk-1.3.2/configh.in.clp-x11 2011-10-04 11:21:47.000000000 +0200
  43. +++ fltk-1.3.2/configh.in 2013-01-30 15:56:25.810663430 +0100
  44. @@ -108,6 +108,14 @@
  45. #define USE_XDBE HAVE_XDBE
  46. /*
  47. + * HAVE_XFIXES:
  48. + *
  49. + * Do we have the X fixes extension?
  50. + */
  51. +
  52. +#define HAVE_XFIXES 0
  53. +
  54. +/*
  55. * __APPLE_QUARTZ__:
  56. *
  57. * All Apple implementations are now based on Quartz and Cocoa,
  58. diff -up fltk-1.3.2/configure.in.clp-x11 fltk-1.3.2/configure.in
  59. --- fltk-1.3.2/configure.in.clp-x11 2013-01-30 15:56:25.802663573 +0100
  60. +++ fltk-1.3.2/configure.in 2013-01-30 15:56:25.810663430 +0100
  61. @@ -999,6 +999,16 @@ case $uname_GUI in
  62. LIBS="-lXext $LIBS")
  63. fi
  64. + dnl Check for the Xfixes extension unless disabled...
  65. + AC_ARG_ENABLE(xfixes, [ --enable-xfixes turn on Xfixes support [default=yes]])
  66. +
  67. + if test x$enable_xfixes != xno; then
  68. + AC_CHECK_HEADER(X11/extensions/Xfixes.h, AC_DEFINE(HAVE_XFIXES),,
  69. + [#include <X11/Xlib.h>])
  70. + AC_CHECK_LIB(Xfixes, XFixesQueryExtension,
  71. + LIBS="-lXfixes $LIBS")
  72. + fi
  73. +
  74. dnl Check for overlay visuals...
  75. AC_PATH_PROG(XPROP, xprop)
  76. AC_CACHE_CHECK(for X overlay visuals, ac_cv_have_overlay,
  77. diff -up fltk-1.3.2/fluid/CMakeLists.txt.clp-x11 fltk-1.3.2/fluid/CMakeLists.txt
  78. diff -up fltk-1.3.2/src/CMakeLists.txt.clp-x11 fltk-1.3.2/src/CMakeLists.txt
  79. --- fltk-1.3.2/src/CMakeLists.txt.clp-x11 2013-01-30 16:06:00.785430590 +0100
  80. +++ fltk-1.3.2/src/CMakeLists.txt 2013-01-30 16:06:17.883126642 +0100
  81. @@ -243,6 +243,10 @@ if(HAVE_XINERAMA)
  82. target_link_libraries(fltk ${X11_Xinerama_LIB})
  83. endif(HAVE_XINERAMA)
  84. +if(HAVE_XFIXES)
  85. + target_link_libraries(fltk ${X11_Xfixes_LIB})
  86. +endif(HAVE_XFIXES)
  87. +
  88. if(USE_XFT)
  89. target_link_libraries(fltk ${X11_Xft_LIB})
  90. endif(USE_XFT)
  91. diff -up fltk-1.3.2/src/Fl_x.cxx.clp-x11 fltk-1.3.2/src/Fl_x.cxx
  92. --- fltk-1.3.2/src/Fl_x.cxx.clp-x11 2013-01-30 15:56:25.793663733 +0100
  93. +++ fltk-1.3.2/src/Fl_x.cxx 2013-01-30 16:03:37.355981103 +0100
  94. @@ -53,6 +53,12 @@ static XRRUpdateConfiguration_type XRRUp
  95. static int randrEventBase; // base of RandR-defined events
  96. #endif
  97. +# if HAVE_XFIXES
  98. +# include <X11/extensions/Xfixes.h>
  99. +static int xfixes_event_base = 0;
  100. +static bool have_xfixes = false;
  101. +# endif
  102. +
  103. static Fl_Xlib_Graphics_Driver fl_xlib_driver;
  104. static Fl_Display_Device fl_xlib_display(&fl_xlib_driver);
  105. Fl_Display_Device *Fl_Display_Device::_display = &fl_xlib_display;// the platform display
  106. @@ -307,6 +313,9 @@ static Atom WM_PROTOCOLS;
  107. static Atom fl_MOTIF_WM_HINTS;
  108. static Atom TARGETS;
  109. static Atom CLIPBOARD;
  110. +static Atom TIMESTAMP;
  111. +static Atom PRIMARY_TIMESTAMP;
  112. +static Atom CLIPBOARD_TIMESTAMP;
  113. Atom fl_XdndAware;
  114. Atom fl_XdndSelection;
  115. Atom fl_XdndEnter;
  116. @@ -667,6 +676,9 @@ void fl_open_display(Display* d) {
  117. fl_MOTIF_WM_HINTS = XInternAtom(d, "_MOTIF_WM_HINTS", 0);
  118. TARGETS = XInternAtom(d, "TARGETS", 0);
  119. CLIPBOARD = XInternAtom(d, "CLIPBOARD", 0);
  120. + TIMESTAMP = XInternAtom(d, "TIMESTAMP", 0);
  121. + PRIMARY_TIMESTAMP = XInternAtom(d, "PRIMARY_TIMESTAMP", 0);
  122. + CLIPBOARD_TIMESTAMP = XInternAtom(d, "CLIPBOARD_TIMESTAMP", 0);
  123. fl_XdndAware = XInternAtom(d, "XdndAware", 0);
  124. fl_XdndSelection = XInternAtom(d, "XdndSelection", 0);
  125. fl_XdndEnter = XInternAtom(d, "XdndEnter", 0);
  126. @@ -713,6 +725,15 @@ void fl_open_display(Display* d) {
  127. #if !USE_COLORMAP
  128. Fl::visual(FL_RGB);
  129. #endif
  130. +
  131. +#if HAVE_XFIXES
  132. + int error_base;
  133. + if (XFixesQueryExtension(fl_display, &xfixes_event_base, &error_base))
  134. + have_xfixes = true;
  135. + else
  136. + have_xfixes = false;
  137. +#endif
  138. +
  139. #if USE_XRANDR
  140. void *libxrandr_addr = dlopen("libXrandr.so.2", RTLD_LAZY);
  141. if (!libxrandr_addr) libxrandr_addr = dlopen("libXrandr.so", RTLD_LAZY);
  142. @@ -901,6 +922,107 @@ void Fl::copy(const char *stuff, int len
  143. }
  144. ////////////////////////////////////////////////////////////////
  145. +// Code for tracking clipboard changes:
  146. +
  147. +static Time primary_timestamp = -1;
  148. +static Time clipboard_timestamp = -1;
  149. +
  150. +extern bool fl_clipboard_notify_empty(void);
  151. +extern void fl_trigger_clipboard_notify(int source);
  152. +
  153. +static void poll_clipboard_owner(void) {
  154. + Window xid;
  155. +
  156. +#if HAVE_XFIXES
  157. + // No polling needed with Xfixes
  158. + if (have_xfixes)
  159. + return;
  160. +#endif
  161. +
  162. + // No one is interested, so no point polling
  163. + if (fl_clipboard_notify_empty())
  164. + return;
  165. +
  166. + // We need a window for this to work
  167. + if (!Fl::first_window())
  168. + return;
  169. + xid = fl_xid(Fl::first_window());
  170. + if (!xid)
  171. + return;
  172. +
  173. + // Request an update of the selection time for both the primary and
  174. + // clipboard selections. Magic continues when we get a SelectionNotify.
  175. + if (!fl_i_own_selection[0])
  176. + XConvertSelection(fl_display, XA_PRIMARY, TIMESTAMP, PRIMARY_TIMESTAMP,
  177. + xid, fl_event_time);
  178. + if (!fl_i_own_selection[1])
  179. + XConvertSelection(fl_display, CLIPBOARD, TIMESTAMP, CLIPBOARD_TIMESTAMP,
  180. + xid, fl_event_time);
  181. +}
  182. +
  183. +static void clipboard_timeout(void *data)
  184. +{
  185. + // No one is interested, so stop polling
  186. + if (fl_clipboard_notify_empty())
  187. + return;
  188. +
  189. + poll_clipboard_owner();
  190. +
  191. + Fl::repeat_timeout(0.5, clipboard_timeout);
  192. +}
  193. +
  194. +static void handle_clipboard_timestamp(int clipboard, Time time)
  195. +{
  196. + Time *timestamp;
  197. +
  198. + timestamp = clipboard ? &clipboard_timestamp : &primary_timestamp;
  199. +
  200. +#if HAVE_XFIXES
  201. + if (!have_xfixes)
  202. +#endif
  203. + {
  204. + // Initial scan, just store the value
  205. + if (*timestamp == (Time)-1) {
  206. + *timestamp = time;
  207. + return;
  208. + }
  209. + }
  210. +
  211. + // Same selection
  212. + if (time == *timestamp)
  213. + return;
  214. +
  215. + *timestamp = time;
  216. +
  217. + // The clipboard change is the event that caused us to request
  218. + // the clipboard data, so use that time as the latest event.
  219. + if (time > fl_event_time)
  220. + fl_event_time = time;
  221. +
  222. + // Something happened! Let's tell someone!
  223. + fl_trigger_clipboard_notify(clipboard);
  224. +}
  225. +
  226. +void fl_clipboard_notify_change() {
  227. + // Reset the timestamps if we've going idle so that you don't
  228. + // get a bogus immediate trigger next time they're activated.
  229. + if (fl_clipboard_notify_empty()) {
  230. + primary_timestamp = -1;
  231. + clipboard_timestamp = -1;
  232. + } else {
  233. +#if HAVE_XFIXES
  234. + if (!have_xfixes)
  235. +#endif
  236. + {
  237. + poll_clipboard_owner();
  238. +
  239. + if (!Fl::has_timeout(clipboard_timeout))
  240. + Fl::add_timeout(0.5, clipboard_timeout);
  241. + }
  242. + }
  243. +}
  244. +
  245. +////////////////////////////////////////////////////////////////
  246. const XEvent* fl_xevent; // the current x event
  247. ulong fl_event_time; // the last timestamp from an x event
  248. @@ -1024,7 +1141,6 @@ int fl_handle(const XEvent& thisevent)
  249. return 0;
  250. case SelectionNotify: {
  251. - if (!fl_selection_requestor) return 0;
  252. static unsigned char* buffer = 0;
  253. if (buffer) {XFree(buffer); buffer = 0;}
  254. long bytesread = 0;
  255. @@ -1040,6 +1156,19 @@ int fl_handle(const XEvent& thisevent)
  256. bytesread/4, 65536, 1, 0,
  257. &actual, &format, &count, &remaining,
  258. &portion)) break; // quit on error
  259. +
  260. + if ((fl_xevent->xselection.property == PRIMARY_TIMESTAMP) ||
  261. + (fl_xevent->xselection.property == CLIPBOARD_TIMESTAMP)) {
  262. + if (portion && format == 32 && count == 1) {
  263. + Time t = *(unsigned int*)portion;
  264. + if (fl_xevent->xselection.property == CLIPBOARD_TIMESTAMP)
  265. + handle_clipboard_timestamp(1, t);
  266. + else
  267. + handle_clipboard_timestamp(0, t);
  268. + }
  269. + return true;
  270. + }
  271. +
  272. if (actual == TARGETS || actual == XA_ATOM) {
  273. Atom type = XA_STRING;
  274. for (unsigned i = 0; i<count; i++) {
  275. @@ -1076,6 +1205,9 @@ int fl_handle(const XEvent& thisevent)
  276. buffer[bytesread] = 0;
  277. convert_crlf(buffer, bytesread);
  278. }
  279. +
  280. + if (!fl_selection_requestor) return 0;
  281. +
  282. Fl::e_text = buffer ? (char*)buffer : (char *)"";
  283. Fl::e_length = bytesread;
  284. int old_event = Fl::e_number;
  285. @@ -1096,6 +1228,7 @@ int fl_handle(const XEvent& thisevent)
  286. case SelectionClear: {
  287. int clipboard = fl_xevent->xselectionclear.selection == CLIPBOARD;
  288. fl_i_own_selection[clipboard] = 0;
  289. + poll_clipboard_owner();
  290. return 1;}
  291. case SelectionRequest: {
  292. @@ -1308,6 +1441,9 @@ int fl_handle(const XEvent& thisevent)
  293. case FocusIn:
  294. if (fl_xim_ic) XSetICFocus(fl_xim_ic);
  295. event = FL_FOCUS;
  296. + // If the user has toggled from another application to this one,
  297. + // then it's a good time to check for clipboard changes.
  298. + poll_clipboard_owner();
  299. break;
  300. case FocusOut:
  301. @@ -1676,6 +1812,25 @@ int fl_handle(const XEvent& thisevent)
  302. }
  303. }
  304. +#if HAVE_XFIXES
  305. + switch (xevent.type - xfixes_event_base) {
  306. + case XFixesSelectionNotify: {
  307. + // Someone feeding us bogus events?
  308. + if (!have_xfixes)
  309. + return true;
  310. +
  311. + XFixesSelectionNotifyEvent *selection_notify = (XFixesSelectionNotifyEvent *)&xevent;
  312. +
  313. + if ((selection_notify->selection == XA_PRIMARY) && !fl_i_own_selection[0])
  314. + handle_clipboard_timestamp(0, selection_notify->selection_timestamp);
  315. + else if ((selection_notify->selection == CLIPBOARD) && !fl_i_own_selection[1])
  316. + handle_clipboard_timestamp(1, selection_notify->selection_timestamp);
  317. +
  318. + return true;
  319. + }
  320. + }
  321. +#endif
  322. +
  323. return Fl::handle(event, window);
  324. }
  325. @@ -1995,6 +2150,16 @@ void Fl_X::make_xid(Fl_Window* win, XVis
  326. XChangeProperty(fl_display, xp->xid, net_wm_type, XA_ATOM, 32, PropModeReplace, (unsigned char*)&net_wm_type_kind, 1);
  327. }
  328. +#if HAVE_XFIXES
  329. + // register for clipboard change notifications
  330. + if (have_xfixes && !win->parent()) {
  331. + XFixesSelectSelectionInput(fl_display, xp->xid, XA_PRIMARY,
  332. + XFixesSetSelectionOwnerNotifyMask);
  333. + XFixesSelectSelectionInput(fl_display, xp->xid, CLIPBOARD,
  334. + XFixesSetSelectionOwnerNotifyMask);
  335. + }
  336. +#endif
  337. +
  338. XMapWindow(fl_display, xp->xid);
  339. if (showit) {
  340. win->set_visible();
  341. diff -up fltk-1.3.2/test/CMakeLists.txt.clp-x11 fltk-1.3.2/test/CMakeLists.txt