DO NOT REPLY TO THIS MESSAGE.  INSTEAD, POST ANY RESPONSES TO THE LINK BELOW.

[STR New]

Link: http://www.fltk.org/str.php?L2636
Version: 1.4-feature


Attached file "fltk-1_v4.3.x-clipboard-x11.patch"...


Link: http://www.fltk.org/str.php?L2636
Version: 1.4-feature
diff -urp fltk-1.3.2.org/CMakeLists.txt fltk-1.3.2/CMakeLists.txt
--- fltk-1.3.2.org/CMakeLists.txt       2012-09-13 16:19:01.000000000 +0200
+++ fltk-1.3.2/CMakeLists.txt   2013-01-21 15:04:20.808353056 +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 -urp fltk-1.3.2.org/configh.cmake.in fltk-1.3.2/configh.cmake.in
--- fltk-1.3.2.org/configh.cmake.in     2011-07-19 06:49:30.000000000 +0200
+++ fltk-1.3.2/configh.cmake.in 2013-01-21 15:04:20.809352676 +0100
@@ -108,6 +108,22 @@
 #define USE_XDBE HAVE_XDBE
 
 /*
+ * HAVE_XFIXES:
+ *
+ * Do we have the X fixes extension?
+ */
+
+#define HAVE_XFIXES 0
+
+/*
+ * HAVE_XCURSOR:
+ *
+ * Do we have the X cursor library?
+ */
+
+#define HAVE_XCURSOR 0
+
+/*
  * __APPLE_QUARTZ__:
  *
  * If __APPLE_QUARTZ__ is defined, FLTK will be
diff -urp fltk-1.3.2.org/configh.in fltk-1.3.2/configh.in
--- fltk-1.3.2.org/configh.in   2011-10-04 11:21:47.000000000 +0200
+++ fltk-1.3.2/configh.in       2013-01-21 15:03:47.557352862 +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 -urp fltk-1.3.2.org/configure.in fltk-1.3.2/configure.in
--- fltk-1.3.2.org/configure.in 2013-01-21 15:03:47.486103076 +0100
+++ fltk-1.3.2/configure.in     2013-01-21 15:03:47.558353440 +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 -urp fltk-1.3.2.org/fluid/CMakeLists.txt fltk-1.3.2/fluid/CMakeLists.txt
--- fltk-1.3.2.org/fluid/CMakeLists.txt 2011-01-06 11:24:58.000000000 +0100
+++ fltk-1.3.2/fluid/CMakeLists.txt     2013-01-21 15:04:20.809352676 +0100
@@ -42,6 +42,10 @@ if(HAVE_XINERAMA)
    target_link_libraries(fluid ${X11_Xinerama_LIB})
 endif(HAVE_XINERAMA)
 
+if(HAVE_XFIXES)
+   target_link_libraries(fluid ${X11_Xfixes_LIB})
+endif(HAVE_XFIXES)
+
 install(TARGETS fluid
    EXPORT fltk-install
    DESTINATION ${PREFIX_BIN}
diff -urp fltk-1.3.2.org/src/Fl_x.cxx fltk-1.3.2/src/Fl_x.cxx
--- fltk-1.3.2.org/src/Fl_x.cxx 2013-01-21 15:03:47.481103255 +0100
+++ fltk-1.3.2/src/Fl_x.cxx     2013-01-21 15:03:47.559355892 +0100
@@ -53,6 +53,12 @@ static XRRUpdateConfiguration_type XRRUp
 static int randrEventBase;                  // base of RandR-defined events
 #endif
 
+#  ifdef 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
+
+#ifdef 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,94 @@ 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;
+
+  // No polling needed with Xfixes
+  if (have_xfixes)
+    return;
+
+  // 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) {
+    // Initial scan, just store the value
+    if (*timestamp == (Time)-1) {
+      *timestamp = time;
+      return;
+    }
+  }
+
+  // Same selection
+  if (time == *timestamp)
+    return;
+
+  *timestamp = 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) {
+      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 +1133,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 +1148,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 +1197,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 +1220,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 +1433,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 +1804,25 @@ int fl_handle(const XEvent& thisevent)
     }
   }
 
+#ifdef 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 +2142,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);
   }
 
+#ifdef 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 -urp fltk-1.3.2.org/test/CMakeLists.txt fltk-1.3.2/test/CMakeLists.txt
--- fltk-1.3.2.org/test/CMakeLists.txt  2011-01-06 11:24:58.000000000 +0100
+++ fltk-1.3.2/test/CMakeLists.txt      2013-01-21 15:04:20.808353056 +0100
@@ -45,6 +45,10 @@ macro(CREATE_EXAMPLE NAME SOURCES LIBRAR
       target_link_libraries(${NAME} ${X11_Xinerama_LIB})
    endif(HAVE_XINERAMA)
 
+   if(HAVE_XFIXES)
+      target_link_libraries(${NAME} ${X11_Xfixes_LIB})
+   endif(HAVE_XFIXES)
+
    install(TARGETS ${NAME}
       DESTINATION ${PREFIX_DOC}/examples
       )
_______________________________________________
fltk-dev mailing list
fltk-dev@easysw.com
http://lists.easysw.com/mailman/listinfo/fltk-dev

Reply via email to