summaryrefslogtreecommitdiffstats
path: root/contrib/fltk/02-str2636-fltk-1.3.x-clipboard-x11.patch
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/fltk/02-str2636-fltk-1.3.x-clipboard-x11.patch')
-rw-r--r--contrib/fltk/02-str2636-fltk-1.3.x-clipboard-x11.patch355
1 files changed, 355 insertions, 0 deletions
diff --git a/contrib/fltk/02-str2636-fltk-1.3.x-clipboard-x11.patch b/contrib/fltk/02-str2636-fltk-1.3.x-clipboard-x11.patch
new file mode 100644
index 00000000..9e253a3f
--- /dev/null
+++ b/contrib/fltk/02-str2636-fltk-1.3.x-clipboard-x11.patch
@@ -0,0 +1,355 @@
+diff -up fltk-1.3.2/CMakeLists.txt.clp-x11 fltk-1.3.2/CMakeLists.txt
+--- fltk-1.3.2/CMakeLists.txt.clp-x11 2012-09-13 16:19:01.000000000 +0200
++++ fltk-1.3.2/CMakeLists.txt 2013-01-30 15:56:25.810663430 +0100
+@@ -515,6 +515,20 @@ else()
+ endif(OPTION_USE_XINERAMA)
+
+ #######################################################################
++if(X11_Xfixes_FOUND)
++ option(OPTION_USE_XFIXES "use lib XFIXES" ON)
++endif(X11_Xfixes_FOUND)
++
++if(OPTION_USE_XFIXES)
++ set(HAVE_XFIXES ${X11_Xfixes_FOUND})
++ include_directories(${X11_Xfixes_INCLUDE_PATH})
++ list(APPEND FLTK_LDLIBS -lXfixes)
++ set(FLTK_XFIXES_FOUND TRUE)
++else()
++ set(FLTK_XFIXES_FOUND FALSE)
++endif(OPTION_USE_XFIXES)
++
++#######################################################################
+ if(X11_Xft_FOUND)
+ option(OPTION_USE_XFT "use lib Xft" ON)
+ endif(X11_Xft_FOUND)
+diff -up fltk-1.3.2/configh.cmake.in.clp-x11 fltk-1.3.2/configh.cmake.in
+--- fltk-1.3.2/configh.cmake.in.clp-x11 2011-07-19 06:49:30.000000000 +0200
++++ fltk-1.3.2/configh.cmake.in 2013-01-30 15:56:25.810663430 +0100
+@@ -108,6 +108,14 @@
+ #define USE_XDBE HAVE_XDBE
+
+ /*
++ * HAVE_XFIXES:
++ *
++ * Do we have the X fixes extension?
++ */
++
++#cmakedefine01 HAVE_XFIXES
++
++/*
+ * __APPLE_QUARTZ__:
+ *
+ * If __APPLE_QUARTZ__ is defined, FLTK will be
+diff -up fltk-1.3.2/configh.in.clp-x11 fltk-1.3.2/configh.in
+--- fltk-1.3.2/configh.in.clp-x11 2011-10-04 11:21:47.000000000 +0200
++++ fltk-1.3.2/configh.in 2013-01-30 15:56:25.810663430 +0100
+@@ -108,6 +108,14 @@
+ #define USE_XDBE HAVE_XDBE
+
+ /*
++ * HAVE_XFIXES:
++ *
++ * Do we have the X fixes extension?
++ */
++
++#define HAVE_XFIXES 0
++
++/*
+ * __APPLE_QUARTZ__:
+ *
+ * All Apple implementations are now based on Quartz and Cocoa,
+diff -up fltk-1.3.2/configure.in.clp-x11 fltk-1.3.2/configure.in
+--- fltk-1.3.2/configure.in.clp-x11 2013-01-30 15:56:25.802663573 +0100
++++ fltk-1.3.2/configure.in 2013-01-30 15:56:25.810663430 +0100
+@@ -999,6 +999,16 @@ case $uname_GUI in
+ LIBS="-lXext $LIBS")
+ fi
+
++ dnl Check for the Xfixes extension unless disabled...
++ AC_ARG_ENABLE(xfixes, [ --enable-xfixes turn on Xfixes support [default=yes]])
++
++ if test x$enable_xfixes != xno; then
++ AC_CHECK_HEADER(X11/extensions/Xfixes.h, AC_DEFINE(HAVE_XFIXES),,
++ [#include <X11/Xlib.h>])
++ AC_CHECK_LIB(Xfixes, XFixesQueryExtension,
++ LIBS="-lXfixes $LIBS")
++ fi
++
+ dnl Check for overlay visuals...
+ AC_PATH_PROG(XPROP, xprop)
+ AC_CACHE_CHECK(for X overlay visuals, ac_cv_have_overlay,
+diff -up fltk-1.3.2/fluid/CMakeLists.txt.clp-x11 fltk-1.3.2/fluid/CMakeLists.txt
+diff -up fltk-1.3.2/src/CMakeLists.txt.clp-x11 fltk-1.3.2/src/CMakeLists.txt
+--- fltk-1.3.2/src/CMakeLists.txt.clp-x11 2013-01-30 16:06:00.785430590 +0100
++++ fltk-1.3.2/src/CMakeLists.txt 2013-01-30 16:06:17.883126642 +0100
+@@ -243,6 +243,10 @@ if(HAVE_XINERAMA)
+ target_link_libraries(fltk ${X11_Xinerama_LIB})
+ endif(HAVE_XINERAMA)
+
++if(HAVE_XFIXES)
++ target_link_libraries(fltk ${X11_Xfixes_LIB})
++endif(HAVE_XFIXES)
++
+ if(USE_XFT)
+ target_link_libraries(fltk ${X11_Xft_LIB})
+ endif(USE_XFT)
+diff -up fltk-1.3.2/src/Fl_x.cxx.clp-x11 fltk-1.3.2/src/Fl_x.cxx
+--- fltk-1.3.2/src/Fl_x.cxx.clp-x11 2013-01-30 15:56:25.793663733 +0100
++++ fltk-1.3.2/src/Fl_x.cxx 2013-01-30 16:03:37.355981103 +0100
+@@ -53,6 +53,12 @@ static XRRUpdateConfiguration_type XRRUp
+ static int randrEventBase; // base of RandR-defined events
+ #endif
+
++# if HAVE_XFIXES
++# include <X11/extensions/Xfixes.h>
++static int xfixes_event_base = 0;
++static bool have_xfixes = false;
++# endif
++
+ static Fl_Xlib_Graphics_Driver fl_xlib_driver;
+ static Fl_Display_Device fl_xlib_display(&fl_xlib_driver);
+ Fl_Display_Device *Fl_Display_Device::_display = &fl_xlib_display;// the platform display
+@@ -307,6 +313,9 @@ static Atom WM_PROTOCOLS;
+ static Atom fl_MOTIF_WM_HINTS;
+ static Atom TARGETS;
+ static Atom CLIPBOARD;
++static Atom TIMESTAMP;
++static Atom PRIMARY_TIMESTAMP;
++static Atom CLIPBOARD_TIMESTAMP;
+ Atom fl_XdndAware;
+ Atom fl_XdndSelection;
+ Atom fl_XdndEnter;
+@@ -667,6 +676,9 @@ void fl_open_display(Display* d) {
+ fl_MOTIF_WM_HINTS = XInternAtom(d, "_MOTIF_WM_HINTS", 0);
+ TARGETS = XInternAtom(d, "TARGETS", 0);
+ CLIPBOARD = XInternAtom(d, "CLIPBOARD", 0);
++ TIMESTAMP = XInternAtom(d, "TIMESTAMP", 0);
++ PRIMARY_TIMESTAMP = XInternAtom(d, "PRIMARY_TIMESTAMP", 0);
++ CLIPBOARD_TIMESTAMP = XInternAtom(d, "CLIPBOARD_TIMESTAMP", 0);
+ fl_XdndAware = XInternAtom(d, "XdndAware", 0);
+ fl_XdndSelection = XInternAtom(d, "XdndSelection", 0);
+ fl_XdndEnter = XInternAtom(d, "XdndEnter", 0);
+@@ -713,6 +725,15 @@ void fl_open_display(Display* d) {
+ #if !USE_COLORMAP
+ Fl::visual(FL_RGB);
+ #endif
++
++#if HAVE_XFIXES
++ int error_base;
++ if (XFixesQueryExtension(fl_display, &xfixes_event_base, &error_base))
++ have_xfixes = true;
++ else
++ have_xfixes = false;
++#endif
++
+ #if USE_XRANDR
+ void *libxrandr_addr = dlopen("libXrandr.so.2", RTLD_LAZY);
+ if (!libxrandr_addr) libxrandr_addr = dlopen("libXrandr.so", RTLD_LAZY);
+@@ -901,6 +922,107 @@ void Fl::copy(const char *stuff, int len
+ }
+
+ ////////////////////////////////////////////////////////////////
++// Code for tracking clipboard changes:
++
++static Time primary_timestamp = -1;
++static Time clipboard_timestamp = -1;
++
++extern bool fl_clipboard_notify_empty(void);
++extern void fl_trigger_clipboard_notify(int source);
++
++static void poll_clipboard_owner(void) {
++ Window xid;
++
++#if HAVE_XFIXES
++ // No polling needed with Xfixes
++ if (have_xfixes)
++ return;
++#endif
++
++ // No one is interested, so no point polling
++ if (fl_clipboard_notify_empty())
++ return;
++
++ // We need a window for this to work
++ if (!Fl::first_window())
++ return;
++ xid = fl_xid(Fl::first_window());
++ if (!xid)
++ return;
++
++ // Request an update of the selection time for both the primary and
++ // clipboard selections. Magic continues when we get a SelectionNotify.
++ if (!fl_i_own_selection[0])
++ XConvertSelection(fl_display, XA_PRIMARY, TIMESTAMP, PRIMARY_TIMESTAMP,
++ xid, fl_event_time);
++ if (!fl_i_own_selection[1])
++ XConvertSelection(fl_display, CLIPBOARD, TIMESTAMP, CLIPBOARD_TIMESTAMP,
++ xid, fl_event_time);
++}
++
++static void clipboard_timeout(void *data)
++{
++ // No one is interested, so stop polling
++ if (fl_clipboard_notify_empty())
++ return;
++
++ poll_clipboard_owner();
++
++ Fl::repeat_timeout(0.5, clipboard_timeout);
++}
++
++static void handle_clipboard_timestamp(int clipboard, Time time)
++{
++ Time *timestamp;
++
++ timestamp = clipboard ? &clipboard_timestamp : &primary_timestamp;
++
++#if HAVE_XFIXES
++ if (!have_xfixes)
++#endif
++ {
++ // Initial scan, just store the value
++ if (*timestamp == (Time)-1) {
++ *timestamp = time;
++ return;
++ }
++ }
++
++ // Same selection
++ if (time == *timestamp)
++ return;
++
++ *timestamp = time;
++
++ // The clipboard change is the event that caused us to request
++ // the clipboard data, so use that time as the latest event.
++ if (time > fl_event_time)
++ fl_event_time = time;
++
++ // Something happened! Let's tell someone!
++ fl_trigger_clipboard_notify(clipboard);
++}
++
++void fl_clipboard_notify_change() {
++ // Reset the timestamps if we've going idle so that you don't
++ // get a bogus immediate trigger next time they're activated.
++ if (fl_clipboard_notify_empty()) {
++ primary_timestamp = -1;
++ clipboard_timestamp = -1;
++ } else {
++#if HAVE_XFIXES
++ if (!have_xfixes)
++#endif
++ {
++ poll_clipboard_owner();
++
++ if (!Fl::has_timeout(clipboard_timeout))
++ Fl::add_timeout(0.5, clipboard_timeout);
++ }
++ }
++}
++
++////////////////////////////////////////////////////////////////
+
+ const XEvent* fl_xevent; // the current x event
+ ulong fl_event_time; // the last timestamp from an x event
+@@ -1024,7 +1141,6 @@ int fl_handle(const XEvent& thisevent)
+ return 0;
+
+ case SelectionNotify: {
+- if (!fl_selection_requestor) return 0;
+ static unsigned char* buffer = 0;
+ if (buffer) {XFree(buffer); buffer = 0;}
+ long bytesread = 0;
+@@ -1040,6 +1156,19 @@ int fl_handle(const XEvent& thisevent)
+ bytesread/4, 65536, 1, 0,
+ &actual, &format, &count, &remaining,
+ &portion)) break; // quit on error
++
++ if ((fl_xevent->xselection.property == PRIMARY_TIMESTAMP) ||
++ (fl_xevent->xselection.property == CLIPBOARD_TIMESTAMP)) {
++ if (portion && format == 32 && count == 1) {
++ Time t = *(unsigned int*)portion;
++ if (fl_xevent->xselection.property == CLIPBOARD_TIMESTAMP)
++ handle_clipboard_timestamp(1, t);
++ else
++ handle_clipboard_timestamp(0, t);
++ }
++ return true;
++ }
++
+ if (actual == TARGETS || actual == XA_ATOM) {
+ Atom type = XA_STRING;
+ for (unsigned i = 0; i<count; i++) {
+@@ -1076,6 +1205,9 @@ int fl_handle(const XEvent& thisevent)
+ buffer[bytesread] = 0;
+ convert_crlf(buffer, bytesread);
+ }
++
++ if (!fl_selection_requestor) return 0;
++
+ Fl::e_text = buffer ? (char*)buffer : (char *)"";
+ Fl::e_length = bytesread;
+ int old_event = Fl::e_number;
+@@ -1096,6 +1228,7 @@ int fl_handle(const XEvent& thisevent)
+ case SelectionClear: {
+ int clipboard = fl_xevent->xselectionclear.selection == CLIPBOARD;
+ fl_i_own_selection[clipboard] = 0;
++ poll_clipboard_owner();
+ return 1;}
+
+ case SelectionRequest: {
+@@ -1308,6 +1441,9 @@ int fl_handle(const XEvent& thisevent)
+ case FocusIn:
+ if (fl_xim_ic) XSetICFocus(fl_xim_ic);
+ event = FL_FOCUS;
++ // If the user has toggled from another application to this one,
++ // then it's a good time to check for clipboard changes.
++ poll_clipboard_owner();
+ break;
+
+ case FocusOut:
+@@ -1676,6 +1812,25 @@ int fl_handle(const XEvent& thisevent)
+ }
+ }
+
++#if HAVE_XFIXES
++ switch (xevent.type - xfixes_event_base) {
++ case XFixesSelectionNotify: {
++ // Someone feeding us bogus events?
++ if (!have_xfixes)
++ return true;
++
++ XFixesSelectionNotifyEvent *selection_notify = (XFixesSelectionNotifyEvent *)&xevent;
++
++ if ((selection_notify->selection == XA_PRIMARY) && !fl_i_own_selection[0])
++ handle_clipboard_timestamp(0, selection_notify->selection_timestamp);
++ else if ((selection_notify->selection == CLIPBOARD) && !fl_i_own_selection[1])
++ handle_clipboard_timestamp(1, selection_notify->selection_timestamp);
++
++ return true;
++ }
++ }
++#endif
++
+ return Fl::handle(event, window);
+ }
+
+@@ -1995,6 +2150,16 @@ void Fl_X::make_xid(Fl_Window* win, XVis
+ XChangeProperty(fl_display, xp->xid, net_wm_type, XA_ATOM, 32, PropModeReplace, (unsigned char*)&net_wm_type_kind, 1);
+ }
+
++#if HAVE_XFIXES
++ // register for clipboard change notifications
++ if (have_xfixes && !win->parent()) {
++ XFixesSelectSelectionInput(fl_display, xp->xid, XA_PRIMARY,
++ XFixesSetSelectionOwnerNotifyMask);
++ XFixesSelectSelectionInput(fl_display, xp->xid, CLIPBOARD,
++ XFixesSetSelectionOwnerNotifyMask);
++ }
++#endif
++
+ XMapWindow(fl_display, xp->xid);
+ if (showit) {
+ win->set_visible();
+diff -up fltk-1.3.2/test/CMakeLists.txt.clp-x11 fltk-1.3.2/test/CMakeLists.txt