Initial commit
This commit is contained in:
106
contrib/fltk/01-str2636-fltk-1.3.x-clipboard.patch
Normal file
106
contrib/fltk/01-str2636-fltk-1.3.x-clipboard.patch
Normal file
@@ -0,0 +1,106 @@
|
||||
diff -up fltk-1.3.x-r8659/FL/Fl.H.orig fltk-1.3.x-r8659/FL/Fl.H
|
||||
--- fltk-1.3.x-r8659/FL/Fl.H.orig 2011-05-17 16:25:56.671744548 +0200
|
||||
+++ fltk-1.3.x-r8659/FL/Fl.H 2011-05-17 16:26:05.709101536 +0200
|
||||
@@ -108,6 +108,9 @@ typedef int (*Fl_Args_Handler)(int argc,
|
||||
\see Fl::event_dispatch(Fl_Event_Dispatch) */
|
||||
typedef int (*Fl_Event_Dispatch)(int event, Fl_Window *w);
|
||||
|
||||
+/** Signature of add_clipboard_notify functions passed as parameters */
|
||||
+typedef void (*Fl_Clipboard_Notify_Handler)(int source, void *data);
|
||||
+
|
||||
/** @} */ /* group callback_functions */
|
||||
|
||||
|
||||
@@ -744,6 +747,19 @@ public:
|
||||
*/
|
||||
static void paste(Fl_Widget &receiver, int source /*=0*/); // platform dependent
|
||||
/**
|
||||
+ FLTK will call the registered callback whenever there is a change to the
|
||||
+ selection buffer or the clipboard. The source argument indicates which
|
||||
+ of the two has changed. Only changes by other applications are reported.
|
||||
+ \note Some systems require polling to monitor the clipboard and may
|
||||
+ therefore have some delay in detecting changes.
|
||||
+ */
|
||||
+ static void add_clipboard_notify(Fl_Clipboard_Notify_Handler h, void *data);
|
||||
+ /**
|
||||
+ Stop calling the specified callback when there are changes to the selection
|
||||
+ buffer or the clipboard.
|
||||
+ */
|
||||
+ static void remove_clipboard_notify(Fl_Clipboard_Notify_Handler h);
|
||||
+ /**
|
||||
Initiate a Drag And Drop operation. The selection buffer should be
|
||||
filled with relevant data before calling this method. FLTK will
|
||||
then initiate the system wide drag and drop handling. Dropped data
|
||||
diff -up fltk-1.3.x-r8659/src/Fl.cxx.orig fltk-1.3.x-r8659/src/Fl.cxx
|
||||
--- fltk-1.3.x-r8659/src/Fl.cxx.orig 2011-05-18 15:20:26.667291459 +0200
|
||||
+++ fltk-1.3.x-r8659/src/Fl.cxx 2011-05-18 16:31:15.522026086 +0200
|
||||
@@ -430,6 +430,69 @@ static char in_idle;
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
+// Clipboard notifications
|
||||
+
|
||||
+struct Clipboard_Notify {
|
||||
+ Fl_Clipboard_Notify_Handler handler;
|
||||
+ void *data;
|
||||
+ struct Clipboard_Notify *next;
|
||||
+};
|
||||
+
|
||||
+static struct Clipboard_Notify *clip_notify_list = NULL;
|
||||
+
|
||||
+extern void fl_clipboard_notify_change(); // in Fl_<platform>.cxx
|
||||
+
|
||||
+void Fl::add_clipboard_notify(Fl_Clipboard_Notify_Handler h, void *data) {
|
||||
+ struct Clipboard_Notify *node;
|
||||
+
|
||||
+ remove_clipboard_notify(h);
|
||||
+
|
||||
+ node = new Clipboard_Notify;
|
||||
+
|
||||
+ node->handler = h;
|
||||
+ node->data = data;
|
||||
+ node->next = clip_notify_list;
|
||||
+
|
||||
+ clip_notify_list = node;
|
||||
+
|
||||
+ fl_clipboard_notify_change();
|
||||
+}
|
||||
+
|
||||
+void Fl::remove_clipboard_notify(Fl_Clipboard_Notify_Handler h) {
|
||||
+ struct Clipboard_Notify *node, **prev;
|
||||
+
|
||||
+ node = clip_notify_list;
|
||||
+ prev = &clip_notify_list;
|
||||
+ while (node != NULL) {
|
||||
+ if (node->handler == h) {
|
||||
+ *prev = node->next;
|
||||
+ delete node;
|
||||
+
|
||||
+ fl_clipboard_notify_change();
|
||||
+
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ prev = &node->next;
|
||||
+ node = node->next;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+bool fl_clipboard_notify_empty(void) {
|
||||
+ return clip_notify_list == NULL;
|
||||
+}
|
||||
+
|
||||
+void fl_trigger_clipboard_notify(int source) {
|
||||
+ struct Clipboard_Notify *node;
|
||||
+
|
||||
+ node = clip_notify_list;
|
||||
+ while (node != NULL) {
|
||||
+ node->handler(source, node->data);
|
||||
+ node = node->next;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+////////////////////////////////////////////////////////////////
|
||||
// wait/run/check/ready:
|
||||
|
||||
void (*Fl::idle)(); // see Fl::add_idle.cxx for the add/remove functions
|
||||
355
contrib/fltk/02-str2636-fltk-1.3.x-clipboard-x11.patch
Normal file
355
contrib/fltk/02-str2636-fltk-1.3.x-clipboard-x11.patch
Normal file
@@ -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
|
||||
135
contrib/fltk/03-str2636-fltk-1.3.x-clipboard-win32-fix.patch
Normal file
135
contrib/fltk/03-str2636-fltk-1.3.x-clipboard-win32-fix.patch
Normal file
@@ -0,0 +1,135 @@
|
||||
diff -ur fltk-1.3.0r9110.org/src/Fl_win32.cxx fltk-1.3.0r9110/src/Fl_win32.cxx
|
||||
--- fltk-1.3.0r9110.org/src/Fl_win32.cxx 2012-06-17 19:42:02.169422400 +0200
|
||||
+++ fltk-1.3.0r9110/src/Fl_win32.cxx 2012-06-17 19:43:38.286031455 +0200
|
||||
@@ -543,6 +543,37 @@
|
||||
const char* GetValue() const { return(out); }
|
||||
};
|
||||
|
||||
+void fl_update_clipboard(void) {
|
||||
+ Fl_Window *w1 = Fl::first_window();
|
||||
+ if (!w1)
|
||||
+ return;
|
||||
+
|
||||
+ HWND hwnd = fl_xid(w1);
|
||||
+
|
||||
+ if (!OpenClipboard(hwnd))
|
||||
+ return;
|
||||
+
|
||||
+ EmptyClipboard();
|
||||
+
|
||||
+ int utf16_len = fl_utf8toUtf16(fl_selection_buffer[1],
|
||||
+ fl_selection_length[1], 0, 0);
|
||||
+
|
||||
+ HGLOBAL hMem = GlobalAlloc(GHND, utf16_len * 2 + 2); // moveable and zero'ed mem alloc.
|
||||
+ LPVOID memLock = GlobalLock(hMem);
|
||||
+
|
||||
+ fl_utf8toUtf16(fl_selection_buffer[1], fl_selection_length[1],
|
||||
+ (unsigned short*) memLock, utf16_len + 1);
|
||||
+
|
||||
+ GlobalUnlock(hMem);
|
||||
+ SetClipboardData(CF_UNICODETEXT, hMem);
|
||||
+
|
||||
+ CloseClipboard();
|
||||
+
|
||||
+ // In case Windows managed to lob of a WM_DESTROYCLIPBOARD during
|
||||
+ // the above.
|
||||
+ fl_i_own_selection[1] = 1;
|
||||
+}
|
||||
+
|
||||
// call this when you create a selection:
|
||||
void Fl::copy(const char *stuff, int len, int clipboard) {
|
||||
if (!stuff || len<0) return;
|
||||
@@ -560,25 +591,9 @@
|
||||
memcpy(fl_selection_buffer[clipboard], stuff, len);
|
||||
fl_selection_buffer[clipboard][len] = 0; // needed for direct paste
|
||||
fl_selection_length[clipboard] = len;
|
||||
- if (clipboard) {
|
||||
- // set up for "delayed rendering":
|
||||
- if (OpenClipboard(NULL)) {
|
||||
- // if the system clipboard works, use it
|
||||
- int utf16_len = fl_utf8toUtf16(fl_selection_buffer[clipboard], fl_selection_length[clipboard], 0, 0);
|
||||
- EmptyClipboard();
|
||||
- HGLOBAL hMem = GlobalAlloc(GHND, utf16_len * 2 + 2); // moveable and zero'ed mem alloc.
|
||||
- LPVOID memLock = GlobalLock(hMem);
|
||||
- fl_utf8toUtf16(fl_selection_buffer[clipboard], fl_selection_length[clipboard], (unsigned short*) memLock, utf16_len + 1);
|
||||
- GlobalUnlock(hMem);
|
||||
- SetClipboardData(CF_UNICODETEXT, hMem);
|
||||
- CloseClipboard();
|
||||
- GlobalFree(hMem);
|
||||
- fl_i_own_selection[clipboard] = 0;
|
||||
- } else {
|
||||
- // only if it fails, instruct paste() to use the internal buffers
|
||||
- fl_i_own_selection[clipboard] = 1;
|
||||
- }
|
||||
- }
|
||||
+ fl_i_own_selection[clipboard] = 1;
|
||||
+ if (clipboard)
|
||||
+ fl_update_clipboard();
|
||||
}
|
||||
|
||||
// Call this when a "paste" operation happens:
|
||||
@@ -1307,33 +1322,6 @@
|
||||
fl_i_own_selection[1] = 0;
|
||||
return 1;
|
||||
|
||||
- case WM_RENDERALLFORMATS:
|
||||
- fl_i_own_selection[1] = 0;
|
||||
- // Windoze seems unhappy unless I do these two steps. Documentation
|
||||
- // seems to vary on whether opening the clipboard is necessary or
|
||||
- // is in fact wrong:
|
||||
- CloseClipboard();
|
||||
- OpenClipboard(NULL);
|
||||
- // fall through...
|
||||
- case WM_RENDERFORMAT: {
|
||||
- HANDLE h;
|
||||
-
|
||||
-// int l = fl_utf_nb_char((unsigned char*)fl_selection_buffer[1], fl_selection_length[1]);
|
||||
- int l = fl_utf8toUtf16(fl_selection_buffer[1], fl_selection_length[1], NULL, 0); // Pass NULL buffer to query length required
|
||||
- h = GlobalAlloc(GHND, (l+1) * sizeof(unsigned short));
|
||||
- if (h) {
|
||||
- unsigned short *g = (unsigned short*) GlobalLock(h);
|
||||
-// fl_utf2unicode((unsigned char *)fl_selection_buffer[1], fl_selection_length[1], (xchar*)g);
|
||||
- l = fl_utf8toUtf16(fl_selection_buffer[1], fl_selection_length[1], g, (l+1));
|
||||
- g[l] = 0;
|
||||
- GlobalUnlock(h);
|
||||
- SetClipboardData(CF_UNICODETEXT, h);
|
||||
- }
|
||||
-
|
||||
- // Windoze also seems unhappy if I don't do this. Documentation very
|
||||
- // unclear on what is correct:
|
||||
- if (fl_msg.message == WM_RENDERALLFORMATS) CloseClipboard();
|
||||
- return 1;}
|
||||
case WM_DISPLAYCHANGE: // occurs when screen configuration (number, position) changes
|
||||
Fl::call_screen_init();
|
||||
Fl::handle(FL_SCREEN_CONFIGURATION_CHANGED, NULL);
|
||||
diff -ur fltk-1.3.0r9110.org/src/Fl.cxx fltk-1.3.0r9110/src/Fl.cxx
|
||||
--- fltk-1.3.0r9110.org/src/Fl.cxx 2012-06-17 19:42:02.173422595 +0200
|
||||
+++ fltk-1.3.0r9110/src/Fl.cxx 2012-06-17 19:42:02.317429497 +0200
|
||||
@@ -1420,7 +1420,9 @@
|
||||
////////////////////////////////////////////////////////////////
|
||||
// hide() destroys the X window, it does not do unmap!
|
||||
|
||||
-#if !defined(WIN32) && USE_XFT
|
||||
+#if defined(WIN32)
|
||||
+extern void fl_update_clipboard(void);
|
||||
+#elif USE_XFT
|
||||
extern void fl_destroy_xft_draw(Window);
|
||||
#endif
|
||||
|
||||
@@ -1467,14 +1469,8 @@
|
||||
#if defined(WIN32)
|
||||
// this little trick keeps the current clipboard alive, even if we are about
|
||||
// to destroy the window that owns the selection.
|
||||
- if (GetClipboardOwner()==ip->xid) {
|
||||
- Fl_Window *w1 = Fl::first_window();
|
||||
- if (w1 && OpenClipboard(fl_xid(w1))) {
|
||||
- EmptyClipboard();
|
||||
- SetClipboardData(CF_TEXT, NULL);
|
||||
- CloseClipboard();
|
||||
- }
|
||||
- }
|
||||
+ if (GetClipboardOwner()==ip->xid)
|
||||
+ fl_update_clipboard();
|
||||
// Send a message to myself so that I'll get out of the event loop...
|
||||
PostMessage(ip->xid, WM_APP, 0, 0);
|
||||
if (ip->private_dc) fl_release_dc(ip->xid, ip->private_dc);
|
||||
99
contrib/fltk/04-str2636-fltk-1.3.x-clipboard-win32.patch
Normal file
99
contrib/fltk/04-str2636-fltk-1.3.x-clipboard-win32.patch
Normal file
@@ -0,0 +1,99 @@
|
||||
diff -ur fltk-1.3.0r9110.org/src/Fl.cxx fltk-1.3.0r9110/src/Fl.cxx
|
||||
--- fltk-1.3.0r9110.org/src/Fl.cxx 2012-06-17 19:47:09.988183253 +0200
|
||||
+++ fltk-1.3.0r9110/src/Fl.cxx 2012-06-17 19:47:10.127189919 +0200
|
||||
@@ -1421,6 +1421,7 @@
|
||||
// hide() destroys the X window, it does not do unmap!
|
||||
|
||||
#if defined(WIN32)
|
||||
+extern void fl_clipboard_notify_untarget(HWND wnd);
|
||||
extern void fl_update_clipboard(void);
|
||||
#elif USE_XFT
|
||||
extern void fl_destroy_xft_draw(Window);
|
||||
@@ -1471,6 +1472,8 @@
|
||||
// to destroy the window that owns the selection.
|
||||
if (GetClipboardOwner()==ip->xid)
|
||||
fl_update_clipboard();
|
||||
+ // Make sure we unlink this window from the clipboard chain
|
||||
+ fl_clipboard_notify_untarget(ip->xid);
|
||||
// Send a message to myself so that I'll get out of the event loop...
|
||||
PostMessage(ip->xid, WM_APP, 0, 0);
|
||||
if (ip->private_dc) fl_release_dc(ip->xid, ip->private_dc);
|
||||
diff -ur fltk-1.3.0r9110.org/src/Fl_win32.cxx fltk-1.3.0r9110/src/Fl_win32.cxx
|
||||
--- fltk-1.3.0r9110.org/src/Fl_win32.cxx 2012-06-17 19:47:09.987183205 +0200
|
||||
+++ fltk-1.3.0r9110/src/Fl_win32.cxx 2012-06-17 19:47:19.069618739 +0200
|
||||
@@ -646,6 +646,38 @@
|
||||
}
|
||||
}
|
||||
|
||||
+static HWND clipboard_wnd = 0;
|
||||
+static HWND next_clipboard_wnd = 0;
|
||||
+
|
||||
+static bool initial_clipboard = true;
|
||||
+
|
||||
+void fl_clipboard_notify_change() {
|
||||
+ // No need to do anything here...
|
||||
+}
|
||||
+
|
||||
+void fl_clipboard_notify_target(HWND wnd) {
|
||||
+ if (clipboard_wnd)
|
||||
+ return;
|
||||
+
|
||||
+ // We get one fake WM_DRAWCLIPBOARD immediately, which we therefore
|
||||
+ // need to ignore.
|
||||
+ initial_clipboard = true;
|
||||
+
|
||||
+ clipboard_wnd = wnd;
|
||||
+ next_clipboard_wnd = SetClipboardViewer(wnd);
|
||||
+}
|
||||
+
|
||||
+void fl_clipboard_notify_untarget(HWND wnd) {
|
||||
+ if (wnd != clipboard_wnd)
|
||||
+ return;
|
||||
+
|
||||
+ ChangeClipboardChain(wnd, next_clipboard_wnd);
|
||||
+ clipboard_wnd = next_clipboard_wnd = 0;
|
||||
+
|
||||
+ if (Fl::first_window())
|
||||
+ fl_clipboard_notify_target(fl_xid(Fl::first_window()));
|
||||
+}
|
||||
+
|
||||
////////////////////////////////////////////////////////////////
|
||||
char fl_is_ime = 0;
|
||||
void fl_get_codepage()
|
||||
@@ -1327,6 +1359,27 @@
|
||||
Fl::handle(FL_SCREEN_CONFIGURATION_CHANGED, NULL);
|
||||
return 0;
|
||||
|
||||
+ case WM_CHANGECBCHAIN:
|
||||
+ if ((hWnd == clipboard_wnd) &&
|
||||
+ (next_clipboard_wnd == (HWND)wParam)) {
|
||||
+ next_clipboard_wnd = (HWND)lParam;
|
||||
+ return 0;
|
||||
+ }
|
||||
+ break;
|
||||
+
|
||||
+ case WM_DRAWCLIPBOARD:
|
||||
+ // When the clipboard moves between two FLTK windows,
|
||||
+ // fl_i_own_selection will temporarily be false as we are
|
||||
+ // processing this message. Hence the need to use fl_find().
|
||||
+ if (!initial_clipboard && !fl_find(GetClipboardOwner()))
|
||||
+ fl_trigger_clipboard_notify(1);
|
||||
+ initial_clipboard = false;
|
||||
+
|
||||
+ if (next_clipboard_wnd)
|
||||
+ SendMessage(next_clipboard_wnd, WM_DRAWCLIPBOARD, wParam, lParam);
|
||||
+
|
||||
+ return 0;
|
||||
+
|
||||
default:
|
||||
if (Fl::handle(0,0)) return 0;
|
||||
break;
|
||||
@@ -1685,6 +1738,8 @@
|
||||
x->next = Fl_X::first;
|
||||
Fl_X::first = x;
|
||||
|
||||
+ fl_clipboard_notify_target(x->xid);
|
||||
+
|
||||
x->wait_for_expose = 1;
|
||||
if (fl_show_iconic) {showit = 0; fl_show_iconic = 0;}
|
||||
if (showit) {
|
||||
44
contrib/fltk/05-str2636-fltk-1.3.x-clipboard-osx.patch
Normal file
44
contrib/fltk/05-str2636-fltk-1.3.x-clipboard-osx.patch
Normal file
@@ -0,0 +1,44 @@
|
||||
diff -bur fltk-1.3.0r9619.org/src/Fl_cocoa.mm fltk-1.3.0r9619/src/Fl_cocoa.mm
|
||||
--- fltk-1.3.0r9619.org/src/Fl_cocoa.mm 2012-06-18 19:24:30.971688769 +0200
|
||||
+++ fltk-1.3.0r9619/src/Fl_cocoa.mm 2012-06-18 19:25:25.700310375 +0200
|
||||
@@ -1319,9 +1319,13 @@
|
||||
}
|
||||
@end
|
||||
|
||||
+static void clipboard_check(void);
|
||||
+
|
||||
@implementation FLApplication
|
||||
+ (void)sendEvent:(NSEvent *)theEvent
|
||||
{
|
||||
+ // update clipboard status
|
||||
+ clipboard_check();
|
||||
NSEventType type = [theEvent type];
|
||||
if (type == NSLeftMouseDown) {
|
||||
fl_lock_function();
|
||||
@@ -2790,6 +2794,26 @@
|
||||
PasteboardCreate(kPasteboardClipboard, &myPasteboard);
|
||||
}
|
||||
|
||||
+extern void fl_trigger_clipboard_notify(int source);
|
||||
+
|
||||
+void fl_clipboard_notify_change() {
|
||||
+ // No need to do anything here...
|
||||
+}
|
||||
+
|
||||
+static void clipboard_check(void)
|
||||
+{
|
||||
+ PasteboardSyncFlags flags;
|
||||
+
|
||||
+ allocatePasteboard();
|
||||
+ flags = PasteboardSynchronize(myPasteboard);
|
||||
+
|
||||
+ if (!(flags & kPasteboardModified))
|
||||
+ return;
|
||||
+ if (flags & kPasteboardClientIsOwner)
|
||||
+ return;
|
||||
+
|
||||
+ fl_trigger_clipboard_notify(1);
|
||||
+}
|
||||
|
||||
/*
|
||||
* create a selection
|
||||
554
contrib/fltk/06-str2659-pixmap.patch
Normal file
554
contrib/fltk/06-str2659-pixmap.patch
Normal file
@@ -0,0 +1,554 @@
|
||||
diff -ur fltk-1.3.2.org/FL/Fl_Image.H fltk-1.3.2/FL/Fl_Image.H
|
||||
--- fltk-1.3.2.org/FL/Fl_Image.H 2012-11-09 17:02:08.000000000 +0100
|
||||
+++ fltk-1.3.2/FL/Fl_Image.H 2013-01-16 14:40:51.543230638 +0100
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
class Fl_Widget;
|
||||
+class Fl_Pixmap;
|
||||
struct Fl_Menu_Item;
|
||||
struct Fl_Label;
|
||||
|
||||
@@ -203,6 +204,7 @@
|
||||
*/
|
||||
Fl_RGB_Image(const uchar *bits, int W, int H, int D=3, int LD=0) :
|
||||
Fl_Image(W,H,D), array(bits), alloc_array(0), id_(0), mask_(0) {data((const char **)&array, 1); ld(LD);}
|
||||
+ Fl_RGB_Image(const Fl_Pixmap *pxm, Fl_Color bg=FL_GRAY);
|
||||
virtual ~Fl_RGB_Image();
|
||||
virtual Fl_Image *copy(int W, int H);
|
||||
Fl_Image *copy() { return copy(w(), h()); }
|
||||
diff -ur fltk-1.3.2.org/src/fl_draw_pixmap.cxx fltk-1.3.2/src/fl_draw_pixmap.cxx
|
||||
--- fltk-1.3.2.org/src/fl_draw_pixmap.cxx 2012-04-22 05:09:31.000000000 +0200
|
||||
+++ fltk-1.3.2/src/fl_draw_pixmap.cxx 2013-01-16 14:40:51.542230588 +0100
|
||||
@@ -58,99 +58,6 @@
|
||||
return 1;
|
||||
}
|
||||
|
||||
-#ifdef U64
|
||||
-
|
||||
-// The callback from fl_draw_image to get a row of data passes this:
|
||||
-struct pixmap_data {
|
||||
- int w, h;
|
||||
- const uchar*const* data;
|
||||
- union {
|
||||
- U64 colors[256];
|
||||
- U64* byte1[256];
|
||||
- };
|
||||
-};
|
||||
-
|
||||
-// callback for 1 byte per pixel:
|
||||
-static void cb1(void*v, int x, int y, int w, uchar* buf) {
|
||||
- pixmap_data& d = *(pixmap_data*)v;
|
||||
- const uchar* p = d.data[y]+x;
|
||||
- U64* q = (U64*)buf;
|
||||
- for (int X=w; X>0; X-=2, p += 2) {
|
||||
- if (X>1) {
|
||||
-# if WORDS_BIGENDIAN
|
||||
- *q++ = (d.colors[p[0]]<<32) | d.colors[p[1]];
|
||||
-# else
|
||||
- *q++ = (d.colors[p[1]]<<32) | d.colors[p[0]];
|
||||
-# endif
|
||||
- } else {
|
||||
-# if WORDS_BIGENDIAN
|
||||
- *q++ = d.colors[p[0]]<<32;
|
||||
-# else
|
||||
- *q++ = d.colors[p[0]];
|
||||
-# endif
|
||||
- }
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-// callback for 2 bytes per pixel:
|
||||
-static void cb2(void*v, int x, int y, int w, uchar* buf) {
|
||||
- pixmap_data& d = *(pixmap_data*)v;
|
||||
- const uchar* p = d.data[y]+2*x;
|
||||
- U64* q = (U64*)buf;
|
||||
- for (int X=w; X>0; X-=2) {
|
||||
- U64* colors = d.byte1[*p++];
|
||||
- int index = *p++;
|
||||
- if (X>1) {
|
||||
- U64* colors1 = d.byte1[*p++];
|
||||
- int index1 = *p++;
|
||||
-# if WORDS_BIGENDIAN
|
||||
- *q++ = (colors[index]<<32) | colors1[index1];
|
||||
-# else
|
||||
- *q++ = (colors1[index1]<<32) | colors[index];
|
||||
-# endif
|
||||
- } else {
|
||||
-# if WORDS_BIGENDIAN
|
||||
- *q++ = colors[index]<<32;
|
||||
-# else
|
||||
- *q++ = colors[index];
|
||||
-# endif
|
||||
- }
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-#else // U32
|
||||
-
|
||||
-// The callback from fl_draw_image to get a row of data passes this:
|
||||
-struct pixmap_data {
|
||||
- int w, h;
|
||||
- const uchar*const* data;
|
||||
- union {
|
||||
- U32 colors[256];
|
||||
- U32* byte1[256];
|
||||
- };
|
||||
-};
|
||||
-
|
||||
-// callback for 1 byte per pixel:
|
||||
-static void cb1(void*v, int x, int y, int w, uchar* buf) {
|
||||
- pixmap_data& d = *(pixmap_data*)v;
|
||||
- const uchar* p = d.data[y]+x;
|
||||
- U32* q = (U32*)buf;
|
||||
- for (int X=w; X--;) *q++ = d.colors[*p++];
|
||||
-}
|
||||
-
|
||||
-// callback for 2 bytes per pixel:
|
||||
-static void cb2(void*v, int x, int y, int w, uchar* buf) {
|
||||
- pixmap_data& d = *(pixmap_data*)v;
|
||||
- const uchar* p = d.data[y]+2*x;
|
||||
- U32* q = (U32*)buf;
|
||||
- for (int X=w; X--;) {
|
||||
- U32* colors = d.byte1[*p++];
|
||||
- *q++ = colors[*p++];
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-#endif // U64 else U32
|
||||
-
|
||||
uchar **fl_mask_bitmap; // if non-zero, create bitmap and store pointer here
|
||||
|
||||
/**
|
||||
@@ -200,34 +107,33 @@
|
||||
}
|
||||
#endif
|
||||
|
||||
-/**
|
||||
- Draw XPM image data, with the top-left corner at the given position.
|
||||
- \see fl_draw_pixmap(char* const* data, int x, int y, Fl_Color bg)
|
||||
- */
|
||||
-int fl_draw_pixmap(const char*const* cdata, int x, int y, Fl_Color bg) {
|
||||
- pixmap_data d;
|
||||
- if (!fl_measure_pixmap(cdata, d.w, d.h)) return 0;
|
||||
+int fl_convert_pixmap(const char*const* cdata, uchar* out, Fl_Color bg) {
|
||||
+ int w, h;
|
||||
const uchar*const* data = (const uchar*const*)(cdata+1);
|
||||
int transparent_index = -1;
|
||||
+
|
||||
+ if (!fl_measure_pixmap(cdata, w, h))
|
||||
+ return 0;
|
||||
+
|
||||
+ if ((chars_per_pixel < 1) || (chars_per_pixel > 2))
|
||||
+ return 0;
|
||||
+
|
||||
+ uchar colors[1<<(chars_per_pixel*8)][4];
|
||||
+
|
||||
#ifdef WIN32
|
||||
uchar *transparent_c = (uchar *)0; // such that transparent_c[0,1,2] are the RGB of the transparent color
|
||||
color_count = 0;
|
||||
used_colors = (uchar *)malloc(abs(ncolors)*3*sizeof(uchar));
|
||||
#endif
|
||||
|
||||
- if (ncolors < 0) { // FLTK (non standard) compressed colormap
|
||||
+ if (ncolors < 0) {
|
||||
+ // FLTK (non standard) compressed colormap
|
||||
ncolors = -ncolors;
|
||||
const uchar *p = *data++;
|
||||
// if first color is ' ' it is transparent (put it later to make
|
||||
// it not be transparent):
|
||||
if (*p == ' ') {
|
||||
- uchar* c = (uchar*)&d.colors[(int)' '];
|
||||
-#ifdef U64
|
||||
- *(U64*)c = 0;
|
||||
-# if WORDS_BIGENDIAN
|
||||
- c += 4;
|
||||
-# endif
|
||||
-#endif
|
||||
+ uchar* c = colors[(int)' '];
|
||||
transparent_index = ' ';
|
||||
Fl::get_color(bg, c[0], c[1], c[2]); c[3] = 0;
|
||||
#ifdef WIN32
|
||||
@@ -238,13 +144,7 @@
|
||||
}
|
||||
// read all the rest of the colors:
|
||||
for (int i=0; i < ncolors; i++) {
|
||||
- uchar* c = (uchar*)&d.colors[*p++];
|
||||
-#ifdef U64
|
||||
- *(U64*)c = 0;
|
||||
-# if WORDS_BIGENDIAN
|
||||
- c += 4;
|
||||
-# endif
|
||||
-#endif
|
||||
+ uchar* c = colors[*p++];
|
||||
#ifdef WIN32
|
||||
used_colors[3*color_count] = *p;
|
||||
used_colors[3*color_count+1] = *(p+1);
|
||||
@@ -254,69 +154,44 @@
|
||||
*c++ = *p++;
|
||||
*c++ = *p++;
|
||||
*c++ = *p++;
|
||||
-#ifdef __APPLE_QUARTZ__
|
||||
*c = 255;
|
||||
-#else
|
||||
- *c = 0;
|
||||
-#endif
|
||||
}
|
||||
- } else { // normal XPM colormap with names
|
||||
- if (chars_per_pixel>1) memset(d.byte1, 0, sizeof(d.byte1));
|
||||
+ } else {
|
||||
+ // normal XPM colormap with names
|
||||
for (int i=0; i<ncolors; i++) {
|
||||
const uchar *p = *data++;
|
||||
// the first 1 or 2 characters are the color index:
|
||||
int ind = *p++;
|
||||
uchar* c;
|
||||
- if (chars_per_pixel>1) {
|
||||
-#ifdef U64
|
||||
- U64* colors = d.byte1[ind];
|
||||
- if (!colors) colors = d.byte1[ind] = new U64[256];
|
||||
-#else
|
||||
- U32* colors = d.byte1[ind];
|
||||
- if (!colors) colors = d.byte1[ind] = new U32[256];
|
||||
-#endif
|
||||
- c = (uchar*)&colors[*p];
|
||||
- ind = (ind<<8)|*p++;
|
||||
- } else {
|
||||
- c = (uchar *)&d.colors[ind];
|
||||
- }
|
||||
+ if (chars_per_pixel>1)
|
||||
+ ind = (ind<<8)|*p++;
|
||||
+ c = colors[ind];
|
||||
// look for "c word", or last word if none:
|
||||
const uchar *previous_word = p;
|
||||
for (;;) {
|
||||
- while (*p && isspace(*p)) p++;
|
||||
- uchar what = *p++;
|
||||
- while (*p && !isspace(*p)) p++;
|
||||
- while (*p && isspace(*p)) p++;
|
||||
- if (!*p) {p = previous_word; break;}
|
||||
- if (what == 'c') break;
|
||||
- previous_word = p;
|
||||
- while (*p && !isspace(*p)) p++;
|
||||
+ while (*p && isspace(*p)) p++;
|
||||
+ uchar what = *p++;
|
||||
+ while (*p && !isspace(*p)) p++;
|
||||
+ while (*p && isspace(*p)) p++;
|
||||
+ if (!*p) {p = previous_word; break;}
|
||||
+ if (what == 'c') break;
|
||||
+ previous_word = p;
|
||||
+ while (*p && !isspace(*p)) p++;
|
||||
}
|
||||
-#ifdef U64
|
||||
- *(U64*)c = 0;
|
||||
-# if WORDS_BIGENDIAN
|
||||
- c += 4;
|
||||
-# endif
|
||||
-#endif
|
||||
-#ifdef __APPLE_QUARTZ__
|
||||
- c[3] = 255;
|
||||
-#endif
|
||||
int parse = fl_parse_color((const char*)p, c[0], c[1], c[2]);
|
||||
+ c[3] = 255;
|
||||
if (parse) {
|
||||
#ifdef WIN32
|
||||
- used_colors[3*color_count] = c[0];
|
||||
- used_colors[3*color_count+1] = c[1];
|
||||
- used_colors[3*color_count+2] = c[2];
|
||||
- color_count++;
|
||||
+ used_colors[3*color_count] = c[0];
|
||||
+ used_colors[3*color_count+1] = c[1];
|
||||
+ used_colors[3*color_count+2] = c[2];
|
||||
+ color_count++;
|
||||
#endif
|
||||
- }
|
||||
- else {
|
||||
+ } else {
|
||||
// assume "None" or "#transparent" for any errors
|
||||
- // "bg" should be transparent...
|
||||
- Fl::get_color(bg, c[0], c[1], c[2]);
|
||||
-#ifdef __APPLE_QUARTZ__
|
||||
+ // "bg" should be transparent...
|
||||
+ Fl::get_color(bg, c[0], c[1], c[2]);
|
||||
c[3] = 0;
|
||||
-#endif
|
||||
transparent_index = ind;
|
||||
#ifdef WIN32
|
||||
transparent_c = c;
|
||||
@@ -324,7 +199,6 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
- d.data = data;
|
||||
#ifdef WIN32
|
||||
if (transparent_c) {
|
||||
make_unused_color(transparent_c[0], transparent_c[1], transparent_c[2]);
|
||||
@@ -334,77 +208,76 @@
|
||||
make_unused_color(r, g, b);
|
||||
}
|
||||
#endif
|
||||
+
|
||||
+ U32 *q = (U32*)out;
|
||||
+ for (int Y = 0; Y < h; Y++) {
|
||||
+ const uchar* p = data[Y];
|
||||
+ if (chars_per_pixel <= 1) {
|
||||
+ for (int X = 0; X < w; X++)
|
||||
+ memcpy(q++, colors[*p++], 4);
|
||||
+ } else {
|
||||
+ for (int X = 0; X < w; X++) {
|
||||
+ int ind = (*p++)<<8;
|
||||
+ ind |= *p++;
|
||||
+ memcpy(q++, colors[ind], 4);
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ Draw XPM image data, with the top-left corner at the given position.
|
||||
+ \see fl_draw_pixmap(char* const* data, int x, int y, Fl_Color bg)
|
||||
+ */
|
||||
+int fl_draw_pixmap(const char*const* cdata, int x, int y, Fl_Color bg) {
|
||||
+ int w, h;
|
||||
+
|
||||
+ if (!fl_measure_pixmap(cdata, w, h))
|
||||
+ return 0;
|
||||
+
|
||||
+ uchar buffer[w*h*4];
|
||||
+
|
||||
+ if (!fl_convert_pixmap(cdata, buffer, bg))
|
||||
+ return 0;
|
||||
+
|
||||
+ // FIXME: Hack until fl_draw_image() supports alpha properly
|
||||
#ifdef __APPLE_QUARTZ__
|
||||
if (Fl_Surface_Device::surface() == Fl_Display_Device::display_device()) {
|
||||
- U32 *array = new U32[d.w * d.h], *q = array;
|
||||
- for (int Y = 0; Y < d.h; Y++) {
|
||||
- const uchar* p = data[Y];
|
||||
- if (chars_per_pixel <= 1) {
|
||||
- for (int X = 0; X < d.w; X++) {
|
||||
- *q++ = d.colors[*p++];
|
||||
- }
|
||||
- } else {
|
||||
- for (int X = 0; X < d.w; X++) {
|
||||
- U32* colors = (U32*)d.byte1[*p++];
|
||||
- *q++ = colors[*p++];
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
- Fl_RGB_Image* rgb = new Fl_RGB_Image((uchar*)array, d.w, d.h, 4);
|
||||
+ Fl_RGB_Image* rgb = new Fl_RGB_Image(buffer, w, h, 4);
|
||||
rgb->draw(x, y);
|
||||
delete rgb;
|
||||
- delete[] array;
|
||||
- }
|
||||
- else {
|
||||
+ } else {
|
||||
#endif // __APPLE_QUARTZ__
|
||||
-
|
||||
// build the mask bitmap used by Fl_Pixmap:
|
||||
- if (fl_mask_bitmap && transparent_index >= 0) {
|
||||
- int W = (d.w+7)/8;
|
||||
- uchar* bitmap = new uchar[W * d.h];
|
||||
+ if (fl_mask_bitmap) {
|
||||
+ int W = (w+7)/8;
|
||||
+ uchar* bitmap = new uchar[W * h];
|
||||
*fl_mask_bitmap = bitmap;
|
||||
- for (int Y = 0; Y < d.h; Y++) {
|
||||
- const uchar* p = data[Y];
|
||||
- if (chars_per_pixel <= 1) {
|
||||
- int dw = d.w;
|
||||
- for (int X = 0; X < W; X++) {
|
||||
- uchar b = (dw-->0 && *p++ != transparent_index);
|
||||
- if (dw-->0 && *p++ != transparent_index) b |= 2;
|
||||
- if (dw-->0 && *p++ != transparent_index) b |= 4;
|
||||
- if (dw-->0 && *p++ != transparent_index) b |= 8;
|
||||
- if (dw-->0 && *p++ != transparent_index) b |= 16;
|
||||
- if (dw-->0 && *p++ != transparent_index) b |= 32;
|
||||
- if (dw-->0 && *p++ != transparent_index) b |= 64;
|
||||
- if (dw-->0 && *p++ != transparent_index) b |= 128;
|
||||
+ const uchar *p = &buffer[3];
|
||||
+ uchar b = 0;
|
||||
+ for (int Y = 0; Y < h; Y++) {
|
||||
+ b = 0;
|
||||
+ for (int X = 0, bit = 1; X < w; X++, p += 4) {
|
||||
+ if (*p > 127) b |= bit;
|
||||
+ bit <<= 1;
|
||||
+ if (bit > 0x80 || X == w-1) {
|
||||
*bitmap++ = b;
|
||||
- }
|
||||
- } else {
|
||||
- uchar b = 0, bit = 1;
|
||||
- for (int X = 0; X < d.w; X++) {
|
||||
- int ind = *p++;
|
||||
- ind = (ind<<8) | (*p++);
|
||||
- if (ind != transparent_index) b |= bit;
|
||||
-
|
||||
- if (bit < 128) bit <<= 1;
|
||||
- else {
|
||||
- *bitmap++ = b;
|
||||
- b = 0;
|
||||
- bit = 1;
|
||||
+ bit = 1;
|
||||
+ b = 0;
|
||||
}
|
||||
}
|
||||
-
|
||||
- if (bit > 1) *bitmap++ = b;
|
||||
}
|
||||
- }
|
||||
+
|
||||
}
|
||||
|
||||
- fl_draw_image(chars_per_pixel==1 ? cb1 : cb2, &d, x, y, d.w, d.h, 4);
|
||||
+ fl_draw_image(buffer, x, y, w, h, 4);
|
||||
+
|
||||
#ifdef __APPLE_QUARTZ__
|
||||
}
|
||||
#endif
|
||||
|
||||
- if (chars_per_pixel > 1) for (int i = 0; i < 256; i++) delete[] d.byte1[i];
|
||||
return 1;
|
||||
}
|
||||
|
||||
diff -ur fltk-1.3.2.org/src/Fl_Image.cxx fltk-1.3.2/src/Fl_Image.cxx
|
||||
--- fltk-1.3.2.org/src/Fl_Image.cxx 2012-11-09 17:02:08.000000000 +0100
|
||||
+++ fltk-1.3.2/src/Fl_Image.cxx 2013-01-16 14:41:38.404162795 +0100
|
||||
@@ -165,7 +165,22 @@
|
||||
//
|
||||
size_t Fl_RGB_Image::max_size_ = ~((size_t)0);
|
||||
|
||||
-/** The destructor free all memory and server resources that are used by the image. */
|
||||
+int fl_convert_pixmap(const char*const* cdata, uchar* out, Fl_Color bg);
|
||||
+
|
||||
+/** The constructor creates a new RGBA image from the specified Fl_Pixmap.
|
||||
+
|
||||
+ The RGBA image is built fully opaque except for the transparent area
|
||||
+ of the pixmap that is assigned the \par bg color with full transparency */
|
||||
+Fl_RGB_Image::Fl_RGB_Image(const Fl_Pixmap *pxm, Fl_Color bg):
|
||||
+ Fl_Image(pxm->w(), pxm->h(), 4), id_(0), mask_(0)
|
||||
+{
|
||||
+ array = new uchar[w() * h() * d()];
|
||||
+ alloc_array = 1;
|
||||
+ fl_convert_pixmap(pxm->data(), (uchar*)array, bg);
|
||||
+ data((const char **)&array, 1);
|
||||
+}
|
||||
+
|
||||
+/** The destructor frees all memory and server resources that are used by the image. */
|
||||
Fl_RGB_Image::~Fl_RGB_Image() {
|
||||
uncache();
|
||||
if (alloc_array) delete[] (uchar *)array;
|
||||
diff -ur fltk-1.3.2.org/src/ps_image.cxx fltk-1.3.2/src/ps_image.cxx
|
||||
--- fltk-1.3.2.org/src/ps_image.cxx 2011-07-19 06:49:30.000000000 +0200
|
||||
+++ fltk-1.3.2/src/ps_image.cxx 2013-01-16 14:40:51.541228080 +0100
|
||||
@@ -185,72 +185,38 @@
|
||||
|
||||
extern uchar **fl_mask_bitmap;
|
||||
|
||||
+struct callback_data {
|
||||
+ const uchar *data;
|
||||
+ int D, LD;
|
||||
+};
|
||||
|
||||
-void Fl_PostScript_Graphics_Driver::draw_image(const uchar *data, int ix, int iy, int iw, int ih, int D, int LD) {
|
||||
- double x = ix, y = iy, w = iw, h = ih;
|
||||
|
||||
- if (D<3){ //mono
|
||||
- draw_image_mono(data, ix, iy, iw, ih, D, LD);
|
||||
- return;
|
||||
- }
|
||||
+static void draw_image_cb(void *data, int x, int y, int w, uchar *buf) {
|
||||
+ struct callback_data *cb_data;
|
||||
+ const uchar *curdata;
|
||||
|
||||
+ cb_data = (struct callback_data*)data;
|
||||
+ curdata = cb_data->data + x*cb_data->D + y*cb_data->LD;
|
||||
|
||||
- int i,j, k;
|
||||
+ memcpy(buf, curdata, w*cb_data->D);
|
||||
+}
|
||||
|
||||
- fprintf(output,"save\n");
|
||||
|
||||
- const char * interpol;
|
||||
- if (lang_level_>1){
|
||||
- if (interpolate_)
|
||||
- interpol="true";
|
||||
- else
|
||||
- interpol="false";
|
||||
- if (mask && lang_level_>2)
|
||||
- fprintf(output, "%g %g %g %g %i %i %i %i %s CIM\n", x , y+h , w , -h , iw , ih, mx, my, interpol);
|
||||
- else
|
||||
- fprintf(output, "%g %g %g %g %i %i %s CII\n", x , y+h , w , -h , iw , ih, interpol);
|
||||
- } else
|
||||
- fprintf(output , "%g %g %g %g %i %i CI", x , y+h , w , -h , iw , ih);
|
||||
+void Fl_PostScript_Graphics_Driver::draw_image(const uchar *data, int ix, int iy, int iw, int ih, int D, int LD) {
|
||||
+ if (D<3){ //mono
|
||||
+ draw_image_mono(data, ix, iy, iw, ih, D, LD);
|
||||
+ return;
|
||||
+ }
|
||||
|
||||
+ struct callback_data cb_data;
|
||||
|
||||
if (!LD) LD = iw*D;
|
||||
- uchar *curmask=mask;
|
||||
-
|
||||
- for (j=0; j<ih;j++){
|
||||
- if (mask){
|
||||
-
|
||||
- for (k=0;k<my/ih;k++){
|
||||
- for (i=0; i<((mx+7)/8);i++){
|
||||
- if (!(i%80)) fprintf(output, "\n");
|
||||
- fprintf(output, "%.2x",swap_byte(*curmask));
|
||||
- curmask++;
|
||||
- }
|
||||
- fprintf(output,"\n");
|
||||
- }
|
||||
- }
|
||||
- const uchar *curdata=data+j*LD;
|
||||
- for (i=0 ; i<iw ; i++) {
|
||||
- uchar r = curdata[0];
|
||||
- uchar g = curdata[1];
|
||||
- uchar b = curdata[2];
|
||||
- if (lang_level_<3 && D>3) { //can do mixing using bg_* colors)
|
||||
- unsigned int a2 = curdata[3]; //must be int
|
||||
- unsigned int a = 255-a2;
|
||||
- r = (a2 * r + bg_r * a)/255;
|
||||
- g = (a2 * g + bg_g * a)/255;
|
||||
- b = (a2 * b + bg_b * a)/255;
|
||||
- }
|
||||
- if (!(i%40)) fprintf(output, "\n");
|
||||
- fprintf(output, "%.2x%.2x%.2x", r, g, b);
|
||||
- curdata +=D;
|
||||
- }
|
||||
- fprintf(output,"\n");
|
||||
-
|
||||
- }
|
||||
-
|
||||
- fprintf(output," >\nrestore\n" );
|
||||
|
||||
+ cb_data.data = data;
|
||||
+ cb_data.D = D;
|
||||
+ cb_data.LD = LD;
|
||||
|
||||
+ draw_image(draw_image_cb, &cb_data, ix, iy, iw, ih, D);
|
||||
}
|
||||
|
||||
void Fl_PostScript_Graphics_Driver::draw_image(Fl_Draw_Image_Cb call, void *data, int ix, int iy, int iw, int ih, int D) {
|
||||
@@ -325,6 +291,14 @@
|
||||
uchar g = curdata[1];
|
||||
uchar b = curdata[2];
|
||||
|
||||
+ if (lang_level_<3 && D>3) { //can do mixing using bg_* colors)
|
||||
+ unsigned int a2 = curdata[3]; //must be int
|
||||
+ unsigned int a = 255-a2;
|
||||
+ r = (a2 * r + bg_r * a)/255;
|
||||
+ g = (a2 * g + bg_g * a)/255;
|
||||
+ b = (a2 * b + bg_b * a)/255;
|
||||
+ }
|
||||
+
|
||||
if (!(i%40)) fputs("\n", output);
|
||||
fprintf(output, "%.2x%.2x%.2x", r, g, b);
|
||||
|
||||
1623
contrib/fltk/07-str2660-fltk-1.3.x-cursor.patch
Normal file
1623
contrib/fltk/07-str2660-fltk-1.3.x-cursor.patch
Normal file
File diff suppressed because it is too large
Load Diff
75
contrib/fltk/08-str2802-fltk-1.3.0-modal.patch
Normal file
75
contrib/fltk/08-str2802-fltk-1.3.0-modal.patch
Normal file
@@ -0,0 +1,75 @@
|
||||
diff -bur fltk-1.3.0r9619.org/src/Fl_cocoa.mm fltk-1.3.0r9619/src/Fl_cocoa.mm
|
||||
--- fltk-1.3.0r9619.org/src/Fl_cocoa.mm 2012-06-19 12:54:43.694231638 +0200
|
||||
+++ fltk-1.3.0r9619/src/Fl_cocoa.mm 2012-06-19 12:57:05.899048602 +0200
|
||||
@@ -697,12 +697,9 @@
|
||||
return NO; // prevent the caption to be redrawn as active on click
|
||||
// when another modal window is currently the key win
|
||||
|
||||
- return !(w->tooltip_window() || w->menu_window());
|
||||
+ return !w->tooltip_window();
|
||||
}
|
||||
|
||||
-// TODO see if we really need a canBecomeMainWindow ...
|
||||
-#if 0
|
||||
-
|
||||
- (BOOL)canBecomeMainWindow
|
||||
{
|
||||
if (Fl::modal_ && (Fl::modal_ != w))
|
||||
@@ -711,7 +708,6 @@
|
||||
|
||||
return !(w->tooltip_window() || w->menu_window());
|
||||
}
|
||||
-#endif
|
||||
|
||||
@end
|
||||
|
||||
diff -bur fltk-1.3.0r9619.org/src/Fl_win32.cxx fltk-1.3.0r9619/src/Fl_win32.cxx
|
||||
--- fltk-1.3.0r9619.org/src/Fl_win32.cxx 2012-06-19 12:54:43.696231735 +0200
|
||||
+++ fltk-1.3.0r9619/src/Fl_win32.cxx 2012-06-19 12:54:43.803236862 +0200
|
||||
@@ -1065,6 +1065,10 @@
|
||||
break;
|
||||
|
||||
case WM_SETFOCUS:
|
||||
+ if ((Fl::modal_) && (Fl::modal_ != window)) {
|
||||
+ SetFocus(fl_xid(Fl::modal_));
|
||||
+ return 0;
|
||||
+ }
|
||||
Fl::handle(FL_FOCUS, window);
|
||||
break;
|
||||
|
||||
@@ -1826,6 +1830,11 @@
|
||||
Fl::e_number = old_event;
|
||||
w->redraw(); // force draw to happen
|
||||
}
|
||||
+
|
||||
+ // Needs to be done before ShowWindow() to get the correct behaviour
|
||||
+ // when we get WM_SETFOCUS.
|
||||
+ if (w->modal()) {Fl::modal_ = w; fl_fix_focus();}
|
||||
+
|
||||
// If we've captured the mouse, we dont want to activate any
|
||||
// other windows from the code, or we lose the capture.
|
||||
ShowWindow(x->xid, !showit ? SW_SHOWMINNOACTIVE :
|
||||
@@ -1843,7 +1852,6 @@
|
||||
}
|
||||
}
|
||||
|
||||
- if (w->modal()) {Fl::modal_ = w; fl_fix_focus();}
|
||||
return x;
|
||||
}
|
||||
|
||||
diff -bur fltk-1.3.0r9619.org/src/Fl_x.cxx fltk-1.3.0r9619/src/Fl_x.cxx
|
||||
--- fltk-1.3.0r9619.org/src/Fl_x.cxx 2012-06-19 12:54:43.697231783 +0200
|
||||
+++ fltk-1.3.0r9619/src/Fl_x.cxx 2012-06-19 12:54:43.804236911 +0200
|
||||
@@ -2101,6 +2101,12 @@
|
||||
while (wp->parent()) wp = wp->window();
|
||||
XSetTransientForHint(fl_display, xp->xid, fl_xid(wp));
|
||||
if (!wp->visible()) showit = 0; // guess that wm will not show it
|
||||
+ if (win->modal()) {
|
||||
+ Atom net_wm_state = XInternAtom (fl_display, "_NET_WM_STATE", 0);
|
||||
+ Atom net_wm_state_skip_taskbar = XInternAtom (fl_display, "_NET_WM_STATE_MODAL", 0);
|
||||
+ XChangeProperty (fl_display, xp->xid, net_wm_state, XA_ATOM, 32,
|
||||
+ PropModeAppend, (unsigned char*) &net_wm_state_skip_taskbar, 1);
|
||||
+ }
|
||||
}
|
||||
|
||||
// Make sure that borderless windows do not show in the task bar
|
||||
645
contrib/fltk/09-str2816-fltk-1.3.0-icons.patch
Normal file
645
contrib/fltk/09-str2816-fltk-1.3.0-icons.patch
Normal file
@@ -0,0 +1,645 @@
|
||||
diff -ur fltk-1.3.2.org/FL/Fl_Window.H fltk-1.3.2/FL/Fl_Window.H
|
||||
--- fltk-1.3.2.org/FL/Fl_Window.H 2013-01-16 10:49:40.904228200 +0100
|
||||
+++ fltk-1.3.2/FL/Fl_Window.H 2013-01-16 10:49:55.554353925 +0100
|
||||
@@ -22,6 +22,10 @@
|
||||
#ifndef Fl_Window_H
|
||||
#define Fl_Window_H
|
||||
|
||||
+#ifdef WIN32
|
||||
+#include <windows.h>
|
||||
+#endif
|
||||
+
|
||||
#include "Fl_Group.H"
|
||||
|
||||
#define FL_WINDOW 0xF0 ///< window type id all subclasses have type() >= this
|
||||
@@ -73,9 +77,19 @@
|
||||
friend class Fl_X;
|
||||
Fl_X *i; // points at the system-specific stuff
|
||||
|
||||
+ struct icon_data {
|
||||
+ const void *legacy_icon;
|
||||
+ Fl_RGB_Image **icons;
|
||||
+ int count;
|
||||
+#ifdef WIN32
|
||||
+ HICON big_icon;
|
||||
+ HICON small_icon;
|
||||
+#endif
|
||||
+ };
|
||||
+
|
||||
const char* iconlabel_;
|
||||
char* xclass_;
|
||||
- const void* icon_;
|
||||
+ struct icon_data *icon_;
|
||||
// size_range stuff:
|
||||
int minw, minh, maxw, maxh;
|
||||
int dw, dh, aspect;
|
||||
@@ -121,6 +135,8 @@
|
||||
*/
|
||||
int force_position() const { return ((flags() & FORCE_POSITION)?1:0); }
|
||||
|
||||
+ void free_icons();
|
||||
+
|
||||
public:
|
||||
|
||||
/**
|
||||
@@ -350,6 +366,18 @@
|
||||
static const char *default_xclass();
|
||||
const char* xclass() const;
|
||||
void xclass(const char* c);
|
||||
+
|
||||
+ static void default_icon(const Fl_RGB_Image*);
|
||||
+ static void default_icons(const Fl_RGB_Image*[], int);
|
||||
+ void icon(const Fl_RGB_Image*);
|
||||
+ void icons(const Fl_RGB_Image*[], int);
|
||||
+
|
||||
+#ifdef WIN32
|
||||
+ static void default_icons(HICON big_icon, HICON small_icon);
|
||||
+ void icons(HICON big_icon, HICON small_icon);
|
||||
+#endif
|
||||
+
|
||||
+ /* for legacy compatibility */
|
||||
const void* icon() const;
|
||||
void icon(const void * ic);
|
||||
|
||||
diff -ur fltk-1.3.2.org/FL/mac.H fltk-1.3.2/FL/mac.H
|
||||
--- fltk-1.3.2.org/FL/mac.H 2013-01-16 10:49:40.904228200 +0100
|
||||
+++ fltk-1.3.2/FL/mac.H 2013-01-16 10:49:55.554353925 +0100
|
||||
@@ -120,6 +120,9 @@
|
||||
void collapse(void);
|
||||
WindowRef window_ref(void);
|
||||
void set_key_window(void);
|
||||
+ // OS X doesn't have per window icons
|
||||
+ static void set_default_icons(const Fl_RGB_Image*[], int) {};
|
||||
+ void set_icons() {};
|
||||
int set_cursor(Fl_Cursor);
|
||||
int set_cursor(const Fl_RGB_Image*, int, int);
|
||||
static CGImageRef CGImage_from_window_rect(Fl_Window *win, int x, int y, int w, int h);
|
||||
diff -ur fltk-1.3.2.org/FL/win32.H fltk-1.3.2/FL/win32.H
|
||||
--- fltk-1.3.2.org/FL/win32.H 2013-01-16 10:49:40.904228200 +0100
|
||||
+++ fltk-1.3.2/FL/win32.H 2013-01-16 10:49:55.555355617 +0100
|
||||
@@ -84,6 +84,9 @@
|
||||
void flush() {w->flush();}
|
||||
void set_minmax(LPMINMAXINFO minmax);
|
||||
void mapraise();
|
||||
+ static void set_default_icons(const Fl_RGB_Image*[], int);
|
||||
+ static void set_default_icons(HICON, HICON);
|
||||
+ void set_icons();
|
||||
int set_cursor(Fl_Cursor);
|
||||
int set_cursor(const Fl_RGB_Image*, int, int);
|
||||
static Fl_X* make(Fl_Window*);
|
||||
diff -ur fltk-1.3.2.org/FL/x.H fltk-1.3.2/FL/x.H
|
||||
--- fltk-1.3.2.org/FL/x.H 2013-01-16 10:49:40.904228200 +0100
|
||||
+++ fltk-1.3.2/FL/x.H 2013-01-16 10:49:55.555355617 +0100
|
||||
@@ -154,6 +154,8 @@
|
||||
static Fl_X* i(const Fl_Window* wi) {return wi->i;}
|
||||
void setwindow(Fl_Window* wi) {w=wi; wi->i=this;}
|
||||
void sendxjunk();
|
||||
+ static void set_default_icons(const Fl_RGB_Image*[], int);
|
||||
+ void set_icons();
|
||||
int set_cursor(Fl_Cursor);
|
||||
int set_cursor(const Fl_RGB_Image*, int, int);
|
||||
static void make_xid(Fl_Window*,XVisualInfo* =fl_visual, Colormap=fl_colormap);
|
||||
diff -ur fltk-1.3.2.org/src/Fl.cxx fltk-1.3.2/src/Fl.cxx
|
||||
--- fltk-1.3.2.org/src/Fl.cxx 2013-01-16 10:49:40.895228113 +0100
|
||||
+++ fltk-1.3.2/src/Fl.cxx 2013-01-16 10:49:55.556137979 +0100
|
||||
@@ -1530,6 +1530,8 @@
|
||||
if (xclass_) {
|
||||
free(xclass_);
|
||||
}
|
||||
+ free_icons();
|
||||
+ delete icon_;
|
||||
}
|
||||
|
||||
// FL_SHOW and FL_HIDE are called whenever the visibility of this widget
|
||||
diff -ur fltk-1.3.2.org/src/Fl_win32.cxx fltk-1.3.2/src/Fl_win32.cxx
|
||||
--- fltk-1.3.2.org/src/Fl_win32.cxx 2013-01-16 10:49:40.911227539 +0100
|
||||
+++ fltk-1.3.2/src/Fl_win32.cxx 2013-01-16 10:49:55.556137979 +0100
|
||||
@@ -1804,6 +1804,8 @@
|
||||
);
|
||||
if (lab) free(lab);
|
||||
|
||||
+ x->set_icons();
|
||||
+
|
||||
if (w->fullscreen_active()) {
|
||||
/* We need to make sure that the fullscreen is created on the
|
||||
default monitor, ie the desktop where the shortcut is located
|
||||
@@ -2034,71 +2036,19 @@
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
-#ifndef IDC_HAND
|
||||
-# define IDC_HAND MAKEINTRESOURCE(32649)
|
||||
-#endif // !IDC_HAND
|
||||
-
|
||||
-int Fl_X::set_cursor(Fl_Cursor c) {
|
||||
- LPSTR n;
|
||||
- HCURSOR new_cursor;
|
||||
-
|
||||
- if (c == FL_CURSOR_NONE)
|
||||
- new_cursor = NULL;
|
||||
- else {
|
||||
- switch (c) {
|
||||
- case FL_CURSOR_ARROW: n = IDC_ARROW; break;
|
||||
- case FL_CURSOR_CROSS: n = IDC_CROSS; break;
|
||||
- case FL_CURSOR_WAIT: n = IDC_WAIT; break;
|
||||
- case FL_CURSOR_INSERT: n = IDC_IBEAM; break;
|
||||
- case FL_CURSOR_HAND: n = IDC_HAND; break;
|
||||
- case FL_CURSOR_HELP: n = IDC_HELP; break;
|
||||
- case FL_CURSOR_MOVE: n = IDC_SIZEALL; break;
|
||||
- case FL_CURSOR_N:
|
||||
- case FL_CURSOR_S:
|
||||
- // FIXME: Should probably have fallbacks for these instead
|
||||
- case FL_CURSOR_NS: n = IDC_SIZENS; break;
|
||||
- case FL_CURSOR_NE:
|
||||
- case FL_CURSOR_SW:
|
||||
- // FIXME: Dito.
|
||||
- case FL_CURSOR_NESW: n = IDC_SIZENESW; break;
|
||||
- case FL_CURSOR_E:
|
||||
- case FL_CURSOR_W:
|
||||
- // FIXME: Dito.
|
||||
- case FL_CURSOR_WE: n = IDC_SIZEWE; break;
|
||||
- case FL_CURSOR_SE:
|
||||
- case FL_CURSOR_NW:
|
||||
- // FIXME: Dito.
|
||||
- case FL_CURSOR_NWSE: n = IDC_SIZENWSE; break;
|
||||
- default:
|
||||
- return 0;
|
||||
- }
|
||||
-
|
||||
- new_cursor = LoadCursor(NULL, n);
|
||||
- if (new_cursor == NULL)
|
||||
- return 0;
|
||||
- }
|
||||
-
|
||||
- if ((cursor != NULL) && custom_cursor)
|
||||
- DestroyIcon(cursor);
|
||||
-
|
||||
- cursor = new_cursor;
|
||||
- custom_cursor = 0;
|
||||
-
|
||||
- SetCursor(cursor);
|
||||
-
|
||||
- return 1;
|
||||
-}
|
||||
-
|
||||
-int Fl_X::set_cursor(const Fl_RGB_Image *image, int hotx, int hoty) {
|
||||
+static HICON image_to_icon(const Fl_RGB_Image *image, bool is_icon=true,
|
||||
+ int hotx = 0, int hoty = 0) {
|
||||
BITMAPV5HEADER bi;
|
||||
HBITMAP bitmap, mask;
|
||||
DWORD *bits;
|
||||
- HCURSOR new_cursor;
|
||||
+ HICON icon;
|
||||
|
||||
+ if (!is_icon) {
|
||||
if ((hotx < 0) || (hotx >= image->w()))
|
||||
- return 0;
|
||||
+ return NULL;
|
||||
if ((hoty < 0) || (hoty >= image->h()))
|
||||
- return 0;
|
||||
+ return NULL;
|
||||
+ }
|
||||
|
||||
memset(&bi, 0, sizeof(BITMAPV5HEADER));
|
||||
|
||||
@@ -2120,7 +2070,7 @@
|
||||
ReleaseDC(NULL, hdc);
|
||||
|
||||
if (bits == NULL)
|
||||
- return 0;
|
||||
+ return NULL;
|
||||
|
||||
const uchar *i = (const uchar*)*image->data();
|
||||
for (int y = 0;y < image->h();y++) {
|
||||
@@ -2149,22 +2099,206 @@
|
||||
mask = CreateBitmap(image->w(),image->h(),1,1,NULL);
|
||||
if (mask == NULL) {
|
||||
DeleteObject(bitmap);
|
||||
- return 0;
|
||||
+ return NULL;
|
||||
}
|
||||
|
||||
ICONINFO ii;
|
||||
|
||||
- ii.fIcon = FALSE;
|
||||
+ ii.fIcon = is_icon;
|
||||
ii.xHotspot = hotx;
|
||||
ii.yHotspot = hoty;
|
||||
ii.hbmMask = mask;
|
||||
ii.hbmColor = bitmap;
|
||||
|
||||
- new_cursor = CreateIconIndirect(&ii);
|
||||
+ icon = CreateIconIndirect(&ii);
|
||||
|
||||
DeleteObject(bitmap);
|
||||
DeleteObject(mask);
|
||||
|
||||
+ if (icon == NULL)
|
||||
+ return NULL;
|
||||
+
|
||||
+ return icon;
|
||||
+}
|
||||
+
|
||||
+////////////////////////////////////////////////////////////////
|
||||
+
|
||||
+static HICON default_big_icon = NULL;
|
||||
+static HICON default_small_icon = NULL;
|
||||
+
|
||||
+const Fl_RGB_Image *find_best_icon(int ideal_width,
|
||||
+ const Fl_RGB_Image *icons[], int count) {
|
||||
+ const Fl_RGB_Image *best;
|
||||
+
|
||||
+ best = NULL;
|
||||
+
|
||||
+ for (int i = 0;i < count;i++) {
|
||||
+ if (best == NULL)
|
||||
+ best = icons[i];
|
||||
+ else {
|
||||
+ if (best->w() < ideal_width) {
|
||||
+ if (icons[i]->w() > best->w())
|
||||
+ best = icons[i];
|
||||
+ } else {
|
||||
+ if ((icons[i]->w() >= ideal_width) &&
|
||||
+ (icons[i]->w() < best->w()))
|
||||
+ best = icons[i];
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ return best;
|
||||
+}
|
||||
+
|
||||
+void Fl_X::set_default_icons(const Fl_RGB_Image *icons[], int count) {
|
||||
+ const Fl_RGB_Image *best_big, *best_small;
|
||||
+
|
||||
+ if (default_big_icon != NULL)
|
||||
+ DestroyIcon(default_big_icon);
|
||||
+ if (default_small_icon != NULL)
|
||||
+ DestroyIcon(default_small_icon);
|
||||
+
|
||||
+ best_big = find_best_icon(GetSystemMetrics(SM_CXICON), icons, count);
|
||||
+ best_small = find_best_icon(GetSystemMetrics(SM_CXSMICON), icons, count);
|
||||
+
|
||||
+ if (best_big != NULL)
|
||||
+ default_big_icon = image_to_icon(best_big);
|
||||
+ else
|
||||
+ default_big_icon = NULL;
|
||||
+
|
||||
+ if (best_small != NULL)
|
||||
+ default_small_icon = image_to_icon(best_small);
|
||||
+ else
|
||||
+ default_small_icon = NULL;
|
||||
+}
|
||||
+
|
||||
+void Fl_X::set_default_icons(HICON big_icon, HICON small_icon) {
|
||||
+ if (default_big_icon != NULL)
|
||||
+ DestroyIcon(default_big_icon);
|
||||
+ if (default_small_icon != NULL)
|
||||
+ DestroyIcon(default_small_icon);
|
||||
+
|
||||
+ if (big_icon != NULL)
|
||||
+ default_big_icon = CopyIcon(big_icon);
|
||||
+ if (small_icon != NULL)
|
||||
+ default_small_icon = CopyIcon(small_icon);
|
||||
+}
|
||||
+
|
||||
+void Fl_X::set_icons() {
|
||||
+ HICON big_icon, small_icon;
|
||||
+
|
||||
+ big_icon = NULL;
|
||||
+ small_icon = NULL;
|
||||
+
|
||||
+ if (w->icon_->count) {
|
||||
+ const Fl_RGB_Image *best_big, *best_small;
|
||||
+
|
||||
+ best_big = find_best_icon(GetSystemMetrics(SM_CXICON),
|
||||
+ (const Fl_RGB_Image **)w->icon_->icons,
|
||||
+ w->icon_->count);
|
||||
+ best_small = find_best_icon(GetSystemMetrics(SM_CXSMICON),
|
||||
+ (const Fl_RGB_Image **)w->icon_->icons,
|
||||
+ w->icon_->count);
|
||||
+
|
||||
+ if (best_big != NULL)
|
||||
+ big_icon = image_to_icon(best_big);
|
||||
+ if (best_small != NULL)
|
||||
+ small_icon = image_to_icon(best_small);
|
||||
+ } else {
|
||||
+ big_icon = default_big_icon;
|
||||
+ small_icon = default_small_icon;
|
||||
+ }
|
||||
+
|
||||
+ if (big_icon != NULL)
|
||||
+ SendMessage(xid, WM_SETICON, ICON_BIG, (LPARAM)big_icon);
|
||||
+ if (small_icon != NULL)
|
||||
+ SendMessage(xid, WM_SETICON, ICON_SMALL, (LPARAM)small_icon);
|
||||
+
|
||||
+ if (w->icon_->count) {
|
||||
+ if (big_icon != NULL)
|
||||
+ DestroyIcon(big_icon);
|
||||
+ if (small_icon != NULL)
|
||||
+ DestroyIcon(small_icon);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void Fl_Window::default_icons(HICON big_icon, HICON small_icon) {
|
||||
+ Fl_X::set_default_icons(big_icon, small_icon);
|
||||
+}
|
||||
+
|
||||
+void Fl_Window::icons(HICON big_icon, HICON small_icon) {
|
||||
+ free_icons();
|
||||
+
|
||||
+ if (big_icon != NULL)
|
||||
+ icon_->big_icon = CopyIcon(big_icon);
|
||||
+ if (small_icon != NULL)
|
||||
+ icon_->small_icon = CopyIcon(small_icon);
|
||||
+
|
||||
+ if (i)
|
||||
+ i->set_icons();
|
||||
+}
|
||||
+
|
||||
+////////////////////////////////////////////////////////////////
|
||||
+
|
||||
+#ifndef IDC_HAND
|
||||
+# define IDC_HAND MAKEINTRESOURCE(32649)
|
||||
+#endif // !IDC_HAND
|
||||
+
|
||||
+int Fl_X::set_cursor(Fl_Cursor c) {
|
||||
+ LPSTR n;
|
||||
+ HCURSOR new_cursor;
|
||||
+
|
||||
+ if (c == FL_CURSOR_NONE)
|
||||
+ new_cursor = NULL;
|
||||
+ else {
|
||||
+ switch (c) {
|
||||
+ case FL_CURSOR_ARROW: n = IDC_ARROW; break;
|
||||
+ case FL_CURSOR_CROSS: n = IDC_CROSS; break;
|
||||
+ case FL_CURSOR_WAIT: n = IDC_WAIT; break;
|
||||
+ case FL_CURSOR_INSERT: n = IDC_IBEAM; break;
|
||||
+ case FL_CURSOR_HAND: n = IDC_HAND; break;
|
||||
+ case FL_CURSOR_HELP: n = IDC_HELP; break;
|
||||
+ case FL_CURSOR_MOVE: n = IDC_SIZEALL; break;
|
||||
+ case FL_CURSOR_N:
|
||||
+ case FL_CURSOR_S:
|
||||
+ // FIXME: Should probably have fallbacks for these instead
|
||||
+ case FL_CURSOR_NS: n = IDC_SIZENS; break;
|
||||
+ case FL_CURSOR_NE:
|
||||
+ case FL_CURSOR_SW:
|
||||
+ // FIXME: Dito.
|
||||
+ case FL_CURSOR_NESW: n = IDC_SIZENESW; break;
|
||||
+ case FL_CURSOR_E:
|
||||
+ case FL_CURSOR_W:
|
||||
+ // FIXME: Dito.
|
||||
+ case FL_CURSOR_WE: n = IDC_SIZEWE; break;
|
||||
+ case FL_CURSOR_SE:
|
||||
+ case FL_CURSOR_NW:
|
||||
+ // FIXME: Dito.
|
||||
+ case FL_CURSOR_NWSE: n = IDC_SIZENWSE; break;
|
||||
+ default:
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ new_cursor = LoadCursor(NULL, n);
|
||||
+ if (new_cursor == NULL)
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ if ((cursor != NULL) && custom_cursor)
|
||||
+ DestroyIcon(cursor);
|
||||
+
|
||||
+ cursor = new_cursor;
|
||||
+ custom_cursor = 0;
|
||||
+
|
||||
+ SetCursor(cursor);
|
||||
+
|
||||
+ return 1;
|
||||
+}
|
||||
+
|
||||
+int Fl_X::set_cursor(const Fl_RGB_Image *image, int hotx, int hoty) {
|
||||
+ HCURSOR new_cursor;
|
||||
+
|
||||
+ new_cursor = image_to_icon(image, false, hotx, hoty);
|
||||
if (new_cursor == NULL)
|
||||
return 0;
|
||||
|
||||
diff -ur fltk-1.3.2.org/src/Fl_Window.cxx fltk-1.3.2/src/Fl_Window.cxx
|
||||
--- fltk-1.3.2.org/src/Fl_Window.cxx 2013-01-16 10:49:40.908130903 +0100
|
||||
+++ fltk-1.3.2/src/Fl_Window.cxx 2013-01-16 10:49:55.557353865 +0100
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <config.h>
|
||||
#include <FL/Fl.H>
|
||||
#include <FL/x.H>
|
||||
+#include <FL/Fl_RGB_Image.H>
|
||||
#include <FL/Fl_Window.H>
|
||||
#include <stdlib.h>
|
||||
#include "flstring.h"
|
||||
@@ -45,7 +46,8 @@
|
||||
}
|
||||
i = 0;
|
||||
xclass_ = 0;
|
||||
- icon_ = 0;
|
||||
+ icon_ = new icon_data;
|
||||
+ memset(icon_, 0, sizeof(*icon_));
|
||||
iconlabel_ = 0;
|
||||
resizable(0);
|
||||
size_range_set = 0;
|
||||
@@ -264,16 +266,68 @@
|
||||
}
|
||||
}
|
||||
|
||||
+void Fl_Window::default_icon(const Fl_RGB_Image *icon) {
|
||||
+ default_icons(&icon, 1);
|
||||
+}
|
||||
+
|
||||
+void Fl_Window::default_icons(const Fl_RGB_Image **icons, int count) {
|
||||
+ Fl_X::set_default_icons(icons, count);
|
||||
+}
|
||||
+
|
||||
+void Fl_Window::icon(const Fl_RGB_Image *icon) {
|
||||
+ icons(&icon, 1);
|
||||
+}
|
||||
+
|
||||
+void Fl_Window::icons(const Fl_RGB_Image **icons, int count) {
|
||||
+ free_icons();
|
||||
+
|
||||
+ if (count > 0) {
|
||||
+ icon_->icons = new Fl_RGB_Image*[count];
|
||||
+ icon_->count = count;
|
||||
+ // FIXME: Fl_RGB_Image lacks const modifiers on methods
|
||||
+ for (int i = 0;i < count;i++)
|
||||
+ icon_->icons[i] = (Fl_RGB_Image*)((Fl_RGB_Image*)icons[i])->copy();
|
||||
+ }
|
||||
+
|
||||
+ if (i)
|
||||
+ i->set_icons();
|
||||
+}
|
||||
+
|
||||
/** Gets the current icon window target dependent data. */
|
||||
const void *Fl_Window::icon() const {
|
||||
- return icon_;
|
||||
+ return icon_->legacy_icon;
|
||||
}
|
||||
|
||||
/** Sets the current icon window target dependent data. */
|
||||
void Fl_Window::icon(const void * ic) {
|
||||
- icon_ = ic;
|
||||
+ free_icons();
|
||||
+ icon_->legacy_icon = ic;
|
||||
}
|
||||
|
||||
+void Fl_Window::free_icons() {
|
||||
+ int i;
|
||||
+
|
||||
+ icon_->legacy_icon = 0L;
|
||||
+
|
||||
+ if (icon_->icons) {
|
||||
+ for (i = 0;i < icon_->count;i++)
|
||||
+ delete icon_->icons[i];
|
||||
+ delete [] icon_->icons;
|
||||
+ icon_->icons = 0L;
|
||||
+ }
|
||||
+
|
||||
+ icon_->count = 0;
|
||||
+
|
||||
+#ifdef WIN32
|
||||
+ if (icon_->big_icon)
|
||||
+ DestroyIcon(icon_->big_icon);
|
||||
+ if (icon_->small_icon)
|
||||
+ DestroyIcon(icon_->small_icon);
|
||||
+
|
||||
+ icon_->big_icon = NULL;
|
||||
+ icon_->small_icon = NULL;
|
||||
+#endif
|
||||
+}
|
||||
|
||||
//
|
||||
// End of "$Id: Fl_Window.cxx 9706 2012-11-06 20:46:14Z matt $".
|
||||
diff -ur 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-16 10:49:40.912227213 +0100
|
||||
+++ fltk-1.3.2/src/Fl_x.cxx 2013-01-16 10:49:55.558137113 +0100
|
||||
@@ -345,6 +345,7 @@
|
||||
Atom fl_NET_WM_STATE;
|
||||
Atom fl_NET_WM_STATE_FULLSCREEN;
|
||||
Atom fl_NET_WORKAREA;
|
||||
+Atom fl_NET_WM_ICON;
|
||||
|
||||
/*
|
||||
X defines 32-bit-entities to have a format value of max. 32,
|
||||
@@ -709,6 +710,7 @@
|
||||
fl_NET_WM_STATE = XInternAtom(d, "_NET_WM_STATE", 0);
|
||||
fl_NET_WM_STATE_FULLSCREEN = XInternAtom(d, "_NET_WM_STATE_FULLSCREEN", 0);
|
||||
fl_NET_WORKAREA = XInternAtom(d, "_NET_WORKAREA", 0);
|
||||
+ fl_NET_WM_ICON = XInternAtom(d, "_NET_WM_ICON", 0);
|
||||
|
||||
if (sizeof(Atom) < 4)
|
||||
atom_bits = sizeof(Atom) * 8;
|
||||
@@ -2138,12 +2140,14 @@
|
||||
fl_show_iconic = 0;
|
||||
showit = 0;
|
||||
}
|
||||
- if (win->icon()) {
|
||||
- hints->icon_pixmap = (Pixmap)win->icon();
|
||||
+ if (win->icon_->legacy_icon) {
|
||||
+ hints->icon_pixmap = (Pixmap)win->icon_->legacy_icon;
|
||||
hints->flags |= IconPixmapHint;
|
||||
}
|
||||
XSetWMHints(fl_display, xp->xid, hints);
|
||||
XFree(hints);
|
||||
+
|
||||
+ xp->set_icons();
|
||||
}
|
||||
|
||||
// set the window type for menu and tooltip windows to avoid animations (compiz)
|
||||
@@ -2263,6 +2267,93 @@
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
+static unsigned long *default_net_wm_icons = 0L;
|
||||
+static size_t default_net_wm_icons_size = 0;
|
||||
+
|
||||
+void icons_to_property(const Fl_RGB_Image *icons[], int count,
|
||||
+ unsigned long **property, size_t *len) {
|
||||
+ size_t sz;
|
||||
+ unsigned long *data;
|
||||
+
|
||||
+ sz = 0;
|
||||
+ for (int i = 0;i < count;i++)
|
||||
+ sz += 2 + icons[i]->w() * icons[i]->h();
|
||||
+
|
||||
+ // FIXME: Might want to sort the icons
|
||||
+
|
||||
+ *property = data = new unsigned long[sz];
|
||||
+ *len = sz;
|
||||
+
|
||||
+ for (int i = 0;i < count;i++) {
|
||||
+ const Fl_RGB_Image *image;
|
||||
+
|
||||
+ image = icons[i];
|
||||
+
|
||||
+ data[0] = image->w();
|
||||
+ data[1] = image->h();
|
||||
+ data += 2;
|
||||
+
|
||||
+ const uchar *in = (const uchar*)*image->data();
|
||||
+ for (int y = 0;y < image->h();y++) {
|
||||
+ for (int x = 0;x < image->w();x++) {
|
||||
+ switch (image->d()) {
|
||||
+ case 1:
|
||||
+ *data = ( 0xff<<24) | (in[0]<<16) | (in[0]<<8) | in[0];
|
||||
+ break;
|
||||
+ case 2:
|
||||
+ *data = (in[1]<<24) | (in[0]<<16) | (in[0]<<8) | in[0];
|
||||
+ break;
|
||||
+ case 3:
|
||||
+ *data = ( 0xff<<24) | (in[0]<<16) | (in[1]<<8) | in[2];
|
||||
+ break;
|
||||
+ case 4:
|
||||
+ *data = (in[3]<<24) | (in[0]<<16) | (in[1]<<8) | in[2];
|
||||
+ break;
|
||||
+ }
|
||||
+ in += image->d();
|
||||
+ data++;
|
||||
+ }
|
||||
+ in += image->ld();
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void Fl_X::set_default_icons(const Fl_RGB_Image *icons[], int count) {
|
||||
+ if (default_net_wm_icons) {
|
||||
+ delete [] default_net_wm_icons;
|
||||
+ default_net_wm_icons = 0L;
|
||||
+ default_net_wm_icons_size = 0;
|
||||
+ }
|
||||
+
|
||||
+ if (count > 0)
|
||||
+ icons_to_property(icons, count,
|
||||
+ &default_net_wm_icons, &default_net_wm_icons_size);
|
||||
+}
|
||||
+
|
||||
+void Fl_X::set_icons() {
|
||||
+ unsigned long *net_wm_icons;
|
||||
+ size_t net_wm_icons_size;
|
||||
+
|
||||
+ if (w->icon_->count) {
|
||||
+ icons_to_property((const Fl_RGB_Image **)w->icon_->icons, w->icon_->count,
|
||||
+ &net_wm_icons, &net_wm_icons_size);
|
||||
+ } else {
|
||||
+ net_wm_icons = default_net_wm_icons;
|
||||
+ net_wm_icons_size = default_net_wm_icons_size;
|
||||
+ }
|
||||
+
|
||||
+ XChangeProperty (fl_display, xid, fl_NET_WM_ICON, XA_CARDINAL, 32,
|
||||
+ PropModeReplace, (unsigned char*) net_wm_icons, net_wm_icons_size);
|
||||
+
|
||||
+ if (w->icon_->count) {
|
||||
+ delete [] net_wm_icons;
|
||||
+ net_wm_icons = 0L;
|
||||
+ net_wm_icons_size = 0;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+////////////////////////////////////////////////////////////////
|
||||
+
|
||||
int Fl_X::set_cursor(Fl_Cursor c) {
|
||||
unsigned int shape;
|
||||
Cursor xc;
|
||||
131
contrib/fltk/10-str2860-fltk-1.3.x-screen_num.patch
Normal file
131
contrib/fltk/10-str2860-fltk-1.3.x-screen_num.patch
Normal file
@@ -0,0 +1,131 @@
|
||||
diff -up fltk-1.3.0r9619/FL/Fl.H.screen_num fltk-1.3.0r9619/FL/Fl.H
|
||||
--- fltk-1.3.0r9619/FL/Fl.H.screen_num 2012-07-03 13:49:28.663085580 +0200
|
||||
+++ fltk-1.3.0r9619/FL/Fl.H 2012-07-03 13:49:28.731084402 +0200
|
||||
@@ -806,6 +806,8 @@ public:
|
||||
static void screen_xywh(int &X, int &Y, int &W, int &H, int mx, int my);
|
||||
static void screen_xywh(int &X, int &Y, int &W, int &H, int n);
|
||||
static void screen_xywh(int &X, int &Y, int &W, int &H, int mx, int my, int mw, int mh);
|
||||
+ static int screen_num(int x, int y);
|
||||
+ static int screen_num(int x, int y, int w, int h);
|
||||
static void screen_dpi(float &h, float &v, int n=0);
|
||||
static void screen_work_area(int &X, int &Y, int &W, int &H, int mx, int my);
|
||||
static void screen_work_area(int &X, int &Y, int &W, int &H, int n);
|
||||
diff -up fltk-1.3.0r9619/src/screen_xywh.cxx.screen_num fltk-1.3.0r9619/src/screen_xywh.cxx
|
||||
--- fltk-1.3.0r9619/src/screen_xywh.cxx.screen_num 2012-03-23 17:47:53.000000000 +0100
|
||||
+++ fltk-1.3.0r9619/src/screen_xywh.cxx 2012-07-03 13:58:01.947195396 +0200
|
||||
@@ -215,21 +215,6 @@ int Fl::screen_count() {
|
||||
return num_screens ? num_screens : 1;
|
||||
}
|
||||
|
||||
-static int find_screen_with_point(int mx, int my) {
|
||||
- int screen = 0;
|
||||
- if (num_screens < 0) screen_init();
|
||||
-
|
||||
- for (int i = 0; i < num_screens; i ++) {
|
||||
- int sx, sy, sw, sh;
|
||||
- Fl::screen_xywh(sx, sy, sw, sh, i);
|
||||
- if ((mx >= sx) && (mx < (sx+sw)) && (my >= sy) && (my < (sy+sh))) {
|
||||
- screen = i;
|
||||
- break;
|
||||
- }
|
||||
- }
|
||||
- return screen;
|
||||
-}
|
||||
-
|
||||
/**
|
||||
Gets the bounding box of a screen
|
||||
that contains the specified screen position \p mx, \p my
|
||||
@@ -237,7 +222,7 @@ static int find_screen_with_point(int mx
|
||||
\param[in] mx, my the absolute screen position
|
||||
*/
|
||||
void Fl::screen_xywh(int &X, int &Y, int &W, int &H, int mx, int my) {
|
||||
- screen_xywh(X, Y, W, H, find_screen_with_point(mx, my));
|
||||
+ screen_xywh(X, Y, W, H, screen_num(mx, my));
|
||||
}
|
||||
|
||||
|
||||
@@ -248,7 +233,7 @@ void Fl::screen_xywh(int &X, int &Y, int
|
||||
\param[in] mx, my the absolute screen position
|
||||
*/
|
||||
void Fl::screen_work_area(int &X, int &Y, int &W, int &H, int mx, int my) {
|
||||
- screen_work_area(X, Y, W, H, find_screen_with_point(mx, my));
|
||||
+ screen_work_area(X, Y, W, H, screen_num(mx, my));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -321,6 +306,38 @@ void Fl::screen_xywh(int &X, int &Y, int
|
||||
#endif // WIN32
|
||||
}
|
||||
|
||||
+/**
|
||||
+ Gets the screen bounding rect for the screen
|
||||
+ which intersects the most with the rectangle
|
||||
+ defined by \p mx, \p my, \p mw, \p mh.
|
||||
+ \param[out] X,Y,W,H the corresponding screen bounding box
|
||||
+ \param[in] mx, my, mw, mh the rectangle to search for intersection with
|
||||
+ \see void screen_xywh(int &X, int &Y, int &W, int &H, int n)
|
||||
+ */
|
||||
+void Fl::screen_xywh(int &X, int &Y, int &W, int &H, int mx, int my, int mw, int mh) {
|
||||
+ screen_xywh(X, Y, W, H, screen_num(mx, my, mw, mh));
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ Gets the screen number of a screen
|
||||
+ that contains the specified screen position \p x, \p y
|
||||
+ \param[in] x, y the absolute screen position
|
||||
+*/
|
||||
+int Fl::screen_num(int x, int y) {
|
||||
+ int screen = 0;
|
||||
+ if (num_screens < 0) screen_init();
|
||||
+
|
||||
+ for (int i = 0; i < num_screens; i ++) {
|
||||
+ int sx, sy, sw, sh;
|
||||
+ Fl::screen_xywh(sx, sy, sw, sh, i);
|
||||
+ if ((x >= sx) && (x < (sx+sw)) && (y >= sy) && (y < (sy+sh))) {
|
||||
+ screen = i;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ return screen;
|
||||
+}
|
||||
+
|
||||
static inline float fl_intersection(int x1, int y1, int w1, int h1,
|
||||
int x2, int y2, int w2, int h2) {
|
||||
if(x1+w1 < x2 || x2+w2 < x1 || y1+h1 < y2 || y2+h2 < y1)
|
||||
@@ -333,30 +350,27 @@ static inline float fl_intersection(int
|
||||
}
|
||||
|
||||
/**
|
||||
- Gets the screen bounding rect for the screen
|
||||
+ Gets the screen number for the screen
|
||||
which intersects the most with the rectangle
|
||||
- defined by \p mx, \p my, \p mw, \p mh.
|
||||
- \param[out] X,Y,W,H the corresponding screen bounding box
|
||||
- \param[in] mx, my, mw, mh the rectangle to search for intersection with
|
||||
- \see void screen_xywh(int &X, int &Y, int &W, int &H, int n)
|
||||
+ defined by \p x, \p y, \p w, \p h.
|
||||
+ \param[in] x, y, w, h the rectangle to search for intersection with
|
||||
*/
|
||||
-void Fl::screen_xywh(int &X, int &Y, int &W, int &H, int mx, int my, int mw, int mh) {
|
||||
+int Fl::screen_num(int x, int y, int w, int h) {
|
||||
int best_screen = 0;
|
||||
float best_intersection = 0.;
|
||||
for(int i = 0; i < Fl::screen_count(); i++) {
|
||||
int sx, sy, sw, sh;
|
||||
Fl::screen_xywh(sx, sy, sw, sh, i);
|
||||
- float sintersection = fl_intersection(mx, my, mw, mh, sx, sy, sw, sh);
|
||||
+ float sintersection = fl_intersection(x, y, w, h, sx, sy, sw, sh);
|
||||
if(sintersection > best_intersection) {
|
||||
best_screen = i;
|
||||
best_intersection = sintersection;
|
||||
}
|
||||
}
|
||||
- screen_xywh(X, Y, W, H, best_screen);
|
||||
+ return best_screen;
|
||||
}
|
||||
|
||||
|
||||
-
|
||||
/**
|
||||
Gets the screen resolution in dots-per-inch for the given screen.
|
||||
\param[out] h, v horizontal and vertical resolution
|
||||
468
contrib/fltk/11-str2860-fltk-1.3.x-multihead.patch
Normal file
468
contrib/fltk/11-str2860-fltk-1.3.x-multihead.patch
Normal file
@@ -0,0 +1,468 @@
|
||||
diff -urp fltk-1.3.2.org/FL/Fl_Window.H fltk-1.3.2/FL/Fl_Window.H
|
||||
--- fltk-1.3.2.org/FL/Fl_Window.H 2013-01-16 10:52:33.017228122 +0100
|
||||
+++ fltk-1.3.2/FL/Fl_Window.H 2013-01-16 10:52:47.876478968 +0100
|
||||
@@ -54,7 +54,7 @@ class Fl_RGB_Image;
|
||||
class FL_EXPORT Fl_Window : public Fl_Group {
|
||||
|
||||
static char *default_xclass_;
|
||||
- // Note: we must use separate statements for each of the following 4 variables,
|
||||
+ // Note: we must use separate statements for each of the following 8 variables,
|
||||
// with the static attribute, otherwise MS VC++ 2008/2010 complains :-(
|
||||
// AlbrechtS 04/2012
|
||||
#if FLTK_ABI_VERSION < 10301
|
||||
@@ -73,6 +73,22 @@ class FL_EXPORT Fl_Window : public Fl_Gr
|
||||
static // when these members are static, ABI compatibility with 1.3.0 is respected
|
||||
#endif
|
||||
int no_fullscreen_h;
|
||||
+#if FLTK_ABI_VERSION < 10302
|
||||
+ static // when these members are static, ABI compatibility with 1.3.0 is respected
|
||||
+#endif
|
||||
+ int fullscreen_screen_top;
|
||||
+#if FLTK_ABI_VERSION < 10302
|
||||
+ static // when these members are static, ABI compatibility with 1.3.0 is respected
|
||||
+#endif
|
||||
+ int fullscreen_screen_bottom;
|
||||
+#if FLTK_ABI_VERSION < 10302
|
||||
+ static // when these members are static, ABI compatibility with 1.3.0 is respected
|
||||
+#endif
|
||||
+ int fullscreen_screen_left;
|
||||
+#if FLTK_ABI_VERSION < 10302
|
||||
+ static // when these members are static, ABI compatibility with 1.3.0 is respected
|
||||
+#endif
|
||||
+ int fullscreen_screen_right;
|
||||
|
||||
friend class Fl_X;
|
||||
Fl_X *i; // points at the system-specific stuff
|
||||
@@ -430,13 +446,15 @@ public:
|
||||
*/
|
||||
void show(int argc, char **argv);
|
||||
/**
|
||||
- Makes the window completely fill the screen, without any window
|
||||
- manager border visible. You must use fullscreen_off() to undo
|
||||
- this.
|
||||
+ Makes the window completely fill one or more screens, without any
|
||||
+ window manager border visible. You must use fullscreen_off() to
|
||||
+ undo this.
|
||||
|
||||
\note On some platforms, this can result in the keyboard being
|
||||
grabbed. The window may also be recreated, meaning hide() and
|
||||
show() will be called.
|
||||
+
|
||||
+ \see void Fl_Window::fullscreen_screens()
|
||||
*/
|
||||
void fullscreen();
|
||||
/**
|
||||
@@ -453,6 +471,17 @@ public:
|
||||
*/
|
||||
unsigned int fullscreen_active() const { return flags() & FULLSCREEN; }
|
||||
/**
|
||||
+ Sets which screens should be used when this window is in fullscreen
|
||||
+ mode. The window will be resized to the top of the screen with index
|
||||
+ \p top, the bottom of the screen with index \p bottom, etc.
|
||||
+
|
||||
+ If this method is never called, or if any argument is < 0, then the
|
||||
+ window will be resized to fill the screen it is currently on.
|
||||
+
|
||||
+ \see void Fl_Window::fullscreen()
|
||||
+ */
|
||||
+ void fullscreen_screens(int top, int bottom, int left, int right);
|
||||
+ /**
|
||||
Iconifies the window. If you call this when shown() is false
|
||||
it will show() it as an icon. If the window is already
|
||||
iconified this does nothing.
|
||||
diff -urp fltk-1.3.2.org/FL/win32.H fltk-1.3.2/FL/win32.H
|
||||
--- fltk-1.3.2.org/FL/win32.H 2013-01-16 10:52:33.017228122 +0100
|
||||
+++ fltk-1.3.2/FL/win32.H 2013-01-16 10:52:47.876478968 +0100
|
||||
@@ -80,6 +80,7 @@ public:
|
||||
static Fl_X* i(const Fl_Window* w) {return w->i;}
|
||||
static int fake_X_wm(const Fl_Window* w,int &X, int &Y,
|
||||
int &bt,int &bx,int &by);
|
||||
+ void make_fullscreen(int X, int Y, int W, int H);
|
||||
void setwindow(Fl_Window* wi) {w=wi; wi->i=this;}
|
||||
void flush() {w->flush();}
|
||||
void set_minmax(LPMINMAXINFO minmax);
|
||||
diff -urp fltk-1.3.2.org/src/Fl_cocoa.mm fltk-1.3.2/src/Fl_cocoa.mm
|
||||
--- fltk-1.3.2.org/src/Fl_cocoa.mm 2013-01-16 10:52:33.014229574 +0100
|
||||
+++ fltk-1.3.2/src/Fl_cocoa.mm 2013-01-16 10:52:47.877480606 +0100
|
||||
@@ -2438,9 +2438,32 @@ void Fl_X::make(Fl_Window* w)
|
||||
|
||||
NSRect crect;
|
||||
if (w->fullscreen_active()) {
|
||||
- int sx, sy, sw, sh;
|
||||
- Fl::screen_xywh(sx, sy, sw, sh, w->x(), w->y(), w->w(), w->h());
|
||||
- w->resize(sx, sy, sw, sh);
|
||||
+ int top, bottom, left, right;
|
||||
+ int sx, sy, sw, sh, X, Y, W, H;
|
||||
+
|
||||
+ top = w->fullscreen_screen_top;
|
||||
+ bottom = w->fullscreen_screen_bottom;
|
||||
+ left = w->fullscreen_screen_left;
|
||||
+ right = w->fullscreen_screen_right;
|
||||
+
|
||||
+ if ((top < 0) || (bottom < 0) || (left < 0) || (right < 0)) {
|
||||
+ top = Fl::screen_num(w->x(), w->y(), w->w(), w->h());
|
||||
+ bottom = top;
|
||||
+ left = top;
|
||||
+ right = top;
|
||||
+ }
|
||||
+
|
||||
+ Fl::screen_xywh(sx, sy, sw, sh, top);
|
||||
+ Y = sy;
|
||||
+ Fl::screen_xywh(sx, sy, sw, sh, bottom);
|
||||
+ H = sy + sh - Y;
|
||||
+ Fl::screen_xywh(sx, sy, sw, sh, left);
|
||||
+ X = sx;
|
||||
+ Fl::screen_xywh(sx, sy, sw, sh, right);
|
||||
+ W = sx + sw - X;
|
||||
+
|
||||
+ w->resize(X, Y, W, H);
|
||||
+
|
||||
winstyle = NSBorderlessWindowMask;
|
||||
winlevel = NSStatusWindowLevel;
|
||||
}
|
||||
diff -urp fltk-1.3.2.org/src/Fl_win32.cxx fltk-1.3.2/src/Fl_win32.cxx
|
||||
--- fltk-1.3.2.org/src/Fl_win32.cxx 2013-01-16 10:52:33.019230734 +0100
|
||||
+++ fltk-1.3.2/src/Fl_win32.cxx 2013-01-16 10:52:47.878480504 +0100
|
||||
@@ -1493,7 +1493,6 @@ int Fl_X::fake_X_wm(const Fl_Window* w,i
|
||||
Y+=yoff;
|
||||
|
||||
if (w->fullscreen_active()) {
|
||||
- X = Y = 0;
|
||||
bx = by = bt = 0;
|
||||
}
|
||||
|
||||
@@ -1547,19 +1546,42 @@ void Fl_Window::resize(int X,int Y,int W
|
||||
}
|
||||
}
|
||||
|
||||
-static void make_fullscreen(Fl_Window *w, Window xid, int X, int Y, int W, int H) {
|
||||
+void Fl_X::make_fullscreen(int X, int Y, int W, int H) {
|
||||
+ int top, bottom, left, right;
|
||||
int sx, sy, sw, sh;
|
||||
- Fl::screen_xywh(sx, sy, sw, sh, X, Y, W, H);
|
||||
+
|
||||
+ top = w->fullscreen_screen_top;
|
||||
+ bottom = w->fullscreen_screen_bottom;
|
||||
+ left = w->fullscreen_screen_left;
|
||||
+ right = w->fullscreen_screen_right;
|
||||
+
|
||||
+ if ((top < 0) || (bottom < 0) || (left < 0) || (right < 0)) {
|
||||
+ top = Fl::screen_num(X, Y, W, H);
|
||||
+ bottom = top;
|
||||
+ left = top;
|
||||
+ right = top;
|
||||
+ }
|
||||
+
|
||||
+ Fl::screen_xywh(sx, sy, sw, sh, top);
|
||||
+ Y = sy;
|
||||
+ Fl::screen_xywh(sx, sy, sw, sh, bottom);
|
||||
+ H = sy + sh - Y;
|
||||
+ Fl::screen_xywh(sx, sy, sw, sh, left);
|
||||
+ X = sx;
|
||||
+ Fl::screen_xywh(sx, sy, sw, sh, right);
|
||||
+ W = sx + sw - X;
|
||||
+
|
||||
DWORD flags = GetWindowLong(xid, GWL_STYLE);
|
||||
flags = flags & ~(WS_THICKFRAME|WS_CAPTION);
|
||||
SetWindowLong(xid, GWL_STYLE, flags);
|
||||
+
|
||||
// SWP_NOSENDCHANGING is so that we can override size limits
|
||||
- SetWindowPos(xid, HWND_TOP, sx, sy, sw, sh, SWP_NOSENDCHANGING | SWP_FRAMECHANGED);
|
||||
+ SetWindowPos(xid, HWND_TOP, X, Y, W, H, SWP_NOSENDCHANGING | SWP_FRAMECHANGED);
|
||||
}
|
||||
|
||||
void Fl_Window::fullscreen_x() {
|
||||
_set_fullscreen();
|
||||
- make_fullscreen(this, fl_xid(this), x(), y(), w(), h());
|
||||
+ i->make_fullscreen(x(), y(), w(), h());
|
||||
Fl::handle(FL_FULLSCREEN, this);
|
||||
}
|
||||
|
||||
@@ -1814,8 +1836,8 @@ Fl_X* Fl_X::make(Fl_Window* w) {
|
||||
monitor the window was placed on. */
|
||||
RECT rect;
|
||||
GetWindowRect(x->xid, &rect);
|
||||
- make_fullscreen(w, x->xid, rect.left, rect.top,
|
||||
- rect.right - rect.left, rect.bottom - rect.top);
|
||||
+ x->make_fullscreen(rect.left, rect.top,
|
||||
+ rect.right - rect.left, rect.bottom - rect.top);
|
||||
}
|
||||
|
||||
x->next = Fl_X::first;
|
||||
diff -urp fltk-1.3.2.org/src/Fl_Window_fullscreen.cxx fltk-1.3.2/src/Fl_Window_fullscreen.cxx
|
||||
--- fltk-1.3.2.org/src/Fl_Window_fullscreen.cxx 2012-11-06 21:46:14.000000000 +0100
|
||||
+++ fltk-1.3.2/src/Fl_Window_fullscreen.cxx 2013-01-16 10:52:47.879480608 +0100
|
||||
@@ -36,6 +36,10 @@ int Fl_Window::no_fullscreen_x = 0;
|
||||
int Fl_Window::no_fullscreen_y = 0;
|
||||
int Fl_Window::no_fullscreen_w = 0;
|
||||
int Fl_Window::no_fullscreen_h = 0;
|
||||
+int Fl_Window::fullscreen_screen_top = -1;
|
||||
+int Fl_Window::fullscreen_screen_bottom = -1;
|
||||
+int Fl_Window::fullscreen_screen_left = -1;
|
||||
+int Fl_Window::fullscreen_screen_right = -1;
|
||||
#endif
|
||||
|
||||
void Fl_Window::border(int b) {
|
||||
@@ -95,6 +99,23 @@ void Fl_Window::fullscreen_off() {
|
||||
fullscreen_off(no_fullscreen_x, no_fullscreen_y, no_fullscreen_w, no_fullscreen_h);
|
||||
}
|
||||
|
||||
+void Fl_Window::fullscreen_screens(int top, int bottom, int left, int right) {
|
||||
+ if ((top < 0) || (bottom < 0) || (left < 0) || (right < 0)) {
|
||||
+ fullscreen_screen_top = -1;
|
||||
+ fullscreen_screen_bottom = -1;
|
||||
+ fullscreen_screen_left = -1;
|
||||
+ fullscreen_screen_right = -1;
|
||||
+ } else {
|
||||
+ fullscreen_screen_top = top;
|
||||
+ fullscreen_screen_bottom = bottom;
|
||||
+ fullscreen_screen_left = left;
|
||||
+ fullscreen_screen_right = right;
|
||||
+ }
|
||||
+
|
||||
+ if (shown() && (flags() & Fl_Widget::FULLSCREEN))
|
||||
+ fullscreen_x();
|
||||
+}
|
||||
+
|
||||
|
||||
//
|
||||
// End of "$Id: Fl_Window_fullscreen.cxx 9706 2012-11-06 20:46:14Z matt $".
|
||||
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-16 10:52:33.020228202 +0100
|
||||
+++ fltk-1.3.2/src/Fl_x.cxx 2013-01-16 10:52:47.880480556 +0100
|
||||
@@ -344,6 +344,7 @@ Atom fl_NET_WM_ICON_NAME; // utf8 aware
|
||||
Atom fl_NET_SUPPORTING_WM_CHECK;
|
||||
Atom fl_NET_WM_STATE;
|
||||
Atom fl_NET_WM_STATE_FULLSCREEN;
|
||||
+Atom fl_NET_WM_FULLSCREEN_MONITORS;
|
||||
Atom fl_NET_WORKAREA;
|
||||
Atom fl_NET_WM_ICON;
|
||||
|
||||
@@ -709,6 +710,7 @@ void fl_open_display(Display* d) {
|
||||
fl_NET_SUPPORTING_WM_CHECK = XInternAtom(d, "_NET_SUPPORTING_WM_CHECK", 0);
|
||||
fl_NET_WM_STATE = XInternAtom(d, "_NET_WM_STATE", 0);
|
||||
fl_NET_WM_STATE_FULLSCREEN = XInternAtom(d, "_NET_WM_STATE_FULLSCREEN", 0);
|
||||
+ fl_NET_WM_FULLSCREEN_MONITORS = XInternAtom(d, "_NET_WM_FULLSCREEN_MONITORS", 0);
|
||||
fl_NET_WORKAREA = XInternAtom(d, "_NET_WORKAREA", 0);
|
||||
fl_NET_WM_ICON = XInternAtom(d, "_NET_WM_ICON", 0);
|
||||
|
||||
@@ -1872,22 +1874,30 @@ void Fl_Window::resize(int X,int Y,int W
|
||||
#define _NET_WM_STATE_ADD 1 /* add/set property */
|
||||
#define _NET_WM_STATE_TOGGLE 2 /* toggle property */
|
||||
|
||||
-static void send_wm_state_event(Window wnd, int add, Atom prop) {
|
||||
+static void send_wm_event(Window wnd, Atom message,
|
||||
+ unsigned long d0, unsigned long d1=0,
|
||||
+ unsigned long d2=0, unsigned long d3=0,
|
||||
+ unsigned long d4=0) {
|
||||
XEvent e;
|
||||
e.xany.type = ClientMessage;
|
||||
e.xany.window = wnd;
|
||||
- e.xclient.message_type = fl_NET_WM_STATE;
|
||||
+ e.xclient.message_type = message;
|
||||
e.xclient.format = 32;
|
||||
- e.xclient.data.l[0] = add ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
|
||||
- e.xclient.data.l[1] = prop;
|
||||
- e.xclient.data.l[2] = 0;
|
||||
- e.xclient.data.l[3] = 0;
|
||||
- e.xclient.data.l[4] = 0;
|
||||
+ e.xclient.data.l[0] = d0;
|
||||
+ e.xclient.data.l[1] = d1;
|
||||
+ e.xclient.data.l[2] = d2;
|
||||
+ e.xclient.data.l[3] = d3;
|
||||
+ e.xclient.data.l[4] = d4;
|
||||
XSendEvent(fl_display, RootWindow(fl_display, fl_screen),
|
||||
0, SubstructureNotifyMask | SubstructureRedirectMask,
|
||||
&e);
|
||||
}
|
||||
|
||||
+static void send_wm_state_event(Window wnd, int add, Atom prop) {
|
||||
+ send_wm_event(wnd, fl_NET_WM_STATE,
|
||||
+ add ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE, prop);
|
||||
+}
|
||||
+
|
||||
int Fl_X::ewmh_supported() {
|
||||
static int result = -1;
|
||||
|
||||
@@ -1911,6 +1921,22 @@ int Fl_X::ewmh_supported() {
|
||||
/* Change an existing window to fullscreen */
|
||||
void Fl_Window::fullscreen_x() {
|
||||
if (Fl_X::ewmh_supported()) {
|
||||
+ int top, bottom, left, right;
|
||||
+
|
||||
+ top = fullscreen_screen_top;
|
||||
+ bottom = fullscreen_screen_bottom;
|
||||
+ left = fullscreen_screen_left;
|
||||
+ right = fullscreen_screen_right;
|
||||
+
|
||||
+ if ((top < 0) || (bottom < 0) || (left < 0) || (right < 0)) {
|
||||
+ top = Fl::screen_num(x(), y(), w(), h());
|
||||
+ bottom = top;
|
||||
+ left = top;
|
||||
+ right = top;
|
||||
+ }
|
||||
+
|
||||
+ send_wm_event(fl_xid(this), fl_NET_WM_FULLSCREEN_MONITORS,
|
||||
+ top, bottom, left, right);
|
||||
send_wm_state_event(fl_xid(this), 1, fl_NET_WM_STATE_FULLSCREEN);
|
||||
} else {
|
||||
_set_fullscreen();
|
||||
@@ -1997,7 +2023,7 @@ void Fl_X::make_xid(Fl_Window* win, XVis
|
||||
// force the window to be on-screen. Usually the X window manager
|
||||
// does this, but a few don't, so we do it here for consistency:
|
||||
int scr_x, scr_y, scr_w, scr_h;
|
||||
- Fl::screen_xywh(scr_x, scr_y, scr_w, scr_h, X, Y);
|
||||
+ Fl::screen_xywh(scr_x, scr_y, scr_w, scr_h, X, Y, W, H);
|
||||
|
||||
if (win->border()) {
|
||||
// ensure border is on screen:
|
||||
@@ -2026,6 +2052,23 @@ void Fl_X::make_xid(Fl_Window* win, XVis
|
||||
return;
|
||||
}
|
||||
|
||||
+ // Compute which screen(s) we should be on if we want to go fullscreen
|
||||
+ int fullscreen_top, fullscreen_bottom, fullscreen_left, fullscreen_right;
|
||||
+
|
||||
+ fullscreen_top = win->fullscreen_screen_top;
|
||||
+ fullscreen_bottom = win->fullscreen_screen_bottom;
|
||||
+ fullscreen_left = win->fullscreen_screen_left;
|
||||
+ fullscreen_right = win->fullscreen_screen_right;
|
||||
+
|
||||
+ if ((fullscreen_top < 0) || (fullscreen_bottom < 0) ||
|
||||
+ (fullscreen_left < 0) || (fullscreen_right < 0)) {
|
||||
+ fullscreen_top = Fl::screen_num(X, Y, W, H);
|
||||
+ fullscreen_bottom = fullscreen_top;
|
||||
+ fullscreen_left = fullscreen_top;
|
||||
+ fullscreen_right = fullscreen_top;
|
||||
+ }
|
||||
+
|
||||
+
|
||||
ulong root = win->parent() ?
|
||||
fl_xid(win->window()) : RootWindow(fl_display, fl_screen);
|
||||
|
||||
@@ -2049,9 +2092,17 @@ void Fl_X::make_xid(Fl_Window* win, XVis
|
||||
// border, and cannot grab without an existing window. Besides,
|
||||
// there is no clear_override().
|
||||
if (win->flags() & Fl_Widget::FULLSCREEN && !Fl_X::ewmh_supported()) {
|
||||
+ int sx, sy, sw, sh;
|
||||
attr.override_redirect = 1;
|
||||
mask |= CWOverrideRedirect;
|
||||
- Fl::screen_xywh(X, Y, W, H, X, Y, W, H);
|
||||
+ Fl::screen_xywh(sx, sy, sw, sh, fullscreen_left);
|
||||
+ X = sx;
|
||||
+ Fl::screen_xywh(sx, sy, sw, sh, fullscreen_right);
|
||||
+ W = sx + sw - X;
|
||||
+ Fl::screen_xywh(sx, sy, sw, sh, fullscreen_top);
|
||||
+ Y = sy;
|
||||
+ Fl::screen_xywh(sx, sy, sw, sh, fullscreen_bottom);
|
||||
+ H = sy + sh - Y;
|
||||
}
|
||||
|
||||
if (fl_background_pixel >= 0) {
|
||||
@@ -2122,6 +2173,13 @@ void Fl_X::make_xid(Fl_Window* win, XVis
|
||||
|
||||
// If asked for, create fullscreen
|
||||
if (win->flags() & Fl_Widget::FULLSCREEN && Fl_X::ewmh_supported()) {
|
||||
+ unsigned long data[4];
|
||||
+ data[0] = fullscreen_top;
|
||||
+ data[1] = fullscreen_bottom;
|
||||
+ data[2] = fullscreen_left;
|
||||
+ data[3] = fullscreen_right;
|
||||
+ XChangeProperty (fl_display, xp->xid, fl_NET_WM_FULLSCREEN_MONITORS, XA_ATOM, 32,
|
||||
+ PropModeReplace, (unsigned char*) data, 4);
|
||||
XChangeProperty (fl_display, xp->xid, fl_NET_WM_STATE, XA_ATOM, 32,
|
||||
PropModeAppend, (unsigned char*) &fl_NET_WM_STATE_FULLSCREEN, 1);
|
||||
}
|
||||
diff -urp fltk-1.3.2.org/test/fullscreen.cxx fltk-1.3.2/test/fullscreen.cxx
|
||||
--- fltk-1.3.2.org/test/fullscreen.cxx 2012-06-14 17:09:46.000000000 +0200
|
||||
+++ fltk-1.3.2/test/fullscreen.cxx 2013-01-16 10:52:47.881104801 +0100
|
||||
@@ -127,7 +127,7 @@ class fullscreen_window : public Fl_Sing
|
||||
fullscreen_window(int W, int H, const char *t=0);
|
||||
int handle (int e);
|
||||
Fl_Toggle_Light_Button *b3;
|
||||
-
|
||||
+ Fl_Toggle_Light_Button *b4;
|
||||
};
|
||||
|
||||
fullscreen_window::fullscreen_window(int W, int H, const char *t) : Fl_Single_Window(W, H, t) {
|
||||
@@ -170,23 +170,54 @@ void border_cb(Fl_Widget *o, void *p) {
|
||||
#endif
|
||||
}
|
||||
|
||||
-int px,py,pw,ph;
|
||||
Fl_Button *border_button;
|
||||
void fullscreen_cb(Fl_Widget *o, void *p) {
|
||||
Fl_Window *w = (Fl_Window *)p;
|
||||
int d = ((Fl_Button *)o)->value();
|
||||
if (d) {
|
||||
- px = w->x();
|
||||
- py = w->y();
|
||||
- pw = w->w();
|
||||
- ph = w->h();
|
||||
+ if (((fullscreen_window*)w)->b4->value()) {
|
||||
+ int top, bottom, left, right;
|
||||
+ int top_y, bottom_y, left_x, right_x;
|
||||
+
|
||||
+ int sx, sy, sw, sh;
|
||||
+
|
||||
+ top = bottom = left = right = 0;
|
||||
+
|
||||
+ Fl::screen_xywh(sx, sy, sw, sh, 0);
|
||||
+ top_y = sy;
|
||||
+ bottom_y = sy + sh;
|
||||
+ left_x = sx;
|
||||
+ right_x = sx + sw;
|
||||
+
|
||||
+ for (int i = 1;i < Fl::screen_count();i++) {
|
||||
+ Fl::screen_xywh(sx, sy, sw, sh, i);
|
||||
+ if (sy < top_y) {
|
||||
+ top = i;
|
||||
+ top_y = sy;
|
||||
+ }
|
||||
+ if ((sy + sh) > bottom_y) {
|
||||
+ bottom = i;
|
||||
+ bottom_y = sy + sh;
|
||||
+ }
|
||||
+ if (sx < left_x) {
|
||||
+ left = i;
|
||||
+ left_x = sx;
|
||||
+ }
|
||||
+ if ((sx + sw) > right_x) {
|
||||
+ right = i;
|
||||
+ right_x = sx + sw;
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
+ w->fullscreen_screens(top, bottom, left, right);
|
||||
+ } else {
|
||||
+ w->fullscreen_screens(-1, -1, -1, -1);
|
||||
+ }
|
||||
w->fullscreen();
|
||||
- w->override();
|
||||
#ifndef WIN32 // update our border state in case border was turned off
|
||||
border_button->value(w->border());
|
||||
#endif
|
||||
} else {
|
||||
- //w->fullscreen_off(px,py,pw,ph);
|
||||
w->fullscreen_off();
|
||||
}
|
||||
}
|
||||
@@ -219,7 +250,7 @@ void exit_cb(Fl_Widget *, void *) {
|
||||
exit(0);
|
||||
}
|
||||
|
||||
-#define NUMB 7
|
||||
+#define NUMB 8
|
||||
|
||||
int twowindow = 0;
|
||||
int initfull = 0;
|
||||
@@ -284,6 +315,9 @@ int main(int argc, char **argv) {
|
||||
window.b3->callback(fullscreen_cb,w);
|
||||
y+=30;
|
||||
|
||||
+ window.b4 = new Fl_Toggle_Light_Button(50,y,window.w()-60,30,"All Screens");
|
||||
+ y+=30;
|
||||
+
|
||||
Fl_Button eb(50,y,window.w()-60,30,"Exit");
|
||||
eb.callback(exit_cb);
|
||||
y+=30;
|
||||
203
contrib/fltk/12-fltk-1.3.2-xhandlers.patch
Normal file
203
contrib/fltk/12-fltk-1.3.2-xhandlers.patch
Normal file
@@ -0,0 +1,203 @@
|
||||
diff -up fltk-1.3.2/FL/Fl.H.xhandlers fltk-1.3.2/FL/Fl.H
|
||||
--- fltk-1.3.2/FL/Fl.H.xhandlers 2014-07-22 15:23:18.087334467 +0200
|
||||
+++ fltk-1.3.2/FL/Fl.H 2014-07-22 15:23:18.094334589 +0200
|
||||
@@ -96,6 +96,9 @@ typedef void (*Fl_FD_Handler)(FL_SOCKET
|
||||
/** Signature of add_handler functions passed as parameters */
|
||||
typedef int (*Fl_Event_Handler)(int event);
|
||||
|
||||
+/** Signature of add_system_handler functions passed as parameters */
|
||||
+typedef int (*Fl_System_Handler)(void *event, void *data);
|
||||
+
|
||||
/** Signature of set_abort functions passed as parameters */
|
||||
typedef void (*Fl_Abort_Handler)(const char *format,...);
|
||||
|
||||
@@ -712,6 +715,8 @@ public:
|
||||
static void focus(Fl_Widget*);
|
||||
static void add_handler(Fl_Event_Handler h);
|
||||
static void remove_handler(Fl_Event_Handler h);
|
||||
+ static void add_system_handler(Fl_System_Handler h, void *data);
|
||||
+ static void remove_system_handler(Fl_System_Handler h);
|
||||
static void event_dispatch(Fl_Event_Dispatch d);
|
||||
static Fl_Event_Dispatch event_dispatch();
|
||||
/** @} */
|
||||
diff -up fltk-1.3.2/src/Fl_cocoa.mm.xhandlers fltk-1.3.2/src/Fl_cocoa.mm
|
||||
--- fltk-1.3.2/src/Fl_cocoa.mm.xhandlers 2014-07-22 15:23:18.089334502 +0200
|
||||
+++ fltk-1.3.2/src/Fl_cocoa.mm 2014-07-22 15:23:18.095334607 +0200
|
||||
@@ -1269,6 +1269,8 @@ void fl_open_callback(void (*cb)(const c
|
||||
}
|
||||
@end
|
||||
|
||||
+extern int fl_send_system_handlers(void *e);
|
||||
+
|
||||
static void clipboard_check(void);
|
||||
|
||||
@implementation FLApplication
|
||||
@@ -1276,6 +1278,10 @@ static void clipboard_check(void);
|
||||
{
|
||||
// update clipboard status
|
||||
clipboard_check();
|
||||
+
|
||||
+ if (fl_send_system_handlers(theEvent))
|
||||
+ return;
|
||||
+
|
||||
NSEventType type = [theEvent type];
|
||||
if (type == NSLeftMouseDown) {
|
||||
fl_lock_function();
|
||||
diff -up fltk-1.3.2/src/Fl.cxx.xhandlers fltk-1.3.2/src/Fl.cxx
|
||||
--- fltk-1.3.2/src/Fl.cxx.xhandlers 2014-07-22 15:23:18.085334432 +0200
|
||||
+++ fltk-1.3.2/src/Fl.cxx 2014-07-22 15:23:18.095334607 +0200
|
||||
@@ -891,6 +891,83 @@ static int send_handlers(int e) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
+
|
||||
+////////////////////////////////////////////////////////////////
|
||||
+// System event handlers:
|
||||
+
|
||||
+
|
||||
+struct system_handler_link {
|
||||
+ Fl_System_Handler handle;
|
||||
+ void *data;
|
||||
+ system_handler_link *next;
|
||||
+};
|
||||
+
|
||||
+
|
||||
+static system_handler_link *sys_handlers = 0;
|
||||
+
|
||||
+
|
||||
+/**
|
||||
+ \brief Install a function to intercept system events.
|
||||
+
|
||||
+ FLTK calls each of these functions as soon as a new system event is
|
||||
+ received. The processing will stop at the first function to return
|
||||
+ non-zero. If all functions return zero then the event is passed on
|
||||
+ for normal handling by FLTK.
|
||||
+
|
||||
+ Each function will be called with a pointer to the system event as
|
||||
+ the first argument and \p data as the second argument. The system
|
||||
+ event pointer will always be void *, but will point to different
|
||||
+ objects depending on the platform:
|
||||
+ - X11: XEvent
|
||||
+ - Windows: MSG
|
||||
+ - OS X: NSEvent
|
||||
+
|
||||
+ \param ha The event handler function to register
|
||||
+ \param data User data to include on each call
|
||||
+
|
||||
+ \see Fl::remove_system_handler(Fl_System_Handler)
|
||||
+*/
|
||||
+void Fl::add_system_handler(Fl_System_Handler ha, void *data) {
|
||||
+ system_handler_link *l = new system_handler_link;
|
||||
+ l->handle = ha;
|
||||
+ l->data = data;
|
||||
+ l->next = sys_handlers;
|
||||
+ sys_handlers = l;
|
||||
+}
|
||||
+
|
||||
+
|
||||
+/**
|
||||
+ Removes a previously added system event handler.
|
||||
+
|
||||
+ \param ha The event handler function to remove
|
||||
+
|
||||
+ \see Fl::add_system_handler(Fl_System_Handler)
|
||||
+*/
|
||||
+void Fl::remove_system_handler(Fl_System_Handler ha) {
|
||||
+ system_handler_link *l, *p;
|
||||
+
|
||||
+ // Search for the handler in the list...
|
||||
+ for (l = sys_handlers, p = 0; l && l->handle != ha; p = l, l = l->next);
|
||||
+
|
||||
+ if (l) {
|
||||
+ // Found it, so remove it from the list...
|
||||
+ if (p) p->next = l->next;
|
||||
+ else sys_handlers = l->next;
|
||||
+
|
||||
+ // And free the record...
|
||||
+ delete l;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+int fl_send_system_handlers(void *e) {
|
||||
+ for (const system_handler_link *hl = sys_handlers; hl; hl = hl->next) {
|
||||
+ if (hl->handle(e, hl->data))
|
||||
+ return 1;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
Fl_Widget* fl_oldfocus; // kludge for Fl_Group...
|
||||
diff -up fltk-1.3.2/src/Fl_win32.cxx.xhandlers fltk-1.3.2/src/Fl_win32.cxx
|
||||
--- fltk-1.3.2/src/Fl_win32.cxx.xhandlers 2014-07-22 15:23:18.092334554 +0200
|
||||
+++ fltk-1.3.2/src/Fl_win32.cxx 2014-07-22 15:24:44.682843610 +0200
|
||||
@@ -336,6 +336,8 @@ void* Fl::thread_message() {
|
||||
return r;
|
||||
}
|
||||
|
||||
+extern int fl_send_system_handlers(void *e);
|
||||
+
|
||||
IActiveIMMApp *fl_aimm = NULL;
|
||||
MSG fl_msg;
|
||||
|
||||
@@ -401,23 +403,21 @@ int fl_wait(double time_to_wait) {
|
||||
|
||||
// Execute the message we got, and all other pending messages:
|
||||
// have_message = PeekMessage(&fl_msg, NULL, 0, 0, PM_REMOVE);
|
||||
- have_message = PeekMessageW(&fl_msg, NULL, 0, 0, PM_REMOVE);
|
||||
- if (have_message > 0) {
|
||||
- while (have_message != 0 && have_message != -1) {
|
||||
- if (fl_msg.message == fl_wake_msg) {
|
||||
- // Used for awaking wait() from another thread
|
||||
- thread_message_ = (void*)fl_msg.wParam;
|
||||
- Fl_Awake_Handler func;
|
||||
- void *data;
|
||||
- while (Fl::get_awake_handler_(func, data)==0) {
|
||||
- func(data);
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- TranslateMessage(&fl_msg);
|
||||
- DispatchMessageW(&fl_msg);
|
||||
- have_message = PeekMessageW(&fl_msg, NULL, 0, 0, PM_REMOVE);
|
||||
+ while ((have_message = PeekMessageW(&fl_msg, NULL, 0, 0, PM_REMOVE)) > 0) {
|
||||
+ if (fl_send_system_handlers(&fl_msg))
|
||||
+ continue;
|
||||
+
|
||||
+ if (fl_msg.message == fl_wake_msg) {
|
||||
+ // Used for awaking wait() from another thread
|
||||
+ thread_message_ = (void*)fl_msg.wParam;
|
||||
+ Fl_Awake_Handler func;
|
||||
+ void *data;
|
||||
+ while (Fl::get_awake_handler_(func, data)==0)
|
||||
+ func(data);
|
||||
}
|
||||
+
|
||||
+ TranslateMessage(&fl_msg);
|
||||
+ DispatchMessageW(&fl_msg);
|
||||
}
|
||||
Fl::flush();
|
||||
|
||||
diff -up fltk-1.3.2/src/Fl_x.cxx.xhandlers fltk-1.3.2/src/Fl_x.cxx
|
||||
--- fltk-1.3.2/src/Fl_x.cxx.xhandlers 2014-07-22 15:23:18.093334572 +0200
|
||||
+++ fltk-1.3.2/src/Fl_x.cxx 2014-07-22 15:23:18.096334624 +0200
|
||||
@@ -188,6 +188,8 @@ void Fl::remove_fd(int n) {
|
||||
remove_fd(n, -1);
|
||||
}
|
||||
|
||||
+extern int fl_send_system_handlers(void *e);
|
||||
+
|
||||
#if CONSOLIDATE_MOTION
|
||||
static Fl_Window* send_motion;
|
||||
extern Fl_Window* fl_xmousewin;
|
||||
@@ -198,6 +200,8 @@ static void do_queued_events() {
|
||||
while (XEventsQueued(fl_display,QueuedAfterReading)) {
|
||||
XEvent xevent;
|
||||
XNextEvent(fl_display, &xevent);
|
||||
+ if (fl_send_system_handlers(&xevent))
|
||||
+ continue;
|
||||
fl_handle(xevent);
|
||||
}
|
||||
// we send FL_LEAVE only if the mouse did not enter some other window:
|
||||
582
contrib/fltk/13-fltk-1.3.2-im.patch
Normal file
582
contrib/fltk/13-fltk-1.3.2-im.patch
Normal file
@@ -0,0 +1,582 @@
|
||||
diff -up fltk-1.3.2/FL/Fl.H.im fltk-1.3.2/FL/Fl.H
|
||||
--- fltk-1.3.2/FL/Fl.H.im 2014-09-10 14:40:05.193265424 +0200
|
||||
+++ fltk-1.3.2/FL/Fl.H 2014-09-10 14:40:05.196265471 +0200
|
||||
@@ -699,6 +699,17 @@ public:
|
||||
static int event_inside(const Fl_Widget*);
|
||||
static int test_shortcut(Fl_Shortcut);
|
||||
|
||||
+ /**
|
||||
+ Enables the system input methods facilities. This is the default.
|
||||
+ \see disable_im()
|
||||
+ */
|
||||
+ static void enable_im();
|
||||
+ /**
|
||||
+ Disables the system input methods facilities.
|
||||
+ \see enable_im()
|
||||
+ */
|
||||
+ static void disable_im();
|
||||
+
|
||||
// event destinations:
|
||||
static int handle(int, Fl_Window*);
|
||||
static int handle_(int, Fl_Window*);
|
||||
diff -up fltk-1.3.2/FL/win32.H.im fltk-1.3.2/FL/win32.H
|
||||
--- fltk-1.3.2/FL/win32.H.im 2014-09-10 14:40:05.186265315 +0200
|
||||
+++ fltk-1.3.2/FL/win32.H 2014-09-10 14:40:05.196265471 +0200
|
||||
@@ -102,6 +102,8 @@ extern FL_EXPORT void fl_save_dc( HWND w
|
||||
|
||||
inline Window fl_xid(const Fl_Window* w) { Fl_X *temp = Fl_X::i(w); return temp ? temp->xid : 0; }
|
||||
|
||||
+extern FL_EXPORT void fl_open_display();
|
||||
+
|
||||
#else
|
||||
FL_EXPORT Window fl_xid_(const Fl_Window* w);
|
||||
#define fl_xid(w) fl_xid_(w)
|
||||
diff -up fltk-1.3.2/src/Fl_cocoa.mm.im fltk-1.3.2/src/Fl_cocoa.mm
|
||||
--- fltk-1.3.2/src/Fl_cocoa.mm.im 2014-09-10 14:40:05.193265424 +0200
|
||||
+++ fltk-1.3.2/src/Fl_cocoa.mm 2014-09-10 14:43:41.103642243 +0200
|
||||
@@ -88,6 +88,7 @@ static void createAppleMenu(void);
|
||||
static Fl_Region MacRegionMinusRect(Fl_Region r, int x,int y,int w,int h);
|
||||
static void cocoaMouseHandler(NSEvent *theEvent);
|
||||
static int calc_mac_os_version();
|
||||
+static void im_update(void);
|
||||
|
||||
static Fl_Quartz_Graphics_Driver fl_quartz_driver;
|
||||
static Fl_Display_Device fl_quartz_display(&fl_quartz_driver);
|
||||
@@ -108,6 +109,30 @@ int fl_mac_os_version = calc_mac_os_vers
|
||||
static int got_events = 0;
|
||||
static Fl_Window* resize_from_system;
|
||||
static int main_screen_height; // height of menubar-containing screen used to convert between Cocoa and FLTK global screen coordinates
|
||||
+static int im_enabled = -1;
|
||||
+
|
||||
+// Carbon functions and definitions
|
||||
+
|
||||
+typedef void *TSMDocumentID;
|
||||
+
|
||||
+extern "C" enum {
|
||||
+ kTSMDocumentEnabledInputSourcesPropertyTag = 'enis' // from Carbon/TextServices.h
|
||||
+};
|
||||
+
|
||||
+// Undocumented voodoo. Taken from Mozilla.
|
||||
+static const int smEnableRomanKybdsOnly = -23;
|
||||
+
|
||||
+typedef TSMDocumentID (*TSMGetActiveDocument_type)(void);
|
||||
+static TSMGetActiveDocument_type TSMGetActiveDocument;
|
||||
+typedef OSStatus (*TSMSetDocumentProperty_type)(TSMDocumentID, OSType, UInt32, void*);
|
||||
+static TSMSetDocumentProperty_type TSMSetDocumentProperty;
|
||||
+typedef OSStatus (*TSMRemoveDocumentProperty_type)(TSMDocumentID, OSType);
|
||||
+static TSMRemoveDocumentProperty_type TSMRemoveDocumentProperty;
|
||||
+typedef CFArrayRef (*TISCreateASCIICapableInputSourceList_type)(void);
|
||||
+static TISCreateASCIICapableInputSourceList_type TISCreateASCIICapableInputSourceList;
|
||||
+
|
||||
+typedef void (*KeyScript_type)(short);
|
||||
+static KeyScript_type KeyScript;
|
||||
|
||||
#if CONSOLIDATE_MOTION
|
||||
static Fl_Window* send_motion;
|
||||
@@ -978,6 +1003,7 @@ void fl_open_callback(void (*cb)(const c
|
||||
#endif
|
||||
{
|
||||
BOOL seen_open_file;
|
||||
+ TSMDocumentID currentDoc;
|
||||
}
|
||||
- (void)windowDidMove:(NSNotification *)notif;
|
||||
- (void)windowDidResize:(NSNotification *)notif;
|
||||
@@ -991,6 +1017,7 @@ void fl_open_callback(void (*cb)(const c
|
||||
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication*)sender;
|
||||
- (void)applicationDidBecomeActive:(NSNotification *)notify;
|
||||
- (void)applicationDidChangeScreenParameters:(NSNotification *)aNotification;
|
||||
+- (void)applicationDidUpdate:(NSNotification *)aNotification;
|
||||
- (void)applicationWillResignActive:(NSNotification *)notify;
|
||||
- (void)applicationWillHide:(NSNotification *)notify;
|
||||
- (void)applicationWillUnhide:(NSNotification *)notify;
|
||||
@@ -1175,6 +1202,23 @@ void fl_open_callback(void (*cb)(const c
|
||||
}
|
||||
Fl::handle(FL_SCREEN_CONFIGURATION_CHANGED, NULL);
|
||||
}
|
||||
+- (void)applicationDidUpdate:(NSNotification *)aNotification
|
||||
+{
|
||||
+ if ((fl_mac_os_version >= 100500) && (im_enabled != -1) &&
|
||||
+ (TSMGetActiveDocument != NULL)) {
|
||||
+ TSMDocumentID newDoc;
|
||||
+ // It is extremely unclear when Cocoa decides to create/update
|
||||
+ // the input context, but debugging reveals that it is done
|
||||
+ // by NSApplication:updateWindows. So check if the input context
|
||||
+ // has shifted after each such run so that we can update our
|
||||
+ // input methods status.
|
||||
+ newDoc = TSMGetActiveDocument();
|
||||
+ if (newDoc != currentDoc) {
|
||||
+ im_update();
|
||||
+ currentDoc = newDoc;
|
||||
+ }
|
||||
+ }
|
||||
+}
|
||||
- (void)applicationWillResignActive:(NSNotification *)notify
|
||||
{
|
||||
fl_lock_function();
|
||||
@@ -1322,6 +1365,13 @@ void fl_open_display() {
|
||||
static char beenHereDoneThat = 0;
|
||||
if ( !beenHereDoneThat ) {
|
||||
beenHereDoneThat = 1;
|
||||
+
|
||||
+ TSMGetActiveDocument = (TSMGetActiveDocument_type)Fl_X::get_carbon_function("TSMGetActiveDocument");
|
||||
+ TSMSetDocumentProperty = (TSMSetDocumentProperty_type)Fl_X::get_carbon_function("TSMSetDocumentProperty");
|
||||
+ TSMRemoveDocumentProperty = (TSMRemoveDocumentProperty_type)Fl_X::get_carbon_function("TSMRemoveDocumentProperty");
|
||||
+ TISCreateASCIICapableInputSourceList = (TISCreateASCIICapableInputSourceList_type)Fl_X::get_carbon_function("TISCreateASCIICapableInputSourceList");
|
||||
+
|
||||
+ KeyScript = (KeyScript_type)Fl_X::get_carbon_function("KeyScript");
|
||||
|
||||
BOOL need_new_nsapp = (NSApp == nil);
|
||||
if (need_new_nsapp) [NSApplication sharedApplication];
|
||||
@@ -1390,6 +1440,66 @@ void fl_open_display() {
|
||||
void fl_close_display() {
|
||||
}
|
||||
|
||||
+// Force a "Roman" or "ASCII" keyboard, which both the Mozilla and
|
||||
+// Safari people seem to think implies turning off advanced IME stuff
|
||||
+// (see nsTSMManager::SyncKeyScript in Mozilla and enableSecureTextInput
|
||||
+// in Safari/Webcore). Should be good enough for us then...
|
||||
+
|
||||
+static void im_update(void) {
|
||||
+ if (fl_mac_os_version >= 100500) {
|
||||
+ TSMDocumentID doc;
|
||||
+
|
||||
+ if ((TSMGetActiveDocument == NULL) ||
|
||||
+ (TSMSetDocumentProperty == NULL) ||
|
||||
+ (TSMRemoveDocumentProperty == NULL) ||
|
||||
+ (TISCreateASCIICapableInputSourceList == NULL))
|
||||
+ return;
|
||||
+
|
||||
+ doc = TSMGetActiveDocument();
|
||||
+
|
||||
+ if (im_enabled)
|
||||
+ TSMRemoveDocumentProperty(doc, kTSMDocumentEnabledInputSourcesPropertyTag);
|
||||
+ else {
|
||||
+ CFArrayRef inputSources;
|
||||
+
|
||||
+ inputSources = TISCreateASCIICapableInputSourceList();
|
||||
+ TSMSetDocumentProperty(doc, kTSMDocumentEnabledInputSourcesPropertyTag,
|
||||
+ sizeof(CFArrayRef), &inputSources);
|
||||
+ CFRelease(inputSources);
|
||||
+ }
|
||||
+ } else {
|
||||
+ if (KeyScript == NULL)
|
||||
+ return;
|
||||
+
|
||||
+ if (im_enabled)
|
||||
+ KeyScript(smKeyEnableKybds);
|
||||
+ else
|
||||
+ KeyScript(smEnableRomanKybdsOnly);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void Fl::enable_im() {
|
||||
+ fl_open_display();
|
||||
+
|
||||
+ im_enabled = 1;
|
||||
+
|
||||
+ if (fl_mac_os_version >= 100500)
|
||||
+ [NSApp updateWindows];
|
||||
+ else
|
||||
+ im_update();
|
||||
+}
|
||||
+
|
||||
+void Fl::disable_im() {
|
||||
+ fl_open_display();
|
||||
+
|
||||
+ im_enabled = 0;
|
||||
+
|
||||
+ if (fl_mac_os_version >= 100500)
|
||||
+ [NSApp updateWindows];
|
||||
+ else
|
||||
+ im_update();
|
||||
+}
|
||||
+
|
||||
|
||||
// Gets the border sizes and the titlebar size
|
||||
static void get_window_frame_sizes(int &bx, int &by, int &bt) {
|
||||
diff -up fltk-1.3.2/src/Fl.cxx.im fltk-1.3.2/src/Fl.cxx
|
||||
--- fltk-1.3.2/src/Fl.cxx.im 2014-09-10 14:40:05.194265440 +0200
|
||||
+++ fltk-1.3.2/src/Fl.cxx 2014-09-10 14:40:05.197265486 +0200
|
||||
@@ -593,45 +593,6 @@ int Fl::run() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
-#ifdef WIN32
|
||||
-
|
||||
-// Function to initialize COM/OLE for usage. This must be done only once.
|
||||
-// We define a flag to register whether we called it:
|
||||
-static char oleInitialized = 0;
|
||||
-
|
||||
-// This calls the Windows function OleInitialize() exactly once.
|
||||
-void fl_OleInitialize() {
|
||||
- if (!oleInitialized) {
|
||||
- OleInitialize(0L);
|
||||
- oleInitialized = 1;
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-// This calls the Windows function OleUninitialize() only, if
|
||||
-// OleInitialize has been called before.
|
||||
-void fl_OleUninitialize() {
|
||||
- if (oleInitialized) {
|
||||
- OleUninitialize();
|
||||
- oleInitialized = 0;
|
||||
- }
|
||||
-}
|
||||
-
|
||||
-class Fl_Win32_At_Exit {
|
||||
-public:
|
||||
- Fl_Win32_At_Exit() { }
|
||||
- ~Fl_Win32_At_Exit() {
|
||||
- fl_free_fonts(); // do some WIN32 cleanup
|
||||
- fl_cleanup_pens();
|
||||
- fl_OleUninitialize();
|
||||
- fl_brush_action(1);
|
||||
- fl_cleanup_dc_list();
|
||||
- }
|
||||
-};
|
||||
-static Fl_Win32_At_Exit win32_at_exit;
|
||||
-#endif
|
||||
-
|
||||
-
|
||||
-
|
||||
/**
|
||||
Waits until "something happens" and then returns. Call this
|
||||
repeatedly to "run" your program. You can also check what happened
|
||||
diff -up fltk-1.3.2/src/Fl_Native_File_Chooser_WIN32.cxx.im fltk-1.3.2/src/Fl_Native_File_Chooser_WIN32.cxx
|
||||
--- fltk-1.3.2/src/Fl_Native_File_Chooser_WIN32.cxx.im 2012-06-26 09:03:46.000000000 +0200
|
||||
+++ fltk-1.3.2/src/Fl_Native_File_Chooser_WIN32.cxx 2014-09-10 14:40:05.197265486 +0200
|
||||
@@ -34,6 +34,7 @@ LPCWSTR utf8towchar(const char *in); //M
|
||||
char *wchartoutf8(LPCWSTR in); //MG
|
||||
|
||||
#include <FL/Fl_Native_File_Chooser.H>
|
||||
+#include <FL/x.H>
|
||||
|
||||
#define LCURLY_CHR '{'
|
||||
#define RCURLY_CHR '}'
|
||||
@@ -41,8 +42,6 @@ char *wchartoutf8(LPCWSTR in); //MG
|
||||
#define RBRACKET_CHR ']'
|
||||
#define MAXFILTERS 80
|
||||
|
||||
-void fl_OleInitialize(); // in Fl.cxx (Windows only)
|
||||
-
|
||||
// STATIC: PRINT WINDOWS 'DOUBLE NULL' STRING (DEBUG)
|
||||
#ifdef DEBUG
|
||||
static void dnullprint(char *wp) {
|
||||
@@ -471,7 +470,7 @@ int CALLBACK Fl_Native_File_Chooser::Dir
|
||||
// SHOW DIRECTORY BROWSER
|
||||
int Fl_Native_File_Chooser::showdir() {
|
||||
// initialize OLE only once
|
||||
- fl_OleInitialize(); // init needed by BIF_USENEWUI
|
||||
+ fl_open_display(); // init needed by BIF_USENEWUI
|
||||
ClearBINF();
|
||||
clear_pathnames();
|
||||
// PARENT WINDOW
|
||||
diff -up fltk-1.3.2/src/Fl_win32.cxx.im fltk-1.3.2/src/Fl_win32.cxx
|
||||
--- fltk-1.3.2/src/Fl_win32.cxx.im 2014-09-10 14:40:05.194265440 +0200
|
||||
+++ fltk-1.3.2/src/Fl_win32.cxx 2014-09-10 14:40:05.197265486 +0200
|
||||
@@ -60,8 +60,6 @@
|
||||
#include <ole2.h>
|
||||
#include <shellapi.h>
|
||||
|
||||
-#include "aimm.h"
|
||||
-
|
||||
//
|
||||
// USE_ASYNC_SELECT - define it if you have WSAAsyncSelect()...
|
||||
// USE_ASYNC_SELECT is OBSOLETED in 1.3 for the following reasons:
|
||||
@@ -121,27 +119,24 @@ static HMODULE get_wsock_mod() {
|
||||
* size and link dependencies.
|
||||
*/
|
||||
static HMODULE s_imm_module = 0;
|
||||
+typedef BOOL (WINAPI* flTypeImmAssociateContextEx)(HWND, HIMC, DWORD);
|
||||
+static flTypeImmAssociateContextEx flImmAssociateContextEx = 0;
|
||||
typedef HIMC (WINAPI* flTypeImmGetContext)(HWND);
|
||||
static flTypeImmGetContext flImmGetContext = 0;
|
||||
typedef BOOL (WINAPI* flTypeImmSetCompositionWindow)(HIMC, LPCOMPOSITIONFORM);
|
||||
static flTypeImmSetCompositionWindow flImmSetCompositionWindow = 0;
|
||||
typedef BOOL (WINAPI* flTypeImmReleaseContext)(HWND, HIMC);
|
||||
static flTypeImmReleaseContext flImmReleaseContext = 0;
|
||||
-typedef BOOL (WINAPI* flTypeImmIsIME)(HKL);
|
||||
-static flTypeImmIsIME flImmIsIME = 0;
|
||||
|
||||
-static HMODULE get_imm_module() {
|
||||
- if (!s_imm_module) {
|
||||
- s_imm_module = LoadLibrary("IMM32.DLL");
|
||||
- if (!s_imm_module)
|
||||
- Fl::fatal("FLTK Lib Error: IMM32.DLL file not found!\n\n"
|
||||
- "Please check your input method manager library accessibility.");
|
||||
- flImmGetContext = (flTypeImmGetContext)GetProcAddress(s_imm_module, "ImmGetContext");
|
||||
- flImmSetCompositionWindow = (flTypeImmSetCompositionWindow)GetProcAddress(s_imm_module, "ImmSetCompositionWindow");
|
||||
- flImmReleaseContext = (flTypeImmReleaseContext)GetProcAddress(s_imm_module, "ImmReleaseContext");
|
||||
- flImmIsIME = (flTypeImmIsIME)GetProcAddress(s_imm_module, "ImmIsIME");
|
||||
- }
|
||||
- return s_imm_module;
|
||||
+static void get_imm_module() {
|
||||
+ s_imm_module = LoadLibrary("IMM32.DLL");
|
||||
+ if (!s_imm_module)
|
||||
+ Fl::fatal("FLTK Lib Error: IMM32.DLL file not found!\n\n"
|
||||
+ "Please check your input method manager library accessibility.");
|
||||
+ flImmAssociateContextEx = (flTypeImmAssociateContextEx)GetProcAddress(s_imm_module, "ImmAssociateContextEx");
|
||||
+ flImmGetContext = (flTypeImmGetContext)GetProcAddress(s_imm_module, "ImmGetContext");
|
||||
+ flImmSetCompositionWindow = (flTypeImmSetCompositionWindow)GetProcAddress(s_imm_module, "ImmSetCompositionWindow");
|
||||
+ flImmReleaseContext = (flTypeImmReleaseContext)GetProcAddress(s_imm_module, "ImmReleaseContext");
|
||||
}
|
||||
|
||||
// USE_TRACK_MOUSE - define NO_TRACK_MOUSE if you don't have
|
||||
@@ -259,7 +254,9 @@ void fl_set_spot(int font, int size, int
|
||||
Fl_Window* tw = win;
|
||||
while (tw->parent()) tw = tw->window(); // find top level window
|
||||
|
||||
- get_imm_module();
|
||||
+ if (!tw->shown())
|
||||
+ return;
|
||||
+
|
||||
HIMC himc = flImmGetContext(fl_xid(tw));
|
||||
|
||||
if (himc) {
|
||||
@@ -338,7 +335,6 @@ void* Fl::thread_message() {
|
||||
|
||||
extern int fl_send_system_handlers(void *e);
|
||||
|
||||
-IActiveIMMApp *fl_aimm = NULL;
|
||||
MSG fl_msg;
|
||||
|
||||
// This is never called with time_to_wait < 0.0.
|
||||
@@ -441,6 +437,58 @@ int fl_ready() {
|
||||
return get_wsock_mod() ? s_wsock_select(0,&fdt[0],&fdt[1],&fdt[2],&t) : 0;
|
||||
}
|
||||
|
||||
+void fl_open_display() {
|
||||
+ static char beenHereDoneThat = 0;
|
||||
+
|
||||
+ if (beenHereDoneThat)
|
||||
+ return;
|
||||
+
|
||||
+ beenHereDoneThat = 1;
|
||||
+
|
||||
+ OleInitialize(0L);
|
||||
+
|
||||
+ get_imm_module();
|
||||
+}
|
||||
+
|
||||
+class Fl_Win32_At_Exit {
|
||||
+public:
|
||||
+ Fl_Win32_At_Exit() { }
|
||||
+ ~Fl_Win32_At_Exit() {
|
||||
+ fl_free_fonts(); // do some WIN32 cleanup
|
||||
+ fl_cleanup_pens();
|
||||
+ OleUninitialize();
|
||||
+ fl_brush_action(1);
|
||||
+ fl_cleanup_dc_list();
|
||||
+ }
|
||||
+};
|
||||
+static Fl_Win32_At_Exit win32_at_exit;
|
||||
+
|
||||
+static char im_enabled = 1;
|
||||
+
|
||||
+void Fl::enable_im() {
|
||||
+ fl_open_display();
|
||||
+
|
||||
+ Fl_X* i = Fl_X::first;
|
||||
+ while (i) {
|
||||
+ flImmAssociateContextEx(i->xid, 0, IACE_DEFAULT);
|
||||
+ i = i->next;
|
||||
+ }
|
||||
+
|
||||
+ im_enabled = 1;
|
||||
+}
|
||||
+
|
||||
+void Fl::disable_im() {
|
||||
+ fl_open_display();
|
||||
+
|
||||
+ Fl_X* i = Fl_X::first;
|
||||
+ while (i) {
|
||||
+ flImmAssociateContextEx(i->xid, 0, 0);
|
||||
+ i = i->next;
|
||||
+ }
|
||||
+
|
||||
+ im_enabled = 0;
|
||||
+}
|
||||
+
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
int Fl::x()
|
||||
@@ -683,7 +731,6 @@ void fl_clipboard_notify_untarget(HWND w
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
-char fl_is_ime = 0;
|
||||
void fl_get_codepage()
|
||||
{
|
||||
HKL hkl = GetKeyboardLayout(0);
|
||||
@@ -691,14 +738,8 @@ void fl_get_codepage()
|
||||
|
||||
GetLocaleInfo (LOWORD(hkl), LOCALE_IDEFAULTANSICODEPAGE, ld, 6);
|
||||
DWORD ccp = atol(ld);
|
||||
- fl_is_ime = 0;
|
||||
|
||||
fl_codepage = ccp;
|
||||
- if (fl_aimm) {
|
||||
- fl_aimm->GetCodePageA(GetKeyboardLayout(0), &fl_codepage);
|
||||
- } else if (get_imm_module() && flImmIsIME(hkl)) {
|
||||
- fl_is_ime = 1;
|
||||
- }
|
||||
}
|
||||
|
||||
HWND fl_capture;
|
||||
@@ -1564,6 +1605,8 @@ int fl_disable_transient_for; // secret
|
||||
Fl_X* Fl_X::make(Fl_Window* w) {
|
||||
Fl_Group::current(0); // get rid of very common user bug: forgot end()
|
||||
|
||||
+ fl_open_display();
|
||||
+
|
||||
// if the window is a subwindow and our parent is not mapped yet, we
|
||||
// mark this window visible, so that mapping the parent at a later
|
||||
// point in time will call this function again to finally map the subwindow.
|
||||
@@ -1767,16 +1810,10 @@ Fl_X* Fl_X::make(Fl_Window* w) {
|
||||
(Fl::grab() || (styleEx & WS_EX_TOOLWINDOW)) ? SW_SHOWNOACTIVATE : SW_SHOWNORMAL);
|
||||
|
||||
// Register all windows for potential drag'n'drop operations
|
||||
- fl_OleInitialize();
|
||||
RegisterDragDrop(x->xid, flIDropTarget);
|
||||
|
||||
- if (!fl_aimm) {
|
||||
- CoCreateInstance(CLSID_CActiveIMM, NULL, CLSCTX_INPROC_SERVER,
|
||||
- IID_IActiveIMMApp, (void**) &fl_aimm);
|
||||
- if (fl_aimm) {
|
||||
- fl_aimm->Activate(TRUE);
|
||||
- }
|
||||
- }
|
||||
+ if (!im_enabled)
|
||||
+ flImmAssociateContextEx(x->xid, 0, 0);
|
||||
|
||||
return x;
|
||||
}
|
||||
diff -up fltk-1.3.2/src/Fl_x.cxx.im fltk-1.3.2/src/Fl_x.cxx
|
||||
--- fltk-1.3.2/src/Fl_x.cxx.im 2014-09-10 14:40:05.194265440 +0200
|
||||
+++ fltk-1.3.2/src/Fl_x.cxx 2014-09-10 14:40:05.198265502 +0200
|
||||
@@ -313,6 +313,7 @@ XVisualInfo *fl_visual;
|
||||
Colormap fl_colormap;
|
||||
XIM fl_xim_im = 0;
|
||||
XIC fl_xim_ic = 0;
|
||||
+Window fl_xim_win = 0;
|
||||
char fl_is_over_the_spot = 0;
|
||||
static XRectangle status_area;
|
||||
|
||||
@@ -603,6 +604,55 @@ void fl_init_xim() {
|
||||
if(xim_styles) XFree(xim_styles);
|
||||
}
|
||||
|
||||
+void fl_xim_deactivate(void);
|
||||
+
|
||||
+void fl_xim_activate(Window xid) {
|
||||
+ if (!fl_xim_im)
|
||||
+ return;
|
||||
+
|
||||
+ // If the focused window has changed, then use the brute force method
|
||||
+ // of completely recreating the input context.
|
||||
+ if (fl_xim_win != xid) {
|
||||
+ fl_xim_deactivate();
|
||||
+
|
||||
+ fl_new_ic();
|
||||
+ fl_xim_win = xid;
|
||||
+
|
||||
+ XSetICValues(fl_xim_ic,
|
||||
+ XNFocusWindow, fl_xim_win,
|
||||
+ XNClientWindow, fl_xim_win,
|
||||
+ NULL);
|
||||
+ }
|
||||
+
|
||||
+ fl_set_spot(spotf, spots, spot.x, spot.y, spot.width, spot.height);
|
||||
+}
|
||||
+
|
||||
+void fl_xim_deactivate(void) {
|
||||
+ if (!fl_xim_ic)
|
||||
+ return;
|
||||
+
|
||||
+ XDestroyIC(fl_xim_ic);
|
||||
+ fl_xim_ic = NULL;
|
||||
+
|
||||
+ fl_xim_win = 0;
|
||||
+}
|
||||
+
|
||||
+void Fl::enable_im() {
|
||||
+ Fl_Window *win;
|
||||
+
|
||||
+ win = Fl::first_window();
|
||||
+ if (win && win->shown()) {
|
||||
+ fl_xim_activate(fl_xid(win));
|
||||
+ XSetICFocus(fl_xim_ic);
|
||||
+ } else {
|
||||
+ fl_new_ic();
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+void Fl::disable_im() {
|
||||
+ fl_xim_deactivate();
|
||||
+}
|
||||
+
|
||||
void fl_open_display() {
|
||||
if (fl_display) return;
|
||||
|
||||
@@ -1053,10 +1103,9 @@ int fl_handle(const XEvent& thisevent)
|
||||
XEvent xevent = thisevent;
|
||||
fl_xevent = &thisevent;
|
||||
Window xid = xevent.xany.window;
|
||||
- static Window xim_win = 0;
|
||||
|
||||
if (fl_xim_ic && xevent.type == DestroyNotify &&
|
||||
- xid != xim_win && !fl_find(xid))
|
||||
+ xid != fl_xim_win && !fl_find(xid))
|
||||
{
|
||||
XIM xim_im;
|
||||
xim_im = XOpenIM(fl_display, NULL, NULL, NULL);
|
||||
@@ -1072,46 +1121,9 @@ int fl_handle(const XEvent& thisevent)
|
||||
}
|
||||
|
||||
if (fl_xim_ic && (xevent.type == FocusIn))
|
||||
- {
|
||||
-#define POOR_XIM
|
||||
-#ifdef POOR_XIM
|
||||
- if (xim_win != xid)
|
||||
- {
|
||||
- xim_win = xid;
|
||||
- XDestroyIC(fl_xim_ic);
|
||||
- fl_xim_ic = NULL;
|
||||
- fl_new_ic();
|
||||
- XSetICValues(fl_xim_ic,
|
||||
- XNFocusWindow, xevent.xclient.window,
|
||||
- XNClientWindow, xid,
|
||||
- NULL);
|
||||
- }
|
||||
- fl_set_spot(spotf, spots, spot.x, spot.y, spot.width, spot.height);
|
||||
-#else
|
||||
- if (Fl::first_window() && Fl::first_window()->modal()) {
|
||||
- Window x = fl_xid(Fl::first_window());
|
||||
- if (x != xim_win) {
|
||||
- xim_win = x;
|
||||
- XSetICValues(fl_xim_ic,
|
||||
- XNFocusWindow, xim_win,
|
||||
- XNClientWindow, xim_win,
|
||||
- NULL);
|
||||
- fl_set_spot(spotf, spots, spot.x, spot.y, spot.width, spot.height);
|
||||
- }
|
||||
- } else if (xim_win != xid && xid) {
|
||||
- xim_win = xid;
|
||||
- XSetICValues(fl_xim_ic,
|
||||
- XNFocusWindow, xevent.xclient.window,
|
||||
- XNClientWindow, xid,
|
||||
- //XNFocusWindow, xim_win,
|
||||
- //XNClientWindow, xim_win,
|
||||
- NULL);
|
||||
- fl_set_spot(spotf, spots, spot.x, spot.y, spot.width, spot.height);
|
||||
- }
|
||||
-#endif
|
||||
- }
|
||||
+ fl_xim_activate(xid);
|
||||
|
||||
- if ( XFilterEvent((XEvent *)&xevent, 0) )
|
||||
+ if (fl_xim_ic && XFilterEvent((XEvent *)&xevent, 0))
|
||||
return(1);
|
||||
|
||||
#if USE_XRANDR
|
||||
@@ -0,0 +1,67 @@
|
||||
>From 7a15d1c9a908afe429c1aba1c27516d18bdea299 Mon Sep 17 00:00:00 2001
|
||||
From: DRC <information@virtualgl.org>
|
||||
Date: Tue, 26 Feb 2013 03:37:12 -0600
|
||||
Subject: [PATCH 1/4] Add BUILD_STATIC feature from TigerVNC to (optionally)
|
||||
prevent FLTK from depending on libgcc and libstdc++
|
||||
|
||||
---
|
||||
CMakeLists.txt | 43 +++++++++++++++++++++++++++++++++++++++++++
|
||||
1 file changed, 43 insertions(+)
|
||||
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index a1ee285..7d9d94b 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -150,6 +150,49 @@ mark_as_advanced(LIB_CAIRO LIB_fontconfig LIB_freetype)
|
||||
mark_as_advanced(LIB_GL LIB_MesaGL)
|
||||
mark_as_advanced(LIB_jpeg LIB_png LIB_zlib)
|
||||
|
||||
+# This ensures that we don't depend on libstdc++ or libgcc
|
||||
+if(CMAKE_COMPILER_IS_GNUCXX AND NOT APPLE AND NOT CYGWIN)
|
||||
+ option(BUILD_STATIC
|
||||
+ "Link statically against libgcc and libstdc++, if possible" OFF)
|
||||
+ if(BUILD_STATIC)
|
||||
+ # For some reason, simply passing ${CMAKE_CXX_FLAGS} to the compiler in
|
||||
+ # execute_process() doesn't work. Grrr...
|
||||
+ if(CMAKE_SIZEOF_VOID_P MATCHES 8)
|
||||
+ execute_process(COMMAND ${CMAKE_CXX_COMPILER} -m64
|
||||
+ --print-file-name=libstdc++.a OUTPUT_VARIABLE LIBSTDCPLUSPLUS
|
||||
+ RESULT_VARIABLE RESULT)
|
||||
+ else()
|
||||
+ execute_process(COMMAND ${CMAKE_CXX_COMPILER} -m32
|
||||
+ --print-file-name=libstdc++.a OUTPUT_VARIABLE LIBSTDCPLUSPLUS
|
||||
+ RESULT_VARIABLE RESULT)
|
||||
+ endif()
|
||||
+ string(REGEX REPLACE "\n" "" LIBSTDCPLUSPLUS ${LIBSTDCPLUSPLUS})
|
||||
+ if(RESULT MATCHES 0 AND LIBSTDCPLUSPLUS)
|
||||
+ message(STATUS "Linking with static libstdc++:\n ${LIBSTDCPLUSPLUS}")
|
||||
+ file(MAKE_DIRECTORY ${CMAKE_BINARY_DIR}/staticlib)
|
||||
+ execute_process(COMMAND ${CMAKE_COMMAND} -E remove
|
||||
+ ${CMAKE_BINARY_DIR}/staticlib/libstdc++.a)
|
||||
+ if(MINGW)
|
||||
+ execute_process(COMMAND ${CMAKE_COMMAND} -E copy
|
||||
+ ${LIBSTDCPLUSPLUS} ${CMAKE_BINARY_DIR}/staticlib/libstdc++.a)
|
||||
+ else()
|
||||
+ execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink
|
||||
+ ${LIBSTDCPLUSPLUS} ${CMAKE_BINARY_DIR}/staticlib/libstdc++.a)
|
||||
+ endif()
|
||||
+ set(CMAKE_EXE_LINKER_FLAGS
|
||||
+ "${CMAKE_EXE_LINKER_FLAGS} -L${CMAKE_BINARY_DIR}/staticlib")
|
||||
+ set(CMAKE_SHARED_LINKER_FLAGS
|
||||
+ "${CMAKE_SHARED_LINKER_FLAGS} -L${CMAKE_BINARY_DIR}/staticlib")
|
||||
+ else()
|
||||
+ message(WARNING Cannot find static libstdc++. TigerVNC will depend on dynamic libstdc++.)
|
||||
+ endif()
|
||||
+ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static-libgcc")
|
||||
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -static-libgcc")
|
||||
+ set(CMAKE_SHARED_LINKER_FLAGS
|
||||
+ "${CMAKE_SHARED_LINKER_FLAGS} -static-libgcc")
|
||||
+ endif()
|
||||
+endif()
|
||||
+
|
||||
#######################################################################
|
||||
# functions
|
||||
include(CheckFunctionExists)
|
||||
--
|
||||
1.8.1.3
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
>From bf06cdf83375c11a47bddc3683143b3e2c0fdfcb Mon Sep 17 00:00:00 2001
|
||||
From: DRC <information@virtualgl.org>
|
||||
Date: Tue, 26 Feb 2013 03:38:45 -0600
|
||||
Subject: [PATCH 2/4] Fl_cocoa.mm depends on some Carbon functions, so we need
|
||||
to include that framework.
|
||||
|
||||
---
|
||||
CMakeLists.txt | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index 7d9d94b..cae895e 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -51,7 +51,7 @@ if(APPLE)
|
||||
set(HAVE_STRTOLL 1)
|
||||
set(HAVE_STRCASECMP 1)
|
||||
set(HAVE_DIRENT_H 1)
|
||||
- set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -framework Cocoa")
|
||||
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -framework Cocoa -framework Carbon")
|
||||
endif(APPLE)
|
||||
|
||||
if(WIN32)
|
||||
--
|
||||
1.8.1.3
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
>From bb02d8426a9a279df76376313349c17774030753 Mon Sep 17 00:00:00 2001
|
||||
From: DRC <information@virtualgl.org>
|
||||
Date: Tue, 26 Feb 2013 04:01:36 -0600
|
||||
Subject: [PATCH 3/4] We need to unset CMAKE_REQUIRED_LIBRARIES after checking
|
||||
for the libpng functions. Otherwise, under certain circumstances (known to
|
||||
be an issue when building on OS X with the in-tree libpng implementation),
|
||||
the scandir() function check will fail, leaving HAVE_SCANDIR unset, and the
|
||||
build will subsequently fail.
|
||||
|
||||
---
|
||||
CMakeLists.txt | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||
index cae895e..0984aae 100644
|
||||
--- a/CMakeLists.txt
|
||||
+++ b/CMakeLists.txt
|
||||
@@ -210,6 +210,9 @@ if(LIB_png)
|
||||
endif(LIB_png)
|
||||
CHECK_FUNCTION_EXISTS(png_get_valid HAVE_PNG_GET_VALID)
|
||||
CHECK_FUNCTION_EXISTS(png_set_tRNS_to_alpha HAVE_PNG_SET_TRNS_TO_ALPHA)
|
||||
+if(LIB_png)
|
||||
+ set(CMAKE_REQUIRED_LIBRARIES "")
|
||||
+endif(LIB_png)
|
||||
|
||||
CHECK_FUNCTION_EXISTS(scandir HAVE_SCANDIR)
|
||||
CHECK_FUNCTION_EXISTS(snprintf HAVE_SNPRINTF)
|
||||
--
|
||||
1.8.1.3
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
--- fltk-1.3.2.org/src/Fl_cocoa.mm 2013-01-16 11:32:11.788478228 +0100
|
||||
+++ fltk-1.3.2/src/Fl_cocoa.mm 2013-01-16 11:32:55.824101285 +0100
|
||||
@@ -3727,7 +3727,7 @@ CGImageRef Fl_X::CGImage_from_window_rec
|
||||
CGImageRef img;
|
||||
if (fl_mac_os_version >= 100500) {
|
||||
NSBitmapImageRep *bitmap = rect_to_NSBitmapImageRep(win, x, y, w, h);
|
||||
- img = [bitmap CGImage]; // requires Mac OS 10.5
|
||||
+ img = (CGImageRef)[bitmap CGImage]; // requires Mac OS 10.5
|
||||
CGImageRetain(img);
|
||||
[bitmap release];
|
||||
}
|
||||
77
contrib/fltk/fltk-1.3.x-osx-clip.patch
Normal file
77
contrib/fltk/fltk-1.3.x-osx-clip.patch
Normal file
@@ -0,0 +1,77 @@
|
||||
diff -up fltk-1.3.3/src/Fl_cocoa.mm.clip fltk-1.3.3/src/Fl_cocoa.mm
|
||||
--- fltk-1.3.3/src/Fl_cocoa.mm.clip 2014-11-02 22:06:07.000000000 +0100
|
||||
+++ fltk-1.3.3/src/Fl_cocoa.mm 2015-04-20 13:45:03.526688921 +0200
|
||||
@@ -3061,6 +3061,14 @@ static void clipboard_check(void)
|
||||
fl_trigger_clipboard_notify(1);
|
||||
}
|
||||
|
||||
+static void resize_selection_buffer(int len, int clipboard) {
|
||||
+ if (len <= fl_selection_buffer_length[clipboard])
|
||||
+ return;
|
||||
+ delete[] fl_selection_buffer[clipboard];
|
||||
+ fl_selection_buffer[clipboard] = new char[len+100];
|
||||
+ fl_selection_buffer_length[clipboard] = len+100;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* create a selection
|
||||
* stuff: pointer to selected data
|
||||
@@ -3069,11 +3077,7 @@ static void clipboard_check(void)
|
||||
*/
|
||||
void Fl::copy(const char *stuff, int len, int clipboard, const char *type) {
|
||||
if (!stuff || len<0) return;
|
||||
- if (len+1 > fl_selection_buffer_length[clipboard]) {
|
||||
- delete[] fl_selection_buffer[clipboard];
|
||||
- fl_selection_buffer[clipboard] = new char[len+100];
|
||||
- fl_selection_buffer_length[clipboard] = len+100;
|
||||
- }
|
||||
+ resize_selection_buffer(len+1, clipboard);
|
||||
memcpy(fl_selection_buffer[clipboard], stuff, len);
|
||||
fl_selection_buffer[clipboard][len] = 0; // needed for direct paste
|
||||
fl_selection_length[clipboard] = len;
|
||||
@@ -3087,7 +3091,7 @@ void Fl::copy(const char *stuff, int len
|
||||
}
|
||||
}
|
||||
|
||||
-static int get_plain_text_from_clipboard(char **buffer, int previous_length)
|
||||
+static int get_plain_text_from_clipboard(int clipboard)
|
||||
{
|
||||
NSInteger length = 0;
|
||||
NSPasteboard *clip = [NSPasteboard generalPasteboard];
|
||||
@@ -3109,21 +3113,17 @@ static int get_plain_text_from_clipboard
|
||||
len = strlen(aux_c) + 1;
|
||||
}
|
||||
else len = [data length] + 1;
|
||||
- if ( len >= previous_length ) {
|
||||
- length = len;
|
||||
- delete[] *buffer;
|
||||
- *buffer = new char[len];
|
||||
- }
|
||||
+ resize_selection_buffer(len, clipboard);
|
||||
if (![found isEqualToString:utf8_format]) {
|
||||
- strcpy(*buffer, aux_c);
|
||||
- free(aux_c);
|
||||
+ strcpy(fl_selection_buffer[clipboard], aux_c);
|
||||
+ free(aux_c);
|
||||
}
|
||||
else {
|
||||
- [data getBytes:*buffer];
|
||||
+ [data getBytes:fl_selection_buffer[clipboard]];
|
||||
}
|
||||
- (*buffer)[len - 1] = 0;
|
||||
+ fl_selection_buffer[clipboard][len - 1] = 0;
|
||||
length = len - 1;
|
||||
- convert_crlf(*buffer, len - 1); // turn all \r characters into \n:
|
||||
+ convert_crlf(fl_selection_buffer[clipboard], len - 1); // turn all \r characters into \n:
|
||||
Fl::e_clipboard_type = Fl::clipboard_plain_text;
|
||||
}
|
||||
}
|
||||
@@ -3218,7 +3218,7 @@ void Fl::paste(Fl_Widget &receiver, int
|
||||
if (clipboard) {
|
||||
Fl::e_clipboard_type = "";
|
||||
if (strcmp(type, Fl::clipboard_plain_text) == 0) {
|
||||
- fl_selection_length[1] = get_plain_text_from_clipboard( &fl_selection_buffer[1], fl_selection_length[1]);
|
||||
+ fl_selection_length[1] = get_plain_text_from_clipboard(1);
|
||||
}
|
||||
else if (strcmp(type, Fl::clipboard_image) == 0) {
|
||||
Fl::e_clipboard_data = get_image_from_clipboard( );
|
||||
Reference in New Issue
Block a user