blob: edce5f9fa21b544971915bee475f7c6a5da6c33c [file] [log] [blame]
*** fltk-1.3.0/CMakeLists.txt 2011-01-06 04:24:58.000000000 -0600
--- fltk-1.3.0-new/CMakeLists.txt 2011-06-23 21:39:42.000000000 -0500
***************
*** 49,52 ****
--- 49,56 ----
include_directories(${FLTK_BINARY_DIR} ${FLTK_SOURCE_DIR})
+ if(NOT CMAKE_BUILD_TYPE)
+ set(CMAKE_BUILD_TYPE Release)
+ endif()
+
#######################################################################
# platform dependent information
***************
*** 62,65 ****
--- 66,70 ----
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 Carbon")
endif(APPLE)
***************
*** 68,71 ****
--- 73,86 ----
add_definitions(-DWIN32_LEAN_AND_MEAN)
add_definitions(-D_CRT_SECURE_NO_WARNINGS)
+
+ # Use the static C library for all build types
+ foreach(var CMAKE_C_FLAGS CMAKE_C_FLAGS_DEBUG CMAKE_C_FLAGS_RELEASE
+ CMAKE_C_FLAGS_MINSIZEREL CMAKE_C_FLAGS_RELWITHDEBINFO
+ CMAKE_CXX_FLAGS CMAKE_CXX_FLAGS_DEBUG CMAKE_CXX_FLAGS_RELEASE
+ CMAKE_CXX_FLAGS_MINSIZEREL CMAKE_CXX_FLAGS_RELWITHDEBINFO)
+ if(${var} MATCHES "/MD")
+ string(REGEX REPLACE "/MD" "/MT" ${var} "${${var}}")
+ endif()
+ endforeach()
endif(MSVC)
if(CMAKE_C_COMPILER_ID STREQUAL GNU)
*** fltk-1.3.0/FL/Enumerations.H 2011-05-21 16:55:59.000000000 -0500
--- fltk-1.3.0-new/FL/Enumerations.H 2011-06-22 22:35:32.000000000 -0500
***************
*** 293,297 ****
following FL_PASTE event.
*/
! FL_DND_RELEASE = 23
};
--- 293,302 ----
following FL_PASTE event.
*/
! FL_DND_RELEASE = 23,
!
! /** The fullscreen state of the window has changed
! */
! FL_FULLSCREEN = 24
!
};
***************
*** 875,907 ****
/** The following constants define the mouse cursors that are available in FLTK.
! The double-headed arrows are bitmaps provided by FLTK on X, the others
! are provided by system-defined cursors.
\todo enum Fl_Cursor needs maybe an image.
*/
enum Fl_Cursor {
! FL_CURSOR_DEFAULT = 0, /**< the default cursor, usually an arrow. */
! FL_CURSOR_ARROW = 35, /**< an arrow pointer. */
! FL_CURSOR_CROSS = 66, /**< crosshair. */
! FL_CURSOR_WAIT = 76, /**< watch or hourglass. */
! FL_CURSOR_INSERT = 77, /**< I-beam. */
! FL_CURSOR_HAND = 31, /**< hand (uparrow on MSWindows). */
! FL_CURSOR_HELP = 47, /**< question mark. */
! FL_CURSOR_MOVE = 27, /**< 4-pointed arrow. */
! // fltk provides bitmaps for these:
! FL_CURSOR_NS = 78, /**< up/down arrow. */
! FL_CURSOR_WE = 79, /**< left/right arrow. */
! FL_CURSOR_NWSE = 80, /**< diagonal arrow. */
! FL_CURSOR_NESW = 81, /**< diagonal arrow. */
! FL_CURSOR_NONE =255, /**< invisible. */
! // for back compatibility (non MSWindows ones):
! FL_CURSOR_N = 70, /**< for back compatibility. */
! FL_CURSOR_NE = 69, /**< for back compatibility. */
! FL_CURSOR_E = 49, /**< for back compatibility. */
! FL_CURSOR_SE = 8, /**< for back compatibility. */
! FL_CURSOR_S = 9, /**< for back compatibility. */
! FL_CURSOR_SW = 7, /**< for back compatibility. */
! FL_CURSOR_W = 36, /**< for back compatibility. */
! FL_CURSOR_NW = 68 /**< for back compatibility. */
};
/*@}*/ // group: Cursors
--- 880,913 ----
/** The following constants define the mouse cursors that are available in FLTK.
! Cursors are provided by the system when available, or bitmaps built into
! FLTK as a fallback.
\todo enum Fl_Cursor needs maybe an image.
*/
enum Fl_Cursor {
! FL_CURSOR_DEFAULT = 0, /**< the default cursor, usually an arrow. */
! FL_CURSOR_ARROW = 1, /**< an arrow pointer. */
! FL_CURSOR_CROSS = 2, /**< crosshair. */
! FL_CURSOR_WAIT = 3, /**< busy indicator (e.g. hourglass). */
! FL_CURSOR_INSERT = 4, /**< I-beam. */
! FL_CURSOR_HAND = 5, /**< pointing hand. */
! FL_CURSOR_HELP = 6, /**< question mark pointer. */
! FL_CURSOR_MOVE = 7, /**< 4-pointed arrow or hand. */
!
! /* Resize indicators */
! FL_CURSOR_NS = 101, /**< up/down resize. */
! FL_CURSOR_WE = 102, /**< left/right resize. */
! FL_CURSOR_NWSE = 103, /**< diagonal resize. */
! FL_CURSOR_NESW = 104, /**< diagonal resize. */
! FL_CURSOR_NE = 110, /**< upwards, right resize. */
! FL_CURSOR_N = 111, /**< upwards resize. */
! FL_CURSOR_NW = 112, /**< upwards, left resize. */
! FL_CURSOR_E = 113, /**< leftwards resize. */
! FL_CURSOR_W = 114, /**< rightwards resize. */
! FL_CURSOR_SE = 115, /**< downwards, right resize. */
! FL_CURSOR_S = 116, /**< downwards resize. */
! FL_CURSOR_SW = 117, /**< downwards, left resize. */
!
! FL_CURSOR_NONE = 255, /**< invisible. */
};
/*@}*/ // group: Cursors
*** fltk-1.3.0/FL/Fl.H 2011-05-23 13:01:29.000000000 -0500
--- fltk-1.3.0-new/FL/Fl.H 2011-06-22 22:35:31.000000000 -0500
***************
*** 109,112 ****
--- 109,115 ----
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 */
***************
*** 745,748 ****
--- 748,764 ----
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
*** fltk-1.3.0/FL/Fl_Image.H 2011-01-30 03:24:40.000000000 -0600
--- fltk-1.3.0-new/FL/Fl_Image.H 2011-06-22 22:35:32.000000000 -0500
***************
*** 35,38 ****
--- 35,39 ----
class Fl_Widget;
+ class Fl_Pixmap;
struct Fl_Menu_Item;
struct Fl_Label;
***************
*** 197,200 ****
--- 198,202 ----
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);
*** fltk-1.3.0/FL/Fl_Widget.H 2011-04-24 12:09:41.000000000 -0500
--- fltk-1.3.0-new/FL/Fl_Widget.H 2011-06-22 22:41:26.000000000 -0500
***************
*** 109,112 ****
--- 109,113 ----
class FL_EXPORT Fl_Widget {
friend class Fl_Group;
+ friend class Fl_X;
Fl_Group* parent_;
***************
*** 180,183 ****
--- 181,186 ----
GROUP_RELATIVE = 1<<16, ///< position this widget relative to the parent group, not to the window
COPIED_TOOLTIP = 1<<17, ///< the widget tooltip is internally copied, its destruction is handled by the widget
+ SIMPLE_KEYBOARD = 1<<18, ///< the widget wants simple, consistent keypresses and not advanced input (like character composition and CJK input)
+ FULLSCREEN = 1<<19, ///< a fullscreen window (Fl_Window)
// (space for more flags)
USERFLAG3 = 1<<29, ///< reserved for 3rd party extensions
***************
*** 785,788 ****
--- 788,820 ----
void clear_changed() {flags_ &= ~CHANGED;}
+ /**
+ Returns if the widget sees a simplified keyboard model or not.
+
+ Normally widgets get a full-featured keyboard model that is geared
+ towards text input. This includes support for compose sequences and
+ advanced input methods, commonly used for asian writing system. This
+ system however has downsides in that extra graphic can be presented
+ to the user and that a physical key press doesn't correspond directly
+ to a FLTK event.
+
+ Widgets that need a direct correspondence between actual key events
+ and those seen by the widget can swith to the simplified keyboard
+ model.
+
+ \retval 0 if the widget uses the normal keyboard model
+ \see set_changed(), clear_changed()
+ */
+ unsigned int simple_keyboard() const {return flags_&SIMPLE_KEYBOARD;}
+
+ /** Marks a widget to use the simple keyboard model.
+ \see changed(), clear_changed()
+ */
+ void set_simple_keyboard() {flags_ |= SIMPLE_KEYBOARD;}
+
+ /** Marks a widget to use the normal keyboard model.
+ \see changed(), set_changed()
+ */
+ void set_normal_keyboard() {flags_ &= ~SIMPLE_KEYBOARD;}
+
/** Gives the widget the keyboard focus.
Tries to make this widget be the Fl::focus() widget, by first sending
***************
*** 853,856 ****
--- 885,891 ----
/* Internal use only. */
static int test_shortcut(const char*, const bool require_alt = false);
+ /* Internal use only. */
+ void _set_fullscreen() {flags_ |= FULLSCREEN;}
+ void _clear_fullscreen() {flags_ &= ~FULLSCREEN;}
/** Checks if w is a child of this widget.
*** fltk-1.3.0/FL/Fl_Window.H 2011-04-15 16:38:05.000000000 -0500
--- fltk-1.3.0-new/FL/Fl_Window.H 2011-06-22 22:35:32.000000000 -0500
***************
*** 38,41 ****
--- 38,42 ----
class Fl_X;
+ class Fl_RGB_Image;
/**
***************
*** 70,76 ****
int dw, dh, aspect;
uchar size_range_set;
// cursor stuff
Fl_Cursor cursor_default;
- Fl_Color cursor_fg, cursor_bg;
void size_range_();
void _Fl_Window(); // constructor innards
--- 71,77 ----
int dw, dh, aspect;
uchar size_range_set;
+ int no_fullscreen_x, no_fullscreen_y, no_fullscreen_w, no_fullscreen_h;
// cursor stuff
Fl_Cursor cursor_default;
void size_range_();
void _Fl_Window(); // constructor innards
***************
*** 385,392 ****
Makes the window completely fill the screen, without any window
manager border visible. You must use fullscreen_off() to undo
! this. This may not work with all window managers.
*/
void fullscreen();
/**
Turns off any side effects of fullscreen() and does
resize(x,y,w,h).
--- 386,401 ----
Makes the window completely fill the screen, 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.
*/
void fullscreen();
/**
+ Turns off any side effects of fullscreen()
+ */
+ void fullscreen_off();
+ /**
Turns off any side effects of fullscreen() and does
resize(x,y,w,h).
***************
*** 394,397 ****
--- 403,410 ----
void fullscreen_off(int,int,int,int);
/**
+ Returns non zero if FULLSCREEN flag is set, 0 otherwise.
+ */
+ unsigned int fullscreen_active() const { return flags() & FULLSCREEN; }
+ /**
Iconifies the window. If you call this when shown() is false
it will show() it as an icon. If the window is already
***************
*** 435,446 ****
The type Fl_Cursor is an enumeration defined in <FL/Enumerations.H>.
- (Under X you can get any XC_cursor value by passing
- Fl_Cursor((XC_foo/2)+1)). The colors only work on X, they are
- not implemented on WIN32.
! For back compatibility only.
*/
! void cursor(Fl_Cursor, Fl_Color=FL_BLACK, Fl_Color=FL_WHITE); // platform dependent
! void default_cursor(Fl_Cursor, Fl_Color=FL_BLACK, Fl_Color=FL_WHITE);
static void default_callback(Fl_Window*, void* v);
--- 448,462 ----
The type Fl_Cursor is an enumeration defined in <FL/Enumerations.H>.
! \see cursor(const Fl_RGB_Image*, int, int), default_cursor()
*/
! void cursor(Fl_Cursor);
! void cursor(const Fl_RGB_Image*, int, int);
! void default_cursor(Fl_Cursor);
!
! /* for legacy compatibility */
! void cursor(Fl_Cursor c, Fl_Color, Fl_Color=FL_WHITE) { cursor(c); };
! void default_cursor(Fl_Cursor c, Fl_Color, Fl_Color=FL_WHITE) { default_cursor(c); };
!
static void default_callback(Fl_Window*, void* v);
*** fltk-1.3.0/FL/fl_draw.H 2011-06-02 03:06:09.000000000 -0500
--- fltk-1.3.0-new/FL/fl_draw.H 2011-06-22 22:35:32.000000000 -0500
***************
*** 758,762 ****
FL_EXPORT void fl_overlay_rect(int x,int y,int w,int h);
FL_EXPORT void fl_overlay_clear();
! FL_EXPORT void fl_cursor(Fl_Cursor, Fl_Color fg=FL_BLACK, Fl_Color bg=FL_WHITE);
FL_EXPORT const char* fl_expand_text(const char* from, char* buf, int maxbuf,
double maxw, int& n, double &width,
--- 758,763 ----
FL_EXPORT void fl_overlay_rect(int x,int y,int w,int h);
FL_EXPORT void fl_overlay_clear();
! FL_EXPORT void fl_cursor(Fl_Cursor);
! FL_EXPORT void fl_cursor(Fl_Cursor, Fl_Color fg, Fl_Color bg=FL_WHITE);
FL_EXPORT const char* fl_expand_text(const char* from, char* buf, int maxbuf,
double maxw, int& n, double &width,
*** fltk-1.3.0/FL/mac.H 2011-05-12 06:50:43.000000000 -0500
--- fltk-1.3.0-new/FL/mac.H 2011-06-22 22:35:32.000000000 -0500
***************
*** 142,146 ****
WindowRef window_ref(void);
void set_key_window(void);
! void set_cursor(Fl_Cursor);
static CGImageRef CGImage_from_window_rect(Fl_Window *win, int x, int y, int w, int h);
static unsigned char *bitmap_from_window_rect(Fl_Window *win, int x, int y, int w, int h, int *bytesPerPixel);
--- 142,147 ----
WindowRef window_ref(void);
void set_key_window(void);
! 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);
static unsigned char *bitmap_from_window_rect(Fl_Window *win, int x, int y, int w, int h, int *bytesPerPixel);
*** fltk-1.3.0/FL/names.h 2010-11-28 15:06:39.000000000 -0600
--- fltk-1.3.0-new/FL/names.h 2011-06-22 22:35:32.000000000 -0500
***************
*** 76,79 ****
--- 76,80 ----
"FL_DND_LEAVE",
"FL_DND_RELEASE",
+ "FL_FULLSCREEN"
};
*** fltk-1.3.0/FL/win32.H 2011-05-23 13:32:47.000000000 -0500
--- fltk-1.3.0-new/FL/win32.H 2011-06-22 22:35:32.000000000 -0500
***************
*** 93,96 ****
--- 93,98 ----
void set_minmax(LPMINMAXINFO minmax);
void mapraise();
+ int set_cursor(Fl_Cursor);
+ int set_cursor(const Fl_RGB_Image*, int, int);
static Fl_X* make(Fl_Window*);
};
*** fltk-1.3.0/FL/x.H 2011-05-21 05:05:19.000000000 -0500
--- fltk-1.3.0-new/FL/x.H 2011-06-22 22:35:32.000000000 -0500
***************
*** 164,167 ****
--- 164,169 ----
void setwindow(Fl_Window* wi) {w=wi; wi->i=this;}
void sendxjunk();
+ 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);
static Fl_X* set_xid(Fl_Window*, Window);
*** fltk-1.3.0/configh.in 2011-06-09 11:21:40.000000000 -0500
--- fltk-1.3.0-new/configh.in 2011-06-22 22:35:32.000000000 -0500
***************
*** 118,121 ****
--- 118,137 ----
/*
+ * HAVE_XFIXES:
+ *
+ * Do we have the X fixes extension?
+ */
+
+ #define HAVE_XFIXES 0
+
+ /*
+ * HAVE_XCURSOR:
+ *
+ * Do we have the X cursor library?
+ */
+
+ #define HAVE_XCURSOR 0
+
+ /*
* __APPLE_QUARTZ__:
*
*** fltk-1.3.0/configure.in 2011-03-06 10:54:58.000000000 -0600
--- fltk-1.3.0-new/configure.in 2011-06-22 22:35:32.000000000 -0500
***************
*** 875,878 ****
--- 875,880 ----
# MacOS X uses Cocoa for graphics.
LIBS="$LIBS -framework Cocoa"
+ # And some Carbon for keyboard handling
+ LIBS="$LIBS -framework Carbon"
if test x$have_pthread = xyes; then
***************
*** 1007,1010 ****
--- 1009,1032 ----
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 the Xcursor library unless disabled...
+ AC_ARG_ENABLE(xcursor, [ --enable-xcursor turn on Xcursor support [default=yes]])
+
+ if test x$enable_xcursor != xno; then
+ AC_CHECK_HEADER(X11/Xcursor/Xcursor.h, AC_DEFINE(HAVE_XCURSOR),,
+ [#include <X11/Xlib.h>])
+ AC_CHECK_LIB(Xcursor, XcursorImageCreate,
+ LIBS="-lXcursor $LIBS")
+ fi
+
dnl Check for overlay visuals...
AC_PATH_PROG(XPROP, xprop)
*** fltk-1.3.0/documentation/src/enumerations.dox 2011-05-11 10:49:30.000000000 -0500
--- fltk-1.3.0-new/documentation/src/enumerations.dox 2011-06-22 22:35:32.000000000 -0500
***************
*** 58,61 ****
--- 58,62 ----
data.
\li FL_DND_RELEASE - Dragged data is about to be dropped.
+ \li FL_FULLSCREEN - The fullscreen state of the window has changed.
*** fltk-1.3.0/documentation/src/events.dox 2011-05-11 10:49:30.000000000 -0500
--- fltk-1.3.0-new/documentation/src/events.dox 2011-06-22 22:35:32.000000000 -0500
***************
*** 301,304 ****
--- 301,311 ----
the immediately following \p FL_PASTE event.
+ \subsection events_fl_fullscreen FL_FULLSCREEN
+
+ The application window has been changed from normal to fullscreen, or
+ from fullscreen to normal. If you are using a X window manager which
+ supports Extended Window Manager Hints, this event will not be
+ delivered until the change has actually happened.
+
\section events_event_xxx Fl::event_*() methods
*** fltk-1.3.0/src/Fl.cxx 2011-05-23 11:49:02.000000000 -0500
--- fltk-1.3.0.new/src/Fl.cxx 2011-06-22 22:35:32.000000000 -0500
***************
*** 80,83 ****
--- 80,85 ----
#endif // WIN32
+ extern void fl_update_focus(void);
+
//
// Globals...
***************
*** 445,448 ****
--- 447,513 ----
////////////////////////////////////////////////////////////////
+ // 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:
***************
*** 881,884 ****
--- 946,951 ----
}
e_number = old_event;
+ // let the platform code do what it needs
+ fl_update_focus();
}
}
***************
*** 1362,1366 ****
// hide() destroys the X window, it does not do unmap!
! #if !defined(WIN32) && USE_XFT
extern void fl_destroy_xft_draw(Window);
#endif
--- 1429,1436 ----
// 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);
#endif
***************
*** 1409,1420 ****
// 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();
! }
! }
// Send a message to myself so that I'll get out of the event loop...
PostMessage(ip->xid, WM_APP, 0, 0);
--- 1479,1486 ----
// 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_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);
*** fltk-1.3.0/src/Fl_Image.cxx 2011-04-20 09:01:04.000000000 -0500
--- fltk-1.3.0.new/src/Fl_Image.cxx 2011-06-22 22:35:32.000000000 -0500
***************
*** 173,176 ****
--- 173,189 ----
// RGB image class...
//
+
+ 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. */
+ 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 free all memory and server resources that are used by the image. */
Fl_RGB_Image::~Fl_RGB_Image() {
*** fltk-1.3.0/src/Fl_Window.cxx 2011-02-25 02:44:47.000000000 -0600
--- fltk-1.3.0.new/src/Fl_Window.cxx 2011-06-22 22:35:32.000000000 -0500
***************
*** 60,63 ****
--- 60,67 ----
size_range_set = 0;
minw = maxw = minh = maxh = 0;
+ no_fullscreen_x = 0;
+ no_fullscreen_y = 0;
+ no_fullscreen_w = w();
+ no_fullscreen_h = h();
callback((Fl_Callback*)default_callback);
}
***************
*** 66,71 ****
: Fl_Group(X, Y, W, H, l) {
cursor_default = FL_CURSOR_DEFAULT;
- cursor_fg = FL_BLACK;
- cursor_bg = FL_WHITE;
_Fl_Window();
--- 70,73 ----
***************
*** 77,82 ****
: Fl_Group((Fl_Group::current(0),0), 0, W, H, l) {
cursor_default = FL_CURSOR_DEFAULT;
- cursor_fg = FL_BLACK;
- cursor_bg = FL_WHITE;
_Fl_Window();
--- 79,82 ----
*** fltk-1.3.0/src/Fl_Window_fullscreen.cxx 2011-03-12 15:36:21.000000000 -0600
--- fltk-1.3.0.new/src/Fl_Window_fullscreen.cxx 2011-06-22 22:35:32.000000000 -0500
***************
*** 61,97 ****
}
void Fl_Window::fullscreen() {
! #ifndef WIN32
! //this would clobber the fake wm, since it relies on the border flags to
! //determine its thickness
! border(0);
! #endif
! #if defined(__APPLE__) || defined(WIN32) || defined(USE_X11)
! int sx, sy, sw, sh;
! Fl::screen_xywh(sx, sy, sw, sh, x(), y(), w(), h());
! // if we are on the main screen, we will leave the system menu bar unobstructed
! if (Fl::x()>=sx && Fl::y()>=sy && Fl::x()+Fl::w()<=sx+sw && Fl::y()+Fl::h()<=sy+sh) {
! sx = Fl::x(); sy = Fl::y();
! sw = Fl::w(); sh = Fl::h();
}
- if (x()==sx) x(sx+1); // make sure that we actually execute the resize
- #if defined(USE_X11)
- resize(0, 0, w(), h()); // work around some quirks in X11
- #endif
- resize(sx, sy, sw, sh);
- #else
- if (!x()) x(1); // make sure that we actually execute the resize
- resize(0,0,Fl::w(),Fl::h());
- #endif
}
void Fl_Window::fullscreen_off(int X,int Y,int W,int H) {
! // this order produces less blinking on IRIX:
! resize(X,Y,W,H);
! #ifndef WIN32
! border(1);
! #endif
}
//
// End of "$Id: Fl_Window_fullscreen.cxx 8515 2011-03-12 21:36:21Z manolo $".
--- 61,106 ----
}
+ void fullscreen_x(Fl_Window *w);
+ void fullscreen_off_x();
+ void fullscreen_off_x(Fl_Window *w, int X, int Y, int W, int H);
+
+ /* Note: The previous implementation toggled border(). With this new
+ implementation this is not necessary. Additionally, if we do that,
+ the application may lose focus when switching out of fullscreen
+ mode with some window managers. Besides, the API does not say that
+ the FLTK border state should be toggled; it only says that the
+ borders should not be *visible*.
+ */
void Fl_Window::fullscreen() {
! if (shown() && !(flags() & Fl_Widget::FULLSCREEN)) {
! no_fullscreen_x = x();
! no_fullscreen_y = y();
! no_fullscreen_w = w();
! no_fullscreen_h = h();
! fullscreen_x(this);
! } else {
! set_flag(FULLSCREEN);
}
}
void Fl_Window::fullscreen_off(int X,int Y,int W,int H) {
! if (shown() && (flags() & Fl_Widget::FULLSCREEN)) {
! fullscreen_off_x(this, X, Y, W, H);
! } else {
! clear_flag(FULLSCREEN);
! }
! no_fullscreen_x = no_fullscreen_y = no_fullscreen_w = no_fullscreen_h = 0;
! }
!
! void Fl_Window::fullscreen_off() {
! if (!no_fullscreen_x && !no_fullscreen_y) {
! // Window was initially created fullscreen - default to current monitor
! no_fullscreen_x = x();
! no_fullscreen_y = y();
! }
! fullscreen_off(no_fullscreen_x, no_fullscreen_y, no_fullscreen_w, no_fullscreen_h);
}
+
//
// End of "$Id: Fl_Window_fullscreen.cxx 8515 2011-03-12 21:36:21Z manolo $".
*** fltk-1.3.0/src/Fl_cocoa.mm 2011-06-16 07:35:32.000000000 -0500
--- fltk-1.3.0.new/src/Fl_cocoa.mm 2011-06-22 22:35:32.000000000 -0500
***************
*** 62,65 ****
--- 62,66 ----
#import <Cocoa/Cocoa.h>
+ #import <Carbon/Carbon.h>
#ifndef NSINTEGER_DEFINED // appears with 10.5 in NSObjCRuntime.h
***************
*** 108,112 ****
void *fl_system_menu; // this is really a NSMenu*
Fl_Sys_Menu_Bar *fl_sys_menu_bar = 0;
- void *fl_default_cursor; // this is really a NSCursor*
void *fl_capture = 0; // (NSWindow*) we need this to compensate for a missing(?) mouse capture
bool fl_show_iconic; // true if called from iconize() - shows the next created window in collapsed state
--- 109,112 ----
***************
*** 125,128 ****
--- 125,130 ----
#endif
+ bool use_simple_keyboard = false;
+
enum { FLTKTimerEvent = 1, FLTKDataReadyEvent };
***************
*** 141,144 ****
--- 143,179 ----
}
+ // Undocumented voodoo. Taken from Mozilla.
+ #define ENABLE_ROMAN_KYBDS_ONLY -23
+
+ void fl_update_focus(void)
+ {
+ Fl_Widget *focus;
+
+ focus = Fl::grab();
+ if (!focus)
+ focus = Fl::focus();
+ if (!focus)
+ return;
+
+ if (focus->simple_keyboard())
+ use_simple_keyboard = true;
+ else
+ use_simple_keyboard = false;
+
+ // 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...
+ #if (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_5)
+ CFArrayRef inputSources = TISCreateASCIICapableInputSourceList();
+ TSMSetDocumentProperty(TSMGetActiveDocument(),
+ kTSMDocumentEnabledInputSourcesPropertyTag,
+ sizeof(CFArrayRef), &inputSources);
+ CFRelease(inputSources);
+ #else
+ KeyScript(use_simple_keyboard ? ENABLE_ROMAN_KYBDS_ONLY : smKeyEnableKybds);
+ #endif
+ }
+
/*
* Mac keyboard lookup table
***************
*** 615,618 ****
--- 650,657 ----
containsGLsubwindow = contains;
}
+ - (BOOL)canBecomeKeyWindow
+ {
+ return YES;
+ }
@end
***************
*** 844,847 ****
--- 883,905 ----
@end
+ static const char* cocoaDead2FLTK(const char *in)
+ {
+ if (strcmp(in, "\140") == 0) // GRAVE ACCENT
+ return "\314\200"; // COMBINING GRAVE ACCENT
+ if (strcmp(in, "\302\264") == 0) // ACUTE ACCENT
+ return "\314\201"; // COMBINING ACUTE ACCENT
+ if (strcmp(in, "\136") == 0) // CIRCUMFLEX ACCENT
+ return "\314\202"; // COMBINING CIRCUMFLEX ACCENT
+ if (strcmp(in, "\176") == 0) // TILDE
+ return "\314\203"; // COMBINING TILDE
+ if (strcmp(in, "\302\250") == 0) // DIAERESIS
+ return "\314\210"; // COMBINING DIAERESIS
+ // FIXME: OS X dead key behaviour isn't documented and I don't have
+ // any more keyboards to test with...
+
+ // hope that OS X gave us something proper to begin with
+ return in;
+ }
+
/*
Handle cocoa keyboard events
***************
*** 1034,1037 ****
--- 1092,1099 ----
FLWindow *nsw = (FLWindow*)[notif object];
Fl_Window *window = [nsw getFl_Window];
+ /* Fullscreen windows obscure all other windows so we need to return
+ to a "normal" level when the user switches to another window */
+ if (window->fullscreen_active())
+ [nsw setLevel:NSNormalWindowLevel];
Fl::handle( FL_UNFOCUS, window);
fl_unlock_function();
***************
*** 1042,1045 ****
--- 1104,1110 ----
FLWindow *nsw = (FLWindow*)[notif object];
Fl_Window *w = [nsw getFl_Window];
+ /* Restore previous fullscreen level */
+ if (w->fullscreen_active())
+ [nsw setLevel:NSStatusWindowLevel];
if ( w->border() || (!w->modal() && !w->tooltip_window()) ) Fl::handle( FL_FOCUS, w);
fl_unlock_function();
***************
*** 1229,1235 ****
--- 1294,1304 ----
@end
+ static void clipboard_check(void);
+
@implementation FLApplication
+ (void)sendEvent:(NSEvent *)theEvent
{
+ // update clipboard status
+ clipboard_check();
NSEventType type = [theEvent type];
if (type == NSLeftMouseDown) {
***************
*** 1286,1291 ****
while (ign_event);
- fl_default_cursor = [NSCursor arrowCursor];
-
// bring the application into foreground without a 'CARB' resource
Boolean same_psn;
--- 1355,1358 ----
***************
*** 1587,1590 ****
--- 1654,1658 ----
- (BOOL)acceptsFirstResponder;
- (BOOL)acceptsFirstMouse:(NSEvent*)theEvent;
+ - (void)resetCursorRects;
- (BOOL)performKeyEquivalent:(NSEvent*)theEvent;
- (void)mouseUp:(NSEvent *)theEvent;
***************
*** 1644,1647 ****
--- 1712,1725 ----
return (first == w || !first->modal());
}
+ - (void)resetCursorRects {
+ Fl_Window *w = [(FLWindow*)[self window] getFl_Window];
+ Fl_X *i = Fl_X::i(w);
+ // We have to have at least one cursor rect for invalidateCursorRectsForView
+ // to work, hence the "else" clause.
+ if (i->cursor)
+ [self addCursorRect:[self visibleRect] cursor:(NSCursor*)i->cursor];
+ else
+ [self addCursorRect:[self visibleRect] cursor:[NSCursor arrowCursor]];
+ }
- (void)mouseUp:(NSEvent *)theEvent {
cocoaMouseHandler(theEvent);
***************
*** 1703,1708 ****
}
}
if (!no_text_key && !(Fl::e_state & FL_META) ) {
! // Don't send cmd-<key> to interpretKeyEvents because it beeps.
// Then we can let the OS have a stab at it and see if it thinks it
// should result in some text
--- 1781,1791 ----
}
}
+ // Don't send cmd-<key> to interpretKeyEvents because it beeps.
if (!no_text_key && !(Fl::e_state & FL_META) ) {
! // The simple keyboard model will ignore insertText, so we need to grab
! // the symbol directly from the event. Note that we still use setMarkedText.
! if (use_simple_keyboard)
! [FLView prepareEtext:[theEvent charactersIgnoringModifiers]];
!
// Then we can let the OS have a stab at it and see if it thinks it
// should result in some text
***************
*** 1883,1901 ****
if (!in_key_event) fl_lock_function();
[FLView prepareEtext:received];
// We can get called outside of key events (e.g. from the character
! // palette). Transform such actions to FL_PASTE events.
if (!in_key_event) {
Fl_Window *target = [(FLWindow*)[self window] getFl_Window];
! Fl::handle(FL_PASTE, target);
// for some reason, the window does not redraw until the next mouse move or button push
// sending a 'redraw()' or 'awake()' does not solve the issue!
Fl::flush();
}
if (!in_key_event) fl_unlock_function();
}
- (void)setMarkedText:(id)aString selectedRange:(NSRange)newSelection {
! NSString *received;
if (newSelection.location == 0) {
[self unmarkText];
--- 1966,1993 ----
if (!in_key_event) fl_lock_function();
+
+ // Simple keyboard widgets do not want these side channel inputs.
+ if (use_simple_keyboard)
+ goto end;
+
[FLView prepareEtext:received];
+
// We can get called outside of key events (e.g. from the character
! // palette). We need to fake our own key event at that point.
if (!in_key_event) {
Fl_Window *target = [(FLWindow*)[self window] getFl_Window];
! Fl::e_keysym = Fl::e_original_keysym = 0;
! Fl::handle(FL_KEYDOWN, target);
// for some reason, the window does not redraw until the next mouse move or button push
// sending a 'redraw()' or 'awake()' does not solve the issue!
Fl::flush();
}
+
+ end:
if (!in_key_event) fl_unlock_function();
}
- (void)setMarkedText:(id)aString selectedRange:(NSRange)newSelection {
! NSString *received, *current, *aggregate;
if (newSelection.location == 0) {
[self unmarkText];
***************
*** 1908,1916 ****
}
//NSLog(@"setMarkedText: %@ %d %d",received,newSelection.location,newSelection.length);
// This code creates the OS X behaviour of seeing dead keys as things
// are being composed.
next_compose_length = newSelection.location;
! [FLView prepareEtext:received];
! //NSLog(@"Fl::e_text=%@ Fl::e_length=%d next_compose_length=%d", received, Fl::e_length, next_compose_length);
}
--- 2000,2044 ----
}
//NSLog(@"setMarkedText: %@ %d %d",received,newSelection.location,newSelection.length);
+
+ fl_lock_function();
+
+ // Simple keyboard widgets generally do not want these side channel
+ // inputs, but we have no other way of getting dead keys so we make
+ // an exception in that case.
+ if (use_simple_keyboard) {
+ if (in_key_event && (Fl::e_length == 0)) {
+ [FLView prepareEtext:received];
+
+ Fl::e_text = (char*)cocoaDead2FLTK(Fl::e_text);
+ Fl::e_length = strlen(Fl::e_text);
+ }
+ goto end;
+ }
+
// This code creates the OS X behaviour of seeing dead keys as things
// are being composed.
+ //
+ // Note: The concatenation thing is because of how OS X deals with
+ // invalid sequences. At that point it will spit out one call
+ // to insertText with the now aborted sequence, and one new
+ // call to setMarkedText with the new sequence. Since we want
+ // both to be visible, we need to concatenate.
next_compose_length = newSelection.location;
! current = [NSString stringWithUTF8String:Fl::e_text];
! aggregate = [current stringByAppendingString:received];
!
! [FLView prepareEtext:aggregate];
! //NSLog(@"Fl::e_text=%@ Fl::e_length=%d next_compose_length=%d", aggregate, Fl::e_length, next_compose_length);
!
! // We can get called outside of key events (e.g. from the character
! // palette). We need to fake our own key event at that point.
! if (!in_key_event) {
! Fl_Window *target = [(FLWindow*)[self window] getFl_Window];
! Fl::e_keysym = Fl::e_original_keysym = 0;
! Fl::handle(FL_KEYDOWN, target);
! }
!
! end:
! fl_unlock_function();
}
***************
*** 1982,1985 ****
--- 2110,2129 ----
@end
+ void fullscreen_x(Fl_Window *w) {
+ w->_set_fullscreen();
+ /* On OS X < 10.6, it is necessary to recreate the window. This is done
+ with hide+show. */
+ w->hide();
+ w->show();
+ Fl::handle(FL_FULLSCREEN, w);
+ }
+
+ void fullscreen_off_x(Fl_Window *w, int X, int Y, int W, int H) {
+ w->_clear_fullscreen();
+ w->hide();
+ w->resize(X, Y, W, H);
+ w->show();
+ Fl::handle(FL_FULLSCREEN, w);
+ }
/*
***************
*** 1997,2001 ****
x->region = 0;
x->subRegion = 0;
! x->cursor = fl_default_cursor;
x->gc = 0; // stay 0 for Quickdraw; fill with CGContext for Quartz
Fl_Window *win = w->window();
--- 2141,2145 ----
x->region = 0;
x->subRegion = 0;
! x->cursor = NULL;
x->gc = 0; // stay 0 for Quickdraw; fill with CGContext for Quartz
Fl_Window *win = w->window();
***************
*** 2099,2103 ****
x->region = 0;
x->subRegion = 0;
! x->cursor = fl_default_cursor;
x->xidChildren = 0;
x->xidNext = 0;
--- 2243,2247 ----
x->region = 0;
x->subRegion = 0;
! x->cursor = NULL;
x->xidChildren = 0;
x->xidNext = 0;
***************
*** 2105,2108 ****
--- 2249,2259 ----
NSRect srect = [[NSScreen mainScreen] frame];
+ if (w->flags() & Fl_Widget::FULLSCREEN) {
+ 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);
+ winstyle = NSBorderlessWindowMask;
+ winlevel = NSStatusWindowLevel;
+ }
NSRect crect;
crect.origin.x = w->x();
***************
*** 2553,2556 ****
--- 2704,2728 ----
}
+ 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);
+ }
+
void Fl::add_timeout(double time, Fl_Timeout_Handler cb, void* data)
{
***************
*** 2677,2680 ****
--- 2849,2856 ----
[(NSWindow *)xid close];
}
+ if (cursor) {
+ [(NSCursor*)cursor release];
+ cursor = NULL;
+ }
}
***************
*** 2792,2857 ****
}
! static NSCursor *PrepareCursor(NSCursor *cursor, CGContextRef (*f)() )
{
! if (cursor == nil) {
! CGContextRef c = f();
! NSImage *image = CGBitmapContextToNSImage(c);
! fl_delete_offscreen( (Fl_Offscreen)c );
! NSPoint pt = {[image size].width/2, [image size].height/2};
! cursor = [[NSCursor alloc] initWithImage:image hotSpot:pt];
}
- return cursor;
- }
- void Fl_X::set_cursor(Fl_Cursor c)
- {
- NSCursor *icrsr;
switch (c) {
! case FL_CURSOR_CROSS: icrsr = [NSCursor crosshairCursor]; break;
! case FL_CURSOR_WAIT:
! static NSCursor *watch = nil;
! watch = PrepareCursor(watch, &Fl_X::watch_cursor_image);
! icrsr = watch;
! break;
! case FL_CURSOR_INSERT: icrsr = [NSCursor IBeamCursor]; break;
! case FL_CURSOR_N: icrsr = [NSCursor resizeUpCursor]; break;
! case FL_CURSOR_S: icrsr = [NSCursor resizeDownCursor]; break;
! case FL_CURSOR_NS: icrsr = [NSCursor resizeUpDownCursor]; break;
! case FL_CURSOR_HELP:
! static NSCursor *help = nil;
! help = PrepareCursor(help, &Fl_X::help_cursor_image);
! icrsr = help;
! break;
! case FL_CURSOR_HAND: icrsr = [NSCursor pointingHandCursor]; break;
! case FL_CURSOR_MOVE: icrsr = [NSCursor openHandCursor]; break;
! case FL_CURSOR_NE:
! case FL_CURSOR_SW:
! case FL_CURSOR_NESW:
! static NSCursor *nesw = nil;
! nesw = PrepareCursor(nesw, &Fl_X::nesw_cursor_image);
! icrsr = nesw;
! break;
! case FL_CURSOR_E: icrsr = [NSCursor resizeRightCursor]; break;
! case FL_CURSOR_W: icrsr = [NSCursor resizeLeftCursor]; break;
! case FL_CURSOR_WE: icrsr = [NSCursor resizeLeftRightCursor]; break;
! case FL_CURSOR_SE:
! case FL_CURSOR_NW:
! case FL_CURSOR_NWSE:
! static NSCursor *nwse = nil;
! nwse = PrepareCursor(nwse, &Fl_X::nwse_cursor_image);
! icrsr = nwse;
! break;
! case FL_CURSOR_NONE:
! static NSCursor *none = nil;
! none = PrepareCursor(none, &Fl_X::none_cursor_image);
! icrsr = none;
! break;
! case FL_CURSOR_ARROW:
! case FL_CURSOR_DEFAULT:
! default: icrsr = [NSCursor arrowCursor];
! break;
}
! [icrsr set];
! cursor = icrsr;
}
--- 2968,3071 ----
}
! int Fl_X::set_cursor(Fl_Cursor c)
{
! if (cursor) {
! [(NSCursor*)cursor release];
! cursor = NULL;
}
switch (c) {
! case FL_CURSOR_ARROW: cursor = [NSCursor arrowCursor]; break;
! case FL_CURSOR_CROSS: cursor = [NSCursor crosshairCursor]; break;
! case FL_CURSOR_INSERT: cursor = [NSCursor IBeamCursor]; break;
! case FL_CURSOR_HAND: cursor = [NSCursor pointingHandCursor]; break;
! case FL_CURSOR_MOVE: cursor = [NSCursor openHandCursor]; break;
! case FL_CURSOR_NS: cursor = [NSCursor resizeUpDownCursor]; break;
! case FL_CURSOR_WE: cursor = [NSCursor resizeLeftRightCursor]; break;
! case FL_CURSOR_N: cursor = [NSCursor resizeUpCursor]; break;
! case FL_CURSOR_E: cursor = [NSCursor resizeRightCursor]; break;
! case FL_CURSOR_W: cursor = [NSCursor resizeLeftCursor]; break;
! case FL_CURSOR_S: cursor = [NSCursor resizeDownCursor]; break;
! default:
! return 0;
! }
!
! [(NSCursor*)cursor retain];
!
! [(NSWindow*)xid invalidateCursorRectsForView:[(NSWindow*)xid contentView]];
!
! return 1;
! }
!
! int Fl_X::set_cursor(const Fl_RGB_Image *image, int hotx, int hoty) {
! if (cursor) {
! [(NSCursor*)cursor release];
! cursor = NULL;
! }
!
! if ((hotx < 0) || (hotx >= image->w()))
! return 0;
! if ((hoty < 0) || (hoty >= image->h()))
! return 0;
!
! // OS X >= 10.6 can create a NSImage from a CGImage, but we need to
! // support older versions, hence this pesky handling.
!
! NSBitmapImageRep *bitmap = [[NSBitmapImageRep alloc]
! initWithBitmapDataPlanes:NULL
! pixelsWide:image->w()
! pixelsHigh:image->h()
! bitsPerSample:8
! samplesPerPixel:image->d()
! hasAlpha:!(image->d() & 1)
! isPlanar:NO
! colorSpaceName:(image->d()<=2) ? NSDeviceWhiteColorSpace : NSDeviceRGBColorSpace
! bytesPerRow:(image->w() * image->d())
! bitsPerPixel:(image->d()*8)];
!
! // Alpha needs to be premultiplied for this format
!
! const uchar *i = (const uchar*)*image->data();
! unsigned char *o = [bitmap bitmapData];
! for (int y = 0;y < image->h();y++) {
! if (image->d() & 1) {
! for (int x = 0;x < image->w();x++) {
! unsigned int alpha;
! if (image->d() == 4) {
! alpha = i[3];
! *o++ = (unsigned char)((unsigned int)*i++ * alpha / 255);
! *o++ = (unsigned char)((unsigned int)*i++ * alpha / 255);
! }
!
! alpha = i[1];
! *o++ = (unsigned char)((unsigned int)*i++ * alpha / 255);
! *o++ = alpha;
! i++;
! }
! } else {
! // No alpha, so we can just copy everything directly.
! int len = image->w() * image->d();
! memcpy(o, i, len);
! o += len;
! i += len;
! }
! i += image->ld();
}
!
! NSImage *nsimage = [[NSImage alloc]
! initWithSize:NSMakeSize(image->w(), image->h())];
!
! [nsimage addRepresentation:bitmap];
!
! cursor = [[NSCursor alloc]
! initWithImage:nsimage
! hotSpot:NSMakePoint(hotx, hoty)];
!
! [(NSWindow*)xid invalidateCursorRectsForView:[(NSWindow*)xid contentView]];
!
! [bitmap release];
! [nsimage release];
!
! return 1;
}
*** fltk-1.3.0/src/Fl_grab.cxx 2010-12-18 16:31:01.000000000 -0600
--- fltk-1.3.0.new/src/Fl_grab.cxx 2011-06-22 22:35:32.000000000 -0500
***************
*** 39,42 ****
--- 39,43 ----
extern void fl_fix_focus(); // in Fl.cxx
+ void fl_update_focus(void);
#ifdef WIN32
***************
*** 51,55 ****
--- 52,68 ----
#endif
+ #if !(defined(WIN32) || defined(__APPLE__))
+ extern int ewmh_supported(); // from Fl_x.cxx
+ #endif
+
void Fl::grab(Fl_Window* win) {
+ Fl_Window *fullscreen_win = NULL;
+ for (Fl_Window *W = Fl::first_window(); W; W = Fl::next_window(W)) {
+ if (W->fullscreen_active()) {
+ fullscreen_win = W;
+ break;
+ }
+ }
+
if (win) {
if (!grab_) {
***************
*** 61,66 ****
Fl_X::i(first_window())->set_key_window();
#else
XGrabPointer(fl_display,
! fl_xid(first_window()),
1,
ButtonPressMask|ButtonReleaseMask|
--- 74,80 ----
Fl_X::i(first_window())->set_key_window();
#else
+ Window xid = fullscreen_win ? fl_xid(fullscreen_win) : fl_xid(first_window());
XGrabPointer(fl_display,
! xid,
1,
ButtonPressMask|ButtonReleaseMask|
***************
*** 72,76 ****
fl_event_time);
XGrabKeyboard(fl_display,
! fl_xid(first_window()),
1,
GrabModeAsync,
--- 86,90 ----
fl_event_time);
XGrabKeyboard(fl_display,
! xid,
1,
GrabModeAsync,
***************
*** 80,83 ****
--- 94,98 ----
}
grab_ = win;
+ fl_update_focus();
} else {
if (grab_) {
***************
*** 88,92 ****
--- 103,110 ----
fl_capture = 0;
#else
+ // We must keep the grab in the non-EWMH fullscreen case
+ if (!fullscreen_win || ewmh_supported()) {
XUngrabKeyboard(fl_display, fl_event_time);
+ }
XUngrabPointer(fl_display, fl_event_time);
// this flush is done in case the picked menu item goes into
***************
*** 95,98 ****
--- 113,117 ----
#endif
grab_ = 0;
+ fl_update_focus();
fl_fix_focus();
}
*** fltk-1.3.0/src/Fl_win32.cxx 2011-05-30 07:33:51.000000000 -0500
--- fltk-1.3.0.new/src/Fl_win32.cxx 2011-06-22 22:35:32.000000000 -0500
***************
*** 99,102 ****
--- 99,104 ----
Fl_Display_Device *Fl_Display_Device::_display = &fl_gdi_display; // the platform display
+ bool use_simple_keyboard = false;
+
// dynamic wsock dll handling api:
#if defined(__CYGWIN__) && !defined(SOCKET)
***************
*** 132,135 ****
--- 134,139 ----
*/
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;
***************
*** 147,150 ****
--- 151,155 ----
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");
***************
*** 425,429 ****
}
! TranslateMessage(&fl_msg);
DispatchMessageW(&fl_msg);
have_message = PeekMessageW(&fl_msg, NULL, 0, 0, PM_REMOVE);
--- 430,439 ----
}
! // Don't bother with key to character translation as we do
! // it manually for simpley keyboard widgets. In fact, calling
! // TranslateMessage() just makes it more difficult as it sets
! // a bunch of internal state.
! if (!use_simple_keyboard)
! TranslateMessage(&fl_msg);
DispatchMessageW(&fl_msg);
have_message = PeekMessageW(&fl_msg, NULL, 0, 0, PM_REMOVE);
***************
*** 543,546 ****
--- 553,586 ----
};
+ void fl_update_clipboard(void) {
+ HWND hwnd = fl_xid(Fl::first_window());
+
+ if (!hwnd)
+ return;
+
+ 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) {
***************
*** 560,582 ****
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;
! }
! }
}
--- 600,606 ----
fl_selection_buffer[clipboard][len] = 0; // needed for direct paste
fl_selection_length[clipboard] = len;
! fl_i_own_selection[clipboard] = 1;
! if (clipboard)
! fl_update_clipboard();
}
***************
*** 631,634 ****
--- 655,690 ----
}
+ 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;
***************
*** 650,653 ****
--- 706,752 ----
}
+ void fl_update_focus(void)
+ {
+ Fl_Widget *focus;
+ Fl_Window *win;
+
+ get_imm_module();
+
+ focus = Fl::grab();
+ if (!focus)
+ focus = Fl::focus();
+ if (!focus)
+ return;
+
+ // Grabs are special in that events are sent to the first
+ // available window
+ if (focus == Fl::grab())
+ win = Fl::first_window();
+ else {
+ win = focus->as_window();
+ if (!win)
+ win = focus->window();
+ }
+
+ if (!win) {
+ Fl::warning("Cannot find window for widget receiving focus");
+ return;
+ }
+
+ // No Win32 window created yet
+ if (!Fl_X::i(win) || !fl_xid(win))
+ return;
+
+ if (focus->simple_keyboard()) {
+ use_simple_keyboard = true;
+ if (flImmGetContext(fl_xid(win)) != 0)
+ flImmAssociateContextEx(fl_xid(win), 0, 0);
+ } else {
+ use_simple_keyboard = false;
+ if (flImmGetContext(fl_xid(win)) == 0)
+ flImmAssociateContextEx(fl_xid(win), 0, IACE_DEFAULT);
+ }
+ }
+
HWND fl_capture;
***************
*** 797,800 ****
--- 896,920 ----
}
+ static xchar msdead2fltk(xchar in)
+ {
+ switch (in) {
+ case 0x0060: // GRAVE ACCENT
+ return 0x0300; // COMBINING GRAVE ACCENT
+ case 0x00b4: // ACUTE ACCENT
+ return 0x0301; // COMBINING ACUTE ACCENT
+ case 0x005e: // CIRCUMFLEX ACCENT
+ return 0x0302; // COMBINING CIRCUMFLEX ACCENT
+ case 0x007e: // TILDE
+ return 0x0303; // COMBINING TILDE
+ case 0x00a8: // DIAERESIS
+ return 0x0308; // COMBINING DIAERESIS
+ // FIXME: Windows dead key behaviour isn't documented and I don't have
+ // any more keyboards to test with...
+ }
+
+ // hope that Windows gave us something proper to begin with
+ return in;
+ }
+
#if USE_COLORMAP
extern HPALETTE fl_select_palette(void); // in fl_color_win32.cxx
***************
*** 858,861 ****
--- 978,983 ----
//fl_msg.lPrivate = ???
+ MSG fl_orig_msg = fl_msg;
+
Fl_Window *window = fl_find(hWnd);
***************
*** 1037,1057 ****
Fl::e_state = state;
static char buffer[1024];
- if (uMsg == WM_CHAR || uMsg == WM_SYSCHAR) {
xchar u = (xchar) wParam;
// Fl::e_length = fl_unicode2utf(&u, 1, buffer);
Fl::e_length = fl_utf8fromwc(buffer, 1024, &u, 1);
buffer[Fl::e_length] = 0;
!
! } else if (Fl::e_keysym >= FL_KP && Fl::e_keysym <= FL_KP_Last) {
! if (state & FL_NUM_LOCK) {
! // Convert to regular keypress...
! buffer[0] = Fl::e_keysym-FL_KP;
! Fl::e_length = 1;
! } else {
! // Convert to special keypress...
! buffer[0] = 0;
! Fl::e_length = 0;
switch (Fl::e_keysym) {
case FL_KP + '0' :
--- 1159,1238 ----
Fl::e_state = state;
static char buffer[1024];
+ if (use_simple_keyboard) {
+ BYTE keystate[256];
+ WCHAR wbuf[8];
+ int ret;
+
+ // I'm not sure if we ever get WM_CHAR (& friends) without an initial
+ // WM_KEYDOWN (& friends), but if we do then we should not send such
+ // side band events to simple keyboard widgets.
+ if ((fl_orig_msg.message != WM_KEYDOWN) &&
+ (fl_orig_msg.message != WM_SYSKEYDOWN) &&
+ (fl_orig_msg.message != WM_KEYUP) &&
+ (fl_orig_msg.message != WM_SYSKEYUP))
+ break;
+
+ GetKeyboardState(keystate);
+
+ // Pressing Ctrl wreaks havoc with the symbol lookup, so turn that off.
+ // But AltGr shows up as Ctrl+Alt in Windows, so keep Ctrl if Alt is
+ // active.
+ if (!(keystate[VK_MENU] & (1<<31)))
+ keystate[VK_CONTROL] = keystate[VK_LCONTROL] = keystate[VK_RCONTROL] = 0;
+
+ // We cannot inspect or modify Windows' internal state of the keyboard
+ // so we have to try to infer information from ToUnicode() and wedge
+ // things into a known state.
+ for (int i = 0;i < 2;i++) {
+ ret = ToUnicode(fl_orig_msg.wParam, 0, keystate, wbuf,
+ sizeof(wbuf)/sizeof(wbuf[0]), 0);
+
+ // No symbol for this key (or unexpected length)
+ if ((ret == 0) || (ret < -1)) {
+ buffer[0] = 0;
+ Fl::e_length = 0;
+ break;
+ }
+
+ // A dead key. Convert this to a Unicode combining character so
+ // that the application can tell the difference between dead and
+ // normal keys.
+ if (ret == -1) {
+ xchar u = (xchar) msdead2fltk(wbuf[0]);
+ Fl::e_length = fl_utf8fromwc(buffer, 1024, &u, 1);
+ buffer[Fl::e_length] = 0;
+ break;
+ }
+
+ // If we have two characters (or more) from ToUnicode(), that's
+ // an invalid sequence. One character chould mean a proper symbol,
+ // or it could mean a composed one. In both cases we need to call
+ // ToUnicode() again to get something sane.
+ if (i == 0)
+ continue;
+
+ // We should now have something sane. Give whatever we have to the
+ // application.
+ Fl::e_length = fl_utf8fromwc(buffer, 1024, wbuf, ret);
+ buffer[Fl::e_length] = 0;
+ }
+ } else if (uMsg == WM_CHAR || uMsg == WM_SYSCHAR) {
xchar u = (xchar) wParam;
// Fl::e_length = fl_unicode2utf(&u, 1, buffer);
Fl::e_length = fl_utf8fromwc(buffer, 1024, &u, 1);
buffer[Fl::e_length] = 0;
+ } else {
+ buffer[0] = 0;
+ Fl::e_length = 0;
+ }
! // The keypad area is a bit odd in that we need to change the keysym
! // to properly indicate what the user meant, unlike other keys where
! // we normally change the text and keep keysym stable.
! if (Fl::e_keysym >= FL_KP && Fl::e_keysym <= FL_KP_Last) {
! // The initial mapping tables give us a keysym that corresponds to
! // numlock being on, so we only do something when it is off.
! if (!(state & FL_NUM_LOCK)) {
switch (Fl::e_keysym) {
case FL_KP + '0' :
***************
*** 1085,1112 ****
Fl::e_keysym = FL_Delete;
break;
- case FL_KP + '/' :
- case FL_KP + '*' :
- case FL_KP + '-' :
- case FL_KP + '+' :
- buffer[0] = Fl::e_keysym-FL_KP;
- Fl::e_length = 1;
- break;
}
}
- } else if ((lParam & (1<<31))==0) {
- #ifdef FLTK_PREVIEW_DEAD_KEYS
- if ((lParam & (1<<24))==0) { // clear if dead key (always?)
- xchar u = (xchar) wParam;
- Fl::e_length = fl_utf8fromwc(buffer, 1024, &u, 1);
- buffer[Fl::e_length] = 0;
- } else { // set if "extended key" (never printable?)
- buffer[0] = 0;
- Fl::e_length = 0;
- }
- #else
- buffer[0] = 0;
- Fl::e_length = 0;
- #endif
}
Fl::e_text = buffer;
if (lParam & (1<<31)) { // key up events.
--- 1266,1273 ----
Fl::e_keysym = FL_Delete;
break;
}
}
}
+
Fl::e_text = buffer;
if (lParam & (1<<31)) { // key up events.
***************
*** 1126,1129 ****
--- 1287,1291 ----
static int delta = 0; // running total of all motion
delta += (SHORT)(HIWORD(wParam));
+ Fl::e_dx = 0;
Fl::e_dy = -delta / WHEEL_DELTA;
delta += Fl::e_dy * WHEEL_DELTA;
***************
*** 1132,1135 ****
--- 1294,1312 ----
}
+ // This is only defined on Vista and upwards...
+ #ifndef WM_MOUSEHWHEEL
+ #define WM_MOUSEHWHEEL 0x020E
+ #endif
+
+ case WM_MOUSEHWHEEL: {
+ static int delta = 0; // running total of all motion
+ delta += (SHORT)(HIWORD(wParam));
+ Fl::e_dy = 0;
+ Fl::e_dx = delta / WHEEL_DELTA;
+ delta -= Fl::e_dx * WHEEL_DELTA;
+ if (Fl::e_dx) Fl::handle(FL_MOUSEWHEEL, window);
+ return 0;
+ }
+
case WM_GETMINMAXINFO:
Fl_X::i(window)->set_minmax((LPMINMAXINFO)lParam);
***************
*** 1186,1216 ****
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;}
default:
--- 1363,1386 ----
return 1;
! 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:
***************
*** 1321,1324 ****
--- 1491,1499 ----
Y+=yoff;
+ if (w->flags() & Fl_Widget::FULLSCREEN) {
+ X = Y = 0;
+ bx = by = bt = 0;
+ }
+
return ret;
}
***************
*** 1371,1374 ****
--- 1546,1601 ----
}
+ static void make_fullscreen(Fl_Window *w, Window xid, int X, int Y, int W, int H) {
+ int sx, sy, sw, sh;
+ Fl::screen_xywh(sx, sy, sw, sh, X, Y, W, H);
+ 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);
+ }
+
+ void fullscreen_x(Fl_Window *w) {
+ w->_set_fullscreen();
+ make_fullscreen(w, fl_xid(w), w->x(), w->y(), w->w(), w->h());
+ Fl::handle(FL_FULLSCREEN, w);
+ }
+
+ void fullscreen_off_x(Fl_Window *w, int X, int Y, int W, int H) {
+ w->_clear_fullscreen();
+ DWORD style = GetWindowLong(fl_xid(w), GWL_STYLE);
+ // Remove the xid temporarily so that Fl_X::fake_X_wm() behaves like it
+ // does in Fl_X::make().
+ HWND xid = fl_xid(w);
+ Fl_X::i(w)->xid = NULL;
+ int x, y, bt, bx, by;
+ switch (Fl_X::fake_X_wm(w, x, y, bt, bx, by)) {
+ case 0:
+ break;
+ case 1:
+ style |= WS_CAPTION;
+ break;
+ case 2:
+ if (w->border()) {
+ style |= WS_THICKFRAME | WS_CAPTION;
+ }
+ break;
+ }
+ Fl_X::i(w)->xid = xid;
+ // Adjust for decorations (but not if that puts the decorations
+ // outside the screen)
+ if ((X != w->x()) || (Y != w->y())) {
+ X -= bx;
+ Y -= by+bt;
+ }
+ W += bx*2;
+ H += by*2+bt;
+ SetWindowLong(fl_xid(w), GWL_STYLE, style);
+ SetWindowPos(fl_xid(w), 0, X, Y, W, H,
+ SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED);
+ Fl::handle(FL_FULLSCREEN, w);
+ }
+
+
////////////////////////////////////////////////////////////////
***************
*** 1409,1413 ****
char fl_show_iconic; // hack for Fl_Window::iconic()
// int fl_background_pixel = -1; // color to use for background
- HCURSOR fl_default_cursor;
UINT fl_wake_msg = 0;
int fl_disable_transient_for; // secret method of removing TRANSIENT_FOR
--- 1636,1639 ----
***************
*** 1457,1461 ****
w->icon((void *)LoadIcon(NULL, IDI_APPLICATION));
wcw.hIcon = wcw.hIconSm = (HICON)w->icon();
! wcw.hCursor = fl_default_cursor = LoadCursor(NULL, IDC_ARROW);
//uchar r,g,b; Fl::get_color(FL_GRAY,r,g,b);
//wc.hbrBackground = (HBRUSH)CreateSolidBrush(RGB(r,g,b));
--- 1683,1687 ----
w->icon((void *)LoadIcon(NULL, IDI_APPLICATION));
wcw.hIcon = wcw.hIconSm = (HICON)w->icon();
! wcw.hCursor = LoadCursor(NULL, IDC_ARROW);
//uchar r,g,b; Fl::get_color(FL_GRAY,r,g,b);
//wc.hbrBackground = (HBRUSH)CreateSolidBrush(RGB(r,g,b));
***************
*** 1500,1515 ****
switch (fake_X_wm(w, xwm, ywm, bt, bx, by)) {
// No border (used for menus)
! case 0: style |= WS_POPUP;
! styleEx |= WS_EX_TOOLWINDOW;
break;
// Thin border and title bar
! case 1: style |= WS_DLGFRAME | WS_CAPTION; break;
// Thick, resizable border and title bar, with maximize button
! case 2: style |= WS_THICKFRAME | WS_MAXIMIZEBOX | WS_CAPTION ; break;
}
if (by+bt) {
- if (!w->modal()) style |= WS_SYSMENU | WS_MINIMIZEBOX;
wp += 2*bx;
hp += 2*by+bt;
--- 1726,1749 ----
switch (fake_X_wm(w, xwm, ywm, bt, bx, by)) {
// No border (used for menus)
! case 0:
! style |= WS_POPUP;
! styleEx |= WS_EX_TOOLWINDOW;
break;
// Thin border and title bar
! case 1:
! style |= WS_DLGFRAME | WS_CAPTION;
! if (!w->modal())
! style |= WS_SYSMENU | WS_MINIMIZEBOX;
! break;
// Thick, resizable border and title bar, with maximize button
! case 2:
! style |= WS_THICKFRAME | WS_SYSMENU | WS_MAXIMIZEBOX | WS_CAPTION;
! if (!w->modal())
! style |= WS_MINIMIZEBOX;
! break;
}
if (by+bt) {
wp += 2*bx;
hp += 2*by+bt;
***************
*** 1541,1545 ****
x->region = 0;
x->private_dc = 0;
! x->cursor = fl_default_cursor;
if (!fl_codepage) fl_get_codepage();
--- 1775,1779 ----
x->region = 0;
x->private_dc = 0;
! x->cursor = LoadCursor(NULL, IDC_ARROW);
if (!fl_codepage) fl_get_codepage();
***************
*** 1567,1573 ****
--- 1801,1821 ----
if (lab) free(lab);
+ if (w->flags() & Fl_Widget::FULLSCREEN) {
+ /* We need to make sure that the fullscreen is created on the
+ default monitor, ie the desktop where the shortcut is located
+ etc. This requires that CreateWindow is called with CW_USEDEFAULT
+ for x and y. We can then use GetWindowRect to determine which
+ 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->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;}
***************
*** 1582,1586 ****
// other windows from the code, or we lose the capture.
ShowWindow(x->xid, !showit ? SW_SHOWMINNOACTIVE :
! (Fl::grab() || (style & WS_POPUP)) ? SW_SHOWNOACTIVATE : SW_SHOWNORMAL);
// Register all windows for potential drag'n'drop operations
--- 1830,1834 ----
// other windows from the code, or we lose the capture.
ShowWindow(x->xid, !showit ? SW_SHOWMINNOACTIVE :
! (Fl::grab() || (styleEx & WS_EX_TOOLWINDOW)) ? SW_SHOWNOACTIVATE : SW_SHOWNORMAL);
// Register all windows for potential drag'n'drop operations
***************
*** 1778,1781 ****
--- 2026,2152 ----
////////////////////////////////////////////////////////////////
+
+ #ifndef IDC_HAND
+ # define IDC_HAND MAKEINTRESOURCE(32649)
+ #endif // !IDC_HAND
+
+ int Fl_X::set_cursor(Fl_Cursor c) {
+ LPSTR n;
+
+ if (c == FL_CURSOR_NONE)
+ 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;
+ }
+
+ cursor = LoadCursor(NULL, n);
+ if (cursor == NULL)
+ return 0;
+ }
+
+ SetCursor(cursor);
+
+ return 1;
+ }
+
+ int Fl_X::set_cursor(const Fl_RGB_Image *image, int hotx, int hoty) {
+ BITMAPV5HEADER bi;
+ HBITMAP bitmap, mask;
+ DWORD *bits;
+
+ if ((hotx < 0) || (hotx >= image->w()))
+ return 0;
+ if ((hoty < 0) || (hoty >= image->h()))
+ return 0;
+
+ memset(&bi, 0, sizeof(BITMAPV5HEADER));
+
+ bi.bV5Size = sizeof(BITMAPV5HEADER);
+ bi.bV5Width = image->w();
+ bi.bV5Height = image->h();
+ bi.bV5Planes = 1;
+ bi.bV5BitCount = 32;
+ bi.bV5Compression = BI_BITFIELDS;
+ bi.bV5RedMask = 0x00FF0000;
+ bi.bV5GreenMask = 0x0000FF00;
+ bi.bV5BlueMask = 0x000000FF;
+ bi.bV5AlphaMask = 0xFF000000;
+
+ HDC hdc;
+
+ hdc = GetDC(NULL);
+ bitmap = CreateDIBSection(hdc, (BITMAPINFO*)&bi, DIB_RGB_COLORS, (void**)&bits, NULL, 0);
+ ReleaseDC(NULL, hdc);
+
+ const uchar *i = (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:
+ *bits = (0xff<<24) | (i[0]<<16) | (i[0]<<8) | i[0];
+ break;
+ case 2:
+ *bits = (i[1]<<24) | (i[0]<<16) | (i[0]<<8) | i[0];
+ break;
+ case 3:
+ *bits = (0xff<<24) | (i[0]<<16) | (i[1]<<8) | i[2];
+ break;
+ case 4:
+ *bits = (i[3]<<24) | (i[0]<<16) | (i[1]<<8) | i[2];
+ break;
+ }
+ i += image->d();
+ bits++;
+ }
+ i += image->ld();
+ }
+
+ // A mask bitmap is still needed even though it isn't used
+ mask = CreateBitmap(image->w(),image->h(),1,1,NULL);
+
+ ICONINFO ii;
+
+ ii.fIcon = FALSE;
+ ii.xHotspot = hotx;
+ ii.yHotspot = hoty;
+ ii.hbmMask = mask;
+ ii.hbmColor = bitmap;
+
+ cursor = CreateIconIndirect(&ii);
+
+ DeleteObject(bitmap);
+ DeleteObject(mask);
+
+ SetCursor(cursor);
+
+ return 1;
+ }
+
+ ////////////////////////////////////////////////////////////////
// Implement the virtual functions for the base Fl_Window class:
*** fltk-1.3.0/src/Fl_x.cxx 2011-05-30 11:47:48.000000000 -0500
--- fltk-1.3.0.new/src/Fl_x.cxx 2011-06-22 22:35:32.000000000 -0500
***************
*** 53,56 ****
--- 53,65 ----
# include <X11/Xlib.h>
# include <X11/keysym.h>
+ # include <X11/cursorfont.h>
+
+ # if HAVE_XCURSOR
+ # include <X11/Xcursor/Xcursor.h>
+ # endif
+
+ # ifdef HAVE_XFIXES
+ # include <X11/extensions/Xfixes.h>
+ # endif
static Fl_Xlib_Graphics_Driver fl_xlib_driver;
***************
*** 301,306 ****
--- 310,318 ----
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;
+ static bool have_xfixes = false;
+ static int xfixes_event_base = 0;
static Atom WM_DELETE_WINDOW;
***************
*** 309,312 ****
--- 321,327 ----
static Atom TARGETS;
static Atom CLIPBOARD;
+ static Atom TIMESTAMP;
+ static Atom PRIMARY_TIMESTAMP;
+ static Atom CLIPBOARD_TIMESTAMP;
Atom fl_XdndAware;
Atom fl_XdndSelection;
***************
*** 329,332 ****
--- 344,350 ----
Atom fl_NET_WM_NAME; // utf8 aware window label
Atom fl_NET_WM_ICON_NAME; // utf8 aware window icon name
+ Atom fl_NET_SUPPORTING_WM_CHECK;
+ Atom fl_NET_WM_STATE;
+ Atom fl_NET_WM_STATE_FULLSCREEN;
/*
***************
*** 582,585 ****
--- 600,662 ----
}
+ 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;
+ }
+
+ extern Fl_Window *fl_xfocus;
+
+ void fl_update_focus(void)
+ {
+ Fl_Widget *focus;
+
+ focus = Fl::grab();
+ if (!focus)
+ focus = Fl::focus();
+ if (!focus)
+ return;
+
+ if (focus->simple_keyboard()) {
+ fl_xim_deactivate();
+ } else {
+ // fl_xfocus should always be set if something has focus, but let's
+ // play it safe
+ if (!fl_xfocus || !fl_xid(fl_xfocus))
+ return;
+
+ fl_xim_activate(fl_xid(fl_xfocus));
+ }
+ }
+
void fl_open_display() {
if (fl_display) return;
***************
*** 605,608 ****
--- 682,688 ----
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);
***************
*** 626,629 ****
--- 706,712 ----
fl_NET_WM_NAME = XInternAtom(d, "_NET_WM_NAME", 0);
fl_NET_WM_ICON_NAME = XInternAtom(d, "_NET_WM_ICON_NAME", 0);
+ 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);
if (sizeof(Atom) < 4)
***************
*** 647,650 ****
--- 730,741 ----
Fl::visual(FL_RGB);
#endif
+
+ #ifdef HAVE_XFIXES
+ int error_base;
+ if (XFixesQueryExtension(d, &xfixes_event_base, &error_base))
+ have_xfixes = true;
+ else
+ have_xfixes = false;
+ #endif
}
***************
*** 769,772 ****
--- 860,888 ----
}
+
+ /*
+ Get window property value (32 bit format)
+ Returns zero on success, -1 on error
+ */
+ static int get_xwinprop(Window wnd, Atom prop, long max_length,
+ unsigned long *nitems, unsigned long **data) {
+ Atom actual;
+ int format;
+ unsigned long bytes_after;
+
+ if (Success != XGetWindowProperty(fl_display, wnd, prop, 0, max_length,
+ False, AnyPropertyType, &actual, &format,
+ nitems, &bytes_after, (unsigned char**)data)) {
+ return -1;
+ }
+
+ if (actual == None || format != 32) {
+ return -1;
+ }
+
+ return 0;
+ }
+
+
////////////////////////////////////////////////////////////////
// Code for copying to clipboard and DnD out of the program:
***************
*** 788,791 ****
--- 904,995 ----
////////////////////////////////////////////////////////////////
+ // Code for tracking clipboard changes:
+
+ static Time primary_timestamp = -1;
+ static Time clipboard_timestamp = -1;
+
+ extern bool fl_clipboard_notify_empty(void);
+ extern void fl_trigger_clipboard_notify(int source);
+
+ static void poll_clipboard_owner(void) {
+ Window xid;
+
+ // No polling needed with Xfixes
+ if (have_xfixes)
+ return;
+
+ // No one is interested, so no point polling
+ if (fl_clipboard_notify_empty())
+ return;
+
+ // We need a window for this to work
+ if (!Fl::first_window())
+ return;
+ xid = fl_xid(Fl::first_window());
+ if (!xid)
+ return;
+
+ // Request an update of the selection time for both the primary and
+ // clipboard selections. Magic continues when we get a SelectionNotify.
+ if (!fl_i_own_selection[0])
+ XConvertSelection(fl_display, XA_PRIMARY, TIMESTAMP, PRIMARY_TIMESTAMP,
+ xid, fl_event_time);
+ if (!fl_i_own_selection[1])
+ XConvertSelection(fl_display, CLIPBOARD, TIMESTAMP, CLIPBOARD_TIMESTAMP,
+ xid, fl_event_time);
+ }
+
+ static void clipboard_timeout(void *data)
+ {
+ // No one is interested, so stop polling
+ if (fl_clipboard_notify_empty())
+ return;
+
+ poll_clipboard_owner();
+
+ Fl::repeat_timeout(0.5, clipboard_timeout);
+ }
+
+ static void handle_clipboard_timestamp(int clipboard, Time time)
+ {
+ Time *timestamp;
+
+ timestamp = clipboard ? &clipboard_timestamp : &primary_timestamp;
+
+ if (!have_xfixes) {
+ // Initial scan, just store the value
+ if (*timestamp == (Time)-1) {
+ *timestamp = time;
+ return;
+ }
+ }
+
+ // Same selection
+ if (time == *timestamp)
+ return;
+
+ *timestamp = time;
+
+ // Something happened! Let's tell someone!
+ fl_trigger_clipboard_notify(clipboard);
+ }
+
+ void fl_clipboard_notify_change() {
+ // Reset the timestamps if we've going idle so that you don't
+ // get a bogus immediate trigger next time they're activated.
+ if (fl_clipboard_notify_empty()) {
+ primary_timestamp = -1;
+ clipboard_timestamp = -1;
+ } else {
+ if (!have_xfixes) {
+ poll_clipboard_owner();
+
+ if (!Fl::has_timeout(clipboard_timeout))
+ Fl::add_timeout(0.5, clipboard_timeout);
+ }
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////
const XEvent* fl_xevent; // the current x event
***************
*** 865,872 ****
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))
{
XIM xim_im;
--- 1069,1075 ----
fl_xevent = &thisevent;
Window xid = xevent.xany.window;
if (fl_xim_ic && xevent.type == DestroyNotify &&
! xid != fl_xim_win && !fl_find(xid))
{
XIM xim_im;
***************
*** 883,929 ****
}
! 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
}
- if ( XFilterEvent((XEvent *)&xevent, 0) )
- return(1);
-
switch (xevent.type) {
--- 1086,1094 ----
}
! if (fl_xim_ic) {
! if (XFilterEvent((XEvent *)&xevent, 0))
! return 1;
}
switch (xevent.type) {
***************
*** 937,941 ****
case SelectionNotify: {
- if (!fl_selection_requestor) return 0;
static unsigned char* buffer = 0;
if (buffer) {XFree(buffer); buffer = 0;}
--- 1102,1105 ----
***************
*** 953,956 ****
--- 1117,1133 ----
&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;
***************
*** 989,992 ****
--- 1166,1172 ----
convert_crlf(buffer, bytesread);
}
+
+ if (!fl_selection_requestor) return 0;
+
Fl::e_text = buffer ? (char*)buffer : (char *)"";
Fl::e_length = bytesread;
***************
*** 1009,1012 ****
--- 1189,1193 ----
int clipboard = fl_xevent->xselectionclear.selection == CLIPBOARD;
fl_i_own_selection[clipboard] = 0;
+ poll_clipboard_owner();
return 1;}
***************
*** 1221,1224 ****
--- 1402,1408 ----
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;
***************
*** 1261,1273 ****
len = XLookupString((XKeyEvent*)&(xevent.xkey),
buffer, buffer_len, &keysym, 0/*&compose*/);
! if (keysym && keysym < 0x400) { // a character in latin-1,2,3,4 sets
! // force it to type a character (not sure if this ever is needed):
! // if (!len) {buffer[0] = char(keysym); len = 1;}
! len = fl_utf8encode(XKeysymToUcs(keysym), buffer);
! if (len < 1) len = 1;
! // ignore all effects of shift on the keysyms, which makes it a lot
! // easier to program shortcuts and is Windoze-compatible:
! keysym = XKeycodeToKeysym(fl_display, keycode, 0);
! }
}
// MRS: Can't use Fl::event_state(FL_CTRL) since the state is not
--- 1445,1457 ----
len = XLookupString((XKeyEvent*)&(xevent.xkey),
buffer, buffer_len, &keysym, 0/*&compose*/);
! // XLookupString() is only defined to return Latin-1 (although it
! // often gives you more). To be safe, use our own lookups based on
! // keysym.
! len = fl_utf8encode(XKeysymToUcs(keysym), buffer);
! if (len < 1)
! len = 1;
! // ignore all effects of shift on the keysyms, which makes it a lot
! // easier to program shortcuts and is Windoze-compatable:
! keysym = XKeycodeToKeysym(fl_display, keycode, 0);
}
// MRS: Can't use Fl::event_state(FL_CTRL) since the state is not
***************
*** 1441,1444 ****
--- 1625,1629 ----
Fl::e_keysym = FL_Button + xevent.xbutton.button;
set_event_xy();
+ Fl::e_dx = Fl::e_dy = 0;
if (xevent.xbutton.button == Button4) {
Fl::e_dy = -1; // Up
***************
*** 1447,1450 ****
--- 1632,1641 ----
Fl::e_dy = +1; // Down
event = FL_MOUSEWHEEL;
+ } else if (xevent.xbutton.button == 6) {
+ Fl::e_dx = -1; // Left
+ event = FL_MOUSEWHEEL;
+ } else if (xevent.xbutton.button == 7) {
+ Fl::e_dx = +1; // Right
+ event = FL_MOUSEWHEEL;
} else {
Fl::e_state |= (FL_BUTTON1 << (xevent.xbutton.button-1));
***************
*** 1457,1460 ****
--- 1648,1676 ----
break;
+ case PropertyNotify:
+ if (xevent.xproperty.atom == fl_NET_WM_STATE) {
+ int fullscreen_state = 0;
+ if (xevent.xproperty.state != PropertyDelete) {
+ unsigned long nitems;
+ unsigned long *words = 0;
+ if (0 == get_xwinprop(xid, fl_NET_WM_STATE, 64, &nitems, &words) ) {
+ for (unsigned long item = 0; item < nitems; item++) {
+ if (words[item] == fl_NET_WM_STATE_FULLSCREEN) {
+ fullscreen_state = 1;
+ }
+ }
+ }
+ }
+ if (window->fullscreen_active() && !fullscreen_state) {
+ window->_clear_fullscreen();
+ event = FL_FULLSCREEN;
+ }
+ if (!window->fullscreen_active() && fullscreen_state) {
+ window->_set_fullscreen();
+ event = FL_FULLSCREEN;
+ }
+ }
+ break;
+
case MotionNotify:
set_event_xy();
***************
*** 1557,1560 ****
--- 1773,1795 ----
}
+ #ifdef HAVE_XFIXES
+ switch (xevent.type - xfixes_event_base) {
+ case XFixesSelectionNotify: {
+ // Someone feeding us bogus events?
+ if (!have_xfixes)
+ return true;
+
+ XFixesSelectionNotifyEvent *selection_notify = (XFixesSelectionNotifyEvent *)&xevent;
+
+ if ((selection_notify->selection == XA_PRIMARY) && !fl_i_own_selection[0])
+ handle_clipboard_timestamp(0, selection_notify->selection_timestamp);
+ else if ((selection_notify->selection == CLIPBOARD) && !fl_i_own_selection[1])
+ handle_clipboard_timestamp(1, selection_notify->selection_timestamp);
+
+ return true;
+ }
+ }
+ #endif
+
return Fl::handle(event, window);
}
***************
*** 1596,1599 ****
--- 1831,1903 ----
////////////////////////////////////////////////////////////////
+ #define _NET_WM_STATE_REMOVE 0 /* remove/unset property */
+ #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) {
+ XEvent e;
+ e.xany.type = ClientMessage;
+ e.xany.window = wnd;
+ e.xclient.message_type = fl_NET_WM_STATE;
+ 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;
+ XSendEvent(fl_display, RootWindow(fl_display, fl_screen),
+ 0, SubstructureNotifyMask | SubstructureRedirectMask,
+ &e);
+ }
+
+ int ewmh_supported() {
+ static int result = -1;
+
+ if (result == -1) {
+ result = 0;
+ unsigned long nitems;
+ unsigned long *words = 0;
+ if (0 == get_xwinprop(XRootWindow(fl_display, fl_screen), fl_NET_SUPPORTING_WM_CHECK, 64,
+ &nitems, &words) && nitems == 1) {
+ Window child = words[0];
+ if (0 == get_xwinprop(child, fl_NET_SUPPORTING_WM_CHECK, 64,
+ &nitems, &words) && nitems == 1) {
+ result = (child == words[0]);
+ }
+ }
+ }
+
+ return result;
+ }
+
+ /* Change an existing window to fullscreen */
+ void fullscreen_x(Fl_Window *w) {
+ if (ewmh_supported()) {
+ send_wm_state_event(fl_xid(w), 1, fl_NET_WM_STATE_FULLSCREEN);
+ } else {
+ w->_set_fullscreen();
+ w->hide();
+ w->show();
+ /* We want to grab the window, not a widget, so we cannot use Fl::grab */
+ XGrabKeyboard(fl_display, fl_xid(w), 1, GrabModeAsync, GrabModeAsync, fl_event_time);
+ Fl::handle(FL_FULLSCREEN, w);
+ }
+ }
+
+ void fullscreen_off_x(Fl_Window *w, int X, int Y, int W, int H) {
+ if (ewmh_supported()) {
+ send_wm_state_event(fl_xid(w), 0, fl_NET_WM_STATE_FULLSCREEN);
+ } else {
+ w->_clear_fullscreen();
+ /* The grab will be lost when the window is destroyed */
+ w->hide();
+ w->resize(X,Y,W,H);
+ w->show();
+ Fl::handle(FL_FULLSCREEN, w);
+ }
+ }
+
+ ////////////////////////////////////////////////////////////////
+
// A subclass of Fl_Window may call this to associate an X window it
// creates with the Fl_Window:
***************
*** 1631,1634 ****
--- 1935,1939 ----
|ButtonPressMask|ButtonReleaseMask
|EnterWindowMask|LeaveWindowMask
+ |PropertyChangeMask
|PointerMotionMask;
***************
*** 1702,1705 ****
--- 2007,2020 ----
if (!win->border()) {attr.override_redirect = 1; mask |= CWOverrideRedirect;}
}
+ // For the non-EWMH fullscreen case, we cannot use the code above,
+ // since we do not want save_under, do not want to turn off the
+ // border, and cannot grab without an existing window. Besides,
+ // there is no clear_override().
+ if (win->flags() & Fl_Widget::FULLSCREEN && !ewmh_supported()) {
+ attr.override_redirect = 1;
+ mask |= CWOverrideRedirect;
+ Fl::screen_xywh(X, Y, W, H, X, Y, W, H);
+ }
+
if (fl_background_pixel >= 0) {
attr.background_pixel = fl_background_pixel;
***************
*** 1761,1764 ****
--- 2076,2085 ----
}
+ // If asked for, create fullscreen
+ if (win->flags() & Fl_Widget::FULLSCREEN && ewmh_supported()) {
+ XChangeProperty (fl_display, xp->xid, fl_NET_WM_STATE, XA_ATOM, 32,
+ PropModeAppend, (unsigned char*) &fl_NET_WM_STATE_FULLSCREEN, 1);
+ }
+
// Make it receptive to DnD:
long version = 4;
***************
*** 1790,1793 ****
--- 2111,2124 ----
}
+ #ifdef HAVE_XFIXES
+ // register for clipboard change notifications
+ if (have_xfixes && !win->parent()) {
+ XFixesSelectSelectionInput(fl_display, xp->xid, XA_PRIMARY,
+ XFixesSetSelectionOwnerNotifyMask);
+ XFixesSelectSelectionInput(fl_display, xp->xid, CLIPBOARD,
+ XFixesSetSelectionOwnerNotifyMask);
+ }
+ #endif
+
XMapWindow(fl_display, xp->xid);
if (showit) {
***************
*** 1798,1801 ****
--- 2129,2138 ----
win->redraw();
}
+
+ // non-EWMH fullscreen case, need grab
+ if (win->flags() & Fl_Widget::FULLSCREEN && !ewmh_supported()) {
+ XGrabKeyboard(fl_display, xp->xid, 1, GrabModeAsync, GrabModeAsync, fl_event_time);
+ }
+
}
***************
*** 1884,1887 ****
--- 2221,2312 ----
////////////////////////////////////////////////////////////////
+ int Fl_X::set_cursor(Fl_Cursor c) {
+ unsigned int shape;
+ Cursor xc;
+
+ switch (c) {
+ case FL_CURSOR_ARROW: shape = XC_left_ptr; break;
+ case FL_CURSOR_CROSS: shape = XC_tcross; break;
+ case FL_CURSOR_WAIT: shape = XC_watch; break;
+ case FL_CURSOR_INSERT: shape = XC_xterm; break;
+ case FL_CURSOR_HAND: shape = XC_hand2; break;
+ case FL_CURSOR_HELP: shape = XC_question_arrow; break;
+ case FL_CURSOR_MOVE: shape = XC_fleur; break;
+ case FL_CURSOR_NS: shape = XC_sb_v_double_arrow; break;
+ case FL_CURSOR_WE: shape = XC_sb_h_double_arrow; break;
+ case FL_CURSOR_NE: shape = XC_top_right_corner; break;
+ case FL_CURSOR_N: shape = XC_top_side; break;
+ case FL_CURSOR_NW: shape = XC_top_left_corner; break;
+ case FL_CURSOR_E: shape = XC_right_side; break;
+ case FL_CURSOR_W: shape = XC_left_side; break;
+ case FL_CURSOR_SE: shape = XC_bottom_right_corner; break;
+ case FL_CURSOR_S: shape = XC_bottom_side; break;
+ case FL_CURSOR_SW: shape = XC_bottom_left_corner; break;
+ default:
+ return 0;
+ }
+
+ xc = XCreateFontCursor(fl_display, shape);
+ XDefineCursor(fl_display, xid, xc);
+ XFreeCursor(fl_display, xc);
+
+ return 1;
+ }
+
+ int Fl_X::set_cursor(const Fl_RGB_Image *image, int hotx, int hoty) {
+ #if ! HAVE_XCURSOR
+ return 0;
+ #else
+ XcursorImage *cursor;
+ Cursor xc;
+
+ if ((hotx < 0) || (hotx >= image->w()))
+ return 0;
+ if ((hoty < 0) || (hoty >= image->h()))
+ return 0;
+
+ cursor = XcursorImageCreate(image->w(), image->h());
+ if (!cursor)
+ return 0;
+
+ const uchar *i = (const uchar*)*image->data();
+ XcursorPixel *o = cursor->pixels;
+ for (int y = 0;y < image->h();y++) {
+ for (int x = 0;x < image->w();x++) {
+ switch (image->d()) {
+ case 1:
+ *o = (0xff<<24) | (i[0]<<16) | (i[0]<<8) | i[0];
+ break;
+ case 2:
+ *o = (i[1]<<24) | (i[0]<<16) | (i[0]<<8) | i[0];
+ break;
+ case 3:
+ *o = (0xff<<24) | (i[0]<<16) | (i[1]<<8) | i[2];
+ break;
+ case 4:
+ *o = (i[3]<<24) | (i[0]<<16) | (i[1]<<8) | i[2];
+ break;
+ }
+ i += image->d();
+ o++;
+ }
+ i += image->ld();
+ }
+
+ cursor->xhot = hotx;
+ cursor->yhot = hoty;
+
+ xc = XcursorImageLoadCursor(fl_display, cursor);
+ XDefineCursor(fl_display, xid, xc);
+ XFreeCursor(fl_display, xc);
+
+ XcursorImageDestroy(cursor);
+
+ return 1;
+ #endif
+ }
+
+ ////////////////////////////////////////////////////////////////
+
// returns pointer to the filename, or null if name ends with '/'
const char *fl_filename_name(const char *name) {
*** fltk-1.3.0/src/fl_cursor.cxx 2010-12-18 16:31:01.000000000 -0600
--- fltk-1.3.0.new/src/fl_cursor.cxx 2011-06-22 22:35:32.000000000 -0500
***************
*** 34,331 ****
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
#include <FL/x.H>
- #if !defined(WIN32) && !defined(__APPLE__)
- # include <X11/cursorfont.h>
- #endif
#include <FL/fl_draw.H>
/**
Sets the cursor for the current window to the specified shape and colors.
The cursors are defined in the <FL/Enumerations.H> header file.
*/
void fl_cursor(Fl_Cursor c, Fl_Color fg, Fl_Color bg) {
! if (Fl::first_window()) Fl::first_window()->cursor(c,fg,bg);
}
/**
! Sets the default window cursor as well as its color.
! For back compatibility only.
*/
! void Fl_Window::default_cursor(Fl_Cursor c, Fl_Color fg, Fl_Color bg) {
! // if (c == FL_CURSOR_DEFAULT) c = FL_CURSOR_ARROW;
!
cursor_default = c;
! cursor_fg = fg;
! cursor_bg = bg;
! cursor(c, fg, bg);
}
- #ifdef WIN32
! # ifndef IDC_HAND
! # define IDC_HAND MAKEINTRESOURCE(32649)
! # endif // !IDC_HAND
- void Fl_Window::cursor(Fl_Cursor c, Fl_Color c1, Fl_Color c2) {
- if (!shown()) return;
// the cursor must be set for the top level window, not for subwindows
Fl_Window *w = window(), *toplevel = this;
! while (w) { toplevel = w; w = w->window(); }
! if (toplevel != this) { toplevel->cursor(c, c1, c2); return; }
! // now set the actual cursor
! if (c == FL_CURSOR_DEFAULT) {
! c = cursor_default;
! }
! if (c > FL_CURSOR_NESW) {
! i->cursor = 0;
! } else if (c == FL_CURSOR_DEFAULT) {
! i->cursor = fl_default_cursor;
! } else {
! LPSTR n;
! 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_HELP: n = IDC_HELP; break;
! case FL_CURSOR_HAND: {
! OSVERSIONINFO osvi;
!
! // Get the OS version: Windows 98 and 2000 have a standard
! // hand cursor.
! memset(&osvi, 0, sizeof(OSVERSIONINFO));
! osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
! GetVersionEx(&osvi);
!
! if (osvi.dwMajorVersion > 4 ||
! (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion > 0 &&
! osvi.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)) n = IDC_HAND;
! else n = IDC_UPARROW;
! } break;
! case FL_CURSOR_MOVE: n = IDC_SIZEALL; break;
! case FL_CURSOR_N:
! case FL_CURSOR_S:
! case FL_CURSOR_NS: n = IDC_SIZENS; break;
! case FL_CURSOR_NE:
! case FL_CURSOR_SW:
! case FL_CURSOR_NESW: n = IDC_SIZENESW; break;
! case FL_CURSOR_E:
! case FL_CURSOR_W:
! case FL_CURSOR_WE: n = IDC_SIZEWE; break;
! case FL_CURSOR_SE:
! case FL_CURSOR_NW:
! case FL_CURSOR_NWSE: n = IDC_SIZENWSE; break;
! default: n = IDC_NO; break;
! }
! i->cursor = LoadCursor(NULL, n);
}
- SetCursor(i->cursor);
- }
! #elif defined(__APPLE__)
! #ifdef __BIG_ENDIAN__
! # define E(x) x
! #elif defined __LITTLE_ENDIAN__
! // Don't worry. This will be resolved at compile time
! # define E(x) (x>>8)|((x<<8)&0xff00)
! #else
! # error "Either __LITTLE_ENDIAN__ or __BIG_ENDIAN__ must be defined"
! #endif
!
! extern Fl_Offscreen fl_create_offscreen_with_alpha(int w, int h);
!
!
! CGContextRef Fl_X::help_cursor_image(void)
! {
! int w = 20, h = 20;
! Fl_Offscreen off = fl_create_offscreen_with_alpha(w, h);
! fl_begin_offscreen(off);
! CGContextSetRGBFillColor( (CGContextRef)off, 0,0,0,0);
! fl_rectf(0,0,w,h);
! fl_color(FL_BLACK);
! fl_font(FL_COURIER_BOLD, 20);
! fl_draw("?", 1, h-1);
! fl_end_offscreen();
! return (CGContextRef)off;
! }
! CGContextRef Fl_X::none_cursor_image(void)
! {
! int w = 20, h = 20;
! Fl_Offscreen off = fl_create_offscreen_with_alpha(w, h);
! fl_begin_offscreen(off);
! CGContextSetRGBFillColor( (CGContextRef)off, 0,0,0,0);
! fl_rectf(0,0,w,h);
! fl_end_offscreen();
! return (CGContextRef)off;
! }
! CGContextRef Fl_X::watch_cursor_image(void)
! {
! int w, h, r = 5;
! w = 2*r+6;
! h = 4*r;
! Fl_Offscreen off = fl_create_offscreen_with_alpha(w, h);
! fl_begin_offscreen(off);
! CGContextSetRGBFillColor( (CGContextRef)off, 0,0,0,0);
! fl_rectf(0,0,w,h);
! CGContextTranslateCTM( (CGContextRef)off, w/2, h/2);
! fl_color(FL_WHITE);
! fl_circle(0, 0, r+1);
! fl_color(FL_BLACK);
! fl_rectf(int(-r*0.7), int(-r*1.7), int(1.4*r), int(3.4*r));
! fl_rectf(r-1, -1, 3, 3);
! fl_color(FL_WHITE);
! fl_pie(-r, -r, 2*r, 2*r, 0, 360);
! fl_color(FL_BLACK);
! fl_circle(0,0,r);
! fl_xyline(0, 0, int(-r*.7));
! fl_xyline(0, 0, 0, int(-r*.7));
! fl_end_offscreen();
! return (CGContextRef)off;
! }
! CGContextRef Fl_X::nesw_cursor_image(void)
! {
! int c = 7, r = 2*c;
! int w = r, h = r;
! Fl_Offscreen off = fl_create_offscreen_with_alpha(w, h);
! fl_begin_offscreen(off);
! CGContextSetRGBFillColor( (CGContextRef)off, 0,0,0,0);
! fl_rectf(0,0,w,h);
! CGContextTranslateCTM( (CGContextRef)off, 0, h);
! CGContextScaleCTM( (CGContextRef)off, 1, -1);
! fl_color(FL_BLACK);
! fl_polygon(0, 0, c, 0, 0, c);
! fl_polygon(r, r, r, r-c, r-c, r);
! fl_line_style(FL_SOLID, 2, 0);
! fl_line(0,1, r,r+1);
! fl_line_style(FL_SOLID, 0, 0);
! fl_end_offscreen();
! return (CGContextRef)off;
}
! CGContextRef Fl_X::nwse_cursor_image(void)
! {
! int c = 7, r = 2*c;
! int w = r, h = r;
! Fl_Offscreen off = fl_create_offscreen_with_alpha(w, h);
! fl_begin_offscreen(off);
! CGContextSetRGBFillColor( (CGContextRef)off, 0,0,0,0);
! fl_rectf(0,0,w,h);
! CGContextTranslateCTM( (CGContextRef)off, 0, h);
! CGContextScaleCTM( (CGContextRef)off, 1, -1);
! fl_color(FL_BLACK);
! fl_polygon(r-1, 0, r-1, c, r-1-c, 0);
! fl_polygon(-1, r, c-1, r, -1, r-c);
! fl_line_style(FL_SOLID, 2, 0);
! fl_line(r-1,1, -1,r+1);
! fl_line_style(FL_SOLID, 0, 0);
! fl_end_offscreen();
! return (CGContextRef)off;
! }
! void Fl_Window::cursor(Fl_Cursor c, Fl_Color, Fl_Color) {
! if (c == FL_CURSOR_DEFAULT) {
! c = cursor_default;
! }
! if (i) i->set_cursor(c);
! }
! #else
! // I like the MSWindows resize cursors, so I duplicate them here:
! #define CURSORSIZE 16
! #define HOTXY 7
! static struct TableEntry {
! uchar bits[CURSORSIZE*CURSORSIZE/8];
! uchar mask[CURSORSIZE*CURSORSIZE/8];
! Cursor cursor;
! } table[] = {
! {{ // FL_CURSOR_NS
! 0x00, 0x00, 0x80, 0x01, 0xc0, 0x03, 0xe0, 0x07, 0x80, 0x01, 0x80, 0x01,
! 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01, 0x80, 0x01,
! 0xe0, 0x07, 0xc0, 0x03, 0x80, 0x01, 0x00, 0x00},
! {
! 0x80, 0x01, 0xc0, 0x03, 0xe0, 0x07, 0xf0, 0x0f, 0xf0, 0x0f, 0xc0, 0x03,
! 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xc0, 0x03, 0xf0, 0x0f,
! 0xf0, 0x0f, 0xe0, 0x07, 0xc0, 0x03, 0x80, 0x01}},
! {{ // FL_CURSOR_EW
! 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x10,
! 0x0c, 0x30, 0xfe, 0x7f, 0xfe, 0x7f, 0x0c, 0x30, 0x08, 0x10, 0x00, 0x00,
! 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
! {
! 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x18, 0x18, 0x1c, 0x38,
! 0xfe, 0x7f, 0xff, 0xff, 0xff, 0xff, 0xfe, 0x7f, 0x1c, 0x38, 0x18, 0x18,
! 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
! {{ // FL_CURSOR_NWSE
! 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x00, 0x38, 0x00, 0x78, 0x00,
! 0xe8, 0x00, 0xc0, 0x01, 0x80, 0x03, 0x00, 0x17, 0x00, 0x1e, 0x00, 0x1c,
! 0x00, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
! {
! 0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0xfc, 0x00, 0x7c, 0x00, 0xfc, 0x00,
! 0xfc, 0x01, 0xec, 0x03, 0xc0, 0x37, 0x80, 0x3f, 0x00, 0x3f, 0x00, 0x3e,
! 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x00, 0x00, 0x00}},
! {{ // FL_CURSOR_NESW
! 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1e, 0x00, 0x1c, 0x00, 0x1e,
! 0x00, 0x17, 0x80, 0x03, 0xc0, 0x01, 0xe8, 0x00, 0x78, 0x00, 0x38, 0x00,
! 0x78, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
! {
! 0x00, 0x00, 0x00, 0x00, 0x00, 0x3f, 0x00, 0x3f, 0x00, 0x3e, 0x00, 0x3f,
! 0x80, 0x3f, 0xc0, 0x37, 0xec, 0x03, 0xfc, 0x01, 0xfc, 0x00, 0x7c, 0x00,
! 0xfc, 0x00, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x00}},
! {{0}, {0}} // FL_CURSOR_NONE & unknown
! };
!
! void Fl_Window::cursor(Fl_Cursor c, Fl_Color fg, Fl_Color bg) {
! if (!shown()) return;
! Cursor xc;
! int deleteit = 0;
! if (c == FL_CURSOR_DEFAULT) {
! c = cursor_default;
! fg = cursor_fg;
! bg = cursor_bg;
}
! if (!c) {
! xc = None;
! } else {
! if (c >= FL_CURSOR_NS) {
! TableEntry *q = (c > FL_CURSOR_NESW) ? table+4 : table+(c-FL_CURSOR_NS);
! if (!(q->cursor)) {
! XColor dummy = { 0 };
! Pixmap p = XCreateBitmapFromData(fl_display,
! RootWindow(fl_display, fl_screen), (const char*)(q->bits),
! CURSORSIZE, CURSORSIZE);
! Pixmap m = XCreateBitmapFromData(fl_display,
! RootWindow(fl_display, fl_screen), (const char*)(q->mask),
! CURSORSIZE, CURSORSIZE);
! q->cursor = XCreatePixmapCursor(fl_display, p,m,&dummy, &dummy,
! HOTXY, HOTXY);
! XFreePixmap(fl_display, m);
! XFreePixmap(fl_display, p);
! }
! xc = q->cursor;
! } else {
! xc = XCreateFontCursor(fl_display, (c-1)*2);
! deleteit = 1;
! }
! XColor fgc;
! uchar r,g,b;
! Fl::get_color(fg,r,g,b);
! fgc.red = r<<8; fgc.green = g<<8; fgc.blue = b<<8;
! XColor bgc;
! Fl::get_color(bg,r,g,b);
! bgc.red = r<<8; bgc.green = g<<8; bgc.blue = b<<8;
! XRecolorCursor(fl_display, xc, &fgc, &bgc);
}
- XDefineCursor(fl_display, fl_xid(this), xc);
- if (deleteit) XFreeCursor(fl_display, xc);
- }
! #endif
//
--- 34,186 ----
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
+ #include <FL/Fl_Pixmap.H>
+ #include <FL/Fl_RGB_Image.H>
#include <FL/x.H>
#include <FL/fl_draw.H>
+ #include "fl_cursor_wait.xpm"
+ #include "fl_cursor_help.xpm"
+ #include "fl_cursor_nwse.xpm"
+ #include "fl_cursor_nesw.xpm"
+ #include "fl_cursor_none.xpm"
+
/**
Sets the cursor for the current window to the specified shape and colors.
The cursors are defined in the <FL/Enumerations.H> header file.
*/
+ void fl_cursor(Fl_Cursor c) {
+ if (Fl::first_window()) Fl::first_window()->cursor(c);
+ }
+
+ /* For back compatibility only. */
void fl_cursor(Fl_Cursor c, Fl_Color fg, Fl_Color bg) {
! fl_cursor(c);
}
+
+
/**
! Sets the default window cursor. This is the cursor that will be used
! after the mouse pointer leaves a widget with a custom cursor set.
! \see cursor(const Fl_RGB_Image*, int, int), default_cursor()
*/
! void Fl_Window::default_cursor(Fl_Cursor c) {
cursor_default = c;
! cursor(c);
! }
!
! void fallback_cursor(Fl_Window *w, Fl_Cursor c) {
! const char **xpm;
! int hotx, hoty;
!
! // The standard arrow is our final fallback, so something is broken
! // if we get called back here with that as an argument.
! if (c == FL_CURSOR_ARROW)
! return;
!
! switch (c) {
! case FL_CURSOR_WAIT:
! xpm = (const char**)fl_cursor_wait_xpm;
! hotx = 8;
! hoty = 15;
! break;
! case FL_CURSOR_HELP:
! xpm = (const char**)fl_cursor_help_xpm;
! hotx = 1;
! hoty = 3;
! break;
! case FL_CURSOR_NWSE:
! xpm = (const char**)fl_cursor_nwse_xpm;
! hotx = 7;
! hoty = 7;
! break;
! case FL_CURSOR_NESW:
! xpm = (const char**)fl_cursor_nesw_xpm;
! hotx = 7;
! hoty = 7;
! break;
! case FL_CURSOR_NONE:
! xpm = (const char**)fl_cursor_none_xpm;
! hotx = 0;
! hoty = 0;
! break;
! default:
! w->cursor(FL_CURSOR_ARROW);
! return;
! }
!
! Fl_Pixmap pxm(xpm);
! Fl_RGB_Image image(&pxm);
!
! w->cursor(&image, hotx, hoty);
}
! void Fl_Window::cursor(Fl_Cursor c) {
! int ret;
// the cursor must be set for the top level window, not for subwindows
Fl_Window *w = window(), *toplevel = this;
!
! while (w) {
! toplevel = w;
! w = w->window();
}
! if (toplevel != this) {
! toplevel->cursor(c);
! return;
! }
! if (c == FL_CURSOR_DEFAULT)
! c = cursor_default;
! if (!i)
! return;
! ret = i->set_cursor(c);
! if (ret)
! return;
! fallback_cursor(this, c);
}
! /**
! Changes the cursor for this window. This always calls the system, if
! you are changing the cursor a lot you may want to keep track of how
! you set it in a static variable and call this only if the new cursor
! is different.
! The default cursor will be used if the provided image cannot be used
! as a cursor.
! \see cursor(Fl_Cursor), default_cursor()
! */
! void Fl_Window::cursor(const Fl_RGB_Image *image, int hotx, int hoty) {
! int ret;
! // the cursor must be set for the top level window, not for subwindows
! Fl_Window *w = window(), *toplevel = this;
! while (w) {
! toplevel = w;
! w = w->window();
}
! if (toplevel != this) {
! toplevel->cursor(image, hotx, hoty);
! return;
}
! if (!i)
! return;
!
! ret = i->set_cursor(image, hotx, hoty);
! if (ret)
! return;
!
! cursor(FL_CURSOR_DEFAULT);
! }
//
*** fltk-1.3.0/src/fl_draw_pixmap.cxx 2011-02-02 12:39:34.000000000 -0600
--- fltk-1.3.0.new/src/fl_draw_pixmap.cxx 2011-06-22 22:46:30.000000000 -0500
***************
*** 68,164 ****
}
- #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
--- 68,71 ----
***************
*** 210,223 ****
#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;
const uchar*const* data = (const uchar*const*)(cdata+1);
int transparent_index = -1;
uchar *transparent_c = (uchar *)0; // such that transparent_c[0,1,2] are the RGB of the transparent color
#ifdef WIN32
color_count = 0;
--- 117,134 ----
#endif
! 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;
uchar *transparent_c = (uchar *)0; // such that transparent_c[0,1,2] are the RGB of the transparent color
+
+ if (!fl_measure_pixmap(cdata, w, h))
+ return 0;
+
+ if ((chars_per_pixel < 1) || (chars_per_pixel > 2))
+ return 0;
+
+ uchar (*colors)[4] = new uchar [1<<(chars_per_pixel*8)][4];
+
#ifdef WIN32
color_count = 0;
***************
*** 225,229 ****
#endif
! if (ncolors < 0) { // FLTK (non standard) compressed colormap
ncolors = -ncolors;
const uchar *p = *data++;
--- 136,141 ----
#endif
! if (ncolors < 0) {
! // FLTK (non standard) compressed colormap
ncolors = -ncolors;
const uchar *p = *data++;
***************
*** 231,241 ****
// it not be transparent):
if (*p == ' ') {
! uchar* c = (uchar*)&d.colors[(int)' '];
! #ifdef U64
! *(U64*)c = 0;
! # if WORDS_BIGENDIAN
! c += 4;
! # endif
! #endif
transparent_index = ' ';
Fl::get_color(bg, c[0], c[1], c[2]); c[3] = 0;
--- 143,147 ----
// it not be transparent):
if (*p == ' ') {
! uchar* c = colors[(int)' '];
transparent_index = ' ';
Fl::get_color(bg, c[0], c[1], c[2]); c[3] = 0;
***************
*** 246,256 ****
// 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
#ifdef WIN32
used_colors[3*color_count] = *p;
--- 152,156 ----
// read all the rest of the colors:
for (int i=0; i < ncolors; i++) {
! uchar* c = colors[*p++];
#ifdef WIN32
used_colors[3*color_count] = *p;
***************
*** 262,273 ****
*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));
for (int i=0; i<ncolors; i++) {
const uchar *p = *data++;
--- 162,169 ----
*c++ = *p++;
*c++ = *p++;
*c = 255;
}
! } else {
! // normal XPM colormap with names
for (int i=0; i<ncolors; i++) {
const uchar *p = *data++;
***************
*** 275,334 ****
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];
! }
// 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++;
}
- #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]);
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++;
#endif
! }
! 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__
c[3] = 0;
! #endif
! transparent_index = ind;
! transparent_c = c;
}
}
}
- d.data = data;
#ifdef WIN32
if (transparent_c) {
--- 171,208 ----
int ind = *p++;
uchar* c;
! 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++;
}
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++;
#endif
! } else {
// assume "None" or "#transparent" for any errors
! // "bg" should be transparent...
! Fl::get_color(bg, c[0], c[1], c[2]);
c[3] = 0;
! transparent_index = ind;
! transparent_c = c;
}
}
}
#ifdef WIN32
if (transparent_c) {
***************
*** 340,425 ****
}
#endif
#ifdef __APPLE_QUARTZ__
if (fl_graphics_driver->class_name() == Fl_Quartz_Graphics_Driver::class_id ) {
- bool transparent = (transparent_index>=0);
- transparent = true;
- 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++];
- }
- }
- }
CGColorSpaceRef lut = CGColorSpaceCreateDeviceRGB();
! CGDataProviderRef src = CGDataProviderCreateWithData( 0L, array, d.w * d.h * 4, 0L);
! CGImageRef img = CGImageCreate(d.w, d.h, 8, 4*8, 4*d.w,
! lut, transparent?kCGImageAlphaLast:kCGImageAlphaNoneSkipLast,
! src, 0L, false, kCGRenderingIntentDefault);
CGColorSpaceRelease(lut);
CGDataProviderRelease(src);
! CGRect rect = { { x, y} , { d.w, d.h } };
! Fl_X::q_begin_image(rect, 0, 0, d.w, d.h);
CGContextDrawImage(fl_gc, rect, img);
Fl_X::q_end_image();
CGImageRelease(img);
! delete[] array;
! }
! 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];
*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;
! *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;
! }
! }
!
! if (bit > 1) *bitmap++ = b;
}
}
}
! fl_draw_image(chars_per_pixel==1 ? cb1 : cb2, &d, x, y, d.w, d.h, 4);
#ifdef __APPLE_QUARTZ__
}
#endif
! if (chars_per_pixel > 1) for (int i = 0; i < 256; i++) delete[] d.byte1[i];
return 1;
}
--- 214,300 ----
}
#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);
+ }
+ }
+ }
+ delete [] colors;
+ 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 = new uchar[w*h*4];
+
+ if (!fl_convert_pixmap(cdata, buffer, bg)) {
+ delete buffer;
+ return 0;
+ }
+
+ // FIXME: Hack until fl_draw_image() supports alpha properly
#ifdef __APPLE_QUARTZ__
if (fl_graphics_driver->class_name() == Fl_Quartz_Graphics_Driver::class_id ) {
CGColorSpaceRef lut = CGColorSpaceCreateDeviceRGB();
! CGDataProviderRef src = CGDataProviderCreateWithData( 0L, buffer, w * h * 4, 0L);
! CGImageRef img = CGImageCreate(w, h, 8, 4*8, 4*w,
! lut, kCGImageAlphaLast,
! src, 0L, false, kCGRenderingIntentDefault);
CGColorSpaceRelease(lut);
CGDataProviderRelease(src);
! CGRect rect = { { x, y }, { w, h } };
! Fl_X::q_begin_image(rect, 0, 0, w, h);
CGContextDrawImage(fl_gc, rect, img);
Fl_X::q_end_image();
CGImageRelease(img);
! } else {
#endif // __APPLE_QUARTZ__
// build the mask bitmap used by Fl_Pixmap:
! if (fl_mask_bitmap) {
! int W = (w+7)/8;
! uchar* bitmap = new uchar[W * h];
*fl_mask_bitmap = bitmap;
! const uchar *p = &buffer[3];
! for (int Y = 0; Y < h; Y++) {
! int dw = w;
! for (int X = 0; X < W; X++) {
! uchar b = 0;
! for (int bit = 0x01;bit <= 0x80;bit<<=1) {
! if (dw-- < 0)
! break;
! if (*p > 127)
! b |= bit;
! p += 4;
! }
! *bitmap++ = b;
}
}
}
! fl_draw_image(buffer, x, y, w, h, 4);
!
#ifdef __APPLE_QUARTZ__
}
#endif
! delete buffer;
return 1;
}
*** fltk-1.3.0/src/xutf8/imKStoUCS.c 2009-03-13 17:43:43.000000000 -0500
--- fltk-1.3.0.new/src/xutf8/imKStoUCS.c 2011-06-22 22:35:31.000000000 -0500
***************
*** 267,270 ****
--- 267,276 ----
};
+ static unsigned short const keysym_to_unicode_fe50_fe60[] = {
+ 0x0300, 0x0301, 0x0302, 0x0303, 0x0304, 0x0306, 0x0307, 0x0308, /* 0xfe50-0xfe57 */
+ 0x030a, 0x030b, 0x030c, 0x0327, 0x0328, 0x1da5, 0x3099, 0x309a, /* 0xfe58-0xfe5f */
+ 0x0323 /* 0xfe60-0xfe67 */
+ };
+
unsigned int
KeySymToUcs4(KeySym keysym)
***************
*** 316,319 ****
--- 322,327 ----
else if (keysym > 0x209f && keysym < 0x20ad)
return keysym_to_unicode_20a0_20ac[keysym - 0x20a0];
+ else if (keysym > 0xfe4f && keysym < 0xfe61)
+ return keysym_to_unicode_fe50_fe60[keysym - 0xfe50];
else
return 0;
*** fltk-1.3.0/test/cursor.cxx 2010-12-08 08:00:35.000000000 -0600
--- fltk-1.3.0.new/test/cursor.cxx 2011-06-22 22:35:32.000000000 -0500
***************
*** 33,38 ****
#include <FL/Fl_Box.H>
- Fl_Color fg = FL_BLACK;
- Fl_Color bg = FL_WHITE;
Fl_Cursor cursor = FL_CURSOR_DEFAULT;
--- 33,36 ----
***************
*** 42,46 ****
cursor = (Fl_Cursor)(fl_intptr_t)v;
cursor_slider->value(cursor);
! fl_cursor(cursor,fg,bg);
}
--- 40,44 ----
cursor = (Fl_Cursor)(fl_intptr_t)v;
cursor_slider->value(cursor);
! fl_cursor(cursor);
}
***************
*** 58,63 ****
{"FL_CURSOR_NWSE",0,choice_cb,(void*)FL_CURSOR_NWSE},
{"FL_CURSOR_NESW",0,choice_cb,(void*)FL_CURSOR_NESW},
- {"FL_CURSOR_NONE",0,choice_cb,(void*)FL_CURSOR_NONE},
- #if 0
{"FL_CURSOR_N",0,choice_cb,(void*)FL_CURSOR_N},
{"FL_CURSOR_NE",0,choice_cb,(void*)FL_CURSOR_NE},
--- 56,59 ----
***************
*** 68,72 ****
{"FL_CURSOR_W",0,choice_cb,(void*)FL_CURSOR_W},
{"FL_CURSOR_NW",0,choice_cb,(void*)FL_CURSOR_NW},
! #endif
{0}
};
--- 64,68 ----
{"FL_CURSOR_W",0,choice_cb,(void*)FL_CURSOR_W},
{"FL_CURSOR_NW",0,choice_cb,(void*)FL_CURSOR_NW},
! {"FL_CURSOR_NONE",0,choice_cb,(void*)FL_CURSOR_NONE},
{0}
};
***************
*** 75,91 ****
Fl_Hor_Value_Slider *slider = (Fl_Hor_Value_Slider *)o;
cursor = Fl_Cursor((int)slider->value());
! fl_cursor(cursor,fg,bg);
! }
!
! void setfg(Fl_Widget *o, void *) {
! Fl_Hor_Value_Slider *slider = (Fl_Hor_Value_Slider *)o;
! fg = Fl_Color((int)slider->value());
! fl_cursor(cursor,fg,bg);
! }
!
! void setbg(Fl_Widget *o, void *) {
! Fl_Hor_Value_Slider *slider = (Fl_Hor_Value_Slider *)o;
! bg = Fl_Color((int)slider->value());
! fl_cursor(cursor,fg,bg);
}
--- 71,75 ----
Fl_Hor_Value_Slider *slider = (Fl_Hor_Value_Slider *)o;
cursor = Fl_Cursor((int)slider->value());
! fl_cursor(cursor);
}
***************
*** 113,139 ****
slider1.step(1);
slider1.precision(0);
! slider1.bounds(0,100);
slider1.value(0);
slider1.callback(setcursor);
slider1.value(cursor);
- Fl_Hor_Value_Slider slider2(80,220,310,30,"fgcolor:");
- slider2.align(FL_ALIGN_LEFT);
- slider2.step(1);
- slider2.precision(0);
- slider2.bounds(0,255);
- slider2.value(0);
- slider2.callback(setfg);
- slider2.value(fg);
-
- Fl_Hor_Value_Slider slider3(80,260,310,30,"bgcolor:");
- slider3.align(FL_ALIGN_LEFT);
- slider3.step(1);
- slider3.precision(0);
- slider3.bounds(0,255);
- slider3.value(0);
- slider3.callback(setbg);
- slider3.value(bg);
-
#if 0
// draw the manual's diagram of cursors...
--- 97,105 ----
slider1.step(1);
slider1.precision(0);
! slider1.bounds(0,255);
slider1.value(0);
slider1.callback(setcursor);
slider1.value(cursor);
#if 0
// draw the manual's diagram of cursors...
*** fltk-1.3.0/test/fullscreen.cxx 2010-12-15 06:11:16.000000000 -0600
--- fltk-1.3.0.new/test/fullscreen.cxx 2011-06-22 22:35:32.000000000 -0500
***************
*** 61,66 ****
--- 61,69 ----
#include <FL/Fl_Single_Window.H>
#include <FL/Fl_Hor_Slider.H>
+ #include <FL/Fl_Input.H>
+ #include <FL/Fl_Menu_Button.H>
#include <FL/Fl_Toggle_Light_Button.H>
#include <FL/math.h>
+ #include <FL/fl_ask.H>
#include <stdio.h>
***************
*** 125,128 ****
--- 128,153 ----
#endif
+ class fullscreen_window : public Fl_Single_Window {
+
+ public:
+ fullscreen_window(int W, int H, const char *t=0);
+ int handle (int e);
+ Fl_Toggle_Light_Button *b3;
+
+ };
+
+ fullscreen_window::fullscreen_window(int W, int H, const char *t) : Fl_Single_Window(W, H, t) {
+
+ }
+
+ int fullscreen_window::handle(int e) {
+ if (e == FL_FULLSCREEN) {
+ printf("Recieved FL_FULLSCREEN event\n");
+ b3->value(fullscreen_active());
+ }
+ if (Fl_Single_Window::handle(e)) return 1;
+ return 0;
+ }
+
void sides_cb(Fl_Widget *o, void *p) {
shape_window *sw = (shape_window *)p;
***************
*** 162,172 ****
pw = w->w();
ph = w->h();
- #ifndef WIN32//necessary because fullscreen removes border
- border_button->value(0);
- border_button->do_callback();
- #endif
w->fullscreen();
} else {
! w->fullscreen_off(px,py,pw,ph);
}
}
--- 187,198 ----
pw = w->w();
ph = w->h();
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();
}
}
***************
*** 178,182 ****
}
! #define NUMB 5
int twowindow = 0;
--- 204,208 ----
}
! #define NUMB 6
int twowindow = 0;
***************
*** 194,198 ****
Fl::fatal("Options are:\n -2 = 2 windows\n -f = startup fullscreen\n%s",Fl::help);
! Fl_Single_Window window(300,300+30*NUMB); window.end();
shape_window sw(10,10,window.w()-20,window.h()-30*NUMB-20);
--- 220,224 ----
Fl::fatal("Options are:\n -2 = 2 windows\n -f = startup fullscreen\n%s",Fl::help);
! fullscreen_window window(300,300+30*NUMB); window.end();
shape_window sw(10,10,window.w()-20,window.h()-30*NUMB-20);
***************
*** 229,232 ****
--- 255,261 ----
y+=30;
+ Fl_Input i1(50,y,window.w()-60,30, "Input");
+ y+=30;
+
Fl_Toggle_Light_Button b2(50,y,window.w()-60,30,"Border");
b2.callback(border_cb,w);
***************
*** 235,240 ****
y+=30;
! Fl_Toggle_Light_Button b3(50,y,window.w()-60,30,"FullScreen");
! b3.callback(fullscreen_cb,w);
y+=30;
--- 264,269 ----
y+=30;
! window.b3 = new Fl_Toggle_Light_Button(50,y,window.w()-60,30,"FullScreen");
! window.b3->callback(fullscreen_cb,w);
y+=30;
***************
*** 243,247 ****
y+=30;
! if (initfull) {b3.set(); b3.do_callback();}
window.end();
--- 272,276 ----
y+=30;
! if (initfull) {window.b3->set(); window.b3->do_callback();}
window.end();