summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAaron M. Ucko <ucko@debian.org>2015-07-07 01:32:55 -0400
committerAaron M. Ucko <ucko@debian.org>2015-07-07 01:40:11 -0400
commit574b357ee8bd5c44a1511a5a29f60b2d659b263f (patch)
treee7f69d70ef4c9414325db8cca0b4e7b56ee7c81a /src
parent51a046516db7c8e194cc232e4fb18ecb3ffa65dc (diff)
parenta3d0ced57399c9fd8075377b7310d545f968e524 (diff)
Merge tag 'upstream/1.3.3' (Closes: #791346.)
Upstream version 1.3.3
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt247
-rw-r--r--src/Fl.cxx313
-rw-r--r--src/Fl_Bitmap.cxx131
-rw-r--r--src/Fl_Button.cxx50
-rw-r--r--src/Fl_Check_Button.cxx36
-rw-r--r--src/Fl_Color_Chooser.cxx6
-rw-r--r--src/Fl_Copy_Surface.cxx399
-rw-r--r--src/Fl_Double_Window.cxx13
-rw-r--r--src/Fl_File_Browser.cxx116
-rw-r--r--src/Fl_File_Chooser.cxx19
-rw-r--r--src/Fl_File_Chooser.fl137
-rw-r--r--src/Fl_File_Chooser2.cxx13
-rw-r--r--src/Fl_File_Icon2.cxx15
-rw-r--r--src/Fl_Font.H7
-rw-r--r--src/Fl_GDI_Printer.cxx10
-rw-r--r--src/Fl_Gl_Device_Plugin.cxx37
-rw-r--r--src/Fl_Gl_Window.cxx61
-rw-r--r--src/Fl_Group.cxx8
-rw-r--r--src/Fl_Help_Dialog.cxx57
-rw-r--r--src/Fl_Help_Dialog.fl36
-rw-r--r--src/Fl_Help_View.cxx8
-rw-r--r--src/Fl_Image.cxx134
-rw-r--r--src/Fl_Image_Surface.cxx157
-rw-r--r--src/Fl_Input.cxx60
-rw-r--r--src/Fl_Input_.cxx82
-rw-r--r--src/Fl_JPEG_Image.cxx56
-rw-r--r--src/Fl_Menu.cxx16
-rw-r--r--src/Fl_Menu_Window.cxx5
-rw-r--r--src/Fl_Native_File_Chooser_FLTK.cxx552
-rw-r--r--src/Fl_Native_File_Chooser_GTK.cxx732
-rw-r--r--src/Fl_Native_File_Chooser_MAC.mm120
-rw-r--r--src/Fl_Native_File_Chooser_WIN32.cxx182
-rw-r--r--src/Fl_Native_File_Chooser_common.cxx5
-rw-r--r--src/Fl_PNG_Image.cxx32
-rw-r--r--src/Fl_Paged_Device.cxx18
-rw-r--r--src/Fl_PostScript.cxx131
-rw-r--r--src/Fl_Preferences.cxx17
-rw-r--r--src/Fl_Printer.cxx10
-rw-r--r--src/Fl_Quartz_Printer.mm71
-rw-r--r--src/Fl_Round_Button.cxx43
-rw-r--r--src/Fl_Scroll.cxx139
-rw-r--r--src/Fl_Sys_Menu_Bar.cxx289
-rw-r--r--src/Fl_Sys_Menu_Bar.mm508
-rw-r--r--src/Fl_Table.cxx41
-rw-r--r--src/Fl_Tabs.cxx32
-rw-r--r--src/Fl_Text_Buffer.cxx27
-rw-r--r--src/Fl_Text_Display.cxx390
-rw-r--r--src/Fl_Text_Editor.cxx25
-rw-r--r--src/Fl_Tile.cxx146
-rw-r--r--src/Fl_Tiled_Image.cxx19
-rw-r--r--src/Fl_Tree.cxx1602
-rw-r--r--src/Fl_Tree_Item.cxx1013
-rw-r--r--src/Fl_Tree_Item_Array.cxx166
-rw-r--r--src/Fl_Tree_Prefs.cxx12
-rw-r--r--src/Fl_Window.cxx276
-rw-r--r--src/Fl_Window_fullscreen.cxx25
-rw-r--r--src/Fl_Window_shape.cxx407
-rw-r--r--src/Fl_XPM_Image.cxx25
-rw-r--r--src/Fl_arg.cxx8
-rw-r--r--src/Fl_cocoa.mm2173
-rw-r--r--src/Fl_compose.cxx107
-rw-r--r--src/Fl_get_key_mac.cxx22
-rw-r--r--src/Fl_get_system_colors.cxx61
-rw-r--r--src/Fl_mac.cxx2861
-rw-r--r--src/Fl_win32.cxx885
-rw-r--r--src/Fl_x.cxx1109
-rw-r--r--src/Makefile31
-rw-r--r--src/Xutf8.h184
-rw-r--r--src/aimm.h422
-rw-r--r--src/fastarrow.h2
-rw-r--r--src/fl_ask.cxx24
-rw-r--r--src/fl_boxtype.cxx14
-rw-r--r--src/fl_call_main.c10
-rw-r--r--src/fl_cursor.cxx389
-rw-r--r--src/fl_cursor_help.xpm39
-rw-r--r--src/fl_cursor_nesw.xpm46
-rw-r--r--src/fl_cursor_none.xpm19
-rw-r--r--src/fl_cursor_nwse.xpm46
-rw-r--r--src/fl_cursor_wait.xpm28
-rw-r--r--src/fl_diamond_box.cxx38
-rw-r--r--src/fl_dnd_x.cxx10
-rw-r--r--src/fl_draw.cxx191
-rw-r--r--src/fl_draw_pixmap.cxx342
-rw-r--r--src/fl_engraved_label.cxx12
-rw-r--r--src/fl_font_mac.cxx102
-rw-r--r--src/fl_font_win32.cxx57
-rw-r--r--src/fl_font_xft.cxx22
-rw-r--r--src/fl_gleam.cxx137
-rw-r--r--src/fl_gtk.cxx8
-rw-r--r--src/fl_open_uri.cxx12
-rw-r--r--src/fl_plastic.cxx20
-rw-r--r--src/fl_read_image.cxx12
-rw-r--r--src/fl_read_image_mac.cxx5
-rw-r--r--src/fl_rect.cxx6
-rw-r--r--src/fl_round_box.cxx46
-rw-r--r--src/fl_scroll_area.cxx16
-rw-r--r--src/fl_set_fonts_mac.cxx70
-rw-r--r--src/fl_set_fonts_xft.cxx54
-rw-r--r--src/fl_shortcut.cxx75
-rw-r--r--src/fl_utf8.cxx12
-rw-r--r--src/flstring.h6
-rw-r--r--src/forms_timer.cxx5
-rw-r--r--src/gl_draw.cxx15
-rw-r--r--src/gl_start.cxx5
-rw-r--r--src/makedepend1590
-rw-r--r--src/mediumarrow.h2
-rw-r--r--src/numericsort.c8
-rw-r--r--src/print_panel.cxx10
-rw-r--r--src/ps_image.cxx84
-rw-r--r--src/scandir.c46
-rw-r--r--src/scandir_posix.c205
-rw-r--r--src/scandir_win32.c6
-rw-r--r--src/screen_xywh.cxx110
-rw-r--r--src/slowarrow.h2
-rw-r--r--src/tile.xpm2
-rw-r--r--src/vsnprintf.c8
-rw-r--r--src/xutf8/headers/dingbats_.h250
-rw-r--r--src/xutf8/headers/symbol_.h190
-rw-r--r--src/xutf8/imKStoUCS.c2
-rw-r--r--src/xutf8/is_right2left.c10
-rw-r--r--src/xutf8/keysym2Ucs.c2
-rw-r--r--src/xutf8/ucs2fontmap.c5
-rw-r--r--src/xutf8/utf8Input.c20
-rw-r--r--src/xutf8/utf8Utils.c2
-rw-r--r--src/xutf8/utf8Wrap.c10
125 files changed, 13003 insertions, 8603 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 0c0865a..d53ab80 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,4 +1,3 @@
-include_regular_expression("[.][cxx|c|h]$")
set(CPPFILES
Fl.cxx
@@ -15,9 +14,11 @@ set(CPPFILES
Fl_Choice.cxx
Fl_Clock.cxx
Fl_Color_Chooser.cxx
+ Fl_Copy_Surface.cxx
Fl_Counter.cxx
Fl_Device.cxx
Fl_Dial.cxx
+ Fl_Help_Dialog_Dox.cxx
Fl_Double_Window.cxx
Fl_File_Browser.cxx
Fl_File_Chooser.cxx
@@ -27,13 +28,13 @@ set(CPPFILES
Fl_Group.cxx
Fl_Help_View.cxx
Fl_Image.cxx
+ Fl_Image_Surface.cxx
Fl_Input.cxx
Fl_Input_.cxx
Fl_Light_Button.cxx
Fl_Menu.cxx
Fl_Menu_.cxx
Fl_Menu_Bar.cxx
- Fl_Sys_Menu_Bar.cxx
Fl_Menu_Button.cxx
Fl_Menu_Window.cxx
Fl_Menu_add.cxx
@@ -45,6 +46,7 @@ set(CPPFILES
Fl_Paged_Device.cxx
Fl_Pixmap.cxx
Fl_Positioner.cxx
+ Fl_PostScript.cxx
Fl_Printer.cxx
Fl_Preferences.cxx
Fl_Progress.cxx
@@ -79,6 +81,7 @@ set(CPPFILES
Fl_Window_fullscreen.cxx
Fl_Window_hotspot.cxx
Fl_Window_iconize.cxx
+ Fl_Window_shape.cxx
Fl_Wizard.cxx
Fl_XBM_Image.cxx
Fl_XPM_Image.cxx
@@ -116,6 +119,7 @@ set(CPPFILES
fl_engraved_label.cxx
fl_file_dir.cxx
fl_font.cxx
+ fl_gleam.cxx
fl_gtk.cxx
fl_labeltype.cxx
fl_line_style.cxx
@@ -195,32 +199,22 @@ set(CFILES
add_definitions(-DFL_LIBRARY)
if(APPLE)
- set(MMFILES
- Fl_cocoa.mm
- Fl_Quartz_Printer.mm
- Fl_Native_File_Chooser_MAC.mm
- )
+ set(MMFILES
+ Fl_cocoa.mm
+ Fl_Quartz_Printer.mm
+ Fl_Native_File_Chooser_MAC.mm
+ Fl_Sys_Menu_Bar.mm
+ )
else()
set(MMFILES
)
endif(APPLE)
#######################################################################
-add_library(fltk STATIC ${CPPFILES} ${MMFILES} ${CFILES} fl_call_main.c)
-set_target_properties(fltk PROPERTIES CLEAN_DIRECT_OUTPUT 1)
-if(MSVC)
- if(OPTION_LARGE_FILE)
- set_target_properties(fltk PROPERTIES LINK_FLAGS /LARGEADDRESSAWARE)
- endif()
- set_target_properties(fltk
- PROPERTIES
- OUTPUT_NAME fltk
- DEBUG_OUTPUT_NAME fltkd
- )
-endif(MSVC)
+FL_ADD_LIBRARY(fltk STATIC "${CPPFILES};${MMFILES};${CFILES};fl_call_main.c")
if(USE_THREADS)
- target_link_libraries(fltk ${CMAKE_THREAD_LIBS_INIT})
+ target_link_libraries(fltk ${CMAKE_THREAD_LIBS_INIT} ${LIB_dl})
endif(USE_THREADS)
if(USE_X11)
@@ -239,73 +233,52 @@ if(HAVE_XINERAMA)
target_link_libraries(fltk ${X11_Xinerama_LIB})
endif(HAVE_XINERAMA)
+if(HAVE_XFIXES)
+ target_link_libraries(fltk ${X11_Xfixes_LIB})
+endif(HAVE_XFIXES)
+
+if(HAVE_XCURSOR)
+ target_link_libraries(fltk ${X11_Xcursor_LIB})
+endif(HAVE_XCURSOR)
+
if(USE_XFT)
target_link_libraries(fltk ${X11_Xft_LIB})
+ if(LIB_fontconfig)
+ target_link_libraries(fltk ${LIB_fontconfig})
+ endif(LIB_fontconfig)
endif(USE_XFT)
-if(LIB_fontconfig)
- target_link_libraries(fltk ${LIB_fontconfig})
-endif(LIB_fontconfig)
-
#######################################################################
-add_library(fltk_forms STATIC ${FLCPPFILES})
+FL_ADD_LIBRARY(fltk_forms STATIC "${FLCPPFILES}")
target_link_libraries(fltk_forms fltk)
-set_target_properties(fltk_forms
- PROPERTIES CLEAN_DIRECT_OUTPUT 1
-)
-if(MSVC)
- if(OPTION_LARGE_FILE)
- set_target_properties(fltk_forms PROPERTIES LINK_FLAGS /LARGEADDRESSAWARE)
- endif()
- set_target_properties(fltk_forms
- PROPERTIES
- OUTPUT_NAME fltkforms
- DEBUG_OUTPUT_NAME fltkformsd
- )
-endif(MSVC)
#######################################################################
-add_library(fltk_images STATIC ${IMGCPPFILES})
+FL_ADD_LIBRARY(fltk_images STATIC "${IMGCPPFILES}")
target_link_libraries(fltk_images fltk ${FLTK_PNG_LIBRARIES}
${FLTK_JPEG_LIBRARIES} ${FLTK_ZLIB_LIBRARIES})
-set_target_properties(fltk_images PROPERTIES CLEAN_DIRECT_OUTPUT 1)
-if(MSVC)
- if(OPTION_LARGE_FILE)
- set_target_properties(fltk_images PROPERTIES LINK_FLAGS /LARGEADDRESSAWARE)
- endif()
- set_target_properties(fltk_images
- PROPERTIES
- OUTPUT_NAME fltkimages
- DEBUG_OUTPUT_NAME fltkimagesd
- )
-endif(MSVC)
-#######################################################################
-install(TARGETS fltk fltk_forms fltk_images
- EXPORT fltk-install
- DESTINATION ${PREFIX_LIB}
-)
+if(OPTION_USE_SYSTEM_LIBJPEG)
+ target_link_libraries(fltk_images ${FLTK_JPEG_LIBRARIES})
+else()
+ target_link_libraries(fltk_images fltk_jpeg)
+endif(OPTION_USE_SYSTEM_LIBJPEG)
+
+if(OPTION_USE_SYSTEM_ZLIB)
+ target_link_libraries(fltk_images ${FLTK_ZLIB_LIBRARIES})
+else()
+ target_link_libraries(fltk_images fltk_z)
+endif(OPTION_USE_SYSTEM_ZLIB)
+
+if(OPTION_USE_SYSTEM_LIBPNG)
+ target_link_libraries(fltk_images ${FLTK_PNG_LIBRARIES})
+else()
+ target_link_libraries(fltk_images fltk_png)
+endif(OPTION_USE_SYSTEM_LIBPNG)
#######################################################################
if(OPENGL_FOUND)
- add_library(fltk_gl STATIC ${GLCPPFILES})
+ FL_ADD_LIBRARY(fltk_gl STATIC "${GLCPPFILES}")
target_link_libraries(fltk_gl fltk ${OPENGL_LIBRARIES})
- set_target_properties(fltk_gl PROPERTIES CLEAN_DIRECT_OUTPUT 1)
- if(MSVC)
- if(OPTION_LARGE_FILE)
- set_target_properties(fltk_gl PROPERTIES LINK_FLAGS /LARGEADDRESSAWARE)
- endif()
- set_target_properties(fltk_gl
- PROPERTIES
- OUTPUT_NAME fltkgl
- DEBUG_OUTPUT_NAME fltkgld
- )
- endif(MSVC)
-
- install(TARGETS fltk_gl
- EXPORT fltk-install
- DESTINATION ${PREFIX_LIB}
- )
endif(OPENGL_FOUND)
#######################################################################
@@ -313,28 +286,10 @@ endif(OPENGL_FOUND)
if(OPTION_BUILD_SHARED_LIBS)
#######################################################################
-add_library(fltk_SHARED SHARED ${CPPFILES} ${MMFILES} ${CFILES})
-set_target_properties(fltk_SHARED
- PROPERTIES CLEAN_DIRECT_OUTPUT 1
- VERSION ${FLTK_VERSION_MAJOR}.${FLTK_VERSION_MINOR}
- SOVERSION ${FLTK_VERSION_PATCH}
-)
-if(MSVC)
- set_target_properties(fltk_SHARED
- PROPERTIES
- OUTPUT_NAME fltkdll
- DEBUG_OUTPUT_NAME fltkdlld
- COMPILE_DEFINITIONS "FL_DLL;FL_LIBRARY"
- )
- if(OPTION_LARGE_FILE)
- set_target_properties(fltk_SHARED PROPERTIES LINK_FLAGS /LARGEADDRESSAWARE)
- endif(OPTION_LARGE_FILE)
-else()
- set_target_properties(fltk_SHARED PROPERTIES OUTPUT_NAME fltk)
-endif(MSVC)
+FL_ADD_LIBRARY(fltk SHARED "${CPPFILES};${MMFILES};${CFILES}")
if(USE_THREADS)
- target_link_libraries(fltk_SHARED ${CMAKE_THREAD_LIBS_INIT})
+ target_link_libraries(fltk_SHARED ${CMAKE_THREAD_LIBS_INIT} ${LIB_dl})
endif(USE_THREADS)
if(USE_X11)
@@ -346,7 +301,7 @@ if(WIN32)
endif(WIN32)
if(FLTK_HAVE_CAIRO)
- target_link_libraries(fltk_SHARED fltk_cairo ${PKG_CAIRO_LIBRARIES})
+ target_link_libraries(fltk_SHARED fltk_cairo_SHARED ${PKG_CAIRO_LIBRARIES})
ENDif(FLTK_HAVE_CAIRO)
if(HAVE_XINERAMA)
@@ -355,99 +310,51 @@ endif(HAVE_XINERAMA)
if(USE_XFT)
target_link_libraries(fltk_SHARED ${X11_Xft_LIB})
+ if(LIB_fontconfig)
+ target_link_libraries(fltk_SHARED ${LIB_fontconfig})
+ endif(LIB_fontconfig)
endif(USE_XFT)
-if(LIB_fontconfig)
- target_link_libraries(fltk_SHARED ${LIB_fontconfig})
-endif(LIB_fontconfig)
-
#######################################################################
-add_library(fltk_forms_SHARED SHARED ${FLCPPFILES})
-target_link_libraries(fltk_forms_SHARED fltk)
-set_target_properties(fltk_forms_SHARED
- PROPERTIES CLEAN_DIRECT_OUTPUT 1
- VERSION ${FLTK_VERSION_MAJOR}.${FLTK_VERSION_MINOR}
- SOVERSION ${FLTK_VERSION_PATCH}
-)
-if(MSVC)
- set_target_properties(fltk_forms_SHARED
- PROPERTIES
- OUTPUT_NAME fltkformsdll
- DEBUG_OUTPUT_NAME fltkformsdlld
- COMPILE_DEFINITIONS "FL_DLL;FL_LIBRARY"
- )
- if(OPTION_LARGE_FILE)
- set_target_properties(fltk_forms_SHARED PROPERTIES LINK_FLAGS /LARGEADDRESSAWARE)
- endif(OPTION_LARGE_FILE)
-else()
- set_target_properties(fltk_forms_SHARED PROPERTIES OUTPUT_NAME fltk_forms)
-endif(MSVC)
+FL_ADD_LIBRARY(fltk_forms SHARED "${FLCPPFILES}")
+target_link_libraries(fltk_forms_SHARED fltk_SHARED)
if(USE_THREADS)
- target_link_libraries(fltk_SHARED ${CMAKE_THREAD_LIBS_INIT})
+ target_link_libraries(fltk_forms_SHARED ${CMAKE_THREAD_LIBS_INIT} ${LIB_dl})
endif(USE_THREADS)
if(USE_X11)
- target_link_libraries(fltk_SHARED ${X11_LIBRARIES})
+ target_link_libraries(fltk_forms_SHARED ${X11_LIBRARIES})
endif(USE_X11)
#######################################################################
-add_library(fltk_images_SHARED SHARED ${IMGCPPFILES})
-target_link_libraries(fltk_images_SHARED fltk
- ${FLTK_PNG_LIBRARIES} ${FLTK_JPEG_LIBRARIES} ${FLTK_ZLIB_LIBRARIES}
-)
-set_target_properties(fltk_images_SHARED
- PROPERTIES CLEAN_DIRECT_OUTPUT 1
- VERSION ${FLTK_VERSION_MAJOR}.${FLTK_VERSION_MINOR}
- SOVERSION ${FLTK_VERSION_PATCH}
-)
-if(MSVC)
- set_target_properties(fltk_images_SHARED
- PROPERTIES
- OUTPUT_NAME fltkimagesdll
- DEBUG_OUTPUT_NAME fltkimagesdlld
- COMPILE_DEFINITIONS "FL_DLL;FL_LIBRARY"
- )
- if(OPTION_LARGE_FILE)
- set_target_properties(fltk_images_SHARED PROPERTIES LINK_FLAGS /LARGEADDRESSAWARE)
- endif(OPTION_LARGE_FILE)
+FL_ADD_LIBRARY(fltk_images SHARED "${IMGCPPFILES}")
+target_link_libraries(fltk_images_SHARED fltk_SHARED)
+
+if(OPTION_USE_SYSTEM_LIBJPEG)
+ target_link_libraries(fltk_images_SHARED ${FLTK_JPEG_LIBRARIES})
else()
- set_target_properties(fltk_images_SHARED PROPERTIES OUTPUT_NAME fltk_images)
-endif(MSVC)
+ target_link_libraries(fltk_images_SHARED fltk_jpeg_SHARED)
+endif(OPTION_USE_SYSTEM_LIBJPEG)
-#######################################################################
-install(TARGETS fltk_SHARED fltk_forms_SHARED fltk_images_SHARED
- EXPORT fltk-install
- DESTINATION ${PREFIX_LIB}
-)
+if(OPTION_USE_SYSTEM_ZLIB)
+ target_link_libraries(fltk_images_SHARED ${FLTK_ZLIB_LIBRARIES})
+else()
+ target_link_libraries(fltk_images_SHARED fltk_z_SHARED)
+endif(OPTION_USE_SYSTEM_ZLIB)
+
+if(OPTION_USE_SYSTEM_LIBPNG)
+ target_link_libraries(fltk_images_SHARED ${FLTK_PNG_LIBRARIES})
+else()
+ target_link_libraries(fltk_images_SHARED fltk_png_SHARED)
+endif(OPTION_USE_SYSTEM_LIBPNG)
#######################################################################
if(OPENGL_FOUND)
- add_library(fltk_gl_SHARED SHARED ${GLCPPFILES})
- target_link_libraries(fltk_gl_SHARED fltk ${OPENGL_LIBRARIES})
- set_target_properties(fltk_gl_SHARED
- PROPERTIES CLEAN_DIRECT_OUTPUT 1
- VERSION ${FLTK_VERSION_MAJOR}.${FLTK_VERSION_MINOR}
- SOVERSION ${FLTK_VERSION_PATCH}
- )
- if(MSVC)
- set_target_properties(fltk_gl_SHARED
- PROPERTIES
- OUTPUT_NAME fltkgldll
- DEBUG_OUTPUT_NAME fltkgldlld
- COMPILE_DEFINITIONS "FL_DLL;FL_LIBRARY"
- )
- if(OPTION_LARGE_FILE)
- set_target_properties(fltk_gl_SHARED PROPERTIES LINK_FLAGS /LARGEADDRESSAWARE)
- endif(OPTION_LARGE_FILE)
- else()
- set_target_properties(fltk_gl_SHARED PROPERTIES OUTPUT_NAME fltk_gl)
- endif(MSVC)
-
- install(TARGETS fltk_gl_SHARED
- EXPORT fltk-install
- DESTINATION ${PREFIX_LIB}
- )
+ FL_ADD_LIBRARY(fltk_gl SHARED "${GLCPPFILES}")
+ target_link_libraries(fltk_gl_SHARED fltk_SHARED ${OPENGL_LIBRARIES})
endif(OPENGL_FOUND)
+#######################################################################
endif(OPTION_BUILD_SHARED_LIBS)
+#######################################################################
diff --git a/src/Fl.cxx b/src/Fl.cxx
index e8cfd5e..05618d6 100644
--- a/src/Fl.cxx
+++ b/src/Fl.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: Fl.cxx 9666 2012-08-16 20:59:36Z matt $"
+// "$Id: Fl.cxx 10364 2014-10-08 12:47:20Z ossman $"
//
// Main event handling code for the Fast Light Tool Kit (FLTK).
//
@@ -67,20 +67,20 @@ void fl_cleanup_pens(void);
void fl_release_dc(HWND,HDC);
void fl_cleanup_dc_list(void);
#elif defined(__APPLE__)
-extern double fl_mac_flush_and_wait(double time_to_wait, char in_idle);
+extern double fl_mac_flush_and_wait(double time_to_wait);
#endif // WIN32
//
// Globals...
//
#if defined(__APPLE__) || defined(FL_DOXYGEN)
-const char *Fl_Mac_App_Menu::about = "About ";
+const char *Fl_Mac_App_Menu::about = "About %@";
const char *Fl_Mac_App_Menu::print = "Print Front Window";
const char *Fl_Mac_App_Menu::services = "Services";
-const char *Fl_Mac_App_Menu::hide = "Hide ";
+const char *Fl_Mac_App_Menu::hide = "Hide %@";
const char *Fl_Mac_App_Menu::hide_others = "Hide Others";
const char *Fl_Mac_App_Menu::show = "Show All";
-const char *Fl_Mac_App_Menu::quit = "Quit ";
+const char *Fl_Mac_App_Menu::quit = "Quit %@";
#endif // __APPLE__
#ifndef FL_DOXYGEN
Fl_Widget *Fl::belowmouse_,
@@ -104,6 +104,8 @@ int Fl::damage_,
char *Fl::e_text = (char *)"";
int Fl::e_length;
+const char* Fl::e_clipboard_type = "";
+void * Fl::e_clipboard_data = NULL;
Fl_Event_Dispatch Fl::e_dispatch = 0;
@@ -111,13 +113,16 @@ unsigned char Fl::options_[] = { 0, 0 };
unsigned char Fl::options_read_ = 0;
-Fl_Window *fl_xfocus; // which window X thinks has focus
+Fl_Window *fl_xfocus = NULL; // which window X thinks has focus
Fl_Window *fl_xmousewin;// which window X thinks has FL_ENTER
Fl_Window *Fl::grab_; // most recent Fl::grab()
Fl_Window *Fl::modal_; // topmost modal() window
#endif // FL_DOXYGEN
+char const * const Fl::clipboard_plain_text = "text/plain";
+char const * const Fl::clipboard_image = "image";
+
//
// 'Fl::version()' - Return the API version number...
//
@@ -220,7 +225,7 @@ int Fl::event_inside(const Fl_Widget *o) /*const*/ {
#elif defined(__APPLE__)
-// implementation in Fl_mac.cxx
+// implementation in Fl_cocoa.mm (was Fl_mac.cxx)
#else
@@ -430,11 +435,75 @@ static void run_checks()
}
}
-#ifndef WIN32
+#if !defined(WIN32) && !defined(__APPLE__)
static char in_idle;
#endif
////////////////////////////////////////////////////////////////
+// Clipboard notifications
+
+struct Clipboard_Notify {
+ Fl_Clipboard_Notify_Handler handler;
+ void *data;
+ struct Clipboard_Notify *next;
+};
+
+static struct Clipboard_Notify *clip_notify_list = NULL;
+
+extern void fl_clipboard_notify_change(); // in Fl_<platform>.cxx
+
+void Fl::add_clipboard_notify(Fl_Clipboard_Notify_Handler h, void *data) {
+ struct Clipboard_Notify *node;
+
+ remove_clipboard_notify(h);
+
+ node = new Clipboard_Notify;
+
+ node->handler = h;
+ node->data = data;
+ node->next = clip_notify_list;
+
+ clip_notify_list = node;
+
+ fl_clipboard_notify_change();
+}
+
+void Fl::remove_clipboard_notify(Fl_Clipboard_Notify_Handler h) {
+ struct Clipboard_Notify *node, **prev;
+
+ node = clip_notify_list;
+ prev = &clip_notify_list;
+ while (node != NULL) {
+ if (node->handler == h) {
+ *prev = node->next;
+ delete node;
+
+ fl_clipboard_notify_change();
+
+ return;
+ }
+
+ prev = &node->next;
+ node = node->next;
+ }
+}
+
+bool fl_clipboard_notify_empty(void) {
+ return clip_notify_list == NULL;
+}
+
+void fl_trigger_clipboard_notify(int source) {
+ struct Clipboard_Notify *node, *next;
+
+ node = clip_notify_list;
+ while (node != NULL) {
+ next = node->next;
+ node->handler(source, node->data);
+ node = next;
+ }
+}
+
+////////////////////////////////////////////////////////////////
// wait/run/check/ready:
void (*Fl::idle)(); // see Fl::add_idle.cxx for the add/remove functions
@@ -456,16 +525,7 @@ double Fl::wait(double time_to_wait) {
#elif defined(__APPLE__)
run_checks();
- if (idle) {
- if (!in_idle) {
- in_idle = 1;
- idle();
- in_idle = 0;
- }
- // the idle function may turn off idle, we can then wait:
- if (idle) time_to_wait = 0.0;
- }
- return fl_mac_flush_and_wait(time_to_wait, in_idle);
+ return fl_mac_flush_and_wait(time_to_wait);
#else
@@ -530,45 +590,6 @@ int Fl::run() {
return 0;
}
-#ifdef WIN32
-
-// Function to initialize COM/OLE for usage. This must be done only once.
-// We define a flag to register whether we called it:
-static char oleInitialized = 0;
-
-// This calls the Windows function OleInitialize() exactly once.
-void fl_OleInitialize() {
- if (!oleInitialized) {
- OleInitialize(0L);
- oleInitialized = 1;
- }
-}
-
-// This calls the Windows function OleUninitialize() only, if
-// OleInitialize has been called before.
-void fl_OleUninitialize() {
- if (oleInitialized) {
- OleUninitialize();
- oleInitialized = 0;
- }
-}
-
-class Fl_Win32_At_Exit {
-public:
- Fl_Win32_At_Exit() { }
- ~Fl_Win32_At_Exit() {
- fl_free_fonts(); // do some WIN32 cleanup
- fl_cleanup_pens();
- fl_OleUninitialize();
- fl_brush_action(1);
- fl_cleanup_dc_list();
- }
-};
-static Fl_Win32_At_Exit win32_at_exit;
-#endif
-
-
-
/**
Waits until "something happens" and then returns. Call this
repeatedly to "run" your program. You can also check what happened
@@ -828,6 +849,83 @@ static int send_handlers(int e) {
return 0;
}
+
+////////////////////////////////////////////////////////////////
+// System event handlers:
+
+
+struct system_handler_link {
+ Fl_System_Handler handle;
+ void *data;
+ system_handler_link *next;
+};
+
+
+static system_handler_link *sys_handlers = 0;
+
+
+/**
+ \brief Install a function to intercept system events.
+
+ FLTK calls each of these functions as soon as a new system event is
+ received. The processing will stop at the first function to return
+ non-zero. If all functions return zero then the event is passed on
+ for normal handling by FLTK.
+
+ Each function will be called with a pointer to the system event as
+ the first argument and \p data as the second argument. The system
+ event pointer will always be void *, but will point to different
+ objects depending on the platform:
+ - X11: XEvent
+ - Windows: MSG
+ - OS X: NSEvent
+
+ \param ha The event handler function to register
+ \param data User data to include on each call
+
+ \see Fl::remove_system_handler(Fl_System_Handler)
+*/
+void Fl::add_system_handler(Fl_System_Handler ha, void *data) {
+ system_handler_link *l = new system_handler_link;
+ l->handle = ha;
+ l->data = data;
+ l->next = sys_handlers;
+ sys_handlers = l;
+}
+
+
+/**
+ Removes a previously added system event handler.
+
+ \param ha The event handler function to remove
+
+ \see Fl::add_system_handler(Fl_System_Handler)
+*/
+void Fl::remove_system_handler(Fl_System_Handler ha) {
+ system_handler_link *l, *p;
+
+ // Search for the handler in the list...
+ for (l = sys_handlers, p = 0; l && l->handle != ha; p = l, l = l->next);
+
+ if (l) {
+ // Found it, so remove it from the list...
+ if (p) p->next = l->next;
+ else sys_handlers = l->next;
+
+ // And free the record...
+ delete l;
+ }
+}
+
+int fl_send_system_handlers(void *e) {
+ for (const system_handler_link *hl = sys_handlers; hl; hl = hl->next) {
+ if (hl->handle(e, hl->data))
+ return 1;
+ }
+ return 0;
+}
+
+
////////////////////////////////////////////////////////////////
Fl_Widget* fl_oldfocus; // kludge for Fl_Group...
@@ -862,10 +960,18 @@ void Fl::focus(Fl_Widget *o) {
if (fl_xfocus != win) {
Fl_X *x = Fl_X::i(win);
if (x) x->set_key_window();
- }
+ }
+#elif defined(USE_X11)
+ if (fl_xfocus != win) {
+ Fl_X *x = Fl_X::i(win);
+ if (!Fl_X::ewmh_supported())
+ win->show(); // Old WMs, XMapRaised
+ else if (x) // New WMs use the NETWM attribute:
+ Fl_X::activate_window(x->xid);
+ }
#endif
fl_xfocus = win;
- }
+ }
}
// take focus from the old focused window
fl_oldfocus = 0;
@@ -1357,11 +1463,38 @@ int Fl::handle_(int e, Fl_Window* window)
////////////////////////////////////////////////////////////////
// hide() destroys the X window, it does not do unmap!
-#if !defined(WIN32) && USE_XFT
+#if defined(WIN32)
+extern void fl_clipboard_notify_retarget(HWND wnd);
+extern void fl_update_clipboard(void);
+#elif USE_XFT
extern void fl_destroy_xft_draw(Window);
#endif
void Fl_Window::hide() {
+#ifdef WIN32
+ // STR#3079: if there remains a window and a non-modal window, and the window is deleted,
+ // the app remains running without any apparent window.
+ // Bug mechanism: hiding an owner window unmaps the owned (non-modal) window(s)
+ // but does not delete it(them) in FLTK.
+ // Fix for it:
+ // when hiding a window, build list of windows it owns, and do hide/show on them.
+ int count = 0;
+ Fl_Window *win, **doit = NULL;
+ for (win = Fl::first_window(); win && i; win = Fl::next_window(win)) {
+ if (win->non_modal() && GetWindow(fl_xid(win), GW_OWNER) == i->xid) {
+ count++;
+ }
+ }
+ if (count) {
+ doit = new Fl_Window*[count];
+ count = 0;
+ for (win = Fl::first_window(); win && i; win = Fl::next_window(win)) {
+ if (win->non_modal() && GetWindow(fl_xid(win), GW_OWNER) == i->xid) {
+ doit[count++] = win;
+ }
+ }
+ }
+#endif
clear_visible();
if (!shown()) return;
@@ -1402,16 +1535,14 @@ void Fl_Window::hide() {
handle(FL_HIDE);
#if defined(WIN32)
+ // make sure any custom icons get freed
+ icons(NULL, 0);
// this little trick keeps the current clipboard alive, even if we are about
// to destroy the window that owns the selection.
- if (GetClipboardOwner()==ip->xid) {
- Fl_Window *w1 = Fl::first_window();
- if (w1 && OpenClipboard(fl_xid(w1))) {
- EmptyClipboard();
- SetClipboardData(CF_TEXT, NULL);
- CloseClipboard();
- }
- }
+ if (GetClipboardOwner()==ip->xid)
+ fl_update_clipboard();
+ // Make sure we unlink this window from the clipboard chain
+ fl_clipboard_notify_retarget(ip->xid);
// Send a message to myself so that I'll get out of the event loop...
PostMessage(ip->xid, WM_APP, 0, 0);
if (ip->private_dc) fl_release_dc(ip->xid, ip->private_dc);
@@ -1445,6 +1576,12 @@ void Fl_Window::hide() {
ShowWindow(p, SW_SHOWNA);
}
XDestroyWindow(fl_display, ip->xid);
+ // end of fix for STR#3079
+ for (int ii = 0; ii < count; ii++) {
+ doit[ii]->hide();
+ doit[ii]->show();
+ }
+ if (count) delete[] doit;
#elif defined(__APPLE_QUARTZ__)
ip->destroy();
#else
@@ -1459,12 +1596,6 @@ void Fl_Window::hide() {
delete ip;
}
-Fl_Window::~Fl_Window() {
- hide();
- if (xclass_) {
- free(xclass_);
- }
-}
// FL_SHOW and FL_HIDE are called whenever the visibility of this widget
// or any parent changes. We must correctly map/unmap the system's window.
@@ -1551,12 +1682,23 @@ void Fl::selection(Fl_Widget &owner, const char* text, int len) {
/** Backward compatibility only.
This calls Fl::paste(receiver, 0);
- \see Fl::paste(Fl_Widget &receiver, int clipboard)
+ \see Fl::paste(Fl_Widget &receiver, int clipboard, const char* type)
*/
void Fl::paste(Fl_Widget &receiver) {
Fl::paste(receiver, 0);
}
+#if FLTK_ABI_VERSION >= 10303
+#elif !defined(FL_DOXYGEN)
+void Fl::paste(Fl_Widget &receiver, int source)
+{
+ Fl::paste(receiver, source, Fl::clipboard_plain_text);
+}
+
+void Fl::copy(const char* stuff, int len, int destination) {
+ Fl::copy(stuff, len, destination, Fl::clipboard_plain_text);
+}
+#endif
////////////////////////////////////////////////////////////////
#include <FL/fl_draw.H>
@@ -1696,6 +1838,7 @@ void Fl_Widget::damage(uchar fl, int X, int Y, int W, int H) {
Fl::damage(FL_DAMAGE_CHILD);
}
void Fl_Window::flush() {
+ if (!shown()) return;
make_current();
//if (damage() == FL_DAMAGE_EXPOSE && can_boxcheat(box())) fl_boxcheat = this;
fl_clip_region(i->region); i->region = 0;
@@ -1931,6 +2074,14 @@ void Fl::clear_widget_pointer(Fl_Widget const *w)
There should be an application that manages options system wide, per user, and
per application.
+ Example:
+ \code
+ if ( Fl::option(Fl::OPTION_ARROW_FOCUS) )
+ { ..on.. }
+ else
+ { ..off.. }
+ \endcode
+
\note As of FLTK 1.3.0, options can be managed within fluid, using the menu
<i>Edit/Global FLTK Settings</i>.
@@ -1960,6 +2111,8 @@ bool Fl::option(Fl_Option opt)
options_[OPTION_DND_TEXT] = tmp;
opt_prefs.get("ShowTooltips", tmp, 1); // default: on
options_[OPTION_SHOW_TOOLTIPS] = tmp;
+ opt_prefs.get("FNFCUsesGTK", tmp, 1); // default: on
+ options_[OPTION_FNFC_USES_GTK] = tmp;
}
{ // next, check the user preferences
// override system options only, if the option is set ( >= 0 )
@@ -1977,6 +2130,8 @@ bool Fl::option(Fl_Option opt)
if (tmp >= 0) options_[OPTION_DND_TEXT] = tmp;
opt_prefs.get("ShowTooltips", tmp, -1);
if (tmp >= 0) options_[OPTION_SHOW_TOOLTIPS] = tmp;
+ opt_prefs.get("FNFCUsesGTK", tmp, -1);
+ if (tmp >= 0) options_[OPTION_FNFC_USES_GTK] = tmp;
}
{ // now, if the developer has registered this app, we could as for per-application preferences
}
@@ -1992,6 +2147,12 @@ bool Fl::option(Fl_Option opt)
This function does not change any system or user settings.
+ Example:
+ \code
+ Fl::option(Fl::OPTION_ARROW_FOCUS, true); // on
+ Fl::option(Fl::OPTION_ARROW_FOCUS, false); // off
+ \endcode
+
\param opt which option
\param val set to true or false
\see enum Fl::Fl_Option
@@ -2030,5 +2191,5 @@ Fl_Widget_Tracker::~Fl_Widget_Tracker()
//
-// End of "$Id: Fl.cxx 9666 2012-08-16 20:59:36Z matt $".
+// End of "$Id: Fl.cxx 10364 2014-10-08 12:47:20Z ossman $".
//
diff --git a/src/Fl_Bitmap.cxx b/src/Fl_Bitmap.cxx
index 01fb41a..67a2905 100644
--- a/src/Fl_Bitmap.cxx
+++ b/src/Fl_Bitmap.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: Fl_Bitmap.cxx 9293 2012-03-18 18:48:29Z manolo $"
+// "$Id: Fl_Bitmap.cxx 10132 2014-04-28 09:17:12Z manolo $"
//
// Bitmap drawing routines for the Fast Light Tool Kit (FLTK).
//
@@ -243,35 +243,39 @@ void Fl_Bitmap::draw(int XP, int YP, int WP, int HP, int cx, int cy) {
fl_graphics_driver->draw(this, XP, YP, WP, HP, cx, cy);
}
-static int start(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int w, int h, int &cx, int &cy,
+int Fl_Bitmap::start(int XP, int YP, int WP, int HP, int &cx, int &cy,
int &X, int &Y, int &W, int &H)
{
+ if (!array) {
+ draw_empty(XP, YP);
+ return 1;
+ }
// account for current clip region (faster on Irix):
fl_clip_box(XP,YP,WP,HP,X,Y,W,H);
cx += X-XP; cy += Y-YP;
// clip the box down to the size of image, quit if empty:
if (cx < 0) {W += cx; X -= cx; cx = 0;}
- if (cx+W > w) W = w-cx;
+ if (cx+W > w()) W = w()-cx;
if (W <= 0) return 1;
if (cy < 0) {H += cy; Y -= cy; cy = 0;}
- if (cy+H > h) H = h-cy;
+ if (cy+H > h()) H = h()-cy;
if (H <= 0) return 1;
+#if defined(WIN32)
+ if (!id_) id_ = fl_create_bitmap(w(), h(), array);
+#else
+ if (!id_) id_ = fl_create_bitmask(w(), h(), array);
+#endif
return 0;
}
#ifdef __APPLE__
void Fl_Quartz_Graphics_Driver::draw(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy) {
int X, Y, W, H;
- if (!bm->array) {
- bm->draw_empty(XP, YP);
+ if (bm->start(XP, YP, WP, HP, cx, cy, X, Y, W, H)) {
return;
}
- if (start(bm, XP, YP, WP, HP, bm->w(), bm->h(), cx, cy, X, Y, W, H)) {
- return;
- }
- if (!bm->id_) bm->id_ = fl_create_bitmask(bm->w(), bm->h(), bm->array);
if (bm->id_ && fl_gc) {
- CGRect rect = { { X, Y }, { W, H } };
+ CGRect rect = { { (CGFloat)X, (CGFloat)Y }, { (CGFloat)W, (CGFloat)H } };
Fl_X::q_begin_image(rect, cx, cy, bm->w(), bm->h());
CGContextDrawImage(fl_gc, rect, (CGImageRef)bm->id_);
Fl_X::q_end_image();
@@ -281,60 +285,62 @@ void Fl_Quartz_Graphics_Driver::draw(Fl_Bitmap *bm, int XP, int YP, int WP, int
#elif defined(WIN32)
void Fl_GDI_Graphics_Driver::draw(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy) {
int X, Y, W, H;
- if (!bm->array) {
- bm->draw_empty(XP, YP);
+ if (bm->start(XP, YP, WP, HP, cx, cy, X, Y, W, H)) {
return;
}
- if (start(bm, XP, YP, WP, HP, bm->w(), bm->h(), cx, cy, X, Y, W, H)) {
+
+ HDC tempdc = CreateCompatibleDC(fl_gc);
+ int save = SaveDC(tempdc);
+ SelectObject(tempdc, (HGDIOBJ)bm->id_);
+ SelectObject(fl_gc, fl_brush());
+ // secret bitblt code found in old MSWindows reference manual:
+ BitBlt(fl_gc, X, Y, W, H, tempdc, cx, cy, 0xE20746L);
+ RestoreDC(tempdc, save);
+ DeleteDC(tempdc);
+}
+
+void Fl_GDI_Printer_Graphics_Driver::draw(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy) {
+ int X, Y, W, H;
+ typedef BOOL (WINAPI* fl_transp_func) (HDC,int,int,int,int,HDC,int,int,int,int,UINT);
+ static fl_transp_func fl_TransparentBlt = NULL;
+ static HMODULE hMod = NULL;
+ if (!hMod) {
+ hMod = LoadLibrary("MSIMG32.DLL");
+ if (hMod) fl_TransparentBlt = (fl_transp_func)GetProcAddress(hMod, "TransparentBlt");
+ }
+ if (!fl_TransparentBlt) {
+ Fl_GDI_Graphics_Driver::draw(bm, XP, YP, WP, HP, cx, cy);
+ return;
+ }
+ if (bm->start(XP, YP, WP, HP, cx, cy, X, Y, W, H)) {
return;
}
- if (!bm->id_) bm->id_ = fl_create_bitmap(bm->w(), bm->h(), bm->array);
- typedef BOOL (WINAPI* fl_transp_func) (HDC,int,int,int,int,HDC,int,int,int,int,UINT);
- static fl_transp_func fl_TransparentBlt;
HDC tempdc;
int save;
- BOOL use_print_algo = false;
- if (Fl_Surface_Device::surface() != Fl_Display_Device::display_device()) {
- static HMODULE hMod = NULL;
- if (!hMod) {
- hMod = LoadLibrary("MSIMG32.DLL");
- if (hMod) fl_TransparentBlt = (fl_transp_func)GetProcAddress(hMod, "TransparentBlt");
- }
- if (fl_TransparentBlt) use_print_algo = true;
- }
- if (use_print_algo) { // algorithm for bitmap output to Fl_GDI_Printer
- Fl_Color save_c = fl_color(); // save bitmap's desired color
- uchar r, g, b;
- Fl::get_color(save_c, r, g, b);
- r = 255-r;
- g = 255-g;
- b = 255-b;
- Fl_Color background = fl_rgb_color(r, g, b); // a color very different from the bitmap's
- Fl_Offscreen tmp_id = fl_create_offscreen(W, H);
- fl_begin_offscreen(tmp_id);
- fl_color(background);
- fl_rectf(0,0,W,H); // use this color as offscreen background
- fl_color(save_c); // back to bitmap's color
- tempdc = CreateCompatibleDC(fl_gc);
- save = SaveDC(tempdc);
- SelectObject(tempdc, (HGDIOBJ)bm->id_);
- SelectObject(fl_gc, fl_brush()); // use bitmap's desired color
- BitBlt(fl_gc, 0, 0, W, H, tempdc, 0, 0, 0xE20746L); // draw bitmap to offscreen
- fl_end_offscreen(); // offscreen data is in tmp_id
- SelectObject(tempdc, (HGDIOBJ)tmp_id); // use offscreen data
- // draw it to printer context with background color as transparent
- fl_TransparentBlt(fl_gc, X,Y,W,H, tempdc, cx, cy, bm->w(), bm->h(), RGB(r, g, b) );
- fl_delete_offscreen(tmp_id);
- }
- else { // algorithm for bitmap output to display
- tempdc = CreateCompatibleDC(fl_gc);
- save = SaveDC(tempdc);
- SelectObject(tempdc, (HGDIOBJ)bm->id_);
- SelectObject(fl_gc, fl_brush());
- // secret bitblt code found in old MSWindows reference manual:
- BitBlt(fl_gc, X, Y, W, H, tempdc, cx, cy, 0xE20746L);
- }
+ // algorithm for bitmap output to Fl_GDI_Printer
+ Fl_Color save_c = fl_color(); // save bitmap's desired color
+ uchar r, g, b;
+ Fl::get_color(save_c, r, g, b);
+ r = 255-r;
+ g = 255-g;
+ b = 255-b;
+ Fl_Color background = fl_rgb_color(r, g, b); // a color very different from the bitmap's
+ Fl_Offscreen tmp_id = fl_create_offscreen(W, H);
+ fl_begin_offscreen(tmp_id);
+ fl_color(background);
+ fl_rectf(0,0,W,H); // use this color as offscreen background
+ fl_color(save_c); // back to bitmap's color
+ tempdc = CreateCompatibleDC(fl_gc);
+ save = SaveDC(tempdc);
+ SelectObject(tempdc, (HGDIOBJ)bm->id_);
+ SelectObject(fl_gc, fl_brush()); // use bitmap's desired color
+ BitBlt(fl_gc, 0, 0, W, H, tempdc, 0, 0, 0xE20746L); // draw bitmap to offscreen
+ fl_end_offscreen(); // offscreen data is in tmp_id
+ SelectObject(tempdc, (HGDIOBJ)tmp_id); // use offscreen data
+ // draw it to printer context with background color as transparent
+ fl_TransparentBlt(fl_gc, X,Y,W,H, tempdc, cx, cy, bm->w(), bm->h(), RGB(r, g, b) );
+ fl_delete_offscreen(tmp_id);
RestoreDC(tempdc, save);
DeleteDC(tempdc);
}
@@ -342,14 +348,9 @@ void Fl_GDI_Graphics_Driver::draw(Fl_Bitmap *bm, int XP, int YP, int WP, int HP,
#else // Xlib
void Fl_Xlib_Graphics_Driver::draw(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy) {
int X, Y, W, H;
- if (!bm->array) {
- bm->draw_empty(XP, YP);
- return;
- }
- if (start(bm, XP, YP, WP, HP, bm->w(), bm->h(), cx, cy, X, Y, W, H)) {
+ if (bm->start(XP, YP, WP, HP, cx, cy, X, Y, W, H)) {
return;
}
- if (!bm->id_) bm->id_ = fl_create_bitmask(bm->w(), bm->h(), bm->array);
XSetStipple(fl_display, fl_gc, bm->id_);
int ox = X-cx; if (ox < 0) ox += bm->w();
@@ -469,5 +470,5 @@ Fl_Image *Fl_Bitmap::copy(int W, int H) {
//
-// End of "$Id: Fl_Bitmap.cxx 9293 2012-03-18 18:48:29Z manolo $".
+// End of "$Id: Fl_Bitmap.cxx 10132 2014-04-28 09:17:12Z manolo $".
//
diff --git a/src/Fl_Button.cxx b/src/Fl_Button.cxx
index e75621b..145c80d 100644
--- a/src/Fl_Button.cxx
+++ b/src/Fl_Button.cxx
@@ -1,12 +1,12 @@
//
-// "$Id: Fl_Button.cxx 9637 2012-07-24 04:37:22Z matt $"
+// "$Id: Fl_Button.cxx 10386 2014-10-19 20:17:17Z AlbrechtS $"
//
// Button widget for the Fast Light Tool Kit (FLTK).
//
-// Copyright 1998-2010 by Bill Spitzak and others.
+// Copyright 1998-2014 by Bill Spitzak and others.
//
// This library is free software. Distribution and use rights are outlined in
-// the file "COPYING" which should have been included with this file. If this
+// the file "COPYING" which should have been included with this file. If this
// file is missing or damaged, see the license at:
//
// http://www.fltk.org/COPYING.php
@@ -89,12 +89,12 @@ int Fl_Button::handle(int event) {
return 1;
case FL_PUSH:
if (Fl::visible_focus() && handle(FL_FOCUS)) Fl::focus(this);
+ /* FALLTHROUGH */
case FL_DRAG:
if (Fl::event_inside(this)) {
if (type() == FL_RADIO_BUTTON) newval = 1;
else newval = !oldval;
- } else
- {
+ } else {
clear_changed();
newval = oldval;
}
@@ -126,10 +126,10 @@ int Fl_Button::handle(int event) {
return 1;
case FL_SHORTCUT:
if (!(shortcut() ?
- Fl::test_shortcut(shortcut()) : test_shortcut())) return 0;
+ Fl::test_shortcut(shortcut()) : test_shortcut())) return 0;
if (Fl::visible_focus() && handle(FL_FOCUS)) Fl::focus(this);
goto triggered_by_keyboard;
- case FL_FOCUS : /* FALLTHROUGH */
+ case FL_FOCUS :
case FL_UNFOCUS :
if (Fl::visible_focus()) {
if (box() == FL_NO_BOX) {
@@ -142,6 +142,7 @@ int Fl_Button::handle(int event) {
} else redraw();
return 1;
} else return 0;
+ /* NOTREACHED */
case FL_KEYBOARD :
if (Fl::focus() == this && Fl::event_key() == ' ' &&
!(Fl::event_state() & (FL_SHIFT | FL_CTRL | FL_ALT | FL_META))) {
@@ -174,7 +175,7 @@ void Fl_Button::simulate_key_action()
Fl::remove_timeout(key_release_timeout, key_release_tracker);
key_release_timeout(key_release_tracker);
}
- value(1);
+ value(1);
redraw();
key_release_tracker = new Fl_Widget_Tracker(this);
Fl::add_timeout(0.15, key_release_timeout, key_release_tracker);
@@ -185,7 +186,7 @@ void Fl_Button::key_release_timeout(void *d)
Fl_Widget_Tracker *wt = (Fl_Widget_Tracker*)d;
if (!wt)
return;
- if (wt==key_release_tracker)
+ if (wt==key_release_tracker)
key_release_tracker = 0L;
Fl_Button *btn = (Fl_Button*)wt->widget();
if (btn) {
@@ -196,7 +197,16 @@ void Fl_Button::key_release_timeout(void *d)
}
/**
- The constructor creates the button using the given position, size and label.
+ The constructor creates the button using the given position, size, and label.
+
+ The default box type is box(FL_UP_BOX).
+
+ You can control how the button is drawn when ON by setting down_box().
+ The default is FL_NO_BOX (0) which will select an appropriate box type
+ using the normal (OFF) box type by using fl_down(box()).
+
+ Derived classes may handle this differently.
+
\param[in] X, Y, W, H position and size of the widget
\param[in] L widget label, default is no label
*/
@@ -209,20 +219,34 @@ Fl_Button::Fl_Button(int X, int Y, int W, int H, const char *L)
set_flag(SHORTCUT_LABEL);
}
+/**
+ The constructor creates the button using the given position, size, and label.
+
+ The Button type() is set to FL_RADIO_BUTTON.
+ \param[in] X, Y, W, H position and size of the widget
+ \param[in] L widget label, default is no label
+ */
Fl_Radio_Button::Fl_Radio_Button(int X,int Y,int W,int H,const char *L)
: Fl_Button(X, Y, W, H, L) {
type(FL_RADIO_BUTTON);
}
+/**
+ The constructor creates the button using the given position, size, and label.
+
+ The Button type() is set to FL_TOGGLE_BUTTON.
-Fl_Toggle_Button::Fl_Toggle_Button(int X,int Y,int W,int H,const char *l)
-: Fl_Button(X,Y,W,H,l)
+ \param[in] X, Y, W, H position and size of the widget
+ \param[in] L widget label, default is no label
+ */
+Fl_Toggle_Button::Fl_Toggle_Button(int X,int Y,int W,int H,const char *L)
+: Fl_Button(X,Y,W,H,L)
{
type(FL_TOGGLE_BUTTON);
}
//
-// End of "$Id: Fl_Button.cxx 9637 2012-07-24 04:37:22Z matt $".
+// End of "$Id: Fl_Button.cxx 10386 2014-10-19 20:17:17Z AlbrechtS $".
//
diff --git a/src/Fl_Check_Button.cxx b/src/Fl_Check_Button.cxx
index 2da2e99..e42cac1 100644
--- a/src/Fl_Check_Button.cxx
+++ b/src/Fl_Check_Button.cxx
@@ -1,12 +1,12 @@
//
-// "$Id: Fl_Check_Button.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $"
+// "$Id: Fl_Check_Button.cxx 10386 2014-10-19 20:17:17Z AlbrechtS $"
//
// Check button widget for the Fast Light Tool Kit (FLTK).
//
-// Copyright 1998-2010 by Bill Spitzak and others.
+// Copyright 1998-2014 by Bill Spitzak and others.
//
// This library is free software. Distribution and use rights are outlined in
-// the file "COPYING" which should have been included with this file. If this
+// the file "COPYING" which should have been included with this file. If this
// file is missing or damaged, see the license at:
//
// http://www.fltk.org/COPYING.php
@@ -19,14 +19,32 @@
#include <FL/Fl.H>
#include <FL/Fl_Check_Button.H>
-// TODO Correct incorrect Fl_Check_Button comments.
-// A subclass of Fl_Button that always draws as a diamond box. This
-// diamond is smaller than the widget size and can be surchecked by
-// another box type, for compatibility with Forms.
+/**
+ \class Fl_Check_Button
+ \brief A button with a "checkmark" to show its status.
+
+ \image html Fl_Check_Button.png
+ \image latex Fl_Check_Button.png "Fl_Check_Button" width=4cm
+
+ Buttons generate callbacks when they are clicked by the user. You control
+ exactly when and how by changing the values for type() and when().
+
+ The Fl_Check_Button subclass displays its "ON" state by showing a "checkmark"
+ rather than drawing itself pushed in.
+ */
/**
- Creates a new Fl_Check_Button widget using the given position, size and
- label string.
+ Creates a new Fl_Check_Button widget using the given position, size, and label string.
+
+ The default box type is FL_NO_BOX, which draws the label w/o a box
+ right of the checkmark.
+
+ The selection_color() sets the color of the checkmark.
+ Default is FL_FOREGROUND_COLOR (usually black).
+
+ You can use down_box() to change the box type of the checkmark.
+ Default is FL_DOWN_BOX.
+
\param[in] X, Y, W, H position and size of the widget
\param[in] L widget label, default is no label
*/
diff --git a/src/Fl_Color_Chooser.cxx b/src/Fl_Color_Chooser.cxx
index bfcc682..4b4ce1d 100644
--- a/src/Fl_Color_Chooser.cxx
+++ b/src/Fl_Color_Chooser.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: Fl_Color_Chooser.cxx 9673 2012-08-18 10:47:48Z AlbrechtS $"
+// "$Id: Fl_Color_Chooser.cxx 10234 2014-08-21 12:18:32Z cand $"
//
// Color chooser for the Fast Light Tool Kit (FLTK).
//
@@ -91,7 +91,7 @@ enum {
M_HEX, /**< mode() of Fl_Color_Chooser showing hex values */
M_HSV /**< mode() of Fl_Color_Chooser showing HSV values */
};
-static Fl_Menu_Item mode_menu[] = {
+static const Fl_Menu_Item mode_menu[] = {
{"rgb"},
{"byte"},
{"hex"},
@@ -619,5 +619,5 @@ int fl_color_chooser(const char* name, uchar& r, uchar& g, uchar& b, int cmode)
/** @} */
//
-// End of "$Id: Fl_Color_Chooser.cxx 9673 2012-08-18 10:47:48Z AlbrechtS $".
+// End of "$Id: Fl_Color_Chooser.cxx 10234 2014-08-21 12:18:32Z cand $".
//
diff --git a/src/Fl_Copy_Surface.cxx b/src/Fl_Copy_Surface.cxx
new file mode 100644
index 0000000..ecb8ebc
--- /dev/null
+++ b/src/Fl_Copy_Surface.cxx
@@ -0,0 +1,399 @@
+//
+// "$Id: Fl_Copy_Surface.cxx 10209 2014-06-26 16:14:42Z manolo $"
+//
+// Copy-to-clipboard code for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2014 by Bill Spitzak and others.
+//
+// This library is free software. Distribution and use rights are outlined in
+// the file "COPYING" which should have been included with this file. If this
+// file is missing or damaged, see the license at:
+//
+// http://www.fltk.org/COPYING.php
+//
+// Please report all bugs and problems on the following page:
+//
+// http://www.fltk.org/str.php
+//
+
+#include <FL/Fl_Copy_Surface.H>
+#include <FL/Fl.H>
+
+
+#if defined(__APPLE__)
+#include <ApplicationServices/ApplicationServices.h>
+#if defined(__ppc__)
+#include <QuickTime/QuickTimeComponents.h>
+#endif // __ppc__
+
+Fl_Quartz_Surface_::Fl_Quartz_Surface_(int w, int h) : Fl_System_Printer(), width(w), height(h) {
+}
+
+int Fl_Quartz_Surface_::printable_rect(int *w, int *h) {
+ *w = width;
+ *h = height;
+ return 0;
+}
+
+const char *Fl_Quartz_Surface_::class_id = "Fl_Quartz_Surface_";
+
+#elif defined(WIN32)
+
+Fl_GDI_Surface_::Fl_GDI_Surface_() : Fl_Paged_Device() {
+ driver(new Fl_GDI_Graphics_Driver);
+ depth = 0;
+}
+
+Fl_GDI_Surface_::~Fl_GDI_Surface_() {
+ delete driver();
+}
+
+void Fl_GDI_Surface_::translate(int x, int y) {
+ GetWindowOrgEx(fl_gc, origins+depth);
+ SetWindowOrgEx(fl_gc, origins[depth].x - x, origins[depth].y - y, NULL);
+ if (depth < sizeof(origins)/sizeof(POINT)) depth++;
+ else Fl::warning("Fl_GDI_Surface_: translate stack overflow!");
+}
+
+void Fl_GDI_Surface_::untranslate() {
+ if (depth > 0) depth--;
+ SetWindowOrgEx(fl_gc, origins[depth].x, origins[depth].y, NULL);
+}
+
+const char *Fl_GDI_Surface_::class_id = "Fl_GDI_Surface_";
+
+#endif
+
+
+const char *Fl_Copy_Surface::class_id = "Fl_Copy_Surface";
+
+/** Constructor.
+ \param w and \param h are the width and height of the clipboard surface
+ in pixels where drawing will occur.
+ */
+Fl_Copy_Surface::Fl_Copy_Surface(int w, int h) : Fl_Surface_Device(NULL)
+{
+ width = w;
+ height = h;
+#ifdef __APPLE__
+ helper = new Fl_Quartz_Surface_(width, height);
+ driver(helper->driver());
+ prepare_copy_pdf_and_tiff(w, h);
+ oldgc = fl_gc;
+#elif defined(WIN32)
+ helper = new Fl_GDI_Surface_();
+ driver(helper->driver());
+ oldgc = fl_gc;
+ // exact computation of factor from screen units to EnhMetaFile units (0.01 mm)
+ HDC hdc = GetDC(NULL);
+ int hmm = GetDeviceCaps(hdc, HORZSIZE);
+ int hdots = GetDeviceCaps(hdc, HORZRES);
+ int vmm = GetDeviceCaps(hdc, VERTSIZE);
+ int vdots = GetDeviceCaps(hdc, VERTRES);
+ ReleaseDC(NULL, hdc);
+ float factorw = (100. * hmm) / hdots;
+ float factorh = (100. * vmm) / vdots + 0.5;
+
+ RECT rect; rect.left = 0; rect.top = 0; rect.right = w * factorw; rect.bottom = h * factorh;
+ gc = CreateEnhMetaFile (NULL, NULL, &rect, NULL);
+ if (gc != NULL) {
+ SetTextAlign(gc, TA_BASELINE|TA_LEFT);
+ SetBkMode(gc, TRANSPARENT);
+ }
+#else // Xlib
+ helper = new Fl_Xlib_Surface_();
+ driver(helper->driver());
+ Fl::first_window()->make_current();
+ oldwindow = fl_xid(Fl::first_window());
+ xid = fl_create_offscreen(w,h);
+ Fl_Surface_Device *present_surface = Fl_Surface_Device::surface();
+ set_current();
+ fl_color(FL_WHITE);
+ fl_rectf(0, 0, w, h);
+ present_surface->set_current();
+#endif
+}
+
+/** Destructor.
+ */
+Fl_Copy_Surface::~Fl_Copy_Surface()
+{
+#ifdef __APPLE__
+ complete_copy_pdf_and_tiff();
+ fl_gc = oldgc;
+ delete (Fl_Quartz_Surface_*)helper;
+#elif defined(WIN32)
+ if(oldgc == fl_gc) oldgc = NULL;
+ HENHMETAFILE hmf = CloseEnhMetaFile (gc);
+ if ( hmf != NULL ) {
+ if ( OpenClipboard (NULL) ){
+ EmptyClipboard ();
+ SetClipboardData (CF_ENHMETAFILE, hmf);
+ CloseClipboard ();
+ }
+ DeleteEnhMetaFile(hmf);
+ }
+ DeleteDC(gc);
+ fl_gc = oldgc;
+ delete (Fl_GDI_Surface_*)helper;
+#else // Xlib
+ fl_pop_clip();
+ unsigned char *data = fl_read_image(NULL,0,0,width,height,0);
+ fl_window = oldwindow;
+ _ss->set_current();
+ Fl::copy_image(data,width,height,1);
+ delete[] data;
+ fl_delete_offscreen(xid);
+ delete (Fl_Xlib_Surface_*)helper;
+#endif
+}
+
+/** Copies a widget in the clipboard
+
+ \param widget any FLTK widget (e.g., standard, custom, window, GL view) to copy
+ \param delta_x and \param delta_y give
+ the position in the clipboard of the top-left corner of the widget
+ */
+void Fl_Copy_Surface::draw(Fl_Widget* widget, int delta_x, int delta_y)
+{
+ helper->print_widget(widget, delta_x, delta_y);
+}
+
+void Fl_Copy_Surface::set_current()
+{
+#if defined(__APPLE__) || defined(WIN32)
+ fl_gc = gc;
+ fl_window = (Window)1;
+ Fl_Surface_Device::set_current();
+#else
+ fl_window=xid;
+ _ss = Fl_Surface_Device::surface();
+ Fl_Surface_Device::set_current();
+ fl_push_no_clip();
+#endif
+}
+
+
+#if defined(__APPLE__)
+
+size_t Fl_Copy_Surface::MyPutBytes(void* info, const void* buffer, size_t count)
+ {
+ CFDataAppendBytes ((CFMutableDataRef) info, (const UInt8 *)buffer, count);
+ return count;
+}
+
+void Fl_Copy_Surface::init_PDF_context(int w, int h)
+{
+ CGRect bounds = CGRectMake(0, 0, w, h );
+ pdfdata = CFDataCreateMutable(NULL, 0);
+ CGDataConsumerRef myconsumer;
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1040
+ if(CGDataConsumerCreateWithCFData != NULL) {
+ myconsumer = CGDataConsumerCreateWithCFData(pdfdata); // 10.4
+ }
+ else
+#endif
+ {
+ static CGDataConsumerCallbacks callbacks = { Fl_Copy_Surface::MyPutBytes, NULL };
+ myconsumer = CGDataConsumerCreate ((void*) pdfdata, &callbacks);
+ }
+ gc = CGPDFContextCreate (myconsumer, &bounds, NULL);
+ CGDataConsumerRelease (myconsumer);
+}
+
+void Fl_Copy_Surface::prepare_copy_pdf_and_tiff(int w, int h)
+{
+ init_PDF_context(w, h);
+ if (gc == NULL) return;
+ CGRect bounds = CGRectMake(0, 0, w, h );
+ CGContextBeginPage (gc, &bounds);
+ CGContextTranslateCTM(gc, 0, h);
+ CGContextScaleCTM(gc, 1.0f, -1.0f);
+ CGContextSaveGState(gc);
+}
+
+
+void Fl_Copy_Surface::complete_copy_pdf_and_tiff()
+{
+ CGContextRestoreGState(gc);
+ CGContextEndPage(gc);
+ CGContextRelease(gc);
+ PasteboardRef clipboard = NULL;
+ PasteboardCreate(kPasteboardClipboard, &clipboard);
+ PasteboardClear(clipboard); // first, copy PDF to clipboard
+ PasteboardPutItemFlavor (clipboard, (PasteboardItemID)1,
+ CFSTR("com.adobe.pdf"), // kUTTypePDF
+ pdfdata, kPasteboardFlavorNoFlags);
+ //second, transform this PDF to a bitmap image and put it as tiff in clipboard
+ CGDataProviderRef prov;
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1040
+ if(fl_mac_os_version >= 100400)
+ prov = CGDataProviderCreateWithCFData(pdfdata); // 10.4
+ else
+#endif
+ prov = CGDataProviderCreateWithData(NULL, CFDataGetBytePtr(pdfdata), CFDataGetLength(pdfdata), NULL);
+ CGPDFDocumentRef pdfdoc = CGPDFDocumentCreateWithProvider(prov);
+ CGPDFPageRef pdfpage = CGPDFDocumentGetPage(pdfdoc, 1);
+ CGDataProviderRelease(prov);
+ CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
+ void *mem = ( fl_mac_os_version >= 100600 ? NULL : malloc(width * height * 4) );
+ gc = CGBitmapContextCreate(mem, width, height, 8, width * 4, space, kCGImageAlphaNoneSkipLast);
+ CFRelease(space);
+ if (gc == NULL) { if (mem) free(mem); return; }
+ CGRect rect = CGRectMake(0, 0, width, height);
+ CGContextSetRGBFillColor(gc, 1,1,1,1);//need to clear background
+ CGContextFillRect(gc, rect);
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= 1030
+ CGContextDrawPDFPage(gc, pdfpage); // requires 10.3
+#endif
+ CGPDFDocumentRelease(pdfdoc);
+ CFRelease(pdfdata);
+ PasteboardPutItemFlavor(clipboard, (PasteboardItemID)1, CFSTR("public.tiff"),
+ Fl_X::CGBitmapContextToTIFF(gc), kPasteboardFlavorNoFlags);
+ CFRelease(clipboard);
+ CGContextRelease(gc);
+ if (mem) free(mem);
+}
+
+#endif // __APPLE__
+
+#if !(defined(__APPLE__) || defined(WIN32) || defined(FL_DOXYGEN))
+/* graphics driver that translates all graphics coordinates before calling Xlib */
+class Fl_translated_Xlib_Graphics_Driver_ : public Fl_Xlib_Graphics_Driver {
+ int offset_x, offset_y; // translation between user and graphical coordinates: graphical = user + offset
+ unsigned depth; // depth of translation stack
+ int stack_x[20], stack_y[20]; // translation stack allowing cumulative translations
+public:
+ static const char *class_id;
+ const char *class_name() {return class_id;};
+ Fl_translated_Xlib_Graphics_Driver_() {
+ offset_x = 0; offset_y = 0;
+ depth = 0;
+ }
+ virtual ~Fl_translated_Xlib_Graphics_Driver_() {};
+ void translate_all(int dx, int dy) { // reversibly adds dx,dy to the offset between user and graphical coordinates
+ stack_x[depth] = offset_x;
+ stack_y[depth] = offset_y;
+ offset_x = stack_x[depth] + dx;
+ offset_y = stack_y[depth] + dy;
+ push_matrix();
+ translate(dx, dy);
+ if (depth < sizeof(stack_x)/sizeof(int)) depth++;
+ else Fl::warning("%s: translate stack overflow!", class_id);
+ }
+ void untranslate_all() { // undoes previous translate_all()
+ if (depth > 0) depth--;
+ offset_x = stack_x[depth];
+ offset_y = stack_y[depth];
+ pop_matrix();
+ }
+ void rect(int x, int y, int w, int h) { Fl_Xlib_Graphics_Driver::rect(x+offset_x, y+offset_y, w, h); }
+ void rectf(int x, int y, int w, int h) { Fl_Xlib_Graphics_Driver::rectf(x+offset_x, y+offset_y, w, h); }
+ void xyline(int x, int y, int x1) { Fl_Xlib_Graphics_Driver::xyline(x+offset_x, y+offset_y, x1+offset_x); }
+ void xyline(int x, int y, int x1, int y2) { Fl_Xlib_Graphics_Driver::xyline(x+offset_x, y+offset_y, x1+offset_x, y2+offset_y); }
+ void xyline(int x, int y, int x1, int y2, int x3) { Fl_Xlib_Graphics_Driver::xyline(x+offset_x, y+offset_y, x1+offset_x, y2+offset_y, x3+offset_x); }
+ void yxline(int x, int y, int y1) { Fl_Xlib_Graphics_Driver::yxline(x+offset_x, y+offset_y, y1+offset_y); }
+ void yxline(int x, int y, int y1, int x2) { Fl_Xlib_Graphics_Driver::yxline(x+offset_x, y+offset_y, y1+offset_y, x2+offset_x); }
+ void yxline(int x, int y, int y1, int x2, int y3) { Fl_Xlib_Graphics_Driver::yxline(x+offset_x, y+offset_y, y1+offset_y, x2+offset_x, y3+offset_y); }
+ void line(int x, int y, int x1, int y1) { Fl_Xlib_Graphics_Driver::line(x+offset_x, y+offset_y, x1+offset_x, y1+offset_y); }
+ void line(int x, int y, int x1, int y1, int x2, int y2) { Fl_Xlib_Graphics_Driver::line(x+offset_x, y+offset_y, x1+offset_x, y1+offset_y, x2+offset_x, y2+offset_y); }
+ void draw(const char* str, int n, int x, int y) {
+ Fl_Xlib_Graphics_Driver::draw(str, n, x+offset_x, y+offset_y);
+ }
+ void draw(int angle, const char *str, int n, int x, int y) {
+ Fl_Xlib_Graphics_Driver::draw(angle, str, n, x+offset_x, y+offset_y);
+ }
+ void rtl_draw(const char* str, int n, int x, int y) {
+ Fl_Xlib_Graphics_Driver::rtl_draw(str, n, x+offset_x, y+offset_y);
+ }
+ void draw(Fl_Pixmap *pxm, int XP, int YP, int WP, int HP, int cx, int cy) {
+ XP += offset_x; YP += offset_y;
+ translate_all(-offset_x, -offset_y);
+ Fl_Xlib_Graphics_Driver::draw(pxm, XP, YP, WP,HP,cx,cy);
+ untranslate_all();
+ }
+ void draw(Fl_Bitmap *bm, int XP, int YP, int WP, int HP, int cx, int cy) {
+ XP += offset_x; YP += offset_y;
+ translate_all(-offset_x, -offset_y);
+ Fl_Xlib_Graphics_Driver::draw(bm, XP, YP, WP,HP,cx,cy);
+ untranslate_all();
+ }
+ void draw(Fl_RGB_Image *img, int XP, int YP, int WP, int HP, int cx, int cy) {
+ XP += offset_x; YP += offset_y;
+ translate_all(-offset_x, -offset_y);
+ Fl_Xlib_Graphics_Driver::draw(img, XP, YP, WP,HP,cx,cy);
+ untranslate_all();
+ }
+ void draw_image(const uchar* buf, int X,int Y,int W,int H, int D=3, int L=0) {
+ X += offset_x; Y += offset_y;
+ translate_all(-offset_x, -offset_y);
+ Fl_Xlib_Graphics_Driver::draw_image(buf, X, Y, W,H,D,L);
+ untranslate_all();
+ }
+ void draw_image(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D=3) {
+ X += offset_x; Y += offset_y;
+ translate_all(-offset_x, -offset_y);
+ Fl_Xlib_Graphics_Driver::draw_image(cb, data, X, Y, W,H,D);
+ untranslate_all();
+ }
+ void draw_image_mono(const uchar* buf, int X,int Y,int W,int H, int D=1, int L=0) {
+ X += offset_x; Y += offset_y;
+ translate_all(-offset_x, -offset_y);
+ Fl_Xlib_Graphics_Driver::draw_image_mono(buf, X, Y, W,H,D,L);
+ untranslate_all();
+ }
+ void draw_image_mono(Fl_Draw_Image_Cb cb, void* data, int X,int Y,int W,int H, int D=1) {
+ X += offset_x; Y += offset_y;
+ translate_all(-offset_x, -offset_y);
+ Fl_Xlib_Graphics_Driver::draw_image_mono(cb, data, X, Y, W,H,D);
+ untranslate_all();
+ }
+ void copy_offscreen(int x, int y, int w, int h, Fl_Offscreen pixmap, int srcx, int srcy) {
+ Fl_Xlib_Graphics_Driver::copy_offscreen(x+offset_x, y+offset_y, w, h,pixmap,srcx,srcy);
+ }
+ void push_clip(int x, int y, int w, int h) {
+ Fl_Xlib_Graphics_Driver::push_clip(x+offset_x, y+offset_y, w, h);
+ }
+ int not_clipped(int x, int y, int w, int h) { return Fl_Xlib_Graphics_Driver::not_clipped(x + offset_x, y + offset_y, w, h); };
+ int clip_box(int x, int y, int w, int h, int& X, int& Y, int& W, int& H) {
+ int retval = Fl_Xlib_Graphics_Driver::clip_box(x + offset_x, y + offset_y, w,h,X,Y,W,H);
+ X -= offset_x;
+ Y -= offset_y;
+ return retval;
+ }
+ void pie(int x, int y, int w, int h, double a1, double a2) { Fl_Xlib_Graphics_Driver::pie(x+offset_x,y+offset_y,w,h,a1,a2); }
+ void arc(int x, int y, int w, int h, double a1, double a2) { Fl_Xlib_Graphics_Driver::arc(x+offset_x,y+offset_y,w,h,a1,a2); }
+ void polygon(int x0, int y0, int x1, int y1, int x2, int y2) { Fl_Xlib_Graphics_Driver::polygon(x0+offset_x,y0+offset_y,x1+offset_x,y1+offset_y,x2+offset_x,y2+offset_y);}
+ void polygon(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3) {
+ Fl_Xlib_Graphics_Driver::polygon(x0+offset_x,y0+offset_y,x1+offset_x,y1+offset_y,x2+offset_x,y2+offset_y,x3+offset_x,y3+offset_y);
+ }
+ void loop(int x0, int y0, int x1, int y1, int x2, int y2) {Fl_Xlib_Graphics_Driver::loop(x0+offset_x,y0+offset_y,x1+offset_x,y1+offset_y,x2+offset_x,y2+offset_y);}
+ void loop(int x0, int y0, int x1, int y1, int x2, int y2, int x3, int y3) {
+ Fl_Xlib_Graphics_Driver::loop(x0+offset_x,y0+offset_y,x1+offset_x,y1+offset_y,x2+offset_x,y2+offset_y,x3+offset_x,y3+offset_y);
+ }
+ void point(int x, int y) { Fl_Xlib_Graphics_Driver::point(x+offset_x, y+offset_y); }
+};
+
+const char *Fl_translated_Xlib_Graphics_Driver_::class_id = "Fl_translated_Xlib_Graphics_Driver_";
+
+void Fl_Xlib_Surface_::translate(int x, int y) {
+ ((Fl_translated_Xlib_Graphics_Driver_*)driver())->translate_all(x, y);
+}
+void Fl_Xlib_Surface_::untranslate() {
+ ((Fl_translated_Xlib_Graphics_Driver_*)driver())->untranslate_all();
+}
+
+Fl_Xlib_Surface_::Fl_Xlib_Surface_() : Fl_Paged_Device() {
+ driver(new Fl_translated_Xlib_Graphics_Driver_());
+}
+Fl_Xlib_Surface_::~Fl_Xlib_Surface_() {
+ delete driver();
+}
+
+const char *Fl_Xlib_Surface_::class_id = "Fl_Xlib_Surface_";
+
+#endif
+
+//
+// End of "$Id: Fl_Copy_Surface.cxx 10209 2014-06-26 16:14:42Z manolo $".
+//
diff --git a/src/Fl_Double_Window.cxx b/src/Fl_Double_Window.cxx
index e31643d..6fbfa24 100644
--- a/src/Fl_Double_Window.cxx
+++ b/src/Fl_Double_Window.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: Fl_Double_Window.cxx 9719 2012-11-13 14:45:42Z manolo $"
+// "$Id: Fl_Double_Window.cxx 10335 2014-09-23 10:48:36Z manolo $"
//
// Double-buffered window code for the Fast Light Tool Kit (FLTK).
//
@@ -214,12 +214,10 @@ void Fl_GDI_Graphics_Driver::copy_offscreen_with_alpha(int x,int y,int w,int h,H
HDC new_gc = CreateCompatibleDC(fl_gc);
int save = SaveDC(new_gc);
SelectObject(new_gc, bitmap);
- fl_can_do_alpha_blending(); // make sure this is called
BOOL alpha_ok = 0;
// first try to alpha blend
- // if to printer, always try alpha_blend
- if ( Fl_Surface_Device::surface() != Fl_Display_Device::display_device() || fl_can_do_alpha_blending() ) {
- if (fl_alpha_blend) alpha_ok = fl_alpha_blend(fl_gc, x, y, w, h, new_gc, srcx, srcy, w, h, blendfunc);
+ if ( fl_can_do_alpha_blending() ) {
+ alpha_ok = fl_alpha_blend(fl_gc, x, y, w, h, new_gc, srcx, srcy, w, h, blendfunc);
}
// if that failed (it shouldn't), still copy the bitmap over, but now alpha is 1
if (!alpha_ok) {
@@ -229,7 +227,6 @@ void Fl_GDI_Graphics_Driver::copy_offscreen_with_alpha(int x,int y,int w,int h,H
DeleteDC(new_gc);
}
-extern void fl_restore_clip();
#elif defined(__APPLE_QUARTZ__) || defined(FL_DOXYGEN)
@@ -349,7 +346,6 @@ void fl_end_offscreen() {
/** @} */
-extern void fl_restore_clip();
#else
# error unsupported platform
@@ -369,6 +365,7 @@ void Fl_Double_Window::flush() {flush(0);}
and leaving the clip region set to the entire window.
*/
void Fl_Double_Window::flush(int eraseoverlay) {
+ if (!shown()) return;
make_current(); // make sure fl_gc is non-zero
Fl_X *myi = Fl_X::i(this);
if (!myi) return; // window not yet created
@@ -514,5 +511,5 @@ Fl_Overlay_Window::Fl_Overlay_Window(int X, int Y, int W, int H, const char *l)
//
-// End of "$Id: Fl_Double_Window.cxx 9719 2012-11-13 14:45:42Z manolo $".
+// End of "$Id: Fl_Double_Window.cxx 10335 2014-09-23 10:48:36Z manolo $".
//
diff --git a/src/Fl_File_Browser.cxx b/src/Fl_File_Browser.cxx
index f6d4d65..d7f3d2a 100644
--- a/src/Fl_File_Browser.cxx
+++ b/src/Fl_File_Browser.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: Fl_File_Browser.cxx 9325 2012-04-05 05:12:30Z fabien $"
+// "$Id: Fl_File_Browser.cxx 10145 2014-05-04 13:46:09Z manolo $"
//
// Fl_File_Browser routines.
//
@@ -62,6 +62,33 @@
# include <sys/mount.h>
#endif // __APPLE__
+#if defined(_AIX)
+extern "C" {
+# include <sys/types.h>
+# include <sys/vmount.h>
+# include <sys/mntctl.h>
+ // Older AIX versions don't expose this prototype
+ int
+ mntctl(int, int, char *);
+}
+#endif // _AIX
+
+#if defined(__NetBSD__)
+extern "C" {
+# include <sys/param.h> // For '__NetBSD_Version__' definition
+# if defined(__NetBSD_Version__) && (__NetBSD_Version__ >= 300000000)
+# include <sys/types.h>
+# include <sys/statvfs.h>
+# if defined(HAVE_PTHREAD) && defined(HAVE_PTHREAD_H)
+# include <pthread.h>
+# endif // HAVE_PTHREAD && HAVE_PTHREAD_H
+# ifdef HAVE_PTHREAD
+ static pthread_mutex_t getvfsstat_mutex = PTHREAD_MUTEX_INITIALIZER;
+# endif // HAVE_PTHREAD/
+# endif // __NetBSD_Version__
+}
+#endif // __NetBSD__
+
//
// FL_BLINE definition from "Fl_Browser.cxx"...
//
@@ -349,7 +376,7 @@ Fl_File_Browser::item_draw(void *p, // I - List item data
if (columns)
{
// Try clipping inside this column...
- for (i = 0; i < column && columns[i]; i ++);
+ for (i = 0; i < column && columns[i]; i ++) { ; }
if (columns[i])
cW = columns[i];
@@ -522,6 +549,77 @@ Fl_File_Browser::load(const char *directory,// I - Directory to load
// Free the memory used for the file system info array...
delete[] fs;
}
+#elif defined(_AIX)
+ // AIX don't write the mounted filesystems to a file like '/etc/mnttab'.
+ // But reading the list of mounted filesystems from the kernel is possible:
+ // http://publib.boulder.ibm.com/infocenter/pseries/v5r3/topic/com.ibm.aix.basetechref/doc/basetrf1/mntctl.htm
+ int res = -1, len;
+ char *list = NULL, *name;
+ struct vmount *vp;
+
+ // We always have the root filesystem
+ add("/", icon);
+ // Get the required buffer size for the vmount structures
+ res = mntctl(MCTL_QUERY, sizeof(len), (char *) &len);
+ if (!res) {
+ // Allocate buffer ...
+ list = (char *) malloc((size_t) len);
+ if (NULL == list) {
+ res = -1;
+ } else {
+ // ... and read vmount structures from kernel
+ res = mntctl(MCTL_QUERY, len, list);
+ if (0 >= res) {
+ res = -1;
+ } else {
+ for (i = 0, vp = (struct vmount *) list; i < res; ++i) {
+ name = (char *) vp + vp->vmt_data[VMT_STUB].vmt_off;
+ strlcpy(filename, name, sizeof(filename));
+ // Skip the already added root filesystem
+ if (strcmp("/", filename) != 0) {
+ strlcat(filename, "/", sizeof(filename));
+ add(filename, icon);
+ }
+ vp = (struct vmount *) ((char *) vp + vp->vmt_length);
+ }
+ }
+ }
+ }
+ // Note: Executing 'free(NULL)' is allowed and simply do nothing
+ free((void *) list);
+#elif defined(__NetBSD__) && defined(__NetBSD_Version__) \
+ && (__NetBSD_Version__ >= 300000000)
+ // NetBSD don't write the mounted filesystems to a file like '/etc/mnttab'.
+ // Since NetBSD 3.0 the system call getvfsstat(2) has replaced getfsstat(2)
+ // that is used by getmntinfo(3):
+ // http://www.daemon-systems.org/man/getmntinfo.3.html
+ int res = -1;
+ struct statvfs *list;
+
+ // We always have the root filesystem
+ add("/", icon);
+# ifdef HAVE_PTHREAD
+ // Lock mutex for thread safety
+ if (!pthread_mutex_lock(&getvfsstat_mutex)) {
+# endif // HAVE_PTHREAD
+ // Get list of statvfs structures
+ res = getmntinfo(&list, ST_WAIT);
+ if(0 < res) {
+ for (i = 0; i < res; ++i) {
+ strlcpy(filename, list[i].f_mntonname, sizeof(filename));
+ // Skip the already added root filesystem
+ if (strcmp("/", filename) != 0) {
+ strlcat(filename, "/", sizeof(filename));
+ add(filename, icon);
+ }
+ }
+ } else {
+ res = -1;
+ }
+# ifdef HAVE_PTHREAD
+ pthread_mutex_unlock(&getvfsstat_mutex);
+ }
+# endif // HAVE_PTHREAD
#else
//
// UNIX code uses /etc/fstab or similar...
@@ -550,7 +648,10 @@ Fl_File_Browser::load(const char *directory,// I - Directory to load
if (sscanf(line, "%*s%4095s", filename) != 1)
continue;
- strlcat(filename, "/", sizeof(filename));
+ // Add a trailing slash (except for the root filesystem)
+ if (strcmp("/", filename) != 0) {
+ strlcat(filename, "/", sizeof(filename));
+ }
// printf("Fl_File_Browser::load() - adding \"%s\" to list...\n", filename);
add(filename, icon);
@@ -558,8 +659,13 @@ Fl_File_Browser::load(const char *directory,// I - Directory to load
}
fclose(mtab);
+ } else {
+ // Every Unix has a root filesystem '/'.
+ // This last stage fallback ensures that the user don't get an empty
+ // window after requesting filesystem list.
+ add("/", icon);
}
-#endif // WIN32 || __EMX__
+#endif // WIN32 || __EMX__ || __APPLE__ || _AIX || ...
}
else
{
@@ -630,5 +736,5 @@ Fl_File_Browser::filter(const char *pattern) // I - Pattern string
//
-// End of "$Id: Fl_File_Browser.cxx 9325 2012-04-05 05:12:30Z fabien $".
+// End of "$Id: Fl_File_Browser.cxx 10145 2014-05-04 13:46:09Z manolo $".
//
diff --git a/src/Fl_File_Chooser.cxx b/src/Fl_File_Chooser.cxx
index 62ee256..935127e 100644
--- a/src/Fl_File_Chooser.cxx
+++ b/src/Fl_File_Chooser.cxx
@@ -1,9 +1,9 @@
//
-// "$Id: Fl_File_Chooser.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $"
+// "$Id: Fl_File_Chooser.cxx 10358 2014-10-05 11:56:06Z AlbrechtS $"
//
// Fl_File_Chooser dialog for the Fast Light Tool Kit (FLTK).
//
-// Copyright 1998-2011 by Bill Spitzak and others.
+// Copyright 1998-2014 by Bill Spitzak and others.
//
// This library is free software. Distribution and use rights are outlined in
// the file "COPYING" which should have been included with this file. If this
@@ -15,8 +15,15 @@
//
// http://www.fltk.org/str.php
//
+// ========================================================================
+// DO NOT EDIT FL/Fl_File_Chooser.H and src/Fl_File_Chooser.cxx !!!
+// ========================================================================
+// Please use fluid to change src/Fl_File_Chooser.fl interactively
+// and then use fluid to "write code" or edit and use fluid -c .
+// ========================================================================
+//
-// generated by Fast Light User Interface Designer (fluid) version 1.0300
+// generated by Fast Light User Interface Designer (fluid) version 1.0303
#include "../FL/Fl_File_Chooser.H"
#include <FL/fl_draw.H>
@@ -53,7 +60,7 @@ void Fl_File_Chooser::cb_newButton(Fl_Button* o, void* v) {
}
#include <FL/Fl_Bitmap.H>
-static unsigned char idata_new[] =
+static const unsigned char idata_new[] =
{0,0,120,0,132,0,2,1,1,254,1,128,49,128,49,128,253,128,253,128,49,128,49,
128,1,128,1,128,255,255,0,0};
static Fl_Bitmap image_new(idata_new, 16, 16);
@@ -221,7 +228,7 @@ Fl_File_Chooser::Fl_File_Chooser(const char *d, const char *p, int t, const char
fileName->callback((Fl_Callback*)cb_fileName);
fileName->when(FL_WHEN_ENTER_KEY);
Fl_Group::current()->resizable(fileName);
- fileName->when(FL_WHEN_CHANGED | FL_WHEN_ENTER_KEY);
+ fileName->when(FL_WHEN_CHANGED | FL_WHEN_ENTER_KEY_ALWAYS);
} // Fl_File_Input* fileName
{ Fl_Box* o = new Fl_Box(10, 310, 105, 25, "Filename:");
o->labelfont(1);
@@ -462,5 +469,5 @@ Fl_Widget* Fl_File_Chooser::add_extra(Fl_Widget* gr) {
}
//
-// End of "$Id: Fl_File_Chooser.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $".
+// End of "$Id: Fl_File_Chooser.cxx 10358 2014-10-05 11:56:06Z AlbrechtS $".
//
diff --git a/src/Fl_File_Chooser.fl b/src/Fl_File_Chooser.fl
index d13d23e..b2a528b 100644
--- a/src/Fl_File_Chooser.fl
+++ b/src/Fl_File_Chooser.fl
@@ -1,13 +1,13 @@
# data file for the Fltk User Interface Designer (fluid)
-version 1.0300
+version 1.0303
header_name {../FL/Fl_File_Chooser.H}
code_name {.cxx}
comment {//
-// "$Id: Fl_File_Chooser.fl 8864 2011-07-19 04:49:30Z greg.ercolano $"
+// "$Id: Fl_File_Chooser.fl 10357 2014-10-05 11:28:29Z AlbrechtS $"
//
// Fl_File_Chooser dialog for the Fast Light Tool Kit (FLTK).
//
-// Copyright 1998-2011 by Bill Spitzak and others.
+// Copyright 1998-2014 by Bill Spitzak and others.
//
// This library is free software. Distribution and use rights are outlined in
// the file "COPYING" which should have been included with this file. If this
@@ -19,31 +19,55 @@ comment {//
//
// http://www.fltk.org/str.php
//
+// ========================================================================
+// DO NOT EDIT FL/Fl_File_Chooser.H and src/Fl_File_Chooser.cxx !!!
+// ========================================================================
+// Please use fluid to change src/Fl_File_Chooser.fl interactively
+// and then use fluid to "write code" or edit and use fluid -c .
+// ========================================================================
+//
} {in_source in_header
}
-decl {\#include <FL/fl_draw.H>} {}
+decl {\#include <FL/fl_draw.H>} {private local
+}
class FL_EXPORT Fl_File_Chooser {open
} {
- decl {enum { SINGLE = 0, MULTI = 1, CREATE = 2, DIRECTORY = 4 };} {public
- }
- decl {static Fl_Preferences prefs_;} {}
- decl {void (*callback_)(Fl_File_Chooser*, void *);} {}
- decl {void *data_;} {}
- decl {char directory_[FL_PATH_MAX];} {}
- decl {char pattern_[FL_PATH_MAX];} {}
- decl {char preview_text_[2048];} {}
- decl {int type_;} {}
- decl {void favoritesButtonCB();} {}
- decl {void favoritesCB(Fl_Widget *w);} {}
- decl {void fileListCB();} {}
- decl {void fileNameCB();} {}
- decl {void newdir();} {}
- decl {static void previewCB(Fl_File_Chooser *fc);} {}
- decl {void showChoiceCB();} {}
- decl {void update_favorites();} {}
- decl {void update_preview();} {}
+ decl {enum { SINGLE = 0, MULTI = 1, CREATE = 2, DIRECTORY = 4 };} {public local
+ }
+ decl {static Fl_Preferences prefs_;} {private local
+ }
+ decl {void (*callback_)(Fl_File_Chooser*, void *);} {private local
+ }
+ decl {void *data_;} {private local
+ }
+ decl {char directory_[FL_PATH_MAX];} {private local
+ }
+ decl {char pattern_[FL_PATH_MAX];} {private local
+ }
+ decl {char preview_text_[2048];} {private local
+ }
+ decl {int type_;} {private local
+ }
+ decl {void favoritesButtonCB();} {private local
+ }
+ decl {void favoritesCB(Fl_Widget *w);} {private local
+ }
+ decl {void fileListCB();} {private local
+ }
+ decl {void fileNameCB();} {private local
+ }
+ decl {void newdir();} {private local
+ }
+ decl {static void previewCB(Fl_File_Chooser *fc);} {private local
+ }
+ decl {void showChoiceCB();} {private local
+ }
+ decl {void update_favorites();} {private local
+ }
+ decl {void update_preview();} {private local
+ }
Function {Fl_File_Chooser(const char *d, const char *p, int t, const char *title)} {} {
code {Fl_Group *prev_current = Fl_Group::current();} {}
Fl_Window window {
@@ -119,7 +143,7 @@ window->hide();} open
Fl_File_Input fileName {
callback {fileNameCB();}
private xywh {115 300 365 35} labelfont 1 when 8 resizable
- code0 {fileName->when(FL_WHEN_CHANGED | FL_WHEN_ENTER_KEY);}
+ code0 {fileName->when(FL_WHEN_CHANGED | FL_WHEN_ENTER_KEY_ALWAYS);}
}
Fl_Box {} {
label {Filename:}
@@ -238,15 +262,15 @@ data_ = d;} {}
} {
code {return (fileList->color());} {}
}
- decl {int count();} {public
+ decl {int count();} {public local
}
- decl {void directory(const char *d);} {public
+ decl {void directory(const char *d);} {public local
}
Function {directory()} {return_type {char *}
} {
code {return directory_;} {}
}
- decl {void filter(const char *p);} {public
+ decl {void filter(const char *p);} {public local
}
Function {filter()} {return_type {const char *}
} {
@@ -294,19 +318,19 @@ okButton->parent()->init_sizes();} {}
} {
code {return (okButton->label());} {}
}
- decl {void preview(int e);} {public
+ decl {void preview(int e);} {public local
}
- decl {int preview() const { return previewButton->value(); }} {public
+ decl {int preview() const { return previewButton->value(); }} {public local
}
- decl {void showHidden(int e);} {private
+ decl {void showHidden(int e);} {private local
}
- decl {void remove_hidden_files();} {private
+ decl {void remove_hidden_files();} {private local
}
- decl {void rescan();} {public
+ decl {void rescan();} {public local
}
- decl {void rescan_keep_filename();} {public
+ decl {void rescan_keep_filename();} {public local
}
- decl {void show();} {public
+ decl {void show();} {public local
}
Function {shown()} {return_type int
} {
@@ -364,61 +388,62 @@ else
} {
code {data_ = d;} {}
}
- decl {const char *value(int f = 1);} {public
+ decl {const char *value(int f = 1);} {public local
}
- decl {void value(const char *filename);} {public
+ decl {void value(const char *filename);} {public local
}
Function {visible()} {return_type int
} {
code {return window->visible();} {}
}
decl {static const char *add_favorites_label;} {
- comment {[standard text may be customized at run-time]} public
+ comment {[standard text may be customized at run-time]} public local
}
decl {static const char *all_files_label;} {
- comment {[standard text may be customized at run-time]} public
+ comment {[standard text may be customized at run-time]} public local
}
decl {static const char *custom_filter_label;} {
- comment {[standard text may be customized at run-time]} public
+ comment {[standard text may be customized at run-time]} public local
}
decl {static const char *existing_file_label;} {
- comment {[standard text may be customized at run-time]} public
+ comment {[standard text may be customized at run-time]} public local
}
decl {static const char *favorites_label;} {
- comment {[standard text may be customized at run-time]} public
+ comment {[standard text may be customized at run-time]} public local
}
decl {static const char *filename_label;} {
- comment {[standard text may be customized at run-time]} public
+ comment {[standard text may be customized at run-time]} public local
}
decl {static const char *filesystems_label;} {
- comment {[standard text may be customized at run-time]} public
+ comment {[standard text may be customized at run-time]} public local
}
decl {static const char *manage_favorites_label;} {
- comment {[standard text may be customized at run-time]} public
+ comment {[standard text may be customized at run-time]} public local
}
decl {static const char *new_directory_label;} {
- comment {[standard text may be customized at run-time]} public
+ comment {[standard text may be customized at run-time]} public local
}
decl {static const char *new_directory_tooltip;} {
- comment {[standard text may be customized at run-time]} public
+ comment {[standard text may be customized at run-time]} public local
}
decl {static const char *preview_label;} {
- comment {[standard text may be customized at run-time]} public
+ comment {[standard text may be customized at run-time]} public local
}
decl {static const char *save_label;} {
- comment {[standard text may be customized at run-time]} public
+ comment {[standard text may be customized at run-time]} public local
}
decl {static const char *show_label;} {
- comment {[standard text may be customized at run-time]} public
+ comment {[standard text may be customized at run-time]} public local
}
decl {static const char *hidden_label;} {
- comment {[standard text may be customized at run-time]} public
+ comment {[standard text may be customized at run-time]} public local
}
decl {static Fl_File_Sort_F *sort;} {
comment {the sort function that is used when loading
-the contents of a directory.} public
+the contents of a directory.} public local
+ }
+ decl {Fl_Widget* ext_group;} {private local
}
- decl {Fl_Widget* ext_group;} {}
Function {add_extra(Fl_Widget* gr)} {open return_type {Fl_Widget*}
} {
code {Fl_Widget* ret=ext_group;} {}
@@ -451,20 +476,20 @@ window->resizable(svres);} {}
}
}
-decl {FL_EXPORT char *fl_dir_chooser(const char *message,const char *fname,int relative=0);} {public
+decl {FL_EXPORT char *fl_dir_chooser(const char *message,const char *fname,int relative=0);} {public local
}
-decl {FL_EXPORT char *fl_file_chooser(const char *message,const char *pat,const char *fname,int relative=0);} {public
+decl {FL_EXPORT char *fl_file_chooser(const char *message,const char *pat,const char *fname,int relative=0);} {public local
}
-decl {FL_EXPORT void fl_file_chooser_callback(void (*cb)(const char*));} {public
+decl {FL_EXPORT void fl_file_chooser_callback(void (*cb)(const char*));} {public local
}
-decl {FL_EXPORT void fl_file_chooser_ok_label(const char*l);} {public
+decl {FL_EXPORT void fl_file_chooser_ok_label(const char*l);} {public local
}
comment {
//
-// End of "$Id: Fl_File_Chooser.fl 8864 2011-07-19 04:49:30Z greg.ercolano $".
+// End of "$Id: Fl_File_Chooser.fl 10357 2014-10-05 11:28:29Z AlbrechtS $".
//} {in_source in_header
}
diff --git a/src/Fl_File_Chooser2.cxx b/src/Fl_File_Chooser2.cxx
index 72378d9..a1a0b9e 100644
--- a/src/Fl_File_Chooser2.cxx
+++ b/src/Fl_File_Chooser2.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: Fl_File_Chooser2.cxx 9704 2012-10-19 11:23:51Z manolo $"
+// "$Id: Fl_File_Chooser2.cxx 10004 2013-10-21 04:58:43Z greg.ercolano $"
//
// More Fl_File_Chooser routines.
//
@@ -1423,6 +1423,15 @@ Fl_File_Chooser::update_preview()
previewBox->labelsize(size);
previewBox->labelfont(FL_COURIER);
}
+ } else if (image && ( (image->w() <= 0) ||
+ (image->h() <= 0) ||
+ (image->d() <= 0) )) {
+ // Image has errors? Show big 'X'
+ previewBox->label("X");
+ previewBox->align(FL_ALIGN_CLIP);
+ previewBox->labelsize(70);
+ previewBox->labelfont(FL_HELVETICA);
+ previewBox->redraw();
} else if (image) {
pbw = previewBox->w() - 20;
pbh = previewBox->h() - 20;
@@ -1696,5 +1705,5 @@ unquote_pathname(char *dst, // O - Destination string
//
-// End of "$Id: Fl_File_Chooser2.cxx 9704 2012-10-19 11:23:51Z manolo $".
+// End of "$Id: Fl_File_Chooser2.cxx 10004 2013-10-21 04:58:43Z greg.ercolano $".
//
diff --git a/src/Fl_File_Icon2.cxx b/src/Fl_File_Icon2.cxx
index 1e31b13..89d7958 100644
--- a/src/Fl_File_Icon2.cxx
+++ b/src/Fl_File_Icon2.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: Fl_File_Icon2.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $"
+// "$Id: Fl_File_Icon2.cxx 10140 2014-05-01 15:55:03Z manolo $"
//
// Fl_File_Icon system icon routines.
//
@@ -570,9 +570,14 @@ int Fl_File_Icon::load_image(const char *ifile) // I - File to read from
img->release();
#ifdef DEBUG
- printf("Icon File \"%s\":\n", xpm);
+{
+ int i;
+ printf("Icon File \"%s\":\n", ifile);
for (i = 0; i < num_data_; i ++)
+ {
printf(" %d,\n", data_[i]);
+ }
+}
#endif // DEBUG
return 0;
@@ -582,7 +587,7 @@ int Fl_File_Icon::load_image(const char *ifile) // I - File to read from
/**
Loads all system-defined icons. This call is useful when using the
FileChooser widget and should be used when the application starts:
-
+
\code
Fl_File_Icon::load_system_icons();
\endcode
@@ -616,7 +621,7 @@ Fl_File_Icon::load_system_icons(void) {
VERTEX, 7000, 5000, END, LINE, VERTEX, 3000, 4000,
VERTEX, 7000, 4000, END, LINE, VERTEX, 3000, 3000,
VERTEX, 7000, 3000, END, LINE, VERTEX, 3000, 2000,
- VERTEX, 7000, 2000, END,
+ VERTEX, 7000, 2000, END,
END
};
static short image[] = { // Image file icon
@@ -1009,5 +1014,5 @@ get_kde_val(char *str,
//
-// End of "$Id: Fl_File_Icon2.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $".
+// End of "$Id: Fl_File_Icon2.cxx 10140 2014-05-01 15:55:03Z manolo $".
//
diff --git a/src/Fl_Font.H b/src/Fl_Font.H
index 3c6ddc8..6eb6743 100644
--- a/src/Fl_Font.H
+++ b/src/Fl_Font.H
@@ -1,5 +1,5 @@
//
-// "$Id: Fl_Font.H 8864 2011-07-19 04:49:30Z greg.ercolano $"
+// "$Id: Fl_Font.H 10248 2014-08-23 08:41:58Z cand $"
//
// Font definitions for the Fast Light Tool Kit (FLTK).
//
@@ -29,7 +29,7 @@
# if USE_XFT
typedef struct _XftFont XftFont;
# elif !defined(WIN32) && !defined(__APPLE__)
-# include <FL/Xutf8.h>
+# include "Xutf8.h"
# endif // USE_XFT
/**
@@ -60,7 +60,6 @@ public:
# endif
ATSUStyle style;
short ascent, descent, q_width;
- char *q_name;
# elif USE_XFT
XftFont* font;
//const char* encoding;
@@ -105,5 +104,5 @@ FL_EXPORT char *fl_find_fontsize(char *name);
#endif
//
-// End of "$Id: Fl_Font.H 8864 2011-07-19 04:49:30Z greg.ercolano $".
+// End of "$Id: Fl_Font.H 10248 2014-08-23 08:41:58Z cand $".
//
diff --git a/src/Fl_GDI_Printer.cxx b/src/Fl_GDI_Printer.cxx
index e07e5ec..ad1988b 100644
--- a/src/Fl_GDI_Printer.cxx
+++ b/src/Fl_GDI_Printer.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: Fl_GDI_Printer.cxx 9325 2012-04-05 05:12:30Z fabien $"
+// "$Id: Fl_GDI_Printer.cxx 10391 2014-10-23 11:33:43Z AlbrechtS $"
//
// Support for WIN32 printing for the Fast Light Tool Kit (FLTK).
//
@@ -132,8 +132,11 @@ void Fl_System_Printer::absolute_printable_rect(int *x, int *y, int *w, int *h)
{
POINT physPageSize;
POINT pixelsPerInch;
+ XFORM transform;
if (hPr == NULL) return;
+ GetWorldTransform(fl_gc, &transform);
+ ModifyWorldTransform(fl_gc, NULL, MWT_IDENTITY);
SetWindowOrgEx(fl_gc, 0, 0, NULL);
physPageSize.x = GetDeviceCaps(hPr, HORZRES);
@@ -152,11 +155,12 @@ void Fl_System_Printer::absolute_printable_rect(int *x, int *y, int *w, int *h)
*x = left_margin;
*y = top_margin;
origin(x_offset, y_offset);
+ SetWorldTransform(fl_gc, &transform);
}
void Fl_System_Printer::margins(int *left, int *top, int *right, int *bottom)
{
- int x, y, w, h;
+ int x = 0, y = 0, w = 0, h = 0;
absolute_printable_rect(&x, &y, &w, &h);
if (left) *left = x;
if (top) *top = y;
@@ -273,5 +277,5 @@ void Fl_System_Printer::untranslate (void)
#endif // WIN32
//
-// End of "$Id: Fl_GDI_Printer.cxx 9325 2012-04-05 05:12:30Z fabien $".
+// End of "$Id: Fl_GDI_Printer.cxx 10391 2014-10-23 11:33:43Z AlbrechtS $".
//
diff --git a/src/Fl_Gl_Device_Plugin.cxx b/src/Fl_Gl_Device_Plugin.cxx
index 53d2e1b..313cd8e 100644
--- a/src/Fl_Gl_Device_Plugin.cxx
+++ b/src/Fl_Gl_Device_Plugin.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: Fl_Gl_Device_Plugin.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $"
+// "$Id: Fl_Gl_Device_Plugin.cxx 10051 2014-01-10 16:50:55Z manolo $"
//
// implementation of class Fl_Gl_Device_Plugin for the Fast Light Tool Kit (FLTK).
//
@@ -34,33 +34,12 @@ static void imgProviderReleaseData (void *info, const void *data, size_t size)
static void print_gl_window(Fl_Gl_Window *glw, int x, int y, int height)
{
-#ifdef WIN32
- HDC save_gc = fl_gc;
- const int bytesperpixel = 3;
-#elif defined(__APPLE__)
- CGContextRef save_gc = fl_gc;
+#if defined(__APPLE__)
const int bytesperpixel = 4;
#else
- _XGC *save_gc = fl_gc;
const int bytesperpixel = 3;
#endif
- Fl_Surface_Device *save_surface = Fl_Surface_Device::surface();
- fl_gc = NULL;
- Fl_Display_Device::display_device()->set_current();
-#ifdef WIN32
- Fl::check();
- Fl_Window *win = (Fl_Window*)glw;
- while( win->window() ) win = win->window();
- win->redraw();
- Fl::check();
- glw->make_current();
-#else
- glw->make_current();
- glw->redraw();
- glFlush();
- Fl::check();
- glFinish();
-#endif
+ glw->flush(); // forces a GL redraw necessary for the glpuzzle demo
// Read OpenGL context pixels directly.
// For extra safety, save & restore OpenGL states that are changed
glPushClientAttrib(GL_CLIENT_PIXEL_STORE_BIT);
@@ -73,17 +52,13 @@ static void print_gl_window(Fl_Gl_Window *glw, int x, int y, int height)
mByteWidth = (mByteWidth + 3) & ~3; // Align to 4 bytes
uchar *baseAddress = (uchar*)malloc(mByteWidth * glw->h());
glReadPixels(0, 0, glw->w(), glw->h(),
-#ifdef WIN32
- GL_RGB, GL_UNSIGNED_BYTE,
-#elif defined(__APPLE__)
+#if defined(__APPLE__)
GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV,
-#else // FIXME Linux/Unix
+#else
GL_RGB, GL_UNSIGNED_BYTE,
#endif
baseAddress);
glPopClientAttrib();
- save_surface->set_current();
- fl_gc = save_gc;
#if defined(__APPLE__)
// kCGBitmapByteOrder32Host and CGBitmapInfo are supposed to arrive with 10.4
// but some 10.4 don't have kCGBitmapByteOrder32Host, so we play a little #define game
@@ -143,5 +118,5 @@ static Fl_Gl_Device_Plugin Gl_Device_Plugin;
FL_EXPORT int fl_gl_load_plugin = 0;
//
-// End of "$Id: Fl_Gl_Device_Plugin.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $".
+// End of "$Id: Fl_Gl_Device_Plugin.cxx 10051 2014-01-10 16:50:55Z manolo $".
//
diff --git a/src/Fl_Gl_Window.cxx b/src/Fl_Gl_Window.cxx
index 36f3ddf..257085c 100644
--- a/src/Fl_Gl_Window.cxx
+++ b/src/Fl_Gl_Window.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: Fl_Gl_Window.cxx 9264 2012-03-05 08:46:30Z manolo $"
+// "$Id: Fl_Gl_Window.cxx 10214 2014-06-30 10:30:58Z ossman $"
//
// OpenGL window code for the Fast Light Tool Kit (FLTK).
//
@@ -24,8 +24,6 @@ extern int fl_gl_load_plugin;
extern void gl_texture_reset();
#endif
-static int temp = fl_gl_load_plugin;
-
#include <FL/Fl.H>
#include <FL/x.H>
#ifdef __APPLE__
@@ -183,8 +181,10 @@ void Fl_Gl_Window::make_current() {
GLint xywh[4];
if (window()) {
- xywh[0] = x();
- xywh[1] = window()->h() - y() - h();
+ int xoff,yoff;
+ const Fl_Window *win = top_window_offset(xoff, yoff); // STR #2944 [2]
+ xywh[0] = xoff;
+ xywh[1] = win->h() - yoff - h();
} else {
xywh[0] = 0;
xywh[1] = 0;
@@ -249,10 +249,34 @@ void Fl_Gl_Window::swap_buffers() {
# endif
#elif defined(__APPLE_QUARTZ__)
if(overlay != NULL) {
- //aglSwapBuffers does not work well with overlays under cocoa
- glReadBuffer(GL_BACK);
- glDrawBuffer(GL_FRONT);
- glCopyPixels(0,0,w(),h(),GL_COLOR);
+ // STR# 2944 [1]
+ // Save matrixmode/proj/modelview/rasterpos before doing overlay.
+ //
+ int wo=w(), ho=h();
+ GLint matrixmode;
+ GLfloat pos[4];
+ glGetIntegerv(GL_MATRIX_MODE, &matrixmode);
+ glGetFloatv(GL_CURRENT_RASTER_POSITION, pos); // save original glRasterPos
+ glMatrixMode(GL_PROJECTION); // save proj/model matrices
+ glPushMatrix();
+ glLoadIdentity();
+ glMatrixMode(GL_MODELVIEW);
+ glPushMatrix();
+ glLoadIdentity();
+ glScalef(2.0f/wo, 2.0f/ho, 1.0f);
+ glTranslatef(-wo/2.0f, -ho/2.0f, 0.0f); // set transform so 0,0 is bottom/left of Gl_Window
+ glRasterPos2i(0,0); // set glRasterPos to bottom left corner
+ {
+ // Emulate overlay by doing copypixels
+ glReadBuffer(GL_BACK);
+ glDrawBuffer(GL_FRONT);
+ glCopyPixels(0, 0, wo, ho, GL_COLOR); // copy GL_BACK to GL_FRONT
+ }
+ glPopMatrix(); // GL_MODELVIEW // restore model/proj matrices
+ glMatrixMode(GL_PROJECTION);
+ glPopMatrix();
+ glMatrixMode(matrixmode);
+ glRasterPos3f(pos[0], pos[1], pos[2]); // restore original glRasterPos
}
else
aglSwapBuffers((AGLContext)context_);
@@ -268,6 +292,7 @@ int fl_overlay_depth = 0;
void Fl_Gl_Window::flush() {
+ if (!shown()) return;
uchar save_valid = valid_f_ & 1;
#if HAVE_GL_OVERLAY && defined(WIN32)
uchar save_valid_f = valid_f_;
@@ -288,16 +313,9 @@ void Fl_Gl_Window::flush() {
#if HAVE_GL_OVERLAY && defined(WIN32)
- bool fixcursor = false; // for fixing the SGI 320 bug
-
// Draw into hardware overlay planes if they are damaged:
if (overlay && overlay != this
&& (damage()&(FL_DAMAGE_OVERLAY|FL_DAMAGE_EXPOSE) || !save_valid)) {
- // SGI 320 messes up overlay with user-defined cursors:
- if (Fl_X::i(this)->cursor && Fl_X::i(this)->cursor != fl_default_cursor) {
- fixcursor = true; // make it restore cursor later
- SetCursor(0);
- }
fl_set_gl_context(this, (GLContext)overlay);
if (fl_overlay_depth)
wglRealizeLayerPalette(Fl_X::i(this)->private_dc, 1, TRUE);
@@ -310,7 +328,6 @@ void Fl_Gl_Window::flush() {
wglSwapLayerBuffers(Fl_X::i(this)->private_dc, WGL_SWAP_OVERLAY1);
// if only the overlay was damaged we are done, leave main layer alone:
if (damage() == FL_DAMAGE_OVERLAY) {
- if (fixcursor) SetCursor(Fl_X::i(this)->cursor);
return;
}
}
@@ -406,9 +423,6 @@ void Fl_Gl_Window::flush() {
}
-#if HAVE_GL_OVERLAY && defined(WIN32)
- if (fixcursor) SetCursor(Fl_X::i(this)->cursor);
-#endif
valid(1);
context_valid(1);
}
@@ -549,6 +563,11 @@ int Fl_Gl_Window::handle(int event)
return Fl_Window::handle(event);
}
+// don't remove me! this serves only to force linking of Fl_Gl_Device_Plugin.o
+int Fl_Gl_Window::gl_plugin_linkage() {
+ return fl_gl_load_plugin;
+}
+
//
-// End of "$Id: Fl_Gl_Window.cxx 9264 2012-03-05 08:46:30Z manolo $".
+// End of "$Id: Fl_Gl_Window.cxx 10214 2014-06-30 10:30:58Z ossman $".
//
diff --git a/src/Fl_Group.cxx b/src/Fl_Group.cxx
index 6584be7..3f9f8fc 100644
--- a/src/Fl_Group.cxx
+++ b/src/Fl_Group.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: Fl_Group.cxx 9637 2012-07-24 04:37:22Z matt $"
+// "$Id: Fl_Group.cxx 10261 2014-08-29 12:10:11Z cand $"
//
// Group widget for the Fast Light Tool Kit (FLTK).
//
@@ -122,8 +122,10 @@ static int send(Fl_Widget* o, int event) {
}
// translate the current keystroke into up/down/left/right for navigation:
-#define ctrl(x) (x^0x40)
static int navkey() {
+ // The app may want these for hotkeys, check key state
+ if (Fl::event_state(FL_CTRL | FL_ALT | FL_META)) return 0;
+
switch (Fl::event_key()) {
case 0: // not an FL_KEYBOARD/FL_SHORTCUT event
break;
@@ -875,5 +877,5 @@ Fl_Spinner::Fl_Spinner(int X, int Y, int W, int H, const char *L)
//
-// End of "$Id: Fl_Group.cxx 9637 2012-07-24 04:37:22Z matt $".
+// End of "$Id: Fl_Group.cxx 10261 2014-08-29 12:10:11Z cand $".
//
diff --git a/src/Fl_Help_Dialog.cxx b/src/Fl_Help_Dialog.cxx
index ae8a36b..b608cbe 100644
--- a/src/Fl_Help_Dialog.cxx
+++ b/src/Fl_Help_Dialog.cxx
@@ -1,9 +1,9 @@
//
-// "$Id: Fl_Help_Dialog.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $"
+// "$Id: Fl_Help_Dialog.cxx 10357 2014-10-05 11:28:29Z AlbrechtS $"
//
// Fl_Help_Dialog dialog for the Fast Light Tool Kit (FLTK).
//
-// Copyright 1998-2010 by Bill Spitzak and others.
+// Copyright 1998-2014 by Bill Spitzak and others.
//
// This library is free software. Distribution and use rights are outlined in
// the file "COPYING" which should have been included with this file. If this
@@ -15,8 +15,15 @@
//
// http://www.fltk.org/str.php
//
+// ========================================================================
+// DO NOT EDIT FL/Fl_Help_Dialog.H and src/Fl_Help_Dialog.cxx !!!
+// ========================================================================
+// Please use fluid to change src/Fl_Help_Dialog.fl interactively
+// and then use fluid to "write code" or edit and use fluid -c .
+// ========================================================================
+//
-// generated by Fast Light User Interface Designer (fluid) version 1.0108
+// generated by Fast Light User Interface Designer (fluid) version 1.0303
#include "../FL/Fl_Help_Dialog.H"
#include "flstring.h"
@@ -192,13 +199,13 @@ Fl_Help_Dialog::Fl_Help_Dialog() {
window_->end();
} // Fl_Double_Window* window_
back_->deactivate();
-forward_->deactivate();
-
-index_ = -1;
-max_ = 0;
-find_pos_ = 0;
-
-fl_register_images();
+ forward_->deactivate();
+
+ index_ = -1;
+ max_ = 0;
+ find_pos_ = 0;
+
+ fl_register_images();
}
Fl_Help_Dialog::~Fl_Help_Dialog() {
@@ -215,8 +222,8 @@ void Fl_Help_Dialog::hide() {
void Fl_Help_Dialog::load(const char *f) {
view_->set_changed();
-view_->load(f);
-window_->label(view_->title());
+ view_->load(f);
+ window_->label(view_->title());
}
void Fl_Help_Dialog::position(int xx, int yy) {
@@ -237,16 +244,16 @@ void Fl_Help_Dialog::show(int argc, char **argv) {
void Fl_Help_Dialog::textsize(Fl_Fontsize s) {
view_->textsize(s);
-
-if (s <= 8)
- smaller_->deactivate();
-else
- smaller_->activate();
-
-if (s >= 18)
- larger_->deactivate();
-else
- larger_->activate();
+
+ if (s <= 8)
+ smaller_->deactivate();
+ else
+ smaller_->activate();
+
+ if (s >= 18)
+ larger_->deactivate();
+ else
+ larger_->activate();
}
Fl_Fontsize Fl_Help_Dialog::textsize() {
@@ -263,8 +270,8 @@ void Fl_Help_Dialog::topline(int n) {
void Fl_Help_Dialog::value(const char *f) {
view_->set_changed();
-view_->value(f);
-window_->label(view_->title());
+ view_->value(f);
+ window_->label(view_->title());
}
const char * Fl_Help_Dialog::value() const {
@@ -288,5 +295,5 @@ int Fl_Help_Dialog::y() {
}
//
-// End of "$Id: Fl_Help_Dialog.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $".
+// End of "$Id: Fl_Help_Dialog.cxx 10357 2014-10-05 11:28:29Z AlbrechtS $".
//
diff --git a/src/Fl_Help_Dialog.fl b/src/Fl_Help_Dialog.fl
index 30e731b..42dc5d2 100644
--- a/src/Fl_Help_Dialog.fl
+++ b/src/Fl_Help_Dialog.fl
@@ -1,13 +1,13 @@
# data file for the Fltk User Interface Designer (fluid)
-version 1.0108
+version 1.0303
header_name {../FL/Fl_Help_Dialog.H}
code_name {.cxx}
comment {//
-// "$Id: Fl_Help_Dialog.fl 8864 2011-07-19 04:49:30Z greg.ercolano $"
+// "$Id: Fl_Help_Dialog.fl 10357 2014-10-05 11:28:29Z AlbrechtS $"
//
// Fl_Help_Dialog dialog for the Fast Light Tool Kit (FLTK).
//
-// Copyright 1998-2010 by Bill Spitzak and others.
+// Copyright 1998-2014 by Bill Spitzak and others.
//
// This library is free software. Distribution and use rights are outlined in
// the file "COPYING" which should have been included with this file. If this
@@ -19,20 +19,34 @@ comment {//
//
// http://www.fltk.org/str.php
//
+// ========================================================================
+// DO NOT EDIT FL/Fl_Help_Dialog.H and src/Fl_Help_Dialog.cxx !!!
+// ========================================================================
+// Please use fluid to change src/Fl_Help_Dialog.fl interactively
+// and then use fluid to "write code" or edit and use fluid -c .
+// ========================================================================
+//
} {in_source in_header
}
-decl {\#include "flstring.h"} {}
+decl {\#include "flstring.h"} {private local
+}
-decl {\#include <FL/fl_ask.H>} {}
+decl {\#include <FL/fl_ask.H>} {private local
+}
class FL_EXPORT Fl_Help_Dialog {open
} {
- decl {int index_;} {}
- decl {int max_;} {}
- decl {int line_[100];} {}
- decl {char file_[100][256];} {}
- decl {int find_pos_;} {}
+ decl {int index_;} {private local
+ }
+ decl {int max_;} {private local
+ }
+ decl {int line_[100]; // FIXME: we must remove those static numbers} {private local
+ }
+ decl {char file_[100][FL_PATH_MAX]; // FIXME: we must remove those static numbers} {private local
+ }
+ decl {int find_pos_;} {private local
+ }
Function {Fl_Help_Dialog()} {open
} {
Fl_Window window_ {
@@ -251,6 +265,6 @@ window_->label(view_->title());} {}
comment {
//
-// End of "$Id: Fl_Help_Dialog.fl 8864 2011-07-19 04:49:30Z greg.ercolano $".
+// End of "$Id: Fl_Help_Dialog.fl 10357 2014-10-05 11:28:29Z AlbrechtS $".
//} {in_source in_header
}
diff --git a/src/Fl_Help_View.cxx b/src/Fl_Help_View.cxx
index 46d8090..f2e3fe0 100644
--- a/src/Fl_Help_View.cxx
+++ b/src/Fl_Help_View.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: Fl_Help_View.cxx 9325 2012-04-05 05:12:30Z fabien $"
+// "$Id: Fl_Help_View.cxx 10234 2014-08-21 12:18:32Z cand $"
//
// Fl_Help_View widget routines.
//
@@ -97,7 +97,7 @@ static char initial_load = 0;
// Broken image...
//
-static const char *broken_xpm[] =
+static const char * const broken_xpm[] =
{
"16 24 4 1",
"@ c #000000",
@@ -3362,7 +3362,7 @@ Fl_Help_View::value(const char *val) // I - Text to view
static int // O - Code or -1 on error
quote_char(const char *p) { // I - Quoted string
int i; // Looping var
- static struct {
+ static const struct {
const char *name;
int namelen;
int code;
@@ -3505,5 +3505,5 @@ hscrollbar_callback(Fl_Widget *s, void *)
//
-// End of "$Id: Fl_Help_View.cxx 9325 2012-04-05 05:12:30Z fabien $".
+// End of "$Id: Fl_Help_View.cxx 10234 2014-08-21 12:18:32Z cand $".
//
diff --git a/src/Fl_Image.cxx b/src/Fl_Image.cxx
index 69c972b..da0bccf 100644
--- a/src/Fl_Image.cxx
+++ b/src/Fl_Image.cxx
@@ -1,9 +1,9 @@
//
-// "$Id: Fl_Image.cxx 9709 2012-11-09 16:02:08Z manolo $"
+// "$Id: Fl_Image.cxx 10377 2014-10-14 11:53:51Z AlbrechtS $"
//
// Image drawing code for the Fast Light Tool Kit (FLTK).
//
-// Copyright 1998-2012 by Bill Spitzak and others.
+// Copyright 1998-2014 by Bill Spitzak and others.
//
// This library is free software. Distribution and use rights are outlined in
// the file "COPYING" which should have been included with this file. If this
@@ -34,6 +34,8 @@ void fl_restore_clip(); // from fl_rect.cxx
// Base image class...
//
+Fl_RGB_Scaling Fl_Image::RGB_scaling_ = FL_RGB_SCALING_NEAREST;
+
/**
The destructor is a virtual method that frees all memory used
by the image.
@@ -159,13 +161,40 @@ Fl_Image::measure(const Fl_Label *lo, // I - Label
lh = img->h();
}
+/** Sets the RGB image scaling method used for copy(int, int).
+ Applies to all RGB images, defaults to FL_RGB_SCALING_NEAREST.
+*/
+void Fl_Image::RGB_scaling(Fl_RGB_Scaling method) {
+ RGB_scaling_ = method;
+}
+
+/** Returns the currently used RGB image scaling method. */
+Fl_RGB_Scaling Fl_Image::RGB_scaling() {
+ return RGB_scaling_;
+}
+
//
// RGB image class...
//
size_t Fl_RGB_Image::max_size_ = ~((size_t)0);
-/** The destructor free all memory and server resources that are used by the image. */
+int fl_convert_pixmap(const char*const* cdata, uchar* out, Fl_Color bg);
+
+/** The constructor creates a new RGBA image from the specified Fl_Pixmap.
+
+ The RGBA image is built fully opaque except for the transparent area
+ of the pixmap that is assigned the \par bg color with full transparency */
+Fl_RGB_Image::Fl_RGB_Image(const Fl_Pixmap *pxm, Fl_Color bg):
+ Fl_Image(pxm->w(), pxm->h(), 4), id_(0), mask_(0)
+{
+ array = new uchar[w() * h() * d()];
+ alloc_array = 1;
+ fl_convert_pixmap(pxm->data(), (uchar*)array, bg);
+ data((const char **)&array, 1);
+}
+
+/** The destructor frees all memory and server resources that are used by the image. */
Fl_RGB_Image::~Fl_RGB_Image() {
uncache();
if (alloc_array) delete[] (uchar *)array;
@@ -245,25 +274,89 @@ Fl_Image *Fl_RGB_Image::copy(int W, int H) {
new_image = new Fl_RGB_Image(new_array, W, H, d());
new_image->alloc_array = 1;
- // Scale the image using a nearest-neighbor algorithm...
- for (dy = H, sy = 0, yerr = H, new_ptr = new_array; dy > 0; dy --) {
- for (dx = W, xerr = W, old_ptr = array + sy * line_d; dx > 0; dx --) {
- for (c = 0; c < d(); c ++) *new_ptr++ = old_ptr[c];
+ if (Fl_Image::RGB_scaling() == FL_RGB_SCALING_NEAREST) {
+ // Scale the image using a nearest-neighbor algorithm...
+ for (dy = H, sy = 0, yerr = H, new_ptr = new_array; dy > 0; dy --) {
+ for (dx = W, xerr = W, old_ptr = array + sy * line_d; dx > 0; dx --) {
+ for (c = 0; c < d(); c ++) *new_ptr++ = old_ptr[c];
+
+ old_ptr += xstep;
+ xerr -= xmod;
- old_ptr += xstep;
- xerr -= xmod;
+ if (xerr <= 0) {
+ xerr += W;
+ old_ptr += d();
+ }
+ }
- if (xerr <= 0) {
- xerr += W;
- old_ptr += d();
+ sy += ystep;
+ yerr -= ymod;
+ if (yerr <= 0) {
+ yerr += H;
+ sy ++;
}
}
+ } else {
+ // Bilinear scaling (FL_RGB_SCALING_BILINEAR)
+ const float xscale = (w() - 1) / (float) W;
+ const float yscale = (h() - 1) / (float) H;
+ for (dy = 0; dy < H; dy++) {
+ float oldy = dy * yscale;
+ if (oldy >= h())
+ oldy = h() - 1;
+ const float yfract = oldy - (unsigned) oldy;
+
+ for (dx = 0; dx < W; dx++) {
+ new_ptr = new_array + dy * W * d() + dx * d();
+
+ float oldx = dx * xscale;
+ if (oldx >= w())
+ oldx = w() - 1;
+ const float xfract = oldx - (unsigned) oldx;
+
+ const unsigned leftx = oldx;
+ const unsigned lefty = oldy;
+ const unsigned rightx = oldx + 1 >= w() ? oldx : oldx + 1;
+ const unsigned righty = oldy;
+ const unsigned dleftx = oldx;
+ const unsigned dlefty = oldy + 1 >= h() ? oldy : oldy + 1;
+ const unsigned drightx = rightx;
+ const unsigned drighty = dlefty;
+
+ uchar left[4], right[4], downleft[4], downright[4];
+ memcpy(left, array + lefty * line_d + leftx * d(), d());
+ memcpy(right, array + righty * line_d + rightx * d(), d());
+ memcpy(downleft, array + dlefty * line_d + dleftx * d(), d());
+ memcpy(downright, array + drighty * line_d + drightx * d(), d());
+
+ int i;
+ if (d() == 4) {
+ for (i = 0; i < 3; i++) {
+ left[i] *= left[3] / 255.0f;
+ right[i] *= right[3] / 255.0f;
+ downleft[i] *= downleft[3] / 255.0f;
+ downright[i] *= downright[3] / 255.0f;
+ }
+ }
+
+ const float leftf = 1 - xfract;
+ const float rightf = xfract;
+ const float upf = 1 - yfract;
+ const float downf = yfract;
+
+ for (i = 0; i < d(); i++) {
+ new_ptr[i] = (left[i] * leftf +
+ right[i] * rightf) * upf +
+ (downleft[i] * leftf +
+ downright[i] * rightf) * downf;
+ }
- sy += ystep;
- yerr -= ymod;
- if (yerr <= 0) {
- yerr += H;
- sy ++;
+ if (d() == 4 && new_ptr[3]) {
+ for (i = 0; i < 3; i++) {
+ new_ptr[i] /= new_ptr[3] / 255.0f;
+ }
+ }
+ }
}
}
@@ -453,6 +546,10 @@ static void imgProviderReleaseData (void *info, const void *data, size_t size)
delete[] (unsigned char *)data;
}
+#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5
+typedef void (*CGDataProviderReleaseDataCallback)(void *info, const void *data, size_t size);
+#endif
+
void Fl_Quartz_Graphics_Driver::draw(Fl_RGB_Image *img, int XP, int YP, int WP, int HP, int cx, int cy) {
int X, Y, W, H;
// Don't draw an empty image...
@@ -595,7 +692,6 @@ void Fl_RGB_Image::label(Fl_Menu_Item* m) {
m->label(_FL_IMAGE_LABEL, (const char*)this);
}
-
//
-// End of "$Id: Fl_Image.cxx 9709 2012-11-09 16:02:08Z manolo $".
+// End of "$Id: Fl_Image.cxx 10377 2014-10-14 11:53:51Z AlbrechtS $".
//
diff --git a/src/Fl_Image_Surface.cxx b/src/Fl_Image_Surface.cxx
new file mode 100644
index 0000000..b69b477
--- /dev/null
+++ b/src/Fl_Image_Surface.cxx
@@ -0,0 +1,157 @@
+//
+// "$Id: Fl_Image_Surface.cxx 10200 2014-06-18 01:22:16Z manolo $"
+//
+// Draw-to-image code for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2014 by Bill Spitzak and others.
+//
+// This library is free software. Distribution and use rights are outlined in
+// the file "COPYING" which should have been included with this file. If this
+// file is missing or damaged, see the license at:
+//
+// http://www.fltk.org/COPYING.php
+//
+// Please report all bugs and problems on the following page:
+//
+// http://www.fltk.org/str.php
+//
+
+#include <FL/Fl_Image_Surface.H>
+#include <FL/Fl_Printer.H>
+#include <FL/Fl.H>
+
+
+const char *Fl_Image_Surface::class_id = "Fl_Image_Surface";
+
+/** The constructor.
+ \param w and \param h give the size in pixels of the resulting image.
+ */
+Fl_Image_Surface::Fl_Image_Surface(int w, int h) : Fl_Surface_Device(NULL) {
+ width = w;
+ height = h;
+#if !(defined(__APPLE__) || defined(WIN32))
+ gc = 0;
+ if (!fl_display) { // allows use of this class before any window is shown
+ fl_open_display();
+ gc = XCreateGC(fl_display, RootWindow(fl_display, fl_screen), 0, 0);
+ fl_gc = gc;
+ }
+#endif
+ offscreen = fl_create_offscreen(w, h);
+#ifdef __APPLE__
+ helper = new Fl_Quartz_Flipped_Surface_(width, height);
+ driver(helper->driver());
+#elif defined(WIN32)
+ helper = new Fl_GDI_Surface_();
+ driver(helper->driver());
+#else
+ helper = new Fl_Xlib_Surface_();
+ driver(helper->driver());
+#endif
+}
+
+/** The destructor.
+ */
+Fl_Image_Surface::~Fl_Image_Surface() {
+ fl_delete_offscreen(offscreen);
+#ifdef __APPLE__
+ delete (Fl_Quartz_Flipped_Surface_*)helper;
+#elif defined(WIN32)
+ delete (Fl_GDI_Surface_*)helper;
+#else
+ if (gc) { XFreeGC(fl_display, gc); fl_gc = 0; }
+ delete (Fl_Xlib_Surface_*)helper;
+#endif
+}
+
+/** Returns an image made of all drawings sent to the Fl_Image_Surface object.
+ The returned object contains its own copy of the RGB data.
+ */
+Fl_RGB_Image* Fl_Image_Surface::image()
+{
+ unsigned char *data;
+#ifdef __APPLE__
+ CGContextFlush(offscreen);
+ data = fl_read_image(NULL, 0, 0, width, height, 0);
+ fl_end_offscreen();
+#elif defined(WIN32)
+ fl_pop_clip();
+ data = fl_read_image(NULL, 0, 0, width, height, 0);
+ RestoreDC(fl_gc, _savedc);
+ DeleteDC(fl_gc);
+ _ss->set_current();
+ fl_window=_sw;
+ fl_gc = _sgc;
+#else
+ fl_pop_clip();
+ data = fl_read_image(NULL, 0, 0, width, height, 0);
+ fl_window = pre_window;
+ previous->set_current();
+#endif
+ Fl_RGB_Image *image = new Fl_RGB_Image(data, width, height);
+ image->alloc_array = 1;
+ return image;
+}
+
+/** Draws a widget in the image surface
+
+ \param widget any FLTK widget (e.g., standard, custom, window, GL view) to draw in the image
+ \param delta_x and \param delta_y give
+ the position in the image of the top-left corner of the widget
+ */
+void Fl_Image_Surface::draw(Fl_Widget *widget, int delta_x, int delta_y)
+{
+ helper->print_widget(widget, delta_x, delta_y);
+}
+
+
+void Fl_Image_Surface::set_current()
+{
+#if defined(__APPLE__)
+ fl_begin_offscreen(offscreen);
+ fl_pop_clip();
+ Fl_Surface_Device::set_current();
+ fl_push_no_clip();
+#elif defined(WIN32)
+ _sgc=fl_gc;
+ _sw=fl_window;
+ _ss = Fl_Surface_Device::surface();
+ Fl_Surface_Device::set_current();
+ fl_gc = fl_makeDC(offscreen);
+ _savedc = SaveDC(fl_gc);
+ fl_window=(HWND)offscreen;
+ fl_push_no_clip();
+#else
+ pre_window = fl_window;
+ fl_window = offscreen;
+ previous = Fl_Surface_Device::surface();
+ Fl_Surface_Device::set_current();
+ fl_push_no_clip();
+#endif
+}
+
+#if defined(__APPLE__)
+
+Fl_Quartz_Flipped_Surface_::Fl_Quartz_Flipped_Surface_(int w, int h) : Fl_Quartz_Surface_(w, h) {
+}
+
+void Fl_Quartz_Flipped_Surface_::translate(int x, int y) {
+ CGContextRestoreGState(fl_gc);
+ CGContextSaveGState(fl_gc);
+ CGContextTranslateCTM(fl_gc, x, -y);
+ CGContextSaveGState(fl_gc);
+ CGContextTranslateCTM(fl_gc, 0, height);
+ CGContextScaleCTM(fl_gc, 1.0f, -1.0f);
+}
+
+void Fl_Quartz_Flipped_Surface_::untranslate() {
+ CGContextRestoreGState(fl_gc);
+}
+
+const char *Fl_Quartz_Flipped_Surface_::class_id = "Fl_Quartz_Flipped_Surface_";
+
+#endif // __APPLE__
+
+//
+// End of "$Id: Fl_Image_Surface.cxx 10200 2014-06-18 01:22:16Z manolo $".
+//
diff --git a/src/Fl_Input.cxx b/src/Fl_Input.cxx
index f1e8e1c..623e87f 100644
--- a/src/Fl_Input.cxx
+++ b/src/Fl_Input.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: Fl_Input.cxx 9637 2012-07-24 04:37:22Z matt $"
+// "$Id: Fl_Input.cxx 10031 2013-12-13 16:28:38Z manolo $"
//
// Input widget for the Fast Light Tool Kit (FLTK).
//
@@ -358,6 +358,11 @@ int Fl_Input::handle_key() {
else replace(position(), del ? position()-del : mark(),
Fl::event_text(), Fl::event_length());
}
+#ifdef __APPLE__
+ if (Fl::compose_state) {
+ this->mark( this->position() - Fl::compose_state );
+ }
+#endif
return 1;
}
@@ -583,8 +588,16 @@ int Fl_Input::handle_key() {
int Fl_Input::handle(int event) {
static int dnd_save_position, dnd_save_mark, drag_start = -1, newpos;
- static Fl_Widget *dnd_save_focus;
+ static Fl_Widget *dnd_save_focus = NULL;
switch (event) {
+#ifdef __APPLE__
+ case FL_UNFOCUS:
+ if (Fl::compose_state) {
+ this->mark( this->position() );
+ Fl::reset_marked_text();
+ }
+ break;
+#endif
case FL_FOCUS:
switch (Fl::event_key()) {
case FL_Right:
@@ -617,7 +630,8 @@ int Fl_Input::handle(int event) {
&& !Fl::event_state(FL_SHIFT) // no shift?
&& !tab_nav() // with tab navigation disabled?
&& input_type() == FL_MULTILINE_INPUT // with a multiline input?
- && (mark()==0 && position()==size())) { // while entire field selected?
+ && size() > 0 // non-empty field?
+ && ((mark()==0 && position()==size()) || (position()==0 && mark()==size()))) {// while entire field selected?
// Set cursor to the end of the selection...
if (mark() > position())
position(mark());
@@ -662,6 +676,7 @@ int Fl_Input::handle(int event) {
// save the position because sometimes we don't get DND_ENTER:
dnd_save_position = position();
dnd_save_mark = mark();
+ dnd_save_focus = this;
// drag the data:
copy(0); Fl::dnd();
return 1;
@@ -693,10 +708,10 @@ int Fl_Input::handle(int event) {
case FL_DND_ENTER:
Fl::belowmouse(this); // send the leave events first
- dnd_save_position = position();
- dnd_save_mark = mark();
- dnd_save_focus = Fl::focus();
if (dnd_save_focus != this) {
+ dnd_save_position = position();
+ dnd_save_mark = mark();
+ dnd_save_focus = Fl::focus();
Fl::focus(this);
handle(FL_FOCUS);
}
@@ -722,16 +737,33 @@ int Fl_Input::handle(int event) {
#if DND_OUT_XXXX
if (!focused())
#endif
- if (dnd_save_focus != this) {
+ if (dnd_save_focus && dnd_save_focus != this) {
Fl::focus(dnd_save_focus);
handle(FL_UNFOCUS);
}
#if !(defined(__APPLE__) || defined(WIN32))
Fl::first_window()->cursor(FL_CURSOR_MOVE);
#endif
+ dnd_save_focus = NULL;
return 1;
case FL_DND_RELEASE:
+ if (dnd_save_focus == this) { // if the dragged text comes from the same widget
+ // remove the selected text
+ int old_position = position();
+ if (dnd_save_mark > dnd_save_position) {
+ int tmp = dnd_save_mark;
+ dnd_save_mark = dnd_save_position;
+ dnd_save_position = tmp;
+ }
+ replace(dnd_save_mark, dnd_save_position, NULL, 0);
+ if (old_position > dnd_save_position) position(old_position - (dnd_save_position - dnd_save_mark));
+ else position(old_position);
+ }
+ else if(dnd_save_focus) {
+ dnd_save_focus->handle(FL_UNFOCUS);
+ }
+ dnd_save_focus = NULL;
take_focus();
return 1;
@@ -766,12 +798,14 @@ Fl_Float_Input::Fl_Float_Input(int X,int Y,int W,int H,const char *l)
: Fl_Input(X,Y,W,H,l)
{
type(FL_FLOAT_INPUT);
+ clear_flag(MAC_USE_ACCENTS_MENU);
}
Fl_Int_Input::Fl_Int_Input(int X,int Y,int W,int H,const char *l)
: Fl_Input(X,Y,W,H,l) {
type(FL_INT_INPUT);
+ clear_flag(MAC_USE_ACCENTS_MENU);
}
@@ -796,9 +830,19 @@ Fl_Multiline_Output::Fl_Multiline_Output(int X,int Y,int W,int H,const char *l)
Fl_Secret_Input::Fl_Secret_Input(int X,int Y,int W,int H,const char *l)
: Fl_Input(X,Y,W,H,l) {
type(FL_SECRET_INPUT);
+ clear_flag(MAC_USE_ACCENTS_MENU);
}
+int Fl_Secret_Input::handle(int event) {
+ int retval = Fl_Input::handle(event);
+#ifdef __APPLE__
+ if (event == FL_KEYBOARD && Fl::compose_state) {
+ this->mark( this->position() ); // don't underline marked text
+ }
+#endif
+ return retval;
+}
//
-// End of "$Id: Fl_Input.cxx 9637 2012-07-24 04:37:22Z matt $".
+// End of "$Id: Fl_Input.cxx 10031 2013-12-13 16:28:38Z manolo $".
//
diff --git a/src/Fl_Input_.cxx b/src/Fl_Input_.cxx
index ff29d2a..08b4222 100644
--- a/src/Fl_Input_.cxx
+++ b/src/Fl_Input_.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: Fl_Input_.cxx 9326 2012-04-05 14:30:19Z AlbrechtS $"
+// "$Id: Fl_Input_.cxx 10402 2014-10-28 15:33:17Z cand $"
//
// Common input widget routines for the Fast Light Tool Kit (FLTK).
//
@@ -339,10 +339,25 @@ void Fl_Input_::drawtext(int X, int Y, int W, int H) {
int offset2;
if (pp <= e) x2 = xpos + (float)expandpos(p, pp, buf, &offset2);
else offset2 = (int) strlen(buf);
+#ifdef __APPLE__ // Mac OS: underline marked ( = selected + Fl::compose_state != 0) text
+ if (Fl::compose_state) {
+ fl_color(textcolor());
+ }
+ else
+#endif
+ {
fl_color(selection_color());
fl_rectf((int)(x1+0.5), Y+ypos, (int)(x2-x1+0.5), height);
fl_color(fl_contrast(textcolor(), selection_color()));
+ }
fl_draw(buf+offset1, offset2-offset1, x1, (float)(Y+ypos+desc));
+#ifdef __APPLE__ // Mac OS: underline marked ( = selected + Fl::compose_state != 0) text
+ if (Fl::compose_state) {
+ fl_color( fl_color_average(textcolor(), color(), 0.6) );
+ float width = fl_width(buf+offset1, offset2-offset1);
+ fl_line(x1, Y+ypos+height-1, x1+width, Y+ypos+height-1);
+ }
+#endif
if (pp < e) {
fl_color(tc);
fl_draw(buf+offset2, (int) strlen(buf+offset2), x2, (float)(Y+ypos+desc));
@@ -357,7 +372,11 @@ void Fl_Input_::drawtext(int X, int Y, int W, int H) {
CONTINUE2:
// draw the cursor:
- if (Fl::focus() == this && selstart == selend &&
+ if (Fl::focus() == this && (
+#ifdef __APPLE__
+ Fl::compose_state ||
+#endif
+ selstart == selend) &&
position() >= p-value() && position() <= e-value()) {
fl_color(cursor_color());
// cursor position may need to be recomputed (see STR #2486)
@@ -369,6 +388,9 @@ void Fl_Input_::drawtext(int X, int Y, int W, int H) {
} else {
fl_rectf((int)(xpos+curx+0.5), Y+ypos, 2, height);
}
+#ifdef __APPLE__
+ Fl::insertion_point_location(xpos+curx, Y+ypos+height, height);
+#endif
}
CONTINUE:
@@ -397,25 +419,27 @@ void Fl_Input_::drawtext(int X, int Y, int W, int H) {
/** \internal
Simple function that determines if a character could be part of a word.
- \todo This function is not ucs4-aware.
+ \todo This function is not UTF-8-aware.
*/
static int isword(char c) {
- return (c&128 || isalnum(c) || strchr("#%&-/@\\_~", c));
+ return (c&128 || isalnum(c) || strchr("#%-@_~", c));
}
/**
Finds the end of a word.
- This call calculates the end of a word based on the given
- index \p i. Calling this function repeatedly will move
- forwards to the end of the text.
-
+ Returns the index after the last byte of a word.
+ If the index is already at the end of a word, it will find the
+ end of the following word, so if you call it repeatedly you will
+ move forwards to the end of the text.
+
+ Note that this is inconsistent with line_end().
+
\param [in] i starting index for the search
\return end of the word
*/
int Fl_Input_::word_end(int i) const {
if (input_type() == FL_SECRET_INPUT) return size();
- //while (i < size() && !isword(index(i))) i++;
while (i < size() && !isword(index(i))) i++;
while (i < size() && isword(index(i))) i++;
return i;
@@ -424,17 +448,18 @@ int Fl_Input_::word_end(int i) const {
/**
Finds the start of a word.
- This call calculates the start of a word based on the given
- index \p i. Calling this function repeatedly will move
- backwards to the beginning of the text.
-
+ Returns the index of the first byte of a word.
+ If the index is already at the beginning of a word, it will find the
+ beginning of the previous word, so if you call it repeatedly you will
+ move backwards to the beginning of the text.
+
+ Note that this is inconsistent with line_start().
+
\param [in] i starting index for the search
- \return start of the word
+ \return start of the word, or previous word
*/
int Fl_Input_::word_start(int i) const {
if (input_type() == FL_SECRET_INPUT) return 0;
-// if (i >= size() || !isword(index(i)))
-// while (i > 0 && !isword(index(i-1))) i--;
while (i > 0 && !isword(index(i-1))) i--;
while (i > 0 && isword(index(i-1))) i--;
return i;
@@ -496,6 +521,20 @@ int Fl_Input_::line_start(int i) const {
} else return j;
}
+static int strict_word_start(const char *s, int i, int itype) {
+ if (itype == FL_SECRET_INPUT) return 0;
+ while (i > 0 && !isspace(s[i-1]))
+ i--;
+ return i;
+}
+
+static int strict_word_end(const char *s, int len, int i, int itype) {
+ if (itype == FL_SECRET_INPUT) return len;
+ while (i < len && !isspace(s[i]))
+ i++;
+ return i;
+}
+
/**
Handles mouse clicks and mouse moves.
\todo Add comment and parameters
@@ -549,16 +588,16 @@ void Fl_Input_::handle_mouse(int X, int Y, int /*W*/, int /*H*/, int drag) {
newpos = line_end(newpos);
newmark = line_start(newmark);
} else {
- newpos = word_end(newpos);
- newmark = word_start(newmark);
+ newpos = strict_word_end(value(), size(), newpos, input_type());
+ newmark = strict_word_start(value(), newmark, input_type());
}
} else {
if (Fl::event_clicks() > 1) {
newpos = line_start(newpos);
newmark = line_end(newmark);
} else {
- newpos = word_start(newpos);
- newmark = word_end(newmark);
+ newpos = strict_word_start(value(), newpos, input_type());
+ newmark = strict_word_end(value(), size(), newmark, input_type());
}
}
// if the multiple click does not increase the selection, revert
@@ -1100,6 +1139,7 @@ Fl_Input_::Fl_Input_(int X, int Y, int W, int H, const char* l)
maximum_size_ = 32767;
shortcut_ = 0;
set_flag(SHORTCUT_LABEL);
+ set_flag(MAC_USE_ACCENTS_MENU);
tab_nav(1);
}
@@ -1298,5 +1338,5 @@ unsigned int Fl_Input_::index(int i) const
}
//
-// End of "$Id: Fl_Input_.cxx 9326 2012-04-05 14:30:19Z AlbrechtS $".
+// End of "$Id: Fl_Input_.cxx 10402 2014-10-28 15:33:17Z cand $".
//
diff --git a/src/Fl_JPEG_Image.cxx b/src/Fl_JPEG_Image.cxx
index e62768f..179ade6 100644
--- a/src/Fl_JPEG_Image.cxx
+++ b/src/Fl_JPEG_Image.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: Fl_JPEG_Image.cxx 9709 2012-11-09 16:02:08Z manolo $"
+// "$Id: Fl_JPEG_Image.cxx 9980 2013-09-21 16:41:23Z greg.ercolano $"
//
// Fl_JPEG_Image routines.
//
@@ -212,35 +212,39 @@ typedef struct {
typedef my_source_mgr *my_src_ptr;
-void init_source (j_decompress_ptr cinfo) {
- my_src_ptr src = (my_src_ptr)cinfo->src;
- src->s = src->data;
-}
+extern "C" {
-boolean fill_input_buffer(j_decompress_ptr cinfo) {
- my_src_ptr src = (my_src_ptr)cinfo->src;
- size_t nbytes = 4096;
- src->pub.next_input_byte = src->s;
- src->pub.bytes_in_buffer = nbytes;
- src->s += nbytes;
- return TRUE;
-}
+ static void init_source(j_decompress_ptr cinfo) {
+ my_src_ptr src = (my_src_ptr)cinfo->src;
+ src->s = src->data;
+ }
-void term_source(j_decompress_ptr cinfo)
-{
-}
+ static boolean fill_input_buffer(j_decompress_ptr cinfo) {
+ my_src_ptr src = (my_src_ptr)cinfo->src;
+ size_t nbytes = 4096;
+ src->pub.next_input_byte = src->s;
+ src->pub.bytes_in_buffer = nbytes;
+ src->s += nbytes;
+ return TRUE;
+ }
+
+ static void term_source(j_decompress_ptr cinfo)
+ {
+ }
-void skip_input_data(j_decompress_ptr cinfo, long num_bytes) {
- my_src_ptr src = (my_src_ptr)cinfo->src;
- if (num_bytes > 0) {
- while (num_bytes > (long)src->pub.bytes_in_buffer) {
- num_bytes -= (long)src->pub.bytes_in_buffer;
- fill_input_buffer(cinfo);
+ static void skip_input_data(j_decompress_ptr cinfo, long num_bytes) {
+ my_src_ptr src = (my_src_ptr)cinfo->src;
+ if (num_bytes > 0) {
+ while (num_bytes > (long)src->pub.bytes_in_buffer) {
+ num_bytes -= (long)src->pub.bytes_in_buffer;
+ fill_input_buffer(cinfo);
+ }
+ src->pub.next_input_byte += (size_t) num_bytes;
+ src->pub.bytes_in_buffer -= (size_t) num_bytes;
}
- src->pub.next_input_byte += (size_t) num_bytes;
- src->pub.bytes_in_buffer -= (size_t) num_bytes;
}
-}
+
+} // extern "C"
static void jpeg_mem_src(j_decompress_ptr cinfo, const unsigned char *data)
{
@@ -373,5 +377,5 @@ Fl_JPEG_Image::Fl_JPEG_Image(const char *name, const unsigned char *data)
}
//
-// End of "$Id: Fl_JPEG_Image.cxx 9709 2012-11-09 16:02:08Z manolo $".
+// End of "$Id: Fl_JPEG_Image.cxx 9980 2013-09-21 16:41:23Z greg.ercolano $".
//
diff --git a/src/Fl_Menu.cxx b/src/Fl_Menu.cxx
index 4e07383..20c9eed 100644
--- a/src/Fl_Menu.cxx
+++ b/src/Fl_Menu.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: Fl_Menu.cxx 9738 2012-12-07 16:29:49Z AlbrechtS $"
+// "$Id: Fl_Menu.cxx 10211 2014-06-28 12:29:51Z manolo $"
//
// Menu code for the Fast Light Tool Kit (FLTK).
//
@@ -353,7 +353,11 @@ menuwindow::menuwindow(const Fl_Menu_Item* m, int X, int Y, int Wp, int Hp,
if (Wp > W) W = Wp;
if (Wtitle > W) W = Wtitle;
- if (X < scr_x) X = scr_x; if (X > scr_x+scr_w-W) X = right_edge-W;
+ if (X < scr_x) X = scr_x;
+ // this change improves popup submenu positioning at right screen edge,
+ // but it makes right_edge argument useless
+ //if (X > scr_x+scr_w-W) X = right_edge-W;
+ if (X > scr_x+scr_w-W) X = scr_x+scr_w-W;
x(X); w(W);
h((numitems ? itemheight*numitems-LEADING : 0)+2*BW+3);
if (selected >= 0) {
@@ -916,10 +920,12 @@ const Fl_Menu_Item* Fl_Menu_Item::pulldown(
if (n->selected>=0) {
int dy = n->y()-nY;
int dx = n->x()-nX;
+ int waX, waY, waW, waH;
+ Fl::screen_work_area(waX, waY, waW, waH, X, Y);
for (int menu = 0; menu <= pp.menu_number; menu++) {
menuwindow* tt = pp.p[menu];
- int nx = tt->x()+dx; if (nx < 0) {nx = 0; dx = -tt->x();}
- int ny = tt->y()+dy; if (ny < 0) {ny = 0; dy = -tt->y();}
+ int nx = tt->x()+dx; if (nx < waX) {nx = waX; dx = -tt->x() + waX;}
+ int ny = tt->y()+dy; if (ny < waY) {ny = waY; dy = -tt->y() + waY;}
tt->position(nx, ny);
}
setitem(pp.nummenus-1, n->selected);
@@ -1046,5 +1052,5 @@ const Fl_Menu_Item* Fl_Menu_Item::test_shortcut() const {
}
//
-// End of "$Id: Fl_Menu.cxx 9738 2012-12-07 16:29:49Z AlbrechtS $".
+// End of "$Id: Fl_Menu.cxx 10211 2014-06-28 12:29:51Z manolo $".
//
diff --git a/src/Fl_Menu_Window.cxx b/src/Fl_Menu_Window.cxx
index f49d74d..6380572 100644
--- a/src/Fl_Menu_Window.cxx
+++ b/src/Fl_Menu_Window.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: Fl_Menu_Window.cxx 9637 2012-07-24 04:37:22Z matt $"
+// "$Id: Fl_Menu_Window.cxx 10095 2014-02-07 00:09:52Z AlbrechtS $"
//
// Menu window code for the Fast Light Tool Kit (FLTK).
//
@@ -54,6 +54,7 @@ void Fl_Menu_Window::show() {
}
void Fl_Menu_Window::flush() {
+ if (!shown()) return;
#if HAVE_OVERLAY
if (!fl_overlay_visual || !overlay()) {Fl_Single_Window::flush(); return;}
Fl_X *myi = Fl_X::i(this);
@@ -111,5 +112,5 @@ Fl_Menu_Window::Fl_Menu_Window(int X, int Y, int W, int H, const char *l)
//
-// End of "$Id: Fl_Menu_Window.cxx 9637 2012-07-24 04:37:22Z matt $".
+// End of "$Id: Fl_Menu_Window.cxx 10095 2014-02-07 00:09:52Z AlbrechtS $".
//
diff --git a/src/Fl_Native_File_Chooser_FLTK.cxx b/src/Fl_Native_File_Chooser_FLTK.cxx
index e3160b5..bedd7c7 100644
--- a/src/Fl_Native_File_Chooser_FLTK.cxx
+++ b/src/Fl_Native_File_Chooser_FLTK.cxx
@@ -1,10 +1,9 @@
-// "$Id: Fl_Native_File_Chooser_FLTK.cxx 9547 2012-05-25 14:46:02Z manolo $"
+// "$Id: Fl_Native_File_Chooser_FLTK.cxx 10349 2014-10-01 17:24:55Z manolo $"
//
-// FLTK native OS file chooser widget
+// FLTK native file chooser widget wrapper for GTK's GtkFileChooserDialog
//
-// Copyright 1998-2010 by Bill Spitzak and others.
-// Copyright 2004 Greg Ercolano.
-// API changes + filter improvements by Nathan Vander Wilt 2005
+// Copyright 1998-2014 by Bill Spitzak and others.
+// Copyright 2012 IMM
//
// This library is free software. Distribution and use rights are outlined in
// the file "COPYING" which should have been included with this file. If this
@@ -17,6 +16,7 @@
// http://www.fltk.org/str.php
//
+#include <config.h>
#include <FL/Fl_Native_File_Chooser.H>
#include <FL/Fl_File_Icon.H>
#define FLTK_CHOOSER_SINGLE Fl_File_Chooser::SINGLE
@@ -25,24 +25,20 @@
#define FLTK_CHOOSER_CREATE Fl_File_Chooser::CREATE
#include "Fl_Native_File_Chooser_common.cxx"
+#include "Fl_Native_File_Chooser_GTK.cxx"
+
#include <sys/stat.h>
#include <string.h>
+int Fl_Native_File_Chooser::have_looked_for_GTK_libs = 0;
+
/**
- The constructor. Internally allocates the native widgets.
- Optional \p val presets the type of browser this will be,
- which can also be changed with type().
-*/
+ The constructor. Internally allocates the native widgets.
+ Optional \p val presets the type of browser this will be,
+ which can also be changed with type().
+ */
Fl_Native_File_Chooser::Fl_Native_File_Chooser(int val) {
- //// CANT USE THIS -- MESSES UP LINKING/CREATES DEPENDENCY ON fltk_images.
- //// Have app call this from main() instead.
- ////
- //// static int init = 0; // 'first time' initialize flag
- //// if ( init == 0 ) {
- //// // Initialize when instanced for first time
- //// Fl_File_Icon::load_system_icons();
- //// init = 1;
- //// }
+#if FLTK_ABI_VERSION <= 10302
_btype = val;
_options = NO_OPTIONS;
_filter = NULL;
@@ -52,17 +48,203 @@ Fl_Native_File_Chooser::Fl_Native_File_Chooser(int val) {
_prevvalue = NULL;
_directory = NULL;
_errmsg = NULL;
- _file_chooser = new Fl_File_Chooser(NULL, NULL, 0, NULL);
- type(val); // do this after _file_chooser created
- _nfilters = 0;
-}
+#endif // FLTK_ABI_VERSION
+ if (have_looked_for_GTK_libs == 0) {
+ // First Time here, try to find the GTK libs if they are installed
+#if HAVE_DLSYM && HAVE_DLFCN_H
+ if (Fl::option(Fl::OPTION_FNFC_USES_GTK)) {
+ Fl_GTK_File_Chooser::probe_for_GTK_libs();
+ }
+#endif
+ have_looked_for_GTK_libs = -1;
+ }
+ // if we found all the GTK functions we need, we will use the GtkFileChooserDialog
+ if (Fl_GTK_File_Chooser::did_find_GTK_libs) _gtk_file_chooser = new Fl_GTK_File_Chooser(val);
+ else _x11_file_chooser = new Fl_FLTK_File_Chooser(val);
+}
/**
- Destructor.
- Deallocates any resources allocated to this widget.
-*/
+ Destructor.
+ Deallocates any resources allocated to this widget.
+ */
Fl_Native_File_Chooser::~Fl_Native_File_Chooser() {
+ delete _x11_file_chooser;
+}
+
+/**
+ Sets the current Fl_Native_File_Chooser::Type of browser.
+ */
+void Fl_Native_File_Chooser::type(int t) { return _x11_file_chooser->type(t); }
+/**
+ Gets the current Fl_Native_File_Chooser::Type of browser.
+ */
+int Fl_Native_File_Chooser::type() const { return _x11_file_chooser->type(); }
+/**
+ Sets the platform specific chooser options to \p val.
+ \p val is expected to be one or more Fl_Native_File_Chooser::Option flags ORed together.
+ Some platforms have OS-specific functions that can be enabled/disabled via this method.
+ <P>
+ \code
+ Flag Description Win Mac Other
+ -------------- ----------------------------------------------- ------- ------- -------
+ NEW_FOLDER Shows the 'New Folder' button. Ignored Used Used
+ PREVIEW Enables the 'Preview' mode by default. Ignored Ignored Used
+ SAVEAS_CONFIRM Confirm dialog if BROWSE_SAVE_FILE file exists. Used Used Used
+ USE_FILTER_EXT Chooser filter pilots the output file extension. Ignored Used Ignored
+\endcode
+ */
+void Fl_Native_File_Chooser::options(int o) { _x11_file_chooser->options(o); }
+/**
+ Gets the platform specific Fl_Native_File_Chooser::Option flags.
+ */
+int Fl_Native_File_Chooser::options() const { return _x11_file_chooser->options(); }
+
+/**
+ Returns the number of filenames (or directory names) the user selected.
+ <P>
+ \b Example:
+ \code
+ if ( fnfc->show() == 0 ) {
+ // Print all filenames user selected
+ for (int n=0; n<fnfc->count(); n++ ) {
+ printf("%d) '%s'\n", n, fnfc->filename(n));
+ }
+ }
+ \endcode
+ */
+int Fl_Native_File_Chooser::count() const { return _x11_file_chooser->count(); }
+/**
+ Return the filename the user chose.
+ Use this if only expecting a single filename.
+ If more than one filename is expected, use filename(int) instead.
+ Return value may be "" if no filename was chosen (eg. user cancelled).
+ */
+const char *Fl_Native_File_Chooser::filename() const { return _x11_file_chooser->filename(); }
+/**
+ Return one of the filenames the user selected.
+ Use count() to determine how many filenames the user selected.
+ <P>
+ \b Example:
+ \code
+ if ( fnfc->show() == 0 ) {
+ // Print all filenames user selected
+ for (int n=0; n<fnfc->count(); n++ ) {
+ printf("%d) '%s'\n", n, fnfc->filename(n));
+ }
+ }
+ \endcode
+ */
+const char *Fl_Native_File_Chooser::filename(int i) const { return _x11_file_chooser->filename(i); }
+/**
+ Preset the directory the browser will show when opened.
+ If \p val is NULL, or no directory is specified, the chooser will attempt
+ to use the last non-cancelled folder.
+ */
+void Fl_Native_File_Chooser::directory(const char *val) { _x11_file_chooser->directory(val); }
+/**
+ Returns the current preset directory() value.
+ */
+const char *Fl_Native_File_Chooser::directory() const { return _x11_file_chooser->directory(); }
+/**
+ Set the title of the file chooser's dialog window.
+ Can be NULL if no title desired.
+ The default title varies according to the platform, so you are advised to set the title explicitly.
+ */
+void Fl_Native_File_Chooser::title(const char *t) { _x11_file_chooser->title(t); }
+/**
+ Get the title of the file chooser's dialog window.
+ Return value may be NULL if no title was set.
+ */
+const char* Fl_Native_File_Chooser::title() const { return _x11_file_chooser->title(); }
+/**
+ Returns the filter string last set.
+ Can be NULL if no filter was set.
+ */
+const char *Fl_Native_File_Chooser::filter() const { return _x11_file_chooser->filter(); }
+/**
+ Sets the filename filters used for browsing.
+ The default is NULL, which browses all files.
+ <P>
+ The filter string can be any of:
+ <P>
+ - A single wildcard (eg. "*.txt")
+ - Multiple wildcards (eg. "*.{cxx,h,H}")
+ - A descriptive name followed by a "\t" and a wildcard (eg. "Text Files\t*.txt")
+ - A list of separate wildcards with a "\n" between each (eg. "*.{cxx,H}\n*.txt")
+ - A list of descriptive names and wildcards (eg. "C++ Files\t*.{cxx,H}\nTxt Files\t*.txt")
+ <P>
+ The format of each filter is a wildcard, or an optional user description
+ followed by '\\t' and the wildcard.
+ <P>
+ On most platforms, each filter is available to the user via a pulldown menu
+ in the file chooser. The 'All Files' option is always available to the user.
+ */
+void Fl_Native_File_Chooser::filter(const char *f) { _x11_file_chooser->filter(f); }
+/**
+ Gets how many filters were available, not including "All Files"
+ */
+int Fl_Native_File_Chooser::filters() const { return _x11_file_chooser->filters(); }
+/**
+ Sets which filter will be initially selected.
+
+ The first filter is indexed as 0.
+ If filter_value()==filters(), then "All Files" was chosen.
+ If filter_value() > filters(), then a custom filter was set.
+ */
+void Fl_Native_File_Chooser::filter_value(int i) { _x11_file_chooser->filter_value(i); }
+/**
+ Returns which filter value was last selected by the user.
+ This is only valid if the chooser returns success.
+ */
+int Fl_Native_File_Chooser::filter_value() const { return _x11_file_chooser->filter_value(); }
+/**
+ Sets the default filename for the chooser.
+ Use directory() to set the default directory.
+ Mainly used to preset the filename for save dialogs,
+ and on most platforms can be used for opening files as well.
+ */
+void Fl_Native_File_Chooser::preset_file(const char* f) { _x11_file_chooser->preset_file(f); }
+/**
+ Get the preset filename.
+ */
+const char* Fl_Native_File_Chooser::preset_file() const { return _x11_file_chooser->preset_file(); }
+/**
+ Returns a system dependent error message for the last method that failed.
+ This message should at least be flagged to the user in a dialog box, or to some kind of error log.
+ Contents will be valid only for methods that document errmsg() will have info on failures.
+ */
+const char *Fl_Native_File_Chooser::errmsg() const { return _x11_file_chooser->errmsg(); }
+/**
+ Post the chooser's dialog. Blocks until dialog has been completed or cancelled.
+ \returns
+ - 0 -- user picked a file
+ - 1 -- user cancelled
+ - -1 -- failed; errmsg() has reason
+ */
+int Fl_Native_File_Chooser::show() { return _x11_file_chooser->show(); }
+
+
+Fl_FLTK_File_Chooser::Fl_FLTK_File_Chooser(int val) {
+ _btype = 0;
+ _options = 0;
+ _filter = NULL;
+ _filtvalue = 0;
+ _parsedfilt = NULL;
+ _preset_file = NULL;
+ _prevvalue = NULL;
+ _directory = NULL;
+ _errmsg = NULL;
+ _file_chooser= NULL;
+ if (val >= 0) {
+ _file_chooser = new Fl_File_Chooser(NULL, NULL, 0, NULL);
+ type(val); // do this after _file_chooser created
+ }
+ _nfilters = 0;
+}
+
+Fl_FLTK_File_Chooser::~Fl_FLTK_File_Chooser() {
delete _file_chooser;
+ _file_chooser = NULL;
_filter = strfree(_filter);
_parsedfilt = strfree(_parsedfilt);
_preset_file = strfree(_preset_file);
@@ -71,285 +253,169 @@ Fl_Native_File_Chooser::~Fl_Native_File_Chooser() {
_errmsg = strfree(_errmsg);
}
+
// PRIVATE: SET ERROR MESSAGE
-void Fl_Native_File_Chooser::errmsg(const char *msg) {
+void Fl_FLTK_File_Chooser::errmsg(const char *msg) {
_errmsg = strfree(_errmsg);
_errmsg = strnew(msg);
}
// PRIVATE: translate Native types to Fl_File_Chooser types
-int Fl_Native_File_Chooser::type_fl_file(int val) {
+int Fl_FLTK_File_Chooser::type_fl_file(int val) {
switch (val) {
- case BROWSE_FILE:
- return(FLTK_CHOOSER_SINGLE);
- case BROWSE_DIRECTORY:
- return(FLTK_CHOOSER_SINGLE | FLTK_CHOOSER_DIRECTORY);
- case BROWSE_MULTI_FILE:
- return(FLTK_CHOOSER_MULTI);
- case BROWSE_MULTI_DIRECTORY:
- return(FLTK_CHOOSER_DIRECTORY | FLTK_CHOOSER_MULTI);
- case BROWSE_SAVE_FILE:
- return(FLTK_CHOOSER_SINGLE | FLTK_CHOOSER_CREATE);
- case BROWSE_SAVE_DIRECTORY:
- return(FLTK_CHOOSER_DIRECTORY | FLTK_CHOOSER_MULTI | FLTK_CHOOSER_CREATE);
+ case Fl_Native_File_Chooser::BROWSE_FILE:
+ return(Fl_File_Chooser::SINGLE);
+ case Fl_Native_File_Chooser::BROWSE_DIRECTORY:
+ return(Fl_File_Chooser::SINGLE | Fl_File_Chooser::DIRECTORY);
+ case Fl_Native_File_Chooser::BROWSE_MULTI_FILE:
+ return(Fl_File_Chooser::MULTI);
+ case Fl_Native_File_Chooser::BROWSE_MULTI_DIRECTORY:
+ return(Fl_File_Chooser::DIRECTORY | Fl_File_Chooser::MULTI);
+ case Fl_Native_File_Chooser::BROWSE_SAVE_FILE:
+ return(Fl_File_Chooser::SINGLE | Fl_File_Chooser::CREATE);
+ case Fl_Native_File_Chooser::BROWSE_SAVE_DIRECTORY:
+ return(Fl_File_Chooser::DIRECTORY | Fl_File_Chooser::MULTI | Fl_File_Chooser::CREATE);
default:
- return(FLTK_CHOOSER_SINGLE);
+ return(Fl_File_Chooser::SINGLE);
}
}
-/**
- Sets the current Fl_Native_File_Chooser::Type of browser.
- */
-void Fl_Native_File_Chooser::type(int val) {
+void Fl_FLTK_File_Chooser::type(int val) {
_btype = val;
_file_chooser->type(type_fl_file(val));
}
-/**
- Gets the current Fl_Native_File_Chooser::Type of browser.
- */
-int Fl_Native_File_Chooser::type() const {
+int Fl_FLTK_File_Chooser::type() const {
return(_btype);
}
-/**
- Sets the platform specific chooser options to \p val.
- \p val is expected to be one or more Fl_Native_File_Chooser::Option flags ORed together.
- Some platforms have OS-specific functions that can be enabled/disabled via this method.
- <P>
- \code
- Flag Description Win Mac Other
- -------------- ----------------------------------------------- ------- ------- -------
- NEW_FOLDER Shows the 'New Folder' button. Ignored Used Used
- PREVIEW Enables the 'Preview' mode by default. Ignored Ignored Used
- SAVEAS_CONFIRM Confirm dialog if BROWSE_SAVE_FILE file exists. Used Used Used
- \endcode
-*/
-void Fl_Native_File_Chooser::options(int val) {
+void Fl_FLTK_File_Chooser::options(int val) {
_options = val;
}
-/**
- Gets the platform specific Fl_Native_File_Chooser::Option flags.
-*/
-int Fl_Native_File_Chooser::options() const {
+int Fl_FLTK_File_Chooser::options() const {
return(_options);
}
-/**
- Post the chooser's dialog. Blocks until dialog has been completed or cancelled.
- \returns
- - 0 -- user picked a file
- - 1 -- user cancelled
- - -1 -- failed; errmsg() has reason
-*/
-int Fl_Native_File_Chooser::show() {
- // FILTER
- if ( _parsedfilt ) {
- _file_chooser->filter(_parsedfilt);
- }
+int Fl_FLTK_File_Chooser::show() {
- // FILTER VALUE
- // Set this /after/ setting the filter
- //
- _file_chooser->filter_value(_filtvalue);
+ // FILTER
+ if ( _parsedfilt ) {
+ _file_chooser->filter(_parsedfilt);
+ }
- // DIRECTORY
- if ( _directory && _directory[0] ) {
- _file_chooser->directory(_directory);
- } else {
- _file_chooser->directory(_prevvalue);
- }
+ // FILTER VALUE
+ // Set this /after/ setting the filter
+ //
+ _file_chooser->filter_value(_filtvalue);
- // PRESET FILE
- if ( _preset_file ) {
- _file_chooser->value(_preset_file);
- }
+ // DIRECTORY
+ if ( _directory && _directory[0] ) {
+ _file_chooser->directory(_directory);
+ } else {
+ _file_chooser->directory(_prevvalue);
+ }
- // OPTIONS: PREVIEW
- _file_chooser->preview( (options() & PREVIEW) ? 1 : 0);
+ // PRESET FILE
+ if ( _preset_file ) {
+ _file_chooser->value(_preset_file);
+ }
- // OPTIONS: NEW FOLDER
- if ( options() & NEW_FOLDER )
- _file_chooser->type(_file_chooser->type() | FLTK_CHOOSER_CREATE); // on
+ // OPTIONS: PREVIEW
+ _file_chooser->preview( (options() & Fl_Native_File_Chooser::PREVIEW) ? 1 : 0);
- // SHOW
- _file_chooser->show();
+ // OPTIONS: NEW FOLDER
+ if ( options() & Fl_Native_File_Chooser::NEW_FOLDER )
+ _file_chooser->type(_file_chooser->type() | Fl_File_Chooser::CREATE); // on
+
+ // SHOW
+ _file_chooser->show();
- // BLOCK WHILE BROWSER SHOWN
- while ( _file_chooser->shown() ) {
- Fl::wait();
- }
+ // BLOCK WHILE BROWSER SHOWN
+ while ( _file_chooser->shown() ) {
+ Fl::wait();
+ }
- if ( _file_chooser->value() && _file_chooser->value()[0] ) {
- _prevvalue = strfree(_prevvalue);
- _prevvalue = strnew(_file_chooser->value());
- _filtvalue = _file_chooser->filter_value(); // update filter value
-
- // HANDLE SHOWING 'SaveAs' CONFIRM
- if ( options() & SAVEAS_CONFIRM && type() == BROWSE_SAVE_FILE ) {
- struct stat buf;
- if ( stat(_file_chooser->value(), &buf) != -1 ) {
- if ( buf.st_mode & S_IFREG ) { // Regular file + exists?
- if ( exist_dialog() == 0 ) {
- return(1);
- }
- }
+ if ( _file_chooser->value() && _file_chooser->value()[0] ) {
+ _prevvalue = strfree(_prevvalue);
+ _prevvalue = strnew(_file_chooser->value());
+ _filtvalue = _file_chooser->filter_value(); // update filter value
+
+ // HANDLE SHOWING 'SaveAs' CONFIRM
+ if ( options() & Fl_Native_File_Chooser::SAVEAS_CONFIRM && type() == Fl_Native_File_Chooser::BROWSE_SAVE_FILE ) {
+ struct stat buf;
+ if ( stat(_file_chooser->value(), &buf) != -1 ) {
+ if ( buf.st_mode & S_IFREG ) { // Regular file + exists?
+ if ( exist_dialog() == 0 ) {
+ return(1);
+ }
+ }
+ }
}
}
- }
- if ( _file_chooser->count() ) return(0);
- else return(1);
+ if ( _file_chooser->count() ) return(0);
+ else return(1);
}
-/**
- Returns a system dependent error message for the last method that failed.
- This message should at least be flagged to the user in a dialog box, or to some kind of error log.
- Contents will be valid only for methods that document errmsg() will have info on failures.
- */
-const char *Fl_Native_File_Chooser::errmsg() const {
+const char *Fl_FLTK_File_Chooser::errmsg() const {
return(_errmsg ? _errmsg : "No error");
}
-/**
- Return the filename the user choose.
- Use this if only expecting a single filename.
- If more than one filename is expected, use filename(int) instead.
- Return value may be "" if no filename was chosen (eg. user cancelled).
- */
-const char* Fl_Native_File_Chooser::filename() const {
- if ( _file_chooser->count() > 0 ) return(_file_chooser->value());
+const char* Fl_FLTK_File_Chooser::filename() const {
+ if ( _file_chooser->count() > 0 ) {
+ return(_file_chooser->value());
+ }
return("");
}
-/**
- Return one of the filenames the user selected.
- Use count() to determine how many filenames the user selected.
- <P>
- \b Example:
- \code
- if ( fnfc->show() == 0 ) {
- // Print all filenames user selected
- for (int n=0; n<fnfc->count(); n++ ) {
- printf("%d) '%s'\n", n, fnfc->filename(n));
- }
- }
- \endcode
- */
-const char* Fl_Native_File_Chooser::filename(int i) const {
- if ( i < _file_chooser->count() )
- return(_file_chooser->value(i+1)); // convert fltk 1 based to our 0 based
+const char* Fl_FLTK_File_Chooser::filename(int i) const {
+ if ( i < _file_chooser->count() )
+ return(_file_chooser->value(i+1)); // convert fltk 1 based to our 0 based
return("");
}
-/**
- Set the title of the file chooser's dialog window.
- Can be NULL if no title desired.
- The default title varies according to the platform, so you are advised to set the title explicitly.
-*/
-void Fl_Native_File_Chooser::title(const char *val) {
+void Fl_FLTK_File_Chooser::title(const char *val) {
_file_chooser->label(val);
}
-/**
- Get the title of the file chooser's dialog window.
- Return value may be NULL if no title was set.
-*/
-const char *Fl_Native_File_Chooser::title() const {
- return(_file_chooser->label());
+const char *Fl_FLTK_File_Chooser::title() const {
+ return(_file_chooser->label());
}
-/**
- Sets the filename filters used for browsing.
- The default is NULL, which browses all files.
- <P>
- The filter string can be any of:
- <P>
- - A single wildcard (eg. "*.txt")
- - Multiple wildcards (eg. "*.{cxx,h,H}")
- - A descriptive name followed by a "\t" and a wildcard (eg. "Text Files\t*.txt")
- - A list of separate wildcards with a "\n" between each (eg. "*.{cxx,H}\n*.txt")
- - A list of descriptive names and wildcards (eg. "C++ Files\t*.{cxx,H}\nTxt Files\t*.txt")
- <P>
- The format of each filter is a wildcard, or an optional user description
- followed by '\\t' and the wildcard.
- <P>
- On most platforms, each filter is available to the user via a pulldown menu
- in the file chooser. The 'All Files' option is always available to the user.
-*/
-void Fl_Native_File_Chooser::filter(const char *val) {
+void Fl_FLTK_File_Chooser::filter(const char *val) {
_filter = strfree(_filter);
_filter = strnew(val);
parse_filter();
}
-/**
- Returns the filter string last set.
- Can be NULL if no filter was set.
- */
-const char *Fl_Native_File_Chooser::filter() const {
+const char *Fl_FLTK_File_Chooser::filter() const {
return(_filter);
}
-/**
-Gets how many filters were available, not including "All Files"
-*/
-int Fl_Native_File_Chooser::filters() const {
+int Fl_FLTK_File_Chooser::filters() const {
return(_nfilters);
}
-/**
- Sets which filter will be initially selected.
-
- The first filter is indexed as 0.
- If filter_value()==filters(), then "All Files" was chosen.
- If filter_value() > filters(), then a custom filter was set.
- */
-void Fl_Native_File_Chooser::filter_value(int val) {
+void Fl_FLTK_File_Chooser::filter_value(int val) {
_filtvalue = val;
}
-/**
- Returns which filter value was last selected by the user.
- This is only valid if the chooser returns success.
- */
-int Fl_Native_File_Chooser::filter_value() const {
- return(_filtvalue);
+int Fl_FLTK_File_Chooser::filter_value() const {
+ return _filtvalue;
}
-/**
- Returns the number of filenames (or directory names) the user selected.
- <P>
- \b Example:
- \code
- if ( fnfc->show() == 0 ) {
- // Print all filenames user selected
- for (int n=0; n<fnfc->count(); n++ ) {
- printf("%d) '%s'\n", n, fnfc->filename(n));
- }
- }
- \endcode
-*/
-int Fl_Native_File_Chooser::count() const {
- return(_file_chooser->count());
+int Fl_FLTK_File_Chooser::count() const {
+ return _file_chooser->count();
}
-/**
- Preset the directory the browser will show when opened.
- If \p val is NULL, or no directory is specified, the chooser will attempt
- to use the last non-cancelled folder.
-*/
-void Fl_Native_File_Chooser::directory(const char *val) {
+void Fl_FLTK_File_Chooser::directory(const char *val) {
_directory = strfree(_directory);
_directory = strnew(val);
}
-/**
- Returns the current preset directory() value.
-*/
-const char *Fl_Native_File_Chooser::directory() const {
- return(_directory);
+const char *Fl_FLTK_File_Chooser::directory() const {
+ return _directory;
}
// PRIVATE: Convert our filter format to fltk's chooser format
@@ -362,7 +428,7 @@ const char *Fl_Native_File_Chooser::directory() const {
// Returns a modified version of the filter that the caller is responsible
// for freeing with strfree().
//
-void Fl_Native_File_Chooser::parse_filter() {
+void Fl_FLTK_File_Chooser::parse_filter() {
_parsedfilt = strfree(_parsedfilt); // clear previous parsed filter (if any)
_nfilters = 0;
char *in = _filter;
@@ -425,29 +491,19 @@ void Fl_Native_File_Chooser::parse_filter() {
//NOTREACHED
}
-/**
- Sets the default filename for the chooser.
- Use directory() to set the default directory.
- Mainly used to preset the filename for save dialogs,
- and on most platforms can be used for opening files as well.
- */
-void Fl_Native_File_Chooser::preset_file(const char* val) {
+void Fl_FLTK_File_Chooser::preset_file(const char* val) {
_preset_file = strfree(_preset_file);
_preset_file = strnew(val);
}
-/**
- Get the preset filename.
- */
-const char* Fl_Native_File_Chooser::preset_file() const {
- return(_preset_file);
+const char* Fl_FLTK_File_Chooser::preset_file() const {
+ return _preset_file;
}
-
-int Fl_Native_File_Chooser::exist_dialog() {
- return(fl_choice("%s", fl_cancel, fl_ok, NULL, file_exists_message));
+int Fl_FLTK_File_Chooser::exist_dialog() {
+ return fl_choice("%s", fl_cancel, fl_ok, NULL, Fl_Native_File_Chooser::file_exists_message);
}
//
-// End of "$Id: Fl_Native_File_Chooser_FLTK.cxx 9547 2012-05-25 14:46:02Z manolo $".
+// End of "$Id: Fl_Native_File_Chooser_FLTK.cxx 10349 2014-10-01 17:24:55Z manolo $".
//
diff --git a/src/Fl_Native_File_Chooser_GTK.cxx b/src/Fl_Native_File_Chooser_GTK.cxx
new file mode 100644
index 0000000..1b47511
--- /dev/null
+++ b/src/Fl_Native_File_Chooser_GTK.cxx
@@ -0,0 +1,732 @@
+// "$Id$"
+//
+// FLTK native file chooser widget wrapper for GTK's GtkFileChooserDialog
+//
+// Copyright 1998-2014 by Bill Spitzak and others.
+// Copyright 2012 IMM
+//
+// This library is free software. Distribution and use rights are outlined in
+// the file "COPYING" which should have been included with this file. If this
+// file is missing or damaged, see the license at:
+//
+// http://www.fltk.org/COPYING.php
+//
+// Please report all bugs and problems to:
+//
+// http://www.fltk.org/str.php
+//
+
+#include <FL/x.H>
+#if HAVE_DLSYM && HAVE_DLFCN_H
+#include <dlfcn.h> // for dlopen et al
+#endif
+#include <locale.h> // for setlocale
+
+/* --------------------- Type definitions from GLIB and GTK --------------------- */
+/* all of this is from the public gnome API, so unlikely to change */
+#ifndef FALSE
+#define FALSE (0)
+#endif
+#ifndef TRUE
+#define TRUE (!FALSE)
+#endif
+typedef void* gpointer;
+typedef int gint;
+typedef unsigned int guint;
+typedef unsigned long gulong;
+typedef gint gboolean;
+typedef char gchar;
+typedef struct _GSList GSList;
+struct _GSList
+{
+ gpointer data;
+ GSList *next;
+};
+#define g_slist_next(slist) ((slist) ? (((GSList *)(slist))->next) : NULL)
+typedef struct _GtkWidget GtkWidget;
+typedef struct _GtkFileChooser GtkFileChooser;
+typedef struct _GtkDialog GtkDialog;
+typedef struct _GtkWindow GtkWindow;
+typedef struct _GdkDrawable GdkWindow;
+typedef struct _GtkFileFilter GtkFileFilter;
+typedef struct _GtkToggleButton GtkToggleButton;
+typedef enum {
+ GTK_FILE_FILTER_FILENAME = 1 << 0,
+ GTK_FILE_FILTER_URI = 1 << 1,
+ GTK_FILE_FILTER_DISPLAY_NAME = 1 << 2,
+ GTK_FILE_FILTER_MIME_TYPE = 1 << 3
+} GtkFileFilterFlags;
+struct _GtkFileFilterInfo
+{
+ GtkFileFilterFlags contains;
+
+ const gchar *filename;
+ const gchar *uri;
+ const gchar *display_name;
+ const gchar *mime_type;
+};
+typedef struct _GtkFileFilterInfo GtkFileFilterInfo;
+typedef gboolean (*GtkFileFilterFunc) (const GtkFileFilterInfo *filter_info, gpointer data);
+typedef void (*GDestroyNotify)(gpointer data);
+typedef enum
+{
+ GTK_FILE_CHOOSER_ACTION_OPEN,
+ GTK_FILE_CHOOSER_ACTION_SAVE,
+ GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
+ GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER
+} GtkFileChooserAction;
+#define GTK_STOCK_CANCEL "gtk-cancel"
+#define GTK_STOCK_SAVE "gtk-save"
+#define GTK_STOCK_OPEN "gtk-open"
+const int GTK_RESPONSE_NONE = -1;
+const int GTK_RESPONSE_ACCEPT = -3;
+const int GTK_RESPONSE_DELETE_EVENT = -4;
+const int GTK_RESPONSE_CANCEL = -6;
+typedef void (*GCallback)(void);
+#define G_CALLBACK(f) ((GCallback) (f))
+typedef int GConnectFlags;
+typedef struct _GClosure GClosure;
+typedef void (*GClosureNotify)(gpointer data, GClosure *closure);
+
+/* --------------------- End of Type definitions from GLIB and GTK --------------------- */
+
+int Fl_GTK_File_Chooser::did_find_GTK_libs = 0;
+
+/* These are the GTK/GLib methods we want to load, but not call by name...! */
+
+// void g_free (gpointer mem);
+typedef void (*XX_g_free)(gpointer);
+static XX_g_free fl_g_free = NULL;
+
+// gpointer g_slist_nth_data (GSList *list, guint n);
+typedef gpointer (*XX_g_slist_nth_data) (GSList *, guint);
+static XX_g_slist_nth_data fl_g_slist_nth_data = NULL;
+
+// guint g_slist_length (GSList *list);
+typedef guint (*XX_g_slist_length) (GSList *);
+static XX_g_slist_length fl_g_slist_length = NULL;
+
+// void g_slist_free (GSList *list);
+typedef void (*XX_g_slist_free) (GSList *);
+static XX_g_slist_free fl_g_slist_free = NULL;
+
+// gboolean gtk_init_check (int *argc, char ***argv);
+typedef gboolean (*XX_gtk_init_check)(int *, char ***);
+static XX_gtk_init_check fl_gtk_init_check = NULL;
+
+// void gtk_widget_destroy (GtkWidget *widget);
+typedef void (*XX_gtk_widget_destroy) (GtkWidget *);
+static XX_gtk_widget_destroy fl_gtk_widget_destroy = NULL;
+
+// void gtk_file_chooser_set_select_multiple(GtkFileChooser *chooser, gboolean select_multiple);
+typedef void (*XX_gtk_file_chooser_set_select_multiple)(GtkFileChooser *, gboolean);
+static XX_gtk_file_chooser_set_select_multiple fl_gtk_file_chooser_set_select_multiple = NULL;
+
+// void gtk_file_chooser_set_do_overwrite_confirmation(GtkFileChooser *chooser, gboolean do_overwrite_confirmation);
+typedef void (*XX_gtk_file_chooser_set_do_overwrite_confirmation)(GtkFileChooser *, gboolean);
+static XX_gtk_file_chooser_set_do_overwrite_confirmation fl_gtk_file_chooser_set_do_overwrite_confirmation = NULL;
+
+// void gtk_file_chooser_set_current_name (GtkFileChooser *chooser, const gchar *name);
+typedef void (*XX_gtk_file_chooser_set_current_name)(GtkFileChooser *, const gchar *);
+static XX_gtk_file_chooser_set_current_name fl_gtk_file_chooser_set_current_name = NULL;
+
+// void gtk_file_chooser_set_current_folder (GtkFileChooser *chooser, const gchar *name);
+typedef void (*XX_gtk_file_chooser_set_current_folder)(GtkFileChooser *, const gchar *);
+static XX_gtk_file_chooser_set_current_folder fl_gtk_file_chooser_set_current_folder = NULL;
+
+// void gtk_file_chooser_set_create_folders (GtkFileChooser *chooser, gboolean create_folders);
+typedef void (*XX_gtk_file_chooser_set_create_folders) (GtkFileChooser *, gboolean);
+static XX_gtk_file_chooser_set_create_folders fl_gtk_file_chooser_set_create_folders = NULL;
+
+// gboolean gtk_file_chooser_get_select_multiple(GtkFileChooser *chooser);
+typedef gboolean (*XX_gtk_file_chooser_get_select_multiple)(GtkFileChooser *);
+static XX_gtk_file_chooser_get_select_multiple fl_gtk_file_chooser_get_select_multiple = NULL;
+
+// void gtk_widget_hide(GtkWidget *widget);
+typedef void (*XX_gtk_widget_hide)(GtkWidget *);
+static XX_gtk_widget_hide fl_gtk_widget_hide = NULL;
+
+// gchar * gtk_file_chooser_get_filename(GtkFileChooser *chooser);
+typedef gchar* (*XX_gtk_file_chooser_get_filename)(GtkFileChooser *);
+static XX_gtk_file_chooser_get_filename fl_gtk_file_chooser_get_filename = NULL;
+
+// GSList * gtk_file_chooser_get_filenames(GtkFileChooser *chooser);
+typedef GSList* (*XX_gtk_file_chooser_get_filenames)(GtkFileChooser *chooser);
+static XX_gtk_file_chooser_get_filenames fl_gtk_file_chooser_get_filenames = NULL;
+
+// gboolean gtk_main_iteration(void);
+typedef gboolean (*XX_gtk_main_iteration)(void);
+static XX_gtk_main_iteration fl_gtk_main_iteration = NULL;
+
+// gboolean gtk_events_pending(void);
+typedef gboolean (*XX_gtk_events_pending)(void);
+static XX_gtk_events_pending fl_gtk_events_pending = NULL;
+
+// GtkWidget * gtk_file_chooser_dialog_new(const gchar *title, GtkWindow *parent, GtkFileChooserAction action, const gchar *first_button_text, ...);
+typedef GtkWidget* (*XX_gtk_file_chooser_dialog_new)(const gchar *, GtkWindow *, GtkFileChooserAction, const gchar *, ...);
+static XX_gtk_file_chooser_dialog_new fl_gtk_file_chooser_dialog_new = NULL;
+
+// void gtk_file_chooser_add_filter(GtkFileChooser*, GtkFileFilter*);
+typedef void (*XX_gtk_file_chooser_add_filter)(GtkFileChooser*, GtkFileFilter*);
+static XX_gtk_file_chooser_add_filter fl_gtk_file_chooser_add_filter = NULL;
+
+// GtkFileFilter* gtk_file_chooser_get_filter(GtkFileChooser*);
+typedef GtkFileFilter* (*XX_gtk_file_chooser_get_filter)(GtkFileChooser*);
+static XX_gtk_file_chooser_get_filter fl_gtk_file_chooser_get_filter = NULL;
+
+// void gtk_file_chooser_set_filter(GtkFileChooser*, GtkFileFilter*);
+typedef void (*XX_gtk_file_chooser_set_filter)(GtkFileChooser*, GtkFileFilter*);
+static XX_gtk_file_chooser_set_filter fl_gtk_file_chooser_set_filter = NULL;
+
+// GtkFileFilter * gtk_file_filter_new();
+typedef GtkFileFilter* (*XX_gtk_file_filter_new)(void);
+static XX_gtk_file_filter_new fl_gtk_file_filter_new = NULL;
+
+// void gtk_file_filter_add_pattern(GtkFileFilter*, const gchar*);
+typedef void (*XX_gtk_file_filter_add_pattern)(GtkFileFilter*, const gchar*);
+static XX_gtk_file_filter_add_pattern fl_gtk_file_filter_add_pattern = NULL;
+
+// void gtk_file_filter_add_custom(GtkFileFilter *filter, GtkFileFilterFlags needed,
+// GtkFileFilterFunc func, gpointer data, GDestroyNotify notify);
+typedef void (*XX_gtk_file_filter_add_custom)(GtkFileFilter *filter, GtkFileFilterFlags needed,
+ GtkFileFilterFunc func, gpointer data,
+ GDestroyNotify notify);
+static XX_gtk_file_filter_add_custom fl_gtk_file_filter_add_custom = NULL;
+
+// void gtk_file_filter_set_name(GtkFileFilter*, const gchar*);
+typedef void (*XX_gtk_file_filter_set_name)(GtkFileFilter*, const gchar*);
+static XX_gtk_file_filter_set_name fl_gtk_file_filter_set_name = NULL;
+
+// const gchar* gtk_file_filter_get_name(GtkFileFilter*);
+typedef const gchar* (*XX_gtk_file_filter_get_name)(GtkFileFilter*);
+static XX_gtk_file_filter_get_name fl_gtk_file_filter_get_name = NULL;
+
+// void gtk_file_chooser_set_extra_widget(GtkFileChooser *, GtkWidget *);
+typedef void (*XX_gtk_file_chooser_set_extra_widget)(GtkFileChooser *, GtkWidget *);
+static XX_gtk_file_chooser_set_extra_widget fl_gtk_file_chooser_set_extra_widget = NULL;
+
+// void gtk_widget_show_now(GtkWidget *);
+typedef void (*XX_gtk_widget_show_now)(GtkWidget *);
+static XX_gtk_widget_show_now fl_gtk_widget_show_now = NULL;
+
+// GdkWindow* gtk_widget_get_window(GtkWidget *);
+typedef GdkWindow* (*XX_gtk_widget_get_window)(GtkWidget *);
+static XX_gtk_widget_get_window fl_gtk_widget_get_window = NULL;
+
+// Window gdk_x11_drawable_get_xid(GdkWindow *);
+typedef Window (*XX_gdk_x11_drawable_get_xid)(GdkWindow *);
+static XX_gdk_x11_drawable_get_xid fl_gdk_x11_drawable_get_xid = NULL;
+
+// GtkWidget *gtk_check_button_new_with_label(const gchar *);
+typedef GtkWidget* (*XX_gtk_check_button_new_with_label)(const gchar *);
+static XX_gtk_check_button_new_with_label fl_gtk_check_button_new_with_label = NULL;
+
+// gulong g_signal_connect_data(gpointer, const gchar *, GCallback, gpointer, GClosureNotify, GConnectFlags);
+typedef gulong (*XX_g_signal_connect_data)(gpointer, const gchar *, GCallback, gpointer, GClosureNotify, GConnectFlags);
+static XX_g_signal_connect_data fl_g_signal_connect_data = NULL;
+
+// gboolean gtk_toggle_button_get_active(GtkToggleButton *);
+typedef gboolean (*XX_gtk_toggle_button_get_active)(GtkToggleButton*);
+static XX_gtk_toggle_button_get_active fl_gtk_toggle_button_get_active = NULL;
+
+// void gtk_file_chooser_set_show_hidden(GtkFileChooser *, gboolean);
+typedef void (*XX_gtk_file_chooser_set_show_hidden)(GtkFileChooser *, gboolean);
+static XX_gtk_file_chooser_set_show_hidden fl_gtk_file_chooser_set_show_hidden = NULL;
+
+// gboolean gtk_file_chooser_get_show_hidden(GtkFileChooser *);
+typedef gboolean (*XX_gtk_file_chooser_get_show_hidden)(GtkFileChooser *);
+static XX_gtk_file_chooser_get_show_hidden fl_gtk_file_chooser_get_show_hidden = NULL;
+
+// void gtk_toggle_button_set_active(GtkToggleButton *, gboolean);
+typedef void (*XX_gtk_toggle_button_set_active)(GtkToggleButton *, gboolean);
+static XX_gtk_toggle_button_set_active fl_gtk_toggle_button_set_active = NULL;
+
+
+Fl_GTK_File_Chooser::Fl_GTK_File_Chooser(int val) : Fl_FLTK_File_Chooser(-1)
+{
+ gtkw_ptr = NULL; // used to hold a GtkWidget*
+ gtkw_slist = NULL; // will hold the returned file names in a multi-selection...
+ gtkw_count = 0; // How many items were selected?
+ gtkw_filename = NULL; // holds the last name we read back in a single file selection...
+ gtkw_title = NULL; // dialog title
+ _btype = val;
+ previous_filter = NULL;
+}
+
+Fl_GTK_File_Chooser::~Fl_GTK_File_Chooser()
+{
+ // Should free up resources taken for...
+ if(gtkw_ptr) {
+ fl_gtk_widget_destroy (gtkw_ptr);
+ gtkw_ptr = NULL;
+ }
+ if(gtkw_filename) {
+ fl_g_free(gtkw_filename);
+ gtkw_filename = NULL;
+ }
+ if(gtkw_slist) {
+ GSList *iter = (GSList *)gtkw_slist;
+ while(iter) {
+ if(iter->data) fl_g_free(iter->data);
+ iter = g_slist_next(iter);
+ }
+ fl_g_slist_free((GSList *)gtkw_slist);
+ gtkw_slist = NULL;
+ }
+ gtkw_count = 0; // assume we have no files selected now
+ gtkw_title = strfree(gtkw_title);
+}
+
+void Fl_GTK_File_Chooser::type(int val) {
+ _btype = val;
+}
+
+int Fl_GTK_File_Chooser::count() const {
+ return gtkw_count;
+}
+
+const char *Fl_GTK_File_Chooser::filename() const
+{
+ if(gtkw_ptr) {
+ if(fl_gtk_file_chooser_get_select_multiple((GtkFileChooser *)gtkw_ptr) == FALSE) {
+ return gtkw_filename;
+ }
+ else {
+ GSList *iter = (GSList *)gtkw_slist;
+ char *nm = (char *)iter->data;
+ return nm;
+ }
+ }
+ return("");
+}
+
+const char *Fl_GTK_File_Chooser::filename(int i) const
+{
+ if(fl_gtk_file_chooser_get_select_multiple((GtkFileChooser *)gtkw_ptr) == FALSE) {
+ return gtkw_filename;
+ }
+ else {
+ if ((unsigned)i < gtkw_count) {
+ GSList *iter = (GSList *)gtkw_slist;
+ char *nm = (char *)fl_g_slist_nth_data(iter, i);
+ return nm;
+ }
+ }
+ return("");
+}
+
+void Fl_GTK_File_Chooser::title(const char *val)
+{
+ strfree(gtkw_title);
+ gtkw_title = strnew(val);
+}
+
+const char* Fl_GTK_File_Chooser::title() const
+{
+ return gtkw_title;
+}
+
+/* changes the extension of the outfile in the chooser according to newly selected filter */
+void Fl_GTK_File_Chooser::changed_output_type(const char *filter)
+{
+ if ( !(options()&Fl_Native_File_Chooser::USE_FILTER_EXT) ) return;
+ if (strchr(filter, '(') || strchr(filter, '{') || strchr(filter+1, '*') || strncmp(filter, "*.", 2)) return;
+ const char *p = fl_gtk_file_chooser_get_filename((GtkFileChooser*)gtkw_ptr);
+ if (!p) return;
+ p = fl_filename_name(p);
+ const char *q = strrchr(p, '.');
+ if (!q) q = p + strlen(p);
+ char *r = new char[strlen(p) + strlen(filter)];
+ strcpy(r, p);
+ strcpy(r + (q - p), filter + 1);
+ fl_gtk_file_chooser_set_current_name((GtkFileChooser*)gtkw_ptr, r);
+ delete[] r;
+}
+
+/* Filters files before display in chooser.
+ Also used to detect when the filter just changed */
+gboolean Fl_GTK_File_Chooser::custom_gtk_filter_function(const GtkFileFilterInfo *info, Fl_GTK_File_Chooser::pair* p)
+{
+ if (p->running->previous_filter != p->filter) {
+ p->running->changed_output_type(p->filter);
+ p->running->previous_filter = p->filter;
+ }
+ return (gboolean)fl_filename_match(info->filename, p->filter);
+}
+
+void Fl_GTK_File_Chooser::free_pair(Fl_GTK_File_Chooser::pair *p)
+{
+ delete p;
+}
+
+static void hidden_files_cb(GtkToggleButton *togglebutton, gpointer user_data)
+{
+ gboolean state = fl_gtk_toggle_button_get_active(togglebutton);
+ fl_gtk_file_chooser_set_show_hidden((GtkFileChooser*)user_data, state);
+}
+
+int Fl_GTK_File_Chooser::show()
+{
+ // The point here is that after running a GTK dialog, the calling program's current locale is modified.
+ // To avoid that, we memorize the calling program's current locale, and the locale as modified
+ // by GTK after the first dialog use. We restore the calling program's current locale
+ // before returning, and we set the locale as modified by GTK before subsequent GTK dialog uses.
+ static bool first = true;
+ char *p;
+ char *before = NULL;
+ static char *gtk_wants = NULL;
+ // record in before the calling program's current locale
+ p = setlocale(LC_ALL, NULL);
+ if (p) before = strdup(p);
+ if (gtk_wants) { // set the locale as GTK 'wants it'
+ setlocale(LC_ALL, gtk_wants);
+ }
+ int retval = fl_gtk_chooser_wrapper(); // may change the locale
+ if (first) {
+ first = false;
+ // record in gtk_wants the locale as modified by the GTK dialog
+ p = setlocale(LC_ALL, NULL);
+ if (p) gtk_wants = strdup(p);
+ }
+ if (before) {
+ setlocale(LC_ALL, before); // restore calling program's current locale
+ free(before);
+ }
+ return retval;
+}
+
+static char *extract_dir_from_path(const char *path)
+{
+ static char *dir = NULL;
+ if (fl_filename_isdir(path)) {
+ return (char*)path;
+ }
+ if (*path != '/') return NULL;
+ if (dir) free(dir);
+ dir = strdup(path);
+ do {
+ char *p = strrchr(dir, '/');
+ if (p == dir) p++;
+ *p = 0;
+ }
+ while (!fl_filename_isdir(dir));
+ return dir;
+}
+
+static void run_response_handler(GtkDialog *dialog, gint response_id, gpointer data)
+{
+ gint *ri = (gint *)data;
+ *ri = response_id;
+}
+
+
+int Fl_GTK_File_Chooser::fl_gtk_chooser_wrapper()
+{
+ int result = 1;
+ static int have_gtk_init = 0;
+ char *p;
+
+ if(!have_gtk_init) {
+ have_gtk_init = -1;
+ int ac = 0;
+ fl_gtk_init_check(&ac, NULL);
+ }
+
+ if(gtkw_ptr) { // discard the previous dialog widget
+ fl_gtk_widget_destroy (gtkw_ptr);
+ gtkw_ptr = NULL;
+ }
+
+ // set the dialog action type
+ GtkFileChooserAction gtw_action_type;
+ switch (_btype) {
+ case Fl_Native_File_Chooser::BROWSE_DIRECTORY:
+ case Fl_Native_File_Chooser::BROWSE_MULTI_DIRECTORY:
+ gtw_action_type = GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER;
+ break;
+
+ case Fl_Native_File_Chooser::BROWSE_SAVE_FILE:
+ gtw_action_type = GTK_FILE_CHOOSER_ACTION_SAVE;
+ break;
+
+ case Fl_Native_File_Chooser::BROWSE_SAVE_DIRECTORY:
+ gtw_action_type = GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER;
+ break;
+
+ case Fl_Native_File_Chooser::BROWSE_MULTI_FILE:
+ case Fl_Native_File_Chooser::BROWSE_FILE:
+ default:
+ gtw_action_type = GTK_FILE_CHOOSER_ACTION_OPEN;
+ break;
+ }
+ // create a new dialog
+ gtkw_ptr = fl_gtk_file_chooser_dialog_new (gtkw_title,
+ NULL, /* parent_window */
+ gtw_action_type,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ gtw_action_type == GTK_FILE_CHOOSER_ACTION_SAVE || gtw_action_type == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER ?
+ GTK_STOCK_SAVE : GTK_STOCK_OPEN,
+ GTK_RESPONSE_ACCEPT,
+ NULL);
+ // did we create a valid dialog widget?
+ if(!gtkw_ptr) {
+ // fail
+ return -1;
+ }
+
+ // set the dialog properties
+ switch (_btype) {
+ case Fl_Native_File_Chooser::BROWSE_MULTI_DIRECTORY:
+ case Fl_Native_File_Chooser::BROWSE_MULTI_FILE:
+ fl_gtk_file_chooser_set_select_multiple((GtkFileChooser *)gtkw_ptr, TRUE);
+ break;
+
+ case Fl_Native_File_Chooser::BROWSE_SAVE_FILE:
+ if (_preset_file)fl_gtk_file_chooser_set_current_name ((GtkFileChooser *)gtkw_ptr, fl_filename_name(_preset_file));
+ /* FALLTHROUGH */
+ case Fl_Native_File_Chooser::BROWSE_SAVE_DIRECTORY:
+ fl_gtk_file_chooser_set_create_folders((GtkFileChooser *)gtkw_ptr, TRUE);
+ fl_gtk_file_chooser_set_do_overwrite_confirmation ((GtkFileChooser *)gtkw_ptr, (_options & Fl_Native_File_Chooser::SAVEAS_CONFIRM)?TRUE:FALSE);
+ break;
+
+ case Fl_Native_File_Chooser::BROWSE_DIRECTORY:
+ case Fl_Native_File_Chooser::BROWSE_FILE:
+ default:
+ break;
+ }
+
+ if (_directory && _directory[0]) {
+ p = extract_dir_from_path(_directory);
+ if (p) fl_gtk_file_chooser_set_current_folder((GtkFileChooser *)gtkw_ptr, p);
+ }
+ else if (_preset_file) {
+ p = extract_dir_from_path(_preset_file);
+ if (p) fl_gtk_file_chooser_set_current_folder((GtkFileChooser *)gtkw_ptr, p);
+ }
+
+ GtkFileFilter **filter_tab = NULL;
+ if (_parsedfilt) {
+ filter_tab = new GtkFileFilter*[_nfilters];
+ char *filter = strdup(_parsedfilt);
+ p = strtok(filter, "\t");
+ int count = 0;
+ while (p) {
+ filter_tab[count] = fl_gtk_file_filter_new();
+ fl_gtk_file_filter_set_name(filter_tab[count], p);
+ p = strchr(p, '(') + 1;
+ char *q = strchr(p, ')'); *q = 0;
+ fl_gtk_file_filter_add_custom(filter_tab[count],
+ GTK_FILE_FILTER_FILENAME,
+ (GtkFileFilterFunc)Fl_GTK_File_Chooser::custom_gtk_filter_function,
+ new Fl_GTK_File_Chooser::pair(this, p),
+ (GDestroyNotify)Fl_GTK_File_Chooser::free_pair);
+ fl_gtk_file_chooser_add_filter((GtkFileChooser *)gtkw_ptr, filter_tab[count]);
+ p = strtok(NULL, "\t");
+ count++;
+ }
+ free(filter);
+ fl_gtk_file_chooser_set_filter((GtkFileChooser *)gtkw_ptr, filter_tab[_filtvalue < _nfilters?_filtvalue:0]);
+ previous_filter = NULL;
+ if (gtw_action_type == GTK_FILE_CHOOSER_ACTION_OPEN) {
+ GtkFileFilter* gfilter = fl_gtk_file_filter_new();
+ fl_gtk_file_filter_set_name(gfilter, Fl_File_Chooser::all_files_label);
+ fl_gtk_file_filter_add_pattern(gfilter, "*");
+ fl_gtk_file_chooser_add_filter((GtkFileChooser *)gtkw_ptr, gfilter);
+ }
+ }
+
+ GtkWidget *toggle = fl_gtk_check_button_new_with_label(Fl_File_Chooser::hidden_label);
+ fl_gtk_file_chooser_set_extra_widget((GtkFileChooser *)gtkw_ptr, toggle);
+ fl_g_signal_connect_data(toggle, "toggled", G_CALLBACK(hidden_files_cb), gtkw_ptr, NULL, (GConnectFlags) 0);
+ Fl_Window* firstw = Fl::first_window();
+ fl_gtk_widget_show_now(gtkw_ptr); // map the GTK window on screen
+ if (firstw) {
+ GdkWindow* gdkw = fl_gtk_widget_get_window(gtkw_ptr);
+ Window xw = fl_gdk_x11_drawable_get_xid(gdkw); // get the X11 ref of the GTK window
+ XSetTransientForHint(fl_display, xw, fl_xid(firstw)); // set the GTK window transient for the last FLTK win
+ }
+ gboolean state = fl_gtk_file_chooser_get_show_hidden((GtkFileChooser *)gtkw_ptr);
+ fl_gtk_toggle_button_set_active((GtkToggleButton *)toggle, state);
+
+ gint response_id = GTK_RESPONSE_NONE;
+ fl_g_signal_connect_data(gtkw_ptr, "response", G_CALLBACK(run_response_handler), &response_id, NULL, (GConnectFlags) 0);
+ while (response_id == GTK_RESPONSE_NONE) { // loop that shows the GTK dialog window
+ fl_gtk_main_iteration(); // one iteration of the GTK event loop
+ while (XEventsQueued(fl_display, QueuedAfterReading)) { // emulate modal dialog
+ XEvent xevent;
+ XNextEvent(fl_display, &xevent);
+ Window xid = xevent.xany.window;
+ if (xevent.type == ConfigureNotify) xid = xevent.xmaprequest.window;
+ if (!fl_find(xid)) continue; // skip events to non-FLTK windows
+ // process Expose and ConfigureNotify events
+ if ( xevent.type == Expose || xevent.type == ConfigureNotify ) fl_handle(xevent);
+ }
+ Fl::flush(); // do the drawings needed after Expose events
+ }
+
+ if (response_id == GTK_RESPONSE_ACCEPT) {
+ if (_parsedfilt) {
+ GtkFileFilter *gfilter = fl_gtk_file_chooser_get_filter((GtkFileChooser *)gtkw_ptr);
+ for (_filtvalue = 0; _filtvalue < _nfilters; _filtvalue++) {
+ if (filter_tab[_filtvalue] == gfilter) break;
+ }
+ }
+
+ // discard any filenames or lists from previous calls
+ if(gtkw_filename) {
+ fl_g_free(gtkw_filename);
+ gtkw_filename = NULL;
+ }
+ if(gtkw_slist) {
+ GSList *iter = (GSList *)gtkw_slist;
+ while(iter) {
+ if(iter->data) fl_g_free(iter->data);
+ iter = g_slist_next(iter);
+ }
+ fl_g_slist_free((GSList *)gtkw_slist);
+ gtkw_slist = NULL;
+ }
+ gtkw_count = 0; // assume we have no files selected now
+
+ if(fl_gtk_file_chooser_get_select_multiple((GtkFileChooser *)gtkw_ptr) == FALSE) {
+ gtkw_filename = fl_gtk_file_chooser_get_filename ((GtkFileChooser *)gtkw_ptr);
+ if (gtkw_filename) {
+ gtkw_count = 1;
+ result = 0;
+ //printf("single: %s\n", gtkw_filename);
+ }
+ }
+ else {
+ gtkw_slist = fl_gtk_file_chooser_get_filenames((GtkFileChooser *)gtkw_ptr);
+ gtkw_count = fl_g_slist_length((GSList *)gtkw_slist);
+ if(gtkw_count) result = 0;
+
+ // puts("multiple");
+ // GSList *iter = (GSList *)gtkw_slist;
+ // printf ("Selected %d files\n", gtkw_count);
+ // while(iter) {
+ // char *nm = (char *)iter->data;
+ // printf("%s\n", nm);
+ // iter = g_slist_next(iter);
+ // }
+ }
+ }
+ delete[] filter_tab;
+ if ( response_id == GTK_RESPONSE_DELETE_EVENT) gtkw_ptr = NULL;
+ else fl_gtk_widget_hide (gtkw_ptr);
+
+ // I think this is analogus to doing an Fl::check() - we need this here to make sure
+ // the GtkFileChooserDialog is removed from the display correctly
+ while (fl_gtk_events_pending ()) fl_gtk_main_iteration ();
+
+ return result;
+} // fl_gtk_chooser_wrapper
+
+#if HAVE_DLSYM && HAVE_DLFCN_H
+// macro to help with the symbol loading boilerplate...
+# define GET_SYM(SSS, LLL) \
+dlerror(); /* Clear any existing error */ \
+fl_##SSS = (XX_##SSS)dlsym(LLL, #SSS); \
+if ((pc_dl_error = dlerror()) != NULL) { \
+fprintf(stderr, "%s\n", pc_dl_error); \
+did_find_GTK_libs = 0; \
+return; }
+
+static void* fl_dlopen(const char *filename1, const char *filename2)
+{
+ void *ptr = dlopen(filename1, RTLD_LAZY | RTLD_GLOBAL);
+ if (!ptr) ptr = dlopen(filename2, RTLD_LAZY | RTLD_GLOBAL);
+ return ptr;
+}
+#endif
+
+/*
+ * Use dlopen to see if we can load the gtk dynamic libraries that
+ * will allow us to create a GtkFileChooserDialog() on the fly,
+ * without linking to the GTK libs at compile time.
+ */
+void Fl_GTK_File_Chooser::probe_for_GTK_libs(void) {
+#if HAVE_DLSYM && HAVE_DLFCN_H
+ void *ptr_glib = NULL;
+ void *ptr_gtk = NULL;
+
+# ifdef __APPLE_CC__ // allows testing on Darwin + X11
+ ptr_glib = dlopen("/sw/lib/libglib-2.0.dylib", RTLD_LAZY | RTLD_GLOBAL);
+# else
+ ptr_glib = fl_dlopen("libglib-2.0.so", "libglib-2.0.so.0");
+# endif
+ // Try first with GTK2
+# ifdef __APPLE_CC__ // allows testing on Darwin + X11
+ ptr_gtk = dlopen("/sw/lib/libgtk-x11-2.0.dylib", RTLD_LAZY | RTLD_GLOBAL);
+#else
+ ptr_gtk = fl_dlopen("libgtk-x11-2.0.so", "libgtk-x11-2.0.so.0");
+#endif
+ if (ptr_gtk && ptr_glib) {
+#ifdef DEBUG
+ puts("selected GTK-2\n");
+#endif
+ }
+ else {// Try then with GTK3
+ ptr_gtk = fl_dlopen("libgtk-3.so", "libgtk-3.so.0");
+#ifdef DEBUG
+ if (ptr_gtk && ptr_glib) {
+ puts("selected GTK-3\n");
+ }
+#endif
+ }
+
+ if((!ptr_glib) || (!ptr_gtk)) {
+#ifdef DEBUG
+ puts("Failure to load libglib or libgtk");
+#endif
+ did_find_GTK_libs = 0;
+ return;
+ }
+
+ char *pc_dl_error; // used to report errors by the GET_SYM macro...
+ // items we need from GLib
+ GET_SYM(g_free, ptr_glib);
+ GET_SYM(g_slist_nth_data, ptr_glib);
+ GET_SYM(g_slist_length, ptr_glib);
+ GET_SYM(g_slist_free, ptr_glib);
+ // items we need from GTK
+ GET_SYM(gtk_init_check, ptr_gtk);
+ GET_SYM(gtk_widget_destroy, ptr_gtk);
+ GET_SYM(gtk_file_chooser_set_select_multiple, ptr_gtk);
+ GET_SYM(gtk_file_chooser_set_do_overwrite_confirmation, ptr_gtk);
+ GET_SYM(gtk_file_chooser_set_current_name, ptr_gtk);
+ GET_SYM(gtk_file_chooser_set_current_folder, ptr_gtk);
+ GET_SYM(gtk_file_chooser_set_create_folders, ptr_gtk);
+ GET_SYM(gtk_file_chooser_get_select_multiple, ptr_gtk);
+ GET_SYM(gtk_widget_hide, ptr_gtk);
+ GET_SYM(gtk_file_chooser_get_filename, ptr_gtk);
+ GET_SYM(gtk_file_chooser_get_filenames, ptr_gtk);
+ GET_SYM(gtk_main_iteration, ptr_gtk);
+ GET_SYM(gtk_events_pending, ptr_gtk);
+ GET_SYM(gtk_file_chooser_dialog_new, ptr_gtk);
+ GET_SYM(gtk_file_chooser_add_filter, ptr_gtk);
+ GET_SYM(gtk_file_chooser_get_filter, ptr_gtk);
+ GET_SYM(gtk_file_chooser_set_filter, ptr_gtk);
+ GET_SYM(gtk_file_filter_new, ptr_gtk);
+ GET_SYM(gtk_file_filter_add_pattern, ptr_gtk);
+ GET_SYM(gtk_file_filter_add_custom, ptr_gtk);
+ GET_SYM(gtk_file_filter_set_name, ptr_gtk);
+ GET_SYM(gtk_file_filter_get_name, ptr_gtk);
+ GET_SYM(gtk_file_chooser_set_extra_widget, ptr_gtk);
+ GET_SYM(gtk_widget_show_now, ptr_gtk);
+ GET_SYM(gtk_widget_get_window, ptr_gtk);
+ GET_SYM(gdk_x11_drawable_get_xid, ptr_gtk);
+ GET_SYM(gtk_check_button_new_with_label, ptr_gtk);
+ GET_SYM(g_signal_connect_data, ptr_gtk);
+ GET_SYM(gtk_toggle_button_get_active, ptr_gtk);
+ GET_SYM(gtk_file_chooser_set_show_hidden, ptr_gtk);
+ GET_SYM(gtk_file_chooser_get_show_hidden, ptr_gtk);
+ GET_SYM(gtk_toggle_button_set_active, ptr_gtk);
+
+ did_find_GTK_libs = 1;
+#endif
+} // probe_for_GTK_libs
+
+//
+// End of "$Id$".
+//
diff --git a/src/Fl_Native_File_Chooser_MAC.mm b/src/Fl_Native_File_Chooser_MAC.mm
index 6fc9c82..518ae02 100644
--- a/src/Fl_Native_File_Chooser_MAC.mm
+++ b/src/Fl_Native_File_Chooser_MAC.mm
@@ -1,4 +1,4 @@
-// "$Id: Fl_Native_File_Chooser_MAC.mm 9685 2012-09-27 12:49:39Z manolo $"
+// "$Id: Fl_Native_File_Chooser_MAC.mm 10317 2014-09-16 17:34:29Z manolo $"
//
// FLTK native OS file chooser widget
//
@@ -344,8 +344,7 @@ int Fl_Native_File_Chooser::filters() const {
int Fl_Native_File_Chooser::get_saveas_basename(void) {
char *q = strdup( [[[(NSSavePanel*)_panel URL] path] UTF8String] );
- id delegate = [(NSSavePanel*)_panel delegate];
- if (delegate != nil) {
+ if ( !(_options & SAVEAS_CONFIRM) ) {
const char *d = [[[[(NSSavePanel*)_panel URL] path] stringByDeletingLastPathComponent] UTF8String];
int l = strlen(d) + 1;
if (strcmp(d, "/") == 0) l = 1;
@@ -412,6 +411,7 @@ static char *prepareMacFilter(int count, const char *filter, char **patterns) {
}
- (FLopenDelegate*)setPopup:(NSPopUpButton*)popup filter_pattern:(char**)pattern;
- (BOOL)panel:(id)sender shouldShowFilename:(NSString *)filename;
+- (BOOL)panel:(id)sender shouldEnableURL:(NSURL *)url;
@end
@implementation FLopenDelegate
- (FLopenDelegate*)setPopup:(NSPopUpButton*)popup filter_pattern:(char**)pattern
@@ -423,11 +423,16 @@ static char *prepareMacFilter(int count, const char *filter, char **patterns) {
- (BOOL)panel:(id)sender shouldShowFilename:(NSString *)filename
{
if ( [nspopup indexOfSelectedItem] == [nspopup numberOfItems] - 1) return YES;
- const char *pathname = [filename fileSystemRepresentation];
- if ( fl_filename_isdir(pathname) ) return YES;
- if ( fl_filename_match(pathname, filter_pattern[ [nspopup indexOfSelectedItem] ]) ) return YES;
+ BOOL isdir = NO;
+ [[NSFileManager defaultManager] fileExistsAtPath:filename isDirectory:&isdir];
+ if (isdir) return YES;
+ if ( fl_filename_match([filename fileSystemRepresentation], filter_pattern[ [nspopup indexOfSelectedItem] ]) ) return YES;
return NO;
}
+- (BOOL)panel:(id)sender shouldEnableURL:(NSURL *)url
+{
+ return [self panel:sender shouldShowFilename:[url path]];
+}
@end
@interface FLsaveDelegate : NSObject
@@ -435,17 +440,53 @@ static char *prepareMacFilter(int count, const char *filter, char **patterns) {
<NSOpenSavePanelDelegate>
#endif
{
+ NSSavePanel *dialog;
+ BOOL saveas_confirm;
}
- (NSString *)panel:(id)sender userEnteredFilename:(NSString *)filename confirmed:(BOOL)okFlag;
+- (void)changedPopup:(id)sender;
+- (void)panel:(NSSavePanel*)p;
+- (void)option:(BOOL)o;
@end
@implementation FLsaveDelegate
- (NSString *)panel:(id)sender userEnteredFilename:(NSString *)filename confirmed:(BOOL)okFlag
{
- if (! okFlag) return filename;
+ if ( !okFlag || saveas_confirm ) return filename;
// User has clicked save, and no overwrite confirmation should occur.
// To get the latter, we need to change the name we return (hence the prefix):
return [@ UNLIKELYPREFIX stringByAppendingString:filename];
}
+- (void)changedPopup:(id)sender
+// runs when the save panel popup menu changes output file type
+// correspondingly changes the extension of the output file name
+{
+ if (fl_mac_os_version < 100600) return; // because of setNameFieldStringValue and nameFieldStringValue
+ char *s = strdup([[(NSPopUpButton*)sender titleOfSelectedItem] UTF8String]);
+ if (!s) return;
+ char *p = strchr(s, '(');
+ if (!p) p = s;
+ p = strchr(p, '.');
+ if (!p) {free(s); return;}
+ p++;
+ while (*p == ' ') p++;
+ if (!p || *p == '{') {free(s); return;}
+ char *q = p+1;
+ while (*q != ' ' && *q != ')' && *q != 0) q++;
+ *q = 0;
+ NSString *ns = [NSString stringWithFormat:@"%@.%@",
+ [[dialog performSelector:@selector(nameFieldStringValue)] stringByDeletingPathExtension],
+ [NSString stringWithUTF8String:p]];
+ free(s);
+ [dialog performSelector:@selector(setNameFieldStringValue:) withObject:ns];
+}
+- (void)panel:(NSSavePanel*)p
+{
+ dialog = p;
+}
+- (void) option:(BOOL)o
+{
+ saveas_confirm = o;
+}
@end
static NSPopUpButton *createPopupAccessory(NSSavePanel *panel, const char *filter, const char *title, int rank)
@@ -501,8 +542,8 @@ int Fl_Native_File_Chooser::runmodal()
}
if (_directory && !dir) dir = [[NSString alloc] initWithUTF8String:_directory];
if (fl_mac_os_version >= 100600) {
- if (dir) [(NSSavePanel*)_panel setDirectoryURL:[NSURL fileURLWithPath:dir]];
- if (fname) [(NSSavePanel*)_panel setNameFieldStringValue:fname];
+ if (dir) [(NSSavePanel*)_panel performSelector:@selector(setDirectoryURL:) withObject:[NSURL fileURLWithPath:dir]];
+ if (fname) [(NSSavePanel*)_panel performSelector:@selector(setNameFieldStringValue:) withObject:fname];
retval = [(NSSavePanel*)_panel runModal];
}
else {
@@ -541,7 +582,6 @@ int Fl_Native_File_Chooser::post() {
_panel = [NSSavePanel savePanel];
break;
}
- int retval;
NSString *nstitle = [NSString stringWithUTF8String: (_title ? _title : "No Title")];
[(NSSavePanel*)_panel setTitle:nstitle];
switch (_btype) {
@@ -561,8 +601,9 @@ int Fl_Native_File_Chooser::post() {
// SHOW THE DIALOG
NSWindow *key = [NSApp keyWindow];
- if ( [(NSSavePanel*)_panel isKindOfClass:[NSOpenPanel class]] ) {
- NSPopUpButton *popup = nil;
+ BOOL is_open_panel = [(NSSavePanel*)_panel isKindOfClass:[NSOpenPanel class]];
+ NSPopUpButton *popup = nil;
+ if ( is_open_panel ) {
if (_filt_total) {
char *t = prepareMacFilter(_filt_total, _filter, _filt_patt);
popup = createPopupAccessory((NSSavePanel*)_panel, t, Fl_File_Chooser::show_label, 0);
@@ -571,47 +612,44 @@ int Fl_Native_File_Chooser::post() {
[popup addItemWithTitle:[[NSString alloc] initWithUTF8String:Fl_File_Chooser::all_files_label]];
[popup setAction:@selector(validateVisibleColumns)];
[popup setTarget:(NSObject*)_panel];
- static FLopenDelegate *openDelegate = nil;
- if (openDelegate == nil) {
- // not to be ever freed
- openDelegate = [[FLopenDelegate alloc] init];
- }
+ FLopenDelegate *openDelegate = [[[FLopenDelegate alloc] init] autorelease];
[openDelegate setPopup:popup filter_pattern:_filt_patt];
[(NSOpenPanel*)_panel setDelegate:openDelegate];
}
- retval = runmodal();
- if (_filt_total) {
- _filt_value = [popup indexOfSelectedItem];
- }
- if ( retval == NSOKButton ) {
- clear_pathnames();
- NSArray *array = [(NSOpenPanel*)_panel URLs];
- _tpathnames = [array count];
- _pathnames = new char*[_tpathnames];
- for(int i = 0; i < _tpathnames; i++) {
- _pathnames[i] = strnew([[(NSURL*)[array objectAtIndex:i] path] UTF8String]);
- }
- }
}
else {
- NSPopUpButton *popup = nil;
+ FLsaveDelegate *saveDelegate = [[[FLsaveDelegate alloc] init] autorelease];
[(NSSavePanel*)_panel setAllowsOtherFileTypes:YES];
- if ( !(_options & SAVEAS_CONFIRM) ) {
- static FLsaveDelegate *saveDelegate = nil;
- if (saveDelegate == nil)saveDelegate = [[FLsaveDelegate alloc] init]; // not to be ever freed
- [(NSSavePanel*)_panel setDelegate:saveDelegate];
- }
+ [(NSSavePanel*)_panel setDelegate:saveDelegate];
+ [saveDelegate option:(_options & SAVEAS_CONFIRM)];
if (_filt_total) {
if (_filt_value >= _filt_total) _filt_value = _filt_total - 1;
char *t = prepareMacFilter(_filt_total, _filter, _filt_patt);
popup = createPopupAccessory((NSSavePanel*)_panel, t, [[(NSSavePanel*)_panel nameFieldLabel] UTF8String], _filt_value);
delete[] t;
+ if (_options & USE_FILTER_EXT) {
+ [popup setAction:@selector(changedPopup:)];
+ [popup setTarget:saveDelegate];
+ [saveDelegate panel:(NSSavePanel*)_panel];
+ }
+ [(NSSavePanel*)_panel setCanSelectHiddenExtension:YES];
}
- retval = runmodal();
- if (_filt_total) {
- _filt_value = [popup indexOfSelectedItem];
+ }
+ int retval = runmodal();
+ if (_filt_total) {
+ _filt_value = [popup indexOfSelectedItem];
+ }
+ if ( retval == NSOKButton ) {
+ if (is_open_panel) {
+ clear_pathnames();
+ NSArray *array = [(NSOpenPanel*)_panel URLs];
+ _tpathnames = [array count];
+ _pathnames = new char*[_tpathnames];
+ for(int i = 0; i < _tpathnames; i++) {
+ _pathnames[i] = strnew([[(NSURL*)[array objectAtIndex:i] path] UTF8String]);
+ }
}
- if ( retval == NSOKButton ) get_saveas_basename();
+ else get_saveas_basename();
}
[key makeKeyWindow];
[localPool release];
@@ -621,5 +659,5 @@ int Fl_Native_File_Chooser::post() {
#endif // __APPLE__
//
-// End of "$Id: Fl_Native_File_Chooser_MAC.mm 9685 2012-09-27 12:49:39Z manolo $".
+// End of "$Id: Fl_Native_File_Chooser_MAC.mm 10317 2014-09-16 17:34:29Z manolo $".
//
diff --git a/src/Fl_Native_File_Chooser_WIN32.cxx b/src/Fl_Native_File_Chooser_WIN32.cxx
index 0c8e0a9..094ea9f 100644
--- a/src/Fl_Native_File_Chooser_WIN32.cxx
+++ b/src/Fl_Native_File_Chooser_WIN32.cxx
@@ -1,4 +1,4 @@
-// "$Id: Fl_Native_File_Chooser_WIN32.cxx 9629 2012-06-26 07:03:46Z greg.ercolano $"
+// "$Id: Fl_Native_File_Chooser_WIN32.cxx 10312 2014-09-15 09:35:05Z ossman $"
//
// FLTK native OS file chooser widget
//
@@ -34,14 +34,12 @@ LPCWSTR utf8towchar(const char *in); //MG
char *wchartoutf8(LPCWSTR in); //MG
#include <FL/Fl_Native_File_Chooser.H>
+#include <FL/x.H>
#define LCURLY_CHR '{'
#define RCURLY_CHR '}'
#define LBRACKET_CHR '['
#define RBRACKET_CHR ']'
-#define MAXFILTERS 80
-
-void fl_OleInitialize(); // in Fl.cxx (Windows only)
// STATIC: PRINT WINDOWS 'DOUBLE NULL' STRING (DEBUG)
#ifdef DEBUG
@@ -54,7 +52,7 @@ static void dnullprint(char *wp) {
return;
} else if ( wp[t] == '\0' ) {
printf("\\0");
- } else {
+ } else {
printf("%c",wp[t]);
}
}
@@ -96,7 +94,7 @@ static void dnullcat(char*&wp, const char *string, int n = -1 ) {
// Make copy of wp into larger buffer
char *tmp = new char[wplen + inlen + 4];
memcpy(tmp, wp, wplen+2); // copy of wp plus doublenull
- delete [] wp; // delete old wp
+ delete[] wp; // delete old wp
wp = tmp; // use new copy
//DEBUG printf("DEBUG: dnullcat COPY: <"); dnullprint(wp); printf("> (wplen=%d)\n", wplen);
}
@@ -191,7 +189,7 @@ void Fl_Native_File_Chooser::clear_pathnames() {
while ( --_tpathnames >= 0 ) {
_pathnames[_tpathnames] = strfree(_pathnames[_tpathnames]);
}
- delete [] _pathnames;
+ delete[] _pathnames;
_pathnames = NULL;
}
_tpathnames = 0;
@@ -214,9 +212,9 @@ void Fl_Native_File_Chooser::add_pathname(const char *s) {
} else {
// Grow array by 1
char **tmp = new char*[_tpathnames+1]; // create new buffer
- memcpy((void*)tmp, (void*)_pathnames,
+ memcpy((void*)tmp, (void*)_pathnames,
sizeof(char*)*_tpathnames); // copy old
- delete [] _pathnames; // delete old
+ delete[] _pathnames; // delete old
_pathnames = tmp; // use new
++_tpathnames;
}
@@ -237,11 +235,11 @@ void Fl_Native_File_Chooser::FreePIDL(LPITEMIDLIST pidl) {
void Fl_Native_File_Chooser::ClearOFN() {
// Free any previously allocated lpstrFile before zeroing out _ofn
if ( _ofn.lpstrFile ) {
- delete [] _ofn.lpstrFile;
+ delete[] _ofn.lpstrFile;
_ofn.lpstrFile = NULL;
}
if ( _ofn.lpstrInitialDir ) {
- delete [] (TCHAR*) _ofn.lpstrInitialDir; //msvc6 compilation fix
+ delete[] (TCHAR*) _ofn.lpstrInitialDir; //msvc6 compilation fix
_ofn.lpstrInitialDir = NULL;
}
_ofn.lpstrFilter = NULL; // (deleted elsewhere)
@@ -364,7 +362,7 @@ int Fl_Native_File_Chooser::showfile() {
char *oldcwd = 0;
DWORD oldcwdsz = GetCurrentDirectory(0,0);
if ( oldcwdsz > 0 ) {
- oldcwd = (char*)malloc(oldcwdsz);
+ oldcwd = (char*)malloc(oldcwdsz);
if (GetCurrentDirectory(oldcwdsz, oldcwd) == 0 ) {
free(oldcwd); oldcwd = 0;
}
@@ -376,30 +374,25 @@ int Fl_Native_File_Chooser::showfile() {
} else {
err = GetOpenFileNameW(&_ofn);
}
+ // GET EXTENDED ERROR
+ int exterr = CommDlgExtendedError();
+ // XXX: RESTORE CWD
+ if ( oldcwd ) {
+ SetCurrentDirectory(oldcwd);
+ free(oldcwd); oldcwd = 0;
+ }
+ // ERROR OR CANCEL?
if ( err == 0 ) {
- // EXTENDED ERROR CHECK
- int err = CommDlgExtendedError();
- // CANCEL?
- if ( err == 0 ) return(1); // user hit 'cancel'
- // AN ERROR OCCURRED
+ if ( exterr == 0 ) return(1); // user hit cancel
+ // Otherwise, an error occurred..
char msg[80];
sprintf(msg, "CommDlgExtendedError() code=%d", err);
errmsg(msg);
- // XXX: RESTORE CWD
- if ( oldcwd ) {
- SetCurrentDirectory(oldcwd);
- free(oldcwd); oldcwd = 0;
- }
return(-1);
}
- // XXX: RESTORE CWD
- if ( oldcwd ) {
- SetCurrentDirectory(oldcwd);
- free(oldcwd); oldcwd = 0;
- }
// PREPARE PATHNAMES FOR RETURN
switch ( _btype ) {
- case BROWSE_FILE:
+ case BROWSE_FILE:
case BROWSE_SAVE_FILE:
set_single_pathname(wchartoutf8(_ofn.lpstrFile));
// Win2Unix(_pathnames[_tpathnames-1]);
@@ -412,8 +405,8 @@ int Fl_Native_File_Chooser::showfile() {
// WALK STRING SEARCHING FOR 'DOUBLE-NULL'
// eg. "/dir/name\0foo1\0foo2\0foo3\0\0"
//
- char pathname[FNFC_MAX_PATH];
- for ( const WCHAR *s = dirname + dirlen + 1;
+ char pathname[FNFC_MAX_PATH];
+ for ( const WCHAR *s = dirname + dirlen + 1;
*s; s+= (wcslen(s)+1)) {
strcpy(pathname, wchartoutf8(dirname));
strcat(pathname, "\\");
@@ -427,7 +420,7 @@ int Fl_Native_File_Chooser::showfile() {
// not to grok forward slashes, passing back as a 'filename'..!
//
if ( _tpathnames == 0 ) {
- add_pathname(wchartoutf8(dirname));
+ add_pathname(wchartoutf8(dirname));
// Win2Unix(_pathnames[_tpathnames-1]);
}
break;
@@ -447,7 +440,7 @@ int Fl_Native_File_Chooser::showfile() {
int CALLBACK Fl_Native_File_Chooser::Dir_CB(HWND win, UINT msg, LPARAM param, LPARAM data) {
switch (msg) {
case BFFM_INITIALIZED:
- if (data) ::SendMessage(win, BFFM_SETSELECTION, TRUE, data);
+ if (data) ::SendMessageW(win, BFFM_SETSELECTIONW, TRUE, data);
break;
case BFFM_SELCHANGED:
TCHAR path[FNFC_MAX_PATH];
@@ -459,7 +452,7 @@ int CALLBACK Fl_Native_File_Chooser::Dir_CB(HWND win, UINT msg, LPARAM param, LP
}
break;
case BFFM_VALIDATEFAILED:
- // we could pop up an annoying message here.
+ // we could pop up an annoying message here.
// also needs set ulFlags |= BIF_VALIDATE
break;
default:
@@ -471,13 +464,22 @@ int CALLBACK Fl_Native_File_Chooser::Dir_CB(HWND win, UINT msg, LPARAM param, LP
// SHOW DIRECTORY BROWSER
int Fl_Native_File_Chooser::showdir() {
// initialize OLE only once
- fl_OleInitialize(); // init needed by BIF_USENEWUI
+ fl_open_display(); // init needed by BIF_USENEWUI
ClearBINF();
clear_pathnames();
// PARENT WINDOW
_binf.hwndOwner = GetForegroundWindow();
// DIALOG TITLE
- _binf.lpszTitle = _title ? _title : NULL;
+ //_binf.lpszTitle = _title ? _title : NULL;
+ if (_title) {
+ static WCHAR wtitle[256];
+ wcsncpy(wtitle, utf8towchar(_title), 256);
+ wtitle[255] = 0;
+ _binf.lpszTitle = wtitle;
+ } else {
+ _binf.lpszTitle = NULL;
+ }
+
// FLAGS
_binf.ulFlags = 0; // initialize
@@ -510,19 +512,22 @@ int Fl_Native_File_Chooser::showdir() {
#endif
// BUFFER
- char displayname[FNFC_MAX_PATH];
+ //char displayname[FNFC_MAX_PATH];
+ WCHAR displayname[FNFC_MAX_PATH];
_binf.pszDisplayName = displayname;
+
// PRESET DIR
- char presetname[FNFC_MAX_PATH];
+ WCHAR presetname[FNFC_MAX_PATH];
if ( _directory ) {
- strcpy(presetname, _directory);
// Unix2Win(presetname);
+ wcsncpy(presetname, utf8towchar(_directory), FNFC_MAX_PATH);
+ presetname[FNFC_MAX_PATH-1] = 0;
_binf.lParam = (LPARAM)presetname;
}
else _binf.lParam = 0;
_binf.lpfn = Dir_CB;
// OPEN BROWSER
- LPITEMIDLIST pidl = SHBrowseForFolder(&_binf);
+ LPITEMIDLIST pidl = SHBrowseForFolderW(&_binf);
// CANCEL?
if ( pidl == NULL ) return(1);
@@ -530,13 +535,14 @@ int Fl_Native_File_Chooser::showdir() {
// TBD: expand NetHood shortcuts from this PIDL??
// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/shell/reference/functions/shbrowseforfolder.asp
- TCHAR path[FNFC_MAX_PATH];
- if ( SHGetPathFromIDList(pidl, path) ) {
+ WCHAR path[FNFC_MAX_PATH];
+ if ( SHGetPathFromIDListW(pidl, path) ) {
// Win2Unix(path);
- add_pathname(path);
+ //add_pathname(path);
+ add_pathname(wchartoutf8(path));
}
FreePIDL(pidl);
- if ( !strlen(path) ) return(1); // don't return empty pathnames
+ if ( !wcslen(path) ) return(1); // don't return empty pathnames
return(0);
}
@@ -546,8 +552,8 @@ int Fl_Native_File_Chooser::showdir() {
// -1 - failed; errmsg() has reason
//
int Fl_Native_File_Chooser::show() {
- if ( _btype == BROWSE_DIRECTORY ||
- _btype == BROWSE_MULTI_DIRECTORY ||
+ if ( _btype == BROWSE_DIRECTORY ||
+ _btype == BROWSE_MULTI_DIRECTORY ||
_btype == BROWSE_SAVE_DIRECTORY ) {
return(showdir());
} else {
@@ -620,7 +626,7 @@ void Fl_Native_File_Chooser::filter(const char *val) {
add_filter("All Files", "*.*"); // always include 'all files' option
#ifdef DEBUG
- nullprint(_parsedfilt);
+ dnullprint(_parsedfilt);
#endif /*DEBUG*/
}
@@ -657,7 +663,55 @@ void Fl_Native_File_Chooser::add_filter(const char *name_in, // name of filter (
//DEBUG printf("DEBUG: ADD FILTER name=<%s> winfilter=<%s>\n", name, winfilter);
}
+// RETURN HOW MANY DIFFERENT FILTERS WERE SPECIFIED
+// In: "foo.[CH]" or "foo.{C,H}"
+// Out: 2
+//
+static int count_filters(const char *filter) {
+ int count = 0;
+ char mode = 0;
+ const char *in = filter;
+ while (*in) {
+ switch(*in) {
+ case '\\': // escape next character
+ ++in; if ( *in == 0 ) continue; // skip escape. EOL? done
+ ++in; // skip escaped char
+ continue;
+ case LCURLY_CHR: // start "{aaa,bbb}"
+ mode = *in; // set mode, parse over curly
+ ++count; // at least +1 wildcard
+ break;
+ case RCURLY_CHR: // end "{aaa,bbb}"
+ if ( mode == LCURLY_CHR ) // disable curly mode (if on)
+ mode = 0;
+ break;
+ case LBRACKET_CHR: // start "[xyz]"
+ mode = *in; // set mode, parse over bracket
+ break;
+ case RBRACKET_CHR: // end "[xyz]"
+ if ( mode == LBRACKET_CHR ) // disable bracket mode (if on)
+ mode = 0;
+ break;
+ default: // any other char
+ switch (mode) { // handle {} or [] modes
+ case LCURLY_CHR: // handle "{aaa,bbb}"
+ if (*in==',' || *in=='|') // ',' and '|' adds filters
+ ++count;
+ break;
+ case LBRACKET_CHR: // handle "[xyz]"
+ ++count; // all chars in []'s add new filter
+ break;
+ }
+ break;
+ }
+ ++in; // parse past char
+ }
+ return count > 0 ? count : 1; // return at least 1
+}
+
// CONVERT FLTK STYLE PATTERN MATCHES TO WINDOWS 'DOUBLENULL' PATTERN
+// Returns with the parsed double-null result in '_parsedfilt'.
+//
// Handles:
// IN OUT
// ----------- -----------------------------
@@ -685,16 +739,22 @@ void Fl_Native_File_Chooser::parse_filter(const char *in) {
if ( ! in ) return;
int has_name = strchr(in, '\t') ? 1 : 0;
+ char mode = has_name ? 'n' : 'w'; // parse mode: n=name, w=wildcard
- char mode = has_name ? 'n' : 'w'; // parse mode: n=name, w=wildcard
- int nwildcards = 0;
- char wildcards[MAXFILTERS][1024]; // parsed wildcards (can be several)
- char wildprefix[512] = "";
- char name[512] = "";
+ // whatever input string is, our output won't be much longer in length..
+ // use double length just for safety.
+ size_t slen = strlen(in);
+ char *wildprefix = new char[slen*2]; wildprefix[0] = 0;
+ char *comp = new char[slen*2]; comp[0] = 0;
+ char *name = new char[slen*2]; name[0] = 0;
// Init
+ int nwildcards = 0;
+ int maxfilters = count_filters(in) + 1; // count wildcard seps
+ char **wildcards = new char*[maxfilters]; // parsed wildcards (can be several)
int t;
- for ( t=0; t<MAXFILTERS; t++ ) {
+ for ( t=0; t<maxfilters; t++ ) {
+ wildcards[t] = new char[slen];
wildcards[t][0] = '\0';
}
@@ -739,7 +799,7 @@ void Fl_Native_File_Chooser::parse_filter(const char *in) {
strcpy(wildcards[nwildcards++], wildprefix);
}
// Append wildcards in Microsoft's "*.one;*.two" format
- char comp[4096] = "";
+ comp[0] = 0;
for ( t=0; t<nwildcards; t++ ) {
if ( t != 0 ) strcat(comp, ";");
strcat(comp, wildcards[t]);
@@ -750,14 +810,22 @@ void Fl_Native_File_Chooser::parse_filter(const char *in) {
}
}
// RESET
- for ( t=0; t<MAXFILTERS; t++ ) {
+ for ( t=0; t<maxfilters; t++ ) {
wildcards[t][0] = '\0';
}
nwildcards = 0;
wildprefix[0] = name[0] = '\0';
mode = strchr(in,'\t') ? 'n' : 'w';
// DONE?
- if ( *in == '\0' ) return; // done
+ if ( *in == '\0' ) { // done
+ // Free everything
+ delete[] wildprefix;
+ delete[] comp;
+ delete[] name;
+ for ( t=0; t<maxfilters; t++ ) delete[] wildcards[t];
+ delete[] wildcards;
+ return;
+ }
continue; // not done yet, more filters
}
@@ -781,7 +849,7 @@ void Fl_Native_File_Chooser::parse_filter(const char *in) {
default:
regchar: // handle regular char
switch ( mode ) {
- case LBRACKET_CHR:
+ case LBRACKET_CHR:
// create new wildcard
++nwildcards;
// copy in prefix
@@ -868,5 +936,5 @@ LPCWSTR utf8towchar(const char *in)
#endif /*!FL_DOXYGEN*/
//
-// End of "$Id: Fl_Native_File_Chooser_WIN32.cxx 9629 2012-06-26 07:03:46Z greg.ercolano $".
+// End of "$Id: Fl_Native_File_Chooser_WIN32.cxx 10312 2014-09-15 09:35:05Z ossman $".
//
diff --git a/src/Fl_Native_File_Chooser_common.cxx b/src/Fl_Native_File_Chooser_common.cxx
index 5e8aa98..70e2ca4 100644
--- a/src/Fl_Native_File_Chooser_common.cxx
+++ b/src/Fl_Native_File_Chooser_common.cxx
@@ -1,4 +1,4 @@
-// "$Id: Fl_Native_File_Chooser_common.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $"
+// "$Id: Fl_Native_File_Chooser_common.cxx 10064 2014-01-16 16:10:19Z manolo $"
//
// FLTK native OS file chooser widget
//
@@ -71,6 +71,7 @@ static void chrcat(char *s, char c) {
strcat(s, tmp);
}
+
//
-// End of "$Id: Fl_Native_File_Chooser_common.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $".
+// End of "$Id: Fl_Native_File_Chooser_common.cxx 10064 2014-01-16 16:10:19Z manolo $".
//
diff --git a/src/Fl_PNG_Image.cxx b/src/Fl_PNG_Image.cxx
index 30ea565..67eb3df 100644
--- a/src/Fl_PNG_Image.cxx
+++ b/src/Fl_PNG_Image.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: Fl_PNG_Image.cxx 9713 2012-11-10 09:01:16Z manolo $"
+// "$Id: Fl_PNG_Image.cxx 9980 2013-09-21 16:41:23Z greg.ercolano $"
//
// Fl_PNG_Image routines.
//
@@ -51,20 +51,22 @@ typedef struct {
const unsigned char *last;
} fl_png_memory;
-static void png_read_data_from_mem( png_structp png_ptr, //pointer to our data
- png_bytep data, // where to copy the image data for libpng computing
- png_size_t length) // length of data to copy
-{
- fl_png_memory *png_mem_data = (fl_png_memory*)png_get_io_ptr(png_ptr); // get the pointer to our struct
- if (png_mem_data->current + length > png_mem_data->last) {
- png_error(png_mem_data->pp, "Invalid attempt to read row data");
- return;
+extern "C" {
+ static void png_read_data_from_mem( png_structp png_ptr, //pointer to our data
+ png_bytep data, // where to copy the image data for libpng computing
+ png_size_t length) // length of data to copy
+ {
+ fl_png_memory *png_mem_data = (fl_png_memory*)png_get_io_ptr(png_ptr); // get the pointer to our struct
+ if (png_mem_data->current + length > png_mem_data->last) {
+ png_error(png_mem_data->pp, "Invalid attempt to read row data");
+ return;
+ }
+ /* copy data from image buffer */
+ memcpy (data, png_mem_data->current, length);
+ /* advance in the memory data */
+ png_mem_data->current += length;
}
- /* copy data from image buffer */
- memcpy (data, png_mem_data->current, length);
- /* advance in the memory data */
- png_mem_data->current += length;
-}
+} // extern "C"
#endif // HAVE_LIBPNG && HAVE_LIBZ
@@ -221,5 +223,5 @@ void Fl_PNG_Image::load_png_(const char *name_png, const unsigned char *buffer_p
//
-// End of "$Id: Fl_PNG_Image.cxx 9713 2012-11-10 09:01:16Z manolo $".
+// End of "$Id: Fl_PNG_Image.cxx 9980 2013-09-21 16:41:23Z greg.ercolano $".
//
diff --git a/src/Fl_Paged_Device.cxx b/src/Fl_Paged_Device.cxx
index a5f4b94..8cd4cc7 100644
--- a/src/Fl_Paged_Device.cxx
+++ b/src/Fl_Paged_Device.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: Fl_Paged_Device.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $"
+// "$Id: Fl_Paged_Device.cxx 10116 2014-03-05 12:55:34Z manolo $"
//
// implementation of Fl_Paged_Device class for the Fast Light Tool Kit (FLTK).
//
@@ -42,6 +42,7 @@ void Fl_Paged_Device::print_widget(Fl_Widget* widget, int delta_x, int delta_y)
int old_x, old_y, new_x, new_y, is_window;
if ( ! widget->visible() ) return;
is_window = (widget->as_window() != NULL);
+ uchar old_damage = widget->damage();
widget->damage(FL_DAMAGE_ALL);
// set origin to the desired top-left position of the widget
origin(&old_x, &old_y);
@@ -54,29 +55,34 @@ void Fl_Paged_Device::print_widget(Fl_Widget* widget, int delta_x, int delta_y)
if (new_x != old_x || new_y != old_y) {
translate(new_x - old_x, new_y - old_y );
}
- // if widget is a window, clip all drawings to the window area
- if (is_window) fl_push_clip(0, 0, widget->w(), widget->h() );
+ // if widget is a main window, clip all drawings to the window area
+ if (is_window && !widget->window()) fl_push_clip(0, 0, widget->w(), widget->h() );
// we do some trickery to recognize OpenGL windows and draw them via a plugin
int drawn_by_plugin = 0;
if (widget->as_gl_window()) {
Fl_Plugin_Manager pm("fltk:device");
Fl_Device_Plugin *pi = (Fl_Device_Plugin*)pm.plugin("opengl.device.fltk.org");
if (pi) {
- int width, height;
+ int height = 0;
+#ifdef __APPLE__
+ int width;
this->printable_rect(&width, &height);
+#endif
drawn_by_plugin = pi->print(widget, 0, 0, height);
}
}
if (!drawn_by_plugin) {
widget->draw();
}
- if (is_window) fl_pop_clip();
+ if (is_window && !widget->window()) fl_pop_clip();
// find subwindows of widget and print them
traverse(widget);
// reset origin to where it was
if (new_x != old_x || new_y != old_y) {
untranslate();
}
+ if ((old_damage & FL_DAMAGE_CHILD) == 0) widget->clear_damage(old_damage);
+ else widget->damage(FL_DAMAGE_ALL);
}
@@ -284,5 +290,5 @@ const Fl_Paged_Device::page_format Fl_Paged_Device::page_formats[NO_PAGE_FORMATS
};
//
-// End of "$Id: Fl_Paged_Device.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $".
+// End of "$Id: Fl_Paged_Device.cxx 10116 2014-03-05 12:55:34Z manolo $".
//
diff --git a/src/Fl_PostScript.cxx b/src/Fl_PostScript.cxx
index b7b72e6..bff175e 100644
--- a/src/Fl_PostScript.cxx
+++ b/src/Fl_PostScript.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: Fl_PostScript.cxx 9630 2012-06-28 08:38:14Z manolo $"
+// "$Id: Fl_PostScript.cxx 10308 2014-09-13 17:51:20Z manolo $"
//
// PostScript device support for the Fast Light Tool Kit (FLTK).
//
@@ -16,6 +16,7 @@
// http://www.fltk.org/str.php
//
+#include <FL/Fl_Printer.H>
#include <config.h>
#include <FL/Fl.H>
#include <FL/fl_ask.H>
@@ -23,6 +24,7 @@
#include <stdio.h>
#include <FL/Fl_PostScript.H>
#include <FL/Fl_Native_File_Chooser.H>
+#include <stdarg.h>
#if defined(USE_X11)
#include "Fl_Font.H"
#if USE_XFT
@@ -94,7 +96,7 @@ int Fl_PostScript_File_Device::start_job (int pagecount, enum Fl_Paged_Device::P
// Show native chooser
if ( fnfc.show() ) return 1;
Fl_PostScript_Graphics_Driver *ps = driver();
- ps->output = fopen(fnfc.filename(), "w");
+ ps->output = fl_fopen(fnfc.filename(), "w");
if(ps->output == NULL) return 2;
ps->ps_filename_ = strdup(fnfc.filename());
ps->start_postscript(pagecount, format, layout);
@@ -102,9 +104,11 @@ int Fl_PostScript_File_Device::start_job (int pagecount, enum Fl_Paged_Device::P
return 0;
}
-static int dont_close(FILE *f)
-{
- return 0;
+extern "C" {
+ static int dont_close(FILE *f)
+ {
+ return 0;
+ }
}
/**
@@ -129,6 +133,12 @@ int Fl_PostScript_File_Device::start_job (FILE *ps_output, int pagecount,
return 0;
}
+/** Don't use with this class. */
+int Fl_PostScript_File_Device::start_job(int pagecount, int* from, int* to)
+{
+ return 1;
+}
+
/**
@brief The destructor.
*/
@@ -137,6 +147,24 @@ Fl_PostScript_File_Device::~Fl_PostScript_File_Device() {
if (ps) delete ps;
}
+/** Shields output PostScript data from modifications of the current locale.
+ It typically avoids PostScript errors caused if the current locale uses comma instead of dot
+ as "decimal point".
+ \param format directives controlling output PostScript data
+ \return value returned by vfprintf() call
+ */
+int Fl_PostScript_Graphics_Driver::clocale_printf(const char *format, ...)
+{
+ char *saved_locale = setlocale(LC_NUMERIC, NULL);
+ setlocale(LC_NUMERIC, "C");
+ va_list args;
+ va_start(args, format);
+ int retval = vfprintf(output, format, args);
+ va_end(args);
+ setlocale(LC_NUMERIC, saved_locale);
+ return retval;
+}
+
#ifndef FL_DOXYGEN
#if ! (defined(__APPLE__) || defined(WIN32) )
@@ -652,7 +680,7 @@ void Fl_PostScript_Graphics_Driver::page(double pw, double ph, int media) {
fprintf(output, "save\n");
fprintf(output, "GS\n");
- fprintf(output, "%g %g TR\n", (double)0 /*lm_*/ , ph_ /* - tm_*/);
+ clocale_printf( "%g %g TR\n", (double)0 /*lm_*/ , ph_ /* - tm_*/);
fprintf(output, "1 -1 SC\n");
line_style(0);
fprintf(output, "GS\n");
@@ -701,7 +729,7 @@ void Fl_PostScript_Graphics_Driver::rect(int x, int y, int w, int h) {
}
void Fl_PostScript_Graphics_Driver::rectf(int x, int y, int w, int h) {
- fprintf(output, "%g %g %i %i FR\n", x-0.5, y-0.5, w, h);
+ clocale_printf( "%g %g %i %i FR\n", x-0.5, y-0.5, w, h);
}
void Fl_PostScript_Graphics_Driver::line(int x1, int y1, int x2, int y2) {
@@ -831,7 +859,7 @@ void Fl_PostScript_Graphics_Driver::point(int x, int y){
rectf(x,y,1,1);
}
-static int dashes_flat[5][7]={
+static const int dashes_flat[5][7]={
{-1,0,0,0,0,0,0},
{3,1,-1,0,0,0,0},
{1,1,-1,0,0,0,0},
@@ -841,7 +869,7 @@ static int dashes_flat[5][7]={
//yeah, hack...
-static double dashes_cap[5][7]={
+static const double dashes_cap[5][7]={
{-1,0,0,0,0,0,0},
{2,2,-1,0,0,0,0},
{0.01,1.99,-1,0,0,0,0},
@@ -890,16 +918,15 @@ void Fl_PostScript_Graphics_Driver::line_style(int style, int width, char* dashe
dashes++;
}
}else{
- int * ds;
if(style & 0x200){ // round and square caps, dash length need to be adjusted
- double *dt = dashes_cap[style & 0xff];
+ const double *dt = dashes_cap[style & 0xff];
while (*dt >= 0){
- fprintf(output, "%g ",width * (*dt));
- dt++;
+ clocale_printf("%g ",width * (*dt));
+ dt++;
}
}else{
- ds = dashes_flat[style & 0xff];
+ const int *ds = dashes_flat[style & 0xff];
while (*ds >= 0){
fprintf(output, "%i ",width * (*ds));
ds++;
@@ -954,7 +981,7 @@ void Fl_PostScript_Graphics_Driver::font(int f, int s) {
}
#endif // USE_XFT
#endif // USE_X11
- fprintf(output,"%.1f FS\n", ps_size);
+ clocale_printf("%.1f FS\n", ps_size);
}
}
@@ -962,6 +989,10 @@ double Fl_PostScript_Graphics_Driver::width(const char *s, int n) {
return Fl_Display_Device::display_device()->driver()->width(s, n);
}
+double Fl_PostScript_Graphics_Driver::width(unsigned u) {
+ return Fl_Display_Device::display_device()->driver()->width(u);
+}
+
int Fl_PostScript_Graphics_Driver::height() {
return Fl_Display_Device::display_device()->driver()->height();
}
@@ -985,13 +1016,13 @@ void Fl_PostScript_Graphics_Driver::color(unsigned char r, unsigned char g, unsi
cr_ = r; cg_ = g; cb_ = b;
if (r == g && g == b) {
double gray = r/255.0;
- fprintf(output, "%g GL\n", gray);
+ clocale_printf("%g GL\n", gray);
} else {
double fr, fg, fb;
fr = r/255.0;
fg = g/255.0;
fb = b/255.0;
- fprintf(output, "%g %g %g SRGB\n", fr , fg , fb);
+ clocale_printf("%g %g %g SRGB\n", fr , fg , fb);
}
}
@@ -1035,7 +1066,7 @@ static uchar *calc_mask(uchar *img, int w, int h, Fl_Color bg)
// write to PostScript a bitmap image of a UTF8 string
static void transformed_draw_extra(const char* str, int n, double x, double y, int w,
- FILE *output, Fl_Graphics_Driver *driver, bool rtl) {
+ FILE *output, Fl_PostScript_Graphics_Driver *driver, bool rtl) {
// scale for bitmask computation
#if defined(USE_X11) && !USE_XFT
float scale = 1; // don't scale because we can't expect to have scalable fonts
@@ -1043,11 +1074,11 @@ static void transformed_draw_extra(const char* str, int n, double x, double y, i
float scale = 2;
#endif
Fl_Fontsize old_size = driver->size();
- Fl_Font fontnum = driver->font();
+ Fl_Font fontnum = driver->Fl_Graphics_Driver::font();
int w_scaled = (int)(w * (scale + 0.5));
int h = (int)(driver->height() * scale);
// create an offscreen image of the string
- Fl_Color text_color = driver->color();
+ Fl_Color text_color = driver->Fl_Graphics_Driver::color();
Fl_Color bg_color = fl_contrast(FL_WHITE, text_color);
Fl_Offscreen off = fl_create_offscreen(w_scaled, (int)(h+3*scale) );
fl_begin_offscreen(off);
@@ -1075,7 +1106,7 @@ static void transformed_draw_extra(const char* str, int n, double x, double y, i
delete[] img;
// write the string image to PostScript as a scaled bitmask
scale = w2 / float(w);
- fprintf(output, "%g %g %g %g %d %d MI\n", x, y - h*0.77/scale, w2/scale, h/scale, w2, h);
+ driver->clocale_printf("%g %g %g %g %d %d MI\n", x, y - h*0.77/scale, w2/scale, h/scale, w2, h);
uchar *di;
int wmask = (w2+7)/8;
for (int j = h - 1; j >= 0; j--){
@@ -1151,7 +1182,7 @@ void Fl_PostScript_Graphics_Driver::transformed_draw(const char* str, int n, dou
}
fprintf(output, "%4.4X", utf);
}
- fprintf(output, "> %g %g show_pos_width\n", x, y);
+ clocale_printf("> %g %g show_pos_width\n", x, y);
}
void Fl_PostScript_Graphics_Driver::rtl_draw(const char* str, int n, int x, int y) {
@@ -1160,11 +1191,11 @@ void Fl_PostScript_Graphics_Driver::rtl_draw(const char* str, int n, int x, int
}
void Fl_PostScript_Graphics_Driver::concat(){
- fprintf(output,"[%g %g %g %g %g %g] CT\n", fl_matrix->a , fl_matrix->b , fl_matrix->c , fl_matrix->d , fl_matrix->x , fl_matrix->y);
+ clocale_printf("[%g %g %g %g %g %g] CT\n", fl_matrix->a , fl_matrix->b , fl_matrix->c , fl_matrix->d , fl_matrix->x , fl_matrix->y);
}
void Fl_PostScript_Graphics_Driver::reconcat(){
- fprintf(output, "[%g %g %g %g %g %g] RCT\n" , fl_matrix->a , fl_matrix->b , fl_matrix->c , fl_matrix->d , fl_matrix->x , fl_matrix->y);
+ clocale_printf("[%g %g %g %g %g %g] RCT\n" , fl_matrix->a , fl_matrix->b , fl_matrix->c , fl_matrix->d , fl_matrix->x , fl_matrix->y);
}
///////////////// transformed (double) drawings ////////////////////////////////
@@ -1205,26 +1236,26 @@ void Fl_PostScript_Graphics_Driver::begin_polygon(){
void Fl_PostScript_Graphics_Driver::vertex(double x, double y){
if(shape_==POINTS){
- fprintf(output,"%g %g MT\n", x , y);
+ clocale_printf("%g %g MT\n", x , y);
gap_=1;
return;
}
if(gap_){
- fprintf(output,"%g %g MT\n", x , y);
+ clocale_printf("%g %g MT\n", x , y);
gap_=0;
}else
- fprintf(output, "%g %g LT\n", x , y);
+ clocale_printf("%g %g LT\n", x , y);
}
void Fl_PostScript_Graphics_Driver::curve(double x, double y, double x1, double y1, double x2, double y2, double x3, double y3){
if(shape_==NONE) return;
if(gap_)
- fprintf(output,"%g %g MT\n", x , y);
+ clocale_printf("%g %g MT\n", x , y);
else
- fprintf(output, "%g %g LT\n", x , y);
+ clocale_printf("%g %g LT\n", x , y);
gap_=0;
- fprintf(output, "%g %g %g %g %g %g curveto \n", x1 , y1 , x2 , y2 , x3 , y3);
+ clocale_printf("%g %g %g %g %g %g curveto \n", x1 , y1 , x2 , y2 , x3 , y3);
}
@@ -1233,13 +1264,13 @@ void Fl_PostScript_Graphics_Driver::circle(double x, double y, double r){
fprintf(output, "GS\n");
concat();
// fprintf(output, "BP\n");
- fprintf(output,"%g %g %g 0 360 arc\n", x , y , r);
+ clocale_printf("%g %g %g 0 360 arc\n", x , y , r);
reconcat();
// fprintf(output, "ELP\n");
fprintf(output, "GR\n");
}else
- fprintf(output, "%g %g %g 0 360 arc\n", x , y , r);
+ clocale_printf("%g %g %g 0 360 arc\n", x , y , r);
}
@@ -1247,22 +1278,23 @@ void Fl_PostScript_Graphics_Driver::arc(double x, double y, double r, double sta
if(shape_==NONE) return;
gap_=0;
if(start>a)
- fprintf(output, "%g %g %g %g %g arc\n", x , y , r , -start, -a);
+ clocale_printf("%g %g %g %g %g arc\n", x , y , r , -start, -a);
else
- fprintf(output, "%g %g %g %g %g arcn\n", x , y , r , -start, -a);
+ clocale_printf("%g %g %g %g %g arcn\n", x , y , r , -start, -a);
}
void Fl_PostScript_Graphics_Driver::arc(int x, int y, int w, int h, double a1, double a2) {
+ if (w <= 1 || h <= 1) return;
fprintf(output, "GS\n");
//fprintf(output, "BP\n");
begin_line();
- fprintf(output, "%g %g TR\n", x + w/2.0 -0.5 , y + h/2.0 - 0.5);
- fprintf(output, "%g %g SC\n", (w-1)/2.0 , (h-1)/2.0 );
+ clocale_printf("%g %g TR\n", x + w/2.0 -0.5 , y + h/2.0 - 0.5);
+ clocale_printf("%g %g SC\n", (w-1)/2.0 , (h-1)/2.0 );
arc(0,0,1,a2,a1);
// fprintf(output, "0 0 1 %g %g arc\n" , -a1 , -a2);
- fprintf(output, "%g %g SC\n", 2.0/(w-1) , 2.0/(h-1) );
- fprintf(output, "%g %g TR\n", -x - w/2.0 +0.5 , -y - h/2.0 +0.5);
+ clocale_printf("%g %g SC\n", 2.0/(w-1) , 2.0/(h-1) );
+ clocale_printf("%g %g TR\n", -x - w/2.0 +0.5 , -y - h/2.0 +0.5);
end_line();
// fprintf(output, "%g setlinewidth\n", 2/sqrt(w*h));
@@ -1275,8 +1307,8 @@ void Fl_PostScript_Graphics_Driver::arc(int x, int y, int w, int h, double a1, d
void Fl_PostScript_Graphics_Driver::pie(int x, int y, int w, int h, double a1, double a2) {
fprintf(output, "GS\n");
begin_polygon();
- fprintf(output, "%g %g TR\n", x + w/2.0 -0.5 , y + h/2.0 - 0.5);
- fprintf(output, "%g %g SC\n", (w-1)/2.0 , (h-1)/2.0 );
+ clocale_printf("%g %g TR\n", x + w/2.0 -0.5 , y + h/2.0 - 0.5);
+ clocale_printf("%g %g SC\n", (w-1)/2.0 , (h-1)/2.0 );
vertex(0,0);
arc(0.0,0.0, 1, a2, a1);
end_polygon();
@@ -1318,10 +1350,10 @@ void Fl_PostScript_Graphics_Driver::end_polygon(){
void Fl_PostScript_Graphics_Driver::transformed_vertex(double x, double y){
reconcat();
if(gap_){
- fprintf(output, "%g %g MT\n", x , y);
+ clocale_printf("%g %g MT\n", x , y);
gap_=0;
}else
- fprintf(output, "%g %g LT\n", x , y);
+ clocale_printf("%g %g LT\n", x , y);
concat();
}
@@ -1335,7 +1367,7 @@ void Fl_PostScript_Graphics_Driver::push_clip(int x, int y, int w, int h) {
fprintf(output, "CR\nCS\n");
if(lang_level_<3)
recover();
- fprintf(output, "%g %g %i %i CL\n", clip_->x-0.5 , clip_->y-0.5 , clip_->w , clip_->h);
+ clocale_printf("%g %g %i %i CL\n", clip_->x-0.5 , clip_->y-0.5 , clip_->w , clip_->h);
}
@@ -1356,7 +1388,7 @@ void Fl_PostScript_Graphics_Driver::pop_clip() {
delete c;
fprintf(output, "CR\nCS\n");
if(clip_ && clip_->w >0)
- fprintf(output, "%g %g %i %i CL\n", clip_->x - 0.5, clip_->y - 0.5, clip_->w , clip_->h);
+ clocale_printf("%g %g %i %i CL\n", clip_->x - 0.5, clip_->y - 0.5, clip_->w , clip_->h);
// uh, -0.5 is to match screen clipping, for floats there should be something beter
if(lang_level_<3)
recover();
@@ -1407,7 +1439,6 @@ int Fl_PostScript_Graphics_Driver::not_clipped(int x, int y, int w, int h){
return 0;
}
-
void Fl_PostScript_File_Device::margins(int *left, int *top, int *right, int *bottom) // to implement
{
Fl_PostScript_Graphics_Driver *ps = driver();
@@ -1436,7 +1467,7 @@ void Fl_PostScript_File_Device::origin(int x, int y)
x_offset = x;
y_offset = y;
Fl_PostScript_Graphics_Driver *ps = driver();
- fprintf(ps->output, "GR GR GS %d %d TR %f %f SC %d %d TR %f rotate GS\n",
+ ps->clocale_printf("GR GR GS %d %d TR %f %f SC %d %d TR %f rotate GS\n",
ps->left_margin, ps->top_margin, ps->scale_x, ps->scale_y, x, y, ps->angle);
}
@@ -1446,7 +1477,7 @@ void Fl_PostScript_File_Device::scale (float s_x, float s_y)
Fl_PostScript_Graphics_Driver *ps = driver();
ps->scale_x = s_x;
ps->scale_y = s_y;
- fprintf(ps->output, "GR GR GS %d %d TR %f %f SC %f rotate GS\n",
+ ps->clocale_printf("GR GR GS %d %d TR %f %f SC %f rotate GS\n",
ps->left_margin, ps->top_margin, ps->scale_x, ps->scale_y, ps->angle);
}
@@ -1454,7 +1485,7 @@ void Fl_PostScript_File_Device::rotate (float rot_angle)
{
Fl_PostScript_Graphics_Driver *ps = driver();
ps->angle = - rot_angle;
- fprintf(ps->output, "GR GR GS %d %d TR %f %f SC %d %d TR %f rotate GS\n",
+ ps->clocale_printf("GR GR GS %d %d TR %f %f SC %d %d TR %f rotate GS\n",
ps->left_margin, ps->top_margin, ps->scale_x, ps->scale_y, x_offset, y_offset, ps->angle);
}
@@ -1577,7 +1608,7 @@ int Fl_PostScript_Printer::start_job(int pages, int *firstpage, int *lastpage) {
if (to < from) to = from;
if (firstpage) *firstpage = from;
if (lastpage) *lastpage = to;
- pages = to - from + 1;
+ if (pages > 0) pages = to - from + 1;
}
if (print_output_mode[0]->value()) layout = Fl_Paged_Device::PORTRAIT;
@@ -1617,5 +1648,5 @@ int Fl_PostScript_Printer::start_job(int pages, int *firstpage, int *lastpage) {
#endif // FL_DOXYGEN
//
-// End of "$Id: Fl_PostScript.cxx 9630 2012-06-28 08:38:14Z manolo $".
+// End of "$Id: Fl_PostScript.cxx 10308 2014-09-13 17:51:20Z manolo $".
//
diff --git a/src/Fl_Preferences.cxx b/src/Fl_Preferences.cxx
index ada52a6..3cf501b 100644
--- a/src/Fl_Preferences.cxx
+++ b/src/Fl_Preferences.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: Fl_Preferences.cxx 9334 2012-04-09 12:36:23Z AlbrechtS $"
+// "$Id: Fl_Preferences.cxx 10378 2014-10-14 12:10:18Z ianmacarthur $"
//
// Preferences methods for the Fast Light Tool Kit (FLTK).
//
@@ -40,10 +40,14 @@
#elif defined (__APPLE__)
# include <ApplicationServices/ApplicationServices.h>
# include <unistd.h>
+# include <config.h>
# include <dlfcn.h>
#else
# include <unistd.h>
-# include <dlfcn.h>
+# include <config.h>
+# if HAVE_DLFCN_H
+# include <dlfcn.h>
+# endif
#endif
#ifdef WIN32
@@ -1212,7 +1216,7 @@ int Fl_Preferences::RootNode::write() {
// get the path to the preferences directory
char Fl_Preferences::RootNode::getPath( char *path, int pathlen ) {
if (!filename_) // RUNTIME preferences
- return -1;
+ return 1; // return 1 (not -1) to be consistent with fl_make_path()
strlcpy( path, filename_, pathlen);
char *s;
@@ -1766,7 +1770,10 @@ int Fl_Plugin_Manager::load(const char *filename) {
#if defined(WIN32) && !defined(__CYGWIN__)
HMODULE dl = LoadLibrary(filename);
#else
- void * dl = dlopen(filename, RTLD_LAZY);
+ void * dl = NULL;
+# if HAVE_DLSYM
+ dl = dlopen(filename, RTLD_LAZY);
+# endif
#endif
// There is no way of unloading a plugin!
return (dl!=0) ? 0 : -1;
@@ -1790,5 +1797,5 @@ int Fl_Plugin_Manager::loadAll(const char *filepath, const char *pattern) {
}
//
-// End of "$Id: Fl_Preferences.cxx 9334 2012-04-09 12:36:23Z AlbrechtS $".
+// End of "$Id: Fl_Preferences.cxx 10378 2014-10-14 12:10:18Z ianmacarthur $".
//
diff --git a/src/Fl_Printer.cxx b/src/Fl_Printer.cxx
index a953c9c..3518d23 100644
--- a/src/Fl_Printer.cxx
+++ b/src/Fl_Printer.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: Fl_Printer.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $"
+// "$Id: Fl_Printer.cxx 10291 2014-09-08 16:03:52Z manolo $"
//
// Encompasses platform-specific printing-support code and
// PostScript output code for the Fast Light Tool Kit (FLTK).
@@ -19,14 +19,10 @@
#include <FL/Fl_Printer.H>
-#ifdef __APPLE__
-//#include "Fl_Quartz_Printer.mm"
-#elif defined(WIN32)
+#if defined(WIN32)
#include "Fl_GDI_Printer.cxx"
#endif
-#include "Fl_PostScript.cxx"
-
// print dialog customization strings
/** [this text may be customized at run-time] */
const char *Fl_Printer::dialog_title = "Print";
@@ -189,5 +185,5 @@ Fl_Printer::~Fl_Printer(void)
//
-// End of "$Id: Fl_Printer.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $".
+// End of "$Id: Fl_Printer.cxx 10291 2014-09-08 16:03:52Z manolo $".
//
diff --git a/src/Fl_Quartz_Printer.mm b/src/Fl_Quartz_Printer.mm
index 71646f5..a7cf38e 100644
--- a/src/Fl_Quartz_Printer.mm
+++ b/src/Fl_Quartz_Printer.mm
@@ -1,9 +1,9 @@
//
-// "$Id: Fl_Quartz_Printer.mm 9276 2012-03-12 09:39:17Z manolo $"
+// "$Id: Fl_Quartz_Printer.mm 10393 2014-10-26 15:23:03Z manolo $"
//
// Mac OS X-specific printing support (objective-c++) for the Fast Light Tool Kit (FLTK).
//
-// Copyright 2010-2012 by Bill Spitzak and others.
+// Copyright 2010-2014 by Bill Spitzak and others.
//
// This library is free software. Distribution and use rights are outlined in
// the file "COPYING" which should have been included with this file. If this
@@ -24,6 +24,21 @@
#include <FL/fl_draw.H>
#import <Cocoa/Cocoa.h>
+typedef OSStatus (*PMSessionSetDocumentFormatGeneration_type)(
+ PMPrintSession printSession,
+ CFStringRef docFormat,
+ CFArrayRef graphicsContextTypes,
+ CFTypeRef options);
+typedef OSStatus (*PMSessionBeginDocumentNoDialog_type)(
+ PMPrintSession printSession,
+ PMPrintSettings printSettings,
+ PMPageFormat pageFormat);
+typedef OSStatus
+(*PMSessionGetGraphicsContext_type)(
+ PMPrintSession printSession,
+ CFStringRef graphicsContextType,
+ void ** graphicsContext);
+
extern void fl_quartz_restore_line_style_();
Fl_System_Printer::Fl_System_Printer(void)
@@ -69,9 +84,9 @@ int Fl_System_Printer::start_job (int pagecount, int *frompage, int *topage)
if(topage && *topage > pagecount) *topage = pagecount;
status = PMSessionBeginCGDocumentNoDialog(printSession, printSettings, pageFormat);//from 10.4
}
- else {
+ else
#endif
-
+ {
#if !__LP64__
Boolean accepted;
status = PMCreateSession(&printSession);
@@ -112,14 +127,16 @@ int Fl_System_Printer::start_job (int pagecount, int *frompage, int *topage)
CFStringRef mystring[1];
mystring[0] = kPMGraphicsContextCoreGraphics;
CFArrayRef array = CFArrayCreate(NULL, (const void **)mystring, 1, &kCFTypeArrayCallBacks);
+ PMSessionSetDocumentFormatGeneration_type PMSessionSetDocumentFormatGeneration =
+ (PMSessionSetDocumentFormatGeneration_type)Fl_X::get_carbon_function("PMSessionSetDocumentFormatGeneration");
status = PMSessionSetDocumentFormatGeneration(printSession, kPMDocumentFormatDefault, array, NULL);
CFRelease(array);
+ PMSessionBeginDocumentNoDialog_type PMSessionBeginDocumentNoDialog =
+ (PMSessionBeginDocumentNoDialog_type)Fl_X::get_carbon_function("PMSessionBeginDocumentNoDialog");
status = PMSessionBeginDocumentNoDialog(printSession, printSettings, pageFormat);
#endif //__LP64__
-
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
}
-#endif
+
if (status != noErr) return 1;
y_offset = x_offset = 0;
this->set_current();
@@ -224,14 +241,15 @@ int Fl_System_Printer::start_page (void)
if ( PMSessionGetCGGraphicsContext != NULL ) {
status = PMSessionGetCGGraphicsContext(printSession, &fl_gc);
}
- else {
+ else
#endif
-#if ! __LP64__
- status = PMSessionGetGraphicsContext(printSession,NULL,(void **)&fl_gc);
+ {
+#if ! __LP64_
+ PMSessionGetGraphicsContext_type PMSessionGetGraphicsContext =
+ (PMSessionGetGraphicsContext_type)Fl_X::get_carbon_function("PMSessionGetGraphicsContext");
+ status = PMSessionGetGraphicsContext(printSession, NULL, (void **)&fl_gc);
#endif
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
}
-#endif
PMRect pmRect;
float win_scale_x, win_scale_y;
@@ -284,14 +302,41 @@ void Fl_System_Printer::end_job (void)
fl_alert ("PM Session error %d", (int)status);
}
PMSessionEndDocumentNoDialog(printSession);
+#if !__LP64__
+ if (fl_mac_os_version < 100500) {
+ PMRelease(printSettings);
+ PMRelease(pageFormat);
+ PMRelease(printSession);
+ }
+#endif
Fl_Display_Device::display_device()->set_current();
fl_gc = 0;
Fl_Window *w = Fl::first_window();
if (w) w->show();
}
+// version that prints at high res if using a retina display
+void Fl_System_Printer::print_window_part(Fl_Window *win, int x, int y, int w, int h, int delta_x, int delta_y)
+{
+ Fl_Surface_Device *current = Fl_Surface_Device::surface();
+ Fl_Display_Device::display_device()->set_current();
+ Fl_Window *save_front = Fl::first_window();
+ win->show();
+ fl_gc = NULL;
+ Fl::check();
+ win->make_current();
+ CGImageRef img = Fl_X::CGImage_from_window_rect(win, x, y, w, h);
+ if (save_front != win) save_front->show();
+ current->set_current();
+ CGRect rect = { { delta_x, delta_y }, { w, h } };
+ Fl_X::q_begin_image(rect, 0, 0, w, h);
+ CGContextDrawImage(fl_gc, rect, img);
+ Fl_X::q_end_image();
+ CFRelease(img);
+}
+
#endif // __APPLE__
//
-// End of "$Id: Fl_Quartz_Printer.mm 9276 2012-03-12 09:39:17Z manolo $".
+// End of "$Id: Fl_Quartz_Printer.mm 10393 2014-10-26 15:23:03Z manolo $".
//
diff --git a/src/Fl_Round_Button.cxx b/src/Fl_Round_Button.cxx
index c2edc4e..c2f24ce 100644
--- a/src/Fl_Round_Button.cxx
+++ b/src/Fl_Round_Button.cxx
@@ -1,12 +1,12 @@
//
-// "$Id: Fl_Round_Button.cxx 9637 2012-07-24 04:37:22Z matt $"
+// "$Id: Fl_Round_Button.cxx 10386 2014-10-19 20:17:17Z AlbrechtS $"
//
// Round button for the Fast Light Tool Kit (FLTK).
//
-// Copyright 1998-2010 by Bill Spitzak and others.
+// Copyright 1998-2014 by Bill Spitzak and others.
//
// This library is free software. Distribution and use rights are outlined in
-// the file "COPYING" which should have been included with this file. If this
+// the file "COPYING" which should have been included with this file. If this
// file is missing or damaged, see the license at:
//
// http://www.fltk.org/COPYING.php
@@ -25,24 +25,49 @@
#include <FL/Fl_Radio_Round_Button.H>
/**
- Creates a new Fl_Round_Button widget using the given
- position, size, and label string.
+ Creates a new Fl_Round_Button widget using the given position, size, and label string.
+
+ \image html Fl_Round_Button.png
+ \image latex Fl_Round_Button.png " Fl_Round_Button" width=4cm
+
+ The Fl_Round_Button subclass displays the "ON" state by
+ turning on a light, rather than drawing pushed in.
+
+ The default box type is FL_NO_BOX, which draws the label w/o a box
+ right of the checkmark.
+
+ The shape of the "light" is set with down_box() and its default
+ value is FL_ROUND_DOWN_BOX.
+
+ The color of the light when on is controlled with selection_color(),
+ which defaults to FL_FOREGROUND_COLOR (usually black).
+
+ \param[in] X, Y, W, H position and size of the widget
+ \param[in] L widget label, default is no label
*/
-Fl_Round_Button::Fl_Round_Button(int X,int Y,int W,int H, const char *l)
-: Fl_Light_Button(X,Y,W,H,l) {
+Fl_Round_Button::Fl_Round_Button(int X,int Y,int W,int H, const char *L)
+: Fl_Light_Button(X,Y,W,H,L) {
box(FL_NO_BOX);
down_box(FL_ROUND_DOWN_BOX);
selection_color(FL_FOREGROUND_COLOR);
}
+/**
+ Creates a new Fl_Radio_Button widget using the given position, size, and label string.
+
+ The button type() is set to FL_RADIO_BUTTON.
+
+ \param[in] X, Y, W, H position and size of the widget
+ \param[in] L widget label, default is no label
+*/
Fl_Radio_Round_Button::Fl_Radio_Round_Button(int X,int Y,int W,int H,const char *L)
-: Fl_Round_Button(X,Y,W,H,L)
+: Fl_Round_Button(X,Y,W,H,L)
{
type(FL_RADIO_BUTTON);
}
//
-// End of "$Id: Fl_Round_Button.cxx 9637 2012-07-24 04:37:22Z matt $".
+// End of "$Id: Fl_Round_Button.cxx 10386 2014-10-19 20:17:17Z AlbrechtS $".
//
diff --git a/src/Fl_Scroll.cxx b/src/Fl_Scroll.cxx
index a93cde1..9317a11 100644
--- a/src/Fl_Scroll.cxx
+++ b/src/Fl_Scroll.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: Fl_Scroll.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $"
+// "$Id: Fl_Scroll.cxx 10221 2014-07-16 18:51:56Z greg.ercolano $"
//
// Scroll widget for the Fast Light Tool Kit (FLTK).
//
@@ -100,60 +100,61 @@ void Fl_Scroll::draw_clip(void* v,int X, int Y, int W, int H) {
void Fl_Scroll::recalc_scrollbars(ScrollInfo &si) {
// inner box of widget (excluding scrollbars)
- si.innerbox_x = x()+Fl::box_dx(box());
- si.innerbox_y = y()+Fl::box_dy(box());
- si.innerbox_w = w()-Fl::box_dw(box());
- si.innerbox_h = h()-Fl::box_dh(box());
+ si.innerbox.x = x()+Fl::box_dx(box());
+ si.innerbox.y = y()+Fl::box_dy(box());
+ si.innerbox.w = w()-Fl::box_dw(box());
+ si.innerbox.h = h()-Fl::box_dh(box());
// accumulate a bounding box for all the children
- si.child_l = si.innerbox_x;
- si.child_r = si.innerbox_x;
- si.child_b = si.innerbox_y;
- si.child_t = si.innerbox_y;
+ si.child.l = si.innerbox.x;
+ si.child.r = si.innerbox.x;
+ si.child.b = si.innerbox.y;
+ si.child.t = si.innerbox.y;
int first = 1;
Fl_Widget*const* a = array();
- for (int i=children()-2; i--;) {
+ for (int i=children(); i--;) {
Fl_Widget* o = *a++;
+ if ( o==&scrollbar || o==&hscrollbar ) continue;
if ( first ) {
first = 0;
- si.child_l = o->x();
- si.child_r = o->x()+o->w();
- si.child_b = o->y()+o->h();
- si.child_t = o->y();
+ si.child.l = o->x();
+ si.child.r = o->x()+o->w();
+ si.child.b = o->y()+o->h();
+ si.child.t = o->y();
} else {
- if (o->x() < si.child_l) si.child_l = o->x();
- if (o->y() < si.child_t) si.child_t = o->y();
- if (o->x()+o->w() > si.child_r) si.child_r = o->x()+o->w();
- if (o->y()+o->h() > si.child_b) si.child_b = o->y()+o->h();
+ if (o->x() < si.child.l) si.child.l = o->x();
+ if (o->y() < si.child.t) si.child.t = o->y();
+ if (o->x()+o->w() > si.child.r) si.child.r = o->x()+o->w();
+ if (o->y()+o->h() > si.child.b) si.child.b = o->y()+o->h();
}
}
// Turn the scrollbars on and off as necessary.
// See if children would fit if we had no scrollbars...
{
- int X = si.innerbox_x;
- int Y = si.innerbox_y;
- int W = si.innerbox_w;
- int H = si.innerbox_h;
+ int X = si.innerbox.x;
+ int Y = si.innerbox.y;
+ int W = si.innerbox.w;
+ int H = si.innerbox.h;
si.scrollsize = scrollbar_size_ ? scrollbar_size_ : Fl::scrollbar_size();
si.vneeded = 0;
si.hneeded = 0;
if (type() & VERTICAL) {
- if ((type() & ALWAYS_ON) || si.child_t < Y || si.child_b > Y+H) {
+ if ((type() & ALWAYS_ON) || si.child.t < Y || si.child.b > Y+H) {
si.vneeded = 1;
W -= si.scrollsize;
if (scrollbar.align() & FL_ALIGN_LEFT) X += si.scrollsize;
}
}
if (type() & HORIZONTAL) {
- if ((type() & ALWAYS_ON) || si.child_l < X || si.child_r > X+W) {
+ if ((type() & ALWAYS_ON) || si.child.l < X || si.child.r > X+W) {
si.hneeded = 1;
H -= si.scrollsize;
if (scrollbar.align() & FL_ALIGN_TOP) Y += si.scrollsize;
// recheck vertical since we added a horizontal scrollbar
if (!si.vneeded && (type() & VERTICAL)) {
- if ((type() & ALWAYS_ON) || si.child_t < Y || si.child_b > Y+H) {
+ if ((type() & ALWAYS_ON) || si.child.t < Y || si.child.b > Y+H) {
si.vneeded = 1;
W -= si.scrollsize;
if (scrollbar.align() & FL_ALIGN_LEFT) X += si.scrollsize;
@@ -161,51 +162,51 @@ void Fl_Scroll::recalc_scrollbars(ScrollInfo &si) {
}
}
}
- si.innerchild_x = X;
- si.innerchild_y = Y;
- si.innerchild_w = W;
- si.innerchild_h = H;
+ si.innerchild.x = X;
+ si.innerchild.y = Y;
+ si.innerchild.w = W;
+ si.innerchild.h = H;
}
// calculate hor scrollbar position
- si.hscroll_x = si.innerchild_x;
- si.hscroll_y = (scrollbar.align() & FL_ALIGN_TOP)
- ? si.innerbox_y
- : si.innerbox_y + si.innerbox_h - si.scrollsize;
- si.hscroll_w = si.innerchild_w;
- si.hscroll_h = si.scrollsize;
+ si.hscroll.x = si.innerchild.x;
+ si.hscroll.y = (scrollbar.align() & FL_ALIGN_TOP)
+ ? si.innerbox.y
+ : si.innerbox.y + si.innerbox.h - si.scrollsize;
+ si.hscroll.w = si.innerchild.w;
+ si.hscroll.h = si.scrollsize;
// calculate ver scrollbar position
- si.vscroll_x = (scrollbar.align() & FL_ALIGN_LEFT)
- ? si.innerbox_x
- : si.innerbox_x + si.innerbox_w - si.scrollsize;
- si.vscroll_y = si.innerchild_y;
- si.vscroll_w = si.scrollsize;
- si.vscroll_h = si.innerchild_h;
+ si.vscroll.x = (scrollbar.align() & FL_ALIGN_LEFT)
+ ? si.innerbox.x
+ : si.innerbox.x + si.innerbox.w - si.scrollsize;
+ si.vscroll.y = si.innerchild.y;
+ si.vscroll.w = si.scrollsize;
+ si.vscroll.h = si.innerchild.h;
// calculate h/v scrollbar values (pos/size/first/total)
- si.hpos = si.innerchild_x - si.child_l;
- si.hsize = si.innerchild_w;
- si.hfirst = 0;
- si.htotal = si.child_r - si.child_l;
- if ( si.hpos < 0 ) { si.htotal += (-si.hpos); si.hfirst = si.hpos; }
-
- si.vpos = si.innerchild_y - si.child_t;
- si.vsize = si.innerchild_h;
- si.vfirst = 0;
- si.vtotal = si.child_b - si.child_t;
- if ( si.vpos < 0 ) { si.vtotal += (-si.vpos); si.vfirst = si.vpos; }
+ si.hscroll.pos = si.innerchild.x - si.child.l;
+ si.hscroll.size = si.innerchild.w;
+ si.hscroll.first = 0;
+ si.hscroll.total = si.child.r - si.child.l;
+ if ( si.hscroll.pos < 0 ) { si.hscroll.total += (-si.hscroll.pos); si.hscroll.first = si.hscroll.pos; }
+
+ si.vscroll.pos = si.innerchild.y - si.child.t;
+ si.vscroll.size = si.innerchild.h;
+ si.vscroll.first = 0;
+ si.vscroll.total = si.child.b - si.child.t;
+ if ( si.vscroll.pos < 0 ) { si.vscroll.total += (-si.vscroll.pos); si.vscroll.first = si.vscroll.pos; }
// printf("DEBUG --- ScrollInfo ---\n");
// printf("DEBUG scrollsize: %d\n", si.scrollsize);
// printf("DEBUG hneeded, vneeded: %d %d\n", si.hneeded, si.vneeded);
-// printf("DEBUG innerbox xywh: %d %d %d %d\n", si.innerbox_x, si.innerbox_y, si.innerbox_w, si.innerbox_h);
-// printf("DEBUG innerchild xywh: %d %d %d %d\n", si.innerchild_x, si.innerchild_y, si.innerchild_w, si.innerchild_h);
-// printf("DEBUG child lrbt: %d %d %d %d\n", si.child_l, si.child_r, si.child_b, si.child_t);
-// printf("DEBUG hscroll xywh: %d %d %d %d\n", si.hscroll_x, si.hscroll_y, si.hscroll_w, si.hscroll_h);
-// printf("DEBUG vscroll xywh: %d %d %d %d\n", si.vscroll_x, si.vscroll_y, si.vscroll_w, si.vscroll_h);
-// printf("DEBUG horz scroll vals: %d %d %d %d\n", si.hpos, si.hsize, si.hfirst, si.htotal);
-// printf("DEBUG vert scroll vals: %d %d %d %d\n", si.vpos, si.vsize, si.vfirst, si.vtotal);
+// printf("DEBUG innerbox.x, si.innerbox.y, si.innerbox.w,si.innerbox.h);
+// printf("DEBUG innerchild.xywh: %d %d %d %d\n", si.innerchild.x, si.innerchild.y, si.innerchild.w, si.innerchild.h);
+// printf("DEBUG child lrbt: %d %d %d %d\n", si.child.l, si.child.r, si.child.b, si.child.t);
+// printf("DEBUG hscroll xywh: %d %d %d %d\n", si.hscroll.x, si.hscroll.y, si.hscroll.w, si.hscroll.h);
+// printf("DEBUG vscroll xywh: %d %d %d %d\n", si.vscroll.x, si.vscroll.y, si.vscroll.w, si.vscroll.h);
+// printf("DEBUG horz scroll vals: %d %d %d %d\n", si.hscroll.pos, si.hscroll.size, si.hscroll.first, si.hscroll.total);
+// printf("DEBUG vert scroll vals: %d %d %d %d\n", si.vscroll.pos, si.vscroll.size, si.vscroll.first, si.vscroll.total);
// printf("DEBUG \n");
}
@@ -286,7 +287,7 @@ void Fl_Scroll::draw() {
}
else if (!si.vneeded && scrollbar.visible()) {
scrollbar.clear_visible();
- draw_clip(this, si.vscroll_x, si.vscroll_y, si.vscroll_w, si.vscroll_h);
+ draw_clip(this, si.vscroll.x, si.vscroll.y, si.vscroll.w, si.vscroll.h);
d = FL_DAMAGE_ALL;
}
if (si.hneeded && !hscrollbar.visible()) {
@@ -295,7 +296,7 @@ void Fl_Scroll::draw() {
}
else if (!si.hneeded && hscrollbar.visible()) {
hscrollbar.clear_visible();
- draw_clip(this, si.hscroll_x, si.hscroll_y, si.hscroll_w, si.hscroll_h);
+ draw_clip(this, si.hscroll.x, si.hscroll.y, si.hscroll.w, si.hscroll.h);
d = FL_DAMAGE_ALL;
}
else if ( hscrollbar.h() != si.scrollsize || scrollbar.w() != si.scrollsize ) {
@@ -303,13 +304,13 @@ void Fl_Scroll::draw() {
d = FL_DAMAGE_ALL;
}
- scrollbar.resize(si.vscroll_x, si.vscroll_y, si.vscroll_w, si.vscroll_h);
- oldy = yposition_ = si.vpos; // si.innerchild_y - si.child_t;
- scrollbar.value(si.vpos, si.vsize, si.vfirst, si.vtotal);
+ scrollbar.resize(si.vscroll.x, si.vscroll.y, si.vscroll.w, si.vscroll.h);
+ oldy = yposition_ = si.vscroll.pos; // si.innerchild.y - si.child.t;
+ scrollbar.value(si.vscroll.pos, si.vscroll.size, si.vscroll.first, si.vscroll.total);
- hscrollbar.resize(si.hscroll_x, si.hscroll_y, si.hscroll_w, si.hscroll_h);
- oldx = xposition_ = si.hpos; // si.innerchild_x - si.child_l;
- hscrollbar.value(si.hpos, si.hsize, si.hfirst, si.htotal);
+ hscrollbar.resize(si.hscroll.x, si.hscroll.y, si.hscroll.w, si.hscroll.h);
+ oldx = xposition_ = si.hscroll.pos; // si.innerchild.x - si.child.l;
+ hscrollbar.value(si.hscroll.pos, si.hscroll.size, si.hscroll.first, si.hscroll.total);
}
// draw the scrollbars:
@@ -383,7 +384,7 @@ void Fl_Scroll::scrollbar_cb(Fl_Widget* o, void*) {
whole tree to be deleted at once, without having to keep a pointer to
all the children in the user code. A kludge has been done so the
Fl_Scroll and all of its children can be automatic (local)
- variables, but you must declare the Fl_Scroll<I>first</I>, so
+ variables, but you must declare the Fl_Scroll <I>first</I>, so
that it is destroyed last.
*/
Fl_Scroll::Fl_Scroll(int X,int Y,int W,int H,const char* L)
@@ -407,5 +408,5 @@ int Fl_Scroll::handle(int event) {
}
//
-// End of "$Id: Fl_Scroll.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $".
+// End of "$Id: Fl_Scroll.cxx 10221 2014-07-16 18:51:56Z greg.ercolano $".
//
diff --git a/src/Fl_Sys_Menu_Bar.cxx b/src/Fl_Sys_Menu_Bar.cxx
deleted file mode 100644
index 698d562..0000000
--- a/src/Fl_Sys_Menu_Bar.cxx
+++ /dev/null
@@ -1,289 +0,0 @@
-//
-// "$Id: Fl_Sys_Menu_Bar.cxx 9637 2012-07-24 04:37:22Z matt $"
-//
-// MacOS system menu bar widget for the Fast Light Tool Kit (FLTK).
-//
-// Copyright 1998-2010 by Bill Spitzak and others.
-//
-// This library is free software. Distribution and use rights are outlined in
-// the file "COPYING" which should have been included with this file. If this
-// file is missing or damaged, see the license at:
-//
-// http://www.fltk.org/COPYING.php
-//
-// Please report all bugs and problems on the following page:
-//
-// http://www.fltk.org/str.php
-//
-
-/**
- * This code is a quick hack! It was written as a proof of concept.
- * It has been tested on the "menubar" sample program and provides
- * basic functionality.
- *
- * To use the System Menu Bar, simply replace the main Fl_Menu_Bar
- * in an application with Fl_Sys_Menu_Bar.
- *
- * FLTK features not supported by the Mac System menu
- *
- * - no invisible menu items
- * - no symbolic labels
- * - embossed labels will be underlined instead
- * - no font sizes
- * - Shortcut Characters should be English alphanumeric only, no modifiers yet
- * - no disable main menus
- * - changes to menubar in run-time don't update!
- * (disable, etc. - toggle and radio button do!)
- *
- * No care was taken to clean up the menu bar after destruction!
- * ::menu(bar) should only be called once!
- * Many other calls of the parent class don't work.
- * Changing the menu items has no effect on the menu bar.
- * Starting with OS X 10.5, FLTK applications must be created as
- * a bundle for the System Menu Bar (and maybe other features) to work!
- */
-
-#if defined(__APPLE__) || defined(FL_DOXYGEN)
-
-#include <FL/x.H>
-#include <FL/Fl.H>
-#include <FL/Fl_Sys_Menu_Bar.H>
-
-#include "flstring.h"
-#include <stdio.h>
-#include <ctype.h>
-#include <stdarg.h>
-
-#define MenuHandle void *
-
-typedef const Fl_Menu_Item *pFl_Menu_Item;
-
-
-/*
- * Set a shortcut for an Apple menu item using the FLTK shortcut descriptor.
- */
-static void setMenuShortcut( MenuHandle mh, int miCnt, const Fl_Menu_Item *m )
-{
- if ( !m->shortcut_ )
- return;
- if ( m->flags & FL_SUBMENU )
- return;
- if ( m->flags & FL_SUBMENU_POINTER )
- return;
- char key = m->shortcut_ & 0xff;
- if ( !isalnum( key ) )
- return;
-
- void *menuItem = Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::itemAtIndex, mh, miCnt);
- Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::setKeyEquivalent, menuItem, m->shortcut_ & 0xff );
- Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::setKeyEquivalentModifierMask, menuItem, m->shortcut_ );
-}
-
-
-/*
- * Set the Toggle and Radio flag based on FLTK flags
- */
-static void setMenuFlags( MenuHandle mh, int miCnt, const Fl_Menu_Item *m )
-{
- if ( m->flags & FL_MENU_TOGGLE )
- {
- void *menuItem = Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::itemAtIndex, mh, miCnt);
- Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::setState, menuItem, m->flags & FL_MENU_VALUE );
- }
- else if ( m->flags & FL_MENU_RADIO ) {
- void *menuItem = Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::itemAtIndex, mh, miCnt);
- Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::setState, menuItem, m->flags & FL_MENU_VALUE );
- }
-}
-
-
-/*
- * create a sub menu for a specific menu handle
- */
-static void createSubMenu( void * mh, pFl_Menu_Item &mm, const Fl_Menu_Item *mitem)
-{
- void *submenu;
- int miCnt, flags;
-
- void *menuItem;
- submenu = Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::initWithTitle, mitem->text);
- int cnt;
- Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::numberOfItems, mh, &cnt);
- cnt--;
- menuItem = Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::itemAtIndex, mh, cnt);
- Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::setSubmenu, menuItem, submenu);
-
- while ( mm->text )
- {
- char visible = mm->visible() ? 1 : 0;
- Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::addNewItem, submenu, mm, &miCnt);
- setMenuFlags( submenu, miCnt, mm );
- setMenuShortcut( submenu, miCnt, mm );
- if ( mm->flags & FL_MENU_INACTIVE || mitem->flags & FL_MENU_INACTIVE) {
- void *item = Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::itemAtIndex, submenu, miCnt);
- Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::setEnabled, item, 0);
- }
- flags = mm->flags;
- if ( mm->flags & FL_SUBMENU )
- {
- mm++;
- createSubMenu( submenu, mm, mm - 1 );
- }
- else if ( mm->flags & FL_SUBMENU_POINTER )
- {
- const Fl_Menu_Item *smm = (Fl_Menu_Item*)mm->user_data_;
- createSubMenu( submenu, smm, mm );
- }
- if ( flags & FL_MENU_DIVIDER ) {
- Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::addSeparatorItem, submenu);
- }
- if ( !visible ) {
- Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::removeItem, submenu, miCnt);
- }
- mm++;
- }
-}
-
-
-/*
- * convert a complete Fl_Menu_Item array into a series of menus in the top menu bar
- * ALL PREVIOUS SYSTEM MENUS, EXCEPT THE APPLICATION MENU, ARE REPLACED BY THE NEW DATA
- */
-static void convertToMenuBar(const Fl_Menu_Item *mm)
-{
- int rank;
- int count;//first, delete all existing system menus
- Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::numberOfItems, fl_system_menu, &count);
- for(int i = count - 1; i > 0; i--) {
- Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::removeItem, fl_system_menu, i);
- }
- //now convert FLTK stuff into MacOS menus
- for (;;)
- {
- if ( !mm || !mm->text )
- break;
- char visible = mm->visible() ? 1 : 0;
- Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::addNewItem, fl_system_menu, mm, &rank);
-
- if ( mm->flags & FL_SUBMENU ) {
- mm++;
- createSubMenu( fl_system_menu, mm, mm - 1);
- }
- else if ( mm->flags & FL_SUBMENU_POINTER ) {
- const Fl_Menu_Item *smm = (Fl_Menu_Item*)mm->user_data_;
- createSubMenu( fl_system_menu, smm, mm);
- }
- if ( !visible ) {
- Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::removeItem, fl_system_menu, rank);
- }
- mm++;
- }
-}
-
-
-/**
- * @brief create a system menu bar using the given list of menu structs
- *
- * \author Matthias Melcher
- *
- * @param m list of Fl_Menu_Item
- */
-void Fl_Sys_Menu_Bar::menu(const Fl_Menu_Item *m)
-{
- fl_open_display();
- Fl_Menu_Bar::menu( m );
- convertToMenuBar(m);
-}
-
-
-/**
- * @brief add to the system menu bar a new menu item
- *
- * add to the system menu bar a new menu item, with a title string, shortcut int,
- * callback, argument to the callback, and flags.
- *
- * @see Fl_Menu_::add(const char* label, int shortcut, Fl_Callback *cb, void *user_data, int flags)
- */
-int Fl_Sys_Menu_Bar::add(const char* label, int shortcut, Fl_Callback *cb, void *user_data, int flags)
-{
- fl_open_display();
- int rank = Fl_Menu_::add(label, shortcut, cb, user_data, flags);
- convertToMenuBar(Fl_Menu_::menu());
- return rank;
-}
-
-/**
- * @brief insert in the system menu bar a new menu item
- *
- * insert in the system menu bar a new menu item, with a title string, shortcut int,
- * callback, argument to the callback, and flags.
- *
- * @see Fl_Menu_::insert(int index, const char* label, int shortcut, Fl_Callback *cb, void *user_data, int flags)
- */
-int Fl_Sys_Menu_Bar::insert(int index, const char* label, int shortcut, Fl_Callback *cb, void *user_data, int flags)
-{
- fl_open_display();
- int rank = Fl_Menu_::insert(index, label, shortcut, cb, user_data, flags);
- convertToMenuBar(Fl_Menu_::menu());
- return rank;
-}
-
-void Fl_Sys_Menu_Bar::clear()
-{
- Fl_Menu_::clear();
- convertToMenuBar(NULL);
-}
-
-int Fl_Sys_Menu_Bar::clear_submenu(int index)
-{
- int retval = Fl_Menu_::clear_submenu(index);
- if (retval != -1) convertToMenuBar(Fl_Menu_::menu());
- return retval;
-}
-
-/**
- * @brief remove an item from the system menu bar
- *
- * @param rank the rank of the item to remove
- */
-void Fl_Sys_Menu_Bar::remove(int rank)
-{
- Fl_Menu_::remove(rank);
- convertToMenuBar(Fl_Menu_::menu());
-}
-
-
-/**
- * @brief rename an item from the system menu bar
- *
- * @param rank the rank of the item to rename
- * @param name the new item name as a UTF8 string
- */
-void Fl_Sys_Menu_Bar::replace(int rank, const char *name)
-{
- Fl_Menu_::replace(rank, name);
- convertToMenuBar(Fl_Menu_::menu());
-}
-
-
-/*
- * Draw the menu bar.
- * Nothing here because the OS does this for us.
- */
-void Fl_Sys_Menu_Bar::draw() {
-}
-
-
-Fl_Sys_Menu_Bar::Fl_Sys_Menu_Bar(int x,int y,int w,int h,const char *l)
-: Fl_Menu_Bar(x,y,w,h,l)
-{
- deactivate(); // don't let the old area take events
- fl_sys_menu_bar = this;
-}
-
-
-#endif /* __APPLE__ */
-
-//
-// End of "$Id: Fl_Sys_Menu_Bar.cxx 9637 2012-07-24 04:37:22Z matt $".
-//
diff --git a/src/Fl_Sys_Menu_Bar.mm b/src/Fl_Sys_Menu_Bar.mm
new file mode 100644
index 0000000..0b62fa5
--- /dev/null
+++ b/src/Fl_Sys_Menu_Bar.mm
@@ -0,0 +1,508 @@
+//
+// "$Id: Fl_Sys_Menu_Bar.mm 10106 2014-02-19 16:02:56Z manolo $"
+//
+// MacOS system menu bar widget for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2013 by Bill Spitzak and others.
+//
+// This library is free software. Distribution and use rights are outlined in
+// the file "COPYING" which should have been included with this file. If this
+// file is missing or damaged, see the license at:
+//
+// http://www.fltk.org/COPYING.php
+//
+// Please report all bugs and problems on the following page:
+//
+// http://www.fltk.org/str.php
+//
+
+/*
+ * This code has been tested on the "menubar" sample program and provides
+ * basic functionality.
+ *
+ * To use the System Menu Bar, simply replace the main Fl_Menu_Bar
+ * in an application with Fl_Sys_Menu_Bar.
+ *
+ * FLTK features not supported by the Mac System menu
+ *
+ * - no symbolic labels
+ * - no embossed labels
+ * - no font sizes
+ *
+ * Many other calls of the parent class don't work.
+ */
+
+#if defined(__APPLE__) || defined(FL_DOXYGEN)
+#include <FL/Fl_Menu_Item.H>
+#include <FL/Fl_Sys_Menu_Bar.H>
+#include <FL/x.H>
+#include <FL/Fl.H>
+
+#import <Cocoa/Cocoa.h>
+
+#ifndef NSINTEGER_DEFINED // appears with 10.5 in NSObjCRuntime.h
+#if defined(__LP64__) && __LP64__
+typedef long NSInteger;
+typedef unsigned long NSUInteger;
+#else
+typedef long NSInteger;
+typedef unsigned int NSUInteger;
+#endif
+#endif
+
+#include "flstring.h"
+#include <stdio.h>
+#include <ctype.h>
+#include <stdarg.h>
+
+typedef const Fl_Menu_Item *pFl_Menu_Item;
+
+Fl_Sys_Menu_Bar *fl_sys_menu_bar = 0;
+
+static char *remove_ampersand(const char *s);
+extern void (*fl_lock_function)();
+extern void (*fl_unlock_function)();
+
+/* Each MacOS system menu item contains a pointer to a record of type sys_menu_item defined below.
+ The purpose of these records is to associate each MacOS system menu item with a relevant Fl_Menu_Item.
+ If use_rank is YES, the "rank" field is used, and fl_sys_menu_bar->menu() + rank is the address
+ of the relevant Fl_Menu_Item;
+ Otherwise, the "item" field points to the relevant Fl_Menu_Item.
+ This allows the MacOS system menu to use the same Fl_Menu_Item's as those used by FLTK menus,
+ the address of which can be relocated by the FLTK menu logic.
+ The "item" field is used for non-relocatable Fl_Menu_Item's associated to FL_SUBMENU_POINTER.
+ Sending the getFlItem message to a MacOS system menu item (of class FLMenuItem) returns the address
+ of the relevant Fl_Menu_Item.
+*/
+typedef struct {
+ union {
+ int rank;
+ const Fl_Menu_Item *item;
+ };
+ BOOL use_rank;
+} sys_menu_item;
+
+
+@interface FLMenuItem : NSMenuItem {
+}
+- (void) doCallback:(id)unused;
+- (void) directCallback:(id)unused;
+- (const Fl_Menu_Item*) getFlItem;
+- (void) setKeyEquivalentModifierMask:(int)value;
+- (void) setFltkShortcut:(int)key;
++ (int) addNewItem:(const Fl_Menu_Item*)mitem menu:(NSMenu*)menu;
+@end
+
+@implementation FLMenuItem
+- (const Fl_Menu_Item*) getFlItem
+// returns the Fl_Menu_Item corresponding to this system menu item
+{
+ sys_menu_item *smi = (sys_menu_item*)[(NSData*)[self representedObject] bytes];
+ if (smi->use_rank) return fl_sys_menu_bar->menu() + smi->rank;
+ return smi->item;
+}
+- (void) doCallback:(id)unused
+{
+ fl_lock_function();
+ const Fl_Menu_Item *item = [self getFlItem];
+ fl_sys_menu_bar->picked(item);
+ if ( item->flags & FL_MENU_TOGGLE ) { // update the menu toggle symbol
+ [self setState:(item->value() ? NSOnState : NSOffState)];
+ }
+ else if ( item->flags & FL_MENU_RADIO ) { // update the menu radio symbols
+ NSMenu* menu = [self menu];
+ NSInteger flRank = [menu indexOfItem:self];
+ NSInteger last = [menu numberOfItems] - 1;
+ int from = flRank;
+ while(from > 0) {
+ if ([[menu itemAtIndex:from-1] isSeparatorItem]) break;
+ item = [(FLMenuItem*)[menu itemAtIndex:from-1] getFlItem];
+ if ( !(item->flags & FL_MENU_RADIO) ) break;
+ from--;
+ }
+ int to = flRank;
+ while (to < last) {
+ if ([[menu itemAtIndex:to+1] isSeparatorItem]) break;
+ item = [(FLMenuItem*)[menu itemAtIndex:to+1] getFlItem];
+ if (!(item->flags & FL_MENU_RADIO)) break;
+ to++;
+ }
+ for(int i = from; i <= to; i++) {
+ NSMenuItem *nsitem = [menu itemAtIndex:i];
+ [nsitem setState:(nsitem != self ? NSOffState : NSOnState)];
+ }
+ }
+ fl_unlock_function();
+}
+- (void) directCallback:(id)unused
+{
+ fl_lock_function();
+ Fl_Menu_Item *item = (Fl_Menu_Item *)[(NSData*)[self representedObject] bytes];
+ if ( item && item->callback() ) item->do_callback(NULL);
+ fl_unlock_function();
+}
+- (void) setKeyEquivalentModifierMask:(int)value
+{
+ NSUInteger macMod = 0;
+ if ( value & FL_META ) macMod = NSCommandKeyMask;
+ if ( value & FL_SHIFT || isupper(value) ) macMod |= NSShiftKeyMask;
+ if ( value & FL_ALT ) macMod |= NSAlternateKeyMask;
+ if ( value & FL_CTRL ) macMod |= NSControlKeyMask;
+ [super setKeyEquivalentModifierMask:macMod];
+}
+- (void) setFltkShortcut:(int)key
+{
+ // Separate key and modifier
+ int mod = key;
+ mod &= ~FL_KEY_MASK; // modifier(s)
+ key &= FL_KEY_MASK; // key
+ unichar mac_key = (unichar)key;
+ if ( (key >= (FL_F+1)) && (key <= FL_F_Last) ) { // Handle function keys
+ int fkey_num = (key - FL_F); // 1,2..
+ mac_key = NSF1FunctionKey + fkey_num - 1;
+ }
+ [self setKeyEquivalent:[NSString stringWithCharacters:&mac_key length:1]];
+ [self setKeyEquivalentModifierMask:mod];
+}
++ (int) addNewItem:(const Fl_Menu_Item*)mitem menu:(NSMenu*)menu
+{
+ char *name = remove_ampersand(mitem->label());
+ CFStringRef cfname = CFStringCreateWithCString(NULL, name, kCFStringEncodingUTF8);
+ free(name);
+ FLMenuItem *item = [[FLMenuItem alloc] initWithTitle:(NSString*)cfname
+ action:@selector(doCallback:)
+ keyEquivalent:@""];
+ sys_menu_item smi;
+ smi.rank = fl_sys_menu_bar->find_index(mitem); // ≥ 0 if mitem is in the menu items of fl_sys_menu_bar, -1 if not
+ smi.use_rank = (smi.rank >= 0);
+ if (!smi.use_rank) smi.item = mitem;
+ NSData *pointer = [NSData dataWithBytes:&smi length:sizeof(smi)];
+ [item setRepresentedObject:pointer];
+ [menu addItem:item];
+ CFRelease(cfname);
+ [item setTarget:item];
+ int retval = [menu indexOfItem:item];
+ [item release];
+ return retval;
+}
+@end
+
+
+void fl_mac_set_about( Fl_Callback *cb, void *user_data, int shortcut)
+{
+ fl_open_display();
+ Fl_Menu_Item aboutItem;
+ memset(&aboutItem, 0, sizeof(Fl_Menu_Item));
+ aboutItem.callback(cb);
+ aboutItem.user_data(user_data);
+ aboutItem.shortcut(shortcut);
+ NSMenu *appleMenu = [[[NSApp mainMenu] itemAtIndex:0] submenu];
+ CFStringRef cfname = CFStringCreateCopy(NULL, (CFStringRef)[[appleMenu itemAtIndex:0] title]);
+ [appleMenu removeItemAtIndex:0];
+ FLMenuItem *item = [[[FLMenuItem alloc] initWithTitle:(NSString*)cfname
+ action:@selector(directCallback:)
+ keyEquivalent:@""] autorelease];
+ if (aboutItem.shortcut())
+ [item setFltkShortcut:aboutItem.shortcut()];
+ NSData *pointer = [NSData dataWithBytes:&aboutItem length:sizeof(Fl_Menu_Item)];
+ [item setRepresentedObject:pointer];
+ [appleMenu insertItem:item atIndex:0];
+ CFRelease(cfname);
+ [item setTarget:item];
+}
+
+/*
+ * Set a shortcut for an Apple menu item using the FLTK shortcut descriptor.
+ */
+static void setMenuShortcut( NSMenu* mh, int miCnt, const Fl_Menu_Item *m )
+{
+ if ( !m->shortcut_ )
+ return;
+ if ( m->flags & FL_SUBMENU )
+ return;
+ if ( m->flags & FL_SUBMENU_POINTER )
+ return;
+ FLMenuItem* menuItem = (FLMenuItem*)[mh itemAtIndex:miCnt];
+ [menuItem setFltkShortcut:(m->shortcut_)];
+}
+
+
+/*
+ * Set the Toggle and Radio flag based on FLTK flags
+ */
+static void setMenuFlags( NSMenu* mh, int miCnt, const Fl_Menu_Item *m )
+{
+ if ( m->flags & FL_MENU_TOGGLE )
+ {
+ NSMenuItem *menuItem = [mh itemAtIndex:miCnt];
+ [menuItem setState:(m->flags & FL_MENU_VALUE ? NSOnState : NSOffState)];
+ }
+ else if ( m->flags & FL_MENU_RADIO ) {
+ NSMenuItem *menuItem = [mh itemAtIndex:miCnt];
+ [menuItem setState:(m->flags & FL_MENU_VALUE ? NSOnState : NSOffState)];
+ }
+}
+
+static char *remove_ampersand(const char *s)
+{
+ char *ret = strdup(s);
+ const char *p = s;
+ char *q = ret;
+ while(*p != 0) {
+ if (p[0]=='&') {
+ if (p[1]=='&') {
+ *q++ = '&'; p+=2;
+ } else {
+ p++;
+ }
+ } else {
+ *q++ = *p++;
+ }
+ }
+ *q = 0;
+ return ret;
+}
+
+
+/*
+ * create a sub menu for a specific menu handle
+ */
+static void createSubMenu( NSMenu *mh, pFl_Menu_Item &mm, const Fl_Menu_Item *mitem)
+{
+ NSMenu *submenu;
+ int miCnt, flags;
+
+ NSMenuItem *menuItem;
+ char *ts = remove_ampersand(mitem->text);
+ CFStringRef title = CFStringCreateWithCString(NULL, ts, kCFStringEncodingUTF8);
+ free(ts);
+ submenu = [[NSMenu alloc] initWithTitle:(NSString*)title];
+ CFRelease(title);
+ [submenu setAutoenablesItems:NO];
+
+ int cnt;
+ cnt = [mh numberOfItems];
+ cnt--;
+ menuItem = [mh itemAtIndex:cnt];
+ [menuItem setSubmenu:submenu];
+ [submenu release];
+
+ while ( mm->text )
+ {
+ if (!mm->visible() ) { // skip invisible items and submenus
+ mm = mm->next(0);
+ continue;
+ }
+ miCnt = [FLMenuItem addNewItem:mm menu:submenu];
+ setMenuFlags( submenu, miCnt, mm );
+ setMenuShortcut( submenu, miCnt, mm );
+ if ( mm->flags & FL_MENU_INACTIVE || mitem->flags & FL_MENU_INACTIVE) {
+ NSMenuItem *item = [submenu itemAtIndex:miCnt];
+ [item setEnabled:NO];
+ }
+ flags = mm->flags;
+ if ( mm->flags & FL_SUBMENU )
+ {
+ mm++;
+ createSubMenu( submenu, mm, mm - 1 );
+ }
+ else if ( mm->flags & FL_SUBMENU_POINTER )
+ {
+ const Fl_Menu_Item *smm = (Fl_Menu_Item*)mm->user_data_;
+ createSubMenu( submenu, smm, mm);
+ }
+ if ( flags & FL_MENU_DIVIDER ) {
+ [submenu addItem:[NSMenuItem separatorItem]];
+ }
+ mm++;
+ }
+}
+
+
+/*
+ * convert a complete Fl_Menu_Item array into a series of menus in the top menu bar
+ * ALL PREVIOUS SYSTEM MENUS, EXCEPT THE APPLICATION MENU, ARE REPLACED BY THE NEW DATA
+ */
+static void convertToMenuBar(const Fl_Menu_Item *mm)
+{
+ NSMenu *fl_system_menu = [NSApp mainMenu];
+ int rank;
+ int count;//first, delete all existing system menus
+ count = [fl_system_menu numberOfItems];
+ for(int i = count - 1; i > 0; i--) {
+ [fl_system_menu removeItem:[fl_system_menu itemAtIndex:i]];
+ }
+ //now convert FLTK stuff into MacOS menus
+ for (;;)
+ {
+ if ( !mm || !mm->text )
+ break;
+ if (!mm->visible() ) { // skip invisible menus
+ mm = mm->next(0);
+ continue;
+ }
+ rank = [FLMenuItem addNewItem:mm menu:fl_system_menu];
+
+ if ( mm->flags & FL_SUBMENU ) {
+ mm++;
+ createSubMenu(fl_system_menu, mm, mm - 1);
+ }
+ else if ( mm->flags & FL_SUBMENU_POINTER ) {
+ const Fl_Menu_Item *smm = (Fl_Menu_Item*)mm->user_data_;
+ createSubMenu(fl_system_menu, smm, mm);
+ }
+ mm++;
+ }
+}
+
+
+/**
+ * @brief create a system menu bar using the given list of menu structs
+ *
+ * \author Matthias Melcher
+ *
+ * @param m list of Fl_Menu_Item
+ */
+void Fl_Sys_Menu_Bar::menu(const Fl_Menu_Item *m)
+{
+ fl_open_display();
+ Fl_Menu_Bar::menu( m );
+ convertToMenuBar(m);
+}
+
+
+/**
+ * @brief add to the system menu bar a new menu item
+ *
+ * add to the system menu bar a new menu item, with a title string, shortcut int,
+ * callback, argument to the callback, and flags.
+ *
+ * @see Fl_Menu_::add(const char* label, int shortcut, Fl_Callback *cb, void *user_data, int flags)
+ */
+int Fl_Sys_Menu_Bar::add(const char* label, int shortcut, Fl_Callback *cb, void *user_data, int flags)
+{
+ fl_open_display();
+ int rank = Fl_Menu_::add(label, shortcut, cb, user_data, flags);
+ update();
+ return rank;
+}
+
+/**
+ * Forms-compatible procedure to add items to the system menu bar
+*
+ * @see Fl_Menu_::add(const char* str)
+ */
+int Fl_Sys_Menu_Bar::add(const char* str)
+{
+ fl_open_display();
+ int rank = Fl_Menu_::add(str);
+ update();
+ return rank;
+}
+
+/**
+ * @brief insert in the system menu bar a new menu item
+ *
+ * insert in the system menu bar a new menu item, with a title string, shortcut int,
+ * callback, argument to the callback, and flags.
+ *
+ * @see Fl_Menu_::insert(int index, const char* label, int shortcut, Fl_Callback *cb, void *user_data, int flags)
+ */
+int Fl_Sys_Menu_Bar::insert(int index, const char* label, int shortcut, Fl_Callback *cb, void *user_data, int flags)
+{
+ fl_open_display();
+ int rank = Fl_Menu_::insert(index, label, shortcut, cb, user_data, flags);
+ update();
+ return rank;
+}
+
+void Fl_Sys_Menu_Bar::clear()
+{
+ Fl_Menu_::clear();
+ convertToMenuBar(NULL);
+}
+
+int Fl_Sys_Menu_Bar::clear_submenu(int index)
+{
+ int retval = Fl_Menu_::clear_submenu(index);
+ if (retval != -1) update();
+ return retval;
+}
+
+/**
+ * @brief remove an item from the system menu bar
+ *
+ * @param rank the rank of the item to remove
+ */
+void Fl_Sys_Menu_Bar::remove(int rank)
+{
+ Fl_Menu_::remove(rank);
+ update();
+}
+
+
+/**
+ * @brief rename an item from the system menu bar
+ *
+ * @param rank the rank of the item to rename
+ * @param name the new item name as a UTF8 string
+ */
+void Fl_Sys_Menu_Bar::replace(int rank, const char *name)
+{
+ Fl_Menu_::replace(rank, name);
+ update();
+}
+
+/** Updates the system menu after any change to its items.
+ */
+void Fl_Sys_Menu_Bar::update()
+{
+ convertToMenuBar(Fl_Menu_::menu());
+}
+
+/*
+ * Draw the menu bar.
+ * Nothing here because the OS does this for us.
+ */
+void Fl_Sys_Menu_Bar::draw() {
+}
+
+static int process_sys_menu_shortcuts(int event)
+{
+ if (event != FL_SHORTCUT || !fl_sys_menu_bar || Fl::modal()) return 0;
+ // is the last event the shortcut of an item of the fl_sys_menu_bar menu ?
+ const Fl_Menu_Item *item = fl_sys_menu_bar->menu()->test_shortcut();
+ if (!item) return 0;
+ if (item->visible()) // have the system menu process the shortcut, highlighting the corresponding menu
+ [[NSApp mainMenu] performKeyEquivalent:[NSApp currentEvent]];
+ else // have FLTK process the shortcut associated to an invisible Fl_Menu_Item
+ fl_sys_menu_bar->picked(item);
+ return 1;
+}
+
+
+/**
+ The constructor.
+ On Mac OS X, all arguments are unused. On other platforms they are used as by Fl_Menu_Bar::Fl_Menu_Bar().
+ */
+Fl_Sys_Menu_Bar::Fl_Sys_Menu_Bar(int x,int y,int w,int h,const char *l)
+: Fl_Menu_Bar(x,y,w,h,l)
+{
+ deactivate(); // don't let the old area take events
+ fl_sys_menu_bar = this;
+ Fl::add_handler(process_sys_menu_shortcuts);
+}
+
+/** The destructor */
+Fl_Sys_Menu_Bar::~Fl_Sys_Menu_Bar()
+{
+ fl_sys_menu_bar = 0;
+ clear();
+ Fl::remove_handler(process_sys_menu_shortcuts);
+}
+
+#endif /* __APPLE__ */
+
+//
+// End of "$Id: Fl_Sys_Menu_Bar.mm 10106 2014-02-19 16:02:56Z manolo $".
+//
diff --git a/src/Fl_Table.cxx b/src/Fl_Table.cxx
index 98b67bd..7e42b2e 100644
--- a/src/Fl_Table.cxx
+++ b/src/Fl_Table.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: Fl_Table.cxx 9706 2012-11-06 20:46:14Z matt $"
+// "$Id: Fl_Table.cxx 10225 2014-08-03 16:40:58Z greg.ercolano $"
//
// Fl_Table -- A table widget
//
@@ -131,6 +131,9 @@ Fl_Table::Fl_Table(int X, int Y, int W, int H, const char *l) : Fl_Group(X,Y,W,H
#if FLTK_ABI_VERSION >= 10301
_scrollbar_size = 0;
#endif
+#if FLTK_ABI_VERSION >= 10303
+ flags_ = 0; // TABCELLNAV off
+#endif
box(FL_THIN_DOWN_FRAME);
vscrollbar = new Fl_Scrollbar(x()+w()-Fl::scrollbar_size(), y(),
@@ -196,7 +199,7 @@ void Fl_Table::col_width(int col, int width)
// Add column widths, even if none yet
int now_size = (int)_colwidths.size();
if ( col >= now_size ) {
- _colwidths.size(col);
+ _colwidths.size(col+1);
while (now_size < col) {
_colwidths[now_size++] = width;
}
@@ -674,7 +677,7 @@ void Fl_Table::damage_zone(int r1, int c1, int r2, int c2, int r3, int c3) {
redraw_range(R1, R2, C1, C2);
}
-int Fl_Table::move_cursor(int R, int C) {
+int Fl_Table::move_cursor(int R, int C, int shiftselect) {
if (select_row == -1) R++;
if (select_col == -1) C++;
R += select_row;
@@ -687,7 +690,7 @@ int Fl_Table::move_cursor(int R, int C) {
damage_zone(current_row, current_col, select_row, select_col, R, C);
select_row = R;
select_col = C;
- if (!Fl::event_state(FL_SHIFT)) {
+ if (!shiftselect || !Fl::event_state(FL_SHIFT)) {
current_row = R;
current_col = C;
}
@@ -696,7 +699,11 @@ int Fl_Table::move_cursor(int R, int C) {
return 1;
}
-// #define DEBUG 1
+int Fl_Table::move_cursor(int R, int C) {
+ return move_cursor(R,C,1);
+}
+
+//#define DEBUG 1
#ifdef DEBUG
#include <FL/names.h>
#define PRINTEVENT \
@@ -729,7 +736,9 @@ int Fl_Table::handle(int event) {
int _event_x = Fl::event_x();
int _event_y = Fl::event_y();
int _event_key = Fl::event_key();
+#if FLTK_ABI_VERSION >= 10303
int _event_state = Fl::event_state();
+#endif
Fl_Widget *_focus = Fl::focus();
switch ( event ) {
case FL_PUSH:
@@ -746,8 +755,11 @@ int Fl_Table::handle(int event) {
current_col = select_col = C;
_selecting = CONTEXT_CELL;
} else {
- current_row = select_row = -1;
- current_col = select_col = -1;
+ // Clear selection if not resizing row/col
+ if ( !resizeflag ) {
+ current_row = select_row = -1;
+ current_col = select_col = -1;
+ }
}
}
// A click on table with user's callback defined?
@@ -796,6 +808,7 @@ int Fl_Table::handle(int event) {
ret = 1;
} else {
// Not resizing? Select the column
+ if ( Fl::focus() != this && contains(Fl::focus()) ) return 0; // STR #3018 - item 1
current_col = select_col = C;
current_row = 0;
select_row = rows() - 1;
@@ -822,6 +835,7 @@ int Fl_Table::handle(int event) {
ret = 1;
} else {
// Not resizing? Select the row
+ if ( Fl::focus() != this && contains(Fl::focus()) ) return 0; // STR #3018 - item 1
current_row = select_row = R;
current_col = 0;
select_col = cols() - 1;
@@ -887,6 +901,8 @@ int Fl_Table::handle(int event) {
if (_event_button == 1 &&
_selecting == CONTEXT_CELL &&
context == CONTEXT_CELL) {
+ // Dragging a cell selection?
+ if ( _event_clicks ) break; // STR #3018 - item 2
if (select_row != R || select_col != C) {
damage_zone(current_row, current_col, select_row, select_col, R, C);
}
@@ -1020,12 +1036,17 @@ int Fl_Table::handle(int event) {
ret = move_cursor(1, 0);
break;
case FL_Tab:
+#if FLTK_ABI_VERSION >= 10303
+ if ( !tab_cell_nav() ) break; // not navigating cells? let fltk handle it (STR#2862)
if ( _event_state & FL_SHIFT ) {
- ret = move_cursor(0, -1); // shift-tab -> left
+ ret = move_cursor(0, -1, 0); // shift-tab -> left
} else {
- ret = move_cursor(0, 1); // tab -> right
+ ret = move_cursor(0, 1, 0); // tab -> right
}
break;
+#else
+ break; // without tab_cell_nav(), Fl_Table should default to navigating widgets, not cells
+#endif
}
if (ret && Fl::focus() != this) {
do_callback(CONTEXT_TABLE, -1, -1);
@@ -1293,5 +1314,5 @@ void Fl_Table::draw() {
}
//
-// End of "$Id: Fl_Table.cxx 9706 2012-11-06 20:46:14Z matt $".
+// End of "$Id: Fl_Table.cxx 10225 2014-08-03 16:40:58Z greg.ercolano $".
//
diff --git a/src/Fl_Tabs.cxx b/src/Fl_Tabs.cxx
index 8302afb..75d4458 100644
--- a/src/Fl_Tabs.cxx
+++ b/src/Fl_Tabs.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: Fl_Tabs.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $"
+// "$Id: Fl_Tabs.cxx 10122 2014-03-24 18:24:59Z greg.ercolano $"
//
// Tab widget for the Fast Light Tool Kit (FLTK).
//
@@ -114,8 +114,13 @@ int Fl_Tabs::tab_height() {
else return (H <= 0) ? 0 : H;
}
-// This is used for event handling (clicks) and by fluid to pick tabs.
-// Returns 0, if children() = 0, or if the event is outside of the tabs area.
+/**
+ Return the widget of the tab the user clicked on at \p event_x / \p event_y.
+ This is used for event handling (clicks) and by fluid to pick tabs.
+
+ \returns The child widget of the tab the user clicked on, or<br>
+ 0 if there are no children or if the event is outside of the tabs area.
+*/
Fl_Widget *Fl_Tabs::which(int event_x, int event_y) {
if (children() == 0) return 0;
int H = tab_height();
@@ -173,7 +178,11 @@ int Fl_Tabs::handle(int event) {
Fl::focus(this);
redraw_tabs();
}
- if (o && value(o)) {
+ if (o && // Released on a tab and..
+ (value(o) || // tab changed value or..
+ (when()&(FL_WHEN_NOT_CHANGED)) // ..no change but WHEN_NOT_CHANGED set,
+ ) // handles FL_WHEN_RELEASE_ALWAYS too.
+ ) {
Fl_Widget_Tracker wp(o);
set_changed();
do_callback();
@@ -257,6 +266,17 @@ int Fl_Tabs::handle(int event) {
}
}
+/**
+ This is called by the tab widget's handle() method to set the
+ tab group widget the user last FL_PUSH'ed on. Set back to zero
+ on FL_RELEASE.
+
+ As of this writing, the value is mainly used by draw_tab()
+ to determine whether or not to draw a 'down' box for the tab
+ when it's clicked, and to turn it off if the user drags off it.
+
+ \see push().
+*/
int Fl_Tabs::push(Fl_Widget *o) {
if (push_ == o) return 0;
if ( (push_ && !push_->visible()) || (o && !o->visible()) )
@@ -288,6 +308,8 @@ Fl_Widget* Fl_Tabs::value() {
Sets the widget to become the current visible widget/tab.
Setting the value hides all other children, and makes this one
visible, if it is really a child.
+ \returns 1 if there was a change (new value different from previous),<BR>
+ 0 if there was no change (new value already set)
*/
int Fl_Tabs::value(Fl_Widget *newvalue) {
Fl_Widget*const* a = array();
@@ -518,5 +540,5 @@ void Fl_Tabs::clear_tab_positions() {
}
//
-// End of "$Id: Fl_Tabs.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $".
+// End of "$Id: Fl_Tabs.cxx 10122 2014-03-24 18:24:59Z greg.ercolano $".
//
diff --git a/src/Fl_Text_Buffer.cxx b/src/Fl_Text_Buffer.cxx
index e7c9e99..d4350d8 100644
--- a/src/Fl_Text_Buffer.cxx
+++ b/src/Fl_Text_Buffer.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: Fl_Text_Buffer.cxx 9366 2012-04-21 15:05:00Z fabien $"
+// "$Id: Fl_Text_Buffer.cxx 10083 2014-01-25 23:47:44Z AlbrechtS $"
//
// Copyright 2001-2010 by Bill Spitzak and others.
// Original code Copyright Mark Edel. Permission to distribute under
@@ -139,9 +139,9 @@ Fl_Text_Buffer::~Fl_Text_Buffer()
delete[]mModifyProcs;
delete[]mCbArgs;
}
- if (mNPredeleteProcs != 0) {
- delete[]mPredeleteProcs;
- delete[]mPredeleteCbArgs;
+ if (mNPredeleteProcs > 0) {
+ delete[] mPredeleteProcs;
+ delete[] mPredeleteCbArgs;
}
}
@@ -735,9 +735,9 @@ void Fl_Text_Buffer::add_predelete_callback(Fl_Text_Predelete_Cb bufPreDeleteCB,
newPreDeleteProcs[i + 1] = mPredeleteProcs[i];
newCBArgs[i + 1] = mPredeleteCbArgs[i];
}
- if (!mNPredeleteProcs != 0) {
- delete[]mPredeleteProcs;
- delete[]mPredeleteCbArgs;
+ if (mNPredeleteProcs > 0) {
+ delete[] mPredeleteProcs;
+ delete[] mPredeleteCbArgs;
}
newPreDeleteProcs[0] = bufPreDeleteCB;
newCBArgs[0] = cbArg;
@@ -767,19 +767,16 @@ void Fl_Text_Buffer::remove_predelete_callback(Fl_Text_Predelete_Cb bufPreDelete
return;
}
- /* Allocate new lists for remaining callback procs and args (if
- any are left) */
+ /* Allocate new lists for remaining callback procs and args (if any are left) */
mNPredeleteProcs--;
if (mNPredeleteProcs == 0) {
- mNPredeleteProcs = 0;
delete[]mPredeleteProcs;
mPredeleteProcs = NULL;
delete[]mPredeleteCbArgs;
mPredeleteCbArgs = NULL;
return;
}
- Fl_Text_Predelete_Cb *newPreDeleteProcs =
- new Fl_Text_Predelete_Cb[mNPredeleteProcs];
+ Fl_Text_Predelete_Cb *newPreDeleteProcs = new Fl_Text_Predelete_Cb[mNPredeleteProcs];
void **newCBArgs = new void *[mNPredeleteProcs];
/* copy out the remaining members and free the old lists */
@@ -791,8 +788,8 @@ void Fl_Text_Buffer::remove_predelete_callback(Fl_Text_Predelete_Cb bufPreDelete
newPreDeleteProcs[i] = mPredeleteProcs[i + 1];
newCBArgs[i] = mPredeleteCbArgs[i + 1];
}
- delete[]mPredeleteProcs;
- delete[]mPredeleteCbArgs;
+ delete[] mPredeleteProcs;
+ delete[] mPredeleteCbArgs;
mPredeleteProcs = newPreDeleteProcs;
mPredeleteCbArgs = newCBArgs;
}
@@ -1805,5 +1802,5 @@ int Fl_Text_Buffer::utf8_align(int pos) const
}
//
-// End of "$Id: Fl_Text_Buffer.cxx 9366 2012-04-21 15:05:00Z fabien $".
+// End of "$Id: Fl_Text_Buffer.cxx 10083 2014-01-25 23:47:44Z AlbrechtS $".
//
diff --git a/src/Fl_Text_Display.cxx b/src/Fl_Text_Display.cxx
index d418df7..0255fe8 100644
--- a/src/Fl_Text_Display.cxx
+++ b/src/Fl_Text_Display.cxx
@@ -1,12 +1,12 @@
//
-// "$Id: Fl_Text_Display.cxx 9362 2012-04-21 03:02:25Z fabien $"
+// "$Id: Fl_Text_Display.cxx 10416 2014-10-30 12:35:36Z AlbrechtS $"
//
-// Copyright 2001-2010 by Bill Spitzak and others.
+// Copyright 2001-2014 by Bill Spitzak and others.
// Original code Copyright Mark Edel. Permission to distribute under
// the LGPL for the FLTK library granted by Mark Edel.
//
// This library is free software. Distribution and use rights are outlined in
-// the file "COPYING" which should have been included with this file. If this
+// the file "COPYING" which should have been included with this file. If this
// file is missing or damaged, see the license at:
//
// http://www.fltk.org/COPYING.php
@@ -17,7 +17,7 @@
//
// TODO: rendering of the "optional hyphen"
-// TODO: make line numbering work again
+// TODO: font background color control via style buffer
#include <stdio.h>
#include <stdlib.h>
@@ -25,6 +25,7 @@
#include "flstring.h"
#include <limits.h>
#include <ctype.h>
+#include <string.h> // strdup()
#include <FL/Fl.H>
#include <FL/Fl_Text_Buffer.H>
#include <FL/Fl_Text_Display.H>
@@ -152,6 +153,14 @@ Fl_Text_Display::Fl_Text_Display(int X, int Y, int W, int H, const char* l)
mContinuousWrap = 0;
mWrapMarginPix = 0;
mSuppressResync = mNLinesDeleted = mModifyingTabDistance = 0;
+#if FLTK_ABI_VERSION >= 10303
+ linenumber_font_ = FL_HELVETICA;
+ linenumber_size_ = FL_NORMAL_SIZE;
+ linenumber_fgcolor_ = FL_INACTIVE_COLOR;
+ linenumber_bgcolor_ = 53; // ~90% gray
+ linenumber_align_ = FL_ALIGN_RIGHT;
+ linenumber_format_ = strdup("%d");
+#endif
}
@@ -172,9 +181,189 @@ Fl_Text_Display::~Fl_Text_Display() {
mBuffer->remove_predelete_callback(buffer_predelete_cb, this);
}
if (mLineStarts) delete[] mLineStarts;
+#if FLTK_ABI_VERSION >= 10303
+ if (linenumber_format_) {
+ free((void*)linenumber_format_);
+ linenumber_format_ = 0;
+ }
+#endif
+}
+
+
+/**
+ Set width of screen area for line numbers.
+ Use to also enable/disable line numbers.
+ A value of 0 disables line numbering, values >0 enables them.
+ \param width The new width of the area for line numbers to appear, in pixels.
+ 0 disables line numbers (default)
+*/
+void Fl_Text_Display::linenumber_width(int width) {
+ if (width < 0) return;
+ mLineNumWidth = width;
+ resize(x(), y(), w(), h()); // triggers code to recalculate line#s
+}
+
+/**
+ Return the screen area width provided for line numbers.
+*/
+int Fl_Text_Display::linenumber_width() const {
+ return mLineNumWidth;
+}
+
+/**
+ Set the font used for line numbers (if enabled).
+ \version 1.3.3 ABI feature (ignored in 1.3.x unless FLTK_ABI_VERSION is 10303 or higher)
+*/
+void Fl_Text_Display::linenumber_font(Fl_Font val) {
+#if FLTK_ABI_VERSION >= 10303
+ linenumber_font_ = val;
+#else
+ // do nothing
+#endif
+}
+
+/**
+ Return the font used for line numbers (if enabled).
+*/
+Fl_Font Fl_Text_Display::linenumber_font() const {
+#if FLTK_ABI_VERSION >= 10303
+ return linenumber_font_;
+#else
+ return FL_HELVETICA;
+#endif
+}
+
+/**
+ Set the font size used for line numbers (if enabled).
+ \version 1.3.3 ABI feature (ignored in 1.3.x unless FLTK_ABI_VERSION is 10303 or higher)
+*/
+void Fl_Text_Display::linenumber_size(Fl_Fontsize val) {
+#if FLTK_ABI_VERSION >= 10303
+ linenumber_size_ = val;
+#else
+ // do nothing
+#endif
+}
+
+/**
+ Return the font size used for line numbers (if enabled).
+*/
+Fl_Fontsize Fl_Text_Display::linenumber_size() const {
+#if FLTK_ABI_VERSION >= 10303
+ return linenumber_size_;
+#else
+ return FL_NORMAL_SIZE;
+#endif
+}
+
+/**
+ Set the foreground color used for line numbers (if enabled).
+ \version 1.3.3 ABI feature (ignored in 1.3.x unless FLTK_ABI_VERSION is 10303 or higher)
+*/
+void Fl_Text_Display::linenumber_fgcolor(Fl_Color val) {
+#if FLTK_ABI_VERSION >= 10303
+ linenumber_fgcolor_ = val;
+#else
+ // do nothing
+#endif
+}
+
+/**
+ Return the foreground color used for line numbers (if enabled).
+*/
+Fl_Color Fl_Text_Display::linenumber_fgcolor() const {
+#if FLTK_ABI_VERSION >= 10303
+ return linenumber_fgcolor_;
+#else
+ return FL_INACTIVE_COLOR;
+#endif
}
+/**
+ Set the background color used for line numbers (if enabled).
+ \version 1.3.3 ABI feature (ignored in 1.3.x unless FLTK_ABI_VERSION is 10303 or higher)
+*/
+void Fl_Text_Display::linenumber_bgcolor(Fl_Color val) {
+#if FLTK_ABI_VERSION >= 10303
+ linenumber_bgcolor_ = val;
+#else
+ // do nothing
+#endif
+}
+/**
+ Returns the background color used for line numbers (if enabled).
+*/
+Fl_Color Fl_Text_Display::linenumber_bgcolor() const {
+#if FLTK_ABI_VERSION >= 10303
+ return linenumber_bgcolor_;
+#else
+ return 53; // hard coded ~90% gray
+#endif
+}
+
+/**
+ Set alignment for line numbers (if enabled).
+ Valid values are FL_ALIGN_LEFT, FL_ALIGN_CENTER or FL_ALIGN_RIGHT.
+ \version 1.3.3 ABI feature (ignored in 1.3.x unless FLTK_ABI_VERSION is 10303 or higher)
+*/
+void Fl_Text_Display::linenumber_align(Fl_Align val) {
+#if FLTK_ABI_VERSION >= 10303
+ linenumber_align_ = val;
+#else
+ // do nothing
+#endif
+}
+
+/**
+ Returns the alignment used for line numbers (if enabled).
+*/
+Fl_Align Fl_Text_Display::linenumber_align() const {
+#if FLTK_ABI_VERSION >= 10303
+ return linenumber_align_;
+#else
+ return FL_ALIGN_RIGHT;
+#endif
+}
+
+/**
+ Sets the printf() style format string used for line numbers.
+ Default is "%d" for normal unpadded decimal integers.
+
+ An internal copy of \p val is allocated and managed;
+ it is automatically freed whenever a new value is assigned,
+ or when the widget is destroyed.
+
+ The value of \p val must \a not be NULL.
+
+ Example values:
+
+ - "%d" -- For normal line numbers without padding (Default)
+ - "%03d" -- For 000 padding
+ - "%x" -- For hexadecimal line numbers
+ - "%o" -- For octal line numbers
+
+ \version 1.3.3 ABI feature (ignored in 1.3.x unless FLTK_ABI_VERSION is 10303 or higher)
+*/
+void Fl_Text_Display::linenumber_format(const char* val) {
+#if FLTK_ABI_VERSION >= 10303
+ if ( linenumber_format_ ) free((void*)linenumber_format_);
+ linenumber_format_ = val ? strdup(val) : 0;
+#else
+ // do nothing
+#endif
+}
+
+/**
+ Returns the line number printf() format string.
+*/
+const char* Fl_Text_Display::linenumber_format() const {
+#if FLTK_ABI_VERSION >= 10303
+ return linenumber_format_;
+#else
+ return "%d";
+#endif
+}
/**
Attach a text buffer to display, replacing the current buffer (if any)
@@ -406,6 +595,12 @@ void Fl_Text_Display::resize(int X, int Y, int W, int H) {
}
}
+ // add linenum width to the text area - LZA / STR#2621
+ if (mLineNumWidth > 0) {
+ text_area.x += mLineNumWidth;
+ text_area.w -= mLineNumWidth;
+ }
+
// user request to change viewport
if (mTopLineNumHint != mTopLineNum || mHorizOffsetHint != mHorizOffset)
scroll_(mTopLineNumHint, mHorizOffsetHint);
@@ -465,10 +660,6 @@ void Fl_Text_Display::draw_text( int left, int top, int width, int height ) {
for ( line = firstLine; line <= lastLine; line++ )
draw_vline( line, left, left + width, 0, INT_MAX );
- /* draw the line numbers if exposed area includes them */
- if (mLineNumWidth != 0 && left <= mLineNumLeft + mLineNumWidth)
- draw_line_numbers(false);
-
fl_pop_clip();
}
@@ -700,7 +891,7 @@ void Fl_Text_Display::wrap_mode(int wrap, int wrapMargin) {
mNBufferLines = 0;
mFirstChar = 0;
mTopLineNum = 1;
- mAbsTopLineNum = 0;
+ mAbsTopLineNum = 1; // changed from 0 to 1 -- LZA / STR#2621
}
resize(x(), y(), w(), h());
@@ -1514,8 +1705,10 @@ void Fl_Text_Display::buffer_modified_cb( int pos, int nInserted, int nDeleted,
// CET - FIXME if ( origCursorPos >= startDispPos &&
// ( origCursorPos <= endDispPos || endDispPos == buf->length() ) )
}
-
- if (linesInserted > 1) textD->draw_line_numbers(false);
+ if (linesInserted > 1) {
+ // textD->draw_line_numbers(false); // can't do this b/c not called from virtual draw();
+ textD->damage(::FL_DAMAGE_EXPOSE);
+ }
} else {
endDispPos = buf->next_char(textD->mLastChar);
// CET - FIXME if ( origCursorPos >= pos )
@@ -1524,7 +1717,11 @@ void Fl_Text_Display::buffer_modified_cb( int pos, int nInserted, int nDeleted,
have changed. If only one line is altered, line numbers cannot
be affected (the insertion or removal of a line break always
results in at least two lines being redrawn). */
- textD->draw_line_numbers(false);
+
+ // Call draw_line_numbers() here to ensure line# is drawn
+ // when hitting enter for new line -- LZA / STR #2621
+ //textD->draw_line_numbers(true); // no, can't call this here, not in draw() context -- ERCO / STR#2621
+ //textD->damage(::FL_DAMAGE_EXPOSE);
}
IS_UTF8_ALIGNED2(buf, startDispPos)
IS_UTF8_ALIGNED2(buf, endDispPos)
@@ -1543,6 +1740,7 @@ void Fl_Text_Display::buffer_modified_cb( int pos, int nInserted, int nDeleted,
}
+/* Line Numbering Methods */
/**
\brief Line numbering stuff, currently unused.
@@ -1940,7 +2138,13 @@ void Fl_Text_Display::draw_string(int style,
fsize = styleRec->size;
if (style & PRIMARY_MASK) {
- if (Fl::focus() == (Fl_Widget*)this) background = selection_color();
+ if (Fl::focus() == (Fl_Widget*)this) {
+#ifdef __APPLE__
+ if (Fl::compose_state) background = color();// Mac OS: underline marked text
+ else
+#endif
+ background = selection_color();
+ }
else background = fl_color_average(color(), selection_color(), 0.4f);
} else if (style & HIGHLIGHT_MASK) {
if (Fl::focus() == (Fl_Widget*)this) background = fl_color_average(color(), selection_color(), 0.5f);
@@ -1972,6 +2176,12 @@ void Fl_Text_Display::draw_string(int style,
fl_push_clip(X, Y, toX - X, mMaxsize);
#endif
fl_draw( string, nChars, X, Y + mMaxsize - fl_descent());
+#ifdef __APPLE__ // Mac OS: underline marked (= selected + Fl::compose_state != 0) text
+ if (Fl::compose_state && (style & PRIMARY_MASK)) {
+ fl_color( fl_color_average(foreground, background, 0.6) );
+ fl_line(X, Y + mMaxsize - 1, X + fl_width(string, nChars), Y + mMaxsize - 1);
+ }
+#endif
#if !(defined(__APPLE__) || defined(WIN32)) && USE_XFT
fl_pop_clip();
#endif
@@ -2055,6 +2265,9 @@ void Fl_Text_Display::draw_cursor( int X, int Y ) {
if ( X < text_area.x - 1 || X > text_area.x + text_area.w )
return;
+#ifdef __APPLE__
+ Fl::insertion_point_location(X, bot, fontHeight);
+#endif
/* For cursors other than the block, make them around 2/3 of a character
width, rounded to an even number of pixels so that X will draw an
odd number centered on the stem at x. */
@@ -2630,63 +2843,71 @@ void Fl_Text_Display::h_scrollbar_cb(Fl_Scrollbar* b, Fl_Text_Display* textD) {
/**
\brief Refresh the line number area.
-
- If clearAll is False, writes only over the character cell areas. Setting
- clearAll to True will clear out any stray marks outside of the character cell
- area, which might have been left from before a resize or font change.
-
- This function is not used.
+ \param clearAll -- (currently unused) If False, only draws the line number text,
+ does not clear the area behind it. If True, clears the area
+ and redraws the text. Use False to avoid a 'flash' for
+ single buffered windows.
*/
+
+// This draw_line_numbers() method based on patch from
+// http://www.mail-archive.com/fltk-dev@easysw.com/msg06376.html
+// altered to support line numbers right alignment. -LZA / STR #2621
+//
void Fl_Text_Display::draw_line_numbers(bool /*clearAll*/) {
-#if 0
- int y, line, visLine, nCols, lineStart;
- char lineNumString[12];
- int lineHeight = mMaxsize ? mMaxsize : textsize_;
- int charWidth = TMPFONTWIDTH; //mFontStruct->max_bounds.width;
-
- /* Don't draw if mLineNumWidth == 0 (line numbers are hidden), or widget is
- not yet realized */
- if (mLineNumWidth == 0 || visible_r())
+ int Y, line, visLine, lineStart;
+ char lineNumString[16];
+ int lineHeight = mMaxsize;
+
+ // Don't draw if lineNumWidth == 0 (line numbers are hidden),
+ // or widget is not yet realized
+ if (mLineNumWidth <= 0 || !visible_r())
return;
- /* GC is allocated on demand, since not everyone will use line numbering */
- if (textD->lineNumGC == NULL) {
- XGCValues values;
- values.foreground = textD->lineNumFGPixel;
- values.background = textD->bgPixel;
- values.font = textD->fontStruct->fid;
- textD->lineNumGC = XtGetGC(textD->w,
- GCFont| GCForeground | GCBackground, &values);
- }
-
- /* Erase the previous contents of the line number area, if requested */
- if (clearAll)
- XClearArea(XtDisplay(textD->w), XtWindow(textD->w), textD->lineNumLeft,
- textD->top, textD->lineNumWidth, textD->height, False);
-
- /* Draw the line numbers, aligned to the text */
- nCols = min(11, textD->lineNumWidth / charWidth);
- y = textD->top;
- line = getAbsTopLineNum(textD);
- for (visLine=0; visLine < textD->nVisibleLines; visLine++) {
- lineStart = textD->lineStarts[visLine];
- if (lineStart != -1 && (lineStart==0 ||
- BufGetCharacter(textD->buffer, lineStart-1)=='\n')) {
- sprintf(lineNumString, "%*d", nCols, line);
- XDrawImageString(XtDisplay(textD->w), XtWindow(textD->w),
- textD->lineNumGC, textD->lineNumLeft, y + textD->ascent,
- lineNumString, strlen(lineNumString));
- line++;
- } else {
- XClearArea(XtDisplay(textD->w), XtWindow(textD->w),
- textD->lineNumLeft, y, textD->lineNumWidth,
- textD->ascent + textD->descent, False);
- if (visLine == 0)
- line++;
+ // Make sure we reset clipping range for line number's GC;
+ // it may be shared (e.g. if line numbers and text have same color)
+ // and therefore clipping ranges may be invalid.
+ int xoff = Fl::box_dx(box());
+ int hscroll_h = mHScrollBar->visible() ? mHScrollBar->h() : 0;
+ fl_push_clip(x() + xoff,
+ y() + Fl::box_dy(box()),
+ mLineNumWidth - xoff,
+ h() - Fl::box_dh(box()) - hscroll_h);
+ {
+ // Set background color for line number area -- LZA / STR# 2621
+ // Erase background
+ fl_color(linenumber_bgcolor());
+ fl_rectf(x(), y(), mLineNumWidth, h());
+
+ // Draw separator line
+ //fl_color(180,180,180);
+ //fl_line(x()+mLineNumWidth-1, y(), x()+mLineNumWidth-1, y()+h());
+
+ // Draw line number text
+ fl_font(linenumber_font(), linenumber_size());
+
+ Y = y();
+ line = get_absolute_top_line_number();
+
+ // set font color for line numbers
+ fl_color(linenumber_fgcolor());
+ for (visLine=0; visLine < mNVisibleLines; visLine++) {
+ lineStart = mLineStarts[visLine];
+ if (lineStart != -1 && (lineStart==0 || buffer()->char_at(lineStart-1)=='\n')) {
+ sprintf(lineNumString, linenumber_format(), line);
+ int xx = x() + xoff + 3,
+ yy = Y + 3,
+ ww = mLineNumWidth - xoff - (3*2),
+ hh = lineHeight;
+ fl_draw(lineNumString, xx, yy, ww, hh, linenumber_align(), 0, 0);
+ //DEBUG fl_rect(xx, yy, ww, hh);
+ line++;
+ } else {
+ if (visLine == 0) line++;
+ }
+ Y += lineHeight;
}
- y += lineHeight;
- }
-#endif
+ }
+ fl_pop_clip();
}
static int max( int i1, int i2 ) {
@@ -3042,12 +3263,13 @@ void Fl_Text_Display::measure_deleted_lines(int pos, int nDeleted) {
and the styleBufOffset argument must indicate the starting position of the
copy, to take into account the correct style information.
- \param buf
- \param startPos
- \param maxPos
- \param maxLines
- \param startPosIsLineStart
- \param styleBufOffset
+ \param[in] buf The text buffer to operate on
+ \param[in] startPos Starting index position into the buffer
+ \param[in] maxPos Maximum index position into the buffer we'll reach
+ \param[in] maxLines Maximum number of lines we'll reach
+ \param[in] startPosIsLineStart Flag indicating if startPos is start of line.
+ (If set, prevents our having to find the line start)
+ \param[in] styleBufOffset Offset index position into style buffer.
\param[out] retPos Position where counting ended. When counting lines, the
position returned is the start of the line "maxLines" lines
@@ -3147,9 +3369,13 @@ void Fl_Text_Display::wrapped_line_counter(Fl_Text_Buffer *buf, int startPos,
if (b<lineStart) b = lineStart;
if (!foundBreak) { /* no whitespace, just break at margin */
newLineStart = max(p, buf->next_char(lineStart));
- const char *s = buf->address(b);
colNum++;
- width = measure_proportional_character(s, 0, p+styleBufOffset);
+ if (b >= buf->length()) { // STR #2730
+ width = 0;
+ } else {
+ const char *s = buf->address(b);
+ width = measure_proportional_character(s, 0, p+styleBufOffset);
+ }
}
if (p >= maxPos) {
*retPos = maxPos;
@@ -3401,8 +3627,7 @@ void Fl_Text_Display::draw(void) {
fl_rectf(mVScrollBar->x(), mHScrollBar->y(),
mVScrollBar->w(), mHScrollBar->h(),
FL_GRAY);
-
- // blank the previous cursor protrusions
+ //draw_line_numbers(true); // commented out STR# 2621 / LZA
}
else if (damage() & (FL_DAMAGE_SCROLL | FL_DAMAGE_EXPOSE)) {
// printf("blanking previous cursor extrusions at Y: %d\n", mCursorOldY);
@@ -3456,8 +3681,14 @@ void Fl_Text_Display::draw(void) {
}
// draw the text cursor
+ int start, end;
+ int has_selection = buffer()->selection_position(&start, &end);
if (damage() & (FL_DAMAGE_ALL | FL_DAMAGE_SCROLL | FL_DAMAGE_EXPOSE)
- && !buffer()->primary_selection()->selected() &&
+ && (
+#ifdef __APPLE__
+ Fl::compose_state ||
+#endif
+ !has_selection || mCursorPos < start || mCursorPos > end) &&
mCursorOn && Fl::focus() == (Fl_Widget*)this ) {
fl_push_clip(text_area.x-LEFT_MARGIN,
text_area.y,
@@ -3473,6 +3704,11 @@ void Fl_Text_Display::draw(void) {
//printf("drew cursor at pos: %d (%d,%d)\n", mCursorPos, X, Y);
fl_pop_clip();
}
+
+ // Important to do this at end of this method, otherwise line numbers
+ // will not scroll with the text edit area
+ draw_line_numbers(true);
+
fl_pop_clip();
}
@@ -3797,5 +4033,5 @@ double Fl_Text_Display::col_to_x(double col) const
//
-// End of "$Id: Fl_Text_Display.cxx 9362 2012-04-21 03:02:25Z fabien $".
+// End of "$Id: Fl_Text_Display.cxx 10416 2014-10-30 12:35:36Z AlbrechtS $".
//
diff --git a/src/Fl_Text_Editor.cxx b/src/Fl_Text_Editor.cxx
index 0ec6544..721b31a 100644
--- a/src/Fl_Text_Editor.cxx
+++ b/src/Fl_Text_Editor.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: Fl_Text_Editor.cxx 9325 2012-04-05 05:12:30Z fabien $"
+// "$Id: Fl_Text_Editor.cxx 10031 2013-12-13 16:28:38Z manolo $"
//
// Copyright 2001-2010 by Bill Spitzak and others.
// Original code Copyright Mark Edel. Permission to distribute under
@@ -73,6 +73,7 @@ Fl_Text_Editor::Fl_Text_Editor(int X, int Y, int W, int H, const char* l)
mCursorOn = 1;
insert_mode_ = 1;
key_bindings = 0;
+ set_flag(MAC_USE_ACCENTS_MENU);
// handle the default key bindings
add_default_key_bindings(&key_bindings);
@@ -514,8 +515,9 @@ int Fl_Text_Editor::handle_key() {
int del = 0;
if (Fl::compose(del)) {
if (del) {
- int dp = insert_position(), di = del;
- while (di--) dp = buffer()->prev_char_clipped(dp);
+ // del is a number of bytes
+ int dp = insert_position() - del;
+ if ( dp < 0 ) dp = 0;
buffer()->select(dp, insert_position());
}
kill_selection(this);
@@ -523,6 +525,12 @@ int Fl_Text_Editor::handle_key() {
if (insert_mode()) insert(Fl::event_text());
else overstrike(Fl::event_text());
}
+#ifdef __APPLE__
+ if (Fl::compose_state) {
+ int pos = this->insert_position();
+ this->buffer()->select(pos - Fl::compose_state, pos);
+ }
+#endif
show_insert_position();
set_changed();
if (when()&FL_WHEN_CHANGED) do_callback();
@@ -560,6 +568,13 @@ int Fl_Text_Editor::handle(int event) {
case FL_UNFOCUS:
show_cursor(mCursorOn); // redraws the cursor
+#ifdef __APPLE__
+ if (buffer()->selected() && Fl::compose_state) {
+ int pos = insert_position();
+ buffer()->select(pos, pos);
+ Fl::reset_marked_text();
+ }
+#endif
if (buffer()->selected()) redraw(); // Redraw selections...
case FL_HIDE:
if (when() & FL_WHEN_RELEASE) maybe_do_callback();
@@ -631,7 +646,7 @@ int Fl_Text_Editor::handle(int event) {
insert_position(dndCursorPos);
return 1;
case FL_DND_RELEASE: // keep insertion cursor and wait for the FL_PASTE event
- buffer()->unselect(); // FL_PASTE must not destroy current selection!
+ if (!dragging) buffer()->unselect(); // FL_PASTE must not destroy current selection if drag comes from outside
return 1;
}
@@ -639,5 +654,5 @@ int Fl_Text_Editor::handle(int event) {
}
//
-// End of "$Id: Fl_Text_Editor.cxx 9325 2012-04-05 05:12:30Z fabien $".
+// End of "$Id: Fl_Text_Editor.cxx 10031 2013-12-13 16:28:38Z manolo $".
//
diff --git a/src/Fl_Tile.cxx b/src/Fl_Tile.cxx
index e800110..dfe215f 100644
--- a/src/Fl_Tile.cxx
+++ b/src/Fl_Tile.cxx
@@ -1,12 +1,12 @@
//
-// "$Id: Fl_Tile.cxx 9637 2012-07-24 04:37:22Z matt $"
+// "$Id: Fl_Tile.cxx 10385 2014-10-19 14:17:47Z AlbrechtS $"
//
// Tile widget for the Fast Light Tool Kit (FLTK).
//
-// Copyright 1998-2010 by Bill Spitzak and others.
+// Copyright 1998-2014 by Bill Spitzak and others.
//
// This library is free software. Distribution and use rights are outlined in
-// the file "COPYING" which should have been included with this file. If this
+// the file "COPYING" which should have been included with this file. If this
// file is missing or damaged, see the license at:
//
// http://www.fltk.org/COPYING.php
@@ -16,23 +16,81 @@
// http://www.fltk.org/str.php
//
+/**
+ \class Fl_Tile
-// Group of 2 or 4 "tiles" that can be resized by dragging border
-// The size of the first child determines where the resize border is.
-// The resizebox is used to limit where the border can be dragged to.
+ The Fl_Tile class lets you resize its children by dragging
+ the border between them.
+
+ \image html Fl_Tile.png
+ \image latex Fl_Tile.png "Fl_Tile" width=5cm
+
+ For the tiling to work correctly, the children of an Fl_Tile must
+ cover the entire area of the widget, but not overlap.
+ This means that all children must touch each other at their edges,
+ and no gaps can be left inside the Fl_Tile.
+
+ Fl_Tile does not normally draw any graphics of its own.
+ The "borders" which can be seen in the snapshot above are actually
+ part of the children. Their boxtypes have been set to FL_DOWN_BOX
+ creating the impression of "ridges" where the boxes touch. What
+ you see are actually two adjacent FL_DOWN_BOX's drawn next to each
+ other. All neighboring widgets share the same edge - the widget's
+ thick borders make it appear as though the widgets aren't actually
+ touching, but they are. If the edges of adjacent widgets do not
+ touch, then it will be impossible to drag the corresponding edges.
+
+ Fl_Tile allows objects to be resized to zero dimensions.
+ To prevent this you can use the resizable() to limit where
+ corners can be dragged to. For more information see note below.
+
+ Even though objects can be resized to zero sizes, they must initially
+ have non-zero sizes so the Fl_Tile can figure out their layout.
+ If desired, call position() after creating the children but before
+ displaying the window to set the borders where you want.
+
+ <b>Note on resizable(Fl_Widget &w):</b>
+ The "resizable" child widget (which should be invisible) limits where
+ the borders can be dragged to. All dragging will be limited inside the
+ resizable widget's borders. If you don't set it, it will be possible
+ to drag the borders right to the edges of the Fl_Tile widget, and thus
+ resize objects on the edges to zero width or height. When the entire
+ Fl_Tile widget is resized, the resizable() widget will keep its border
+ distance to all borders the same (this is normal resize behavior), so
+ that you can effectively set a border width that will never change.
+
+ <b>Note:</b>
+ You can still resize widgets \b inside the resizable() to zero width and/or
+ height, i.e. box \b 2b above to zero width and box \b 3a to zero height.
+
+ \see void Fl_Group::resizable(Fl_Widget &w)
+
+ Example for resizable with 20 pixel border distance:
+ \code
+ int dx = 20, dy = dx;
+ Fl_Tile tile(50,50,300,300);
+ // ... create widgets inside tile (see test/tile.cxx) ...
+ // create resizable() box
+ Fl_Box r(tile.x()+dx,tile.y()+dy,tile.w()-2*dx,tile.h()-2*dy);
+ tile.resizable(r);
+ tile.end();
+ \endcode
+
+ See also the complete example program in test/tile.cxx.
+*/
#include <FL/Fl.H>
#include <FL/Fl_Tile.H>
#include <FL/Fl_Window.H>
#include <stdlib.h>
-// Drag the edges that were initially at oldx,oldy to newx,newy:
-// pass zero as oldx or oldy to disable drag in that direction:
-/**
- Drag the intersection at from_x,from_y to to_x,to_y.
+/**
+ Drags the intersection at (\p oldx,\p oldy) to (\p newx,\p newy).
This redraws all the necessary children.
+
+ Pass zero as \p oldx or \p oldy to disable drag in that direction.
*/
-void Fl_Tile::position(int oix, int oiy, int newx, int newy) {
+void Fl_Tile::position(int oldx, int oldy, int newx, int newy) {
Fl_Widget*const* a = array();
int *p = sizes();
p += 8; // skip group & resizable's saved size
@@ -41,28 +99,43 @@ void Fl_Tile::position(int oix, int oiy, int newx, int newy) {
if (o == resizable()) continue;
int X = o->x();
int R = X+o->w();
- if (oix) {
+ if (oldx) {
int t = p[0];
- if (t == oix || (t>oix && X<newx) || (t<oix && X>newx) ) X = newx;
+ if (t == oldx || (t>oldx && X<newx) || (t<oldx && X>newx) ) X = newx;
t = p[1];
- if (t == oix || (t>oix && R<newx) || (t<oix && R>newx) ) R = newx;
+ if (t == oldx || (t>oldx && R<newx) || (t<oldx && R>newx) ) R = newx;
}
int Y = o->y();
int B = Y+o->h();
- if (oiy) {
+ if (oldy) {
int t = p[2];
- if (t == oiy || (t>oiy && Y<newy) || (t<oiy && Y>newy) ) Y = newy;
+ if (t == oldy || (t>oldy && Y<newy) || (t<oldy && Y>newy) ) Y = newy;
t = p[3];
- if (t == oiy || (t>oiy && B<newy) || (t<oiy && B>newy) ) B = newy;
+ if (t == oldy || (t>oldy && B<newy) || (t<oldy && B>newy) ) B = newy;
}
o->damage_resize(X,Y,R-X,B-Y);
}
}
-// move the lower-right corner (sort of):
+/**
+ Resizes the Fl_Tile widget and its children.
+
+ Fl_Tile implements its own resize() method. It does not use
+ Fl_Group::resize() to resize itself and its children.
+
+ Enlarging works by just moving the lower-right corner and resizing
+ the bottom and right border widgets accordingly.
+
+ Shrinking the Fl_Tile works in the opposite way by shrinking
+ the bottom and right border widgets, unless they are reduced to zero
+ width or height, resp. or to their minimal sizes defined by the
+ resizable() widget. In this case other widgets will be shrunk as well.
+
+ See the Fl_Tile class documentation about how the resizable() works.
+*/
+
void Fl_Tile::resize(int X,int Y,int W,int H) {
- //Fl_Group::resize(X, Y, W, H);
- //return;
+
// remember how much to move the child widgets:
int dx = X-x();
int dy = Y-y();
@@ -71,11 +144,13 @@ void Fl_Tile::resize(int X,int Y,int W,int H) {
int *p = sizes();
// resize this (skip the Fl_Group resize):
Fl_Widget::resize(X,Y,W,H);
- // find bottom-right of resiable:
- int OR = p[5];
- int NR = X+W-(p[1]-OR);
- int OB = p[7];
- int NB = Y+H-(p[3]-OB);
+
+ // find bottom-right corner of resizable:
+ int OR = p[5]; // old right border
+ int NR = X+W-(p[1]-OR); // new right border
+ int OB = p[7]; // old bottom border
+ int NB = Y+H-(p[3]-OB); // new bottom border
+
// move everything to be on correct side of new resizable:
Fl_Widget*const* a = array();
p += 8;
@@ -90,7 +165,7 @@ void Fl_Tile::resize(int X,int Y,int W,int H) {
if (*p++ >= OB) yy += dh; else if (yy > NB) yy = NB;
if (*p++ >= OB) B += dh; else if (B > NB) B = NB;
o->resize(xx,yy,R-xx,B-yy);
- // do *not* call o->redraw() here! If you do, and the tile is inside a
+ // do *not* call o->redraw() here! If you do, and the tile is inside a
// scroll, it'll set the damage areas wrong for all children!
}
}
@@ -200,13 +275,26 @@ int Fl_Tile::handle(int event) {
return Fl_Group::handle(event);
}
+/**
+ Creates a new Fl_Tile widget using the given position, size,
+ and label string. The default boxtype is FL_NO_BOX.
+
+ The destructor <I>also deletes all the children</I>. This allows a
+ whole tree to be deleted at once, without having to keep a pointer to
+ all the children in the user code. A kludge has been done so the
+ Fl_Tile and all of its children can be automatic (local)
+ variables, but you must declare the Fl_Tile <I>first</I>, so
+ that it is destroyed last.
+
+ \see class Fl_Group
+*/
-Fl_Tile::Fl_Tile(int X,int Y,int W,int H,const char*l)
-: Fl_Group(X,Y,W,H,l)
+Fl_Tile::Fl_Tile(int X,int Y,int W,int H,const char*l)
+: Fl_Group(X,Y,W,H,l)
{
}
//
-// End of "$Id: Fl_Tile.cxx 9637 2012-07-24 04:37:22Z matt $".
+// End of "$Id: Fl_Tile.cxx 10385 2014-10-19 14:17:47Z AlbrechtS $".
//
diff --git a/src/Fl_Tiled_Image.cxx b/src/Fl_Tiled_Image.cxx
index d708742..2f459ea 100644
--- a/src/Fl_Tiled_Image.cxx
+++ b/src/Fl_Tiled_Image.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: Fl_Tiled_Image.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $"
+// "$Id: Fl_Tiled_Image.cxx 10218 2014-07-10 12:28:00Z manolo $"
//
// Tiled image code for the Fast Light Tool Kit (FLTK).
//
@@ -19,6 +19,7 @@
#include <FL/Fl.H>
#include <FL/Fl_Tiled_Image.H>
+#include <FL/Fl_Window.H>
#include <FL/fl_draw.H>
/**
@@ -31,9 +32,10 @@ Fl_Tiled_Image::Fl_Tiled_Image(Fl_Image *i, // I - Image to tile
Fl_Image(W,H,0) {
image_ = i;
alloc_image_ = 0;
-
- if (W == 0) w(Fl::w());
- if (H == 0) h(Fl::h());
+ // giving to the tiled image the screen size may fail with multiscreen configurations
+ // so we leave it with w = h = 0 (STR #3106)
+ /* if (W == 0) w(Fl::w());
+ if (H == 0) h(Fl::h());*/
}
/**
The destructor frees all memory and server resources that are used by
@@ -99,8 +101,11 @@ Fl_Tiled_Image::draw(int X, // I - Starting X position
int cx, // I - "Source" X position
int cy) { // I - "Source" Y position
if (!image_->w() || !image_->h()) return;
- if (W == 0) W = Fl::w();
- if (H == 0) H = Fl::h();
+ if (W == 0 && H == 0 && Fl_Window::current()) { // W and H null means the image is potentially as large as the current window
+ W = Fl_Window::current()->w();
+ H = Fl_Window::current()->h();
+ X = Y = 0;
+ }
fl_push_clip(X, Y, W, H);
@@ -122,5 +127,5 @@ Fl_Tiled_Image::draw(int X, // I - Starting X position
//
-// End of "$Id: Fl_Tiled_Image.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $".
+// End of "$Id: Fl_Tiled_Image.cxx 10218 2014-07-10 12:28:00Z manolo $".
//
diff --git a/src/Fl_Tree.cxx b/src/Fl_Tree.cxx
index f0c6f72..1a513d1 100644
--- a/src/Fl_Tree.cxx
+++ b/src/Fl_Tree.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: Fl_Tree.cxx 9706 2012-11-06 20:46:14Z matt $"
+// "$Id: Fl_Tree.cxx 10275 2014-09-05 12:04:28Z cand $"
//
#include <stdio.h>
@@ -27,60 +27,44 @@
// http://www.fltk.org/str.php
//
-// INTERNAL: scroller callback
+// INTERNAL: scroller callback (hor+vert scroll)
static void scroll_cb(Fl_Widget*,void *data) {
((Fl_Tree*)data)->redraw();
}
-// INTERNAL: Parse elements from path into an array of null terminated strings
-// Handles escape characters.
-// Path="/aa/bb"
-// Return: arr[0]="aa", arr[1]="bb", arr[2]=0
+// INTERNAL: Parse elements from 'path' into an array of null terminated strings
+// Handles escape characters, ignores multiple /'s.
+// Path="/aa/bb", returns arr[0]="aa", arr[1]="bb", arr[2]=0.
// Caller must call free_path(arr).
//
static char **parse_path(const char *path) {
- while ( *path == '/' ) path++; // skip leading '/'
- // First pass: identify, null terminate, and count separators
- int seps = 1; // separator count (1: first item)
- int arrsize = 1; // array size (1: first item)
- char *save = strdup(path); // make copy we can modify
- char *sin = save, *sout = save;
- while ( *sin ) {
- if ( *sin == '\\' ) { // handle escape character
- *sout++ = *++sin;
- if ( *sin ) ++sin;
- } else if ( *sin == '/' ) { // handle submenu
- *sout++ = 0;
- sin++;
- seps++;
- arrsize++;
- } else { // all other chars
- *sout++ = *sin++;
- }
- }
- *sout = 0;
- arrsize++; // (room for terminating NULL)
- // Second pass: create array, save nonblank elements
- char **arr = (char**)malloc(sizeof(char*) * arrsize);
- int t = 0;
- sin = save;
- while ( seps-- > 0 ) {
- if ( *sin ) { arr[t++] = sin; } // skips empty fields, e.g. '//'
- sin += (strlen(sin) + 1);
+ size_t len = strlen(path);
+ char *cp = new char[(len+1)], *word = cp, *s = cp; // freed below or in free_path()
+ char **ap = new char*[(len+1)], **arr = ap; // overallocates arr[]
+ while (1) {
+ if (*path =='/' || *path == 0) { // handle path sep or eos
+ if (word != s) { *s++ = 0; *arr++= word; word = s; }
+ if ( !*path++) break; else continue; // eos? done, else cont
+ } else if ( *path == '\\' ) { // handle escape
+ if ( *(++path) ) { *s++ = *path++; } else continue;
+ } else { *s++ = *path++; } // handle normal char
}
- arr[t] = 0;
- return(arr);
+ *arr = 0;
+ if ( arr == ap ) delete[] cp; // empty arr[]? delete since free_path() can't
+ return ap;
}
-// INTERNAL: Free the array returned by parse_path()
+// INTERNAL: Free an array 'arr' returned by parse_path()
static void free_path(char **arr) {
if ( arr ) {
- if ( arr[0] ) { free((void*)arr[0]); }
- free((void*)arr);
+ if ( arr[0] ) { delete[] arr[0]; } // deletes cp in parse_path
+ delete[] arr; // deletes ptr array
}
}
-// INTERNAL: Recursively descend tree hierarchy, accumulating total child count
+// INTERNAL: Recursively descend 'item's tree hierarchy
+// accumulating total child 'count'
+//
static int find_total_children(Fl_Tree_Item *item, int count=0) {
count++;
for ( int t=0; t<item->children(); t++ ) {
@@ -91,7 +75,11 @@ static int find_total_children(Fl_Tree_Item *item, int count=0) {
/// Constructor.
Fl_Tree::Fl_Tree(int X, int Y, int W, int H, const char *L) : Fl_Group(X,Y,W,H,L) {
+#if FLTK_ABI_VERSION >= 10303
+ _root = new Fl_Tree_Item(this);
+#else
_root = new Fl_Tree_Item(_prefs);
+#endif
_root->parent(0); // we are root of tree
_root->label("ROOT");
_item_focus = 0;
@@ -109,11 +97,25 @@ Fl_Tree::Fl_Tree(int X, int Y, int W, int H, const char *L) : Fl_Group(X,Y,W,H,L
box(FL_DOWN_BOX);
color(FL_BACKGROUND2_COLOR, FL_SELECTION_COLOR);
when(FL_WHEN_CHANGED);
- _vscroll = new Fl_Scrollbar(0,0,0,0); // will be resized by draw()
+ int scrollsize = _scrollbar_size ? _scrollbar_size : Fl::scrollbar_size();
+ _vscroll = new Fl_Scrollbar(X+W-scrollsize,Y,scrollsize,H);
_vscroll->hide();
_vscroll->type(FL_VERTICAL);
_vscroll->step(1);
_vscroll->callback(scroll_cb, (void*)this);
+#if FLTK_ABI_VERSION >= 10303
+ _hscroll = new Fl_Scrollbar(X,Y+H-scrollsize,W,scrollsize);
+ _hscroll->hide();
+ _hscroll->type(FL_HORIZONTAL);
+ _hscroll->step(1);
+ _hscroll->callback(scroll_cb, (void*)this);
+ _tox = _tix = X + Fl::box_dx(box());
+ _toy = _tiy = Y + Fl::box_dy(box());
+ _tow = _tiw = W - Fl::box_dw(box());
+ _toh = _tih = H - Fl::box_dh(box());
+ _tree_w = -1;
+ _tree_h = -1;
+#endif
end();
}
@@ -122,26 +124,137 @@ Fl_Tree::~Fl_Tree() {
if ( _root ) { delete _root; _root = 0; }
}
-/// Extend a selection between 'from' and 'to'.
-/// Used by SHIFT-click to extend a selection between two items inclusive.
+/// Extend the selection between and including \p 'from' and \p 'to'
+/// depending on direction \p 'dir', \p 'val', and \p 'visible'.
///
-void Fl_Tree::extend_selection(Fl_Tree_Item *from, Fl_Tree_Item *to) {
- char on = 0;
+/// Efficient: does not walk entire tree; starts with \p 'from' and stops
+/// at \p 'to' while moving in direction \p 'dir'. Dir must be specified though.
+#if FLTK_ABI_VERSION >= 10303
+///
+/// If dir cannot be known in advance, such as during SHIFT-click operations,
+/// the method extend_selection(Fl_Tree_Item*,Fl_Tree_Item*,int,bool)
+/// should be used.
+#endif
+///
+/// Handles calling redraw() if anything changed.
+///
+/// \param[in] from Starting item
+/// \param[in] to Ending item
+/// \param[in] dir Direction to extend selection (FL_Up or FL_Down)
+/// \param[in] val 0=deselect, 1=select, 2=toggle
+/// \param[in] visible true=affect only open(), visible items,<br>
+/// false=affect open or closed items (default)
+/// \returns The number of items whose selection states were changed, if any.
+/// \version 1.3.3
+///
+int Fl_Tree::extend_selection_dir(Fl_Tree_Item *from, Fl_Tree_Item *to,
+ int dir, int val, bool visible ) {
+ int changed = 0;
+ for (Fl_Tree_Item *item=from; item; item = next_item(item, dir, visible) ) {
+ switch (val) {
+ case 0:
+ if ( deselect(item, when()) ) ++changed;
+ break;
+ case 1:
+ if ( select(item, when()) ) ++changed;
+ break;
+ case 2:
+ select_toggle(item, when());
+ ++changed; // toggle always involves a change
+ break;
+ }
+ if ( item==to ) break;
+ }
+ return(changed);
+}
+
+/// Extend a selection between \p 'from' and \p 'to' depending on \p 'visible'.
+///
+/// Similar to the more efficient
+/// extend_selection_dir(Fl_Tree_Item*,Fl_Tree_Item*,int dir,int val,bool vis)
+/// method, but direction (up or down) doesn't need to be known.<br>
+/// We're less efficient because we search the tree for to/from, then operate
+/// on items in between. The more efficient method avoids the "search",
+/// but necessitates a direction to be specified to find \p 'to'.<br>
+/// Used by SHIFT-click to extend a selection between two items inclusive.<br>
+/// Handles calling redraw() if anything changed.
+///
+/// \param[in] from Starting item
+/// \param[in] to Ending item
+/// \param[in] val Select or deselect items (0=deselect, 1=select, 2=toggle)
+/// \param[in] visible true=affect only open(), visible items,<br>
+/// false=affect open or closed items (default)
+/// \returns The number of items whose selection states were changed, if any.
+#if FLTK_ABI_VERSION >= 10303
+/// \version 1.3.3 ABI feature
+int Fl_Tree::extend_selection(Fl_Tree_Item *from, Fl_Tree_Item *to,
+ int val, bool visible) {
+#else
+/// \notes Made public in 1.3.3 ABI
+// Adding overload if not at least one overload breaks ABI, so avoid
+// by making a private function until ABI can change..
+int Fl_Tree::extend_selection__(Fl_Tree_Item *from, Fl_Tree_Item *to,
+ int val, bool visible) {
+#endif
+ int changed = 0;
if ( from == to ) {
- from->select();
- return;
+ if ( visible && !from->is_visible() ) return(0); // do nothing
+ switch (val) {
+ case 0:
+ if ( deselect(from, when()) ) ++changed;
+ break;
+ case 1:
+ if ( select(from, when()) ) ++changed;
+ break;
+ case 2:
+ select_toggle(from, when());
+ ++changed; // always changed
+ break;
+ }
+ return(changed);
}
- for ( Fl_Tree_Item *item = first(); item; item = next(item) ) {
- if ( (item == from) || (item == to) ) {
- item->select(); // inclusive
- on ^= 1;
- } else if ( on ) {
- item->select();
+ char on = 0;
+ for ( Fl_Tree_Item *item = first(); item; item = item->next_visible(_prefs) ) {
+ if ( visible && !item->is_visible() ) continue;
+ if ( on || (item == from) || (item == to) ) {
+ switch (val) {
+ case 0:
+ if ( deselect(item, when()) ) ++changed;
+ break;
+ case 1:
+ if ( select(item, when()) ) ++changed;
+ break;
+ case 2:
+ select_toggle(item, when());
+ ++changed; // toggle always involves a change
+ break;
+ }
+ if ( (item == from) || (item == to) ) {
+ on ^= 1;
+ if ( !on ) break; // done
+ }
}
}
+ return(changed);
}
+#if FLTK_ABI_VERSION >= 10303
+// not needed, above overload handles this
+#else
+/// Extend a selection between \p 'from' and \p 'to'.
+/// Extends selection for items and all children, visible ('open') or not.
+/// Walks entire tree from top to bottom looking for \p 'from' and \p 'to'.
+/// \version 1.3.0
+///
+void Fl_Tree::extend_selection(Fl_Tree_Item *from, Fl_Tree_Item *to) {
+ const int val = 1; // 0=clr, 1=set, 2=toggle
+ const bool visible = false; // true=only 'open' items, false='open' or 'closed'
+ extend_selection__(from, to, val, visible); // use private method until we can release it
+}
+#endif
+
/// Standard FLTK event handler for this widget.
+/// \todo add Fl_Widget_Tracker (see Fl_Browser_.cxx::handle())
int Fl_Tree::handle(int e) {
if (e == FL_NO_EVENT) return(0); // XXX: optimize to prevent slow resizes on large trees!
int ret = 0;
@@ -157,6 +270,7 @@ int Fl_Tree::handle(int e) {
// Developer note: Fl_Browser_::handle() used for reference here..
// #include <FL/names.h> // for event debugging
// fprintf(stderr, "DEBUG: %s (%d)\n", fl_eventnames[e], e);
+
if (e == FL_ENTER || e == FL_LEAVE) return(1);
switch (e) {
case FL_FOCUS: {
@@ -164,10 +278,10 @@ int Fl_Tree::handle(int e) {
// If a nav key was used to give us focus, and we've got no saved
// focus widget, determine which item gets focus depending on nav key.
//
- if ( ! _item_focus ) { // no focus established yet?
- switch (Fl::event_key()) { // determine if focus was navigated..
- case FL_Tab: { // received focus via TAB?
- int updown = is_shift ? FL_Up : FL_Down; // SHIFT-TAB similar to Up, TAB similar to Down
+ if ( ! _item_focus ) { // no focus established yet?
+ switch (Fl::event_key()) { // determine if focus was navigated..
+ case FL_Tab: { // received focus via TAB?
+ int updown = is_shift ? FL_Up : FL_Down; // SHIFT-TAB similar to Up, TAB similar to Down
set_item_focus(next_visible_item(0, updown));
break;
}
@@ -196,7 +310,7 @@ int Fl_Tree::handle(int e) {
if ( (Fl::focus() == this) && // tree has focus?
_prefs.selectmode() > FL_TREE_SELECT_NONE ) { // select mode that supports kb events?
if ( !_item_focus ) { // no current focus item?
- set_item_focus(first_visible()); // use first vis item
+ set_item_focus(first_visible_item()); // use first vis item
if ( Fl::event_key() == FL_Up || // Up or down?
Fl::event_key() == FL_Down ) // ..if so, already did 'motion'
return(1); // ..so just return.
@@ -214,6 +328,7 @@ int Fl_Tree::handle(int e) {
case FL_TREE_SELECT_NONE:
break; // ignore, let group have shot at event
case FL_TREE_SELECT_SINGLE:
+ case FL_TREE_SELECT_SINGLE_DRAGGABLE:
if ( is_ctrl ) { // CTRL-SPACE: (single mode) toggle
if ( ! _item_focus->is_selected() ) {
select_only(_item_focus, when());
@@ -239,14 +354,10 @@ int Fl_Tree::handle(int e) {
case FL_Left: { // LEFT: close children (if any)
if ( _item_focus ) {
if ( ekey == FL_Right && _item_focus->is_close() ) {
- // Open closed item
- open(_item_focus);
- redraw();
+ open(_item_focus); // open closed item
ret = 1;
} else if ( ekey == FL_Left && _item_focus->is_open() ) {
- // Close open item
- close(_item_focus);
- redraw();
+ close(_item_focus); // close open item
ret = 1;
}
return(1);
@@ -279,11 +390,12 @@ int Fl_Tree::handle(int e) {
switch ( _prefs.selectmode() ) {
case FL_TREE_SELECT_NONE:
case FL_TREE_SELECT_SINGLE:
+ case FL_TREE_SELECT_SINGLE_DRAGGABLE:
break;
case FL_TREE_SELECT_MULTI:
// Do a 'select all'
select_all();
- _lastselect = first_visible();
+ _lastselect = first_visible_item();
take_focus();
return(1);
}
@@ -306,44 +418,54 @@ int Fl_Tree::handle(int e) {
// fprintf(stderr, "Fl_Tree::handle(): Event was %s (%d)\n", fl_eventnames[e], e); // DEBUGGING
if ( ! _root ) return(ret);
+ static int last_my = 0;
switch ( e ) {
case FL_PUSH: { // clicked on tree
- if (Fl::visible_focus() && handle(FL_FOCUS)) {
- Fl::focus(this);
- }
- // Not extending a selection? zero lastselect
+ last_my = Fl::event_y(); // save for dragging direction..
+ if (Fl::visible_focus() && handle(FL_FOCUS)) Fl::focus(this);
+#if FLTK_ABI_VERSION >= 10303
+ Fl_Tree_Item *item = _root->find_clicked(_prefs, 0);
+#else
Fl_Tree_Item *item = _root->find_clicked(_prefs);
+#endif
if ( !item ) { // clicked, but not on an item?
+ _lastselect = 0;
switch ( _prefs.selectmode() ) {
case FL_TREE_SELECT_NONE:
break;
case FL_TREE_SELECT_SINGLE:
+ case FL_TREE_SELECT_SINGLE_DRAGGABLE:
case FL_TREE_SELECT_MULTI:
deselect_all();
break;
}
break;
}
- set_item_focus(item); // becomes new focus widget
- redraw();
- ret |= 1; // handled
+ set_item_focus(item); // becomes new focus widget, calls redraw() if needed
+ ret |= 1; // handled
if ( Fl::event_button() == FL_LEFT_MOUSE ) {
if ( item->event_on_collapse_icon(_prefs) ) { // collapse icon clicked?
- open_toggle(item);
+ open_toggle(item); // toggle open (handles redraw)
} else if ( item->event_on_label(_prefs) && // label clicked?
- (!item->widget() || !Fl::event_inside(item->widget())) && // not inside widget
- (!_vscroll->visible() || !Fl::event_inside(_vscroll)) ) { // not on scroller
+ (!item->widget() || !Fl::event_inside(item->widget())) ) { // not inside widget
switch ( _prefs.selectmode() ) {
case FL_TREE_SELECT_NONE:
break;
case FL_TREE_SELECT_SINGLE:
- select_only(item, when());
+ case FL_TREE_SELECT_SINGLE_DRAGGABLE:
+ select_only(item, when()); // select only this item (handles redraw)
_lastselect = item;
break;
case FL_TREE_SELECT_MULTI: {
if ( is_shift ) { // SHIFT+PUSH?
if ( _lastselect ) {
- extend_selection(_lastselect, item);
+ int val = is_ctrl ? 2 : 1;
+ bool visible = true;
+#if FLTK_ABI_VERSION >= 10303
+ extend_selection(_lastselect, item, val, visible);
+#else
+ extend_selection__(_lastselect, item, val, visible);
+#endif
} else {
select(item); // add to selection
}
@@ -361,61 +483,363 @@ int Fl_Tree::handle(int e) {
break;
}
case FL_DRAG: {
- // do the scrolling first:
+ // Do scrolling first..
+
+ // Detect up/down dragging
int my = Fl::event_y();
- if ( my < y() ) { // above top?
- int p = vposition()-(y()-my);
- if ( p < 0 ) p = 0;
- vposition(p);
- } else if ( my > (y()+h()) ) { // below bottom?
- int p = vposition()+(my-y()-h());
- if ( p > (int)_vscroll->maximum() ) p = (int)_vscroll->maximum();
- vposition(p);
+ int dir = (my>last_my) ? FL_Down : FL_Up;
+ last_my = my;
+
+ // Handle autoscrolling
+ if ( my < y() ) { // Above top?
+ dir = FL_Up; // ..going up
+ int p = vposition()-(y()-my); // ..position above us
+ if ( p < 0 ) p = 0; // ..don't go above 0
+ vposition(p); // ..scroll to new position
+ } else if ( my > (y()+h()) ) { // Below bottom?
+ dir = FL_Down; // ..going down
+ int p = vposition()+(my-y()-h()); // ..position below us
+ if ( p > (int)_vscroll->maximum() ) // ..don't go below bottom
+ p = (int)_vscroll->maximum();
+ vposition(p); // ..scroll to new position
}
+
+ // Now handle the event..
+ // During drag, only interested in left-mouse operations.
+ //
if ( Fl::event_button() != FL_LEFT_MOUSE ) break;
- Fl_Tree_Item *item = _root->find_clicked(_prefs);
- if ( ! item ) break;
- set_item_focus(item); // becomes new focus widget
- redraw();
- ret |= 1;
- // Item's label clicked?
- if ( item->event_on_label(_prefs) &&
- (!item->widget() || !Fl::event_inside(item->widget())) &&
- (!_vscroll->visible() || !Fl::event_inside(_vscroll)) ) {
- // Handle selection behavior
- switch ( _prefs.selectmode() ) {
- case FL_TREE_SELECT_NONE:
- break; // no selection changes
- case FL_TREE_SELECT_SINGLE:
- select_only(item, when());
- _lastselect = item;
- break;
- case FL_TREE_SELECT_MULTI:
- if ( is_ctrl ) { // CTRL-DRAG: toggle?
- if ( _lastselect != item ) { // not already toggled from last microdrag?
- select_toggle(item, when()); // toggle selection
- }
- } else {
- select(item); // select this
- }
- _lastselect = item;
- break;
+#if FLTK_ABI_VERSION >= 10303
+ Fl_Tree_Item *item = _root->find_clicked(_prefs, 1); // item we're on, vertically
+#else
+ Fl_Tree_Item *item = _root->find_clicked(_prefs); // item we're on, vertically
+#endif
+ if ( !item ) break; // not near item? ignore drag event
+ ret |= 1; // acknowledge event
+ if (_prefs.selectmode() != FL_TREE_SELECT_SINGLE_DRAGGABLE)
+ set_item_focus(item); // becomes new focus item
+ if (item==_lastselect) break; // same item as before? avoid reselect
+
+ // Handle selection behavior
+ switch ( _prefs.selectmode() ) {
+ case FL_TREE_SELECT_NONE:
+ break; // no selection changes
+ case FL_TREE_SELECT_SINGLE: {
+ select_only(item, when()); // select only this item (handles redraw)
+ break;
+ }
+ case FL_TREE_SELECT_SINGLE_DRAGGABLE: {
+ item = _lastselect; // Keep the source intact
+ redraw();
+ break;
+ }
+ case FL_TREE_SELECT_MULTI: {
+ Fl_Tree_Item *from = next_visible_item(_lastselect, dir); // avoid reselecting item
+ Fl_Tree_Item *to = item;
+ int val = is_ctrl ? 2 : 1; // toggle_select() or just select()?
+ bool visible = true;
+ extend_selection_dir(from, to, dir, val, visible);
+ break;
}
}
+ _lastselect = item; // save current item for later
break;
}
+ case FL_RELEASE:
+ if (_prefs.selectmode() == FL_TREE_SELECT_SINGLE_DRAGGABLE &&
+ Fl::event_button() == FL_LEFT_MOUSE) {
+#if FLTK_ABI_VERSION >= 10303
+ Fl_Tree_Item *item = _root->find_clicked(_prefs, 1); // item we're on, vertically
+#else
+ Fl_Tree_Item *item = _root->find_clicked(_prefs); // item we're on, vertically
+#endif
+
+ if (item && _lastselect && item != _lastselect &&
+ Fl::event_x() >= item->label_x()) {
+ //printf("Would drag '%s' to '%s'\n", _lastselect->label(), item->label());
+ // Are we dropping above or below the target item?
+ const int h = Fl::event_y() - item->y();
+ const int mid = item->h() / 2;
+ const bool before = h < mid;
+ //printf("Dropping %s it\n", before ? "before" : "after");
+
+ // Do nothing if it would be a no-op
+ if ((before && prev(item) != _lastselect) ||
+ (!before && next(item) != _lastselect)) {
+ Fl_Tree_Item *parent = item->parent();
+
+ if (parent) {
+ int pos = parent->find_child(item);
+ if (!before)
+ pos++;
+
+ // Special case: trying to drop right before a folder
+ if (item->children() && item->is_open() && !before) {
+ parent = item;
+ pos = 0;
+ }
+
+ // If we're moving inside the same parent, use the below/above methods
+ if (_lastselect->parent() == parent) {
+ if (before) {
+ _lastselect->move_above(item);
+ } else {
+ _lastselect->move_below(item);
+ }
+ } else {
+ _lastselect->move_into(parent, pos);
+ }
+
+ redraw();
+ do_callback_for_item(_lastselect, FL_TREE_REASON_DRAGGED);
+ }
+ }
+ }
+ redraw();
+ } // End single-drag check
+ ret |= 1;
+ break;
}
return(ret);
}
+#if FLTK_ABI_VERSION >= 10303
+// nothing
+#else
+// Redraw timeout callback
+// (Only need this hack for old ABI 10302 and older)
+//
static void redraw_soon(void *data) {
((Fl_Tree*)data)->redraw();
Fl::remove_timeout(redraw_soon, data);
}
+#endif
+
+#if FLTK_ABI_VERSION >= 10303
+/// Recalculate widget dimensions and scrollbar visibility,
+/// normally managed automatically.
+///
+/// Low overhead way to update the tree widget's outer/inner dimensions
+/// and re-determine scrollbar visibility based on these changes without
+/// recalculating the entire size of the tree data.
+///
+/// Assumes that either the tree's size in _tree_w/_tree_h are correct
+/// so that scrollbar visibility can be calculated easily, or are both
+/// zero indicating scrollbar visibility can't be calculated yet.
+///
+/// This method is called when the widget is resize()ed or if the
+/// scrollbar's sizes are changed (affects tree widget's inner dimensions
+/// tix/y/w/h), and also used by calc_tree().
+/// \version 1.3.3 ABI feature
+///
+void Fl_Tree::calc_dimensions() {
+ // Calc tree outer xywh
+ // Area of the tree widget /outside/ scrollbars
+ //
+ _tox = x() + Fl::box_dx(box());
+ _toy = y() + Fl::box_dy(box());
+ _tow = w() - Fl::box_dw(box());
+ _toh = h() - Fl::box_dh(box());
+
+ // Scrollbar visiblity + positions
+ // Calc this ONLY if tree_h and tree_w have been calculated.
+ // Zero values for these indicate calc in progress, but not done yet.
+ //
+ if ( _tree_h >= 0 && _tree_w >= 0 ) {
+ int scrollsize = _scrollbar_size ? _scrollbar_size : Fl::scrollbar_size();
+ int vshow = _tree_h > _toh ? 1 : 0;
+ int hshow = _tree_w > _tow ? 1 : 0;
+ // See if one scroller's appearance affects the other's visibility
+ if ( hshow && !vshow && (_tree_h > (_toh-scrollsize)) ) vshow = 1;
+ if ( vshow && !hshow && (_tree_w > (_tow-scrollsize)) ) hshow = 1;
+ // vertical scrollbar visibility
+ if ( vshow ) {
+ _vscroll->show();
+ _vscroll->resize(_tox+_tow-scrollsize, _toy,
+ scrollsize, h()-Fl::box_dh(box()) - (hshow ? scrollsize : 0));
+ } else {
+ _vscroll->hide();
+ _vscroll->value(0);
+ }
+ // horizontal scrollbar visibility
+ if ( hshow ) {
+ _hscroll->show();
+ _hscroll->resize(_tox, _toy+_toh-scrollsize,
+ _tow - (vshow ? scrollsize : 0), scrollsize);
+ } else {
+ _hscroll->hide();
+ _hscroll->value(0);
+ }
+
+ // Calculate inner dimensions
+ // The area the tree occupies inside the scrollbars and margins
+ //
+ _tix = _tox;
+ _tiy = _toy;
+ _tiw = _tow - (_vscroll->visible() ? _vscroll->w() : 0);
+ _tih = _toh - (_hscroll->visible() ? _hscroll->h() : 0);
+
+ // Scrollbar tab sizes
+ _vscroll->slider_size(float(_tih) / float(_tree_h));
+ _vscroll->range(0.0, _tree_h - _tih);
+
+ _hscroll->slider_size(float(_tiw) / float(_tree_w));
+ _hscroll->range(0.0, _tree_w - _tiw);
+ } else {
+ // Best we can do without knowing tree_h/tree_w
+ _tix = _tox;
+ _tiy = _toy;
+ _tiw = _tow;
+ _tih = _toh;
+ }
+}
+
+/// Recalculuates the tree's sizes and scrollbar visibility,
+/// normally managed automatically.
+///
+/// On return:
+///
+/// - _tree_w will be the overall pixel width of the entire viewable tree
+/// - _tree_h will be the overall pixel height ""
+/// - scrollbar visibility and pan sizes are updated
+/// - internal _tix/_tiy/_tiw/_tih dimensions are updated
+///
+/// _tree_w/_tree_h include the tree's margins (e.g. marginleft()),
+/// whether items are open or closed, label contents and font sizes, etc.
+///
+/// The tree hierarchy's size is managed separately from the widget's
+/// size as an optimization; this way resize() on the widget doesn't
+/// involve recalculating the tree's hierarchy needlessly, as widget
+/// size has no bearing on the tree hierarchy.
+///
+/// The tree hierarchy's size only changes when items are added/removed,
+/// open/closed, label contents or font sizes changed, margins changed, etc.
+///
+/// This calculation involves walking the *entire* tree from top to bottom,
+/// a potentially a slow calculation if the tree has many items (potentially
+/// hundreds of thousands), and should therefore be called sparingly.
+///
+/// For this reason, recalc_tree() is used as a way to /schedule/
+/// calculation when changes affect the tree hierarchy's size.
+///
+/// Apps may want to call this method directly if the app makes changes
+/// to the tree's geometry, then immediately needs to work with the tree's
+/// new dimensions before an actual redraw (and recalc) occurs. (This
+/// use by an app should only rarely be needed)
+///
+void Fl_Tree::calc_tree() {
+ // Set tree width and height to zero, and recalc just _tox/_toy/_tow/_toh for now.
+ _tree_w = _tree_h = -1;
+ calc_dimensions();
+ if ( !_root ) return;
+ // Walk the tree to determine its width and height.
+ // We need this to compute scrollbars..
+ // By the end, 'Y' will be the lowest point on the tree
+ //
+ int X = _tix + _prefs.marginleft() + _hscroll->value();
+ int Y = _tiy + _prefs.margintop() - _vscroll->value();
+ int W = _tiw;
+ // Adjust root's X/W if connectors off
+ if (_prefs.connectorstyle() == FL_TREE_CONNECTOR_NONE) {
+ X -= _prefs.openicon()->w();
+ W += _prefs.openicon()->w();
+ }
+ int xmax = 0, render = 0, ytop = Y;
+ fl_font(_prefs.labelfont(), _prefs.labelsize());
+ _root->draw(X, Y, W, 0, xmax, 1, render); // descend into tree without drawing (render=0)
+ // Save computed tree width and height
+ _tree_w = _prefs.marginleft() + xmax - X; // include margin in tree's width
+ _tree_h = _prefs.margintop() + Y - ytop; // include margin in tree's height
+ // Calc tree dims again; now that tree_w/tree_h are known, scrollbars are calculated.
+ calc_dimensions();
+}
+#endif
+
+void Fl_Tree::resize(int X,int Y,int W, int H) {
+ fix_scrollbar_order();
+ Fl_Group::resize(X,Y,W,H);
+#if FLTK_ABI_VERSION >= 10303
+ calc_dimensions();
+#endif
+ init_sizes();
+}
+
+#if FLTK_ABI_VERSION >= 10303
+/// Standard FLTK draw() method, handles drawing the tree widget.
+void Fl_Tree::draw() {
+ fix_scrollbar_order();
+ // Has tree recalc been scheduled? If so, do it
+ if ( _tree_w == -1 ) calc_tree();
+ else calc_dimensions();
+ // Let group draw box+label but *NOT* children.
+ // We handle drawing children ourselves by calling each item's draw()
+ {
+ // Draw group's bg + label
+ if ( damage() & ~FL_DAMAGE_CHILD) { // redraw entire widget?
+ Fl_Group::draw_box();
+ Fl_Group::draw_label();
+ }
+ if ( ! _root ) return;
+ // These values are changed during drawing
+ // By end, 'Y' will be the lowest point on the tree
+ int X = _tix + _prefs.marginleft() - _hscroll->value();
+ int Y = _tiy + _prefs.margintop() - _vscroll->value();
+ int W = _tiw - X + _tix;
+ // Adjust root's X/W if connectors off
+ if (_prefs.connectorstyle() == FL_TREE_CONNECTOR_NONE) {
+ X -= _prefs.openicon()->w();
+ W += _prefs.openicon()->w();
+ }
+ // Draw entire tree, starting with root
+ fl_push_clip(_tix,_tiy,_tiw,_tih);
+ {
+ int xmax = 0;
+ fl_font(_prefs.labelfont(), _prefs.labelsize());
+ _root->draw(X, Y, W, // descend into tree here to draw it
+ (Fl::focus()==this)?_item_focus:0, // show focus item ONLY if Fl_Tree has focus
+ xmax, 1, 1);
+ }
+ fl_pop_clip();
+ }
+ // Draw scrollbars last
+ draw_child(*_vscroll);
+ draw_child(*_hscroll);
+ // That little tile between the scrollbars
+ if ( _vscroll->visible() && _hscroll->visible() ) {
+ fl_color(_vscroll->color());
+ fl_rectf(_hscroll->x()+_hscroll->w(),
+ _vscroll->y()+_vscroll->h(),
+ _vscroll->w(),
+ _hscroll->h());
+ }
+
+ // Draw dragging line
+ if (_prefs.selectmode() == FL_TREE_SELECT_SINGLE_DRAGGABLE &&
+ Fl::pushed() == this) {
+
+ Fl_Tree_Item *item = _root->find_clicked(_prefs, 1); // item we're on, vertically
+ if (item && item != _item_focus) {
+ // Are we dropping above or before the target item?
+ const int h = Fl::event_y() - item->y();
+ const int mid = item->h() / 2;
+ const bool before = h < mid;
+
+ fl_color(FL_BLACK);
+ int tgt;
+ if (before) {
+ tgt = item->y();
+ } else {
+ tgt = item->y() + item->h();
+ }
+ fl_line(item->x(), tgt, item->x() + item->w(), tgt);
+ }
+ }
+}
+#else
/// Standard FLTK draw() method, handles drawing the tree widget.
void Fl_Tree::draw() {
int ytoofar = draw_tree();
+
// See if we're scrolled below bottom of tree
// This can happen if someone just closed a large item.
// If so, change scroller as needed.
@@ -435,8 +859,32 @@ void Fl_Tree::draw() {
}
Fl::add_timeout(.10, redraw_soon, (void*)this); // use timer to trigger redraw; we can't
}
+
+ // Draw dragging line
+ if (_prefs.selectmode() == FL_TREE_SELECT_SINGLE_DRAGGABLE &&
+ Fl::pushed() == this) {
+
+ Fl_Tree_Item *item = _root->find_clicked(_prefs); // item we're on, vertically
+ if (item && item != _item_focus) {
+ // Are we dropping above or before the target item?
+ const int h = Fl::event_y() - item->y();
+ const int mid = item->h() / 2;
+ const bool before = h < mid;
+
+ fl_color(FL_BLACK);
+
+ int tgt;
+ if (before) {
+ tgt = item->y();
+ } else {
+ tgt = item->y() + item->h();
+ }
+ fl_line(item->x(), tgt, item->x() + item->w(), tgt);
+ }
+ }
}
+// This method is undocumented, and has been removed in ABI 1.3.3
int Fl_Tree::draw_tree() {
int ret = 0;
fix_scrollbar_order();
@@ -465,7 +913,6 @@ int Fl_Tree::draw_tree() {
W += _prefs.openicon()->w();
}
int Ysave = Y;
-
fl_push_clip(cx,cy,cw,ch);
{
fl_font(_prefs.labelfont(), _prefs.labelsize());
@@ -509,16 +956,19 @@ int Fl_Tree::draw_tree() {
draw_child(*_vscroll); // draw scroll last
return(ret);
}
+#endif
/// Print the tree as 'ascii art' to stdout.
/// Used mainly for debugging.
+/// \todo should be const
+/// \version 1.3.0
///
void Fl_Tree::show_self() {
if ( ! _root ) return;
_root->show_self();
}
-/// Set the label for the root item.
+/// Set the label for the root item to \p 'new_label'.
///
/// Makes an internally managed copy of 'new_label'.
///
@@ -532,63 +982,132 @@ Fl_Tree_Item* Fl_Tree::root() {
return(_root);
}
-/// Adds a new item, given a 'menu style' path, eg: "/Parent/Child/item".
+/// Sets the root item to \p 'newitem'.
+///
+/// If a root item already exists, clear() is first to clear it
+/// before replacing it with newitem.
+///
+#if FLTK_ABI_VERSION >= 10303
+/// Use this to install a custom item (derived from Fl_Tree_Item) as the root
+/// of the tree. This allows the derived class to implement custom drawing
+/// by overriding Fl_Tree_Item::draw_item_content().
+///
+#endif
+/// \version 1.3.3
+///
+void Fl_Tree::root(Fl_Tree_Item *newitem) {
+ if ( _root ) clear();
+ _root = newitem;
+}
+
+/// Adds a new item, given a menu style \p 'path'.
/// Any parent nodes that don't already exist are created automatically.
/// Adds the item based on the value of sortorder().
+/// If \p 'item' is NULL, a new item is created.
///
/// To specify items or submenus that contain slashes ('/' or '\')
/// use an escape character to protect them, e.g.
-///
/// \code
/// tree->add("/Holidays/Photos/12\\/25\\2010"); // Adds item "12/25/2010"
/// tree->add("/Pathnames/c:\\\\Program Files\\\\MyApp"); // Adds item "c:\Program Files\MyApp"
/// \endcode
-///
-/// \returns the child item created, or 0 on error.
-///
-Fl_Tree_Item* Fl_Tree::add(const char *path) {
- if ( ! _root ) { // Create root if none
+/// \param[in] path The path to the item, e.g. "Flintsone/Fred".
+/// \param[in] item The new item to be added.
+/// If NULL, a new item is created with
+/// a name that is the last element in \p 'path'.
+/// \returns The new item added, or 0 on error.
+/// \version 1.3.3
+///
+Fl_Tree_Item* Fl_Tree::add(const char *path, Fl_Tree_Item *item) {
+ // Tree has no root? make one
+ if ( ! _root ) {
+#if FLTK_ABI_VERSION >= 10303
+ _root = new Fl_Tree_Item(this);
+#else
_root = new Fl_Tree_Item(_prefs);
+#endif
_root->parent(0);
_root->label("ROOT");
- }
+ }
+ // Find parent item via path
char **arr = parse_path(path);
- Fl_Tree_Item *item = _root->add(_prefs, arr);
+ item = _root->add(_prefs, arr, item);
free_path(arr);
return(item);
}
-/// Add a new child to a specific item in the tree.
+#if FLTK_ABI_VERSION >= 10303
+// do nothing here: add(path,item) where item defaults to 0 takes its place
+#else
+/// Adds a new item given a menu style \p 'path'.
+/// Same as calling add(path, NULL);
+/// \param[in] path The path to the item to be created, e.g. "Flintsone/Fred".
+/// \returns The new item added, or 0 on error.
+/// \see add(const char*,Fl_Tree_Item*)
+/// \version 1.3.0 release
+///
+Fl_Tree_Item* Fl_Tree::add(const char *path) {
+ return add(path, 0);
+}
+#endif
+
+/// Add a new child item labeled \p 'name' to the specified \p 'parent_item'.
///
-/// \param[in] item The existing item to add new child to. Must not be NULL.
+/// \param[in] parent_item The parent item the new child item will be added to.
+/// Must not be NULL.
/// \param[in] name The label for the new item
-/// \returns the item that was added.
+/// \returns The new item added.
+/// \version 1.3.0 release
///
-Fl_Tree_Item* Fl_Tree::add(Fl_Tree_Item *item, const char *name) {
- return(item->add(_prefs, name));
+Fl_Tree_Item* Fl_Tree::add(Fl_Tree_Item *parent_item, const char *name) {
+ return(parent_item->add(_prefs, name));
}
-/// Inserts a new item above the specified Fl_Tree_Item, with the label set to 'name'.
+/// Inserts a new item \p 'name' above the specified Fl_Tree_Item \p 'above'.
+/// Example:
+/// \code
+/// tree->add("Aaa/000"); // "000" is index 0 in Aaa's children
+/// tree->add("Aaa/111"); // "111" is index 1 in Aaa's children
+/// tree->add("Aaa/222"); // "222" is index 2 in Aaa's children
+/// ..
+/// // How to use insert_above() to insert a new item above Aaa/222
+/// Fl_Tree_Item *item = tree->find_item("Aaa/222"); // get item Aaa/222
+/// if (item) tree->insert_above(item, "New item"); // insert new item above it
+/// \endcode
+///
/// \param[in] above -- the item above which to insert the new item. Must not be NULL.
/// \param[in] name -- the name of the new item
-/// \returns the item that was added, or 0 if 'above' could not be found.
+/// \returns The new item added, or 0 if 'above' could not be found.
+/// \see insert()
///
Fl_Tree_Item* Fl_Tree::insert_above(Fl_Tree_Item *above, const char *name) {
return(above->insert_above(_prefs, name));
}
-/// Insert a new item into a tree-item's children at a specified position.
+/// Insert a new item \p 'name' into \p 'item's children at position \p 'pos'.
+///
+/// Example:
+/// \code
+/// tree->add("Aaa/000"); // "000" is index 0 in Aaa's children
+/// tree->add("Aaa/111"); // "111" is index 1 in Aaa's children
+/// tree->add("Aaa/222"); // "222" is index 2 in Aaa's children
+/// ..
+/// // How to use insert() to insert a new item between Aaa/111 + Aaa/222
+/// Fl_Tree_Item *item = tree->find_item("Aaa"); // get parent item Aaa
+/// if (item) tree->insert(item, "New item", 2); // insert as a child of Aaa at index #2
+/// \endcode
///
/// \param[in] item The existing item to insert new child into. Must not be NULL.
/// \param[in] name The label for the new item
/// \param[in] pos The position of the new item in the child list
-/// \returns the item that was added.
+/// \returns The new item added.
+/// \see insert_above()
///
Fl_Tree_Item* Fl_Tree::insert(Fl_Tree_Item *item, const char *name, int pos) {
return(item->insert(_prefs, name, pos));
}
-/// Remove the specified \p item from the tree.
+/// Remove the specified \p 'item' from the tree.
/// \p item may not be NULL.
/// If it has children, all those are removed too.
/// If item being removed has focus, no item will have focus.
@@ -607,7 +1126,7 @@ int Fl_Tree::remove(Fl_Tree_Item *item) {
return(0);
}
-/// Clear all children from the tree.
+/// Clear the entire tree's children, including the root.
/// The tree will be left completely empty.
///
void Fl_Tree::clear() {
@@ -615,7 +1134,8 @@ void Fl_Tree::clear() {
_root->clear_children();
delete _root; _root = 0;
}
-/// Clear all the children of a particular node in the tree specified by \p item.
+
+/// Clear all the children for \p 'item'.
/// Item may not be NULL.
///
void Fl_Tree::clear_children(Fl_Tree_Item *item) {
@@ -625,7 +1145,7 @@ void Fl_Tree::clear_children(Fl_Tree_Item *item) {
}
}
-/// Find the item, given a menu style path, eg: "/Parent/Child/item".
+/// Find the item, given a menu style path, e.g. "/Parent/Child/item".
/// There is both a const and non-const version of this method.
/// Const version allows pure const methods to use this method
/// to do lookups without causing compiler errors.
@@ -639,19 +1159,9 @@ void Fl_Tree::clear_children(Fl_Tree_Item *item) {
/// \endcode
///
/// \param[in] path -- the tree item's pathname to be found (e.g. "Flintstones/Fred")
-/// \returns the item, or NULL if not found.
-///
+/// \returns The item, or NULL if not found.
/// \see item_pathname()
///
-Fl_Tree_Item *Fl_Tree::find_item(const char *path) {
- if ( ! _root ) return(NULL);
- char **arr = parse_path(path);
- Fl_Tree_Item *item = _root->find_item(arr);
- free_path(arr);
- return(item);
-}
-
-/// A const version of Fl_Tree::find_item(const char *path)
const Fl_Tree_Item *Fl_Tree::find_item(const char *path) const {
if ( ! _root ) return(NULL);
char **arr = parse_path(path);
@@ -660,6 +1170,13 @@ const Fl_Tree_Item *Fl_Tree::find_item(const char *path) const {
return(item);
}
+/// Non-const version of Fl_Tree::find_item(const char *path) const
+Fl_Tree_Item *Fl_Tree::find_item(const char *path) {
+ // "Effective C++, 3rd Ed", p.23. Sola fide, Amen.
+ return(const_cast<Fl_Tree_Item*>(
+ static_cast<const Fl_Tree&>(*this).find_item(path)));
+}
+
// Handle safe 'reverse string concatenation'.
// In the following we build the pathname from right-to-left,
// since we start at the child and work our way up to the root.
@@ -669,13 +1186,15 @@ const Fl_Tree_Item *Fl_Tree::find_item(const char *path) const {
*s-- = c; \
}
-/// Find the pathname for the specified \p item.
-/// If \p item is NULL, root() is used.
-/// The tree's root will be included in the pathname of showroot() is on.
+/// Return \p 'pathname' of size \p 'pathnamelen' for the specified \p 'item'.
+///
+/// If \p 'item' is NULL, root() is used.<br>
+/// The tree's root will be included in the pathname of showroot() is on.<br>
/// Menu items or submenus that contain slashes ('/' or '\') in their names
/// will be escaped with a backslash. This is symmetrical with the add()
/// function which uses the same escape pattern to set names.
-/// \param[in] pathname The string to use to return the pathname
+///
+/// \param[out] pathname The string to use to return the pathname
/// \param[in] pathnamelen The maximum length of the string (including NULL). Must not be zero.
/// \param[in] item The item whose pathname is to be returned.
/// \returns
@@ -712,88 +1231,137 @@ int Fl_Tree::item_pathname(char *pathname, int pathnamelen, const Fl_Tree_Item *
return(0);
}
-/// Find the item that was clicked.
+#if FLTK_ABI_VERSION >= 10303
+/// Find the item that was last clicked on.
/// You should use callback_item() instead, which is fast,
/// and is meant to be used within a callback to determine the item clicked.
///
/// This method walks the entire tree looking for the first item that is
-/// under the mouse (ie. at Fl::event_x()/Fl:event_y().
+/// under the mouse. (The value of the \p 'yonly' flag affects whether
+/// both x and y events are checked, or just y)
///
/// Use this method /only/ if you've subclassed Fl_Tree, and are receiving
/// events before Fl_Tree has been able to process and update callback_item().
///
-/// \returns the item clicked, or 0 if no item was under the current event.
+/// \param[in] yonly -- 0: check both event's X and Y values.
+/// -- 1: only check event's Y value, don't care about X.
+/// \returns The item clicked, or NULL if no item was under the current event.
+/// \version 1.3.0
+/// \version 1.3.3 ABI feature: added yonly parameter
+///
+const Fl_Tree_Item* Fl_Tree::find_clicked(int yonly) const {
+ if ( ! _root ) return(NULL);
+ return(_root->find_clicked(_prefs, yonly));
+}
+
+/// Non-const version of Fl_Tree::find_clicked(int yonly) const.
+Fl_Tree_Item *Fl_Tree::find_clicked(int yonly) {
+ // "Effective C++, 3rd Ed", p.23. Sola fide, Amen.
+ return(const_cast<Fl_Tree_Item*>(
+ static_cast<const Fl_Tree&>(*this).find_clicked(yonly)));
+}
+#else
+/// Find the item that was last clicked on.
+/// You should use callback_item() instead, which is fast,
+/// and is meant to be used within a callback to determine the item clicked.
+///
+/// This method walks the entire tree looking for the first item that is
+/// under the mouse, i.e. at Fl::event_x() / Fl::event_y().
+///
+/// Use this method /only/ if you've subclassed Fl_Tree, and are receiving
+/// events before Fl_Tree has been able to process and update callback_item().
+///
+/// \returns The item clicked, or NULL if no item was under the current event.
+/// \version 1.3.0
///
const Fl_Tree_Item* Fl_Tree::find_clicked() const {
if ( ! _root ) return(NULL);
return(_root->find_clicked(_prefs));
}
+/// Non-const version of Fl_Tree::find_clicked() const.
+/// \version 1.3.0
+Fl_Tree_Item *Fl_Tree::find_clicked() {
+ // "Effective C++, 3rd Ed", p.23. Sola fide, Amen.
+ return(const_cast<Fl_Tree_Item*>(
+ static_cast<const Fl_Tree&>(*this).find_clicked()));
+}
+#endif
+
/// Set the item that was last clicked.
/// Should only be used by subclasses needing to change this value.
/// Normally Fl_Tree manages this value.
///
-/// Deprecated: use callback_item() instead.
+/// \deprecated in 1.3.3 ABI -- use callback_item() instead.
///
-void Fl_Tree::item_clicked(Fl_Tree_Item* val) {
- _callback_item = val;
+void Fl_Tree::item_clicked(Fl_Tree_Item* item) {
+ _callback_item = item;
}
/// Return the item that was last clicked.
///
/// Valid only from within the callback().
///
-/// Deprecated: use callback_item() instead.
-///
-/// \returns the item clicked, or 0 if none.
+/// \returns The item clicked, or 0 if none.
/// 0 may also be used to indicate several items were clicked/changed.
+/// \deprecated in 1.3.3 ABI -- use callback_item() instead.
///
Fl_Tree_Item* Fl_Tree::item_clicked() {
return(_callback_item);
}
-/// Returns next visible item above (dir==Fl_Up) or below (dir==Fl_Down) the specified \p item.
-/// If \p item is 0, returns first() if \p dir is Fl_Up, or last() if \p dir is FL_Down.
+/// Returns next open(), visible item above (\p dir==FL_Up)
+/// or below (\p dir==FL_Down) the specified \p 'item', or 0 if no more items.
+///
+/// If \p 'item' is 0, returns first() if \p 'dir' is FL_Up,
+/// or last() if \p dir is FL_Down.
+///
+/// \code
+/// // Walk down the tree (forwards)
+/// for ( Fl_Tree_Item *i=tree->first_visible_item(); i; i=tree->next_visible_item(i, FL_Down) )
+/// printf("Item: %s\n", i->label());
///
+/// // Walk up the tree (backwards)
+/// for ( Fl_Tree_Item *i=tree->last_visible_item(); i; i=tree->next_visible_item(i, FL_Up) )
+/// printf("Item: %s\n", i->label());
+/// \endcode
/// \param[in] item The item above/below which we'll find the next visible item
-/// \param[in] dir The direction to search. Can be FL_Up or FL_Down.
+/// \param[in] dir The direction to search. Can be FL_Up or FL_Down.
/// \returns The item found, or 0 if there's no visible items above/below the specified \p item.
+/// \version 1.3.3
///
Fl_Tree_Item *Fl_Tree::next_visible_item(Fl_Tree_Item *item, int dir) {
- if ( ! item ) { // no start item?
- item = ( dir == FL_Up ) ? last_visible() : // wrap to bottom
- first_visible(); // wrap to top
- if ( ! item ) return(0);
- if ( item->visible_r() ) return(item); // return first/last visible item
- }
- switch ( dir ) {
- case FL_Up: return(item->prev_displayed(_prefs));
- case FL_Down: return(item->next_displayed(_prefs));
- default: return(item->next_displayed(_prefs));
- }
+ return next_item(item, dir, true);
}
-/// Returns the first item in the tree.
+/// Returns the first item in the tree, or 0 if none.
///
-/// Use this to walk the tree in the forward direction, eg:
+/// Use this to walk the tree in the forward direction, e.g.
/// \code
-/// for ( Fl_Tree_Item *item = tree->first(); item; item = tree->next(item) ) {
+/// for ( Fl_Tree_Item *item = tree->first(); item; item = tree->next(item) )
/// printf("Item: %s\n", item->label());
-/// }
/// \endcode
///
-/// \returns first item in tree, or 0 if none (tree empty).
-/// \see first(),next(),last(),prev()
+/// \returns First item in tree, or 0 if none (tree empty).
+/// \see first(), next(), last(), prev()
///
Fl_Tree_Item* Fl_Tree::first() {
- return(_root); // first item always root
+ return(_root); // first item always root
}
-/// Returns the first visible item in the tree.
-/// \returns first visible item in tree, or 0 if none.
-/// \see first_visible(), last_visible()
+/// Returns the first open(), visible item in the tree, or 0 if none.
+/// \deprecated in 1.3.3 ABI -- use first_visible_item() instead.
///
Fl_Tree_Item* Fl_Tree::first_visible() {
+ return(first_visible_item());
+}
+
+/// Returns the first open(), visible item in the tree, or 0 if none.
+/// \returns First visible item in tree, or 0 if none.
+/// \see first_visible_item(), last_visible_item(), next_visible_item()
+/// \version 1.3.3
+///
+Fl_Tree_Item* Fl_Tree::first_visible_item() {
Fl_Tree_Item *i = showroot() ? first() : next(first());
while ( i ) {
if ( i->visible() ) return(i);
@@ -802,39 +1370,36 @@ Fl_Tree_Item* Fl_Tree::first_visible() {
return(0);
}
-/// Return the next item after \p item, or 0 if no more items.
+/// Return the next item after \p 'item', or 0 if no more items.
///
/// Use this code to walk the entire tree:
/// \code
-/// for ( Fl_Tree_Item *item = tree->first(); item; item = tree->next(item) ) {
-/// printf("Item: %s\n", item->label());
-/// }
+/// for ( Fl_Tree_Item *i = tree->first(); i; i = tree->next(i) )
+/// printf("Item: %s\n", i->label());
/// \endcode
///
/// \param[in] item The item to use to find the next item. If NULL, returns 0.
/// \returns Next item in tree, or 0 if at last item.
///
-/// \see first(),next(),last(),prev()
+/// \see first(), next(), last(), prev()
///
Fl_Tree_Item *Fl_Tree::next(Fl_Tree_Item *item) {
if ( ! item ) return(0);
return(item->next());
}
-/// Return the previous item before \p item, or 0 if no more items.
-///
-/// This can be used to walk the tree in reverse, eg:
+/// Return the previous item before \p 'item', or 0 if no more items.
///
+/// This can be used to walk the tree in reverse, e.g.
/// \code
-/// for ( Fl_Tree_Item *item = tree->first(); item; item = tree->prev(item) ) {
+/// for ( Fl_Tree_Item *item = tree->first(); item; item = tree->prev(item) )
/// printf("Item: %s\n", item->label());
-/// }
/// \endcode
///
/// \param[in] item The item to use to find the previous item. If NULL, returns 0.
/// \returns Previous item in tree, or 0 if at first item.
///
-/// \see first(),next(),last(),prev()
+/// \see first(), next(), last(), prev()
///
Fl_Tree_Item *Fl_Tree::prev(Fl_Tree_Item *item) {
if ( ! item ) return(0);
@@ -843,17 +1408,15 @@ Fl_Tree_Item *Fl_Tree::prev(Fl_Tree_Item *item) {
/// Returns the last item in the tree.
///
-/// This can be used to walk the tree in reverse, eg:
+/// This can be used to walk the tree in reverse, e.g.
///
/// \code
-/// for ( Fl_Tree_Item *item = tree->last(); item; item = tree->prev() ) {
+/// for ( Fl_Tree_Item *item = tree->last(); item; item = tree->prev() )
/// printf("Item: %s\n", item->label());
-/// }
/// \endcode
///
-/// \returns last item in the tree, or 0 if none (tree empty).
-///
-/// \see first(),next(),last(),prev()
+/// \returns Last item in the tree, or 0 if none (tree empty).
+/// \see first(), next(), last(), prev()
///
Fl_Tree_Item* Fl_Tree::last() {
if ( ! _root ) return(0);
@@ -864,12 +1427,19 @@ Fl_Tree_Item* Fl_Tree::last() {
return(item);
}
-/// Returns the last visible item in the tree.
-/// \returns last visible item in the tree, or 0 if none.
-///
-/// \see first_visible(), last_visible()
+/// Returns the last open(), visible item in the tree.
+/// \deprecated in 1.3.3 -- use last_visible_item() instead.
///
Fl_Tree_Item* Fl_Tree::last_visible() {
+ return(last_visible_item());
+}
+
+/// Returns the last open(), visible item in the tree.
+/// \returns Last visible item in the tree, or 0 if none.
+/// \see first_visible_item(), last_visible_item(), next_visible_item()
+/// \version 1.3.3
+///
+Fl_Tree_Item* Fl_Tree::last_visible_item() {
Fl_Tree_Item *item = last();
while ( item ) {
if ( item->visible() ) {
@@ -886,48 +1456,216 @@ Fl_Tree_Item* Fl_Tree::last_visible() {
/// Returns the first selected item in the tree.
///
-/// Use this to walk the tree looking for all the selected items, eg:
+/// Use this to walk the tree from top to bottom
+/// looking for all the selected items, e.g.
///
/// \code
-/// for ( Fl_Tree_Item *item = tree->first_selected_item(); item; item = tree->next_selected_item(item) ) {
-/// printf("Item: %s\n", item->label());
-/// }
+/// // Walk tree forward, from top to bottom
+/// for ( Fl_Tree_Item *i=tree->first_selected_item(); i; i=tree->next_selected_item(i) )
+/// printf("Selected item: %s\n", i->label());
/// \endcode
///
-/// \returns The next selected item, or 0 if there are no more selected items.
+/// \returns The first selected item, or 0 if none.
+/// \see first_selected_item(), last_selected_item(), next_selected_item()
///
Fl_Tree_Item *Fl_Tree::first_selected_item() {
return(next_selected_item(0));
}
-/// Returns the next selected item after \p item.
+#if FLTK_ABI_VERSION >= 10303
+// nothing
+#else
+/// Returns the next selected item after \p 'item'.
/// If \p item is 0, search starts at the first item (root).
///
-/// Use this to walk the tree looking for all the selected items, eg:
+/// This is a convenience method; equivalent to next_selected_item(item, FL_Down);
+///
+/// Use this to walk the tree forward (downward) looking for all the selected items, e.g.
/// \code
-/// for ( Fl_Tree_Item *item = tree->first_selected_item(); item; item = tree->next_selected_item(item) ) {
-/// printf("Item: %s\n", item->label());
-/// }
+/// for ( Fl_Tree_Item *i = tree->first_selected_item(); i; i = tree->next_selected_item(i) )
+/// printf("Selected item: %s\n", i->label());
/// \endcode
///
/// \param[in] item The item to use to find the next selected item. If NULL, first() is used.
/// \returns The next selected item, or 0 if there are no more selected items.
+/// \see first_selected_item(), last_selected_item(), next_selected_item()
///
Fl_Tree_Item *Fl_Tree::next_selected_item(Fl_Tree_Item *item) {
- if ( ! item ) {
- if ( ! (item = first()) ) return(0);
- if ( item->is_selected() ) return(item);
+ return(next_selected_item(item, FL_Down));
+}
+#endif
+
+/// Returns the last selected item in the tree.
+///
+/// Use this to walk the tree in reverse from bottom to top
+/// looking for all the selected items, e.g.
+///
+/// \code
+/// // Walk tree in reverse, from bottom to top
+/// for ( Fl_Tree_Item *i=tree->last_selected_item(); i; i=tree->next_selected_item(i, FL_Up) )
+/// printf("Selected item: %s\n", i->label());
+/// \endcode
+///
+/// \returns The last selected item, or 0 if none.
+/// \see first_selected_item(), last_selected_item(), next_selected_item()
+/// \version 1.3.3
+///
+Fl_Tree_Item *Fl_Tree::last_selected_item() {
+ return(next_selected_item(0, FL_Up));
+}
+
+/// Returns next item after \p 'item' in direction \p 'dir'
+/// depending on \p 'visible'.
+///
+/// Next item will be above (if dir==FL_Up) or below (if dir==FL_Down).
+/// If \p 'visible' is true, only items whose parents are open() will be returned.
+/// If \p 'visible' is false, even items whose parents are close()ed will be returned.
+///
+/// If \p item is 0, the return value will be the result of this truth table:
+/// <PRE>
+/// visible=true visible=false
+/// ------------------- -------------
+/// dir=Fl_Up: last_visible_item() last()
+/// dir=Fl_Down: first_visible_item() first()
+/// </PRE>
+///
+/// \par Example use:
+/// \code
+/// // Walk down the tree showing open(), visible items
+/// for ( Fl_Tree_Item *i=tree->first_visible_item(); i; i=tree->next_item(i, FL_Down, true) )
+/// printf("Item: %s\n", i->label());
+///
+/// // Walk up the tree showing open(), visible items
+/// for ( Fl_Tree_Item *i=tree->last_visible_item(); i; i=tree->next_item(i, FL_Up, true) )
+/// printf("Item: %s\n", i->label());
+///
+/// // Walk down the tree showing all items (open or closed)
+/// for ( Fl_Tree_Item *i=tree->first(); i; i=tree->next_item(i, FL_Down, false) )
+/// printf("Item: %s\n", i->label());
+///
+/// // Walk up the tree showing all items (open or closed)
+/// for ( Fl_Tree_Item *i=tree->last(); i; i=tree->next_item(i, FL_Up, false) )
+/// printf("Item: %s\n", i->label());
+/// \endcode
+///
+/// \param[in] item The item to use to find the next item. If NULL, returns 0.
+/// \param[in] dir Can be FL_Up or FL_Down (default=FL_Down or 'next')
+/// \param[in] visible true=return only open(), visible items,<br>
+/// false=return open or closed items (default)
+/// \returns Next item in tree in the direction and visibility specified,
+/// or 0 if no more items of specified visibility in that direction.
+/// \see first(), last(), next(),<BR>
+/// first_visible_item(), last_visible_item(), next_visible_item(),<BR>
+/// first_selected_item(), last_selected_item(), next_selected_item()
+/// \version 1.3.3
+///
+Fl_Tree_Item *Fl_Tree::next_item(Fl_Tree_Item *item, int dir, bool visible) {
+ if ( ! item ) { // no start item?
+ if ( visible ) {
+ item = ( dir == FL_Up ) ? last_visible_item() : // wrap to bottom
+ first_visible_item(); // wrap to top
+ } else {
+ item = ( dir == FL_Up ) ? last() : // wrap to bottom
+ first(); // wrap to top
+ }
+ if ( ! item ) return(0);
+ if ( item->visible_r() ) return(item); // return first/last visible item
+ }
+ switch (dir) {
+ case FL_Up:
+ if ( visible ) return(item->prev_visible(_prefs));
+ else return(item->prev());
+ case FL_Down:
+ if ( visible ) return(item->next_visible(_prefs));
+ else return(item->next());
+ }
+ return(0); // unknown dir
+}
+
+/// Returns the next selected item above or below \p 'item', depending on \p 'dir'.
+/// If \p 'item' is 0, search starts at either first() or last(), depending on \p 'dir':
+/// first() if \p 'dir' is FL_Down (default), last() if \p 'dir' is FL_Up.
+///
+/// Use this to walk the tree looking for all the selected items, e.g.
+/// \code
+/// // Walk down the tree (forwards)
+/// for ( Fl_Tree_Item *i=tree->first_selected_item(); i; i=tree->next_selected_item(i, FL_Down) )
+/// printf("Item: %s\n", i->label());
+///
+/// // Walk up the tree (backwards)
+/// for ( Fl_Tree_Item *i=tree->last_selected_item(); i; i=tree->next_selected_item(i, FL_Up) )
+/// printf("Item: %s\n", i->label());
+/// \endcode
+///
+/// \param[in] item The item above or below which we'll find the next selected item.
+/// If NULL, first() is used if FL_Down, last() if FL_Up.
+/// (default=NULL)
+/// \param[in] dir The direction to go.
+/// FL_Up for moving up the tree,
+/// FL_Down for down the tree (default)
+/// \returns The next selected item, or 0 if there are no more selected items.
+/// \see first_selected_item(), last_selected_item(), next_selected_item()
+/// \version 1.3.3
+///
+Fl_Tree_Item *Fl_Tree::next_selected_item(Fl_Tree_Item *item, int dir) {
+ switch (dir) {
+ case FL_Down:
+ if ( ! item ) {
+ if ( ! (item = first()) ) return(0);
+ if ( item->is_selected() ) return(item);
+ }
+ while ( (item = item->next()) )
+ if ( item->is_selected() )
+ return(item);
+ return(0);
+ case FL_Up:
+ if ( ! item ) {
+ if ( ! (item = last()) ) return(0);
+ if ( item->is_selected() ) return(item);
+ }
+ while ( (item = item->prev()) )
+ if ( item->is_selected() )
+ return(item);
+ return(0);
}
- while ( (item = item->next()) )
- if ( item->is_selected() )
- return(item);
return(0);
}
-/// Open the specified 'item'.
-/// This causes the item's children (if any) to be shown.
-/// Handles redrawing if anything was actually changed.
-/// Invokes the callback depending on the value of optional parameter \p docallback.
+#if FLTK_ABI_VERSION >= 10303 /* reason for this: Fl_Tree_Item_Array::manage_item_destroy() */
+/// Returns the currently selected items as an array of \p 'ret_items'.
+///
+/// Example:
+/// \code
+/// // Get selected items as an array
+/// Fl_Tree_Item_Array items;
+/// tree->get_selected_items(items);
+/// // Manipulate the returned array
+/// for ( int t=0; t<items.total(); t++ ) {
+/// Fl_Tree_Item &item = items[t];
+/// ..do stuff with each selected item..
+/// }
+/// \endcode
+///
+/// \param[out] ret_items The returned array of selected items.
+/// \returns The number of items in the returned array.
+/// \see first_selected_item(), next_selected_item()
+/// \version 1.3.3 ABI feature
+///
+int Fl_Tree::get_selected_items(Fl_Tree_Item_Array &ret_items) {
+ ret_items.clear();
+ for ( Fl_Tree_Item *i=first_selected_item(); i; i=next_selected_item(i) ) {
+ ret_items.add(i);
+ }
+ return ret_items.total();
+}
+#endif
+
+/// Open the specified \p 'item'.
+///
+/// This causes the item's children (if any) to be shown.<br>
+/// Invokes the callback depending on the value of optional
+/// parameter \p 'docallback'.<br>
+/// Handles calling redraw() if anything changed.
///
/// The callback can use callback_item() and callback_reason() respectively to determine
/// the item changed and the reason the callback was called.
@@ -935,7 +1673,7 @@ Fl_Tree_Item *Fl_Tree::next_selected_item(Fl_Tree_Item *item) {
/// \param[in] item -- the item to be opened. Must not be NULL.
/// \param[in] docallback -- A flag that determines if the callback() is invoked or not:
/// - 0 - callback() is not invoked
-/// - 1 - callback() is invoked if item changed,
+/// - 1 - callback() is invoked if item changed, (default)
/// callback_reason() will be FL_TREE_REASON_OPENED
/// \returns
/// - 1 -- item was opened
@@ -945,7 +1683,7 @@ Fl_Tree_Item *Fl_Tree::next_selected_item(Fl_Tree_Item *item) {
///
int Fl_Tree::open(Fl_Tree_Item *item, int docallback) {
if ( item->is_open() ) return(0);
- item->open();
+ item->open(); // handles recalc_tree()
redraw();
if ( docallback ) {
do_callback_for_item(item, FL_TREE_REASON_OPENED);
@@ -953,10 +1691,12 @@ int Fl_Tree::open(Fl_Tree_Item *item, int docallback) {
return(1);
}
-/// Opens the item specified by \p path (eg: "Parent/child/item").
-/// This causes the item's children (if any) to be shown.
-/// Handles redrawing if anything was actually changed.
-/// Invokes the callback depending on the value of optional parameter \p docallback.
+/// Opens the item specified by \p 'path'.
+///
+/// This causes the item's children (if any) to be shown.<br>
+/// Invokes the callback depending on the value of optional
+/// parameter \p 'docallback'.<br>
+/// Handles calling redraw() if anything changed.
///
/// Items or submenus that themselves contain slashes ('/' or '\')
/// should be escaped, e.g. open("Holidays/12\\/25\//2010").
@@ -967,24 +1707,25 @@ int Fl_Tree::open(Fl_Tree_Item *item, int docallback) {
/// \param[in] path -- the tree item's pathname (e.g. "Flintstones/Fred")
/// \param[in] docallback -- A flag that determines if the callback() is invoked or not:
/// - 0 - callback() is not invoked
-/// - 1 - callback() is invoked if item changed,
+/// - 1 - callback() is invoked if item changed (default),
/// callback_reason() will be FL_TREE_REASON_OPENED
/// \returns
/// - 1 -- OK: item opened
/// - 0 -- OK: item was already open, no change
/// - -1 -- ERROR: item was not found
-///
/// \see open(), close(), is_open(), is_close(), callback_item(), callback_reason()
///
int Fl_Tree::open(const char *path, int docallback) {
Fl_Tree_Item *item = find_item(path);
if ( ! item ) return(-1);
- return(open(item, docallback));
+ return(open(item, docallback)); // handles recalc_tree()
}
-/// Toggle the open state of \p item.
-/// Handles redrawing if anything was actually changed.
-/// Invokes the callback depending on the value of optional parameter \p docallback.
+/// Toggle the open state of \p 'item'.
+///
+/// Invokes the callback depending on the value of optional
+/// parameter \p 'docallback'.<br>
+/// Handles calling redraw() if anything changed.
///
/// The callback can use callback_item() and callback_reason() respectively to determine
/// the item changed and the reason the callback was called.
@@ -992,22 +1733,24 @@ int Fl_Tree::open(const char *path, int docallback) {
/// \param[in] item -- the item whose open state is to be toggled. Must not be NULL.
/// \param[in] docallback -- A flag that determines if the callback() is invoked or not:
/// - 0 - callback() is not invoked
-/// - 1 - callback() is invoked, callback_reason() will be either
+/// - 1 - callback() is invoked (default), callback_reason() will be either
/// FL_TREE_REASON_OPENED or FL_TREE_REASON_CLOSED
///
/// \see open(), close(), is_open(), is_close(), callback_item(), callback_reason()
///
void Fl_Tree::open_toggle(Fl_Tree_Item *item, int docallback) {
if ( item->is_open() ) {
- close(item, docallback);
+ close(item, docallback); // handles recalc_tree()
} else {
- open(item, docallback);
+ open(item, docallback); // handles recalc_tree()
}
}
-/// Closes the specified \p item.
-/// Handles redrawing if anything was actually changed.
-/// Invokes the callback depending on the value of optional parameter \p docallback.
+/// Closes the specified \p 'item'.
+///
+/// Invokes the callback depending on the value of optional
+/// parameter \p 'docallback'.<br>
+/// Handles calling redraw() if anything changed.
///
/// The callback can use callback_item() and callback_reason() respectively to determine
/// the item changed and the reason the callback was called.
@@ -1015,17 +1758,16 @@ void Fl_Tree::open_toggle(Fl_Tree_Item *item, int docallback) {
/// \param[in] item -- the item to be closed. Must not be NULL.
/// \param[in] docallback -- A flag that determines if the callback() is invoked or not:
/// - 0 - callback() is not invoked
-/// - 1 - callback() is invoked if item changed,
+/// - 1 - callback() is invoked if item changed (default),
/// callback_reason() will be FL_TREE_REASON_CLOSED
/// \returns
/// - 1 -- item was closed
/// - 0 -- item was already closed, no change
-///
/// \see open(), close(), is_open(), is_close(), callback_item(), callback_reason()
///
int Fl_Tree::close(Fl_Tree_Item *item, int docallback) {
if ( item->is_close() ) return(0);
- item->close();
+ item->close(); // handles recalc_tree()
redraw();
if ( docallback ) {
do_callback_for_item(item, FL_TREE_REASON_CLOSED);
@@ -1033,9 +1775,11 @@ int Fl_Tree::close(Fl_Tree_Item *item, int docallback) {
return(1);
}
-/// Closes the item specified by \p path, eg: "Parent/child/item".
-/// Handles redrawing if anything was actually changed.
-/// Invokes the callback depending on the value of optional parameter \p docallback.
+/// Closes the item specified by \p 'path'.
+///
+/// Invokes the callback depending on the value of optional
+/// parameter \p 'docallback'.<br>
+/// Handles calling redraw() if anything changed.
///
/// Items or submenus that themselves contain slashes ('/' or '\')
/// should be escaped, e.g. close("Holidays/12\\/25\//2010").
@@ -1046,22 +1790,21 @@ int Fl_Tree::close(Fl_Tree_Item *item, int docallback) {
/// \param[in] path -- the tree item's pathname (e.g. "Flintstones/Fred")
/// \param[in] docallback -- A flag that determines if the callback() is invoked or not:
/// - 0 - callback() is not invoked
-/// - 1 - callback() is invoked if item changed,
+/// - 1 - callback() is invoked if item changed (default),
/// callback_reason() will be FL_TREE_REASON_CLOSED
/// \returns
/// - 1 -- OK: item closed
/// - 0 -- OK: item was already closed, no change
/// - -1 -- ERROR: item was not found
-///
/// \see open(), close(), is_open(), is_close(), callback_item(), callback_reason()
///
int Fl_Tree::close(const char *path, int docallback) {
Fl_Tree_Item *item = find_item(path);
if ( ! item ) return(-1);
- return(close(item, docallback));
+ return(close(item, docallback)); // handles recalc_tree()
}
-/// See if \p item is open.
+/// See if \p 'item' is open.
///
/// Items that are 'open' are themselves not necessarily visible;
/// one of the item's parents might be closed.
@@ -1075,7 +1818,7 @@ int Fl_Tree::is_open(Fl_Tree_Item *item) const {
return(item->is_open()?1:0);
}
-/// See if item specified by \p path (eg: "Parent/child/item") is open.
+/// See if item specified by \p 'path' is open.
///
/// Items or submenus that themselves contain slashes ('/' or '\')
/// should be escaped, e.g. is_open("Holidays/12\\/25\//2010").
@@ -1088,6 +1831,7 @@ int Fl_Tree::is_open(Fl_Tree_Item *item) const {
/// - 1 - OK: item is open
/// - 0 - OK: item is closed
/// - -1 - ERROR: item was not found
+/// \see Fl_Tree_Item::visible_r()
///
int Fl_Tree::is_open(const char *path) const {
const Fl_Tree_Item *item = find_item(path);
@@ -1095,7 +1839,7 @@ int Fl_Tree::is_open(const char *path) const {
return(item->is_open()?1:0);
}
-/// See if the specified \p item is closed.
+/// See if the specified \p 'item' is closed.
///
/// \param[in] item -- the item to be tested. Must not be NULL.
/// \returns
@@ -1106,7 +1850,7 @@ int Fl_Tree::is_close(Fl_Tree_Item *item) const {
return(item->is_close());
}
-/// See if item specified by \p path (eg: "Parent/child/item") is closed.
+/// See if item specified by \p 'path' is closed.
///
/// Items or submenus that themselves contain slashes ('/' or '\')
/// should be escaped, e.g. is_close("Holidays/12\\/25\//2010").
@@ -1123,9 +1867,10 @@ int Fl_Tree::is_close(const char *path) const {
return(item->is_close()?1:0);
}
-/// Select the specified \p item. Use 'deselect()' to de-select it.
-/// Handles redrawing if anything was actually changed.
-/// Invokes the callback depending on the value of optional parameter \p docallback.
+/// Select the specified \p 'item'. Use 'deselect()' to de-select it.
+///
+/// Invokes the callback depending on the value of optional parameter \p docallback.<br>
+/// Handles calling redraw() if anything changed.
///
/// The callback can use callback_item() and callback_reason() respectively to determine
/// the item changed and the reason the callback was called.
@@ -1161,9 +1906,11 @@ int Fl_Tree::select(Fl_Tree_Item *item, int docallback) {
return(0);
}
-/// Select the item specified by \p path (eg: "Parent/child/item").
-/// Handles redrawing if anything was actually changed.
-/// Invokes the callback depending on the value of optional parameter \p docallback.
+/// Select the item specified by \p 'path'.
+///
+/// Invokes the callback depending on the value of optional
+/// parameter \p 'docallback'.<br>
+/// Handles calling redraw() if anything changed.
///
/// Items or submenus that themselves contain slashes ('/' or '\')
/// should be escaped, e.g. select("Holidays/12\\/25\//2010").
@@ -1174,7 +1921,7 @@ int Fl_Tree::select(Fl_Tree_Item *item, int docallback) {
/// \param[in] path -- the tree item's pathname (e.g. "Flintstones/Fred")
/// \param[in] docallback -- A flag that determines if the callback() is invoked or not:
/// - 0 - the callback() is not invoked
-/// - 1 - the callback() is invoked if item changed state,
+/// - 1 - the callback() is invoked if item changed state (default),
/// callback_reason() will be FL_TREE_REASON_SELECTED
/// \returns
/// - 1 : OK: item's state was changed
@@ -1187,9 +1934,11 @@ int Fl_Tree::select(const char *path, int docallback) {
return(select(item, docallback));
}
-/// Toggle the select state of the specified \p item.
-/// Handles redrawing if anything was actually changed.
-/// Invokes the callback depending on the value of optional parameter \p docallback.
+/// Toggle the select state of the specified \p 'item'.
+///
+/// Invokes the callback depending on the value of optional
+/// parameter \p 'docallback'.<br>
+/// Handles calling redraw() if anything changed.
///
/// The callback can use callback_item() and callback_reason() respectively to determine
/// the item changed and the reason the callback was called.
@@ -1197,7 +1946,7 @@ int Fl_Tree::select(const char *path, int docallback) {
/// \param[in] item -- the item to be selected. Must not be NULL.
/// \param[in] docallback -- A flag that determines if the callback() is invoked or not:
/// - 0 - the callback() is not invoked
-/// - 1 - the callback() is invoked, callback_reason() will be
+/// - 1 - the callback() is invoked (default), callback_reason() will be
/// either FL_TREE_REASON_SELECTED or FL_TREE_REASON_DESELECTED
///
void Fl_Tree::select_toggle(Fl_Tree_Item *item, int docallback) {
@@ -1211,8 +1960,10 @@ void Fl_Tree::select_toggle(Fl_Tree_Item *item, int docallback) {
}
/// De-select the specified \p item.
-/// Handles redrawing if anything was actually changed.
-/// Invokes the callback depending on the value of optional parameter \p docallback.
+///
+/// Invokes the callback depending on the value of optional
+/// parameter \p 'docallback'.<br>
+/// Handles calling redraw() if anything changed.
///
/// The callback can use callback_item() and callback_reason() respectively to determine
/// the item changed and the reason the callback was called.
@@ -1220,7 +1971,7 @@ void Fl_Tree::select_toggle(Fl_Tree_Item *item, int docallback) {
/// \param[in] item -- the item to be selected. Must not be NULL.
/// \param[in] docallback -- A flag that determines if the callback() is invoked or not:
/// - 0 - the callback() is not invoked
-/// - 1 - the callback() is invoked if item changed state,
+/// - 1 - the callback() is invoked if item changed state (default),
/// callback_reason() will be FL_TREE_REASON_DESELECTED
/// \returns
/// - 0 - item was already deselected, no change was made
@@ -1239,9 +1990,11 @@ int Fl_Tree::deselect(Fl_Tree_Item *item, int docallback) {
return(0);
}
-/// Deselect an item specified by \p path (eg: "Parent/child/item").
-/// Handles redrawing if anything was actually changed.
-/// Invokes the callback depending on the value of optional parameter \p docallback.
+/// Deselect an item specified by \p 'path'.
+///
+/// Invokes the callback depending on the value of optional
+/// parameter \p 'docallback'.<br>
+/// Handles calling redraw() if anything changed.
///
/// Items or submenus that themselves contain slashes ('/' or '\')
/// should be escaped, e.g. deselect("Holidays/12\\/25\//2010").
@@ -1252,7 +2005,7 @@ int Fl_Tree::deselect(Fl_Tree_Item *item, int docallback) {
/// \param[in] path -- the tree item's pathname (e.g. "Flintstones/Fred")
/// \param[in] docallback -- A flag that determines if the callback() is invoked or not:
/// - 0 - the callback() is not invoked
-/// - 1 - the callback() is invoked if item changed state,
+/// - 1 - the callback() is invoked if item changed state (default),
/// callback_reason() will be FL_TREE_REASON_DESELECTED
/// \returns
/// - 1 - OK: item's state was changed
@@ -1265,10 +2018,12 @@ int Fl_Tree::deselect(const char *path, int docallback) {
return(deselect(item, docallback));
}
-/// Deselect \p item and all its children.
-/// If item is NULL, first() is used.
-/// Handles calling redraw() if anything was changed.
-/// Invokes the callback depending on the value of optional parameter \p docallback.
+/// Deselect \p 'item' and all its children.
+///
+/// If item is NULL, first() is used.<br>
+/// Invokes the callback depending on the value of optional
+/// parameter \p 'docallback'.<br>
+/// Handles calling redraw() if anything changed.
///
/// The callback can use callback_item() and callback_reason() respectively to determine
/// the item changed and the reason the callback was called.
@@ -1277,10 +2032,9 @@ int Fl_Tree::deselect(const char *path, int docallback) {
/// If NULL, first() is used.
/// \param[in] docallback -- A flag that determines if the callback() is invoked or not:
/// - 0 - the callback() is not invoked
-/// - 1 - the callback() is invoked for each item that changed state,
+/// - 1 - the callback() is invoked for each item that changed state (default),
/// callback_reason() will be FL_TREE_REASON_DESELECTED
-///
-/// \returns count of how many items were actually changed to the deselected state.
+/// \returns Count of how many items were actually changed to the deselected state.
///
int Fl_Tree::deselect_all(Fl_Tree_Item *item, int docallback) {
item = item ? item : first(); // NULL? use first()
@@ -1297,10 +2051,12 @@ int Fl_Tree::deselect_all(Fl_Tree_Item *item, int docallback) {
return(count);
}
-/// Select only the specified \p item, deselecting all others that might be selected.
-/// If item is 0, first() is used.
-/// Handles calling redraw() if anything was changed.
-/// Invokes the callback depending on the value of optional parameter \p docallback.
+/// Select only the specified \p 'item', deselecting all others that might be selected.
+///
+/// If item is 0, first() is used.<br>
+/// Invokes the callback depending on the value of optional
+/// parameter \p 'docallback'.<br>
+/// Handles calling redraw() if anything changed.
///
/// The callback can use callback_item() and callback_reason() respectively to determine
/// the item changed and the reason the callback was called.
@@ -1308,45 +2064,51 @@ int Fl_Tree::deselect_all(Fl_Tree_Item *item, int docallback) {
/// \param[in] selitem The item to be selected. If NULL, first() is used.
/// \param[in] docallback -- A flag that determines if the callback() is invoked or not:
/// - 0 - the callback() is not invoked
-/// - 1 - the callback() is invoked for each item that changed state,
+/// - 1 - the callback() is invoked for each item that changed state (default),
/// callback_reason() will be either FL_TREE_REASON_SELECTED or
/// FL_TREE_REASON_DESELECTED
-/// \returns the number of items whose selection states were changed, if any.
+/// \returns The number of items whose selection states were changed, if any.
///
int Fl_Tree::select_only(Fl_Tree_Item *selitem, int docallback) {
selitem = selitem ? selitem : first(); // NULL? use first()
if ( ! selitem ) return(0);
int changed = 0;
+ // Deselect everything first.
+ // Prevents callbacks from seeing more than one item selected.
+ //
for ( Fl_Tree_Item *item = first(); item; item = item->next() ) {
- if ( item == selitem ) {
-#if FLTK_ABI_VERSION >= 10301
- // NEW
- if ( item->is_selected() ) { // already selected?
- if ( item_reselect_mode() == FL_TREE_SELECTABLE_ALWAYS ) {
- select(item, docallback); // handles callback with reason==reselect
- }
- continue; // leave 'changed' unmodified (nothing changed)
- }
-#else
- // OLD
- if ( item->is_selected() ) continue; // don't count if already selected
-#endif
- select(item, docallback);
+ if ( item == selitem ) continue; // don't do anything to selitem yet..
+ if ( item->is_selected() ) {
+ deselect(item, docallback);
++changed;
- } else {
- if ( item->is_selected() ) {
- deselect(item, docallback);
- ++changed;
- }
}
}
+#if FLTK_ABI_VERSION >= 10301
+ // Should we 'reselect' item if already selected?
+ if ( selitem->is_selected() && (item_reselect_mode()==FL_TREE_SELECTABLE_ALWAYS) ) {
+ // Selection unchanged, so no ++change
+ select(selitem, docallback); // do callback with reason=reselect
+ } else if ( !selitem->is_selected() ) {
+ // Item was not already selected, select and indicate changed
+ select(selitem, docallback);
+ ++changed;
+ }
+#else
+ if ( !selitem->is_selected() ) {
+ // All items deselected, now select the one we want
+ select(selitem, docallback);
+ ++changed;
+ }
+#endif
return(changed);
}
-/// Select \p item and all its children.
-/// If item is NULL, first() is used.
-/// Handles calling redraw() if anything was changed.
-/// Invokes the callback depending on the value of optional parameter \p docallback.
+/// Select \p 'item' and all its children.
+///
+/// If item is NULL, first() is used.<br>
+/// Invokes the callback depending on the value of optional
+/// parameter \p 'docallback'.<br>
+/// Handles calling redraw() if anything changed.
///
/// The callback can use callback_item() and callback_reason() respectively to determine
/// the item changed and the reason the callback was called.
@@ -1355,9 +2117,9 @@ int Fl_Tree::select_only(Fl_Tree_Item *selitem, int docallback) {
/// If NULL, first() is used.
/// \param[in] docallback -- A flag that determines if the callback() is invoked or not:
/// - 0 - the callback() is not invoked
-/// - 1 - the callback() is invoked for each item that changed state,
+/// - 1 - the callback() is invoked for each item that changed state (default),
/// callback_reason() will be FL_TREE_REASON_SELECTED
-/// \returns count of how many items were actually changed to the selected state.
+/// \returns Count of how many items were actually changed to the selected state.
///
int Fl_Tree::select_all(Fl_Tree_Item *item, int docallback) {
item = item ? item : first(); // NULL? use first()
@@ -1380,6 +2142,7 @@ Fl_Tree_Item* Fl_Tree::get_item_focus() const {
}
/// Set the item that currently should have keyboard focus.
+///
/// Handles calling redraw() to update the focus box (if it is visible).
///
/// \param[in] item The item that should take focus. If NULL, none will have focus.
@@ -1391,7 +2154,7 @@ void Fl_Tree::set_item_focus(Fl_Tree_Item *item) {
}
}
-/// See if the specified \p item is selected.
+/// See if the specified \p 'item' is selected.
///
/// \param[in] item -- the item to be tested. Must not be NULL.
///
@@ -1403,7 +2166,7 @@ int Fl_Tree::is_selected(Fl_Tree_Item *item) const {
return(item->is_selected()?1:0);
}
-/// See if item specified by \p path (eg: "Parent/child/item") is selected.
+/// See if item specified by \p 'path' is selected.
///
/// Items or submenus that themselves contain slashes ('/' or '\')
/// should be escaped, e.g. is_selected("Holidays/12\\/25\//2010").
@@ -1493,6 +2256,7 @@ int Fl_Tree::marginleft() const {
void Fl_Tree::marginleft(int val) {
_prefs.marginleft(val);
redraw();
+ recalc_tree();
}
/// Get the amount of white space (in pixels) that should appear
@@ -1508,6 +2272,7 @@ int Fl_Tree::margintop() const {
void Fl_Tree::margintop(int val) {
_prefs.margintop(val);
redraw();
+ recalc_tree();
}
#if FLTK_ABI_VERSION >= 10301
@@ -1524,6 +2289,7 @@ int Fl_Tree::marginbottom() const {
void Fl_Tree::marginbottom(int val) {
_prefs.marginbottom(val);
redraw();
+ recalc_tree();
}
#endif /*FLTK_ABI_VERSION*/
@@ -1540,6 +2306,7 @@ int Fl_Tree::linespacing() const {
void Fl_Tree::linespacing(int val) {
_prefs.linespacing(val);
redraw();
+ recalc_tree();
}
/// Get the amount of white space (in pixels) that should appear
@@ -1555,40 +2322,50 @@ int Fl_Tree::openchild_marginbottom() const {
void Fl_Tree::openchild_marginbottom(int val) {
_prefs.openchild_marginbottom(val);
redraw();
+ recalc_tree();
}
+
/// Get the amount of white space (in pixels) that should appear
/// to the left of the usericon.
int Fl_Tree::usericonmarginleft() const {
return(_prefs.usericonmarginleft());
}
+
/// Set the amount of white space (in pixels) that should appear
/// to the left of the usericon.
void Fl_Tree::usericonmarginleft(int val) {
_prefs.usericonmarginleft(val);
redraw();
+ recalc_tree();
}
+
/// Get the amount of white space (in pixels) that should appear
/// to the left of the label text.
int Fl_Tree::labelmarginleft() const {
return(_prefs.labelmarginleft());
}
+
/// Set the amount of white space (in pixels) that should appear
/// to the left of the label text.
void Fl_Tree::labelmarginleft(int val) {
_prefs.labelmarginleft(val);
redraw();
+ recalc_tree();
}
+
#if FLTK_ABI_VERSION >= 10301
/// Get the amount of white space (in pixels) that should appear
/// to the left of the child fltk widget (if any).
int Fl_Tree::widgetmarginleft() const {
return(_prefs.widgetmarginleft());
}
+
/// Set the amount of white space (in pixels) that should appear
/// to the left of the child fltk widget (if any).
void Fl_Tree::widgetmarginleft(int val) {
_prefs.widgetmarginleft(val);
redraw();
+ recalc_tree();
}
#endif /*FLTK_ABI_VERSION*/
@@ -1605,6 +2382,7 @@ int Fl_Tree::connectorwidth() const {
void Fl_Tree::connectorwidth(int val) {
_prefs.connectorwidth(val);
redraw();
+ recalc_tree();
}
/// Returns the Fl_Image being used as the default user icon for all
@@ -1627,6 +2405,7 @@ Fl_Image* Fl_Tree::usericon() const {
void Fl_Tree::usericon(Fl_Image *val) {
_prefs.usericon(val);
redraw();
+ recalc_tree();
}
/// Returns the icon to be used as the 'open' icon.
@@ -1645,6 +2424,7 @@ Fl_Image* Fl_Tree::openicon() const {
void Fl_Tree::openicon(Fl_Image *val) {
_prefs.openicon(val);
redraw();
+ recalc_tree();
}
/// Returns the icon to be used as the 'close' icon.
@@ -1663,6 +2443,7 @@ Fl_Image* Fl_Tree::closeicon() const {
void Fl_Tree::closeicon(Fl_Image *val) {
_prefs.closeicon(val);
redraw();
+ recalc_tree();
}
/// Returns 1 if the collapse icon is enabled, 0 if not.
@@ -1681,6 +2462,7 @@ int Fl_Tree::showcollapse() const {
void Fl_Tree::showcollapse(int val) {
_prefs.showcollapse(val);
redraw();
+ recalc_tree();
}
/// Returns 1 if the root item is to be shown, or 0 if not.
@@ -1695,6 +2477,7 @@ int Fl_Tree::showroot() const {
void Fl_Tree::showroot(int val) {
_prefs.showroot(val);
redraw();
+ recalc_tree();
}
/// Returns the line drawing style for inter-connecting items.
@@ -1703,13 +2486,15 @@ Fl_Tree_Connector Fl_Tree::connectorstyle() const {
}
/// Sets the line drawing style for inter-connecting items.
+/// See ::Fl_Tree_Connector for possible values.
+///
void Fl_Tree::connectorstyle(Fl_Tree_Connector val) {
_prefs.connectorstyle(val);
redraw();
}
/// Set the default sort order used when items are added to the tree.
-/// See Fl_Tree_Sort for possible values.
+/// See ::Fl_Tree_Sort for possible values.
///
Fl_Tree_Sort Fl_Tree::sortorder() const {
return(_prefs.sortorder());
@@ -1722,7 +2507,7 @@ void Fl_Tree::sortorder(Fl_Tree_Sort val) {
}
/// Sets the style of box used to draw selected items.
-/// This is an fltk Fl_Boxtype.
+/// This is an fltk ::Fl_Boxtype.
/// The default is influenced by FLTK's current Fl::scheme()
///
Fl_Boxtype Fl_Tree::selectbox() const {
@@ -1730,7 +2515,7 @@ Fl_Boxtype Fl_Tree::selectbox() const {
}
/// Gets the style of box used to draw selected items.
-/// This is an fltk Fl_Boxtype.
+/// This is an fltk ::Fl_Boxtype.
/// The default is influenced by FLTK's current Fl::scheme()
///
void Fl_Tree::selectbox(Fl_Boxtype val) {
@@ -1744,44 +2529,64 @@ Fl_Tree_Select Fl_Tree::selectmode() const {
}
/// Sets the tree's selection mode.
+/// See ::Fl_Tree_Select for possible values.
+///
void Fl_Tree::selectmode(Fl_Tree_Select val) {
_prefs.selectmode(val);
}
#if FLTK_ABI_VERSION >= 10301
-/// Returns the current item re/selection mode
+/// Returns the current item re/selection mode.
+/// \version 1.3.1 ABI feature
+///
Fl_Tree_Item_Reselect_Mode Fl_Tree::item_reselect_mode() const {
return(_prefs.item_reselect_mode());
}
/// Sets the item re/selection mode
+/// See ::Fl_Tree_Item_Reselect_Mode for possible values.
+/// \version 1.3.1 ABI feature
+///
void Fl_Tree::item_reselect_mode(Fl_Tree_Item_Reselect_Mode mode) {
_prefs.item_reselect_mode(mode);
}
/// Get the 'item draw mode' used for the tree
+/// \version 1.3.1 ABI feature
+///
Fl_Tree_Item_Draw_Mode Fl_Tree::item_draw_mode() const {
return(_prefs.item_draw_mode());
}
-/// Set the 'item draw mode' used for the tree to \p val.
-/// This affects how items in the tree are drawn,
-/// such as when a widget() is defined.
-/// See Fl_Tree_Item_Draw_Mode for possible values.
+/// Set the 'item draw mode' used for the tree to \p 'mode'.
+///
+/// This affects how items in the tree are drawn,
+/// such as when a widget() is defined.
+/// See ::Fl_Tree_Item_Draw_Mode for possible values.
+/// \version 1.3.1 ABI feature
///
-void Fl_Tree::item_draw_mode(Fl_Tree_Item_Draw_Mode val) {
- _prefs.item_draw_mode(val);
+void Fl_Tree::item_draw_mode(Fl_Tree_Item_Draw_Mode mode) {
+ _prefs.item_draw_mode(mode);
}
-void Fl_Tree::item_draw_mode(int val) {
- _prefs.item_draw_mode(Fl_Tree_Item_Draw_Mode(val));
+
+/// Set the 'item draw mode' used for the tree to integer \p 'mode'.
+///
+/// This affects how items in the tree are drawn,
+/// such as when a widget() is defined.
+/// See ::Fl_Tree_Item_Draw_Mode for possible values.
+/// \version 1.3.1 ABI feature
+///
+void Fl_Tree::item_draw_mode(int mode) {
+ _prefs.item_draw_mode(Fl_Tree_Item_Draw_Mode(mode));
}
-#endif /*FLTK_ABI_VERSION*/
+#endif
-/// See if \p item is currently displayed on-screen (visible within the widget).
+/// See if \p 'item' is currently displayed on-screen (visible within the widget).
+///
/// This can be used to detect if the item is scrolled off-screen.
/// Checks to see if the item's vertical position is within the top and bottom
-/// edges of the display window. This does NOT take into account the hide()/show()
-/// or open()/close() status of the item.
+/// edges of the display window. This does NOT take into account the hide() / show()
+/// or open() / close() status of the item.
///
/// \param[in] item The item to be checked. If NULL, first() is used.
/// \returns 1 if displayed, 0 if scrolled off screen or no items are in tree.
@@ -1792,8 +2597,8 @@ int Fl_Tree::displayed(Fl_Tree_Item *item) {
return( (item->y() >= y()) && (item->y() <= (y()+h()-item->h())) ? 1 : 0);
}
-/// Adjust the vertical scroll bar so that \p item is visible
-/// \p yoff pixels from the top of the Fl_Tree widget's display.
+/// Adjust the vertical scroll bar so that \p 'item' is visible
+/// \p 'yoff' pixels from the top of the Fl_Tree widget's display.
///
/// For instance, yoff=0 will position the item at the top.
///
@@ -1816,7 +2621,7 @@ void Fl_Tree::show_item(Fl_Tree_Item *item, int yoff) {
redraw();
}
-/// Adjust the vertical scroll bar to show \p item at the top
+/// Adjust the vertical scroll bar to show \p 'item' at the top
/// of the display IF it is currently off-screen (e.g. show_item_top()).
/// If it is already on-screen, no change is made.
///
@@ -1831,7 +2636,7 @@ void Fl_Tree::show_item(Fl_Tree_Item *item) {
show_item_top(item);
}
-/// Adjust the vertical scrollbar so that \p item is at the top of the display.
+/// Adjust the vertical scrollbar so that \p 'item' is at the top of the display.
///
/// \param[in] item The item to be shown. If NULL, first() is used.
///
@@ -1840,25 +2645,33 @@ void Fl_Tree::show_item_top(Fl_Tree_Item *item) {
if (item) show_item(item, 0);
}
-/// Adjust the vertical scrollbar so that \p item is in the middle of the display.
+/// Adjust the vertical scrollbar so that \p 'item' is in the middle of the display.
///
/// \param[in] item The item to be shown. If NULL, first() is used.
///
void Fl_Tree::show_item_middle(Fl_Tree_Item *item) {
item = item ? item : first();
+#if FLTK_ABI_VERSION >= 10303
+ if (item) show_item(item, (_tih/2)-(item->h()/2));
+#else
if (item) show_item(item, (h()/2)-(item->h()/2));
+#endif
}
-/// Adjust the vertical scrollbar so that \p item is at the bottom of the display.
+/// Adjust the vertical scrollbar so that \p 'item' is at the bottom of the display.
///
/// \param[in] item The item to be shown. If NULL, first() is used.
///
void Fl_Tree::show_item_bottom(Fl_Tree_Item *item) {
item = item ? item : first();
+#if FLTK_ABI_VERSION >= 10303
+ if (item) show_item(item, _tih-item->h());
+#else
if (item) show_item(item, h()-item->h());
+#endif
}
-/// Displays \p item, scrolling the tree as necessary.
+/// Displays \p 'item', scrolling the tree as necessary.
/// \param[in] item The item to be displayed. If NULL, first() is used.
///
void Fl_Tree::display(Fl_Tree_Item *item) {
@@ -1868,19 +2681,17 @@ void Fl_Tree::display(Fl_Tree_Item *item) {
/// Returns the vertical scroll position as a pixel offset.
/// The position returned is how many pixels of the tree are scrolled off the top edge
-/// of the screen. Example: A position of '3' indicates the top 3 pixels of
-/// the tree are scrolled off the top edge of the screen.
+/// of the screen.
/// \see vposition(), hposition()
///
int Fl_Tree::vposition() const {
return((int)_vscroll->value());
}
-/// Sets the vertical scroll offset to position \p pos.
-/// The position is how many pixels of the tree are scrolled off the top edge
-/// of the screen. Example: A position of '3' scrolls the top three pixels of
-/// the tree off the top edge of the screen.
-/// \param[in] pos The vertical position (in pixels) to scroll the browser to.
+/// Sets the vertical scroll offset to position \p 'pos'.
+/// The position is how many pixels of the tree are scrolled off the top edge
+/// of the screen.
+/// \param[in] pos The vertical position (in pixels) to scroll the browser to.
///
void Fl_Tree::vposition(int pos) {
if (pos < 0) pos = 0;
@@ -1890,7 +2701,37 @@ void Fl_Tree::vposition(int pos) {
redraw();
}
-/// See if widget \p w is one of the Fl_Tree widget's scrollbars.
+/// Returns the horizontal scroll position as a pixel offset.
+/// The position returned is how many pixels of the tree are scrolled off the left edge
+/// of the screen.
+/// \see vposition(), hposition()
+/// \note Must be using FLTK ABI 1.3.3 or higher for this to be effective.
+///
+int Fl_Tree::hposition() const {
+#if FLTK_ABI_VERSION >= 10303
+ return((int)_hscroll->value());
+#else
+ return(0);
+#endif
+}
+
+/// Sets the horizontal scroll offset to position \p 'pos'.
+/// The position is how many pixels of the tree are scrolled off the left edge
+/// of the screen.
+/// \param[in] pos The vertical position (in pixels) to scroll the browser to.
+/// \note Must be using FLTK ABI 1.3.3 or higher for this to be effective.
+///
+void Fl_Tree::hposition(int pos) {
+#if FLTK_ABI_VERSION >= 10303
+ if (pos < 0) pos = 0;
+ if (pos > _hscroll->maximum()) pos = (int)_hscroll->maximum();
+ if (pos == _hscroll->value()) return;
+ _hscroll->value(pos);
+ redraw();
+#endif
+}
+
+/// See if widget \p 'w' is one of the Fl_Tree widget's scrollbars.
/// Use this to skip over the scrollbars when walking the child() array. Example:
/// \code
/// for ( int i=0; i<tree->children(); i++ ) { // walk children
@@ -1901,12 +2742,18 @@ void Fl_Tree::vposition(int pos) {
/// \endcode
/// \param[in] w Widget to test
/// \returns 1 if \p w is a scrollbar, 0 if not.
+/// \todo should be const
///
int Fl_Tree::is_scrollbar(Fl_Widget *w) {
- return( ( w == _vscroll ) ? 1 : 0 );
+#if FLTK_ABI_VERSION >= 10303
+ return( (w==_vscroll || w==_hscroll) ? 1 : 0 );
+#else
+ return( (w==_vscroll) ? 1 : 0 );
+#endif
}
-/// Gets the current size of the scrollbars' troughs, in pixels.
+/// Gets the default size of scrollbars' troughs for this widget
+/// in pixels.
///
/// If this value is zero (default), this widget will use the global
/// Fl::scrollbar_size() value as the scrollbar's width.
@@ -1918,16 +2765,17 @@ int Fl_Tree::scrollbar_size() const {
return(_scrollbar_size);
}
-/// Sets the pixel size of the scrollbars' troughs to the \p size, in pixels.
+/// Sets the pixel size of the scrollbars' troughs to \p 'size'
+/// for this widget, in pixels.
///
/// Normally you should not need this method, and should use the global
/// Fl::scrollbar_size(int) instead to manage the size of ALL
/// your widgets' scrollbars. This ensures your application
-/// has a consistent UI, is the default behavior, and is normally
-/// what you want.
+/// has a consistent UI, and is the default behavior. Normally
+/// this is what you want.
///
-/// Only use THIS method if you really need to override the global
-/// scrollbar size. The need for this should be rare.
+/// Only use this method if you really need to override just THIS
+/// instance of the widget's scrollbar size. (This need should be rare.)
///
/// Setting \p size to the special value of 0 causes the widget to
/// track the global Fl::scrollbar_size(), which is the default.
@@ -1942,15 +2790,37 @@ void Fl_Tree::scrollbar_size(int size) {
if ( _vscroll->w() != scrollsize ) {
_vscroll->resize(x()+w()-scrollsize, h(), scrollsize, _vscroll->h());
}
+#if FLTK_ABI_VERSION >= 10303
+ if ( _hscroll->h() != scrollsize ) {
+ _hscroll->resize(x(), y()+h()-scrollsize, _hscroll->w(), scrollsize);
+ }
+ // Changing scrollbar size affects _tiw/_tih + may affect scrollbar visibility
+ calc_dimensions();
+#endif
}
/// See if the vertical scrollbar is currently visible.
/// \returns 1 if scrollbar visible, 0 if not.
+///
int Fl_Tree::is_vscroll_visible() const {
return(_vscroll->visible() ? 1 : 0);
}
-/// Do the callback for the item, setting the item and reason
+/// See if the horizontal scrollbar is currently visible.
+/// \returns 1 if scrollbar visible, 0 if not.
+/// \note Must be using FLTK ABI 1.3.3 or higher for this to be effective.
+///
+int Fl_Tree::is_hscroll_visible() const {
+#if FLTK_ABI_VERSION >= 10303
+ return(_hscroll->visible() ? 1 : 0);
+#else
+ return 0;
+#endif
+}
+
+/// Do the callback for the specified \p 'item' using \p 'reason',
+/// setting the callback_item() and callback_reason().
+///
void Fl_Tree::do_callback_for_item(Fl_Tree_Item* item, Fl_Tree_Reason reason) {
callback_reason(reason);
callback_item(item);
@@ -1958,7 +2828,7 @@ void Fl_Tree::do_callback_for_item(Fl_Tree_Item* item, Fl_Tree_Reason reason) {
}
/// Sets the item that was changed for this callback.
-/// Used internally to pass the item that invoked the callback.
+/// Used internally to pass the item that invoked the callback.
///
void Fl_Tree::callback_item(Fl_Tree_Item* item) {
_callback_item = item;
@@ -2007,8 +2877,7 @@ Fl_Tree_Reason Fl_Tree::callback_reason() const {
* directly loaded into the tree view for inspection.
* \param[in] prefs the Fl_Preferences database
*/
-void Fl_Tree::load(Fl_Preferences &prefs)
-{
+void Fl_Tree::load(Fl_Preferences &prefs) {
int i, j, n, pn = (int) strlen(prefs.path());
char *p;
const char *path = prefs.path();
@@ -2056,13 +2925,30 @@ void Fl_Tree::fix_scrollbar_order() {
Fl_Widget** a = (Fl_Widget**)array();
if (a[children()-1] != _vscroll) {
int i,j;
+#if FLTK_ABI_VERSION >= 10303
+ for (i = j = 0; j < children(); j++) {
+ if (a[j] != _vscroll && a[j] != _hscroll ) a[i++] = a[j];
+ }
+ a[i++] = _hscroll;
+ a[i++] = _vscroll;
+#else
for (i = j = 0; j < children(); j++) {
if (a[j] != _vscroll) a[i++] = a[j];
}
a[i++] = _vscroll;
+#endif
}
}
+/// Schedule tree to recalc the entire tree size.
+/// \note Must be using FLTK ABI 1.3.3 or higher for this to be effective.
+///
+void Fl_Tree::recalc_tree() {
+#if FLTK_ABI_VERSION >= 10303
+ _tree_w = _tree_h = -1;
+#endif
+}
+
//
-// End of "$Id: Fl_Tree.cxx 9706 2012-11-06 20:46:14Z matt $".
+// End of "$Id: Fl_Tree.cxx 10275 2014-09-05 12:04:28Z cand $".
//
diff --git a/src/Fl_Tree_Item.cxx b/src/Fl_Tree_Item.cxx
index 81cb47b..d08494e 100644
--- a/src/Fl_Tree_Item.cxx
+++ b/src/Fl_Tree_Item.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: Fl_Tree_Item.cxx 9706 2012-11-06 20:46:14Z matt $"
+// "$Id: Fl_Tree_Item.cxx 10272 2014-09-05 02:59:00Z greg.ercolano $"
//
#include <stdio.h>
@@ -35,9 +35,22 @@ static int event_inside(const int xywh[4]) {
}
/// Constructor.
-/// Makes a new instance of Fl_Tree_Item using defaults from 'prefs'.
+/// Makes a new instance of Fl_Tree_Item using defaults from \p 'prefs'.
+#if FLTK_ABI_VERSION >= 10303
+/// \deprecated in 1.3.3 ABI -- you must use Fl_Tree_Item(Fl_Tree*) for proper horizontal scrollbar behavior.
+#endif
///
Fl_Tree_Item::Fl_Tree_Item(const Fl_Tree_Prefs &prefs) {
+ _Init(prefs, 0);
+}
+
+// Initialize the tree item
+// Used by constructors
+//
+void Fl_Tree_Item::_Init(const Fl_Tree_Prefs &prefs, Fl_Tree *tree) {
+#if FLTK_ABI_VERSION >= 10303
+ _tree = tree;
+#endif
_label = 0;
_labelfont = prefs.labelfont();
_labelsize = prefs.labelsize();
@@ -67,12 +80,29 @@ Fl_Tree_Item::Fl_Tree_Item(const Fl_Tree_Prefs &prefs) {
_usericon = 0;
_userdata = 0;
_parent = 0;
+#if FLTK_ABI_VERSION >= 10303
+ _children.manage_item_destroy(1); // let array's dtor manage destroying Fl_Tree_Items
+#endif
#if FLTK_ABI_VERSION >= 10301
_prev_sibling = 0;
_next_sibling = 0;
#endif /*FLTK_ABI_VERSION*/
}
+#if FLTK_ABI_VERSION >= 10303
+/// Constructor.
+/// Makes a new instance of Fl_Tree_Item for \p 'tree'.
+///
+/// This must be used instead of the older, deprecated Fl_Tree_Item(Fl_Tree_Prefs)
+/// constructor for proper horizontal scrollbar calculation.
+///
+/// \version 1.3.3 ABI feature
+///
+Fl_Tree_Item::Fl_Tree_Item(Fl_Tree *tree) {
+ _Init(tree->_prefs, tree);
+}
+#endif
+
// DTOR
Fl_Tree_Item::~Fl_Tree_Item() {
if ( _label ) {
@@ -86,6 +116,9 @@ Fl_Tree_Item::~Fl_Tree_Item() {
/// Copy constructor.
Fl_Tree_Item::Fl_Tree_Item(const Fl_Tree_Item *o) {
+#if FLTK_ABI_VERSION >= 10303
+ _tree = o->_tree;
+#endif
_label = o->label() ? strdup(o->label()) : 0;
_labelfont = o->labelfont();
_labelsize = o->labelsize();
@@ -125,31 +158,34 @@ Fl_Tree_Item::Fl_Tree_Item(const Fl_Tree_Item *o) {
/// Used mainly for debugging.
///
void Fl_Tree_Item::show_self(const char *indent) const {
- if ( label() ) {
+ const char *thelabel = label() ? label() : "(NULL)";
#if FLTK_ABI_VERSION >= 10301
- printf("%s-%s (%d children, this=%p, parent=%p, prev=%p, next=%p, depth=%d)\n",
- indent,label(),children(),(void*)this, (void*)_parent,
- _prev_sibling, _next_sibling, depth());
+ printf("%s-%s (%d children, this=%p, parent=%p, prev=%p, next=%p, depth=%d)\n",
+ indent,thelabel,children(),(void*)this, (void*)_parent,
+ _prev_sibling, _next_sibling, depth());
#else /*FLTK_ABI_VERSION*/
- printf("%s-%s (%d children, this=%p, parent=%p depth=%d)\n",
- indent,label(),children(),(void*)this, (void*)_parent, depth());
+ printf("%s-%s (%d children, this=%p, parent=%p depth=%d)\n",
+ indent,thelabel,children(),(void*)this, (void*)_parent, depth());
#endif /*FLTK_ABI_VERSION*/
- }
if ( children() ) {
- char *i2 = (char*)malloc(strlen(indent) + 2);
+ char *i2 = new char [strlen(indent)+2];
strcpy(i2, indent);
strcat(i2, " |");
for ( int t=0; t<children(); t++ ) {
child(t)->show_self(i2);
}
+ delete[] i2;
}
fflush(stdout);
}
-/// Set the label. Makes a copy of the name.
+/// Set the label to \p 'name'.
+/// Makes and manages an internal copy of \p 'name'.
+///
void Fl_Tree_Item::label(const char *name) {
if ( _label ) { free((void*)_label); _label = 0; }
_label = name ? strdup(name) : 0;
+ recalc_tree(); // may change label geometry
}
/// Return the label.
@@ -157,7 +193,7 @@ const char *Fl_Tree_Item::label() const {
return(_label);
}
-/// Return child item for the specified 'index'.
+/// Return const child item for the specified 'index'.
const Fl_Tree_Item *Fl_Tree_Item::child(int index) const {
return(_children[index]);
}
@@ -165,51 +201,55 @@ const Fl_Tree_Item *Fl_Tree_Item::child(int index) const {
/// Clear all the children for this item.
void Fl_Tree_Item::clear_children() {
_children.clear();
+ recalc_tree(); // may change tree geometry
}
-/// Return the index of the immediate child of this item that has the label 'name'.
+/// Return the index of the immediate child of this item
+/// that has the label \p 'name'.
///
/// \returns index of found item, or -1 if not found.
+/// \version 1.3.0 release
///
int Fl_Tree_Item::find_child(const char *name) {
if ( name ) {
- for ( int t=0; t<children(); t++ ) {
- if ( child(t)->label() ) {
- if ( strcmp(child(t)->label(), name) == 0 ) {
+ for ( int t=0; t<children(); t++ )
+ if ( child(t)->label() )
+ if ( strcmp(child(t)->label(), name) == 0 )
return(t);
- }
- }
- }
}
return(-1);
}
-/// Find child item by descending array of names. Does not include self in search.
-/// Only Fl_Tree should need this method.
+/// Return the /immediate/ child of current item
+/// that has the label \p 'name'.
///
-/// \returns item, or 0 if not found
+/// \returns const found item, or 0 if not found.
+/// \version 1.3.3
///
-const Fl_Tree_Item *Fl_Tree_Item::find_child_item(char **arr) const {
- for ( int t=0; t<children(); t++ ) {
- if ( child(t)->label() ) {
- if ( strcmp(child(t)->label(), *arr) == 0 ) { // match?
- if ( *(arr+1) ) { // more in arr? descend
- return(_children[t]->find_item(arr+1));
- } else { // end of arr? done
- return(_children[t]);
- }
- }
- }
- }
+const Fl_Tree_Item* Fl_Tree_Item::find_child_item(const char *name) const {
+ if ( name )
+ for ( int t=0; t<children(); t++ )
+ if ( child(t)->label() )
+ if ( strcmp(child(t)->label(), name) == 0 )
+ return(child(t));
return(0);
}
-/// Find child item by descending array of names. Does not include self in search.
-/// Only Fl_Tree should need this method. Use Fl_Tree::find_item() instead.
+/// Non-const version of Fl_Tree_Item::find_child_item(const char *name) const.
+Fl_Tree_Item* Fl_Tree_Item::find_child_item(const char *name) {
+ // "Effective C++, 3rd Ed", p.23. Sola fide, Amen.
+ return(const_cast<Fl_Tree_Item*>(
+ static_cast<const Fl_Tree_Item &>(*this).find_child_item(name)));
+}
+
+/// Find child item by descending array \p 'arr' of names.
+/// Does not include self in search.
+/// Only Fl_Tree should need this method.
///
/// \returns item, or 0 if not found
+/// \version 1.3.0 release
///
-Fl_Tree_Item *Fl_Tree_Item::find_child_item(char **arr) {
+const Fl_Tree_Item *Fl_Tree_Item::find_child_item(char **arr) const {
for ( int t=0; t<children(); t++ ) {
if ( child(t)->label() ) {
if ( strcmp(child(t)->label(), *arr) == 0 ) { // match?
@@ -224,16 +264,24 @@ Fl_Tree_Item *Fl_Tree_Item::find_child_item(char **arr) {
return(0);
}
-/// Find item by descending array of \p names. Includes self in search.
+/// Non-const version of Fl_Tree_Item::find_child_item(char **arr) const.
+Fl_Tree_Item *Fl_Tree_Item::find_child_item(char **arr) {
+ // "Effective C++, 3rd Ed", p.23. Sola fide, Amen.
+ return(const_cast<Fl_Tree_Item*>(
+ static_cast<const Fl_Tree_Item &>(*this).find_child_item(arr)));
+}
+
+/// Find item by descending array of \p 'names'.
+/// Includes self in search.
/// Only Fl_Tree should need this method. Use Fl_Tree::find_item() instead.
///
-/// \returns item, or 0 if not found
+/// \returns const item, or 0 if not found
///
const Fl_Tree_Item *Fl_Tree_Item::find_item(char **names) const {
+ if ( ! *names ) return(0);
if ( label() && strcmp(label(), *names) == 0 ) { // match self?
- if ( *(names+1) == 0 ) { // end of names,
- return(this); // found ourself.
- }
+ ++names; // skip self
+ if ( *names == 0 ) return(this); // end of names, found ourself
}
if ( children() ) { // check children..
return(find_child_item(names));
@@ -241,44 +289,56 @@ const Fl_Tree_Item *Fl_Tree_Item::find_item(char **names) const {
return(0);
}
-/// Find item by descending array of \p names. Includes self in search.
-/// Only Fl_Tree should need this method.
-///
-/// \returns item, or 0 if not found
-///
+/// Non-const version of Fl_Tree_Item::find_item(char **names) const.
Fl_Tree_Item *Fl_Tree_Item::find_item(char **names) {
- if ( label() && strcmp(label(), *names) == 0 ) { // match self?
- if ( *(names+1) == 0 ) { // end of names,
- return(this); // found ourself.
- }
- }
- if ( children() ) { // check children..
- return(find_child_item(names));
- }
- return(0);
+ // "Effective C++, 3rd Ed", p.23. Sola fide, Amen.
+ return(const_cast<Fl_Tree_Item*>(
+ static_cast<const Fl_Tree_Item &>(*this).find_item(names)));
}
-/// Find the index number for the specified 'item'
+/// Find the index number for the specified \p 'item'
/// in the current item's list of children.
///
/// \returns the index, or -1 if not found.
///
int Fl_Tree_Item::find_child(Fl_Tree_Item *item) {
- for ( int t=0; t<children(); t++ ) {
- if ( item == child(t) ) {
+ for ( int t=0; t<children(); t++ )
+ if ( item == child(t) )
return(t);
- }
- }
return(-1);
}
-/// Add a new child to this item with the name 'new_label', with defaults from 'prefs'.
+/// Add a new child to this item with the name \p 'new_label'
+/// and defaults from \p 'prefs'.
/// An internally managed copy is made of the label string.
/// Adds the item based on the value of prefs.sortorder().
+/// \returns the item added
+/// \version 1.3.0 release
///
-Fl_Tree_Item *Fl_Tree_Item::add(const Fl_Tree_Prefs &prefs, const char *new_label) {
- Fl_Tree_Item *item = new Fl_Tree_Item(prefs);
- item->label(new_label);
+Fl_Tree_Item *Fl_Tree_Item::add(const Fl_Tree_Prefs &prefs,
+ const char *new_label) {
+ return(add(prefs, new_label, (Fl_Tree_Item*)0));
+}
+
+/// Add \p 'item' as immediate child with \p 'new_label'
+/// and defaults from \p 'prefs'.
+/// If \p 'item' is NULL, a new item is created.
+/// An internally managed copy is made of the label string.
+/// Adds the item based on the value of prefs.sortorder().
+/// \returns the item added
+/// \version 1.3.3
+///
+Fl_Tree_Item *Fl_Tree_Item::add(const Fl_Tree_Prefs &prefs,
+ const char *new_label,
+ Fl_Tree_Item *item) {
+#if FLTK_ABI_VERSION >= 10303
+ if ( !item )
+ { item = new Fl_Tree_Item(_tree); item->label(new_label); }
+#else
+ if ( !item )
+ { item = new Fl_Tree_Item(prefs); item->label(new_label); }
+#endif
+ recalc_tree(); // may change tree geometry
item->_parent = this;
switch ( prefs.sortorder() ) {
case FL_TREE_SORT_NONE: {
@@ -311,38 +371,73 @@ Fl_Tree_Item *Fl_Tree_Item::add(const Fl_Tree_Prefs &prefs, const char *new_labe
return(item);
}
-/// Descend into the path specified by \p arr, and add a new child there.
+/// Descend into the path specified by \p 'arr', and add a new child there.
/// Should be used only by Fl_Tree's internals.
/// Adds the item based on the value of prefs.sortorder().
/// \returns the item added.
+/// \version 1.3.0 release
///
Fl_Tree_Item *Fl_Tree_Item::add(const Fl_Tree_Prefs &prefs, char **arr) {
- int t = (*arr && *(arr+1)) ? find_child(*arr) : -1;
- Fl_Tree_Item *item = 0;
- if ( t == -1 ) {
- item = (Fl_Tree_Item*)add(prefs, *arr);
- } else {
- item = (Fl_Tree_Item*)child(t);
- }
- if ( *(arr+1) ) { // descend?
- return(item->add(prefs, arr+1));
- } else {
- return(item); // end? done
+ return add(prefs, arr, 0);
+}
+
+/// Descend into path specified by \p 'arr' and add \p 'newitem' there.
+/// Should be used only by Fl_Tree's internals.
+/// If item is NULL, a new item is created.
+/// Adds the item based on the value of prefs.sortorder().
+/// \returns the item added.
+/// \version 1.3.3 ABI feature
+///
+Fl_Tree_Item *Fl_Tree_Item::add(const Fl_Tree_Prefs &prefs,
+ char **arr,
+ Fl_Tree_Item *newitem) {
+ if ( !*arr ) return 0;
+ // See if we can find an existing child with name requested.
+ Fl_Tree_Item *child = find_child_item(*arr);
+ if ( child ) { // Child found?
+ if ( *(arr+1) == 0 ) { // ..and at end of path?
+ if ( !newitem ) { // ..and no item specified?
+ return 0; // ..error: child exists already
+ } else {
+ // Child found, end of path, item specified
+ return child->add(prefs, newitem->label(), newitem);
+ }
+ }
+ // Child found: more path elements to go or item specified?
+ // Descend into child to handle add..
+ return child->add(prefs, arr+1, newitem); // recurse
}
+ // No child found, see if we reached end of path.
+ // If so, add as an immediate child, done
+ if ( *(arr+1) == 0 ) // end of path?
+ return add(prefs, *arr, newitem); // add as immediate child
+
+ // No child found, but more to path?
+ // If so, create new child to handle add()
+ Fl_Tree_Item *newchild;
+ return (newchild=add(prefs, *arr)) // create new immediate child
+ ? newchild->add(prefs,arr+1,newitem) // it worked? recurse to add
+ : 0; // failed? error
}
-/// Insert a new item into current item's children at a specified position.
+/// Insert a new item named \p 'new_label' into current item's
+/// children at a specified position \p 'pos'.
/// \returns the new item inserted.
///
Fl_Tree_Item *Fl_Tree_Item::insert(const Fl_Tree_Prefs &prefs, const char *new_label, int pos) {
+#if FLTK_ABI_VERSION >= 10303
+ Fl_Tree_Item *item = new Fl_Tree_Item(_tree);
+#else
Fl_Tree_Item *item = new Fl_Tree_Item(prefs);
+#endif
item->label(new_label);
item->_parent = this;
_children.insert(pos, item);
+ recalc_tree(); // may change tree geometry
return(item);
}
-/// Insert a new item above this item.
+/// Insert a new item named \p 'new_label' above this item.
/// \returns the new item inserted, or 0 if an error occurred.
///
Fl_Tree_Item *Fl_Tree_Item::insert_above(const Fl_Tree_Prefs &prefs, const char *new_label) {
@@ -358,28 +453,231 @@ Fl_Tree_Item *Fl_Tree_Item::insert_above(const Fl_Tree_Prefs &prefs, const char
return(0);
}
-/// Remove child by item.
-/// \returns 0 if removed, -1 if item not an immediate child.
+/// Deparent child at index position \p 'pos'.
+/// This creates an "orphaned" item that is still allocated,
+/// but has no parent or siblings. Normally the caller would
+/// want to immediately reparent the orphan elsewhere.
+///
+/// A successfully orphaned item will have its parent()
+/// and prev_sibling()/next_sibling() set to NULL.
+///
+/// \returns
+/// - pointer to orphaned item on success
+/// - NULL on error (could not deparent the item)
+///
+Fl_Tree_Item* Fl_Tree_Item::deparent(int pos) {
+ Fl_Tree_Item *orphan = _children[pos];
+ if ( _children.deparent(pos) < 0 ) return NULL;
+ return orphan;
+}
+
+/// Reparent specified item as a child of ourself at position \p 'pos'.
+/// Typically 'newchild' was recently orphaned with deparent().
+///
+/// \returns
+/// - 0: on success
+/// - -1: on error (e.g. if \p 'pos' out of range)
+///
+int Fl_Tree_Item::reparent(Fl_Tree_Item *newchild, int pos) {
+ int ret;
+ if ( (ret = _children.reparent(newchild, this, pos)) < 0 ) return ret;
+ newchild->parent(this); // take custody
+ return 0;
+}
+
+/// Move the item 'to' to sibling position of 'from'.
+///
+/// \returns
+/// - 0: Success
+/// - -1: range error (e.g. if \p 'to' or \p 'from' out of range).
+/// - (Other return values reserved for future use)
+///
+int Fl_Tree_Item::move(int to, int from) {
+ return _children.move(to, from);
+}
+
+/// Move the current item above/below/into the specified 'item',
+/// where \p 'op' determines the type of move:
+///
+/// - 0: move above \p 'item' (\p 'pos' ignored)
+/// - 1: move below \p 'item' (\p 'pos' ignored)
+/// - 2: move into \p 'item' as a child (at optional position \p 'pos')
+///
+/// \returns 0 on success. a negative number on error:
+/// - -1: one of the items has no parent
+/// - -2: item's index could not be determined
+/// - -3: bad 'op'
+/// - -4: index range error
+/// - -5: could not deparent
+/// - -6: could not reparent at \p 'pos'
+/// - (Other return values reserved for future use.)
+///
+int Fl_Tree_Item::move(Fl_Tree_Item *item, int op, int pos) {
+ Fl_Tree_Item *from_parent, *to_parent;
+ int from, to;
+ switch (op) {
+ case 0: // "above"
+ from_parent = this->parent();
+ to_parent = item->parent();
+ from = from_parent->find_child(this);
+ to = to_parent->find_child(item);
+ break;
+ case 1: // "below"
+ from_parent = this->parent();
+ to_parent = item->parent();
+ from = from_parent->find_child(this);
+ to = to_parent->find_child(item);
+ break;
+ case 2: // "into"
+ from_parent = this->parent();
+ to_parent = item;
+ from = from_parent->find_child(this);
+ to = pos;
+ break;
+ default:
+ return -3;
+ }
+ if ( !from_parent || !to_parent ) return -1;
+ if ( from < 0 || to < 0 ) return -2;
+ if ( from_parent == to_parent ) { // same parent?
+ switch (op) { // 'to' offsets due to scroll
+ case 0: if ( from < to && to > 0 ) --to; break;
+ case 1: if ( from > to && to < to_parent->children() ) ++to; break;
+ }
+ if ( from_parent->move(to, from) < 0 ) // simple move among siblings
+ return -4;
+ } else { // different parent?
+ if ( to > to_parent->children() ) // try to prevent a reparent() error
+ return -4;
+ if ( from_parent->deparent(from) < 0 ) // deparent self from current parent
+ return -5;
+ if ( to_parent->reparent(this, to) < 0 ) { // reparent self to new parent at position 'to'
+ to_parent->reparent(this, 0); // failed? shouldn't happen, reparent at 0
+ return -6;
+ }
+ }
+ return 0;
+}
+
+/// Move the current item above the specified 'item'.
+/// This is the equivalent of calling move(item,0,0).
+///
+/// \returns 0 on success.<br>
+/// On error returns a negative value;
+/// see move(Fl_Tree_Item*,int,int) for possible error codes.
+///
+int Fl_Tree_Item::move_above(Fl_Tree_Item *item) {
+ return move(item, 0, 0);
+}
+
+/// Move the current item below the specified 'item'.
+/// This is the equivalent of calling move(item,1,0).
+///
+/// \returns 0 on success.<br>
+/// On error returns a negative value;
+/// see move(Fl_Tree_Item*,int,int) for possible error codes.
+///
+int Fl_Tree_Item::move_below(Fl_Tree_Item *item) {
+ return move(item, 1, 0);
+}
+
+/// Parent the current item as a child of the specified \p 'item'.
+/// This is the equivalent of calling move(item,2,pos).
+///
+/// \returns 0 on success.<br>
+/// On error returns a negative value;
+/// see move(Fl_Tree_Item*,int,int) for possible error codes.
+///
+int Fl_Tree_Item::move_into(Fl_Tree_Item *item, int pos) {
+ return move(item, 2, pos);
+}
+
+#if FLTK_ABI_VERSION >= 10303
+/// Return the parent tree's prefs.
+/// \returns a reference to the parent tree's Fl_Tree_Prefs
+/// \version 1.3.3 ABI feature
+///
+const Fl_Tree_Prefs& Fl_Tree_Item::prefs() const {
+ return(_tree->_prefs);
+}
+
+/// Replace the current item with a new item.
+///
+/// The current item is destroyed if successful.
+/// No checks are made to see if an item with the same name exists.
+///
+/// This method can be used to, for example, install 'custom' items
+/// into the tree derived from Fl_Tree_Item; see draw_item_content().
+///
+/// \param[in] newitem The new item to replace the current item
+/// \returns newitem on success, NULL if could not be replaced.
+/// \see Fl_Tree_Item::draw_item_content(), Fl_Tree::root(Fl_Tree_Item*)
+/// \version 1.3.3 ABI feature
+///
+Fl_Tree_Item *Fl_Tree_Item::replace(Fl_Tree_Item *newitem) {
+ Fl_Tree_Item *p = parent();
+ if ( !p ) { // no parent? then we're the tree's root..
+ _tree->root(newitem); // ..tell tree to replace root
+ return newitem;
+ }
+ // has parent? ask parent to replace us
+ return p->replace_child(this, newitem);
+}
+
+/// Replace existing child \p 'olditem' with \p 'newitem'.
+///
+/// The \p 'olditem' is destroyed if successful.
+/// Can be used to put custom items (derived from Fl_Tree_Item) into the tree.
+/// No checks are made to see if an item with the same name exists.
+///
+/// \param[in] olditem The item to be found and replaced
+/// \param[in] newitem The new item to take the place of \p 'olditem'
+/// \returns newitem on success and \p 'olditem' is destroyed.
+/// NULL on error if \p 'olditem' was not found
+/// as an immediate child.
+/// \see replace(), Fl_Tree_Item::draw()
+/// \version 1.3.3 ABI feature
+///
+Fl_Tree_Item *Fl_Tree_Item::replace_child(Fl_Tree_Item *olditem,
+ Fl_Tree_Item *newitem) {
+ int pos = find_child(olditem); // find our index for olditem
+ if ( pos == -1 ) return(NULL);
+ newitem->_parent = this;
+ // replace in array (handles stitching neighboring items)
+ _children.replace(pos, newitem);
+ recalc_tree(); // newitem may have changed tree geometry
+ return newitem;
+}
+#endif
+
+/// Remove \p 'item' from the current item's children.
+/// \returns 0 if removed, -1 if item not an immediate child.
///
int Fl_Tree_Item::remove_child(Fl_Tree_Item *item) {
for ( int t=0; t<children(); t++ ) {
if ( child(t) == item ) {
item->clear_children();
_children.remove(t);
+ recalc_tree(); // may change tree geometry
return(0);
}
}
return(-1);
}
-/// Remove immediate child (and its children) by its label 'name'.
+/// Remove immediate child (and its children) by its label \p 'name'.
+/// If more than one item matches \p 'name', only the first
+/// matching item is removed.
+/// \param[in] name The label name of the immediate child to remove
/// \returns 0 if removed, -1 if not found.
+/// \version 1.3.3
///
int Fl_Tree_Item::remove_child(const char *name) {
for ( int t=0; t<children(); t++ ) {
if ( child(t)->label() ) {
if ( strcmp(child(t)->label(), name) == 0 ) {
_children.remove(t);
+ recalc_tree(); // may change tree geometry
return(0);
}
}
@@ -387,30 +685,27 @@ int Fl_Tree_Item::remove_child(const char *name) {
return(-1);
}
-/// Swap two of our children, given two child index values.
-/// Use this eg. for sorting.
-///
-/// This method is FAST, and does not involve lookups.
-///
+/// Swap two of our children, given two child index values \p 'ax' and \p 'bx'.
+/// Use e.g. for sorting.<br>
+/// This method is FAST, and does not involve lookups.<br>
/// No range checking is done on either index value.
-///
-/// \returns
-/// - 0 : OK
-/// - -1 : failed: 'a' or 'b' is not our immediate child
+/// \param[in] ax,bx the index of the items to swap
///
void Fl_Tree_Item::swap_children(int ax, int bx) {
_children.swap(ax, bx);
}
-/// Swap two of our children, given item pointers.
-/// Use this eg. for sorting.
+/// Swap two of our immediate children, given item pointers.
+/// Use e.g. for sorting.
///
-/// This method is SLOW because it involves linear lookups.
+/// This method is SLOW because it involves linear lookups.<br>
/// For speed, use swap_children(int,int) instead.
///
+/// \param[in] a,b The item ptrs of the two items to swap.
+/// Both must be immediate children of the current item.
/// \returns
/// - 0 : OK
-/// - -1 : failed: 'a' or 'b' is not our immediate child
+/// - -1 : failed: item \p 'a' or \p 'b' is not our child.
///
int Fl_Tree_Item::swap_children(Fl_Tree_Item *a, Fl_Tree_Item *b) {
int ax = -1, bx = -1;
@@ -424,6 +719,11 @@ int Fl_Tree_Item::swap_children(Fl_Tree_Item *a, Fl_Tree_Item *b) {
}
/// Internal: Horizontal connector line based on preference settings.
+/// \param[in] x1 The left hand X position of the horizontal connector
+/// \param[in] x2 The right hand X position of the horizontal connector
+/// \param[in] y The vertical position of the horizontal connector
+/// \param[in] prefs The Fl_Tree prefs
+///
void Fl_Tree_Item::draw_horizontal_connector(int x1, int x2, int y, const Fl_Tree_Prefs &prefs) {
fl_color(prefs.connectorcolor());
switch ( prefs.connectorstyle() ) {
@@ -445,6 +745,11 @@ void Fl_Tree_Item::draw_horizontal_connector(int x1, int x2, int y, const Fl_Tre
}
/// Internal: Vertical connector line based on preference settings.
+/// \param[in] x The x position of the vertical connector
+/// \param[in] y1 The top of the vertical connector
+/// \param[in] y2 The bottom of the vertical connector
+/// \param[in] prefs The Fl_Tree prefs
+///
void Fl_Tree_Item::draw_vertical_connector(int x, int y1, int y2, const Fl_Tree_Prefs &prefs) {
fl_color(prefs.connectorcolor());
switch ( prefs.connectorstyle() ) {
@@ -467,45 +772,55 @@ void Fl_Tree_Item::draw_vertical_connector(int x, int y1, int y2, const Fl_Tree_
}
}
+#if FLTK_ABI_VERSION >= 10303
/// Find the item that the last event was over.
+/// If \p 'yonly' is 1, only check event's y value, don't care about x.
+/// \param[in] prefs The parent tree's Fl_Tree_Prefs
+/// \param[in] yonly -- 0: check both event's X and Y values.
+/// -- 1: only check event's Y value, don't care about X.
+/// \returns pointer to clicked item, or NULL if none found
+/// \version 1.3.3 ABI feature
///
-/// Returns the item if it is visible, and mouse is over it.
-/// Works even if widget deactivated.
-/// Use event_on_collapse_icon() to determine if collapse button was pressed.
-///
-/// \returns const visible item under the event if found, or 0 if none.
-///
-const Fl_Tree_Item *Fl_Tree_Item::find_clicked(const Fl_Tree_Prefs &prefs) const {
+const Fl_Tree_Item *Fl_Tree_Item::find_clicked(const Fl_Tree_Prefs &prefs, int yonly) const {
if ( ! is_visible() ) return(0);
if ( is_root() && !prefs.showroot() ) {
// skip event check if we're root but root not being shown
} else {
// See if event is over us
- if ( event_inside(_xywh) ) { // event within this item?
- return(this); // found
+ if ( yonly ) {
+ if ( Fl::event_y() >= _xywh[1] &&
+ Fl::event_y() <= (_xywh[1]+_xywh[3]) ) {
+ return(this);
+ }
+ } else {
+ if ( event_inside(_xywh) ) { // event within this item?
+ return(this); // found
+ }
}
}
if ( is_open() ) { // open? check children of this item
for ( int t=0; t<children(); t++ ) {
const Fl_Tree_Item *item;
- if ( ( item = _children[t]->find_clicked(prefs) ) != NULL) { // check child and its descendents
- return(item); // found?
- }
+ if ( (item = _children[t]->find_clicked(prefs, yonly)) != NULL) // recurse into child for descendents
+ return(item); // found?
}
}
return(0);
}
-/// Non-const version of the above.
+/// Non-const version of Fl_Tree_Item::find_clicked(const Fl_Tree_Prefs&,int) const
+Fl_Tree_Item *Fl_Tree_Item::find_clicked(const Fl_Tree_Prefs &prefs, int yonly) {
+ // "Effective C++, 3rd Ed", p.23. Sola fide, Amen.
+ return(const_cast<Fl_Tree_Item*>(
+ static_cast<const Fl_Tree_Item &>(*this).find_clicked(prefs, yonly)));
+}
+#else
/// Find the item that the last event was over.
+/// \param[in] prefs The parent tree's Fl_Tree_Prefs
+/// \returns pointer to clicked item, or NULL if none found
+/// \version 1.3.0
///
-/// Returns the item if it is visible, and mouse is over it.
-/// Works even if widget deactivated.
-/// Use event_on_collapse_icon() to determine if collapse button was pressed.
-///
-/// \returns the visible item under the event if found, or 0 if none.
-///
-Fl_Tree_Item *Fl_Tree_Item::find_clicked(const Fl_Tree_Prefs &prefs) {
+const Fl_Tree_Item *Fl_Tree_Item::find_clicked(const Fl_Tree_Prefs &prefs) const {
if ( ! is_visible() ) return(0);
if ( is_root() && !prefs.showroot() ) {
// skip event check if we're root but root not being shown
@@ -517,16 +832,23 @@ Fl_Tree_Item *Fl_Tree_Item::find_clicked(const Fl_Tree_Prefs &prefs) {
}
if ( is_open() ) { // open? check children of this item
for ( int t=0; t<children(); t++ ) {
- Fl_Tree_Item *item;
- if ( ( item = _children[t]->find_clicked(prefs) ) != NULL ) { // check child and its descendents
- return(item); // found?
- }
+ const Fl_Tree_Item *item;
+ if ( (item = _children[t]->find_clicked(prefs)) != NULL) // recurse into child for descendents
+ return(item); // found?
}
}
return(0);
}
-static void draw_item_focus(Fl_Boxtype B, Fl_Color C, int X, int Y, int W, int H) {
+/// Non-const version of Fl_Tree_Item::find_clicked(const Fl_Tree_Prefs&) const.
+Fl_Tree_Item *Fl_Tree_Item::find_clicked(const Fl_Tree_Prefs &prefs) {
+ // "Effective C++, 3rd Ed", p.23. Sola fide, Amen.
+ return(const_cast<Fl_Tree_Item*>(
+ static_cast<const Fl_Tree_Item &>(*this).find_clicked(prefs)));
+}
+#endif
+
+static void draw_item_focus(Fl_Boxtype B, Fl_Color fg, Fl_Color bg, int X, int Y, int W, int H) {
if (!Fl::visible_focus()) return;
switch (B) {
case FL_DOWN_BOX:
@@ -538,7 +860,7 @@ static void draw_item_focus(Fl_Boxtype B, Fl_Color C, int X, int Y, int W, int H
default:
break;
}
- fl_color(fl_contrast(FL_BLACK, C));
+ fl_color(fl_contrast(fg, bg));
#if defined(USE_X11) || defined(__APPLE_QUARTZ__)
fl_line_style(FL_DOT);
@@ -566,8 +888,14 @@ static void draw_item_focus(Fl_Boxtype B, Fl_Color C, int X, int Y, int W, int H
#endif
}
-/// Return the item's 'visible' height.
-/// Doesn't include linespacing(); prevents affecting eg. height of widget().
+/// Return the item's 'visible' height. Takes into account the item's:
+/// - visibility (if !is_visible(), returns 0)
+/// - labelfont() height: if label() != NULL
+/// - widget() height: if widget() != NULL
+/// - openicon() height (if not NULL)
+/// - usericon() height (if not NULL)
+/// Does NOT include Fl_Tree::linespacing();
+/// \returns maximum pixel height
///
int Fl_Tree_Item::calc_item_height(const Fl_Tree_Prefs &prefs) const {
if ( ! is_visible() ) return(0);
@@ -590,7 +918,336 @@ int Fl_Tree_Item::calc_item_height(const Fl_Tree_Prefs &prefs) const {
return(H);
}
+#if FLTK_ABI_VERSION >= 10303
+// These methods held for 1.3.3 ABI: all need 'tree()' back-reference.
+
+/// Returns the recommended foreground color used for drawing this item.
+/// \see draw_item_content()
+/// \version 1.3.3 ABI ABI
+///
+Fl_Color Fl_Tree_Item::drawfgcolor() const {
+ return is_selected() ? fl_contrast(_labelfgcolor, tree()->selection_color())
+ : is_active() ? _labelfgcolor
+ : fl_inactive(_labelfgcolor);
+}
+
+/// Returns the recommended background color used for drawing this item.
+/// \see draw_item_content()
+/// \version 1.3.3 ABI
+///
+Fl_Color Fl_Tree_Item::drawbgcolor() const {
+ const Fl_Color unspecified = 0xffffffff;
+ return is_selected() ? is_active() ? tree()->selection_color()
+ : fl_inactive(tree()->selection_color())
+ : _labelbgcolor == unspecified ? tree()->color()
+ : _labelbgcolor;
+}
+
+/// Draw the item content
+///
+/// This method can be overridden to implement custom drawing
+/// by filling the label_[xywh]() area with content.
+///
+/// A minimal example of how to override draw_item_content()
+/// and draw just a normal item's background and label ourselves:
+///
+/// \code
+/// class MyTreeItem : public Fl_Tree_Item {
+/// public:
+/// MyTreeItem() { }
+/// ~MyTreeItem() { }
+/// // DRAW OUR CUSTOM CONTENT FOR THE ITEM
+/// int draw_item_content(int render) {
+/// // Our item's dimensions + text content
+/// int X=label_x(), Y=label_y(), W=label_w(), H=label_h();
+/// const char *text = label() ? label() : "";
+/// // Rendering? Do any drawing that's needed
+/// if ( render ) {
+/// // Draw bg -- a filled rectangle
+/// fl_color(drawbgcolor()); fl_rectf(X,Y,W,H);
+/// // Draw label
+/// fl_font(labelfont(), labelsize()); // use item's label font/size
+/// fl_color(drawfgcolor()); // use recommended fg color
+/// fl_draw(text, X,Y,W,H, FL_ALIGN_LEFT); // draw the item's label
+/// }
+/// // Rendered or not, we must calculate content's max X position
+/// int lw=0, lh=0;
+/// fl_measure(text, lw, lh); // get width of label text
+/// return X + lw; // return X + label width
+/// }
+/// };
+/// \endcode
+///
+/// You can draw anything you want inside draw_item_content()
+/// using any of the fl_draw.H functions, as long as it's
+/// within the label's xywh area.
+///
+/// To add instances of your custom item to the tree, you can use:
+///
+/// \code
+/// // Example #1: using add()
+/// MyTreeItem *bart = new MyTreeItem(..); // class derived from Fl_Tree_Item
+/// tree->add("/Simpsons/Bart", bart); // Add item as /Simpsons/Bart
+/// \endcode
+///
+/// ..or you can insert or replace existing items:
+///
+/// \code
+/// // Example #2: using replace()
+/// MyTreeItem *marge = new MyTreeItem(..); // class derived from Fl_Tree_Item
+/// item = tree->add("/Simpsons/Marge"); // create item
+/// item->replace(mi); // replace it with our own
+/// \endcode
+///
+/// \param[in] render Whether we should render content (1), or just tally
+/// the geometry (0). Fl_Tree may want only to find the widest
+/// item in the tree for scrollbar calculations.
+///
+/// \returns the right-most X coordinate, or 'xmax' of content we drew,
+/// i.e. the "scrollable" content.
+/// The tree uses the largest xmax to determine the maximum
+/// width of the tree's content (needed for e.g. computing the
+/// horizontal scrollbar's size).
+/// \version 1.3.3 ABI feature
+///
+int Fl_Tree_Item::draw_item_content(int render) {
+ Fl_Color fg = drawfgcolor();
+ Fl_Color bg = drawbgcolor();
+ const Fl_Tree_Prefs &prefs = tree()->prefs();
+ int xmax = label_x();
+ // Background for this item, only if different from tree's bg
+ if ( render && (bg != tree()->color() || is_selected()) ) {
+ if ( is_selected() ) { // Selected? Use selectbox() style
+ fl_draw_box(prefs.selectbox(),
+ label_x(), label_y(), label_w(), label_h(), bg);
+ } else { // Not Selected? use plain filled rectangle
+ fl_color(bg);
+ fl_rectf(label_x(), label_y(), label_w(), label_h());
+ }
+ if ( widget() ) widget()->damage(FL_DAMAGE_ALL); // if there's a child widget, we just damaged it
+ }
+ // Draw label
+ if ( _label &&
+ ( !widget() ||
+ (prefs.item_draw_mode() & FL_TREE_ITEM_DRAW_LABEL_AND_WIDGET) ) ) {
+ if ( render ) {
+ fl_color(fg);
+ fl_font(_labelfont, _labelsize);
+ }
+ int lx = label_x()+(_label ? prefs.labelmarginleft() : 0);
+ int ly = label_y()+(label_h()/2)+(_labelsize/2)-fl_descent()/2;
+ int lw=0, lh=0;
+ fl_measure(_label, lw, lh); // get box around text (including white space)
+ if ( render ) fl_draw(_label, lx, ly);
+ xmax = lx + lw; // update max width of drawn item
+ }
+ return xmax;
+}
+
+/// Draw this item and its children.
+///
+/// \param[in] X Horizontal position for item being drawn
+/// \param[in,out] Y Vertical position for item being drawn,
+/// returns new position for next item
+/// \param[in] W Recommended width for item
+/// \param[in] itemfocus The tree's current focus item (if any)
+/// \param[in,out] tree_item_xmax The tree's running xmax (right-most edge so far).
+/// Mainly used by parent tree when render==0 to
+/// calculate tree's max width.
+/// \param[in] lastchild Is this item the last child in a subtree?
+/// \param[in] render Whether or not to render the item:
+/// 0: no rendering, just calculate size w/out drawing.
+/// 1: render item as well as size calc
+///
+/// \version 1.3.3 ABI feature: modified parameters
+///
+void Fl_Tree_Item::draw(int X, int &Y, int W, Fl_Tree_Item *itemfocus,
+ int &tree_item_xmax, int lastchild, int render) {
+ Fl_Tree_Prefs &prefs = _tree->_prefs;
+ if ( !is_visible() ) return;
+ int tree_top = tree()->_tiy;
+ int tree_bot = tree_top + tree()->_tih;
+ int H = calc_item_height(prefs); // height of item
+ int H2 = H + prefs.linespacing(); // height of item with line spacing
+
+ // Update the xywh of this item
+ _xywh[0] = X;
+ _xywh[1] = Y;
+ _xywh[2] = W;
+ _xywh[3] = H;
+
+ // Determine collapse icon's xywh
+ // Note: calculate collapse icon's xywh for possible mouse click detection.
+ // We don't care about items clipped off the viewport; they won't get mouse events.
+ //
+ int item_y_center = Y+(H/2);
+ _collapse_xywh[2] = prefs.openicon()->w();
+ int &icon_w = _collapse_xywh[2];
+ _collapse_xywh[0] = X + (icon_w + prefs.connectorwidth())/2 - 3;
+ int &icon_x = _collapse_xywh[0];
+ _collapse_xywh[1] = item_y_center - (prefs.openicon()->h()/2);
+ int &icon_y = _collapse_xywh[1];
+ _collapse_xywh[3] = prefs.openicon()->h();
+
+ // Horizontal connector values
+ // Must calculate these even if(clipped) because 'draw children' code (below)
+ // needs hconn_x_center value. (Otherwise, these calculations could be 'clipped')
+ //
+ int hconn_x = X+icon_w/2-1;
+ int hconn_x2 = hconn_x + prefs.connectorwidth();
+ int hconn_x_center = X + icon_w + ((hconn_x2 - (X + icon_w)) / 2);
+ int cw1 = icon_w+prefs.connectorwidth()/2, cw2 = prefs.connectorwidth();
+ int conn_w = cw1>cw2 ? cw1 : cw2;
+
+ // Usericon position
+ int uicon_x = X+(icon_w/2-1+conn_w) + ( (usericon() || prefs.usericon())
+ ? prefs.usericonmarginleft() : 0);
+ int uicon_w = usericon() ? usericon()->w()
+ : prefs.usericon() ? prefs.usericon()->w() : 0;
+
+ // Label xywh
+ _label_xywh[0] = uicon_x + uicon_w + prefs.labelmarginleft();
+ _label_xywh[1] = Y;
+ _label_xywh[2] = tree()->_tix + tree()->_tiw - _label_xywh[0];
+ _label_xywh[3] = H;
+
+ // Begin calc of this item's max width..
+ // It might not even be visible, so start at zero.
+ //
+ int xmax = 0;
+
+ // Recalc widget position
+ // Do this whether clipped or not, so that when scrolled,
+ // the widgets move to appropriate 'offscreen' positions
+ // (so that they don't get mouse events, etc)
+ //
+ if ( widget() ) {
+ int wx = uicon_x + uicon_w + (_label ? prefs.labelmarginleft() : 0);
+ int wy = label_y();
+ int ww = widget()->w(); // use widget's width
+ int wh = (prefs.item_draw_mode() & FL_TREE_ITEM_HEIGHT_FROM_WIDGET)
+ ? widget()->h() : H;
+ if ( _label &&
+ (prefs.item_draw_mode() & FL_TREE_ITEM_DRAW_LABEL_AND_WIDGET) ) {
+ fl_font(_labelfont, _labelsize); // fldescent() needs this
+ int lw=0, lh=0;
+ fl_measure(_label,lw,lh); // get box around text (including white space)
+ wx += (lw + prefs.widgetmarginleft());
+ }
+ if ( widget()->x() != wx || widget()->y() != wy ||
+ widget()->w() != ww || widget()->h() != wh ) {
+ widget()->resize(wx,wy,ww,wh); // we'll handle redraw below
+ }
+ }
+ char clipped = ((Y+H) < tree_top) || (Y>tree_bot) ? 1 : 0;
+ if (!render) clipped = 0; // NOT rendering? Then don't clip, so we calc unclipped items
+ char drawthis = ( is_root() && prefs.showroot() == 0 ) ? 0 : 1;
+ if ( !clipped ) {
+ Fl_Color fg = drawfgcolor();
+ Fl_Color bg = drawbgcolor();
+ // See if we should draw this item
+ // If this item is root, and showroot() is disabled, don't draw.
+ // 'clipped' is an optimization to prevent drawing anything offscreen.
+ //
+ if ( drawthis ) { // draw this item at all?
+ if ( (tree()->damage() & ~FL_DAMAGE_CHILD) || !render ) { // non-child damage?
+ // Draw connectors
+ if ( render && prefs.connectorstyle() != FL_TREE_CONNECTOR_NONE ) {
+ // Horiz connector between center of icon and text
+ // if this is root, the connector should not dangle in thin air on the left
+ if (is_root()) draw_horizontal_connector(hconn_x_center, hconn_x2, item_y_center, prefs);
+ else draw_horizontal_connector(hconn_x, hconn_x2, item_y_center, prefs);
+ // Small vertical line down to children
+ if ( has_children() && is_open() )
+ draw_vertical_connector(hconn_x_center, item_y_center, Y+H2, prefs);
+ // Connectors for last child
+ if ( !is_root() ) {
+ if ( lastchild ) draw_vertical_connector(hconn_x, Y, item_y_center, prefs);
+ else draw_vertical_connector(hconn_x, Y, Y+H2, prefs);
+ }
+ }
+ // Draw collapse icon
+ if ( render && has_children() && prefs.showcollapse() ) {
+ // Draw icon image
+ if ( is_open() ) {
+ prefs.closeicon()->draw(icon_x,icon_y);
+ } else {
+ prefs.openicon()->draw(icon_x,icon_y);
+ }
+ }
+ // Draw user icon (if any)
+ if ( render && usericon() ) {
+ // Item has user icon? Use it
+ int uicon_y = item_y_center - (usericon()->h() >> 1);
+ usericon()->draw(uicon_x,uicon_y);
+ } else if ( render && prefs.usericon() ) {
+ // Prefs has user icon? Use it
+ int uicon_y = item_y_center - (prefs.usericon()->h() >> 1);
+ prefs.usericon()->draw(uicon_x,uicon_y);
+ }
+ // Draw item's content
+ xmax = draw_item_content(render);
+ } // end non-child damage
+ // Draw child FLTK widget?
+ if ( widget() ) {
+ if (render)
+ tree()->draw_child(*widget()); // let group handle drawing child
+ if ( widget()->label() && render )
+ tree()->draw_outside_label(*widget());// label too
+ xmax = widget()->x() + widget()->w(); // update max width of widget
+ }
+ // Draw focus box around item's bg last
+ if ( render &&
+ this == itemfocus &&
+ Fl::visible_focus() &&
+ Fl::focus() == tree() &&
+ prefs.selectmode() != FL_TREE_SELECT_NONE ) {
+ draw_item_focus(FL_NO_BOX,fg,bg,label_x()+1,label_y()+1,label_w()-1,label_h()-1);
+ }
+ } // end drawthis
+ } // end clipped
+ if ( drawthis ) Y += H2; // adjust Y (even if clipped)
+ // Manage tree_item_xmax
+ if ( xmax > tree_item_xmax )
+ tree_item_xmax = xmax;
+ // Draw child items (if any)
+ if ( has_children() && is_open() ) {
+ int child_x = drawthis ? (hconn_x_center - (icon_w/2) + 1) // offset children to right,
+ : X; // unless didn't drawthis
+ int child_w = W - (child_x-X);
+ int child_y_start = Y;
+ for ( int t=0; t<children(); t++ ) {
+ int lastchild = ((t+1)==children()) ? 1 : 0;
+ _children[t]->draw(child_x, Y, child_w, itemfocus, tree_item_xmax, lastchild, render);
+ }
+ if ( has_children() && is_open() ) {
+ Y += prefs.openchild_marginbottom(); // offset below open child tree
+ }
+ if ( ! lastchild ) {
+ // Special 'clipped' calculation. (intentional variable shadowing)
+ int clipped = ((child_y_start < tree_top) && (Y < tree_top)) ||
+ ((child_y_start > tree_bot) && (Y > tree_bot));
+ if (render && !clipped )
+ draw_vertical_connector(hconn_x, child_y_start, Y, prefs);
+ }
+ }
+}
+
+#else
+
/// Draw this item and its children.
+///
+/// \param[in] X Horizontal position for item being drawn
+/// \param[in,out] Y Vertical position for item being drawn,
+/// returns new position for next item
+/// \param[in] W Recommended width of item
+/// \param[in] tree The parent tree
+/// \param[in] itemfocus The tree's current focus item (if any)
+/// \param[in] prefs The tree's preferences
+/// \param[in] lastchild Is this item the last child in a subtree?
+///
+/// \version 1.3.0 release, removed 1.3.3 ABI
+///
void Fl_Tree_Item::draw(int X, int &Y, int W, Fl_Widget *tree,
Fl_Tree_Item *itemfocus,
const Fl_Tree_Prefs &prefs, int lastchild) {
@@ -611,9 +1268,12 @@ void Fl_Tree_Item::draw(int X, int &Y, int W, Fl_Widget *tree,
// We don't care about items clipped off the viewport; they won't get mouse events.
//
int item_y_center = Y+(H/2);
- int &icon_w = _collapse_xywh[2] = prefs.openicon()->w();
- int &icon_x = _collapse_xywh[0] = X + (icon_w + prefs.connectorwidth())/2 - 3;
- int &icon_y = _collapse_xywh[1] = item_y_center - (prefs.openicon()->h()/2);
+ _collapse_xywh[2] = prefs.openicon()->w();
+ int &icon_w = _collapse_xywh[2];
+ _collapse_xywh[0] = X + (icon_w + prefs.connectorwidth())/2 - 3;
+ int &icon_x = _collapse_xywh[0];
+ _collapse_xywh[1] = item_y_center - (prefs.openicon()->h()/2);
+ int &icon_y = _collapse_xywh[1];
_collapse_xywh[3] = prefs.openicon()->h();
// Horizontal connector values
@@ -676,13 +1336,14 @@ void Fl_Tree_Item::draw(int X, int &Y, int W, Fl_Widget *tree,
char clipped = ((Y+H) < tree_top) || (Y>tree_bot) ? 1 : 0;
char drawthis = ( is_root() && prefs.showroot() == 0 ) ? 0 : 1;
if ( !clipped ) {
+ const Fl_Color unspecified = 0xffffffff;
Fl_Color fg = is_selected() ? fl_contrast(_labelfgcolor, tree->selection_color())
- : is_active() ? _labelfgcolor
+ : is_active() ? _labelfgcolor
: fl_inactive(_labelfgcolor);
Fl_Color bg = is_selected() ? is_active() ? tree->selection_color()
: fl_inactive(tree->selection_color())
- : _labelbgcolor == 0xffffffff ? tree->color() // transparent bg?
- : _labelbgcolor;
+ : _labelbgcolor == unspecified ? tree->color()
+ : _labelbgcolor;
// See if we should draw this item
// If this item is root, and showroot() is disabled, don't draw.
// 'clipped' is an optimization to prevent drawing anything offscreen.
@@ -713,8 +1374,7 @@ void Fl_Tree_Item::draw(int X, int &Y, int W, Fl_Widget *tree,
prefs.openicon()->draw(icon_x,icon_y);
}
}
- // Background for this item
- // Draw bg only if different from tree's bg
+ // Draw background for the item.. only if different from tree's bg color
if ( bg != tree->color() || is_selected() ) {
if ( is_selected() ) { // Selected? Use selectbox() style
fl_draw_box(prefs.selectbox(),bg_x,bg_y,bg_w,bg_h,bg);
@@ -736,13 +1396,13 @@ void Fl_Tree_Item::draw(int X, int &Y, int W, Fl_Widget *tree,
}
// Draw label
#if FLTK_ABI_VERSION >= 10301
- if ( _label &&
+ if ( _label &&
( !widget() ||
(prefs.item_draw_mode() & FL_TREE_ITEM_DRAW_LABEL_AND_WIDGET) ) )
#else /*FLTK_ABI_VERSION*/
- if ( _label && !widget() ) // back compat: don't draw label if widget() present
+ if ( _label && !widget() ) // back compat: don't draw label if widget() present
#endif /*FLTK_ABI_VERSION*/
- {
+ {
fl_color(fg);
fl_font(_labelfont, _labelsize);
int label_y = Y+(H/2)+(_labelsize/2)-fl_descent()/2;
@@ -760,7 +1420,7 @@ void Fl_Tree_Item::draw(int X, int &Y, int W, Fl_Widget *tree,
Fl::visible_focus() &&
Fl::focus() == tree &&
prefs.selectmode() != FL_TREE_SELECT_NONE ) {
- draw_item_focus(FL_NO_BOX,bg,bg_x+1,bg_y+1,bg_w-1,bg_h-1);
+ draw_item_focus(FL_NO_BOX,fg,bg,bg_x+1,bg_y+1,bg_w-1,bg_h-1);
}
} // end drawthis
} // end clipped
@@ -786,8 +1446,9 @@ void Fl_Tree_Item::draw(int X, int &Y, int W, Fl_Widget *tree,
}
}
}
+#endif
-/// Was the event on the 'collapse' button?
+/// Was the event on the 'collapse' button of this item?
///
int Fl_Tree_Item::event_on_collapse_icon(const Fl_Tree_Prefs &prefs) const {
if ( is_visible() && is_active() && has_children() && prefs.showcollapse() ) {
@@ -797,7 +1458,7 @@ int Fl_Tree_Item::event_on_collapse_icon(const Fl_Tree_Prefs &prefs) const {
}
}
-/// Was event on the label()?
+/// Was event on the label() of this item?
///
int Fl_Tree_Item::event_on_label(const Fl_Tree_Prefs &prefs) const {
if ( is_visible() && is_active() ) {
@@ -836,6 +1497,7 @@ void Fl_Tree_Item::open() {
for ( int t=0; t<_children.total(); t++ ) {
_children[t]->show_widgets();
}
+ recalc_tree(); // may change tree geometry
}
/// Close this item and all its children.
@@ -845,12 +1507,14 @@ void Fl_Tree_Item::close() {
for ( int t=0; t<_children.total(); t++ ) {
_children[t]->hide_widgets();
}
+ recalc_tree(); // may change tree geometry
}
/// Returns how many levels deep this item is in the hierarchy.
///
/// For instance; root has a depth of zero, and its immediate children
-/// would have a depth of 1, and so on.
+/// would have a depth of 1, and so on. Use e.g. for determining the
+/// horizontal indent of this item during drawing.
///
int Fl_Tree_Item::depth() const {
int count = 0;
@@ -898,7 +1562,8 @@ Fl_Tree_Item *Fl_Tree_Item::next() {
/// This method can be used to walk the tree backwards.
/// For an example of how to use this method, see Fl_Tree::last().
///
-/// \returns the previous item in the tree, or 0 if there's no item above this one (hit the root).
+/// \returns the previous item in the tree,
+/// or 0 if there's no item above this one (hit the root).
///
Fl_Tree_Item *Fl_Tree_Item::prev() {
#if FLTK_ABI_VERSION >= 10301
@@ -949,7 +1614,7 @@ Fl_Tree_Item *Fl_Tree_Item::prev() {
/// Return this item's next sibling.
///
/// Moves to the next item below us at the same level (sibling).
-/// Use this to move down the tree without moving deeper into the tree,
+/// Use this to move down the tree without changing depth().
/// effectively skipping over this item's children/descendents.
///
/// \returns item's next sibling, or 0 if none.
@@ -972,7 +1637,7 @@ Fl_Tree_Item *Fl_Tree_Item::next_sibling() {
/// Return this item's previous sibling.
///
/// Moves to the previous item above us at the same level (sibling).
-/// Use this to move up the tree without moving deeper into the tree.
+/// Use this to move up the tree without changing depth().
///
/// \returns This item's previous sibling, or 0 if none.
///
@@ -990,13 +1655,21 @@ Fl_Tree_Item *Fl_Tree_Item::prev_sibling() {
#endif /*FLTK_ABI_VERSION*/
}
-/// Update our _prev_sibling and _next_sibling pointers to point to neighbors,
+/// Update our _prev_sibling and _next_sibling pointers to point to neighbors
/// given \p index as being our current position in the parent's item array.
-/// Call this whenever items in the array are added/removed/moved/swapped.
+/// Call this whenever items in the array are added/removed/moved/swapped/etc.
+/// \param[in] index Our index# in the parent.<br>
+/// Special case if index=-1: become an orphan; null out all parent/sibling associations.
///
void Fl_Tree_Item::update_prev_next(int index) {
#if FLTK_ABI_VERSION >= 10301
// NEW
+ if ( index == -1 ) { // special case: become an orphan
+ _parent = 0;
+ _prev_sibling = 0;
+ _next_sibling = 0;
+ return;
+ }
int pchildren = parent() ? parent()->children() : 0;
int index_prev = index-1;
int index_next = index+1;
@@ -1015,14 +1688,17 @@ void Fl_Tree_Item::update_prev_next(int index) {
#endif /*FLTK_ABI_VERSION*/
}
-/// Return the next visible item. (If this item has children and is closed, children are skipped)
+/// Return the next open(), visible() item.
+/// (If this item has children and is closed, children are skipped)
///
/// This method can be used to walk the tree forward, skipping items
-/// that are not currently visible to the user.
+/// that are not currently open/visible to the user.
///
-/// \returns the next visible item below us, or 0 if there's no more items.
+/// \returns the next open() visible() item below us,
+/// or 0 if there's no more items.
+/// \version 1.3.3
///
-Fl_Tree_Item *Fl_Tree_Item::next_displayed(Fl_Tree_Prefs &prefs) {
+Fl_Tree_Item *Fl_Tree_Item::next_visible(Fl_Tree_Prefs &prefs) {
Fl_Tree_Item *item = this;
while ( 1 ) {
item = item->next();
@@ -1032,14 +1708,22 @@ Fl_Tree_Item *Fl_Tree_Item::next_displayed(Fl_Tree_Prefs &prefs) {
}
}
-/// Return the previous visible item. (If this item above us has children and is closed, its children are skipped)
+/// Same as next_visible().
+/// \deprecated in 1.3.3 for confusing name, use next_visible() instead
+Fl_Tree_Item *Fl_Tree_Item::next_displayed(Fl_Tree_Prefs &prefs) {
+ return next_visible(prefs);
+}
+
+/// Return the previous open(), visible() item.
+/// (If this item above us has children and is closed, its children are skipped)
///
/// This method can be used to walk the tree backward,
-/// skipping items that are not currently visible to the user.
+/// skipping items that are not currently open/visible to the user.
///
-/// \returns the previous visible item above us, or 0 if there's no more items.
+/// \returns the previous open() visible() item above us,
+/// or 0 if there's no more items.
///
-Fl_Tree_Item *Fl_Tree_Item::prev_displayed(Fl_Tree_Prefs &prefs) {
+Fl_Tree_Item *Fl_Tree_Item::prev_visible(Fl_Tree_Prefs &prefs) {
Fl_Tree_Item *c = this;
while ( c ) {
c = c->prev(); // previous item
@@ -1059,11 +1743,17 @@ Fl_Tree_Item *Fl_Tree_Item::prev_displayed(Fl_Tree_Prefs &prefs) {
return(0); // hit end: no more items
}
-/// Returns if item and all its parents are visible.
-/// Also takes into consideration if any parent is close()ed.
+/// Same as prev_visible().
+/// \deprecated in 1.3.3 for confusing name, use prev_visible()
+///
+Fl_Tree_Item *Fl_Tree_Item::prev_displayed(Fl_Tree_Prefs &prefs) {
+ return prev_visible(prefs);
+}
+
+/// See if item and all its parents are open() and visible().
/// \returns
-/// 1 -- item and its parents are visible/open()
-/// 0 -- item (or parents) invisible or close()ed.
+/// 1 -- item and its parents are open() and visible()
+/// 0 -- item (or one of its parents) are invisible or close()ed.
///
int Fl_Tree_Item::visible_r() const {
if ( !visible() ) return(0);
@@ -1072,6 +1762,17 @@ int Fl_Tree_Item::visible_r() const {
return(1);
}
+/// Call this when our geometry is changed. (Font size, label contents, etc)
+/// Schedules tree to recalculate itself, as changes to us may affect tree
+/// widget's scrollbar visibility and tab sizes.
+/// \version 1.3.3 ABI
+///
+void Fl_Tree_Item::recalc_tree() {
+#if FLTK_ABI_VERSION >= 10303
+ _tree->recalc_tree();
+#endif
+}
+
//
-// End of "$Id: Fl_Tree_Item.cxx 9706 2012-11-06 20:46:14Z matt $".
+// End of "$Id: Fl_Tree_Item.cxx 10272 2014-09-05 02:59:00Z greg.ercolano $".
//
diff --git a/src/Fl_Tree_Item_Array.cxx b/src/Fl_Tree_Item_Array.cxx
index aea7e09..63d05af 100644
--- a/src/Fl_Tree_Item_Array.cxx
+++ b/src/Fl_Tree_Item_Array.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: Fl_Tree_Item_Array.cxx 9706 2012-11-06 20:46:14Z matt $"
+// "$Id: Fl_Tree_Item_Array.cxx 10272 2014-09-05 02:59:00Z greg.ercolano $"
//
#include <stdio.h>
@@ -36,6 +36,9 @@ Fl_Tree_Item_Array::Fl_Tree_Item_Array(int new_chunksize) {
_items = 0;
_total = 0;
_size = 0;
+#if FLTK_ABI_VERSION >= 10303
+ _flags = 0;
+#endif
_chunksize = new_chunksize;
}
@@ -50,10 +53,24 @@ Fl_Tree_Item_Array::Fl_Tree_Item_Array(const Fl_Tree_Item_Array* o) {
_total = 0;
_size = o->_size;
_chunksize = o->_chunksize;
+#if FLTK_ABI_VERSION >= 10303
+ _flags = o->_flags;
+#endif
for ( int t=0; t<o->_total; t++ ) {
- _items[t] = new Fl_Tree_Item(o->_items[t]);
+#if FLTK_ABI_VERSION >= 10303
+ if ( _flags & MANAGE_ITEM ) {
+ _items[t] = new Fl_Tree_Item(o->_items[t]); // make new copy of item
+ ++_total;
+ _items[t]->update_prev_next(t); // update uses _total's current value
+ } else {
+ _items[t] = o->_items[t]; // copy ptr only
+ ++_total;
+ }
+#else
+ _items[t] = new Fl_Tree_Item(o->_items[t]); // make new copy of item
++_total;
- _items[t]->update_prev_next(t); // update uses _total's current value
+ _items[t]->update_prev_next(t); // update uses _total's current value
+#endif
}
}
@@ -65,8 +82,13 @@ Fl_Tree_Item_Array::Fl_Tree_Item_Array(const Fl_Tree_Item_Array* o) {
void Fl_Tree_Item_Array::clear() {
if ( _items ) {
for ( int t=0; t<_total; t++ ) {
- delete _items[t];
- _items[t] = 0;
+#if FLTK_ABI_VERSION >= 10303
+ if ( _flags & MANAGE_ITEM )
+#endif
+ {
+ delete _items[t];
+ _items[t] = 0;
+ }
}
free((void*)_items); _items = 0;
}
@@ -110,7 +132,12 @@ void Fl_Tree_Item_Array::insert(int pos, Fl_Tree_Item *new_item) {
}
_items[pos] = new_item;
_total++;
- _items[pos]->update_prev_next(pos); // adjust item's prev/next and its neighbors
+#if FLTK_ABI_VERSION >= 10303
+ if ( _flags & MANAGE_ITEM )
+#endif
+ {
+ _items[pos]->update_prev_next(pos); // adjust item's prev/next and its neighbors
+ }
}
/// Add an item* to the end of the array.
@@ -123,24 +150,55 @@ void Fl_Tree_Item_Array::add(Fl_Tree_Item *val) {
insert(_total, val);
}
+/// Replace the item at \p index with \p newitem.
+///
+/// Old item at index position will be destroyed,
+/// and the new item will take it's place, and stitched into the linked list.
+///
+void Fl_Tree_Item_Array::replace(int index, Fl_Tree_Item *newitem) {
+ if ( _items[index] ) { // delete if non-zero
+#if FLTK_ABI_VERSION >= 10303
+ if ( _flags & MANAGE_ITEM )
+#endif
+ // Destroy old item
+ delete _items[index];
+ }
+ _items[index] = newitem; // install new item
+#if FLTK_ABI_VERSION >= 10303
+ if ( _flags & MANAGE_ITEM )
+#endif
+ {
+ // Restitch into linked list
+ _items[index]->update_prev_next(index);
+ }
+}
+
/// Remove the item at \param[in] index from the array.
///
/// The item will be delete'd (if non-NULL), so its destructor will be called.
///
void Fl_Tree_Item_Array::remove(int index) {
if ( _items[index] ) { // delete if non-zero
- delete _items[index];
+#if FLTK_ABI_VERSION >= 10303
+ if ( _flags & MANAGE_ITEM )
+#endif
+ delete _items[index];
}
_items[index] = 0;
_total--;
for ( int i=index; i<_total; i++ ) { // reshuffle the array
_items[i] = _items[i+1];
}
- if ( index < _total ) { // removed item not last?
- _items[index]->update_prev_next(index); // update next item's prev/next and neighbors
- } else if ( ((index-1) >= 0) && // removed item IS last?
- ((index-1) < _total)) {
- _items[index-1]->update_prev_next(index-1); // update prev item's prev/next and neighbors
+#if FLTK_ABI_VERSION >= 10303
+ if ( _flags & MANAGE_ITEM )
+#endif
+ {
+ if ( index < _total ) { // removed item not last?
+ _items[index]->update_prev_next(index); // update next item's prev/next and neighbors
+ } else if ( ((index-1) >= 0) && // removed item IS last?
+ ((index-1) < _total)) {
+ _items[index-1]->update_prev_next(index-1);// update prev item's prev/next and neighbors
+ }
}
}
@@ -164,12 +222,88 @@ void Fl_Tree_Item_Array::swap(int ax, int bx) {
Fl_Tree_Item *asave = _items[ax];
_items[ax] = _items[bx];
_items[bx] = asave;
- // Adjust prev/next ptrs
- _items[ax]->update_prev_next(ax);
- _items[bx]->update_prev_next(bx);
+#if FLTK_ABI_VERSION >= 10303
+ if ( _flags & MANAGE_ITEM )
+#endif
+ {
+ // Adjust prev/next ptrs
+ _items[ax]->update_prev_next(ax);
+ _items[bx]->update_prev_next(bx);
+ }
}
#endif /* FLTK_ABI_VERSION */
+/// Move item at 'from' to new position 'to' in the array.
+/// Due to how the moving an item shuffles the array around,
+/// a positional 'move' implies things that may not be obvious:
+/// - When 'from' moved lower in tree, appears BELOW item that was at 'to'.
+/// - When 'from' moved higher in tree, appears ABOVE item that was at 'to'.
+///
+/// \returns 0 on success, -1 on range error (e.g. if \p 'to' or \p 'from' out of range)
+///
+int Fl_Tree_Item_Array::move(int to, int from) {
+ if ( from == to ) return 0; // nop
+ if ( to<0 || to>=_total || from<0 || from>=_total ) return -1;
+ Fl_Tree_Item *item = _items[from];
+ // Remove item..
+ if ( from < to )
+ for ( int t=from; t<to && t<(_total+1); t++ )
+ _items[t] = _items[t+1];
+ else
+ for ( int t=from; t>to && t>0; t-- )
+ _items[t] = _items[t-1];
+ // Move to new position
+ _items[to] = item;
+ // Update all children
+ for ( int r=0; r<_total; r++ ) // XXX: excessive to do all children,
+ _items[r]->update_prev_next(r); // XXX: but avoids weird boundary issues
+ return 0;
+}
+
+/// Deparent item at \p 'pos' from our list of children.
+/// Similar to a remove() without the destruction of the item.
+/// This creates an orphaned item (still allocated, has no parent)
+/// which soon after is typically reparented elsewhere.
+///
+/// \returns 0 on success, -1 on error (e.g. if \p 'pos' out of range)
+///
+int Fl_Tree_Item_Array::deparent(int pos) {
+ if ( pos>=_total || pos<0 ) return -1;
+ // Save item being deparented, and its two nearest siblings
+ Fl_Tree_Item *item = _items[pos];
+ Fl_Tree_Item *prev = item->prev_sibling();
+ Fl_Tree_Item *next = item->next_sibling();
+ // Remove from parent's list of children
+ _total -= 1;
+ for ( int t=pos; t<_total; t++ )
+ _items[t] = _items[t+1]; // delete, no destroy
+ // Now an orphan: remove association with old parent and siblings
+ item->update_prev_next(-1); // become an orphan
+ // Adjust bereaved siblings
+ if ( prev ) prev->update_prev_next(pos-1);
+ if ( next ) next->update_prev_next(pos);
+ return 0;
+}
+
+/// Reparent specified item as a child of ourself.
+/// Typically 'newchild' was recently orphaned with deparent().
+///
+/// \returns 0 on success, -1 on error (e.g. if \p 'pos' out of range)
+///
+int Fl_Tree_Item_Array::reparent(Fl_Tree_Item *item, Fl_Tree_Item* newparent, int pos) {
+ if ( pos<0 || pos>_total ) return -1;
+ // Add item to new parent
+ enlarge(1);
+ _total += 1;
+ for ( int t=_total-1; t>pos; --t ) // shuffle array to make room for new entry
+ _items[t] = _items[t-1];
+ _items[pos] = item; // insert new entry
+ // Attach to new parent and siblings
+ _items[pos]->parent(newparent); // reparent (update_prev_next() needs this)
+ _items[pos]->update_prev_next(pos); // find new siblings
+ return 0;
+}
+
//
-// End of "$Id: Fl_Tree_Item_Array.cxx 9706 2012-11-06 20:46:14Z matt $".
+// End of "$Id: Fl_Tree_Item_Array.cxx 10272 2014-09-05 02:59:00Z greg.ercolano $".
//
diff --git a/src/Fl_Tree_Prefs.cxx b/src/Fl_Tree_Prefs.cxx
index 204340e..322caee 100644
--- a/src/Fl_Tree_Prefs.cxx
+++ b/src/Fl_Tree_Prefs.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: Fl_Tree_Prefs.cxx 9706 2012-11-06 20:46:14Z matt $"
+// "$Id: Fl_Tree_Prefs.cxx 10233 2014-08-21 12:16:40Z cand $"
//
#include <FL/Fl.H>
@@ -28,7 +28,7 @@
// INTERNAL: BUILT IN OPEN/STOW XPMS
// These can be replaced via prefs.openicon()/closeicon()
//
-static const char *L_open_xpm[] = {
+static const char * const L_open_xpm[] = {
#ifdef __APPLE__
"11 11 2 1",
". c None",
@@ -64,7 +64,7 @@ static const char *L_open_xpm[] = {
};
static Fl_Pixmap L_openpixmap(L_open_xpm);
-static const char *L_close_xpm[] = {
+static const char * const L_close_xpm[] = {
#ifdef __APPLE__
"11 11 2 1",
". c None",
@@ -156,6 +156,10 @@ Fl_Tree_Prefs::Fl_Tree_Prefs() {
_itemreselectmode = FL_TREE_SELECTABLE_ONCE;
_itemdrawmode = FL_TREE_ITEM_DRAW_DEFAULT;
#endif
+#if FLTK_ABI_VERSION >= 10303
+ _itemdrawcallback = 0;
+ _itemdrawuserdata = 0;
+#endif
// Let fltk's current 'scheme' affect defaults
if ( Fl::scheme() ) {
if ( strcmp(Fl::scheme(), "gtk+") == 0 ) {
@@ -167,5 +171,5 @@ Fl_Tree_Prefs::Fl_Tree_Prefs() {
}
//
-// End of "$Id: Fl_Tree_Prefs.cxx 9706 2012-11-06 20:46:14Z matt $".
+// End of "$Id: Fl_Tree_Prefs.cxx 10233 2014-08-21 12:16:40Z cand $".
//
diff --git a/src/Fl_Window.cxx b/src/Fl_Window.cxx
index d7e4794..a0dca45 100644
--- a/src/Fl_Window.cxx
+++ b/src/Fl_Window.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: Fl_Window.cxx 9706 2012-11-06 20:46:14Z matt $"
+// "$Id: Fl_Window.cxx 10405 2014-10-29 15:53:52Z manolo $"
//
// Window widget class for the Fast Light Tool Kit (FLTK).
//
@@ -23,6 +23,7 @@
#include <config.h>
#include <FL/Fl.H>
#include <FL/x.H>
+#include <FL/Fl_RGB_Image.H>
#include <FL/Fl_Window.H>
#include <stdlib.h>
#include "flstring.h"
@@ -45,11 +46,13 @@ void Fl_Window::_Fl_Window() {
}
i = 0;
xclass_ = 0;
- icon_ = 0;
+ icon_ = new icon_data;
+ memset(icon_, 0, sizeof(*icon_));
iconlabel_ = 0;
resizable(0);
size_range_set = 0;
minw = maxw = minh = maxh = 0;
+ shape_data_ = NULL;
#if FLTK_ABI_VERSION >= 10301
no_fullscreen_x = 0;
no_fullscreen_y = 0;
@@ -62,8 +65,6 @@ void Fl_Window::_Fl_Window() {
Fl_Window::Fl_Window(int X,int Y,int W, int H, const char *l)
: Fl_Group(X, Y, W, H, l) {
cursor_default = FL_CURSOR_DEFAULT;
- cursor_fg = FL_BLACK;
- cursor_bg = FL_WHITE;
_Fl_Window();
set_flag(FORCE_POSITION);
@@ -73,18 +74,72 @@ Fl_Window::Fl_Window(int W, int H, const char *l)
// fix common user error of a missing end() with current(0):
: 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();
clear_visible();
}
+Fl_Window::~Fl_Window() {
+ hide();
+ if (xclass_) {
+ free(xclass_);
+ }
+ free_icons();
+ delete icon_;
+ if (shape_data_) {
+ if (shape_data_->todelete_) delete shape_data_->todelete_;
+#if defined(__APPLE__)
+ if (shape_data_->mask) {
+ CGImageRelease(shape_data_->mask);
+ }
+#endif
+ delete shape_data_;
+ }
+}
+
+
+/** Returns a pointer to the nearest parent window up the widget hierarchy.
+ This will return sub-windows if there are any, or the parent window if there's no sub-windows.
+ If this widget IS the top-level window, NULL is returned.
+ \retval NULL if no window is associated with this widget.
+ \note for an Fl_Window widget, this returns its <I>parent</I> window
+ (if any), not <I>this</I> window.
+ \see top_window()
+*/
Fl_Window *Fl_Widget::window() const {
for (Fl_Widget *o = parent(); o; o = o->parent())
if (o->type() >= FL_WINDOW) return (Fl_Window*)o;
return 0;
}
+
+/** Returns a pointer to the top-level window for the widget.
+ In other words, the 'window manager window' that contains this widget.
+ This method differs from window() in that it won't return sub-windows (if there are any).
+ \returns the top-level window, or NULL if no top-level window is associated with this widget.
+ \see window()
+*/
+Fl_Window *Fl_Widget::top_window() const {
+ const Fl_Widget *w = this;
+ while (w->parent()) { w = w->parent(); } // walk up the widget hierarchy to top-level item
+ return const_cast<Fl_Widget*>(w)->as_window(); // return if window, or NULL if not
+}
+
+/**
+ Finds the x/y offset of the current widget relative to the top-level window.
+ \param[out] xoff,yoff Returns the x/y offset
+ \returns the top-level window (or NULL for a widget that's not in any window)
+*/
+Fl_Window* Fl_Widget::top_window_offset(int& xoff, int& yoff) const {
+ xoff = yoff = 0;
+ const Fl_Widget *w = this;
+ while (w && w->window()) {
+ xoff += w->x(); // accumulate offsets
+ yoff += w->y();
+ w = w->window(); // walk up window hierarchy
+ }
+ return const_cast<Fl_Widget*>(w)->as_window();
+}
+
/** Gets the x position of the window on the screen */
int Fl_Window::x_root() const {
Fl_Window *p = window();
@@ -98,50 +153,11 @@ int Fl_Window::y_root() const {
return y();
}
-void Fl_Window::draw() {
-
- // The following is similar to Fl_Group::draw(), but ...
- // - we draw the box with x=0 and y=0 instead of x() and y()
- // - we don't draw a label
-
- if (damage() & ~FL_DAMAGE_CHILD) { // draw the entire thing
- draw_box(box(),0,0,w(),h(),color()); // draw box with x/y = 0
- }
- draw_children();
-
-#ifdef __APPLE_QUARTZ__
- // on OS X, windows have no frame. Before OS X 10.7, to resize a window, we drag the lower right
- // corner. This code draws a little ribbed triangle for dragging.
- if (fl_mac_os_version < 100700 && fl_gc && !parent() && resizable() &&
- (!size_range_set || minh!=maxh || minw!=maxw)) {
- int dx = Fl::box_dw(box())-Fl::box_dx(box());
- int dy = Fl::box_dh(box())-Fl::box_dy(box());
- if (dx<=0) dx = 1;
- if (dy<=0) dy = 1;
- int x1 = w()-dx-1, x2 = x1, y1 = h()-dx-1, y2 = y1;
- Fl_Color c[4] = {
- color(),
- fl_color_average(color(), FL_WHITE, 0.7f),
- fl_color_average(color(), FL_BLACK, 0.6f),
- fl_color_average(color(), FL_BLACK, 0.8f),
- };
- int i;
- for (i=dx; i<12; i++) {
- fl_color(c[i&3]);
- fl_line(x1--, y1, x2, y2--);
- }
- }
-#endif
-
-# if defined(FLTK_USE_CAIRO)
- Fl::cairo_make_current(this); // checkout if an update is necessary
-# endif
-}
-
void Fl_Window::label(const char *name) {
label(name, iconlabel()); // platform dependent
}
+/** Sets the window titlebar label to a copy of a character string */
void Fl_Window::copy_label(const char *a) {
Fl_Widget::copy_label(a);
label(label(), iconlabel()); // platform dependent
@@ -268,17 +284,175 @@ const char *Fl_Window::xclass() const
}
}
-/** Gets the current icon window target dependent data. */
+/** Sets a single default window icon.
+
+ \param[in] icon default icon for all windows subsequently created
+
+ \see Fl_Window::default_icons(const Fl_RGB_Image *[], int)
+ \see Fl_Window::icon(const Fl_RGB_Image *)
+ \see Fl_Window::icons(const Fl_RGB_Image *[], int)
+ */
+void Fl_Window::default_icon(const Fl_RGB_Image *icon) {
+ default_icons(&icon, 1);
+}
+
+/** Sets the default window icons.
+
+ The default icons are used for all windows that don't have their
+ own icons set before show() is called. You can change the default
+ icons whenever you want, but this only affects windows that are
+ created (and shown) after this call.
+
+ The given images in \p icons are copied. You can use a local
+ variable or free the images immediately after this call.
+
+ \param[in] icons default icons for all windows subsequently created
+ \param[in] count number of images in \p icons. set to 0 to remove
+ the current default icons
+
+ \see Fl_Window::default_icon(const Fl_RGB_Image *)
+ \see Fl_Window::icon(const Fl_RGB_Image *)
+ \see Fl_Window::icons(const Fl_RGB_Image *[], int)
+ */
+void Fl_Window::default_icons(const Fl_RGB_Image *icons[], int count) {
+ Fl_X::set_default_icons(icons, count);
+}
+
+/** Sets a single window icon.
+
+ \param[in] icon icon for this window
+
+ \see Fl_Window::default_icon(const Fl_RGB_Image *)
+ \see Fl_Window::default_icons(const Fl_RGB_Image *[], int)
+ \see Fl_Window::icons(const Fl_RGB_Image *[], int)
+ */
+void Fl_Window::icon(const Fl_RGB_Image *icon) {
+ icons(&icon, 1);
+}
+
+/** Sets the window icons.
+
+ The given images in \p icons are copied. You can use a local
+ variable or free the images immediately after this call.
+
+ \param[in] icons icons for this window
+ \param[in] count number of images in \p icons. set to 0 to remove
+ the current icons
+
+ \see Fl_Window::default_icon(const Fl_RGB_Image *)
+ \see Fl_Window::default_icons(const Fl_RGB_Image *[], int)
+ \see Fl_Window::icon(const Fl_RGB_Image *)
+ */
+void Fl_Window::icons(const Fl_RGB_Image *icons[], int count) {
+ free_icons();
+
+ if (count > 0) {
+ icon_->icons = new Fl_RGB_Image*[count];
+ icon_->count = count;
+ // FIXME: Fl_RGB_Image lacks const modifiers on methods
+ for (int i = 0;i < count;i++)
+ icon_->icons[i] = (Fl_RGB_Image*)((Fl_RGB_Image*)icons[i])->copy();
+ }
+
+ if (i)
+ i->set_icons();
+}
+
+/** Gets the current icon window target dependent data.
+ \deprecated in 1.3.3
+ */
const void *Fl_Window::icon() const {
- return icon_;
+ return icon_->legacy_icon;
}
-/** Sets the current icon window target dependent data. */
+/** Sets the current icon window target dependent data.
+ \deprecated in 1.3.3
+ */
void Fl_Window::icon(const void * ic) {
- icon_ = ic;
+ free_icons();
+ icon_->legacy_icon = ic;
+}
+
+/** Deletes all icons previously attached to the window.
+ \see Fl_Window::icons(const Fl_RGB_Image *icons[], int count)
+ */
+void Fl_Window::free_icons() {
+ int i;
+
+ icon_->legacy_icon = 0L;
+
+ if (icon_->icons) {
+ for (i = 0;i < icon_->count;i++)
+ delete icon_->icons[i];
+ delete [] icon_->icons;
+ icon_->icons = 0L;
+ }
+
+ icon_->count = 0;
+
+#ifdef WIN32
+ if (icon_->big_icon)
+ DestroyIcon(icon_->big_icon);
+ if (icon_->small_icon)
+ DestroyIcon(icon_->small_icon);
+
+ icon_->big_icon = NULL;
+ icon_->small_icon = NULL;
+#endif
}
+/**
+ Waits for the window to be fully displayed after calling show().
+
+ Fl_Window::show() is not guaranteed to show and draw the window on
+ all platforms immediately. Instead this is done in the background;
+ particularly on X11 this will take a few messages (client server
+ roundtrips) to display the window.
+
+ Usually this small delay doesn't matter, but in some cases you may
+ want to have the window instantiated and displayed synchronously.
+
+ Currently (as of FLTK 1.3.3) this method only has an effect on X11.
+ On Windows and Mac OS X show() is always synchronous. If you want to
+ write portable code and need this synchronous show() feature, add
+ win->wait_for_expose() on all platforms, FLTK will just do the
+ right thing.
+
+ This method can be used for displaying splash screens before
+ calling Fl::run() or for having exact control over which window
+ has focus after calling show().
+
+ If the window is not shown(), this method does nothing.
+
+ \see virtual void Fl_Window::show()
+
+ Example code for displaying a window before calling Fl::run()
+
+ \code
+ Fl_Double_Window win = new Fl_Double_Window(...);
+
+ // do more window initialization here ...
+
+ win->show(); // show window
+ win->wait_for_expose(); // wait, until displayed
+ Fl::flush(); // make sure everything gets drawn
+
+ // do more initialization work that needs some time here ...
+
+ Fl::run(); // start FLTK event loop
+ \endcode
+
+ Note that the window will not be responsive until the event loop
+ is started with Fl::run().
+*/
+
+void Fl_Window::wait_for_expose() {
+ if (!shown()) return;
+ while (!i || i->wait_for_expose) {
+ Fl::wait();
+ }
+}
//
-// End of "$Id: Fl_Window.cxx 9706 2012-11-06 20:46:14Z matt $".
+// End of "$Id: Fl_Window.cxx 10405 2014-10-29 15:53:52Z manolo $".
//
diff --git a/src/Fl_Window_fullscreen.cxx b/src/Fl_Window_fullscreen.cxx
index a7044eb..2808f29 100644
--- a/src/Fl_Window_fullscreen.cxx
+++ b/src/Fl_Window_fullscreen.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: Fl_Window_fullscreen.cxx 9706 2012-11-06 20:46:14Z matt $"
+// "$Id: Fl_Window_fullscreen.cxx 10189 2014-06-11 09:10:53Z ossman $"
//
// Fullscreen window support for the Fast Light Tool Kit (FLTK).
//
@@ -36,6 +36,10 @@ int Fl_Window::no_fullscreen_x = 0;
int Fl_Window::no_fullscreen_y = 0;
int Fl_Window::no_fullscreen_w = 0;
int Fl_Window::no_fullscreen_h = 0;
+int Fl_Window::fullscreen_screen_top = -1;
+int Fl_Window::fullscreen_screen_bottom = -1;
+int Fl_Window::fullscreen_screen_left = -1;
+int Fl_Window::fullscreen_screen_right = -1;
#endif
void Fl_Window::border(int b) {
@@ -95,7 +99,24 @@ void Fl_Window::fullscreen_off() {
fullscreen_off(no_fullscreen_x, no_fullscreen_y, no_fullscreen_w, no_fullscreen_h);
}
+void Fl_Window::fullscreen_screens(int top, int bottom, int left, int right) {
+ if ((top < 0) || (bottom < 0) || (left < 0) || (right < 0)) {
+ fullscreen_screen_top = -1;
+ fullscreen_screen_bottom = -1;
+ fullscreen_screen_left = -1;
+ fullscreen_screen_right = -1;
+ } else {
+ fullscreen_screen_top = top;
+ fullscreen_screen_bottom = bottom;
+ fullscreen_screen_left = left;
+ fullscreen_screen_right = right;
+ }
+
+ if (shown() && fullscreen_active())
+ fullscreen_x();
+}
+
//
-// End of "$Id: Fl_Window_fullscreen.cxx 9706 2012-11-06 20:46:14Z matt $".
+// End of "$Id: Fl_Window_fullscreen.cxx 10189 2014-06-11 09:10:53Z ossman $".
//
diff --git a/src/Fl_Window_shape.cxx b/src/Fl_Window_shape.cxx
new file mode 100644
index 0000000..3204944
--- /dev/null
+++ b/src/Fl_Window_shape.cxx
@@ -0,0 +1,407 @@
+//
+// "$Id: Fl_Window_shape.cxx 10348 2014-10-01 16:37:13Z manolo $"
+//
+// implementation of Fl_Window::shape(Fl_Image*) for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 2010-2014 by Bill Spitzak and others.
+//
+// This library is free software. Distribution and use rights are outlined in
+// the file "COPYING" which should have been included with this file. If this
+// file is missing or damaged, see the license at:
+//
+// http://www.fltk.org/COPYING.php
+//
+// Please report all bugs and problems to:
+//
+// http://www.fltk.org/str.php
+//
+
+#include <FL/Fl.H>
+#include <FL/fl_draw.H>
+#include <FL/x.H>
+#include <FL/Fl_Window.H>
+#include <FL/Fl_Bitmap.H>
+#include <FL/Fl_Pixmap.H>
+#include <string.h>
+
+#ifdef WIN32
+# include <malloc.h> // needed for VisualC2010
+#elif !defined(__APPLE__)
+#include <config.h>
+#if HAVE_DLFCN_H
+#include <dlfcn.h>
+#endif
+#define ShapeBounding 0
+#define ShapeSet 0
+#endif
+
+
+#if defined(__APPLE__)
+
+static void MyProviderReleaseData (void *info, const void *data, size_t size) {
+ delete[] (uchar*)data;
+}
+
+// bitwise inversion of all 4-bit quantities
+static const unsigned char swapped[16] = {0,8,4,12,2,10,6,14,1,9,5,13,3,11,7,15};
+
+static inline uchar swap_byte(const uchar b) {
+ // reverse the order of bits of byte b: 1->8 becomes 8->1
+ return (swapped[b & 0xF] << 4) | swapped[b >> 4];
+}
+
+#elif defined(WIN32)
+
+static inline BYTE bit(int x) { return (BYTE)(1 << (x%8)); }
+
+static HRGN bitmap2region(Fl_Bitmap* image) {
+ HRGN hRgn = 0;
+ /* Does this need to be dynamically determined, perhaps? */
+ const int ALLOC_UNIT = 100;
+ DWORD maxRects = ALLOC_UNIT;
+
+ RGNDATA* pData = (RGNDATA*)malloc(sizeof(RGNDATAHEADER)+(sizeof(RECT)*maxRects));
+ pData->rdh.dwSize = sizeof(RGNDATAHEADER);
+ pData->rdh.iType = RDH_RECTANGLES;
+ pData->rdh.nCount = pData->rdh.nRgnSize = 0;
+ SetRect(&pData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0);
+
+ const int bytesPerLine = (image->w() + 7)/8;
+ BYTE* p, *data = (BYTE*)image->array;
+ for (int y = 0; y < image->h(); y++) {
+ // each row, left to right
+ for (int x = 0; x < image->w(); x++) {
+ int x0 = x;
+ while (x < image->w()) {
+ p = data + x / 8;
+ if (!((*p) & bit(x))) break; // transparent pixel
+ x++;
+ }
+ if (x > x0) {
+ RECT *pr;
+ /* Add the pixels (x0, y) to (x, y+1) as a new rectangle
+ * in the region
+ */
+ if (pData->rdh.nCount >= maxRects) {
+ maxRects += ALLOC_UNIT;
+ pData = (RGNDATA*)realloc(pData, sizeof(RGNDATAHEADER)
+ + (sizeof(RECT)*maxRects));
+ }
+ pr = (RECT*)&pData->Buffer;
+ SetRect(&pr[pData->rdh.nCount], x0, y, x, y+1);
+ if (x0 < pData->rdh.rcBound.left)
+ pData->rdh.rcBound.left = x0;
+ if (y < pData->rdh.rcBound.top)
+ pData->rdh.rcBound.top = y;
+ if (x > pData->rdh.rcBound.right)
+ pData->rdh.rcBound.right = x;
+ if (y+1 > pData->rdh.rcBound.bottom)
+ pData->rdh.rcBound.bottom = y+1;
+ pData->rdh.nCount++;
+ /* On Windows98, ExtCreateRegion() may fail if the
+ * number of rectangles is too large (ie: >
+ * 4000). Therefore, we have to create the region by
+ * multiple steps.
+ */
+ if (pData->rdh.nCount == 2000) {
+ HRGN h = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER)
+ + (sizeof(RECT)*maxRects), pData);
+ if (hRgn) {
+ CombineRgn(hRgn, hRgn, h, RGN_OR);
+ DeleteObject(h);
+ } else
+ hRgn = h;
+ pData->rdh.nCount = 0;
+ SetRect(&pData->rdh.rcBound, MAXLONG, MAXLONG, 0, 0);
+ }
+ }
+ }
+ /* Go to next row */
+ data += bytesPerLine;
+ }
+ /* Create or extend the region with the remaining rectangles*/
+ HRGN h = ExtCreateRegion(NULL, sizeof(RGNDATAHEADER)
+ + (sizeof(RECT)*maxRects), pData);
+ if (hRgn) {
+ CombineRgn(hRgn, hRgn, h, RGN_OR);
+ DeleteObject(h);
+ } else hRgn = h;
+ free(pData); // I've created the region so I can free this now, right?
+ return hRgn;
+}
+
+#else
+
+#ifndef FL_DOXYGEN
+void Fl_Window::combine_mask()
+{
+ typedef void (*XShapeCombineMask_type)(Display*, int, int, int, int, Pixmap, int);
+ static XShapeCombineMask_type XShapeCombineMask_f = NULL;
+ static int beenhere = 0;
+ typedef Bool (*XShapeQueryExtension_type)(Display*, int*, int*);
+ if (!beenhere) {
+ beenhere = 1;
+#if HAVE_DLSYM && HAVE_DLFCN_H
+ fl_open_display();
+ void *handle = dlopen(NULL, RTLD_LAZY); // search symbols in executable
+ XShapeQueryExtension_type XShapeQueryExtension_f = (XShapeQueryExtension_type)dlsym(handle, "XShapeQueryExtension");
+ XShapeCombineMask_f = (XShapeCombineMask_type)dlsym(handle, "XShapeCombineMask");
+ // make sure that the X server has the SHAPE extension
+ int error_base, shapeEventBase;
+ if ( !( XShapeQueryExtension_f && XShapeCombineMask_f &&
+ XShapeQueryExtension_f(fl_display, &shapeEventBase, &error_base) ) ) XShapeCombineMask_f = NULL;
+#endif
+ }
+ if (!XShapeCombineMask_f) return;
+ shape_data_->lw_ = w();
+ shape_data_->lh_ = h();
+ Fl_Bitmap* temp = (Fl_Bitmap*)shape_data_->shape_->copy(shape_data_->lw_, shape_data_->lh_);
+ Pixmap pbitmap = XCreateBitmapFromData(fl_display, fl_xid(this),
+ (const char*)temp->array,
+ temp->w(), temp->h());
+ XShapeCombineMask_f(fl_display, fl_xid(this), ShapeBounding, 0, 0, pbitmap, ShapeSet);
+ if (pbitmap != None) XFreePixmap(fl_display, pbitmap);
+ delete temp;
+}
+#endif // !FL_DOXYGEN
+
+#endif // __APPLE__
+
+
+void Fl_Window::shape_bitmap_(Fl_Bitmap* b) {
+ shape_data_->shape_ = b;
+#if defined(__APPLE__)
+ if (b) {
+ // complement mask bits and perform bitwise inversion of all bytes and also reverse top and bottom
+ int bytes_per_row = (b->w() + 7)/8;
+ uchar *from = new uchar[bytes_per_row * b->h()];
+ for (int i = 0; i < b->h(); i++) {
+ uchar *p = (uchar*)b->array + bytes_per_row * i;
+ uchar *last = p + bytes_per_row;
+ uchar *q = from + (b->h() - 1 - i) * bytes_per_row;
+ while (p < last) {
+ *q++ = swap_byte(~*p++);
+ }
+ }
+ CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, from, bytes_per_row * b->h(), MyProviderReleaseData);
+ shape_data_->mask = CGImageMaskCreate(b->w(), b->h(), 1, 1, bytes_per_row, provider, NULL, false);
+ CFRelease(provider);
+ }
+#endif
+}
+
+
+#if defined(__APPLE__) // on the mac, use an 8-bit mask
+/* the image can be of any depth
+ offset gives the byte offset from the pixel start to the byte used to construct the shape
+ */
+void Fl_Window::shape_alpha_(Fl_RGB_Image* img, int offset) {
+ int i, d = img->d(), w = img->w(), h = img->h();
+ shape_data_->shape_ = img;
+ if (shape_data_->shape_) {
+ // reverse top and bottom and convert to gray scale if img->d() == 3 and complement bits
+ int bytes_per_row = w * d;
+ uchar *from = new uchar[w * h];
+ for ( i = 0; i < h; i++) {
+ uchar *p = (uchar*)img->array + bytes_per_row * i + offset;
+ uchar *last = p + bytes_per_row;
+ uchar *q = from + (h - 1 - i) * w;
+ while (p < last) {
+ if (d == 3) {
+ unsigned u = *p++;
+ u += *p++;
+ u += *p++;
+ *q++ = ~(u/3);
+ }
+ else {
+ *q++ = ~(*p);
+ p += d;
+ }
+ }
+ }
+ CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, from, w * h, MyProviderReleaseData);
+ shape_data_->mask = CGImageMaskCreate(w, h, 8, 8, w, provider, NULL, false);
+ CFRelease(provider);
+ }
+}
+
+#else
+
+/* the img image can be of any depth
+ offset gives the byte offset from the pixel start to the byte used to construct the shape
+ */
+void Fl_Window::shape_alpha_(Fl_RGB_Image* img, int offset) {
+ int i, j, d = img->d(), w = img->w(), h = img->h(), bytesperrow = (w+7)/8;
+ unsigned u;
+ uchar byte, onebit;
+ // build an Fl_Bitmap covering the non-fully transparent/black part of the image
+ const uchar* bits = new uchar[h*bytesperrow]; // to store the bitmap
+ const uchar* alpha = img->array + offset; // points to alpha value of rgba pixels
+ for (i = 0; i < h; i++) {
+ uchar *p = (uchar*)bits + i * bytesperrow;
+ byte = 0;
+ onebit = 1;
+ for (j = 0; j < w; j++) {
+ if (d == 3) {
+ u = *alpha;
+ u += *(alpha+1);
+ u += *(alpha+2);
+ }
+ else u = *alpha;
+ if (u > 0) { // if the pixel is not fully transparent/black
+ byte |= onebit; // turn on the corresponding bit of the bitmap
+ }
+ onebit = onebit << 1; // move the single set bit one position to the left
+ if (onebit == 0 || j == w-1) {
+ onebit = 1;
+ *p++ = byte; // store in bitmap one pack of bits
+ byte = 0;
+ }
+ alpha += d; // point to alpha value of next pixel
+ }
+ }
+ Fl_Bitmap* bitmap = new Fl_Bitmap(bits, w, h);
+ bitmap->alloc_array = 1;
+ shape_bitmap_(bitmap);
+ shape_data_->todelete_ = bitmap;
+}
+
+#endif
+
+
+void Fl_Window::shape_pixmap_(Fl_Pixmap* pixmap) {
+ Fl_RGB_Image* rgba = new Fl_RGB_Image(pixmap);
+ shape_alpha_(rgba, 3);
+ delete rgba;
+}
+
+#if FLTK_ABI_VERSION < 10303 && !defined(FL_DOXYGEN)
+Fl_Window::shape_data_type* Fl_Window::shape_data_ = NULL;
+#endif
+
+/** Assigns a non-rectangular shape to the window.
+ This function gives an arbitrary shape (not just a rectangular region) to an Fl_Window.
+ An Fl_Image of any dimension can be used as mask; it is rescaled to the window's dimension as needed.
+
+ The layout and widgets inside are unaware of the mask shape, and most will act as though the window's
+ rectangular bounding box is available
+ to them. It is up to you to make sure they adhere to the bounds of their masking shape.
+
+ The \p img argument can be an Fl_Bitmap, Fl_Pixmap or Fl_RGB_Image:
+ \li With Fl_Bitmap or Fl_Pixmap, the shaped window covers the image part where bitmap bits equal one,
+ or where the pixmap is not fully transparent.
+ \li With an Fl_RGB_Image with an alpha channel (depths 2 or 4), the shaped window covers the image part
+ that is not fully transparent.
+ \li With an Fl_RGB_Image of depth 1 (gray-scale) or 3 (RGB), the shaped window covers the non-black image part.
+
+ Platform details:
+ \li On the unix/linux platform, the SHAPE extension of the X server is required.
+ This function does control the shape of Fl_Gl_Window instances.
+ \li On the MSWindows platform, this function does nothing with class Fl_Gl_Window.
+ \li On the Mac platform, OS version 10.4 or above is required.
+ An 8-bit shape-mask is used when \p img is an Fl_RGB_Image:
+ with depths 2 or 4, the image alpha channel becomes the shape mask such that areas with alpha = 0
+ are out of the shaped window;
+ with depths 1 or 3, white and black are in and out of the
+ shaped window, respectively, and other colors give intermediate masking scores.
+ This function does nothing with class Fl_Gl_Window.
+
+ The window borders and caption created by the window system are turned off by default. They
+ can be re-enabled by calling Fl_Window::border(1).
+
+ A usage example is found at example/shapedwindow.cxx.
+
+ \version 1.3.3 (and requires compilation with -DFLTK_ABI_VERSION = 10303)
+ */
+void Fl_Window::shape(const Fl_Image* img) {
+#if FLTK_ABI_VERSION >= 10303
+ if (shape_data_) {
+ if (shape_data_->todelete_) { delete shape_data_->todelete_; }
+#if defined(__APPLE__)
+ if (shape_data_->mask) { CGImageRelease(shape_data_->mask); }
+#endif
+ }
+ else {
+ shape_data_ = new shape_data_type;
+ }
+ memset(shape_data_, 0, sizeof(shape_data_type));
+ border(false);
+ int d = img->d();
+ if (d && img->count() >= 2) shape_pixmap_((Fl_Pixmap*)img);
+ else if (d == 0) shape_bitmap_((Fl_Bitmap*)img);
+ else if (d == 2 || d == 4) shape_alpha_((Fl_RGB_Image*)img, d - 1);
+ else if ((d == 1 || d == 3) && img->count() == 1) shape_alpha_((Fl_RGB_Image*)img, 0);
+#endif
+}
+
+void Fl_Window::draw() {
+ if (shape_data_) {
+# if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
+ if (shape_data_->mask && (CGContextClipToMask != NULL)) {
+ CGContextClipToMask(fl_gc, CGRectMake(0,0,w(),h()), shape_data_->mask); // requires Mac OS 10.4
+ }
+ CGContextSaveGState(fl_gc);
+#elif defined(WIN32)
+ if ((shape_data_->lw_ != w() || shape_data_->lh_ != h()) && shape_data_->shape_) {
+ // size of window has changed since last time
+ shape_data_->lw_ = w();
+ shape_data_->lh_ = h();
+ Fl_Bitmap* temp = (Fl_Bitmap*)shape_data_->shape_->copy(shape_data_->lw_, shape_data_->lh_);
+ HRGN region = bitmap2region(temp);
+ SetWindowRgn(fl_xid(this), region, TRUE); // the system deletes the region when it's no longer needed
+ delete temp;
+ }
+#elif !(defined(__APPLE__) || defined(WIN32))
+ if (( shape_data_->lw_ != w() || shape_data_->lh_ != h() ) && shape_data_->shape_) {
+ // size of window has changed since last time
+ combine_mask();
+ }
+# endif
+ }
+
+ // The following is similar to Fl_Group::draw(), but ...
+ // - we draw the box with x=0 and y=0 instead of x() and y()
+ // - we don't draw a label
+
+ if (damage() & ~FL_DAMAGE_CHILD) { // draw the entire thing
+ draw_box(box(),0,0,w(),h(),color()); // draw box with x/y = 0
+ }
+ draw_children();
+
+#ifdef __APPLE_QUARTZ__
+ // on OS X, windows have no frame. Before OS X 10.7, to resize a window, we drag the lower right
+ // corner. This code draws a little ribbed triangle for dragging.
+ if (fl_mac_os_version < 100700 && fl_gc && !parent() && resizable() &&
+ (!size_range_set || minh!=maxh || minw!=maxw)) {
+ int dx = Fl::box_dw(box())-Fl::box_dx(box());
+ int dy = Fl::box_dh(box())-Fl::box_dy(box());
+ if (dx<=0) dx = 1;
+ if (dy<=0) dy = 1;
+ int x1 = w()-dx-1, x2 = x1, y1 = h()-dx-1, y2 = y1;
+ Fl_Color c[4] = {
+ color(),
+ fl_color_average(color(), FL_WHITE, 0.7f),
+ fl_color_average(color(), FL_BLACK, 0.6f),
+ fl_color_average(color(), FL_BLACK, 0.8f),
+ };
+ int i;
+ for (i=dx; i<12; i++) {
+ fl_color(c[i&3]);
+ fl_line(x1--, y1, x2, y2--);
+ }
+ }
+#endif
+# if defined(__APPLE__) && MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
+ if (shape_data_) CGContextRestoreGState(fl_gc);
+# endif
+
+# if defined(FLTK_USE_CAIRO)
+ Fl::cairo_make_current(this); // checkout if an update is necessary
+# endif
+}
+
+
+
+//
+// End of "$Id: Fl_Window_shape.cxx 10348 2014-10-01 16:37:13Z manolo $".
+//
diff --git a/src/Fl_XPM_Image.cxx b/src/Fl_XPM_Image.cxx
index f79bfef..580d5fe 100644
--- a/src/Fl_XPM_Image.cxx
+++ b/src/Fl_XPM_Image.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: Fl_XPM_Image.cxx 9325 2012-04-05 05:12:30Z fabien $"
+// "$Id: Fl_XPM_Image.cxx 10156 2014-05-22 12:11:17Z manolo $"
//
// Fl_XPM_Image routines.
//
@@ -60,6 +60,7 @@ Fl_XPM_Image::Fl_XPM_Image(const char *name) : Fl_Pixmap((char *const*)0) {
int malloc_size = INITIALLINES;
char buffer[MAXSIZE+20];
int i = 0;
+ int W,H,ncolors,chars_per_pixel;
while (fgets(buffer,MAXSIZE+20,f)) {
if (buffer[0] != '\"') continue;
char *myp = buffer;
@@ -74,7 +75,7 @@ Fl_XPM_Image::Fl_XPM_Image(const char *name) : Fl_Pixmap((char *const*)0) {
case 'x': {
q++;
int n = 0;
- for (int x = 0; x < 3; x++) {
+ for (int x = 0; x < 2; x++) {
int xd = hexdigit(*q);
if (xd > 15) break;
n = (n<<4)+xd;
@@ -107,6 +108,15 @@ Fl_XPM_Image::Fl_XPM_Image(const char *name) : Fl_Pixmap((char *const*)0) {
new_data = temp_data;
malloc_size += INITIALLINES;
}
+ // first line has 4 ints: width, height, ncolors, chars_per_pixel
+ // followed by color segment:
+ // if ncolors < 0 this is FLTK (non standard) compressed colormap - all colors coded in single line of 4*ncolors bytes
+ // otherwise - ncolor lines of at least chars_per_pixel bytes
+ // followed by pic segment: H lines of at least chars_per_pixel*W bytes
+ // next line: would have loved to use measure_pixmap, but it doesn't return all the data!
+ if ((!i) && (sscanf(buffer,"%d%d%d%d", &W, &H, &ncolors, &chars_per_pixel) < 4)) goto bad_data; // first line
+ else if ((i > (ncolors<0?1:ncolors)) && (myp-buffer-1<W*chars_per_pixel)) goto bad_data; // pic segment
+ else if (myp-buffer-1<(ncolors<0?-ncolors*4:chars_per_pixel)) goto bad_data; // color segment
new_data[i] = new char[myp-buffer+1];
memcpy(new_data[i], buffer,myp-buffer);
new_data[i][myp-buffer] = 0;
@@ -114,14 +124,21 @@ Fl_XPM_Image::Fl_XPM_Image(const char *name) : Fl_Pixmap((char *const*)0) {
}
fclose(f);
-
+ f = NULL;
+ if ((!i) || (i<1+(ncolors<0?1:ncolors)+H)) goto bad_data;
data((const char **)new_data, i);
alloc_data = 1;
measure();
+ return;
+ // dealloc and close as needed when bad data was found
+bad_data:
+ while (i > 0) delete[] new_data[--i];
+ delete[] new_data;
+ if (f) fclose(f);
}
//
-// End of "$Id: Fl_XPM_Image.cxx 9325 2012-04-05 05:12:30Z fabien $".
+// End of "$Id: Fl_XPM_Image.cxx 10156 2014-05-22 12:11:17Z manolo $".
//
diff --git a/src/Fl_arg.cxx b/src/Fl_arg.cxx
index 74e525f..99bf6a3 100644
--- a/src/Fl_arg.cxx
+++ b/src/Fl_arg.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: Fl_arg.cxx 9365 2012-04-21 11:13:10Z matt $"
+// "$Id: Fl_arg.cxx 10145 2014-05-04 13:46:09Z manolo $"
//
// Optional argument initialization code for the Fast Light Tool Kit (FLTK).
//
@@ -435,7 +435,7 @@ without express or implied warranty.
static int ReadInteger(char* string, char** NextString)
{
- register int Result = 0;
+ int Result = 0;
int Sign = 1;
if (*string == '+')
@@ -458,7 +458,7 @@ int XParseGeometry(const char* string, int* x, int* y,
unsigned int* width, unsigned int* height)
{
int mask = NoValue;
- register char *strind;
+ char *strind;
unsigned int tempWidth = 0, tempHeight = 0;
int tempX = 0, tempY = 0;
char *nextCharacter;
@@ -541,5 +541,5 @@ int XParseGeometry(const char* string, int* x, int* y,
#endif // ifdef WIN32
//
-// End of "$Id: Fl_arg.cxx 9365 2012-04-21 11:13:10Z matt $".
+// End of "$Id: Fl_arg.cxx 10145 2014-05-04 13:46:09Z manolo $".
//
diff --git a/src/Fl_cocoa.mm b/src/Fl_cocoa.mm
index a361f29..6f5b8b1 100644
--- a/src/Fl_cocoa.mm
+++ b/src/Fl_cocoa.mm
@@ -1,9 +1,9 @@
//
-// "$Id: Fl_cocoa.mm 9734 2012-11-30 18:20:36Z manolo $"
+// "$Id: Fl_cocoa.mm 10427 2014-11-02 21:06:07Z manolo $"
//
// MacOS-Cocoa specific code for the Fast Light Tool Kit (FLTK).
//
-// Copyright 1998-2012 by Bill Spitzak and others.
+// Copyright 1998-2014 by Bill Spitzak and others.
//
// This library is free software. Distribution and use rights are outlined in
// the file "COPYING" which should have been included with this file. If this
@@ -41,7 +41,6 @@ extern "C" {
#include <FL/x.H>
#include <FL/Fl_Window.H>
#include <FL/Fl_Tooltip.H>
-#include <FL/Fl_Sys_Menu_Bar.H>
#include <FL/Fl_Printer.H>
#include <FL/Fl_Input_.H>
#include <FL/Fl_Text_Display.H>
@@ -51,6 +50,8 @@ extern "C" {
#include <unistd.h>
#include <stdarg.h>
#include <math.h>
+#include <limits.h>
+#include <dlfcn.h>
#import <Cocoa/Cocoa.h>
@@ -80,6 +81,7 @@ typedef unsigned int NSUInteger;
// external functions
extern void fl_fix_focus();
extern unsigned short *fl_compute_macKeyLookUp();
+extern int fl_send_system_handlers(void *e);
// forward definition of functions in this file
// converting cr lf converter function
@@ -88,27 +90,34 @@ static void createAppleMenu(void);
static Fl_Region MacRegionMinusRect(Fl_Region r, int x,int y,int w,int h);
static void cocoaMouseHandler(NSEvent *theEvent);
static int calc_mac_os_version();
+static void clipboard_check(void);
+static NSString *calc_utf8_format(void);
+static void im_update(void);
+static unsigned make_current_counts = 0; // if > 0, then Fl_Window::make_current() can be called only once
+static Fl_X *fl_x_to_redraw = NULL; // set by Fl_X::flush() to the Fl_X object of the window to be redrawn
-static Fl_Quartz_Graphics_Driver fl_quartz_driver;
-static Fl_Display_Device fl_quartz_display(&fl_quartz_driver);
-Fl_Display_Device *Fl_Display_Device::_display = &fl_quartz_display; // the platform display
+Fl_Display_Device *Fl_Display_Device::_display = new Fl_Display_Device(new Fl_Quartz_Graphics_Driver); // the platform display
// public variables
CGContextRef fl_gc = 0;
-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
//int fl_disable_transient_for; // secret method of removing TRANSIENT_FOR
Window fl_window;
Fl_Window *Fl_Window::current_;
int fl_mac_os_version = calc_mac_os_version(); // the version number of the running Mac OS X (e.g., 100604 for 10.6.4)
+static SEL inputContextSEL = (fl_mac_os_version >= 100600 ? @selector(inputContext) : @selector(FLinputContext));
+Fl_Fontdesc* fl_fonts = Fl_X::calc_fl_fonts();
+static NSString *utf8_format = calc_utf8_format();
// forward declarations of variables in this file
static int got_events = 0;
static Fl_Window* resize_from_system;
static int main_screen_height; // height of menubar-containing screen used to convert between Cocoa and FLTK global screen coordinates
+// through_drawRect = YES means the drawRect: message was sent to the view,
+// thus the graphics context was prepared by the system
+static BOOL through_drawRect = NO;
+static int im_enabled = -1;
#if CONSOLIDATE_MOTION
static Fl_Window* send_motion;
@@ -117,6 +126,29 @@ extern Fl_Window* fl_xmousewin;
enum { FLTKTimerEvent = 1, FLTKDataReadyEvent };
+// Carbon functions and definitions
+
+typedef void *TSMDocumentID;
+
+extern "C" enum {
+ kTSMDocumentEnabledInputSourcesPropertyTag = 'enis' // from Carbon/TextServices.h
+};
+
+// Undocumented voodoo. Taken from Mozilla.
+static const int smEnableRomanKybdsOnly = -23;
+
+typedef TSMDocumentID (*TSMGetActiveDocument_type)(void);
+static TSMGetActiveDocument_type TSMGetActiveDocument;
+typedef OSStatus (*TSMSetDocumentProperty_type)(TSMDocumentID, OSType, UInt32, void*);
+static TSMSetDocumentProperty_type TSMSetDocumentProperty;
+typedef OSStatus (*TSMRemoveDocumentProperty_type)(TSMDocumentID, OSType);
+static TSMRemoveDocumentProperty_type TSMRemoveDocumentProperty;
+typedef CFArrayRef (*TISCreateASCIICapableInputSourceList_type)(void);
+static TISCreateASCIICapableInputSourceList_type TISCreateASCIICapableInputSourceList;
+
+typedef void (*KeyScript_type)(short);
+static KeyScript_type KeyScript;
+
/* fltk-utf8 placekeepers */
void fl_reset_spot()
@@ -462,9 +494,7 @@ static void processFLTKEvent(void) {
* break the current event loop
*/
static void breakMacEventLoop()
-{
- fl_lock_function();
-
+{
NSPoint pt={0,0};
NSEvent *event = [NSEvent otherEventWithType:NSApplicationDefined location:pt
modifierFlags:0
@@ -472,7 +502,6 @@ static void breakMacEventLoop()
windowNumber:0 context:NULL
subtype:FLTKTimerEvent data1:0 data2:0];
[NSApp postEvent:event atStart:NO];
- fl_unlock_function();
}
//
@@ -520,6 +549,7 @@ static void delete_timer(MacTimeout& t)
static void do_timer(CFRunLoopTimerRef timer, void* data)
{
+ fl_lock_function();
current_timer = (MacTimeout*)data;
current_timer->pending = 0;
(current_timer->callback)(current_timer->data);
@@ -528,6 +558,7 @@ static void do_timer(CFRunLoopTimerRef timer, void* data)
current_timer = NULL;
breakMacEventLoop();
+ fl_unlock_function();
}
void Fl::add_timeout(double time, Fl_Timeout_Handler cb, void* data)
@@ -628,11 +659,35 @@ void Fl::remove_timeout(Fl_Timeout_Handler cb, void* data)
contentRect:(NSRect)rect
styleMask:(NSUInteger)windowStyle;
- (Fl_Window *)getFl_Window;
+/* These two functions allow to check if a window contains OpenGL-subwindows.
+ This is useful only for Mac OS < 10.7 to repair a problem apparent with the "cube" test program:
+ if the cube window is moved around rapidly (with OS < 10.7), the GL pixels leak away from where they should be.
+ The repair is performed by [FLWindowDelegate windowDidMove:], only if OS < 10.7.
+ */
- (BOOL)containsGLsubwindow;
-- (void)setContainsGLsubwindow:(BOOL)contains;
+- (void)containsGLsubwindow:(BOOL)contains;
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
+- (NSPoint)convertBaseToScreen:(NSPoint)aPoint;
+#endif
@end
@implementation FLWindow
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_7
+- (NSPoint)convertBaseToScreen:(NSPoint)aPoint
+{
+ if (fl_mac_os_version >= 100700) {
+ NSRect r = [self convertRectToScreen:NSMakeRect(aPoint.x, aPoint.y, 0, 0)];
+ return r.origin;
+ }
+ else {
+ // replaces return [super convertBaseToScreen:aPoint] that may trigger a compiler warning
+ typedef NSPoint (*convertIMP)(id, SEL, NSPoint);
+ convertIMP addr = (convertIMP)[NSWindow instanceMethodForSelector:@selector(convertBaseToScreen:)];
+ return addr(self, @selector(convertBaseToScreen:), aPoint);
+ }
+}
+#endif
+
- (FLWindow*)initWithFl_W:(Fl_Window *)flw
contentRect:(NSRect)rect
styleMask:(NSUInteger)windowStyle
@@ -641,6 +696,12 @@ void Fl::remove_timeout(Fl_Timeout_Handler cb, void* data)
if (self) {
w = flw;
containsGLsubwindow = NO;
+ if (fl_mac_os_version >= 100700) {
+ // replaces [self setRestorable:NO] that may trigger a compiler warning
+ typedef void (*setIMP)(id, SEL, BOOL);
+ setIMP addr = (setIMP)[self methodForSelector:@selector(setRestorable:)];
+ addr(self, @selector(setRestorable:), NO);
+ }
}
return self;
}
@@ -652,7 +713,7 @@ void Fl::remove_timeout(Fl_Timeout_Handler cb, void* data)
{
return containsGLsubwindow;
}
-- (void)setContainsGLsubwindow:(BOOL)contains
+- (void)containsGLsubwindow:(BOOL)contains
{
containsGLsubwindow = contains;
}
@@ -666,9 +727,6 @@ void Fl::remove_timeout(Fl_Timeout_Handler cb, void* data)
return !(w->tooltip_window() || w->menu_window());
}
-// TODO see if we really need a canBecomeMainWindow ...
-#if 0
-
- (BOOL)canBecomeMainWindow
{
if (Fl::modal_ && (Fl::modal_ != w))
@@ -677,7 +735,6 @@ void Fl::remove_timeout(Fl_Timeout_Handler cb, void* data)
return !(w->tooltip_window() || w->menu_window());
}
-#endif
@end
@@ -726,6 +783,7 @@ static double do_queued_events( double time = 0.0 )
return time;
}
+
/*
* This public function handles all events. It wait a maximum of
* 'time' seconds for an event. This version returns 1 if events
@@ -739,17 +797,132 @@ int fl_wait( double time )
return (got_events);
}
-double fl_mac_flush_and_wait(double time_to_wait, char in_idle) {
+double fl_mac_flush_and_wait(double time_to_wait) {
+ static int in_idle = 0;
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
+ if (Fl::idle) {
+ if (!in_idle) {
+ in_idle = 1;
+ Fl::idle();
+ in_idle = 0;
+ }
+ // the idle function may turn off idle, we can then wait:
+ if (Fl::idle) time_to_wait = 0.0;
+ }
Fl::flush();
if (Fl::idle && !in_idle) // 'idle' may have been set within flush()
time_to_wait = 0.0;
double retval = fl_wait(time_to_wait);
+ if (fl_gc) {
+ CGContextFlush(fl_gc);
+ fl_gc = 0;
+ }
[pool release];
return retval;
}
+static NSInteger max_normal_window_level(void)
+{
+ Fl_X *x;
+ NSInteger max_level;
+
+ max_level = 0;
+
+ for (x = Fl_X::first;x;x = x->next) {
+ NSInteger level;
+ FLWindow *cw = x->xid;
+ Fl_Window *win = x->w;
+ if (!win || !cw || ![cw isVisible])
+ continue;
+ if (win->modal() || win->non_modal())
+ continue;
+ level = [cw level];
+ if (level >= max_level)
+ max_level = level;
+ }
+
+ return max_level;
+}
+
+// appropriate window level for modal windows
+static NSInteger modal_window_level(void)
+{
+ NSInteger level;
+
+ level = max_normal_window_level();
+ if (level < NSModalPanelWindowLevel)
+ return NSModalPanelWindowLevel;
+
+ // Need some room for non-modal windows
+ level += 2;
+
+ // We cannot exceed this
+ if (level > CGShieldingWindowLevel())
+ return CGShieldingWindowLevel();
+
+ return level;
+}
+
+// appropriate window level for non-modal windows
+static NSInteger non_modal_window_level(void)
+{
+ NSInteger level;
+
+ level = max_normal_window_level();
+ if (level < NSFloatingWindowLevel)
+ return NSFloatingWindowLevel;
+
+ level += 1;
+
+ if (level > CGShieldingWindowLevel())
+ return CGShieldingWindowLevel();
+
+ return level;
+}
+
+// makes sure modal and non-modal windows stay on top
+static void fixup_window_levels(void)
+{
+ NSInteger modal_level, non_modal_level;
+
+ Fl_X *x;
+ FLWindow *prev_modal, *prev_non_modal;
+
+ modal_level = modal_window_level();
+ non_modal_level = non_modal_window_level();
+
+ prev_modal = NULL;
+ prev_non_modal = NULL;
+
+ for (x = Fl_X::first;x;x = x->next) {
+ FLWindow *cw = x->xid;
+ Fl_Window *win = x->w;
+ if (!win || !cw || ![cw isVisible])
+ continue;
+ if (win->modal()) {
+ if ([cw level] != modal_level) {
+ [cw setLevel:modal_level];
+ // changing level puts then in front, so make sure the
+ // stacking isn't messed up
+ if (prev_modal != NULL)
+ [cw orderWindow:NSWindowBelow
+ relativeTo:[prev_modal windowNumber]];
+ }
+ prev_modal = cw;
+ } else if (win->non_modal()) {
+ if ([cw level] != non_modal_level) {
+ [cw setLevel:non_modal_level];
+ if (prev_non_modal != NULL)
+ [cw orderWindow:NSWindowBelow
+ relativeTo:[prev_non_modal windowNumber]];
+ }
+ prev_non_modal = cw;
+ }
+ }
+}
+
+
// updates Fl::e_x, Fl::e_y, Fl::e_x_root, and Fl::e_y_root
static void update_e_xy_and_e_xy_root(NSWindow *nsw)
{
@@ -893,97 +1066,35 @@ static void cocoaMouseHandler(NSEvent *theEvent)
return;
}
-@interface FLTextView : NSTextView
-// this subclass is needed under OS X <= 10.5 but not under >= 10.6 where the base class is enough
+@interface FLTextView : NSTextView // this subclass is only needed under OS X < 10.6
{
+ BOOL isActive;
}
+- (void)insertText:(id)aString;
+- (void)doCommandBySelector:(SEL)aSelector;
+- (void)setActive:(BOOL)a;
@end
@implementation FLTextView
- (void)insertText:(id)aString
{
- [[[NSApp keyWindow] contentView] insertText:aString];
+ if (isActive) [[[NSApp keyWindow] contentView] insertText:aString];
}
- (void)doCommandBySelector:(SEL)aSelector
{
[[[NSApp keyWindow] contentView] doCommandBySelector:aSelector];
}
-@end
-
-/*
-Handle cocoa keyboard events
-Events during a character composition sequence:
- - keydown with deadkey -> [[theEvent characters] length] is 0
- - keyup -> [theEvent characters] contains the deadkey
- - keydown with next key -> [theEvent characters] contains the composed character
- - keyup -> [theEvent characters] contains the standard character
- */
-static void cocoaKeyboardHandler(NSEvent *theEvent)
+- (void)setActive:(BOOL)a
{
- NSUInteger mods;
-
- // get the modifiers
- mods = [theEvent modifierFlags];
- // get the key code
- UInt32 keyCode = 0, maskedKeyCode = 0;
- unsigned short sym = 0;
- keyCode = [theEvent keyCode];
- NSString *s = [theEvent characters];
- if ( (mods & NSShiftKeyMask) && (mods & NSCommandKeyMask) ) {
- s = [s uppercaseString]; // US keyboards return lowercase letter in s if cmd-shift-key is hit
- }
- // extended keyboards can also send sequences on key-up to generate Kanji etc. codes.
- // Some observed prefixes are 0x81 to 0x83, followed by an 8 bit keycode.
- // In this mode, there seem to be no key-down codes
- // printf("%08x %08x %08x\n", keyCode, mods, key);
- maskedKeyCode = keyCode & 0x7f;
-
- if ([theEvent type] == NSKeyUp) {
- Fl::e_state &= 0xbfffffff; // clear the deadkey flag
- }
-
- mods_to_e_state( mods ); // process modifier keys
- sym = macKeyLookUp[maskedKeyCode];
- if (sym < 0xff00) { // a "simple" key
- // find the result of this key without modifier
- NSString *sim = [theEvent charactersIgnoringModifiers];
- UniChar one;
- CFStringGetCharacters((CFStringRef)sim, CFRangeMake(0, 1), &one);
- // charactersIgnoringModifiers doesn't ignore shift, remove it when it's on
- if(one >= 'A' && one <= 'Z') one += 32;
- if (one > 0 && one <= 0x7f && (sym<'0' || sym>'9') ) sym = one;
- }
- Fl::e_keysym = Fl::e_original_keysym = sym;
-
- //NSLog(@"cocoaKeyboardHandler: keycode=%08x keysym=%08x mods=%08x symbol=%@ (%@)",
- // keyCode, sym, mods, [theEvent characters], [theEvent charactersIgnoringModifiers]);
-
- // If there is text associated with this key, it will be filled in later.
- Fl::e_length = 0;
- Fl::e_text = (char*)"";
-}
-
-
-/*
- * Open callback function to call...
- */
-static void (*open_cb)(const char *) = 0;
-
-/*
- * Install an open documents event handler...
- */
-void fl_open_callback(void (*cb)(const char *)) {
- fl_open_display();
- open_cb = cb;
+ isActive = a;
}
+@end
-@interface FLDelegate : NSObject
+@interface FLWindowDelegate : NSObject
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
-<NSWindowDelegate, NSApplicationDelegate>
+<NSWindowDelegate>
#endif
-{
- BOOL seen_open_file;
-}
++ (FLWindowDelegate*)createOnce;
- (void)windowDidMove:(NSNotification *)notif;
- (void)windowDidResize:(NSNotification *)notif;
- (void)windowDidResignKey:(NSNotification *)notif;
@@ -992,18 +1103,18 @@ void fl_open_callback(void (*cb)(const char *)) {
- (void)windowDidDeminiaturize:(NSNotification *)notif;
- (void)windowDidMiniaturize:(NSNotification *)notif;
- (BOOL)windowShouldClose:(id)fl;
-- (void)anyWindowWillClose:(NSNotification *)notif;
-- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication*)sender;
-- (void)applicationDidBecomeActive:(NSNotification *)notify;
-- (void)applicationDidChangeScreenParameters:(NSNotification *)aNotification;
-- (void)applicationWillResignActive:(NSNotification *)notify;
-- (void)applicationWillHide:(NSNotification *)notify;
-- (void)applicationWillUnhide:(NSNotification *)notify;
- (id)windowWillReturnFieldEditor:(NSWindow *)sender toObject:(id)client;
-- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename;
-- (void)applicationDidFinishLaunching:(NSNotification *)aNotification;
+- (void)anyWindowWillClose:(NSNotification *)notif;
@end
-@implementation FLDelegate
+@implementation FLWindowDelegate
++ (FLWindowDelegate*)createOnce
+{
+ static FLWindowDelegate* delegate = nil;
+ if (!delegate) {
+ delegate = [[FLWindowDelegate alloc] init];
+ }
+ return delegate;
+}
- (void)windowDidMove:(NSNotification *)notif
{
fl_lock_function();
@@ -1016,8 +1127,8 @@ void fl_open_callback(void (*cb)(const char *)) {
update_e_xy_and_e_xy_root(nsw);
resize_from_system = window;
window->position((int)pt2.x, (int)(main_screen_height - pt2.y));
- if ([nsw containsGLsubwindow] ) {
- [nsw display];// redraw window after moving if it contains OpenGL subwindows
+ if ([nsw containsGLsubwindow] && fl_mac_os_version < 100700) {
+ [nsw display];// with OS < 10.7, redraw window after moving if it contains OpenGL subwindows
}
fl_unlock_function();
}
@@ -1045,9 +1156,11 @@ void fl_open_callback(void (*cb)(const char *)) {
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())
+ to a "normal" level when the user switches to another window */
+ if (window->fullscreen_active()) {
[nsw setLevel:NSNormalWindowLevel];
+ fixup_window_levels();
+ }
Fl::handle( FL_UNFOCUS, window);
fl_unlock_function();
}
@@ -1057,8 +1170,10 @@ void fl_open_callback(void (*cb)(const char *)) {
FLWindow *nsw = (FLWindow*)[notif object];
Fl_Window *w = [nsw getFl_Window];
/* Restore previous fullscreen level */
- if (w->fullscreen_active())
+ if (w->fullscreen_active()) {
[nsw setLevel:NSStatusWindowLevel];
+ fixup_window_levels();
+ }
if ( w->border() || (!w->modal() && !w->tooltip_window()) ) Fl::handle( FL_FOCUS, w);
fl_unlock_function();
}
@@ -1096,6 +1211,18 @@ void fl_open_callback(void (*cb)(const char *)) {
// the system doesn't need to send [fl close] because FLTK does it when needed
return NO;
}
+- (id)windowWillReturnFieldEditor:(NSWindow *)sender toObject:(id)client
+{
+ if (fl_mac_os_version < 100600) {
+ static FLTextView *view = nil;
+ if (!view) {
+ NSRect rect={{0,0},{20,20}};
+ view = [[FLTextView alloc] initWithFrame:rect];
+ }
+ return view;
+ }
+ return nil;
+}
- (void)anyWindowWillClose:(NSNotification *)notif
{
fl_lock_function();
@@ -1105,13 +1232,34 @@ void fl_open_callback(void (*cb)(const char *)) {
Fl_Window *w = Fl::first_window();
while (w && (w->parent() || !w->border() || !w->visible())) {
w = Fl::next_window(w);
- }
+ }
if (w) {
[Fl_X::i(w)->xid makeKeyWindow];
}
}
fl_unlock_function();
}
+@end
+
+@interface FLAppDelegate : NSObject
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
+<NSApplicationDelegate>
+#endif
+{
+ void (*open_cb)(const char*);
+ TSMDocumentID currentDoc;
+}
+- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication*)sender;
+- (void)applicationDidBecomeActive:(NSNotification *)notify;
+- (void)applicationDidChangeScreenParameters:(NSNotification *)aNotification;
+- (void)applicationDidUpdate:(NSNotification *)aNotification;
+- (void)applicationWillResignActive:(NSNotification *)notify;
+- (void)applicationWillHide:(NSNotification *)notify;
+- (void)applicationWillUnhide:(NSNotification *)notify;
+- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename;
+- (void)open_cb:(void (*)(const char*))cb;
+@end
+@implementation FLAppDelegate
- (NSApplicationTerminateReply)applicationShouldTerminate:(NSApplication*)sender
{
fl_lock_function();
@@ -1128,44 +1276,25 @@ void fl_open_callback(void (*cb)(const char *)) {
fl_unlock_function();
return reply;
}
-/**
- * Cocoa organizes the Z depth of windows on a global priority. FLTK however
- * expects the window manager to organize Z level by application. The trickery
- * below will change Z order during activation and deactivation.
- */
- (void)applicationDidBecomeActive:(NSNotification *)notify
{
fl_lock_function();
- Fl_X *x;
- FLWindow *top = 0, *topModal = 0, *topNonModal = 0;
- for (x = Fl_X::first;x;x = x->next) {
- FLWindow *cw = x->xid;
- Fl_Window *win = x->w;
- if (win && cw && [cw isVisible]) {
- if (win->modal()) {
- [cw setLevel:NSModalPanelWindowLevel];
- if (topModal)
- [cw orderWindow:NSWindowBelow relativeTo:[topModal windowNumber]];
- else
- topModal = cw;
- } else if (win->non_modal()) {
- [cw setLevel:NSFloatingWindowLevel];
- if (topNonModal)
- [cw orderWindow:NSWindowBelow relativeTo:[topNonModal windowNumber]];
- else
- topNonModal = cw;
- } else {
- if (top)
- ;
- else
- top = cw;
- }
- }
- }
+
+ // update clipboard status
+ clipboard_check();
+
+ /**
+ * Cocoa organizes the Z depth of windows on a global priority. FLTK however
+ * expects the window manager to organize Z level by application. The trickery
+ * below will change Z order during activation and deactivation.
+ */
+ fixup_window_levels();
+
fl_unlock_function();
}
- (void)applicationDidChangeScreenParameters:(NSNotification *)unused
{ // react to changes in screen numbers and positions
+ fl_lock_function();
main_screen_height = [[[NSScreen screens] objectAtIndex:0] frame].size.height;
Fl::call_screen_init();
// FLTK windows have already been notified they were moved,
@@ -1179,6 +1308,24 @@ void fl_open_callback(void (*cb)(const char *)) {
}
}
Fl::handle(FL_SCREEN_CONFIGURATION_CHANGED, NULL);
+ fl_unlock_function();
+}
+- (void)applicationDidUpdate:(NSNotification *)aNotification
+{
+ if ((fl_mac_os_version >= 100500) && (im_enabled != -1) &&
+ (TSMGetActiveDocument != NULL)) {
+ TSMDocumentID newDoc;
+ // It is extremely unclear when Cocoa decides to create/update
+ // the input context, but debugging reveals that it is done
+ // by NSApplication:updateWindows. So check if the input context
+ // has shifted after each such run so that we can update our
+ // input methods status.
+ newDoc = TSMGetActiveDocument();
+ if (newDoc != currentDoc) {
+ im_update();
+ currentDoc = newDoc;
+ }
+ }
}
- (void)applicationWillResignActive:(NSNotification *)notify
{
@@ -1243,21 +1390,11 @@ void fl_open_callback(void (*cb)(const char *)) {
}
fl_unlock_function();
}
-- (id)windowWillReturnFieldEditor:(NSWindow *)sender toObject:(id)client
-{
- if (fl_mac_os_version < 100600) {
- static FLTextView *view = nil;
- if (!view) {
- NSRect rect={{0,0},{20,20}};
- view = [[FLTextView alloc] initWithFrame:rect];
- }
- return view;
- }
- return nil;
-}
- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
{
- seen_open_file = YES;
+ // without the next statement, the opening of the 1st window is delayed by several seconds
+ // under Mac OS ≥ 10.8 when a file is dragged on the application icon
+ [[theApplication mainWindow] orderFront:self];
if (open_cb) {
fl_lock_function();
(*open_cb)([filename UTF8String]);
@@ -1266,17 +1403,26 @@ void fl_open_callback(void (*cb)(const char *)) {
}
return NO;
}
-- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
+- (void)open_cb:(void (*)(const char*))cb
{
- // without this, the opening of the 1st window is delayed by several seconds
- // under Mac OS 10.8 when a file is dragged on the application icon
- if (fl_mac_os_version >= 100800 && seen_open_file) [[NSApp mainWindow] orderFront:self];
+ open_cb = cb;
}
@end
+/*
+ * Install an open documents event handler...
+ */
+void fl_open_callback(void (*cb)(const char *)) {
+ fl_open_display();
+ [(FLAppDelegate*)[NSApp delegate] open_cb:cb];
+}
+
@implementation FLApplication
+ (void)sendEvent:(NSEvent *)theEvent
{
+ if (fl_send_system_handlers(theEvent))
+ return;
+
NSEventType type = [theEvent type];
if (type == NSLeftMouseDown) {
fl_lock_function();
@@ -1308,21 +1454,29 @@ void fl_open_callback(void (*cb)(const char *)) {
}
@end
-extern "C" {
- OSErr CPSEnableForegroundOperation(ProcessSerialNumber *psn, UInt32 _arg2,
- UInt32 _arg3, UInt32 _arg4, UInt32 _arg5);
+/* Prototype of undocumented function needed to support Mac OS 10.2 or earlier
+ extern "C" {
+ OSErr CPSEnableForegroundOperation(ProcessSerialNumber*, UInt32, UInt32, UInt32, UInt32);
}
+*/
void fl_open_display() {
static char beenHereDoneThat = 0;
if ( !beenHereDoneThat ) {
beenHereDoneThat = 1;
+
+ TSMGetActiveDocument = (TSMGetActiveDocument_type)Fl_X::get_carbon_function("TSMGetActiveDocument");
+ TSMSetDocumentProperty = (TSMSetDocumentProperty_type)Fl_X::get_carbon_function("TSMSetDocumentProperty");
+ TSMRemoveDocumentProperty = (TSMRemoveDocumentProperty_type)Fl_X::get_carbon_function("TSMRemoveDocumentProperty");
+ TISCreateASCIICapableInputSourceList = (TISCreateASCIICapableInputSourceList_type)Fl_X::get_carbon_function("TISCreateASCIICapableInputSourceList");
+
+ KeyScript = (KeyScript_type)Fl_X::get_carbon_function("KeyScript");
BOOL need_new_nsapp = (NSApp == nil);
if (need_new_nsapp) [NSApplication sharedApplication];
NSAutoreleasePool *localPool;
localPool = [[NSAutoreleasePool alloc] init]; // never released
- [NSApp setDelegate:[[FLDelegate alloc] init]];
+ [(NSApplication*)NSApp setDelegate:[[FLAppDelegate alloc] init]];
if (need_new_nsapp) [NSApp finishLaunching];
// empty the event queue but keep system events for drag&drop of files at launch
@@ -1333,44 +1487,48 @@ void fl_open_display() {
dequeue:YES];
while (ign_event);
- fl_default_cursor = [NSCursor arrowCursor];
-
// bring the application into foreground without a 'CARB' resource
- Boolean same_psn;
- ProcessSerialNumber cur_psn, front_psn;
- if ( !GetCurrentProcess( &cur_psn ) && !GetFrontProcess( &front_psn ) &&
- !SameProcess( &front_psn, &cur_psn, &same_psn ) && !same_psn ) {
+ bool i_am_in_front;
+ ProcessSerialNumber cur_psn = { 0, kCurrentProcess };
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
+ if (fl_mac_os_version >= 100600) {
+ i_am_in_front = [[NSRunningApplication currentApplication] isActive];
+ }
+ else
+#endif
+ {
+ Boolean same_psn;
+ ProcessSerialNumber front_psn;
+ //avoid compilation warnings triggered by GetFrontProcess() and SameProcess()
+ void* h = dlopen(NULL, RTLD_LAZY);
+ typedef OSErr (*GetFrontProcess_type)(ProcessSerialNumber*);
+ GetFrontProcess_type GetFrontProcess_ = (GetFrontProcess_type)dlsym(h, "GetFrontProcess");
+ typedef OSErr (*SameProcess_type)(ProcessSerialNumber*, ProcessSerialNumber*, Boolean*);
+ SameProcess_type SameProcess_ = (SameProcess_type)dlsym(h, "SameProcess");
+ i_am_in_front = (!GetFrontProcess_( &front_psn ) &&
+ !SameProcess_( &front_psn, &cur_psn, &same_psn ) && same_psn );
+ }
+ if (!i_am_in_front) {
// only transform the application type for unbundled apps
NSBundle *bundle = [NSBundle mainBundle];
if (bundle) {
- NSString *exe = [[bundle executablePath] stringByStandardizingPath];
- NSString *bpath = [bundle bundlePath];
- NSString *exe_dir = [exe stringByDeletingLastPathComponent];
- if ([bpath isEqualToString:exe] || [bpath isEqualToString:exe_dir]) bundle = nil;
- }
-
- if ( !bundle )
- {
- // Earlier versions of this code tried to use weak linking, however it
- // appears that this does not work on 10.2. Since 10.3 and higher provide
- // both TransformProcessType and CPSEnableForegroundOperation, the following
- // conditional code compiled on 10.2 will still work on newer releases...
- OSErr err;
-#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3
- if (TransformProcessType != NULL) {
- err = TransformProcessType(&cur_psn, kProcessTransformToForegroundApplication);
- } else
-#endif // MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3
- err = CPSEnableForegroundOperation(&cur_psn, 0x03, 0x3C, 0x2C, 0x1103);
- if (err == noErr) {
- SetFrontProcess( &cur_psn );
- }
+ NSString *exe = [[bundle executablePath] stringByStandardizingPath];
+ NSString *bpath = [bundle bundlePath];
+ NSString *exe_dir = [exe stringByDeletingLastPathComponent];
+ if ([bpath isEqualToString:exe] || [bpath isEqualToString:exe_dir]) bundle = nil;
+ }
+
+ if ( !bundle ) {
+ TransformProcessType(&cur_psn, kProcessTransformToForegroundApplication); // needs Mac OS 10.3
+ /* support of Mac OS 10.2 or earlier used this undocumented call instead
+ err = CPSEnableForegroundOperation(&cur_psn, 0x03, 0x3C, 0x2C, 0x1103);
+ */
+ [NSApp activateIgnoringOtherApps:YES];
}
}
if (![NSApp servicesMenu]) createAppleMenu();
- fl_system_menu = [NSApp mainMenu];
main_screen_height = [[[NSScreen screens] objectAtIndex:0] frame].size.height;
- [[NSNotificationCenter defaultCenter] addObserver:[NSApp delegate]
+ [[NSNotificationCenter defaultCenter] addObserver:[FLWindowDelegate createOnce]
selector:@selector(anyWindowWillClose:)
name:NSWindowWillCloseNotification
object:nil];
@@ -1387,6 +1545,66 @@ void fl_open_display() {
void fl_close_display() {
}
+// Force a "Roman" or "ASCII" keyboard, which both the Mozilla and
+// Safari people seem to think implies turning off advanced IME stuff
+// (see nsTSMManager::SyncKeyScript in Mozilla and enableSecureTextInput
+// in Safari/Webcore). Should be good enough for us then...
+
+static void im_update(void) {
+ if (fl_mac_os_version >= 100500) {
+ TSMDocumentID doc;
+
+ if ((TSMGetActiveDocument == NULL) ||
+ (TSMSetDocumentProperty == NULL) ||
+ (TSMRemoveDocumentProperty == NULL) ||
+ (TISCreateASCIICapableInputSourceList == NULL))
+ return;
+
+ doc = TSMGetActiveDocument();
+
+ if (im_enabled)
+ TSMRemoveDocumentProperty(doc, kTSMDocumentEnabledInputSourcesPropertyTag);
+ else {
+ CFArrayRef inputSources;
+
+ inputSources = TISCreateASCIICapableInputSourceList();
+ TSMSetDocumentProperty(doc, kTSMDocumentEnabledInputSourcesPropertyTag,
+ sizeof(CFArrayRef), &inputSources);
+ CFRelease(inputSources);
+ }
+ } else {
+ if (KeyScript == NULL)
+ return;
+
+ if (im_enabled)
+ KeyScript(smKeyEnableKybds);
+ else
+ KeyScript(smEnableRomanKybdsOnly);
+ }
+}
+
+void Fl::enable_im() {
+ fl_open_display();
+
+ im_enabled = 1;
+
+ if (fl_mac_os_version >= 100500)
+ [NSApp updateWindows];
+ else
+ im_update();
+}
+
+void Fl::disable_im() {
+ fl_open_display();
+
+ im_enabled = 0;
+
+ if (fl_mac_os_version >= 100500)
+ [NSApp updateWindows];
+ else
+ im_update();
+}
+
// Gets the border sizes and the titlebar size
static void get_window_frame_sizes(int &bx, int &by, int &bt) {
@@ -1463,15 +1681,6 @@ void Fl::get_mouse(int &x, int &y)
/*
- * Initialize the given port for redraw and call the window's flush() to actually draw the content
- */
-void Fl_X::flush()
-{
- w->flush();
- if (fl_gc) CGContextFlush(fl_gc);
-}
-
-/*
* Gets called when a window is created, resized, or deminiaturized
*/
static void handleUpdateEvent( Fl_Window *window )
@@ -1491,7 +1700,10 @@ static void handleUpdateEvent( Fl_Window *window )
cx->region = 0;
}
cx->w->clear_damage(FL_DAMAGE_ALL);
+ CGContextRef gc = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
+ CGContextSaveGState(gc); // save original context
cx->flush();
+ CGContextRestoreGState(gc); // restore original context
cx->w->clear_damage();
}
window->clear_damage(FL_DAMAGE_ALL);
@@ -1629,16 +1841,143 @@ static void q_set_window_title(NSWindow *nsw, const char * name, const char *mi
}
}
+/** How FLTK handles Mac OS text input
+
+ Let myview be the instance of the FLView class that has the keyboard focus. FLView is an FLTK-defined NSView subclass
+ that implements the NSTextInputClient protocol to properly handle text input. It also implements the old NSTextInput
+ protocol to run with OS <= 10.4. The few NSTextInput protocol methods that differ in signature from the NSTextInputClient
+ protocol transmit the received message to the corresponding NSTextInputClient method.
+
+ Keyboard input sends keyDown: and performKeyEquivalent: messages to myview. The latter occurs for keys such as
+ ForwardDelete, arrows and F1, and when the Ctrl or Cmd modifiers are used. Other key presses send keyDown: messages.
+ The keyDown: method calls [[myview inputContext] handleEvent:theEvent] that triggers system
+ processing of keyboard events. The performKeyEquivalent: method directly calls Fl::handle(FL_KEYBOARD, focus-window)
+ when the Ctrl or Cmd modifiers are used. If not, it also calls [[myview inputContext] handleEvent:theEvent].
+ The performKeyEquivalent: method returns YES when the keystroke has been handled and NO otherwise, which allows
+ shortcuts of the system menu to be processed. Three sorts of messages are then sent back by the system to myview:
+ doCommandBySelector:, setMarkedText: and insertText:. All 3 messages eventually produce Fl::handle(FL_KEYBOARD, win) calls.
+ The doCommandBySelector: message allows to process events such as new-line, forward and backward delete, arrows,
+ escape, tab, F1. The message setMarkedText: is sent when marked text, that is, temporary text that gets replaced later
+ by some other text, is inserted. This happens when a dead key is pressed, and also
+ when entering complex scripts (e.g., Chinese). Fl_X::next_marked_length gives the byte
+ length of marked text before the FL_KEYBOARD event is processed. Fl::compose_state gives this length after this processing.
+ Message insertText: is sent to enter text in the focused widget. If there's marked text, Fl::compose_state is > 0, and this
+ marked text gets replaced by the inserted text. If there's no marked text, the new text is inserted at the insertion point.
+ When the character palette is used to enter text, the system sends an insertText: message to myview.
+ The in_key_event field of the FLView class allows to differentiate keyboard from palette inputs.
+
+ During processing of the handleEvent message, inserted and marked strings are concatenated in a single string
+ inserted in a single FL_KEYBOARD event after return from handleEvent. The need_handle member variable of FLView allows
+ to determine when setMarkedText or insertText strings have been sent during handleEvent processing and must trigger
+ an FL_KEYBOARD event. Concatenating two insertText operations or an insertText followed by a setMarkedText is possible.
+ In contrast, setMarkedText followed by insertText or by another setMarkedText isn't correct if concatenated in a single
+ string. Thus, in such case, the setMarkedText and the next operation produce each an FL_KEYBOARD event.
+
+ OS >= 10.7 contains a feature where pressing and holding certain keys opens a menu window that shows a list
+ of possible accented variants of this key. The selectedRange field of the FLView class and the selectedRange, insertText:
+ and setMarkedText: methods of the NSTextInputClient protocol are used to support this feature.
+ The notion of selected text (!= marked text) is monitored by the selectedRange field.
+ The -(NSRange)[FLView selectedRange] method is used to control whether an FLTK widget opens accented character windows
+ by returning .location = NSNotFound to disable that, or returning the value of the selectedRange field to enable the feature.
+ When selectedRange.location >= 0, the value of selectedRange.length is meaningful. 0 means no text is currently selected,
+ > 0 means this number of characters before the insertion point are selected. The insertText: method does
+ selectedRange = NSMakeRange(100, 0); to indicate no text is selected. The setMarkedText: method does
+ selectedRange = NSMakeRange(100, newSelection.length); to indicate that this length of text is selected.
+
+ With OS <= 10.5, the crucial call [[myview inputContext] handleEvent:theEvent] is not possible because neither the
+ inputContext nor the handleEvent: methods are implemented. This call is re-written:
+ static SEL inputContextSEL = (fl_mac_os_version >= 100600 ? @selector(inputContext) : @selector(FLinputContext));
+ [[myview performSelector:inputContextSEL] handleEvent:theEvent];
+ that replaces the 10.6 inputContext message by the FLinputContext message. This message and two FLTK-defined classes,
+ FLTextInputContext and FLTextView, are used to emulate with OS <= 10.5 what's possible with OS >= 10.6.
+ Method -(FLTextInputContext*)[FLView FLinputContext] returns an instance of class FLTextInputContext that possesses
+ a handleEvent: method. FLView's FLinputContext method also calls [[self window] fieldEditor:YES forObject:nil] which
+ returns the so-called view's "field editor". This editor is an instance of the FLTextView class allocated by the
+ -(id)[FLWindowDelegate windowWillReturnFieldEditor: toObject:] method.
+ The -(BOOL)[FLTextInputContext handleEvent:] method emulates the missing 10.6 -(BOOL)[NSTextInputContext handleEvent:]
+ by sending the interpretKeyEvents: message to the FLTextView object. The system sends back doCommandBySelector: and
+ insertText: messages to the FLTextView object that are transmitted unchanged to myview to be processed as with OS >= 10.6.
+ The system also sends setMarkedText: messages directly to myview.
+
+ There is furthermore an oddity of dead key processing with OS <= 10.5. It occurs when a dead key followed by a non-accented
+ key are pressed. Say, for example, that keys '^' followed by 'p' are pressed on a French or German keyboard. Resulting
+ messages are: [myview setMarkedText:@"^"], [myview insertText:@"^"], [myview insertText:@"p"], [FLTextView insertText:@"^p"].
+ The 2nd '^' replaces the marked 1st one, followed by p^p. The resulting text in the widget is "^p^p" instead of the
+ desired "^p". To avoid that, the FLTextView object is deactivated by the insertText: message and reactivated after
+ the handleEvent: message has been processed.
+
+ NSEvent's during a character composition sequence:
+ - keyDown with deadkey -> [[theEvent characters] length] is 0
+ - keyUp -> [theEvent characters] contains the deadkey
+ - keyDown with next key -> [theEvent characters] contains the composed character
+ - keyUp -> [theEvent characters] contains the standard character
+ */
-@interface FLView : NSView <NSTextInput> {
- int next_compose_length;
- bool in_key_event;
+static void cocoaKeyboardHandler(NSEvent *theEvent)
+{
+ NSUInteger mods;
+ // get the modifiers
+ mods = [theEvent modifierFlags];
+ // get the key code
+ UInt32 keyCode = 0, maskedKeyCode = 0;
+ unsigned short sym = 0;
+ keyCode = [theEvent keyCode];
+ // extended keyboards can also send sequences on key-up to generate Kanji etc. codes.
+ // Some observed prefixes are 0x81 to 0x83, followed by an 8 bit keycode.
+ // In this mode, there seem to be no key-down codes
+ // printf("%08x %08x %08x\n", keyCode, mods, key);
+ maskedKeyCode = keyCode & 0x7f;
+ mods_to_e_state( mods ); // process modifier keys
+ sym = macKeyLookUp[maskedKeyCode];
+ if (sym < 0xff00) { // a "simple" key
+ // find the result of this key without modifier
+ NSString *sim = [theEvent charactersIgnoringModifiers];
+ UniChar one;
+ CFStringGetCharacters((CFStringRef)sim, CFRangeMake(0, 1), &one);
+ // charactersIgnoringModifiers doesn't ignore shift, remove it when it's on
+ if(one >= 'A' && one <= 'Z') one += 32;
+ if (one > 0 && one <= 0x7f && (sym<'0' || sym>'9') ) sym = one;
+ }
+ Fl::e_keysym = Fl::e_original_keysym = sym;
+ /*NSLog(@"cocoaKeyboardHandler: keycode=%08x keysym=%08x mods=%08x symbol=%@ (%@)",
+ keyCode, sym, mods, [theEvent characters], [theEvent charactersIgnoringModifiers]);*/
+ // If there is text associated with this key, it will be filled in later.
+ Fl::e_length = 0;
+ Fl::e_text = (char*)"";
+}
+
+@interface FLTextInputContext : NSObject { // "emulates" NSTextInputContext before OS 10.6
+@public
+ FLTextView *edit;
+}
+-(BOOL)handleEvent:(NSEvent*)theEvent;
+@end
+@implementation FLTextInputContext
+-(BOOL)handleEvent:(NSEvent*)theEvent {
+ [self->edit setActive:YES];
+ [self->edit interpretKeyEvents:[NSArray arrayWithObject:theEvent]];
+ [self->edit setActive:YES];
+ return YES;
+}
+@end
+
+@interface FLView : NSView <NSTextInput
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+, NSTextInputClient
+#endif
+> {
+ BOOL in_key_event; // YES means keypress is being processed by handleEvent
+ BOOL need_handle; // YES means Fl::handle(FL_KEYBOARD,) is needed after handleEvent processing
+ NSInteger identifier;
+ NSRange selectedRange;
}
+ (void)prepareEtext:(NSString*)aString;
++ (void)concatEtext:(NSString*)aString;
- (id)init;
- (void)drawRect:(NSRect)rect;
- (BOOL)acceptsFirstResponder;
- (BOOL)acceptsFirstMouse:(NSEvent*)theEvent;
+- (void)resetCursorRects;
- (BOOL)performKeyEquivalent:(NSEvent*)theEvent;
- (void)mouseUp:(NSEvent *)theEvent;
- (void)rightMouseUp:(NSEvent *)theEvent;
@@ -1651,7 +1990,6 @@ static void q_set_window_title(NSWindow *nsw, const char * name, const char *mi
- (void)rightMouseDragged:(NSEvent *)theEvent;
- (void)otherMouseDragged:(NSEvent *)theEvent;
- (void)scrollWheel:(NSEvent *)theEvent;
-- (BOOL)handleKeyDown:(NSEvent *)theEvent;
- (void)keyDown:(NSEvent *)theEvent;
- (void)keyUp:(NSEvent *)theEvent;
- (void)flagsChanged:(NSEvent *)theEvent;
@@ -1660,24 +1998,36 @@ static void q_set_window_title(NSWindow *nsw, const char * name, const char *mi
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender;
- (void)draggingExited:(id < NSDraggingInfo >)sender;
- (NSDragOperation)draggingSourceOperationMaskForLocal:(BOOL)isLocal;
+- (FLTextInputContext*)FLinputContext;
+#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_5
+- (void)insertText:(id)aString replacementRange:(NSRange)replacementRange;
+- (void)setMarkedText:(id)aString selectedRange:(NSRange)newSelection replacementRange:(NSRange)replacementRange;
+- (NSAttributedString *)attributedSubstringForProposedRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange;
+- (NSRect)firstRectForCharacterRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange;
+- (NSInteger)windowLevel;
+#endif
@end
@implementation FLView
- (id)init
{
+ static NSInteger counter = 0;
self = [super init];
if (self) {
- next_compose_length = -1;
- in_key_event = false;
+ in_key_event = NO;
+ identifier = ++counter;
}
return self;
}
- (void)drawRect:(NSRect)rect
{
fl_lock_function();
+ through_drawRect = YES;
FLWindow *cw = (FLWindow*)[self window];
Fl_Window *w = [cw getFl_Window];
- handleUpdateEvent(w);
+ if (fl_x_to_redraw) fl_x_to_redraw->flush();
+ else handleUpdateEvent(w);
+ through_drawRect = NO;
fl_unlock_function();
}
@@ -1688,7 +2038,28 @@ static void q_set_window_title(NSWindow *nsw, const char * name, const char *mi
- (BOOL)performKeyEquivalent:(NSEvent*)theEvent
{
//NSLog(@"performKeyEquivalent:");
- return [self handleKeyDown:theEvent];
+ fl_lock_function();
+ cocoaKeyboardHandler(theEvent);
+ BOOL handled;
+ NSUInteger mods = [theEvent modifierFlags];
+ if ( (mods & NSControlKeyMask) || (mods & NSCommandKeyMask) ) {
+ NSString *s = [theEvent characters];
+ if ( (mods & NSShiftKeyMask) && (mods & NSCommandKeyMask) ) {
+ s = [s uppercaseString]; // US keyboards return lowercase letter in s if cmd-shift-key is hit
+ }
+ [FLView prepareEtext:s];
+ Fl::compose_state = 0;
+ handled = Fl::handle(FL_KEYBOARD, [(FLWindow*)[theEvent window] getFl_Window]);
+ }
+ else {
+ in_key_event = YES;
+ need_handle = NO;
+ handled = [[self performSelector:inputContextSEL] handleEvent:theEvent];
+ if (need_handle) handled = Fl::handle(FL_KEYBOARD, [(FLWindow*)[theEvent window] getFl_Window]);
+ in_key_event = NO;
+ }
+ fl_unlock_function();
+ return handled;
}
- (BOOL)acceptsFirstMouse:(NSEvent*)theEvent
{
@@ -1696,6 +2067,17 @@ static void q_set_window_title(NSWindow *nsw, const char * name, const char *mi
Fl_Window *first = Fl::first_window();
return (first == w || !first->modal());
}
+- (void)resetCursorRects {
+ Fl_Window *w = [(FLWindow*)[self window] getFl_Window];
+ Fl_X *i = Fl_X::i(w);
+ if (!i) return; // fix for STR #3128
+ // 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);
}
@@ -1729,57 +2111,21 @@ static void q_set_window_title(NSWindow *nsw, const char * name, const char *mi
- (void)scrollWheel:(NSEvent *)theEvent {
cocoaMouseWheelHandler(theEvent);
}
-- (BOOL)handleKeyDown:(NSEvent *)theEvent {
- //NSLog(@"handleKeyDown");
+- (void)keyDown:(NSEvent *)theEvent {
+ //NSLog(@"keyDown:%@",[theEvent characters]);
fl_lock_function();
-
- Fl_Window *window = (Fl_Window*)[(FLWindow*)[theEvent window] getFl_Window];
+ Fl_Window *window = [(FLWindow*)[theEvent window] getFl_Window];
Fl::first_window(window);
-
- next_compose_length = -1;
- // First let's process the raw key press
cocoaKeyboardHandler(theEvent);
-
- int no_text_key = false;
- static const int notext[] = { // keys that don't emit text
- FL_BackSpace, FL_Print, FL_Scroll_Lock, FL_Pause,
- FL_Insert, FL_Home, FL_Page_Up, FL_Delete, FL_End, FL_Page_Down,
- FL_Left, FL_Up, FL_Right, FL_Down,
- FL_Menu, FL_Num_Lock, FL_Help
- };
- static const int count = sizeof(notext)/sizeof(int);
- if (Fl::e_keysym > FL_F && Fl::e_keysym <= FL_F_Last) no_text_key = true;
- else for (int i=0; i < count; i++) {
- if (notext[i] == Fl::e_keysym) {
- no_text_key = true;
- break;
- }
- }
- 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
- NSText *edit = [[theEvent window] fieldEditor:YES forObject:nil];
- in_key_event = true;
- [edit interpretKeyEvents:[NSArray arrayWithObject:theEvent]];
- in_key_event = false;
- }
- //NSLog(@"to text=%@ l=%d", [NSString stringWithUTF8String:Fl::e_text], Fl::e_length);
- int handled = Fl::handle(FL_KEYDOWN, window);
- // We have to update this after Fl::handle as it says what to do on the
- // _next_ input
- if (next_compose_length != -1)
- Fl::compose_state = next_compose_length;
-
+ in_key_event = YES;
+ need_handle = NO;
+ [[self performSelector:inputContextSEL] handleEvent:theEvent];
+ if (need_handle) Fl::handle(FL_KEYBOARD, window);
+ in_key_event = NO;
fl_unlock_function();
- return (handled ? YES : NO);
-}
-- (void)keyDown:(NSEvent *)theEvent {
- //NSLog(@"keyDown: ");
- [self handleKeyDown:theEvent];
}
- (void)keyUp:(NSEvent *)theEvent {
- //NSLog(@"keyUp: ");
+ //NSLog(@"keyUp:%@",[theEvent characters]);
fl_lock_function();
Fl_Window *window = (Fl_Window*)[(FLWindow*)[theEvent window] getFl_Window];
Fl::first_window(window);
@@ -1863,8 +2209,8 @@ static void q_set_window_title(NSWindow *nsw, const char * name, const char *mi
CFStringGetCString(all, DragData, l + 1, kCFStringEncodingUTF8);
CFRelease(all);
}
- else if ( [[pboard types] containsObject:NSStringPboardType] ) {
- NSData *data = [pboard dataForType:NSStringPboardType];
+ else if ( [[pboard types] containsObject:utf8_format] ) {
+ NSData *data = [pboard dataForType:utf8_format];
DragData = (char *)malloc([data length] + 1);
[data getBytes:DragData];
DragData[[data length]] = 0;
@@ -1902,6 +2248,15 @@ static void q_set_window_title(NSWindow *nsw, const char * name, const char *mi
return NSDragOperationGeneric;
}
+- (FLTextInputContext*)FLinputContext { // used only if OS < 10.6 to replace [NSView inputContext]
+ static FLTextInputContext *context = NULL;
+ if (!context) {
+ context = [[FLTextInputContext alloc] init];
+ }
+ context->edit = (FLTextView*)[[self window] fieldEditor:YES forObject:nil];
+ return context;
+}
+
+ (void)prepareEtext:(NSString*)aString {
// fills Fl::e_text with UTF-8 encoded aString using an adequate memory allocation
static char *received_utf8 = NULL;
@@ -1923,69 +2278,124 @@ static void q_set_window_title(NSWindow *nsw, const char * name, const char *mi
Fl::e_length = l;
}
-// These functions implement text input.
-// Only two-stroke character composition works at this point.
-// Needs much elaboration to fully support CJK text input,
-// but this is the way to go.
++ (void)concatEtext:(NSString*)aString {
+ // extends Fl::e_text with aString
+ NSString *newstring = [[NSString stringWithUTF8String:Fl::e_text] stringByAppendingString:aString];
+ [FLView prepareEtext:newstring];
+}
+
- (void)doCommandBySelector:(SEL)aSelector {
+ NSString *s = [[NSApp currentEvent] characters];
+ //NSLog(@"doCommandBySelector:%s text='%@'",sel_getName(aSelector), s);
+ s = [s substringFromIndex:[s length] - 1];
+ [FLView prepareEtext:s]; // use the last character of the event; necessary for deadkey + Tab
+ Fl_Window *target = [(FLWindow*)[self window] getFl_Window];
+ Fl::handle(FL_KEYBOARD, target);
}
- (void)insertText:(id)aString {
+ [self insertText:aString replacementRange:NSMakeRange(NSNotFound, 0)];
+}
+
+- (void)insertText:(id)aString replacementRange:(NSRange)replacementRange {
NSString *received;
if ([aString isKindOfClass:[NSAttributedString class]]) {
received = [(NSAttributedString*)aString string];
} else {
received = (NSString*)aString;
}
- //NSLog(@"insertText: received=%@",received);
-
- 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();
+ /*NSLog(@"insertText='%@' l=%d Fl::compose_state=%d range=%d,%d",
+ received,strlen([received UTF8String]),Fl::compose_state,replacementRange.location,replacementRange.length);*/
+ fl_lock_function();
+ Fl_Window *target = [(FLWindow*)[self window] getFl_Window];
+ while (replacementRange.length--) { // delete replacementRange.length characters before insertion point
+ int saved_keysym = Fl::e_keysym;
+ Fl::e_keysym = FL_BackSpace;
+ Fl::handle(FL_KEYBOARD, target);
+ Fl::e_keysym = saved_keysym;
+ }
+ if (in_key_event && Fl_X::next_marked_length && Fl::e_length) {
+ // if setMarkedText + insertText is sent during handleEvent, text cannot be concatenated in single FL_KEYBOARD event
+ Fl::handle(FL_KEYBOARD, target);
+ Fl::e_length = 0;
+ }
+ if (in_key_event && Fl::e_length) [FLView concatEtext:received];
+ else [FLView prepareEtext:received];
+ Fl_X::next_marked_length = 0;
+ // We can get called outside of key events (e.g., from the character palette, from CJK text input).
+ BOOL palette = !(in_key_event || Fl::compose_state);
+ if (palette) Fl::e_keysym = 0;
+ // YES if key has text attached
+ BOOL has_text_key = Fl::e_keysym <= '~' || Fl::e_keysym == FL_Iso_Key ||
+ (Fl::e_keysym >= FL_KP && Fl::e_keysym <= FL_KP_Last && Fl::e_keysym != FL_KP_Enter);
+ // insertText sent during handleEvent of a key without text cannot be processed in a single FL_KEYBOARD event.
+ // Occurs with deadkey followed by non-text key
+ if (!in_key_event || !has_text_key) {
+ Fl::handle(FL_KEYBOARD, target);
+ Fl::e_length = 0;
+ }
+ else need_handle = YES;
+ selectedRange = NSMakeRange(100, 0); // 100 is an arbitrary value
+ // for some reason, with the palette, the window does not redraw until the next mouse move or button push
+ // sending a 'redraw()' or 'awake()' does not solve the issue!
+ if (palette) Fl::flush();
+ if (fl_mac_os_version < 100600) [(FLTextView*)[[self window] fieldEditor:YES forObject:nil] setActive:NO];
+ fl_unlock_function();
}
- (void)setMarkedText:(id)aString selectedRange:(NSRange)newSelection {
+ [self setMarkedText:aString selectedRange:newSelection replacementRange:NSMakeRange(NSNotFound, 0)];
+}
+
+- (void)setMarkedText:(id)aString selectedRange:(NSRange)newSelection replacementRange:(NSRange)replacementRange {
NSString *received;
- if (newSelection.location == 0) {
- [self unmarkText];
- return;
- }
if ([aString isKindOfClass:[NSAttributedString class]]) {
received = [(NSAttributedString*)aString string];
} else {
received = (NSString*)aString;
}
- //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);
+ fl_lock_function();
+ /*NSLog(@"setMarkedText:%@ l=%d newSelection=%d,%d Fl::compose_state=%d replacement=%d,%d",
+ received, strlen([received UTF8String]), newSelection.location, newSelection.length, Fl::compose_state,
+ replacementRange.location, replacementRange.length);*/
+ Fl_Window *target = [(FLWindow*)[self window] getFl_Window];
+ while (replacementRange.length--) { // delete replacementRange.length characters before insertion point
+ Fl::e_keysym = FL_BackSpace;
+ Fl::compose_state = 0;
+ Fl_X::next_marked_length = 0;
+ Fl::handle(FL_KEYBOARD, target);
+ Fl::e_keysym = 'a'; // pretend a letter key was hit
+ }
+ if (in_key_event && Fl_X::next_marked_length && Fl::e_length) {
+ // if setMarkedText + setMarkedText is sent during handleEvent, text cannot be concatenated in single FL_KEYBOARD event
+ Fl::handle(FL_KEYBOARD, target);
+ Fl::e_length = 0;
+ }
+ if (in_key_event && Fl::e_length) [FLView concatEtext:received];
+ else [FLView prepareEtext:received];
+ Fl_X::next_marked_length = strlen([received UTF8String]);
+ if (!in_key_event) Fl::handle( FL_KEYBOARD, target);
+ else need_handle = YES;
+ selectedRange = NSMakeRange(100, newSelection.length);
+ fl_unlock_function();
}
- (void)unmarkText {
fl_lock_function();
- Fl::compose_state = 0;
+ Fl::reset_marked_text();
fl_unlock_function();
//NSLog(@"unmarkText");
}
- (NSRange)selectedRange {
+ Fl_Widget *w = Fl::focus();
+ if (w && w->use_accents_menu()) return selectedRange;
return NSMakeRange(NSNotFound, 0);
}
- (NSRange)markedRange {
- //NSLog(@"markedRange ?");
- return NSMakeRange(NSNotFound, Fl::compose_state);
+ //NSLog(@"markedRange=%d %d", Fl::compose_state > 0?0:NSNotFound, Fl::compose_state);
+ return NSMakeRange(Fl::compose_state > 0?0:NSNotFound, Fl::compose_state);
}
- (BOOL)hasMarkedText {
@@ -1994,6 +2404,9 @@ static void q_set_window_title(NSWindow *nsw, const char * name, const char *mi
}
- (NSAttributedString *)attributedSubstringFromRange:(NSRange)aRange {
+ return [self attributedSubstringForProposedRange:aRange actualRange:NULL];
+}
+- (NSAttributedString *)attributedSubstringForProposedRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange {
//NSLog(@"attributedSubstringFromRange: %d %d",aRange.location,aRange.length);
return nil;
}
@@ -2003,28 +2416,44 @@ static void q_set_window_title(NSWindow *nsw, const char * name, const char *mi
}
- (NSRect)firstRectForCharacterRange:(NSRange)aRange {
+ return [self firstRectForCharacterRange:aRange actualRange:NULL];
+}
+- (NSRect)firstRectForCharacterRange:(NSRange)aRange actualRange:(NSRangePointer)actualRange {
+ //NSLog(@"firstRectForCharacterRange %d %d actualRange=%p",aRange.location, aRange.length,actualRange);
NSRect glyphRect;
fl_lock_function();
Fl_Widget *focus = Fl::focus();
- Fl_Window *wfocus = focus->window();
- while (wfocus->window()) wfocus = wfocus->window();
+ Fl_Window *wfocus = [(FLWindow*)[self window] getFl_Window];
+ if (!focus) focus = wfocus;
glyphRect.size.width = 0;
- if (dynamic_cast<Fl_Text_Display*>(focus) != NULL) {
- int x, y;
- Fl_Text_Display *current = (Fl_Text_Display*)focus;
- current->position_to_xy( current->insert_position(), &x, &y );
+ int x, y, height;
+ if (Fl_X::insertion_point_location(&x, &y, &height)) {
glyphRect.origin.x = (CGFloat)x;
- glyphRect.origin.y = (CGFloat)y + current->textsize();
- glyphRect.size.height = current->textsize();
+ glyphRect.origin.y = (CGFloat)y;
} else {
- glyphRect.origin.x = focus->x();
- glyphRect.origin.y = focus->y() + focus->h();
- glyphRect.size.height = 12;
+ if (focus->as_window()) {
+ glyphRect.origin.x = 0;
+ glyphRect.origin.y = focus->h();
+ }
+ else {
+ glyphRect.origin.x = focus->x();
+ glyphRect.origin.y = focus->y() + focus->h();
+ }
+ height = 12;
+ }
+ glyphRect.size.height = height;
+ Fl_Window *win = focus->as_window();
+ if (!win) win = focus->window();
+ while (win != NULL && win != wfocus) {
+ glyphRect.origin.x += win->x();
+ glyphRect.origin.y += win->y();
+ win = win->window();
}
// Convert the rect to screen coordinates
glyphRect.origin.y = wfocus->h() - glyphRect.origin.y;
- glyphRect.origin = [[self window] convertBaseToScreen:glyphRect.origin];
+ glyphRect.origin = [(FLWindow*)[self window] convertBaseToScreen:glyphRect.origin];
+ if (actualRange) *actualRange = aRange;
fl_unlock_function();
return glyphRect;
}
@@ -2033,8 +2462,12 @@ static void q_set_window_title(NSWindow *nsw, const char * name, const char *mi
return 0;
}
+- (NSInteger)windowLevel {
+ return [[self window] level];
+}
+
- (NSInteger)conversationIdentifier {
- return (NSInteger)self;
+ return identifier;
}
@end
@@ -2057,6 +2490,29 @@ void Fl_Window::fullscreen_off_x(int X, int Y, int W, int H) {
}
/*
+ * Initialize the given port for redraw and call the window's flush() to actually draw the content
+ */
+void Fl_X::flush()
+{
+ if (through_drawRect || w->as_gl_window()) {
+ make_current_counts = 1;
+ w->flush();
+ make_current_counts = 0;
+ Fl_X::q_release_context();
+ return;
+ }
+ // have Cocoa immediately redraw the window's view
+ FLView *view = (FLView*)[fl_xid(w) contentView];
+ fl_x_to_redraw = this;
+ [view setNeedsDisplay:YES];
+ // will send the drawRect: message to the window's view after having prepared the adequate NSGraphicsContext
+ [view displayIfNeededIgnoringOpacity];
+ fl_x_to_redraw = NULL;
+}
+
+//bool Fl_X::make_shaped = false;
+
+/*
* go ahead, create that (sub)window
*/
void Fl_X::make(Fl_Window* w)
@@ -2069,8 +2525,9 @@ void Fl_X::make(Fl_Window* w)
x->other_xid = 0;
x->region = 0;
x->subRegion = 0;
- x->cursor = fl_default_cursor;
+ x->cursor = NULL;
x->gc = 0; // stay 0 for Quickdraw; fill with CGContext for Quartz
+ w->set_visible();
Fl_Window *win = w->window();
Fl_X *xo = Fl_X::i(win);
if (xo) {
@@ -2092,7 +2549,7 @@ void Fl_X::make(Fl_Window* w)
}
if (w->as_gl_window()) { // if creating a sub-GL-window
while (win->window()) win = win->window();
- [Fl_X::i(win)->xid setContainsGLsubwindow:YES];
+ [Fl_X::i(win)->xid containsGLsubwindow:YES];
}
fl_show_iconic = 0;
}
@@ -2109,7 +2566,7 @@ void Fl_X::make(Fl_Window* w)
int hp = w->h();
if (w->size_range_set) {
if ( w->minh != w->maxh || w->minw != w->maxw) {
- winstyle |= NSResizableWindowMask;
+ if (w->border()) winstyle |= NSResizableWindowMask;
}
} else {
if (w->resizable()) {
@@ -2117,7 +2574,7 @@ void Fl_X::make(Fl_Window* w)
int minw = o->w(); if (minw > 100) minw = 100;
int minh = o->h(); if (minh > 100) minh = 100;
w->size_range(w->w() - o->w() + minw, w->h() - o->h() + minh, 0, 0);
- winstyle |= NSResizableWindowMask;
+ if (w->border()) winstyle |= NSResizableWindowMask;
} else {
w->size_range(w->w(), w->h(), w->w(), w->h());
}
@@ -2127,18 +2584,17 @@ void Fl_X::make(Fl_Window* w)
if (!fake_X_wm(w, xwm, ywm, bt, bx, by)) {
// menu windows and tooltips
if (w->modal()||w->tooltip_window()) {
- winstyle = NSBorderlessWindowMask;
- winlevel = NSModalPanelWindowLevel;
- } else {
- winstyle = NSBorderlessWindowMask;
+ winlevel = modal_window_level();
}
- } else if (w->modal()) {
+ //winstyle = NSBorderlessWindowMask;
+ }
+ if (w->modal()) {
winstyle &= ~NSMiniaturizableWindowMask;
// winstyle &= ~(NSResizableWindowMask | NSMiniaturizableWindowMask);
- winlevel = NSModalPanelWindowLevel;
+ winlevel = modal_window_level();
}
else if (w->non_modal()) {
- winlevel = NSFloatingWindowLevel;
+ winlevel = non_modal_window_level();
}
if (by+bt) {
@@ -2165,16 +2621,39 @@ void Fl_X::make(Fl_Window* w)
x->other_xid = 0; // room for doublebuffering image map. On OS X this is only used by overlay windows
x->region = 0;
x->subRegion = 0;
- x->cursor = fl_default_cursor;
+ x->cursor = NULL;
x->xidChildren = 0;
x->xidNext = 0;
x->gc = 0;
NSRect crect;
if (w->fullscreen_active()) {
- int sx, sy, sw, sh;
- Fl::screen_xywh(sx, sy, sw, sh, w->x(), w->y(), w->w(), w->h());
- w->resize(sx, sy, sw, sh);
+ int top, bottom, left, right;
+ int sx, sy, sw, sh, X, Y, W, H;
+
+ top = w->fullscreen_screen_top;
+ bottom = w->fullscreen_screen_bottom;
+ left = w->fullscreen_screen_left;
+ right = w->fullscreen_screen_right;
+
+ if ((top < 0) || (bottom < 0) || (left < 0) || (right < 0)) {
+ top = Fl::screen_num(w->x(), w->y(), w->w(), w->h());
+ bottom = top;
+ left = top;
+ right = top;
+ }
+
+ Fl::screen_xywh(sx, sy, sw, sh, top);
+ Y = sy;
+ Fl::screen_xywh(sx, sy, sw, sh, bottom);
+ H = sy + sh - Y;
+ Fl::screen_xywh(sx, sy, sw, sh, left);
+ X = sx;
+ Fl::screen_xywh(sx, sy, sw, sh, right);
+ W = sx + sw - X;
+
+ w->resize(X, Y, W, H);
+
winstyle = NSBorderlessWindowMask;
winlevel = NSStatusWindowLevel;
}
@@ -2188,6 +2667,10 @@ void Fl_X::make(Fl_Window* w)
[cw setFrameOrigin:crect.origin];
[cw setHasShadow:YES];
[cw setAcceptsMouseMovedEvents:YES];
+ if (w->shape_data_) {
+ [cw setOpaque:NO]; // shaped windows must be non opaque
+ [cw setBackgroundColor:[NSColor clearColor]]; // and with transparent background color
+ }
x->xid = cw;
x->w = w; w->i = x;
x->wait_for_expose = 1;
@@ -2195,6 +2678,7 @@ void Fl_X::make(Fl_Window* w)
Fl_X::first = x;
FLView *myview = [[FLView alloc] init];
[cw setContentView:myview];
+ [myview release];
[cw setLevel:winlevel];
q_set_window_title(cw, w->label(), w->iconlabel());
@@ -2212,12 +2696,10 @@ void Fl_X::make(Fl_Window* w)
[cw setAlphaValue:0.97];
}
// Install DnD handlers
- [myview registerForDraggedTypes:[NSArray arrayWithObjects:
- NSStringPboardType, NSFilenamesPboardType, nil]];
+ [myview registerForDraggedTypes:[NSArray arrayWithObjects:utf8_format, NSFilenamesPboardType, nil]];
if ( ! Fl_X::first->next ) {
// if this is the first window, we need to bring the application to the front
- ProcessSerialNumber psn = { 0, kCurrentProcess };
- SetFrontProcess( &psn );
+ [NSApp activateIgnoringOtherApps:YES];
}
if (w->size_range_set) w->size_range_();
@@ -2231,7 +2713,7 @@ void Fl_X::make(Fl_Window* w)
w->set_visible();
if ( w->border() || (!w->modal() && !w->tooltip_window()) ) Fl::handle(FL_FOCUS, w);
Fl::first_window(w);
- [cw setDelegate:[NSApp delegate]];
+ [cw setDelegate:[FLWindowDelegate createOnce]];
if (fl_show_iconic) {
fl_show_iconic = 0;
[cw miniaturize:nil];
@@ -2316,7 +2798,7 @@ void Fl_Window::show() {
labeltype(FL_NO_LABEL);
}
Fl_Tooltip::exit(this);
- if (!shown() || !i) {
+ if (!shown()) {
Fl_X::make(this);
} else {
if ( !parent() ) {
@@ -2388,9 +2870,34 @@ void Fl_Window::resize(int X,int Y,int W,int H) {
/*
* make all drawing go into this window (called by subclass flush() impl.)
+
+ This can be called in 3 different instances:
+
+ 1) When a window is created, resized, or deminiaturized.
+ The system sends the drawRect: message to the window's view after having prepared the current graphics context
+ to draw to this view. Variable through_drawRect is YES, and fl_x_to_redraw is NULL. Processing of drawRect: calls
+ handleUpdateEvent() that calls Fl_X::flush() for the window and its subwindows. Fl_X::flush() calls
+ Fl_Window::flush() that calls Fl_Window::make_current() that only needs to identify the graphics port of the
+ current graphics context. The window's draw() function is then executed.
+
+ 2) At each round of the FLTK event loop.
+ Fl::flush() is called, that calls Fl_X::flush() on each window that needs drawing. Fl_X::flush() sets
+ fl_x_to_redraw to this and sends the displayIfNeededIgnoringOpacity message to the window's view.
+ This message makes the system prepare the current graphics context adequately for drawing to this view, and
+ send it the drawRect: message which sets through_drawRect to YES. Processing of the drawRect: message calls
+ Fl_X::flush() for the window which proceeds as in 1) above.
+
+ 3) An FLTK application can call Fl_Window::make_current() at any time before it draws to a window.
+ This occurs for instance in the idle callback function of the mandelbrot test program. Variable through_drawRect is NO,
+ so Fl_Window::make_current() creates a new graphics context adequate for the window.
+ Subsequent drawing requests go to this window. CAUTION: it's not possible to call Fl::wait(), Fl::check()
+ nor Fl::ready() while in the draw() function of a widget. Use an idle callback instead.
+
*/
void Fl_Window::make_current()
{
+ if (make_current_counts > 1) return;
+ if (make_current_counts) make_current_counts++;
Fl_X::q_release_context();
fl_window = i->xid;
current_ = this;
@@ -2404,12 +2911,9 @@ void Fl_Window::make_current()
yp += win->y();
win = (Fl_Window*)win->window();
}
-
- NSView *current_focus = [NSView focusView];
- // sometimes current_focus is set to a non-FLTK view: don't touch that
- if ( [current_focus isKindOfClass:[FLView class]] ) [current_focus unlockFocus];
- [[i->xid contentView] lockFocus];
- i->gc = (CGContextRef)[[NSGraphicsContext currentContext] graphicsPort];
+ NSGraphicsContext *nsgc = through_drawRect ? [NSGraphicsContext currentContext] :
+ [NSGraphicsContext graphicsContextWithWindow:fl_window];
+ i->gc = (CGContextRef)[nsgc graphicsPort];
fl_gc = i->gc;
Fl_Region fl_window_region = XRectangleRegion(0,0,w(),h());
if ( ! this->window() ) {
@@ -2477,7 +2981,8 @@ void Fl_X::q_clear_clipping() {
void Fl_X::q_release_context(Fl_X *x) {
if (x && x->gc!=fl_gc) return;
if (!fl_gc) return;
- CGContextRestoreGState(fl_gc); // matches the CGContextSaveGState of make_current
+ CGContextRestoreGState(fl_gc); // KEEP IT: matches the CGContextSaveGState of make_current
+ CGContextFlush(fl_gc);
fl_gc = 0;
#if defined(FLTK_USE_CAIRO)
if (Fl::cairo_autolink_context()) Fl::cairo_make_current((Fl_Window*) 0); // capture gc changes automatically to update the cairo context adequately
@@ -2514,35 +3019,55 @@ static void convert_crlf(char * s, size_t len)
}
// fltk 1.3 clipboard support constant definitions:
-const CFStringRef flavorNames[] = {
- CFSTR("public.utf16-plain-text"),
- CFSTR("public.utf8-plain-text"),
- CFSTR("com.apple.traditional-mac-plain-text") };
-const CFStringEncoding encodings[] = {
- kCFStringEncodingUnicode,
- kCFStringEncodingUTF8,
- kCFStringEncodingMacRoman};
-const size_t handledFlavorsCount = sizeof(encodings)/sizeof(CFStringEncoding);
+static NSString *calc_utf8_format(void)
+{
+#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_6
+#define NSPasteboardTypeString @"public.utf8-plain-text"
+#endif
+ if (fl_mac_os_version >= 100600) return NSPasteboardTypeString;
+ return NSStringPboardType;
+}
// clipboard variables definitions :
-char *fl_selection_buffer[2];
-int fl_selection_length[2];
+char *fl_selection_buffer[2] = {NULL, NULL};
+int fl_selection_length[2] = {0, 0};
static int fl_selection_buffer_length[2];
-static PasteboardRef myPasteboard = 0;
-static void allocatePasteboard() {
- if (!myPasteboard)
- PasteboardCreate(kPasteboardClipboard, &myPasteboard);
+static PasteboardRef allocatePasteboard(void)
+{
+ PasteboardRef clip;
+ PasteboardCreate(kPasteboardClipboard, &clip); // requires Mac OS 10.3
+ return clip;
}
+static PasteboardRef myPasteboard = allocatePasteboard();
+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;
+
+ flags = PasteboardSynchronize(myPasteboard); // requires Mac OS 10.3
+
+ if (!(flags & kPasteboardModified))
+ return;
+ if (flags & kPasteboardClientIsOwner)
+ return;
+
+ fl_trigger_clipboard_notify(1);
+}
/*
* create a selection
- * owner: widget that created the selection
* stuff: pointer to selected data
- * size of selected data
+ * len: size of selected data
+ * type: always "plain/text" for now
*/
-void Fl::copy(const char *stuff, int len, int clipboard) {
+void Fl::copy(const char *stuff, int len, int clipboard, const char *type) {
if (!stuff || len<0) return;
if (len+1 > fl_selection_buffer_length[clipboard]) {
delete[] fl_selection_buffer[clipboard];
@@ -2553,84 +3078,180 @@ void Fl::copy(const char *stuff, int len, int clipboard) {
fl_selection_buffer[clipboard][len] = 0; // needed for direct paste
fl_selection_length[clipboard] = len;
if (clipboard) {
- allocatePasteboard();
- OSStatus err = PasteboardClear(myPasteboard);
- if (err!=noErr) return; // clear did not work, maybe not owner of clipboard.
- PasteboardSynchronize(myPasteboard);
CFDataRef text = CFDataCreate(kCFAllocatorDefault, (UInt8*)fl_selection_buffer[1], len);
if (text==NULL) return; // there was a pb creating the object, abort.
- err=PasteboardPutItemFlavor(myPasteboard, (PasteboardItemID)1, CFSTR("public.utf8-plain-text"), text, 0);
+ NSPasteboard *clip = [NSPasteboard generalPasteboard];
+ [clip declareTypes:[NSArray arrayWithObject:utf8_format] owner:nil];
+ [clip setData:(NSData*)text forType:utf8_format];
CFRelease(text);
}
}
+static int get_plain_text_from_clipboard(char **buffer, int previous_length)
+{
+ NSInteger length = 0;
+ NSPasteboard *clip = [NSPasteboard generalPasteboard];
+ NSString *found = [clip availableTypeFromArray:[NSArray arrayWithObjects:utf8_format, @"public.utf16-plain-text", @"com.apple.traditional-mac-plain-text", nil]];
+ if (found) {
+ NSData *data = [clip dataForType:found];
+ if (data) {
+ NSInteger len;
+ char *aux_c = NULL;
+ if (![found isEqualToString:utf8_format]) {
+ NSString *auxstring;
+ auxstring = (NSString *)CFStringCreateWithBytes(NULL,
+ (const UInt8*)[data bytes],
+ [data length],
+ [found isEqualToString:@"public.utf16-plain-text"] ? kCFStringEncodingUnicode : kCFStringEncodingMacRoman,
+ false);
+ aux_c = strdup([auxstring UTF8String]);
+ [auxstring release];
+ len = strlen(aux_c) + 1;
+ }
+ else len = [data length] + 1;
+ if ( len >= previous_length ) {
+ length = len;
+ delete[] *buffer;
+ *buffer = new char[len];
+ }
+ if (![found isEqualToString:utf8_format]) {
+ strcpy(*buffer, aux_c);
+ free(aux_c);
+ }
+ else {
+ [data getBytes:*buffer];
+ }
+ (*buffer)[len - 1] = 0;
+ length = len - 1;
+ convert_crlf(*buffer, len - 1); // turn all \r characters into \n:
+ Fl::e_clipboard_type = Fl::clipboard_plain_text;
+ }
+ }
+ return length;
+}
+
+static Fl_Image* get_image_from_clipboard()
+{
+ Fl_RGB_Image *image = NULL;
+ uchar *imagedata;
+ NSBitmapImageRep *bitmap;
+ NSPasteboard *clip = [NSPasteboard generalPasteboard];
+ NSArray *present = [clip types]; // types in pasteboard in order of decreasing preference
+ NSArray *possible = [NSArray arrayWithObjects:@"com.adobe.pdf", @"public.tiff", @"com.apple.pict", nil];
+ NSString *found = nil;
+ NSUInteger rank;
+ for (rank = 0; rank < [present count]; rank++) { // find first of possible types present in pasteboard
+ for (NSUInteger i = 0; i < [possible count]; i++) {
+ if ([[present objectAtIndex:rank] isEqualToString:[possible objectAtIndex:i]]) {
+ found = [present objectAtIndex:rank];
+ goto after_loop;
+ }
+ }
+ }
+after_loop:
+ if (found) {
+ NSData *data = [clip dataForType:found];
+ if (data) {
+ if ([found isEqualToString:@"public.tiff"]) {
+ bitmap = [NSBitmapImageRep imageRepWithData:data];
+ int bpp = [bitmap bytesPerPlane];
+ int bpr = [bitmap bytesPerRow];
+ int depth = [bitmap samplesPerPixel], w = bpr/depth, h = bpp/bpr;
+ imagedata = new uchar[w * h * depth];
+ memcpy(imagedata, [bitmap bitmapData], w * h * depth);
+ image = new Fl_RGB_Image(imagedata, w, h, depth);
+ image->alloc_array = 1;
+ }
+ else if ([found isEqualToString:@"com.adobe.pdf"] || [found isEqualToString:@"com.apple.pict"]) {
+ NSRect rect;
+ NSImageRep *vectorial;
+ NSAffineTransform *dilate = [NSAffineTransform transform];
+ if ([found isEqualToString:@"com.adobe.pdf"] ) {
+ vectorial = [NSPDFImageRep imageRepWithData:data];
+ rect = [(NSPDFImageRep*)vectorial bounds]; // in points = 1/72 inch
+ Fl_Window *win = Fl::first_window();
+ int screen_num = win ? Fl::screen_num(win->x(), win->y(), win->w(), win->h()) : 0;
+ float hr, vr;
+ Fl::screen_dpi(hr, vr, screen_num); // 1 inch = hr pixels = 72 points -> hr/72 pixel/point
+ CGFloat scale = hr/72;
+ [dilate scaleBy:scale];
+ rect.size.width *= scale;
+ rect.size.height *= scale;
+ rect = NSIntegralRect(rect);
+ }
+ else {
+ vectorial = [NSPICTImageRep imageRepWithData:data];
+ rect = [(NSPICTImageRep*)vectorial boundingBox]; // in pixel, no scaling required
+ }
+ imagedata = new uchar[(int)(rect.size.width * rect.size.height) * 4];
+ memset(imagedata, -1, (int)(rect.size.width * rect.size.height) * 4);
+ bitmap = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:&imagedata
+ pixelsWide:rect.size.width
+ pixelsHigh:rect.size.height
+ bitsPerSample:8
+ samplesPerPixel:3
+ hasAlpha:NO
+ isPlanar:NO
+ colorSpaceName:NSDeviceRGBColorSpace
+ bytesPerRow:rect.size.width*4
+ bitsPerPixel:32];
+ NSDictionary *dict = [NSDictionary dictionaryWithObject:bitmap
+ forKey:NSGraphicsContextDestinationAttributeName];
+ NSGraphicsContext *oldgc = [NSGraphicsContext currentContext];
+ [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithAttributes:dict]];
+ [dilate concat];
+ [vectorial draw];
+ [NSGraphicsContext setCurrentContext:oldgc];
+ [bitmap release];
+ image = new Fl_RGB_Image(imagedata, rect.size.width, rect.size.height, 4);
+ image->alloc_array = 1;
+ }
+ Fl::e_clipboard_type = Fl::clipboard_image;
+ }
+ }
+ return image;
+}
+
// Call this when a "paste" operation happens:
-void Fl::paste(Fl_Widget &receiver, int clipboard) {
+void Fl::paste(Fl_Widget &receiver, int clipboard, const char *type) {
+ if (type[0] == 0) type = Fl::clipboard_plain_text;
if (clipboard) {
- // see if we own the selection, if not go get it:
- fl_selection_length[1] = 0;
- OSStatus err = noErr;
- Boolean found = false;
- CFDataRef flavorData = NULL;
- CFStringEncoding encoding = 0;
-
- allocatePasteboard();
- PasteboardSynchronize(myPasteboard);
- ItemCount nFlavor = 0, i, j;
- err = PasteboardGetItemCount(myPasteboard, &nFlavor);
- if (err==noErr) {
- for (i=1; i<=nFlavor; i++) {
- PasteboardItemID itemID = 0;
- CFArrayRef flavorTypeArray = NULL;
- found = false;
- err = PasteboardGetItemIdentifier(myPasteboard, i, &itemID);
- if (err!=noErr) continue;
- err = PasteboardCopyItemFlavors(myPasteboard, itemID, &flavorTypeArray);
- if (err!=noErr) {
- if (flavorTypeArray) {CFRelease(flavorTypeArray); flavorTypeArray = NULL;}
- continue;
- }
- CFIndex flavorCount = CFArrayGetCount(flavorTypeArray);
- for (j = 0; j < handledFlavorsCount; j++) {
- for (CFIndex flavorIndex=0; flavorIndex<flavorCount; flavorIndex++) {
- CFStringRef flavorType = (CFStringRef)CFArrayGetValueAtIndex(flavorTypeArray, flavorIndex);
- if (UTTypeConformsTo(flavorType, flavorNames[j])) {
- err = PasteboardCopyItemFlavorData( myPasteboard, itemID, flavorNames[j], &flavorData );
- if (err != noErr) continue;
- encoding = encodings[j];
- found = true;
- break;
- }
- }
- if (found) break;
- }
- if (flavorTypeArray) {CFRelease(flavorTypeArray); flavorTypeArray = NULL;}
- if (found) break;
+ Fl::e_clipboard_type = "";
+ if (strcmp(type, Fl::clipboard_plain_text) == 0) {
+ fl_selection_length[1] = get_plain_text_from_clipboard( &fl_selection_buffer[1], fl_selection_length[1]);
}
- if (found) {
- CFIndex len = CFDataGetLength(flavorData);
- CFStringRef mycfs = CFStringCreateWithBytes(NULL, CFDataGetBytePtr(flavorData), len, encoding, false);
- CFRelease(flavorData);
- len = CFStringGetMaximumSizeForEncoding(CFStringGetLength(mycfs), kCFStringEncodingUTF8) + 1;
- if ( len >= fl_selection_buffer_length[1] ) {
- fl_selection_buffer_length[1] = len;
- delete[] fl_selection_buffer[1];
- fl_selection_buffer[1] = new char[len];
- }
- CFStringGetCString(mycfs, fl_selection_buffer[1], len, kCFStringEncodingUTF8);
- CFRelease(mycfs);
- len = strlen(fl_selection_buffer[1]);
- fl_selection_length[1] = len;
- convert_crlf(fl_selection_buffer[1],len); // turn all \r characters into \n:
+ else if (strcmp(type, Fl::clipboard_image) == 0) {
+ Fl::e_clipboard_data = get_image_from_clipboard( );
+ if (Fl::e_clipboard_data) {
+ int done = receiver.handle(FL_PASTE);
+ Fl::e_clipboard_type = "";
+ if (done == 0) {
+ delete (Fl_Image*)Fl::e_clipboard_data;
+ Fl::e_clipboard_data = NULL;
+ }
}
- }
+ return;
+ }
+ else
+ fl_selection_length[1] = 0;
}
Fl::e_text = fl_selection_buffer[clipboard];
Fl::e_length = fl_selection_length[clipboard];
- if (!Fl::e_text) Fl::e_text = (char *)"";
+ if (!Fl::e_length) Fl::e_text = (char *)"";
receiver.handle(FL_PASTE);
}
+int Fl::clipboard_contains(const char *type) {
+ NSString *found = nil;
+ if (strcmp(type, Fl::clipboard_plain_text) == 0) {
+ found = [[NSPasteboard generalPasteboard] availableTypeFromArray:[NSArray arrayWithObjects:utf8_format, @"public.utf16-plain-text", @"com.apple.traditional-mac-plain-text", nil]];
+ }
+ else if (strcmp(type, Fl::clipboard_image) == 0) {
+ found = [[NSPasteboard generalPasteboard] availableTypeFromArray:[NSArray arrayWithObjects:@"public.tiff", @"com.adobe.pdf", @"com.apple.pict", nil]];
+ }
+ return found != nil;
+}
+
int Fl_X::unlink(Fl_X *start) {
if (start) {
Fl_X *pc = start;
@@ -2674,11 +3295,6 @@ void Fl_X::relink(Fl_Window *w, Fl_Window *wp) {
void Fl_X::destroy() {
// subwindows share their xid with their parent window, so should not close it
if (!subwindow && w && !w->parent() && xid) {
- NSView *topview = [xid contentView];
- if ( [NSView focusView] == topview ) {
- [topview unlockFocus];
- }
- [topview release];
[xid close];
}
}
@@ -2692,6 +3308,10 @@ void Fl_X::map() {
Fl_X::relink(w, w->window() );
w->redraw();
}
+ if (cursor) {
+ [(NSCursor*)cursor release];
+ cursor = NULL;
+ }
}
void Fl_X::unmap() {
@@ -2780,84 +3400,152 @@ void Fl_X::collapse() {
static NSImage *CGBitmapContextToNSImage(CGContextRef c)
// the returned NSImage is autoreleased
{
+ NSImage* image;
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6
+ if (fl_mac_os_version >= 100600) {
+ CGImageRef cgimg = CGBitmapContextCreateImage(c); // requires 10.4
+ image = [[NSImage alloc] initWithCGImage:cgimg size:NSZeroSize]; // requires 10.6
+ CFRelease(cgimg);
+ }
+ else
+#endif
+ {
+ unsigned char *pdata = (unsigned char *)CGBitmapContextGetData(c);
+ NSBitmapImageRep *imagerep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:&pdata
+ pixelsWide:CGBitmapContextGetWidth(c)
+ pixelsHigh:CGBitmapContextGetHeight(c)
+ bitsPerSample:8
+ samplesPerPixel:4
+ hasAlpha:YES
+ isPlanar:NO
+ colorSpaceName:NSDeviceRGBColorSpace
+ bytesPerRow:CGBitmapContextGetBytesPerRow(c)
+ bitsPerPixel:CGBitmapContextGetBitsPerPixel(c)];
+ image = [[NSImage alloc] initWithData: [imagerep TIFFRepresentation]];
+ [imagerep release];
+ }
+ return [image autorelease];
+}
+
+
+CFDataRef Fl_X::CGBitmapContextToTIFF(CGContextRef c)
+{ // the returned value is autoreleased
unsigned char *pdata = (unsigned char *)CGBitmapContextGetData(c);
NSBitmapImageRep *imagerep = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:&pdata
- pixelsWide:CGBitmapContextGetWidth(c)
- pixelsHigh:CGBitmapContextGetHeight(c)
- bitsPerSample:8
- samplesPerPixel:4
- hasAlpha:YES
- isPlanar:NO
- colorSpaceName:NSDeviceRGBColorSpace
- bytesPerRow:CGBitmapContextGetBytesPerRow(c)
- bitsPerPixel:CGBitmapContextGetBitsPerPixel(c)];
- NSImage* image = [[NSImage alloc] initWithData: [imagerep TIFFRepresentation]];
+ pixelsWide:CGBitmapContextGetWidth(c)
+ pixelsHigh:CGBitmapContextGetHeight(c)
+ bitsPerSample:8
+ samplesPerPixel:3
+ hasAlpha:NO
+ isPlanar:NO
+ colorSpaceName:NSDeviceRGBColorSpace
+ bytesPerRow:CGBitmapContextGetBytesPerRow(c)
+ bitsPerPixel:CGBitmapContextGetBitsPerPixel(c)];
+ NSData* tiff = [imagerep TIFFRepresentation];
[imagerep release];
- return [image autorelease];
+ return (CFDataRef)tiff;
}
-static NSCursor *PrepareCursor(NSCursor *cursor, CGContextRef (*f)() )
+int Fl_X::set_cursor(Fl_Cursor c)
{
- 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];
+ if (cursor) {
+ [(NSCursor*)cursor release];
+ cursor = NULL;
}
- 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;
+ 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;
}
- [icrsr set];
- cursor = icrsr;
+
+ [(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;
}
@interface FLaboutItemTarget : NSObject
@@ -2879,7 +3567,7 @@ void Fl_X::set_cursor(Fl_Cursor c)
}
//#include <FL/Fl_PostScript.H>
- (void)printPanel
-{
+{
Fl_Printer printer;
//Fl_PostScript_File_Device printer;
int w, h, ww, wh;
@@ -2920,24 +3608,26 @@ static void createAppleMenu(void)
static BOOL donethat = NO;
if (donethat) return;
donethat = YES;
- NSMenu *mainmenu, *services, *appleMenu;
+ NSMenu *mainmenu, *services = nil, *appleMenu;
NSMenuItem *menuItem;
NSString *title;
-
- NSString *nsappname = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleName"];
+
+ SEL infodictSEL = (fl_mac_os_version >= 100200 ? @selector(localizedInfoDictionary) : @selector(infoDictionary));
+ NSString *nsappname = [[[NSBundle mainBundle] performSelector:infodictSEL] objectForKey:@"CFBundleName"];
if (nsappname == nil)
nsappname = [[NSProcessInfo processInfo] processName];
appleMenu = [[NSMenu alloc] initWithTitle:@""];
/* Add menu items */
- title = [[NSString stringWithUTF8String:Fl_Mac_App_Menu::about] stringByAppendingString:nsappname];
+ title = [NSString stringWithFormat:NSLocalizedString([NSString stringWithUTF8String:Fl_Mac_App_Menu::about],nil), nsappname];
menuItem = [appleMenu addItemWithTitle:title action:@selector(showPanel) keyEquivalent:@""];
FLaboutItemTarget *about = [[FLaboutItemTarget alloc] init];
[menuItem setTarget:about];
[appleMenu addItem:[NSMenuItem separatorItem]];
// Print front window
- if (strlen(Fl_Mac_App_Menu::print) > 0) {
+ title = NSLocalizedString([NSString stringWithUTF8String:Fl_Mac_App_Menu::print], nil);
+ if ([title length] > 0) {
menuItem = [appleMenu
- addItemWithTitle:[NSString stringWithUTF8String:Fl_Mac_App_Menu::print]
+ addItemWithTitle:title
action:@selector(printPanel)
keyEquivalent:@""];
[menuItem setTarget:about];
@@ -2945,35 +3635,37 @@ static void createAppleMenu(void)
[menuItem setEnabled:YES];
[appleMenu addItem:[NSMenuItem separatorItem]];
}
- // Services Menu
- services = [[NSMenu alloc] init];
- menuItem = [appleMenu
- addItemWithTitle:[NSString stringWithUTF8String:Fl_Mac_App_Menu::services]
- action:nil
- keyEquivalent:@""];
- [appleMenu setSubmenu:services forItem:menuItem];
- [appleMenu addItem:[NSMenuItem separatorItem]];
- // Hide AppName
- title = [[NSString stringWithUTF8String:Fl_Mac_App_Menu::hide] stringByAppendingString:nsappname];
- [appleMenu addItemWithTitle:title
- action:@selector(hide:)
+ if (fl_mac_os_version >= 100400) { // services+hide+quit already in menu in OS 10.3
+ // Services Menu
+ services = [[NSMenu alloc] init];
+ menuItem = [appleMenu
+ addItemWithTitle:NSLocalizedString([NSString stringWithUTF8String:Fl_Mac_App_Menu::services], nil)
+ action:nil
+ keyEquivalent:@""];
+ [appleMenu setSubmenu:services forItem:menuItem];
+ [appleMenu addItem:[NSMenuItem separatorItem]];
+ // Hide AppName
+ title = [NSString stringWithFormat:NSLocalizedString([NSString stringWithUTF8String:Fl_Mac_App_Menu::hide],nil), nsappname];
+ [appleMenu addItemWithTitle:title
+ action:@selector(hide:)
+ keyEquivalent:@"h"];
+ // Hide Others
+ menuItem = [appleMenu
+ addItemWithTitle:NSLocalizedString([NSString stringWithUTF8String:Fl_Mac_App_Menu::hide_others] , nil)
+ action:@selector(hideOtherApplications:)
keyEquivalent:@"h"];
- // Hide Others
- menuItem = [appleMenu
- addItemWithTitle:[NSString stringWithUTF8String:Fl_Mac_App_Menu::hide_others]
- action:@selector(hideOtherApplications:)
- keyEquivalent:@"h"];
- [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)];
- // Show All
- [appleMenu addItemWithTitle:[NSString stringWithUTF8String:Fl_Mac_App_Menu::show]
- action:@selector(unhideAllApplications:) keyEquivalent:@""];
- [appleMenu addItem:[NSMenuItem separatorItem]];
- // Quit AppName
- title = [[NSString stringWithUTF8String:Fl_Mac_App_Menu::quit]
- stringByAppendingString:nsappname];
- [appleMenu addItemWithTitle:title
- action:@selector(terminate:)
- keyEquivalent:@"q"];
+ [menuItem setKeyEquivalentModifierMask:(NSAlternateKeyMask|NSCommandKeyMask)];
+ // Show All
+ [appleMenu addItemWithTitle:NSLocalizedString([NSString stringWithUTF8String:Fl_Mac_App_Menu::show] , nil)
+ action:@selector(unhideAllApplications:) keyEquivalent:@""];
+ [appleMenu addItem:[NSMenuItem separatorItem]];
+ // Quit AppName
+ title = [NSString stringWithFormat:NSLocalizedString([NSString stringWithUTF8String:Fl_Mac_App_Menu::quit] , nil),
+ nsappname];
+ [appleMenu addItemWithTitle:title
+ action:@selector(terminate:)
+ keyEquivalent:@"q"];
+ }
/* Put menu into the menubar */
menuItem = [[NSMenuItem alloc] initWithTitle:@"" action:nil keyEquivalent:@""];
[menuItem setSubmenu:appleMenu];
@@ -2984,224 +3676,16 @@ static void createAppleMenu(void)
// to avoid compiler warning raised by use of undocumented setAppleMenu :
[NSApp performSelector:@selector(setAppleMenu:) withObject:appleMenu];
}
- [NSApp setServicesMenu:services];
[NSApp setMainMenu:mainmenu];
- [services release];
+ if (services) {
+ [NSApp setServicesMenu:services];
+ [services release];
+ }
[mainmenu release];
[appleMenu release];
[menuItem release];
}
-@interface FLMenuItem : NSMenuItem {
-}
-- (void) doCallback:(id)unused;
-- (void) directCallback:(id)unused;
-- (const Fl_Menu_Item*) getFlItem;
-@end
-@implementation FLMenuItem
-- (const Fl_Menu_Item*) getFlItem
-{
- return *(const Fl_Menu_Item **)[(NSData*)[self representedObject] bytes];
-}
-- (void) doCallback:(id)unused
-{
- fl_lock_function();
- const Fl_Menu_Item *item = [self getFlItem];
- fl_sys_menu_bar->picked(item);
- if ( item->flags & FL_MENU_TOGGLE ) { // update the menu toggle symbol
- [self setState:(item->value() ? NSOnState : NSOffState)];
- }
- else if ( item->flags & FL_MENU_RADIO ) { // update the menu radio symbols
- NSMenu* menu = [self menu];
- NSInteger flRank = [menu indexOfItem:self];
- NSInteger last = [menu numberOfItems] - 1;
- int from = flRank;
- while(from > 0) {
- if ([[menu itemAtIndex:from-1] isSeparatorItem]) break;
- item = [(FLMenuItem*)[menu itemAtIndex:from-1] getFlItem];
- if ( !(item->flags & FL_MENU_RADIO) ) break;
- from--;
- }
- int to = flRank;
- while (to < last) {
- if ([[menu itemAtIndex:to+1] isSeparatorItem]) break;
- item = [(FLMenuItem*)[menu itemAtIndex:to+1] getFlItem];
- if (!(item->flags & FL_MENU_RADIO)) break;
- to++;
- }
- for(int i = from; i <= to; i++) {
- NSMenuItem *nsitem = [menu itemAtIndex:i];
- [nsitem setState:(nsitem != self ? NSOffState : NSOnState)];
- }
- }
- fl_unlock_function();
-}
-- (void) directCallback:(id)unused
-{
- fl_lock_function();
- Fl_Menu_Item *item = (Fl_Menu_Item *)[(NSData*)[self representedObject] bytes];
- if ( item && item->callback() ) item->do_callback(NULL);
- fl_unlock_function();
-}
-@end
-
-void fl_mac_set_about( Fl_Callback *cb, void *user_data, int shortcut)
-{
- fl_open_display();
- Fl_Menu_Item aboutItem;
- memset(&aboutItem, 0, sizeof(Fl_Menu_Item));
- aboutItem.callback(cb);
- aboutItem.user_data(user_data);
- aboutItem.shortcut(shortcut);
- NSMenu *appleMenu = [[[NSApp mainMenu] itemAtIndex:0] submenu];
- CFStringRef cfname = CFStringCreateCopy(NULL, (CFStringRef)[[appleMenu itemAtIndex:0] title]);
- [appleMenu removeItemAtIndex:0];
- FLMenuItem *item = [[[FLMenuItem alloc] initWithTitle:(NSString*)cfname
- action:@selector(directCallback:)
- keyEquivalent:@""] autorelease];
- if (aboutItem.shortcut()) {
- Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::setKeyEquivalent, item, aboutItem.shortcut() & 0xff);
- Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::setKeyEquivalentModifierMask, item, aboutItem.shortcut() );
- }
- NSData *pointer = [NSData dataWithBytes:&aboutItem length:sizeof(Fl_Menu_Item)];
- [item setRepresentedObject:pointer];
- [appleMenu insertItem:item atIndex:0];
- CFRelease(cfname);
- [item setTarget:item];
-}
-
-static char *remove_ampersand(const char *s)
-{
- char *ret = strdup(s);
- const char *p = s;
- char *q = ret;
- while(*p != 0) {
- if (p[0]=='&') {
- if (p[1]=='&') {
- *q++ = '&'; p+=2;
- } else {
- p++;
- }
- } else {
- *q++ = *p++;
- }
- }
- *q = 0;
- return ret;
-}
-
-void *Fl_Sys_Menu_Bar::doMenuOrItemOperation(Fl_Sys_Menu_Bar::menuOrItemOperation operation, ...)
-/* these operations apply to menus, submenus, or menu items
- */
-{
- NSAutoreleasePool *localPool;
- localPool = [[NSAutoreleasePool alloc] init];
- NSMenu *menu;
- NSMenuItem *item;
- int value;
- void *pter;
- void *retval = NULL;
- va_list ap;
- va_start(ap, operation);
-
- if (operation == Fl_Sys_Menu_Bar::itemAtIndex) { // arguments: NSMenu*, int. Returns the item
- menu = va_arg(ap, NSMenu*);
- value = va_arg(ap, int);
- retval = (void *)[menu itemAtIndex:value];
- }
- else if (operation == Fl_Sys_Menu_Bar::setKeyEquivalent) { // arguments: NSMenuItem*, int
- item = va_arg(ap, NSMenuItem*);
- value = va_arg(ap, int);
- char key = value;
- NSString *equiv = [[NSString alloc] initWithBytes:&key length:1 encoding:NSASCIIStringEncoding];
- [item setKeyEquivalent:equiv];
- [equiv release];
- }
- else if (operation == Fl_Sys_Menu_Bar::setKeyEquivalentModifierMask) { // arguments: NSMenuItem*, int
- item = va_arg(ap, NSMenuItem*);
- value = va_arg(ap, int);
- NSUInteger macMod = 0;
- if ( value & FL_META ) macMod = NSCommandKeyMask;
- if ( value & FL_SHIFT || isupper(value) ) macMod |= NSShiftKeyMask;
- if ( value & FL_ALT ) macMod |= NSAlternateKeyMask;
- if ( value & FL_CTRL ) macMod |= NSControlKeyMask;
- [item setKeyEquivalentModifierMask:macMod];
- }
- else if (operation == Fl_Sys_Menu_Bar::setState) { // arguments: NSMenuItem*, int
- item = va_arg(ap, NSMenuItem*);
- value = va_arg(ap, int);
- [item setState:(value ? NSOnState : NSOffState)];
- }
- else if (operation == Fl_Sys_Menu_Bar::initWithTitle) { // arguments: const char*title. Returns the newly created menu
- // creates a new (sub)menu
- char *ts = remove_ampersand(va_arg(ap, char *));
- CFStringRef title = CFStringCreateWithCString(NULL, ts, kCFStringEncodingUTF8);
- free(ts);
- NSMenu *menu = [[NSMenu alloc] initWithTitle:(NSString*)title];
- CFRelease(title);
- [menu setAutoenablesItems:NO];
- retval = (void *)menu;
- }
- else if (operation == Fl_Sys_Menu_Bar::numberOfItems) { // arguments: NSMenu *menu, int *pcount
- // upon return, *pcount is set to menu's item count
- menu = va_arg(ap, NSMenu*);
- pter = va_arg(ap, void *);
- *(int*)pter = [menu numberOfItems];
- }
- else if (operation == Fl_Sys_Menu_Bar::setSubmenu) { // arguments: NSMenuItem *item, NSMenu *menu
- // sets 'menu' as submenu attached to 'item'
- item = va_arg(ap, NSMenuItem*);
- menu = va_arg(ap, NSMenu*);
- [item setSubmenu:menu];
- [menu release];
- }
- else if (operation == Fl_Sys_Menu_Bar::setEnabled) { // arguments: NSMenuItem*, int
- item = va_arg(ap, NSMenuItem*);
- value = va_arg(ap, int);
- [item setEnabled:(value ? YES : NO)];
- }
- else if (operation == Fl_Sys_Menu_Bar::addSeparatorItem) { // arguments: NSMenu*
- menu = va_arg(ap, NSMenu*);
- [menu addItem:[NSMenuItem separatorItem]];
- }
- else if (operation == Fl_Sys_Menu_Bar::setTitle) { // arguments: NSMenuItem*, const char *
- item = va_arg(ap, NSMenuItem*);
- char *ts = remove_ampersand(va_arg(ap, char *));
- CFStringRef title = CFStringCreateWithCString(NULL, ts, kCFStringEncodingUTF8);
- free(ts);
- [item setTitle:(NSString*)title];
- CFRelease(title);
- }
- else if (operation == Fl_Sys_Menu_Bar::removeItem) { // arguments: NSMenu*, int
- menu = va_arg(ap, NSMenu*);
- value = va_arg(ap, int);
- [menu removeItem:[menu itemAtIndex:value]];
- }
- else if (operation == Fl_Sys_Menu_Bar::addNewItem) { // arguments: NSMenu *menu, Fl_Menu_Item* mitem, int *prank
- // creates a new menu item at the end of 'menu'
- // attaches the item of fl_sys_menu_bar to it
- // upon return, puts the rank (counted in NSMenu) of the new item in *prank unless prank is NULL
- menu = va_arg(ap, NSMenu*);
- Fl_Menu_Item *mitem = va_arg(ap, Fl_Menu_Item *);
- int *prank = va_arg(ap, int*);
- char *name = remove_ampersand(mitem->label());
- CFStringRef cfname = CFStringCreateWithCString(NULL, name, kCFStringEncodingUTF8);
- free(name);
- FLMenuItem *item = [[FLMenuItem alloc] initWithTitle:(NSString*)cfname
- action:@selector(doCallback:)
- keyEquivalent:@""];
- NSData *pointer = [NSData dataWithBytes:&mitem length:sizeof(Fl_Menu_Item*)];
- [item setRepresentedObject:pointer];
- [menu addItem:item];
- CFRelease(cfname);
- [item setTarget:item];
- if (prank != NULL) *prank = [menu indexOfItem:item];
- [item release];
- }
- va_end(ap);
- [localPool release];
- return retval;
-}
void Fl_X::set_key_window()
{
@@ -3215,7 +3699,7 @@ static NSImage *imageFromText(const char *text, int *pwidth, int *pheight)
fl_font(FL_HELVETICA, 10);
p = text;
int nl = 0;
- while((q=strchr(p, '\n')) != NULL) {
+ while(nl < 100 && (q=strchr(p, '\n')) != NULL) {
nl++;
w2 = int(fl_width(p, q - p));
if (w2 > width) width = w2;
@@ -3256,14 +3740,30 @@ static NSImage *imageFromText(const char *text, int *pwidth, int *pheight)
static NSImage *defaultDragImage(int *pwidth, int *pheight)
{
- const int width = 16, height = 16;
+ const int version_threshold = 100700;
+ int width, height;
+ if (fl_mac_os_version >= version_threshold) {
+ width = 50; height = 40;
+ }
+ else {
+ width = 16; height = 16;
+ }
Fl_Offscreen off = Fl_Quartz_Graphics_Driver::create_offscreen_with_alpha(width, height);
fl_begin_offscreen(off);
- CGContextSetRGBFillColor( (CGContextRef)off, 0,0,0,0);
- fl_rectf(0,0,width,height);
- CGContextSetRGBStrokeColor( (CGContextRef)off, 0,0,0,0.6);
- fl_rect(0,0,width,height);
- fl_rect(2,2,width-4,height-4);
+ if (fl_mac_os_version >= version_threshold) {
+ fl_font(FL_HELVETICA, 20);
+ fl_color(FL_BLACK);
+ char str[4];
+ int l = fl_utf8encode(0x1F69A, str); // the "Delivery truck" Unicode character from "Apple Color Emoji" font
+ fl_draw(str, l, 1, 16);
+ }
+ else { // draw two squares
+ CGContextSetRGBFillColor( (CGContextRef)off, 0,0,0,0);
+ fl_rectf(0,0,width,height);
+ CGContextSetRGBStrokeColor( (CGContextRef)off, 0,0,0,0.6);
+ fl_rect(0,0,width,height);
+ fl_rect(2,2,width-4,height-4);
+ }
fl_end_offscreen();
NSImage* image = CGBitmapContextToNSImage( (CGContextRef)off );
fl_delete_offscreen( off );
@@ -3279,16 +3779,11 @@ int Fl::dnd(void)
NSAutoreleasePool *localPool;
localPool = [[NSAutoreleasePool alloc] init];
NSPasteboard *mypasteboard = [NSPasteboard pasteboardWithName:NSDragPboard];
- [mypasteboard declareTypes:[NSArray arrayWithObjects:@"public.utf8-plain-text", nil] owner:nil];
- [mypasteboard setData:(NSData*)text forType:@"public.utf8-plain-text"];
+ [mypasteboard declareTypes:[NSArray arrayWithObject:utf8_format] owner:nil];
+ [mypasteboard setData:(NSData*)text forType:utf8_format];
CFRelease(text);
Fl_Widget *w = Fl::pushed();
- Fl_Window *win = w->window();
- if (win == NULL) {
- win = (Fl_Window*)w;
- } else {
- while(win->window()) win = win->window();
- }
+ Fl_Window *win = w->top_window();
NSView *myview = [Fl_X::i(win)->xid contentView];
NSEvent *theEvent = [NSApp currentEvent];
@@ -3319,20 +3814,29 @@ int Fl::dnd(void)
}
static NSBitmapImageRep* rect_to_NSBitmapImageRep(Fl_Window *win, int x, int y, int w, int h)
-// release the returned value after use
+// the returned value is autoreleased
{
+ NSRect rect;
+ NSView *winview = nil;
while (win->window()) {
x += win->x();
y += win->y();
win = win->window();
}
- CGFloat epsilon = 0;
- if (fl_mac_os_version >= 100600) epsilon = 0.5; // STR #2887
- // The epsilon offset is absolutely necessary under 10.6. Without it, the top pixel row and
- // left pixel column are not read, and bitmap is read shifted by one pixel in both directions.
- // Under 10.5, we want no offset.
- NSRect rect = NSMakeRect(x - epsilon, y - epsilon, w, h);
- return [[NSBitmapImageRep alloc] initWithFocusedViewRect:rect];
+ if ( through_drawRect ) {
+ CGFloat epsilon = 0;
+ if (fl_mac_os_version >= 100600) epsilon = 0.5; // STR #2887
+ rect = NSMakeRect(x - epsilon, y - epsilon, w, h);
+ }
+ else {
+ rect = NSMakeRect(x, win->h()-(y+h), w, h);
+ // lock focus to win's view
+ winview = [fl_xid(win) contentView];
+ [winview lockFocus];
+ }
+ NSBitmapImageRep *bitmap = [[[NSBitmapImageRep alloc] initWithFocusedViewRect:rect] autorelease];
+ if ( !through_drawRect ) [winview unlockFocus];
+ return bitmap;
}
unsigned char *Fl_X::bitmap_from_window_rect(Fl_Window *win, int x, int y, int w, int h, int *bytesPerPixel)
@@ -3344,24 +3848,38 @@ unsigned char *Fl_X::bitmap_from_window_rect(Fl_Window *win, int x, int y, int w
*/
{
NSBitmapImageRep *bitmap = rect_to_NSBitmapImageRep(win, x, y, w, h);
+ if (bitmap == nil) return NULL;
*bytesPerPixel = [bitmap bitsPerPixel]/8;
int bpp = (int)[bitmap bytesPerPlane];
int bpr = (int)[bitmap bytesPerRow];
- int hh = bpp/bpr; // sometimes hh = h-1 for unclear reason
- int ww = bpr/(*bytesPerPixel); // sometimes ww = w-1
- unsigned char *data = new unsigned char[w * h * *bytesPerPixel];
- if (w == ww) {
- memcpy(data, [bitmap bitmapData], w * hh * *bytesPerPixel);
- } else {
- unsigned char *p = [bitmap bitmapData];
- unsigned char *q = data;
- for(int i = 0;i < hh; i++) {
- memcpy(q, p, *bytesPerPixel * ww);
- p += bpr;
- q += w * *bytesPerPixel;
+ int hh = bpp/bpr; // sometimes hh = h-1 for unclear reason, and hh = 2*h with retina
+ int ww = bpr/(*bytesPerPixel); // sometimes ww = w-1, and ww = 2*w with retina
+ unsigned char *data;
+ if (ww > w) { // with a retina display
+ Fl_RGB_Image *rgb = new Fl_RGB_Image([bitmap bitmapData], ww, hh, 4);
+ Fl_RGB_Scaling save_scaling = Fl_Image::RGB_scaling();
+ Fl_Image::RGB_scaling(FL_RGB_SCALING_BILINEAR);
+ Fl_RGB_Image *rgb2 = (Fl_RGB_Image*)rgb->copy(w, h);
+ Fl_Image::RGB_scaling(save_scaling);
+ delete rgb;
+ rgb2->alloc_array = 0;
+ data = (uchar*)rgb2->array;
+ delete rgb2;
+ }
+ else {
+ data = new unsigned char[w * h * *bytesPerPixel];
+ if (w == ww) {
+ memcpy(data, [bitmap bitmapData], w * hh * *bytesPerPixel);
+ } else {
+ unsigned char *p = [bitmap bitmapData];
+ unsigned char *q = data;
+ for(int i = 0;i < hh; i++) {
+ memcpy(q, p, *bytesPerPixel * ww);
+ p += bpr;
+ q += w * *bytesPerPixel;
}
+ }
}
- [bitmap release];
return data;
}
@@ -3376,13 +3894,13 @@ CGImageRef Fl_X::CGImage_from_window_rect(Fl_Window *win, int x, int y, int w, i
CGImageRef img;
if (fl_mac_os_version >= 100500) {
NSBitmapImageRep *bitmap = rect_to_NSBitmapImageRep(win, x, y, w, h);
- img = [bitmap CGImage]; // requires Mac OS 10.5
+ img = (CGImageRef)[bitmap performSelector:@selector(CGImage)]; // requires Mac OS 10.5
CGImageRetain(img);
- [bitmap release];
}
else {
int bpp;
unsigned char *bitmap = bitmap_from_window_rect(win, x, y, w, h, &bpp);
+ if (!bitmap) return NULL;
CGColorSpaceRef lut = CGColorSpaceCreateDeviceRGB();
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, bitmap, w*h*bpp, imgProviderReleaseData);
img = CGImageCreate(w, h, 8, 8*bpp, w*bpp, lut,
@@ -3401,7 +3919,7 @@ WindowRef Fl_X::window_ref()
// so a CGRect matches exactly what is denoted x,y,w,h for clipping purposes
CGRect fl_cgrectmake_cocoa(int x, int y, int w, int h) {
- return CGRectMake(x, y, w > 0 ? w - 0.9 : 0, h > 0 ? h - 0.9 : 0);
+ return CGRectMake(x - 0.5, y - 0.5, w, h);
}
Window fl_xid(const Fl_Window* w)
@@ -3428,30 +3946,110 @@ int Fl_Window::decorated_h()
void Fl_Paged_Device::print_window(Fl_Window *win, int x_offset, int y_offset)
{
+ NSButton *close = nil, *miniaturize = nil, *zoom = nil;
if (!win->shown() || win->parent() || !win->border() || !win->visible()) {
this->print_widget(win, x_offset, y_offset);
return;
}
- int bx, by, bt;
+ int bx, by, bt, bpp;
get_window_frame_sizes(bx, by, bt);
Fl_Display_Device::display_device()->set_current(); // send win to front and make it current
+ const char *title = win->label();
+ win->label(""); // temporarily set a void window title
win->show();
+ if (fl_mac_os_version >= 101000) {
+ // if linked for OS 10.10, capture of title bar does not capture the title bar buttons
+ // so we draw them in FLTK
+ NSWindow *xid = fl_xid(win);
+ close = [xid standardWindowButton:NSWindowCloseButton]; // 10.2
+ miniaturize = [xid standardWindowButton:NSWindowMiniaturizeButton];
+ zoom = [xid standardWindowButton:NSWindowZoomButton];
+ [close setHidden:YES]; // 10.3
+ [miniaturize setHidden:YES];
+ [zoom setHidden:YES];
+ }
fl_gc = NULL;
Fl::check();
- win->make_current();
+ BOOL to_quartz = dynamic_cast<Fl_Printer*>(this) != NULL;
+ // capture the window title bar with no title
+ CGImageRef img = NULL;
+ unsigned char *bitmap = NULL;
+ if (to_quartz)
+ img = Fl_X::CGImage_from_window_rect(win, 0, -bt, win->w(), bt);
+ else
+ bitmap = Fl_X::bitmap_from_window_rect(win, 0, -bt, win->w(), bt, &bpp);
+ win->label(title); // put back the window title
this->set_current(); // back to the Fl_Paged_Device
- // capture the window title bar
- CGImageRef img = Fl_X::CGImage_from_window_rect(win, 0, -bt, win->w(), bt);
- // and print it
- CGRect rect = { { x_offset, y_offset }, { win->w(), bt } };
- Fl_X::q_begin_image(rect, 0, 0, win->w(), bt);
- CGContextDrawImage(fl_gc, rect, img);
- Fl_X::q_end_image();
- CFRelease(img);
+ if (img && to_quartz) { // print the title bar
+ CGRect rect = { { x_offset, y_offset }, { win->w(), bt } };
+ Fl_X::q_begin_image(rect, 0, 0, win->w(), bt);
+ CGContextDrawImage(fl_gc, rect, img);
+ Fl_X::q_end_image();
+ CFRelease(img);
+ }
+ else if(!to_quartz) {
+ Fl_RGB_Image *rgb = new Fl_RGB_Image(bitmap, win->w(), bt, bpp);
+ rgb->draw(x_offset, y_offset);
+ delete rgb;
+ delete[] bitmap;
+ }
+ if (fl_mac_os_version >= 101000) { // print the title bar buttons
+ Fl_Color inactive = fl_rgb_color((uchar)0xCE, (uchar)0xCE, (uchar)0xCE); // inactive button color
+ Fl_Color redish, yellowish, greenish;
+ if ([[NSUserDefaults standardUserDefaults] integerForKey:@"AppleAquaColorVariant"] == 6) { // graphite appearance
+ redish = yellowish = greenish = fl_rgb_color((uchar)0x8C, (uchar)0x8C, (uchar)0x8C);
+ }
+ else {
+ redish = fl_rgb_color((uchar)0xFF, (uchar)0x63, (uchar)0x5A);
+ yellowish = fl_rgb_color((uchar)0xFF, (uchar)0xC6, (uchar)0x42);
+ greenish = fl_rgb_color((uchar)0x29, (uchar)0xD6, (uchar)0x52);
+ }
+
+ if (![close isEnabled]) fl_color(inactive); else fl_color(redish);
+ fl_pie(x_offset+8, y_offset+5, 12, 12, 0, 360);
+ if (![miniaturize isEnabled]) fl_color(inactive); else fl_color(yellowish);
+ fl_pie(x_offset+28, y_offset+5, 12, 12, 0, 360);
+ if (![zoom isEnabled]) fl_color(inactive); else fl_color(greenish);
+ fl_pie(x_offset+48, y_offset+5, 12, 12, 0, 360);
+
+ [close setHidden:NO]; // 10.3
+ [miniaturize setHidden:NO];
+ [zoom setHidden:NO];
+ }
+ if (title) { // print the window title
+ const int skip = 65; // approx width of the zone of the 3 window control buttons
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
+ if (fl_mac_os_version >= 100400 && to_quartz) { // use Cocoa string drawing with exact title bar font
+ // the exact font is LucidaGrande 13 pts (and HelveticaNeueDeskInterface-Regular with 10.10)
+ NSGraphicsContext *current = [NSGraphicsContext currentContext];
+ [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithGraphicsPort:fl_gc flipped:YES]];//10.4
+ NSDictionary *attr = [NSDictionary dictionaryWithObject:[NSFont titleBarFontOfSize:0]
+ forKey:NSFontAttributeName];
+ NSString *title_s = [fl_xid(win) title];
+ NSSize size = [title_s sizeWithAttributes:attr];
+ int x = x_offset + win->w()/2 - size.width/2;
+ if (x < x_offset+skip) x = x_offset+skip;
+ NSRect r = {{x, y_offset+bt/2+4}, {win->w() - skip, bt}};
+ [[NSGraphicsContext currentContext] setShouldAntialias:YES];
+ [title_s drawWithRect:r options:(NSStringDrawingOptions)0 attributes:attr]; // 10.4
+ [[NSGraphicsContext currentContext] setShouldAntialias:NO];
+ [NSGraphicsContext setCurrentContext:current];
+ }
+ else
+#endif
+ {
+ fl_font(FL_HELVETICA, 14);
+ fl_color(FL_BLACK);
+ int x = x_offset + win->w()/2 - fl_width(title)/2;
+ if (x < x_offset+skip) x = x_offset+skip;
+ fl_push_clip(x_offset, y_offset, win->w(), bt);
+ fl_draw(title, x, y_offset+bt/2+4);
+ fl_pop_clip();
+ }
+ }
this->print_widget(win, x_offset, y_offset + bt); // print the window inner part
}
-#include <dlfcn.h>
/* Returns the address of a Carbon function after dynamically loading the Carbon library if needed.
Supports old Mac OS X versions that may use a couple of Carbon calls:
@@ -3476,9 +4074,20 @@ void *Fl_X::get_carbon_function(const char *function_name) {
static int calc_mac_os_version() {
int M, m, b = 0;
NSAutoreleasePool *localPool = [[NSAutoreleasePool alloc] init];
- NSDictionary * sv = [NSDictionary dictionaryWithContentsOfFile:@"/System/Library/CoreServices/SystemVersion.plist"];
- const char *s = [[sv objectForKey:@"ProductVersion"] UTF8String];
- sscanf(s, "%d.%d.%d", &M, &m, &b);
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_10
+ if ([NSProcessInfo instancesRespondToSelector:@selector(operatingSystemVersion)]) {
+ NSOperatingSystemVersion version = [[NSProcessInfo processInfo] operatingSystemVersion];
+ M = version.majorVersion;
+ m = version.minorVersion;
+ b = version.patchVersion;
+ }
+ else
+#endif
+ {
+ NSDictionary * sv = [NSDictionary dictionaryWithContentsOfFile:@"/System/Library/CoreServices/SystemVersion.plist"];
+ const char *s = [[sv objectForKey:@"ProductVersion"] UTF8String];
+ sscanf(s, "%d.%d.%d", &M, &m, &b);
+ }
[localPool release];
return M*10000 + m*100 + b;
}
@@ -3486,5 +4095,5 @@ static int calc_mac_os_version() {
#endif // __APPLE__
//
-// End of "$Id: Fl_cocoa.mm 9734 2012-11-30 18:20:36Z manolo $".
+// End of "$Id: Fl_cocoa.mm 10427 2014-11-02 21:06:07Z manolo $".
//
diff --git a/src/Fl_compose.cxx b/src/Fl_compose.cxx
index 03dd216..0cd2a57 100644
--- a/src/Fl_compose.cxx
+++ b/src/Fl_compose.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: Fl_compose.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $"
+// "$Id: Fl_compose.cxx 9966 2013-09-06 09:03:22Z manolo $"
//
// Character compose processing for the Fast Light Tool Kit (FLTK).
//
@@ -16,11 +16,20 @@
// http://www.fltk.org/str.php
//
+/**
+\file Fl_compose.cxx
+Utility functions to support text input.
+*/
+
+
#include <FL/Fl.H>
#include <FL/x.H>
#ifndef FL_DOXYGEN
int Fl::compose_state = 0;
+#ifdef __APPLE__
+int Fl_X::next_marked_length = 0;
+#endif
#endif
#if !defined(WIN32) && !defined(__APPLE__)
@@ -32,7 +41,7 @@ extern XIC fl_xim_ic;
<p>If <i>true</i> is returned, then it has modified the
Fl::event_text() and Fl::event_length() to a set of <i>bytes</i> to
- insert (it may be of zero length!). In will also set the "del"
+ insert (it may be of zero length!). It will also set the "del"
parameter to the number of <i>bytes</i> to the left of the cursor to
delete, this is used to delete the results of the previous call to
Fl::compose().
@@ -41,38 +50,88 @@ extern XIC fl_xim_ic;
keys, and del is set to zero. You could insert the text anyways, if
you don't know what else to do.
+ <p>On the Mac OS platform, text input can involve marked text, that is,
+ temporary text replaced by other text during the input process. This occurs,
+ e.g., when using dead keys or when entering CJK characters.
+ Text editing widgets should preferentially signal
+ marked text, usually underlining it. Widgets can use
+ <tt>int Fl::compose_state</tt> <i>after</i> having called Fl::compose(int&)
+ to obtain the length in bytes of marked text that always finishes at the
+ current insertion point. It's the widget's task to underline marked text.
+ Widgets should also call <tt>void Fl::reset_marked_text()</tt> when processing FL_UNFOCUS
+ events. Optionally, widgets can also call
+ <tt>void Fl::insertion_point_location(int x, int y, int height)</tt> to indicate the window
+ coordinates of the bottom of the current insertion point and the line height.
+ This way, auxiliary windows that help choosing among alternative characters
+ appear just below the insertion point. If widgets don't do that,
+ auxiliary windows appear at the widget's bottom. The
+ Fl_Input and Fl_Text_Editor widgets underline marked text.
+ If none of this is done by a user-defined text editing widget,
+ text input will work, but will not signal to the user what text is marked.
+ Finally, text editing widgets should call <tt>set_flag(MAC_USE_ACCENTS_MENU);</tt>
+ in their constructor if they want to use the feature introduced with Mac OS 10.7 "Lion"
+ where pressing and holding a key on the keyboard opens an accented-character menu window.
+
<p>Though the current implementation returns immediately, future
versions may take quite awhile, as they may pop up a window or do
other user-interface things to allow characters to be selected.
*/
int Fl::compose(int& del) {
- // character composition is now handled by the OS
- del = 0;
+ int condition;
#if defined(__APPLE__)
- // this stuff is to be treated as a function key
- if(Fl::e_length == 0 || Fl::e_keysym == FL_Enter || Fl::e_keysym == FL_KP_Enter ||
- Fl::e_keysym == FL_Tab || Fl::e_keysym == FL_Escape || Fl::e_state&(FL_META | FL_CTRL) ) {
- return 0;
- }
-#elif defined(WIN32)
- unsigned char ascii = (unsigned)e_text[0];
- if ((e_state & (FL_ALT | FL_META)) && !(ascii & 128)) return 0;
+ int has_text_key = Fl::compose_state || Fl::e_keysym <= '~' || Fl::e_keysym == FL_Iso_Key ||
+ (Fl::e_keysym >= FL_KP && Fl::e_keysym <= FL_KP_Last && Fl::e_keysym != FL_KP_Enter);
+ condition = Fl::e_state&(FL_META | FL_CTRL) ||
+ (Fl::e_keysym >= FL_Shift_L && Fl::e_keysym <= FL_Alt_R) || // called from flagsChanged
+ !has_text_key ;
#else
- unsigned char ascii = (unsigned)e_text[0];
- if ((e_state & (FL_ALT | FL_META | FL_CTRL)) && !(ascii & 128)) return 0;
-#endif
- if(Fl::compose_state) {
- del = Fl::compose_state;
- Fl::compose_state = 0;
-#ifndef __APPLE__
- } else {
- // Only insert non-control characters:
- if (! (ascii & ~31 && ascii!=127)) { return 0; }
+unsigned char ascii = (unsigned char)e_text[0];
+#if defined(WIN32)
+ condition = (e_state & (FL_ALT | FL_META)) && !(ascii & 128) ;
+#else
+ condition = (e_state & (FL_ALT | FL_META | FL_CTRL)) && !(ascii & 128) ;
+#endif // WIN32
+#endif // __APPLE__
+ if (condition) { del = 0; return 0;} // this stuff is to be treated as a function key
+ del = Fl::compose_state;
+#ifdef __APPLE__
+ Fl::compose_state = Fl_X::next_marked_length;
+#else
+ Fl::compose_state = 0;
+// Only insert non-control characters:
+ if ( (!Fl::compose_state) && ! (ascii & ~31 && ascii!=127)) { return 0; }
#endif
- }
return 1;
}
+#ifdef __APPLE__
+static int insertion_point_x = 0;
+static int insertion_point_y = 0;
+static int insertion_point_height = 0;
+static bool insertion_point_location_is_valid = false;
+
+void Fl::reset_marked_text() {
+ Fl::compose_state = 0;
+ Fl_X::next_marked_length = 0;
+ insertion_point_location_is_valid = false;
+ }
+int Fl_X::insertion_point_location(int *px, int *py, int *pheight)
+// return true if the current coordinates of the insertion point are available
+{
+ if ( ! insertion_point_location_is_valid ) return false;
+ *px = insertion_point_x;
+ *py = insertion_point_y;
+ *pheight = insertion_point_height;
+ return true;
+}
+void Fl::insertion_point_location(int x, int y, int height) {
+ insertion_point_location_is_valid = true;
+ insertion_point_x = x;
+ insertion_point_y = y;
+ insertion_point_height = height;
+}
+#endif // __APPLE__
+
/**
If the user moves the cursor, be sure to call Fl::compose_reset().
The next call to Fl::compose() will start out in an initial state. In
@@ -88,6 +147,6 @@ void Fl::compose_reset()
}
//
-// End of "$Id: Fl_compose.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $"
+// End of "$Id: Fl_compose.cxx 9966 2013-09-06 09:03:22Z manolo $"
//
diff --git a/src/Fl_get_key_mac.cxx b/src/Fl_get_key_mac.cxx
index 01c2c83..a59df4a 100644
--- a/src/Fl_get_key_mac.cxx
+++ b/src/Fl_get_key_mac.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: Fl_get_key_mac.cxx 9303 2012-03-26 16:54:54Z manolo $"
+// "$Id: Fl_get_key_mac.cxx 9952 2013-07-23 16:02:44Z manolo $"
//
// MacOS keyboard state routines for the Fast Light Tool Kit (FLTK).
//
@@ -164,6 +164,15 @@ enum {
kVK_ISO_Section = 0x0A
};
+/* JIS keyboards only*/
+enum {
+ kVK_JIS_Yen = 0x5D,
+ kVK_JIS_Underscore = 0x5E,
+ kVK_JIS_KeypadComma = 0x5F,
+ kVK_JIS_Eisu = 0x66,
+ kVK_JIS_Kana = 0x68
+};
+
#endif
// convert an FLTK (X) keysym to a MacOS symbol:
@@ -181,12 +190,16 @@ static const struct {unsigned short vk, fltk;} vktab[] = {
{ kVK_ANSI_U, 'U' }, { kVK_ANSI_V, 'V' }, { kVK_ANSI_W, 'W' }, { kVK_ANSI_X, 'X' },
{ kVK_ANSI_Y, 'Y' }, { kVK_ANSI_Z, 'Z' },
{ kVK_ANSI_LeftBracket, '[' }, { kVK_ANSI_Backslash, '\\' }, { kVK_ANSI_RightBracket, ']' }, { kVK_ANSI_Grave, '`' },
+ { kVK_VolumeDown, FL_Volume_Down}, { kVK_Mute, FL_Volume_Mute}, { kVK_VolumeUp, FL_Volume_Up},
{ kVK_Delete, FL_BackSpace }, { kVK_Tab, FL_Tab }, { kVK_ISO_Section, FL_Iso_Key }, { kVK_Return, FL_Enter }, /*{ 0x7F, FL_Pause },
- { 0x7F, FL_Scroll_Lock },*/ { kVK_Escape, FL_Escape }, { kVK_Home, FL_Home }, { kVK_LeftArrow, FL_Left },
+ { 0x7F, FL_Scroll_Lock },*/ { kVK_Escape, FL_Escape },
+ { kVK_JIS_Kana, FL_Kana}, { kVK_JIS_Eisu, FL_Eisu}, { kVK_JIS_Yen, FL_Yen}, { kVK_JIS_Underscore, FL_JIS_Underscore},
+ { kVK_Home, FL_Home }, { kVK_LeftArrow, FL_Left },
{ kVK_UpArrow, FL_Up }, { kVK_RightArrow, FL_Right }, { kVK_DownArrow, FL_Down }, { kVK_PageUp, FL_Page_Up },
{ kVK_PageDown, FL_Page_Down }, { kVK_End, FL_End }, /*{ 0x7F, FL_Print }, { 0x7F, FL_Insert },*/
{ 0x6e, FL_Menu }, { kVK_Help, FL_Help }, { kVK_ANSI_KeypadClear, FL_Num_Lock },
{ kVK_ANSI_KeypadEnter, FL_KP_Enter }, { kVK_ANSI_KeypadMultiply, FL_KP+'*' }, { kVK_ANSI_KeypadPlus, FL_KP+'+'},
+ { kVK_JIS_KeypadComma, FL_KP+',' },
{ kVK_ANSI_KeypadMinus, FL_KP+'-' }, { kVK_ANSI_KeypadDecimal, FL_KP+'.' }, { kVK_ANSI_KeypadDivide, FL_KP+'/' },
{ kVK_ANSI_Keypad0, FL_KP+'0' }, { kVK_ANSI_Keypad1, FL_KP+'1' }, { kVK_ANSI_Keypad2, FL_KP+'2' }, { kVK_ANSI_Keypad3, FL_KP+'3' },
{ kVK_ANSI_Keypad4, FL_KP+'4' }, { kVK_ANSI_Keypad5, FL_KP+'5' }, { kVK_ANSI_Keypad6, FL_KP+'6' }, { kVK_ANSI_Keypad7, FL_KP+'7' },
@@ -195,6 +208,7 @@ static const struct {unsigned short vk, fltk;} vktab[] = {
{ kVK_F5, FL_F+5 }, { kVK_F6, FL_F+6 }, { kVK_F7, FL_F+7 }, { kVK_F8, FL_F+8 },
{ kVK_F9, FL_F+9 }, { kVK_F10, FL_F+10 }, { kVK_F11, FL_F+11 }, { kVK_F12, FL_F+12 },
{ kVK_F13, FL_F+13 }, { kVK_F14, FL_F+14 }, { kVK_F15, FL_F+15 }, { kVK_F16, FL_F+16 },
+ { kVK_F17, FL_F+17 }, { kVK_F18, FL_F+18 }, { kVK_F19, FL_F+19 }, { kVK_F20, FL_F+20 },
{ kVK_Shift, FL_Shift_L }, { kVK_RightShift, FL_Shift_R }, { kVK_Control, FL_Control_L }, { kVK_RightControl, FL_Control_R },
{ kVK_CapsLock, FL_Caps_Lock }, { kVK_Command, FL_Meta_L }, { 0x36, FL_Meta_R },
{ kVK_Option, FL_Alt_L }, { kVK_RightOption, FL_Alt_R }, { kVK_ForwardDelete, FL_Delete }
@@ -219,7 +233,7 @@ static int fltk2mac(int fltk) {
if (vktab[c].fltk == fltk) return vktab[c].vk;
if (vktab[c].fltk < fltk) a = c+1; else b = c;
}
- return 127;
+ return vktab[a].vk;
}
//: returns true, if that key was pressed during the last event
@@ -261,5 +275,5 @@ int Fl::get_key(int k) {
}
//
-// End of "$Id: Fl_get_key_mac.cxx 9303 2012-03-26 16:54:54Z manolo $".
+// End of "$Id: Fl_get_key_mac.cxx 9952 2013-07-23 16:02:44Z manolo $".
//
diff --git a/src/Fl_get_system_colors.cxx b/src/Fl_get_system_colors.cxx
index fd64e54..b728b76 100644
--- a/src/Fl_get_system_colors.cxx
+++ b/src/Fl_get_system_colors.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: Fl_get_system_colors.cxx 9740 2012-12-09 17:45:24Z manolo $"
+// "$Id: Fl_get_system_colors.cxx 10126 2014-04-19 14:55:15Z greg.ercolano $"
//
// System color support for the Fast Light Tool Kit (FLTK).
//
@@ -258,19 +258,28 @@ Fl_Image *Fl::scheme_bg_ = (Fl_Image *)0; // current background image for the
static Fl_Pixmap tile(tile_xpm);
/**
- Gets or sets the current widget scheme. NULL will use
- the scheme defined in the FLTK_SCHEME environment
- variable or the scheme resource under X11. Otherwise,
- any of the following schemes can be used:
-
- - "none" - This is the default look-n-feel which resembles old
- Windows (95/98/Me/NT/2000) and old GTK/KDE
-
- - "plastic" - This scheme is inspired by the Aqua user interface
- on Mac OS X
-
- - "gtk+" - This scheme is inspired by the Red Hat Bluecurve
- theme
+ Sets the current widget scheme. NULL will use the scheme defined
+ in the FLTK_SCHEME environment variable or the scheme resource
+ under X11. Otherwise, any of the following schemes can be used:
+
+ - "none" - This is the default look-n-feel which resembles old
+ Windows (95/98/Me/NT/2000) and old GTK/KDE
+
+ - "base" - This is an alias for "none"
+
+ - "plastic" - This scheme is inspired by the Aqua user interface
+ on Mac OS X
+
+ - "gtk+" - This scheme is inspired by the Red Hat Bluecurve theme
+
+ - "gleam" - This scheme is inspired by the Clearlooks Glossy scheme.
+ (Colin Jones and Edmanuel Torres).
+
+ Uppercase scheme names are equivalent, but the stored scheme name will
+ always be lowercase and Fl::scheme() will return this lowercase name.
+
+ If the resulting scheme name is not defined, the default scheme will
+ be used and Fl::scheme() will return NULL.
*/
int Fl::scheme(const char *s) {
if (!s) {
@@ -289,6 +298,7 @@ int Fl::scheme(const char *s) {
if (!fl_ascii_strcasecmp(s, "none") || !fl_ascii_strcasecmp(s, "base") || !*s) s = 0;
else if (!fl_ascii_strcasecmp(s, "gtk+")) s = strdup("gtk+");
else if (!fl_ascii_strcasecmp(s, "plastic")) s = strdup("plastic");
+ else if (!fl_ascii_strcasecmp(s, "gleam")) s = strdup("gleam");
else s = 0;
}
if (scheme_) free((void*)scheme_);
@@ -375,6 +385,27 @@ int Fl::reload_scheme() {
// Use slightly thinner scrollbars...
Fl::scrollbar_size(15);
+ } else if (scheme_ && !fl_ascii_strcasecmp(scheme_, "gleam")) {
+ // Use a GTK+ inspired look-n-feel...
+ if (scheme_bg_) {
+ delete scheme_bg_;
+ scheme_bg_ = (Fl_Image *)0;
+ }
+
+ set_boxtype(FL_UP_FRAME, FL_GLEAM_UP_FRAME);
+ set_boxtype(FL_DOWN_FRAME, FL_GLEAM_DOWN_FRAME);
+ set_boxtype(FL_THIN_UP_FRAME, FL_GLEAM_UP_FRAME);
+ set_boxtype(FL_THIN_DOWN_FRAME, FL_GLEAM_DOWN_FRAME);
+
+ set_boxtype(FL_UP_BOX, FL_GLEAM_UP_BOX);
+ set_boxtype(FL_DOWN_BOX, FL_GLEAM_DOWN_BOX);
+ set_boxtype(FL_THIN_UP_BOX, FL_GLEAM_THIN_UP_BOX);
+ set_boxtype(FL_THIN_DOWN_BOX, FL_GLEAM_THIN_DOWN_BOX);
+ set_boxtype(_FL_ROUND_UP_BOX, FL_GLEAM_ROUND_UP_BOX);
+ set_boxtype(_FL_ROUND_DOWN_BOX, FL_GLEAM_ROUND_DOWN_BOX);
+
+ // Use slightly thinner scrollbars...
+ Fl::scrollbar_size(15);
} else {
// Use the standard FLTK look-n-feel...
if (scheme_bg_) {
@@ -411,5 +442,5 @@ int Fl::reload_scheme() {
//
-// End of "$Id: Fl_get_system_colors.cxx 9740 2012-12-09 17:45:24Z manolo $".
+// End of "$Id: Fl_get_system_colors.cxx 10126 2014-04-19 14:55:15Z greg.ercolano $".
//
diff --git a/src/Fl_mac.cxx b/src/Fl_mac.cxx
deleted file mode 100644
index 3fb4ffc..0000000
--- a/src/Fl_mac.cxx
+++ /dev/null
@@ -1,2861 +0,0 @@
-//
-// "$Id: Fl_mac.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $"
-//
-// MacOS specific code for the Fast Light Tool Kit (FLTK).
-//
-// Copyright 1998-2010 by Bill Spitzak and others.
-//
-// This library is free software. Distribution and use rights are outlined in
-// the file "COPYING" which should have been included with this file. If this
-// file is missing or damaged, see the license at:
-//
-// http://www.fltk.org/COPYING.php
-//
-// Please report all bugs and problems on the following page:
-//
-// http://www.fltk.org/str.php
-//
-
-//// From the inner edge of a MetroWerks CodeWarrior CD:
-// (without permission)
-//
-// "Three Compiles for 68Ks under the sky,
-// Seven Compiles for PPCs in their fragments of code,
-// Nine Compiles for Mortal Carbon doomed to die,
-// One Compile for Mach-O Cocoa on its Mach-O throne,
-// in the Land of MacOS X where the Drop-Shadows lie.
-//
-// One Compile to link them all, One Compile to merge them,
-// One Compile to copy them all and in the bundle bind them,
-// in the Land of MacOS X where the Drop-Shadows lie."
-
-// warning: the Apple Quartz version still uses some Quickdraw calls,
-// mostly to get around the single active context in QD and
-// to implement clipping. This should be changed into pure
-// Quartz calls in the near future.
-
-// FIXME moving away from Carbon, I am replacing the Scrap manager calls with Pasteboard
-// calls that support utf8 encoding. As soon as these function haven proven working
-// the Scrap manager calls should be removed
-#define USE_PASTEBOARD 1
-
-// we don't need the following definition because we deliver only
-// true mouse moves. On very slow systems however, this flag may
-// still be useful.
-#ifndef FL_DOXYGEN
-
-#define CONSOLIDATE_MOTION 0
-extern "C" {
-#include <pthread.h>
-}
-
-#include <config.h>
-#include <FL/Fl.H>
-#include <FL/x.H>
-#include <FL/Fl_Window.H>
-#include <FL/Fl_Tooltip.H>
-#include <FL/Fl_Sys_Menu_Bar.H>
-#include <stdio.h>
-#include <stdlib.h>
-#include "flstring.h"
-#include <unistd.h>
-
-// #define DEBUG_SELECT // UNCOMMENT FOR SELECT()/THREAD DEBUGGING
-#ifdef DEBUG_SELECT
-#include <stdio.h> // testing
-#define DEBUGMSG(msg) if ( msg ) fprintf(stderr, msg);
-#define DEBUGPERRORMSG(msg) if ( msg ) perror(msg)
-#define DEBUGTEXT(txt) txt
-#else
-#define DEBUGMSG(msg)
-#define DEBUGPERRORMSG(msg)
-#define DEBUGTEXT(txt) NULL
-#endif /*DEBUG_SELECT*/
-
-// external functions
-extern Fl_Window* fl_find(Window);
-extern void fl_fix_focus();
-
-// forward definition of functions in this file
-static void handleUpdateEvent( WindowPtr xid );
-//+ int fl_handle(const EventRecord &event);
-static int FSSpec2UnixPath( FSSpec *fs, char *dst );
-// converting cr lf converter function
-static void convert_crlf(char * string, size_t len);
-
-// public variables
-int fl_screen;
-CGContextRef fl_gc = 0;
-Handle fl_system_menu;
-Fl_Sys_Menu_Bar *fl_sys_menu_bar = 0;
-CursHandle fl_default_cursor;
-WindowRef fl_capture = 0; // we need this to compensate for a missing(?) mouse capture
-ulong fl_event_time; // the last timestamp from an x event
-char fl_key_vector[32]; // used by Fl::get_key()
-bool fl_show_iconic; // true if called from iconize() - shows the next created window in collapsed state
-int fl_disable_transient_for; // secret method of removing TRANSIENT_FOR
-const Fl_Window* fl_modal_for; // parent of modal() window
-Fl_Region fl_window_region = 0;
-Window fl_window;
-Fl_Window *Fl_Window::current_;
-EventRef fl_os_event; // last (mouse) event
-
-// forward declarations of variables in this file
-static int got_events = 0;
-static Fl_Window* resize_from_system;
-static CursPtr default_cursor_ptr;
-static Cursor default_cursor;
-static WindowRef fl_os_capture = 0; // the dispatch handler will redirect mose move and drag events to these windows
-
-#if CONSOLIDATE_MOTION
-static Fl_Window* send_motion;
-extern Fl_Window* fl_xmousewin;
-#endif
-
-enum { kEventClassFLTK = 'fltk' };
-enum { kEventFLTKBreakLoop = 1, kEventFLTKDataReady };
-
-/* fltk-utf8 placekeepers */
-void fl_reset_spot()
-{
-}
-
-void fl_set_spot(int font, int size, int X, int Y, int W, int H, Fl_Window *win)
-{
-}
-
-void fl_set_status(int x, int y, int w, int h)
-{
-}
-
-/**
-* Mac keyboard lookup table
- */
-static unsigned short macKeyLookUp[128] =
-{
- 'a', 's', 'd', 'f', 'h', 'g', 'z', 'x',
- 'c', 'v', '^', 'b', 'q', 'w', 'e', 'r',
-
- 'y', 't', '1', '2', '3', '4', '6', '5',
- '=', '9', '7', '-', '8', '0', ']', 'o',
-
- 'u', '[', 'i', 'p', FL_Enter, 'l', 'j', '\'',
- 'k', ';', '\\', ',', '/', 'n', 'm', '.',
-
- FL_Tab, ' ', '`', FL_BackSpace,
- FL_KP_Enter, FL_Escape, 0, 0/*FL_Meta_L*/,
- 0/*FL_Shift_L*/, 0/*FL_Caps_Lock*/, 0/*FL_Alt_L*/, 0/*FL_Control_L*/,
- 0/*FL_Shift_R*/, 0/*FL_Alt_R*/, 0/*FL_Control_R*/, 0,
-
- 0, FL_KP+'.', FL_Right, FL_KP+'*', 0, FL_KP+'+', FL_Left, FL_Delete,
- FL_Down, 0, 0, FL_KP+'/', FL_KP_Enter, FL_Up, FL_KP+'-', 0,
-
- 0, FL_KP+'=', FL_KP+'0', FL_KP+'1', FL_KP+'2', FL_KP+'3', FL_KP+'4', FL_KP+'5',
- FL_KP+'6', FL_KP+'7', 0, FL_KP+'8', FL_KP+'9', 0, 0, 0,
-
- FL_F+5, FL_F+6, FL_F+7, FL_F+3, FL_F+8, FL_F+9, 0, FL_F+11,
- 0, 0/*FL_F+13*/, FL_Print, FL_Scroll_Lock, 0, FL_F+10, FL_Menu, FL_F+12,
-
- 0, FL_Pause, FL_Help, FL_Home, FL_Page_Up, FL_Delete, FL_F+4, FL_End,
- FL_F+2, FL_Page_Down, FL_F+1, FL_Left, FL_Right, FL_Down, FL_Up, 0/*FL_Power*/,
-};
-
-/**
- * convert the current mouse chord into the FLTK modifier state
- */
-static unsigned int mods_to_e_state( UInt32 mods )
-{
- long state = 0;
- if ( mods & kEventKeyModifierNumLockMask ) state |= FL_NUM_LOCK;
- if ( mods & cmdKey ) state |= FL_META;
- if ( mods & (optionKey|rightOptionKey) ) state |= FL_ALT;
- if ( mods & (controlKey|rightControlKey) ) state |= FL_CTRL;
- if ( mods & (shiftKey|rightShiftKey) ) state |= FL_SHIFT;
- if ( mods & alphaLock ) state |= FL_CAPS_LOCK;
- unsigned int ret = ( Fl::e_state & 0xff000000 ) | state;
- Fl::e_state = ret;
- //printf( "State 0x%08x (%04x)\n", Fl::e_state, mods );
- return ret;
-}
-
-
-/**
- * convert the current mouse chord into the FLTK keysym
- */
-static void mods_to_e_keysym( UInt32 mods )
-{
- if ( mods & cmdKey ) Fl::e_keysym = FL_Meta_L;
- else if ( mods & kEventKeyModifierNumLockMask ) Fl::e_keysym = FL_Num_Lock;
- else if ( mods & optionKey ) Fl::e_keysym = FL_Alt_L;
- else if ( mods & rightOptionKey ) Fl::e_keysym = FL_Alt_R;
- else if ( mods & controlKey ) Fl::e_keysym = FL_Control_L;
- else if ( mods & rightControlKey ) Fl::e_keysym = FL_Control_R;
- else if ( mods & shiftKey ) Fl::e_keysym = FL_Shift_L;
- else if ( mods & rightShiftKey ) Fl::e_keysym = FL_Shift_R;
- else if ( mods & alphaLock ) Fl::e_keysym = FL_Caps_Lock;
- else Fl::e_keysym = 0;
- //printf( "to sym 0x%08x (%04x)\n", Fl::e_keysym, mods );
-}
-// these pointers are set by the Fl::lock() function:
-static void nothing() {}
-void (*fl_lock_function)() = nothing;
-void (*fl_unlock_function)() = nothing;
-
-//
-// Select interface -- how it's implemented:
-// When the user app configures one or more file descriptors to monitor
-// with Fl::add_fd(), we start a separate thread to select() the data,
-// sending a custom OSX 'FLTK data ready event' to the parent thread's
-// RunApplicationLoop(), so that it triggers the data ready callbacks
-// in the parent thread. -erco 04/04/04
-//
-#define POLLIN 1
-#define POLLOUT 4
-#define POLLERR 8
-
-// Class to handle select() 'data ready'
-class DataReady
-{
- struct FD
- {
- int fd;
- short events;
- void (*cb)(int, void*);
- void* arg;
- };
- int nfds, fd_array_size;
- FD *fds;
- pthread_t tid; // select()'s thread id
-
- // Data that needs to be locked (all start with '_')
- pthread_mutex_t _datalock; // data lock
- fd_set _fdsets[3]; // r/w/x sets user wants to monitor
- int _maxfd; // max fd count to monitor
- int _cancelpipe[2]; // pipe used to help cancel thread
- void *_userdata; // thread's userdata
-
-public:
- DataReady()
- {
- nfds = 0;
- fd_array_size = 0;
- fds = 0;
- tid = 0;
-
- pthread_mutex_init(&_datalock, NULL);
- FD_ZERO(&_fdsets[0]); FD_ZERO(&_fdsets[1]); FD_ZERO(&_fdsets[2]);
- _cancelpipe[0] = _cancelpipe[1] = 0;
- _userdata = 0;
- _maxfd = 0;
- }
-
- ~DataReady()
- {
- CancelThread(DEBUGTEXT("DESTRUCTOR\n"));
- if (fds) { free(fds); fds = 0; }
- nfds = 0;
- }
-
- // Locks
- // The convention for locks: volatile vars start with '_',
- // and must be locked before use. Locked code is prefixed
- // with /*LOCK*/ to make painfully obvious esp. in debuggers. -erco
- //
- void DataLock() { pthread_mutex_lock(&_datalock); }
- void DataUnlock() { pthread_mutex_unlock(&_datalock); }
-
- // Accessors
- int IsThreadRunning() { return(tid ? 1 : 0); }
- int GetNfds() { return(nfds); }
- int GetCancelPipe(int ix) { return(_cancelpipe[ix]); }
- fd_set GetFdset(int ix) { return(_fdsets[ix]); }
-
- // Methods
- void AddFD(int n, int events, void (*cb)(int, void*), void *v);
- void RemoveFD(int n, int events);
- int CheckData(fd_set& r, fd_set& w, fd_set& x);
- void HandleData(fd_set& r, fd_set& w, fd_set& x);
- static void* DataReadyThread(void *self);
- void StartThread(void *userdata);
- void CancelThread(const char *reason);
-};
-
-static DataReady dataready;
-
-void DataReady::AddFD(int n, int events, void (*cb)(int, void*), void *v)
-{
- RemoveFD(n, events);
- int i = nfds++;
- if (i >= fd_array_size)
- {
- FD *temp;
- fd_array_size = 2*fd_array_size+1;
- if (!fds) { temp = (FD*)malloc(fd_array_size*sizeof(FD)); }
- else { temp = (FD*)realloc(fds, fd_array_size*sizeof(FD)); }
- if (!temp) return;
- fds = temp;
- }
- fds[i].cb = cb;
- fds[i].arg = v;
- fds[i].fd = n;
- fds[i].events = events;
- DataLock();
- /*LOCK*/ if (events & POLLIN) FD_SET(n, &_fdsets[0]);
- /*LOCK*/ if (events & POLLOUT) FD_SET(n, &_fdsets[1]);
- /*LOCK*/ if (events & POLLERR) FD_SET(n, &_fdsets[2]);
- /*LOCK*/ if (n > _maxfd) _maxfd = n;
- DataUnlock();
-}
-
-// Remove an FD from the array
-void DataReady::RemoveFD(int n, int events)
-{
- int i,j;
- for (i=j=0; i<nfds; i++)
- {
- if (fds[i].fd == n)
- {
- int e = fds[i].events & ~events;
- if (!e) continue; // if no events left, delete this fd
- fds[i].events = e;
- }
- // move it down in the array if necessary:
- if (j<i)
- { fds[j] = fds[i]; }
- j++;
- }
- nfds = j;
- DataLock();
- /*LOCK*/ if (events & POLLIN) FD_CLR(n, &_fdsets[0]);
- /*LOCK*/ if (events & POLLOUT) FD_CLR(n, &_fdsets[1]);
- /*LOCK*/ if (events & POLLERR) FD_CLR(n, &_fdsets[2]);
- /*LOCK*/ if (n == _maxfd) _maxfd--;
- DataUnlock();
-}
-
-// CHECK IF USER DATA READY, RETURNS r/w/x INDICATING WHICH IF ANY
-int DataReady::CheckData(fd_set& r, fd_set& w, fd_set& x)
-{
- int ret;
- DataLock();
- /*LOCK*/ timeval t = { 0, 1 }; // quick check
- /*LOCK*/ r = _fdsets[0], w = _fdsets[1], x = _fdsets[2];
- /*LOCK*/ ret = ::select(_maxfd+1, &r, &w, &x, &t);
- DataUnlock();
- if ( ret == -1 )
- { DEBUGPERRORMSG("CheckData(): select()"); }
- return(ret);
-}
-
-// HANDLE DATA READY CALLBACKS
-void DataReady::HandleData(fd_set& r, fd_set& w, fd_set& x)
-{
- for (int i=0; i<nfds; i++)
- {
- int f = fds[i].fd;
- short revents = 0;
- if (FD_ISSET(f, &r)) revents |= POLLIN;
- if (FD_ISSET(f, &w)) revents |= POLLOUT;
- if (FD_ISSET(f, &x)) revents |= POLLERR;
- if (fds[i].events & revents)
- {
- DEBUGMSG("DOING CALLBACK: ");
- fds[i].cb(f, fds[i].arg);
- DEBUGMSG("DONE\n");
- }
- }
-}
-
-// DATA READY THREAD
-// This thread watches for changes in user's file descriptors.
-// Sends a 'data ready event' to the main thread if any change.
-//
-void* DataReady::DataReadyThread(void *o)
-{
- DataReady *self = (DataReady*)o;
- while ( 1 ) // loop until thread cancel or error
- {
- // Thread safe local copies of data before each select()
- self->DataLock();
- /*LOCK*/ int maxfd = self->_maxfd;
- /*LOCK*/ fd_set r = self->GetFdset(0);
- /*LOCK*/ fd_set w = self->GetFdset(1);
- /*LOCK*/ fd_set x = self->GetFdset(2);
- /*LOCK*/ void *userdata = self->_userdata;
- /*LOCK*/ int cancelpipe = self->GetCancelPipe(0);
- /*LOCK*/ if ( cancelpipe > maxfd ) maxfd = cancelpipe;
- /*LOCK*/ FD_SET(cancelpipe, &r); // add cancelpipe to fd's to watch
- /*LOCK*/ FD_SET(cancelpipe, &x);
- self->DataUnlock();
- // timeval t = { 1000, 0 }; // 1000 seconds;
- timeval t = { 2, 0 }; // HACK: 2 secs prevents 'hanging' problem
- int ret = ::select(maxfd+1, &r, &w, &x, &t);
- pthread_testcancel(); // OSX 10.0.4 and older: needed for parent to cancel
- switch ( ret )
- {
- case 0: // NO DATA
- continue;
- case -1: // ERROR
- {
- DEBUGPERRORMSG("CHILD THREAD: select() failed");
- return(NULL); // error? exit thread
- }
- default: // DATA READY
- {
- if (FD_ISSET(cancelpipe, &r) || FD_ISSET(cancelpipe, &x)) // cancel?
- { return(NULL); } // just exit
- DEBUGMSG("CHILD THREAD: DATA IS READY\n");
- EventRef drEvent;
- CreateEvent( 0, kEventClassFLTK, kEventFLTKDataReady,
- 0, kEventAttributeUserEvent, &drEvent);
- EventQueueRef eventqueue = (EventQueueRef)userdata;
- PostEventToQueue(eventqueue, drEvent, kEventPriorityStandard );
- ReleaseEvent( drEvent );
- return(NULL); // done with thread
- }
- }
- }
-}
-
-// START 'DATA READY' THREAD RUNNING, CREATE INTER-THREAD PIPE
-void DataReady::StartThread(void *new_userdata)
-{
- CancelThread(DEBUGTEXT("STARTING NEW THREAD\n"));
- DataLock();
- /*LOCK*/ pipe(_cancelpipe); // pipe for sending cancel msg to thread
- /*LOCK*/ _userdata = new_userdata;
- DataUnlock();
- DEBUGMSG("*** START THREAD\n");
- pthread_create(&tid, NULL, DataReadyThread, (void*)this);
-}
-
-// CANCEL 'DATA READY' THREAD, CLOSE PIPE
-void DataReady::CancelThread(const char *reason)
-{
- if ( tid )
- {
- DEBUGMSG("*** CANCEL THREAD: ");
- DEBUGMSG(reason);
- if ( pthread_cancel(tid) == 0 ) // cancel first
- {
- DataLock();
- /*LOCK*/ write(_cancelpipe[1], "x", 1); // wake thread from select
- DataUnlock();
- pthread_join(tid, NULL); // wait for thread to finish
- }
- tid = 0;
- DEBUGMSG("(JOINED) OK\n");
- }
- // Close pipe if open
- DataLock();
- /*LOCK*/ if ( _cancelpipe[0] ) { close(_cancelpipe[0]); _cancelpipe[0] = 0; }
- /*LOCK*/ if ( _cancelpipe[1] ) { close(_cancelpipe[1]); _cancelpipe[1] = 0; }
- DataUnlock();
-}
-
-void Fl::add_fd( int n, int events, void (*cb)(int, void*), void *v )
- { dataready.AddFD(n, events, cb, v); }
-
-void Fl::add_fd(int fd, void (*cb)(int, void*), void* v)
- { dataready.AddFD(fd, POLLIN, cb, v); }
-
-void Fl::remove_fd(int n, int events)
- { dataready.RemoveFD(n, events); }
-
-void Fl::remove_fd(int n)
- { dataready.RemoveFD(n, -1); }
-
-/**
- * Check if there is actually a message pending!
- */
-int fl_ready()
-{
- EventRef event;
- return !ReceiveNextEvent(0, NULL, 0.0, false, &event);
-}
-
-/**
- * handle Apple Menu items (can be created using the Fl_Sys_Menu_Bar
- * returns eventNotHandledErr if the menu item could not be handled
- */
-OSStatus HandleMenu( HICommand *cmd )
-{
- OSStatus ret = eventNotHandledErr;
- // attributes, commandIDm menu.menuRef, menu.menuItemIndex
- UInt32 ref;
- OSErr rrc = GetMenuItemRefCon( cmd->menu.menuRef, cmd->menu.menuItemIndex, &ref );
- //printf( "%d, %08x, %08x, %d, %d, %8x\n", rrc, cmd->attributes, cmd->commandID, cmd->menu.menuRef, cmd->menu.menuItemIndex, rrc );
- if ( rrc==noErr && ref )
- {
- Fl_Menu_Item *m = (Fl_Menu_Item*)ref;
- //printf( "Menu: %s\n", m->label() );
- fl_sys_menu_bar->picked( m );
- if ( m->flags & FL_MENU_TOGGLE ) // update the menu toggle symbol
- SetItemMark( cmd->menu.menuRef, cmd->menu.menuItemIndex, (m->flags & FL_MENU_VALUE ) ? 0x12 : 0 );
- if ( m->flags & FL_MENU_RADIO ) // update all radio buttons in this menu
- {
- Fl_Menu_Item *j = m;
- int i = cmd->menu.menuItemIndex;
- for (;;)
- {
- if ( j->flags & FL_MENU_DIVIDER )
- break;
- j++; i++;
- if ( !j->text || !j->radio() )
- break;
- SetItemMark( cmd->menu.menuRef, i, ( j->flags & FL_MENU_VALUE ) ? 0x13 : 0 );
- }
- j = m-1; i = cmd->menu.menuItemIndex-1;
- for ( ; i>0; j--, i-- )
- {
- if ( !j->text || j->flags&FL_MENU_DIVIDER || !j->radio() )
- break;
- SetItemMark( cmd->menu.menuRef, i, ( j->flags & FL_MENU_VALUE ) ? 0x13 : 0 );
- }
- SetItemMark( cmd->menu.menuRef, cmd->menu.menuItemIndex, ( m->flags & FL_MENU_VALUE ) ? 0x13 : 0 );
- }
- ret = noErr; // done handling this event
- }
- HiliteMenu(0);
- return ret;
-}
-
-
-/**
- * We can make every event pass through this function
- * - mouse events need to be manipulated to use a mouse focus window
- * - keyboard, mouse and some window events need to quit the Apple Event Loop
- * so FLTK can continue its own management
- */
-static pascal OSStatus carbonDispatchHandler( EventHandlerCallRef nextHandler, EventRef event, void *userData )
-{
- OSStatus ret = eventNotHandledErr;
- HICommand cmd;
-
- fl_lock_function();
-
- got_events = 1;
-
- switch ( GetEventClass( event ) )
- {
- case kEventClassMouse:
- switch ( GetEventKind( event ) )
- {
- case kEventMouseUp:
- case kEventMouseMoved:
- case kEventMouseDragged:
- if ( fl_capture )
- ret = SendEventToEventTarget( event, GetWindowEventTarget( fl_capture ) );
- else if ( fl_os_capture ){
- ret = SendEventToEventTarget( event, GetWindowEventTarget( fl_os_capture ) );
- fl_os_capture = 0;
- }
- break;
- }
- break;
- case kEventClassCommand:
- switch (GetEventKind( event ) )
- {
- case kEventCommandProcess:
- ret = GetEventParameter( event, kEventParamDirectObject, typeHICommand, NULL, sizeof(HICommand), NULL, &cmd );
- if (ret == noErr && (cmd.attributes & kHICommandFromMenu) != 0)
- ret = HandleMenu( &cmd );
- else
- ret = eventNotHandledErr;
- break;
- }
- break;
- case kEventClassFLTK:
- switch ( GetEventKind( event ) )
- {
- case kEventFLTKBreakLoop:
- ret = noErr;
- break;
- case kEventFLTKDataReady:
- {
- dataready.CancelThread(DEBUGTEXT("DATA READY EVENT\n"));
-
- // CHILD THREAD TELLS US DATA READY
- // Check to see what's ready, and invoke user's cb's
- //
- fd_set r,w,x;
- switch(dataready.CheckData(r,w,x))
- {
- case 0: // NO DATA
- break;
- case -1: // ERROR
- break;
- default: // DATA READY
- dataready.HandleData(r,w,x);
- break;
- }
- }
- ret = noErr;
- break;
- }
- }
- if ( ret == eventNotHandledErr )
- ret = CallNextEventHandler( nextHandler, event ); // let the OS handle the activation, but continue to get a click-through effect
-
- fl_unlock_function();
-
- return ret;
-}
-
-
-/**
- * break the current event loop
- */
-static void breakMacEventLoop()
-{
- EventRef breakEvent;
-
- fl_lock_function();
-
- CreateEvent( 0, kEventClassFLTK, kEventFLTKBreakLoop, 0, kEventAttributeUserEvent, &breakEvent );
- PostEventToQueue( GetCurrentEventQueue(), breakEvent, kEventPriorityStandard );
- ReleaseEvent( breakEvent );
-
- fl_unlock_function();
-}
-
-//
-// MacOS X timers
-//
-
-struct MacTimeout {
- Fl_Timeout_Handler callback;
- void* data;
- EventLoopTimerRef timer;
- EventLoopTimerUPP upp;
- char pending;
-};
-static MacTimeout* mac_timers;
-static int mac_timer_alloc;
-static int mac_timer_used;
-
-
-static void realloc_timers()
-{
- if (mac_timer_alloc == 0) {
- mac_timer_alloc = 8;
- }
- mac_timer_alloc *= 2;
- MacTimeout* new_timers = new MacTimeout[mac_timer_alloc];
- memset(new_timers, 0, sizeof(MacTimeout)*mac_timer_alloc);
- memcpy(new_timers, mac_timers, sizeof(MacTimeout) * mac_timer_used);
- MacTimeout* delete_me = mac_timers;
- mac_timers = new_timers;
- delete [] delete_me;
-}
-
-static void delete_timer(MacTimeout& t)
-{
- if (t.timer) {
- RemoveEventLoopTimer(t.timer);
- DisposeEventLoopTimerUPP(t.upp);
- memset(&t, 0, sizeof(MacTimeout));
- }
-}
-
-
-static pascal void do_timer(EventLoopTimerRef timer, void* data)
-{
- for (int i = 0; i < mac_timer_used; ++i) {
- MacTimeout& t = mac_timers[i];
- if (t.timer == timer && t.data == data) {
- t.pending = 0;
- (*t.callback)(data);
- if (t.pending==0)
- delete_timer(t);
- break;
- }
- }
- breakMacEventLoop();
-}
-
-/**
- * This function is the central event handler.
- * It reads events from the event queue using the given maximum time
- * Funny enough, it returns the same time that it got as the argument.
- */
-static double do_queued_events( double time = 0.0 )
-{
- static bool been_here = false;
- static RgnHandle rgn;
-
- // initialize events and a region that enables mouse move events
- if (!been_here) {
- rgn = NewRgn();
- Point mp;
- GetMouse(&mp);
- SetRectRgn(rgn, mp.h, mp.v, mp.h, mp.v);
- SetEventMask(everyEvent);
- been_here = true;
- }
- OSStatus ret;
- static EventTargetRef target = 0;
- if ( !target )
- {
- target = GetEventDispatcherTarget();
-
- EventHandlerUPP dispatchHandler = NewEventHandlerUPP( carbonDispatchHandler ); // will not be disposed by Carbon...
- static EventTypeSpec dispatchEvents[] = {
- { kEventClassWindow, kEventWindowShown },
- { kEventClassWindow, kEventWindowHidden },
- { kEventClassWindow, kEventWindowActivated },
- { kEventClassWindow, kEventWindowDeactivated },
- { kEventClassWindow, kEventWindowClose },
- { kEventClassKeyboard, kEventRawKeyDown },
- { kEventClassKeyboard, kEventRawKeyRepeat },
- { kEventClassKeyboard, kEventRawKeyUp },
- { kEventClassKeyboard, kEventRawKeyModifiersChanged },
- { kEventClassMouse, kEventMouseDown },
- { kEventClassMouse, kEventMouseUp },
- { kEventClassMouse, kEventMouseMoved },
- { kEventClassMouse, 11 }, // MightyMouse wheels
- { kEventClassMouse, kEventMouseWheelMoved },
- { kEventClassMouse, kEventMouseDragged },
- { kEventClassFLTK, kEventFLTKBreakLoop },
- { kEventClassFLTK, kEventFLTKDataReady } };
- ret = InstallEventHandler( target, dispatchHandler, GetEventTypeCount(dispatchEvents), dispatchEvents, 0, 0L );
- static EventTypeSpec appEvents[] = {
- { kEventClassCommand, kEventCommandProcess } };
- ret = InstallApplicationEventHandler( dispatchHandler, GetEventTypeCount(appEvents), appEvents, 0, 0L );
- }
-
- got_events = 0;
-
- // Check for re-entrant condition
- if ( dataready.IsThreadRunning() )
- { dataready.CancelThread(DEBUGTEXT("AVOID REENTRY\n")); }
-
- // Start thread to watch for data ready
- if ( dataready.GetNfds() )
- { dataready.StartThread((void*)GetCurrentEventQueue()); }
-
- fl_unlock_function();
-
- EventRef event;
- EventTimeout timeout = time;
- if (!ReceiveNextEvent(0, NULL, timeout, true, &event)) {
- got_events = 1;
- OSErr ret = SendEventToEventTarget( event, target );
- if (ret!=noErr) {
- EventRecord clevent;
- ConvertEventRefToEventRecord(event, &clevent);
- if (clevent.what==kHighLevelEvent) {
- ret = AEProcessAppleEvent(&clevent);
- }
- }
- if ( ret==eventNotHandledErr
- && GetEventClass(event)==kEventClassMouse
- && GetEventKind(event)==kEventMouseDown ) {
- WindowRef win; Point pos;
- GetEventParameter(event, kEventParamMouseLocation, typeQDPoint,
- NULL, sizeof(pos), NULL, &pos);
- if (MacFindWindow(pos, &win)==inMenuBar) {
- MenuSelect(pos);
- }
- }
- ReleaseEvent( event );
- }
-
- fl_lock_function();
-
-#if CONSOLIDATE_MOTION
- if (send_motion && send_motion == fl_xmousewin) {
- send_motion = 0;
- Fl::handle(FL_MOVE, fl_xmousewin);
- }
-#endif
-
- return time;
-}
-
-
-/**
- * This public function handles all events. It wait a maximum of
- * 'time' secods for an event. This version returns 1 if events
- * other than the timeout timer were processed.
- *
- * \todo there is no socket handling in this code whatsoever
- */
-int fl_wait( double time )
-{
- do_queued_events( time );
- return (got_events);
-}
-
-
-/**
- * event handler for Apple-Q key combination
- * this is also called from the Carbon Window handler after all windows were closed
- */
-static OSErr QuitAppleEventHandler( const AppleEvent *appleEvt, AppleEvent* reply, UInt32 refcon )
-{
- fl_lock_function();
-
- while ( Fl_X::first ) {
- Fl_X *x = Fl_X::first;
- Fl::handle( FL_CLOSE, x->w );
- if ( Fl_X::first == x ) {
- fl_unlock_function();
- return noErr; // FLTK has not close all windows, so we return to the main program now
- }
- }
-
- fl_unlock_function();
-
- return noErr;
-}
-
-
-/**
- * Carbon Window handler
- * This needs to be linked into all new window event handlers
- */
-static pascal OSStatus carbonWindowHandler( EventHandlerCallRef nextHandler, EventRef event, void *userData )
-{
- UInt32 kind = GetEventKind( event );
- OSStatus ret = eventNotHandledErr;
- Fl_Window *window = (Fl_Window*)userData;
- Fl::first_window(window);
-
- Rect currentBounds, originalBounds;
- WindowClass winClass;
- static Fl_Window *activeWindow = 0;
-
- fl_lock_function();
-
- switch ( kind )
- {
- case kEventWindowBoundsChanging:
- GetEventParameter( event, kEventParamCurrentBounds, typeQDRectangle, NULL, sizeof(Rect), NULL, &currentBounds );
- GetEventParameter( event, kEventParamOriginalBounds, typeQDRectangle, NULL, sizeof(Rect), NULL, &originalBounds );
- break;
- case kEventWindowDrawContent:
- handleUpdateEvent( fl_xid( window ) );
- ret = noErr;
- break;
- case kEventWindowBoundsChanged: {
- GetEventParameter( event, kEventParamCurrentBounds, typeQDRectangle, NULL, sizeof(Rect), NULL, &currentBounds );
- GetEventParameter( event, kEventParamOriginalBounds, typeQDRectangle, NULL, sizeof(Rect), NULL, &originalBounds );
- int X = currentBounds.left, W = currentBounds.right-X;
- int Y = currentBounds.top, H = currentBounds.bottom-Y;
- resize_from_system = window;
- window->resize( X, Y, W, H );
- if ( ( originalBounds.right - originalBounds.left != W )
- || ( originalBounds.bottom - originalBounds.top != H ) )
- {
- if ( window->shown() )
- handleUpdateEvent( fl_xid( window ) );
- }
- break; }
- case kEventWindowShown:
- if ( !window->parent() )
- {
- GetWindowClass( fl_xid( window ), &winClass );
- if ( winClass != kHelpWindowClass ) { // help windows can't get the focus!
- Fl::handle( FL_FOCUS, window);
- activeWindow = window;
- }
- Fl::handle( FL_SHOW, window);
- mods_to_e_state(GetCurrentKeyModifiers());
- }
- break;
- case kEventWindowHidden:
- if ( !window->parent() ) Fl::handle( FL_HIDE, window);
- break;
- case kEventWindowActivated:
- if ( window->shown() && window!=activeWindow )
- {
- GetWindowClass( fl_xid( window ), &winClass );
- if ( winClass != kHelpWindowClass ) { // help windows can't get the focus!
- Fl::handle( FL_FOCUS, window);
- activeWindow = window;
- }
- }
- break;
- case kEventWindowDeactivated:
- if ( window==activeWindow )
- {
- Fl::handle( FL_UNFOCUS, window);
- activeWindow = 0;
- }
- break;
- case kEventWindowClose:
- Fl::handle( FL_CLOSE, window ); // this might or might not close the window
- // if there are no more windows, send a high-level quit event
- if (!Fl_X::first) QuitAppleEventHandler( 0, 0, 0 );
- ret = noErr; // returning noErr tells Carbon to stop following up on this event
- break;
- case kEventWindowCollapsed:
- window->clear_visible();
- break;
- case kEventWindowExpanded:
- window->set_visible();
- break;
- }
-
- fl_unlock_function();
-
- return ret;
-}
-
-
-/**
- * Carbon Mousewheel handler
- * This needs to be linked into all new window event handlers
- */
-static pascal OSStatus carbonMousewheelHandler( EventHandlerCallRef nextHandler, EventRef event, void *userData )
-{
- // Handle the new "MightyMouse" mouse wheel events. Please, someone explain
- // to me why Apple changed the API on this even though the current API
- // supports two wheels just fine. Matthias,
- fl_lock_function();
-
- fl_os_event = event;
- Fl_Window *window = (Fl_Window*)userData;
- if ( !window->shown() )
- {
- fl_unlock_function();
- return noErr;
- }
- Fl::first_window(window);
-
- EventMouseWheelAxis axis;
- GetEventParameter( event, kEventParamMouseWheelAxis, typeMouseWheelAxis, NULL, sizeof(EventMouseWheelAxis), NULL, &axis );
- long delta;
- GetEventParameter( event, kEventParamMouseWheelDelta, typeLongInteger, NULL, sizeof(long), NULL, &delta );
-// fprintf(stderr, "axis=%d, delta=%d\n", axis, delta);
- if ( axis == kEventMouseWheelAxisX ) {
- Fl::e_dx = -delta;
- Fl::e_dy = 0;
- if ( Fl::e_dx) Fl::handle( FL_MOUSEWHEEL, window );
- } else if ( axis == kEventMouseWheelAxisY ) {
- Fl::e_dx = 0;
- Fl::e_dy = -delta;
- if ( Fl::e_dy) Fl::handle( FL_MOUSEWHEEL, window );
- } else {
- fl_unlock_function();
-
- return eventNotHandledErr;
- }
-
- fl_unlock_function();
-
- return noErr;
-}
-
-
-/**
- * convert the current mouse chord into the FLTK modifier state
- */
-static void chord_to_e_state( UInt32 chord )
-{
- static ulong state[] =
- {
- 0, FL_BUTTON1, FL_BUTTON3, FL_BUTTON1|FL_BUTTON3, FL_BUTTON2,
- FL_BUTTON2|FL_BUTTON1, FL_BUTTON2|FL_BUTTON3,
- FL_BUTTON2|FL_BUTTON1|FL_BUTTON3
- };
- Fl::e_state = ( Fl::e_state & 0xff0000 ) | state[ chord & 0x07 ];
-}
-
-
-/**
- * Carbon Mouse Button Handler
- */
-static pascal OSStatus carbonMouseHandler( EventHandlerCallRef nextHandler, EventRef event, void *userData )
-{
- static int keysym[] = { 0, FL_Button+1, FL_Button+3, FL_Button+2 };
- static int px, py;
- static char suppressed = 0;
-
- fl_lock_function();
-
- fl_os_event = event;
- Fl_Window *window = (Fl_Window*)userData;
- if ( !window->shown() )
- {
- fl_unlock_function();
- return noErr;
- }
- Fl::first_window(window);
- Point pos;
- GetEventParameter( event, kEventParamMouseLocation, typeQDPoint, NULL, sizeof(Point), NULL, &pos );
- EventMouseButton btn;
- GetEventParameter( event, kEventParamMouseButton, typeMouseButton, NULL, sizeof(EventMouseButton), NULL, &btn );
- UInt32 clickCount;
- GetEventParameter( event, kEventParamClickCount, typeUInt32, NULL, sizeof(UInt32), NULL, &clickCount );
- UInt32 chord;
- GetEventParameter( event, kEventParamMouseChord, typeUInt32, NULL, sizeof(UInt32), NULL, &chord );
- WindowRef xid = fl_xid(window), tempXid;
- int sendEvent = 0, part = 0;
- switch ( GetEventKind( event ) )
- {
- case kEventMouseDown:
- part = FindWindow( pos, &tempXid );
- if (!(Fl::grab() && window!=Fl::grab())) {
- if ( part == inGrow ) {
- fl_unlock_function();
- suppressed = 1;
- Fl_Tooltip::current(0L);
- return CallNextEventHandler( nextHandler, event ); // let the OS handle this for us
- }
- if ( part != inContent ) {
- fl_unlock_function();
- suppressed = 1;
- Fl_Tooltip::current(0L);
- // anything else to here?
- return CallNextEventHandler( nextHandler, event ); // let the OS handle this for us
- }
- }
- suppressed = 0;
- if (part==inContent && !IsWindowActive( xid ) ) {
- CallNextEventHandler( nextHandler, event ); // let the OS handle the activation, but continue to get a click-through effect
- }
- // normal handling of mouse-down follows
- fl_os_capture = xid;
- sendEvent = FL_PUSH;
- Fl::e_is_click = 1; px = pos.h; py = pos.v;
- if (clickCount>1)
- Fl::e_clicks++;
- else
- Fl::e_clicks = 0;
- // fall through
- case kEventMouseUp:
- if (suppressed) {
- suppressed = 0;
- break;
- }
- if ( !window ) break;
- if ( !sendEvent ) {
- sendEvent = FL_RELEASE;
- }
- Fl::e_keysym = keysym[ btn ];
- // fall through
- case kEventMouseMoved:
- suppressed = 0;
- if ( !sendEvent ) {
- sendEvent = FL_MOVE; chord = 0;
- }
- // fall through
- case kEventMouseDragged:
- if (suppressed) break;
- if ( !sendEvent ) {
- sendEvent = FL_MOVE; // Fl::handle will convert into FL_DRAG
- if (abs(pos.h-px)>5 || abs(pos.v-py)>5)
- Fl::e_is_click = 0;
- }
- chord_to_e_state( chord );
- GrafPtr oldPort;
- GetPort( &oldPort );
- SetPort( GetWindowPort(xid) ); // \todo replace this! There must be some GlobalToLocal call that has a port as an argument
- SetOrigin(0, 0);
- Fl::e_x_root = pos.h;
- Fl::e_y_root = pos.v;
- GlobalToLocal( &pos );
- Fl::e_x = pos.h;
- Fl::e_y = pos.v;
- SetPort( oldPort );
- if (GetEventKind(event)==kEventMouseDown && part!=inContent) {
- int used = Fl::handle( sendEvent, window );
- CallNextEventHandler( nextHandler, event ); // let the OS handle this for us
- if (!used)
- suppressed = 1;
- } else {
- Fl::handle( sendEvent, window );
- }
- break;
- }
-
- fl_unlock_function();
-
- return noErr;
-}
-
-
-/**
- * convert the keyboard return code into the symbol on the keycaps
- */
-static unsigned short keycode_to_sym( UInt32 keyCode, UInt32 mods, unsigned short deflt )
-{
- static Ptr map = 0;
- UInt32 state = 0;
- if (!map) {
- map = (Ptr)GetScriptManagerVariable(smKCHRCache);
- if (!map) {
- long kbID = GetScriptManagerVariable(smKeyScript);
- map = *GetResource('KCHR', kbID);
- }
- }
- if (map)
- return KeyTranslate(map, keyCode|mods, &state );
- return deflt;
-}
-
-/*
- * keycode_function for post-10.5 systems, allows more sophisticated decoding of keys
- */
-static int keycodeToUnicode(
- char * uniChars, int maxChars,
- EventKind eKind,
- UInt32 keycode, UInt32 modifiers,
- UInt32 * deadKeyStatePtr,
- unsigned char, // not used in this function
- unsigned short) // not used in this function
-{
- // first get the keyboard mapping in a post 10.2 way
-
- Ptr resource;
- TextEncoding encoding;
- static TextEncoding lastEncoding = kTextEncodingMacRoman;
- int len = 0;
- KeyboardLayoutRef currentLayout = NULL;
- static KeyboardLayoutRef lastLayout = NULL;
- SInt32 currentLayoutId = 0;
- static SInt32 lastLayoutId;
- int hasLayoutChanged = false;
- static Ptr uchr = NULL;
- static Ptr KCHR = NULL;
- // ScriptCode currentKeyScript;
-
- KLGetCurrentKeyboardLayout(&currentLayout);
- if (currentLayout) {
- KLGetKeyboardLayoutProperty(currentLayout, kKLIdentifier, (const void**)&currentLayoutId);
- if ( (lastLayout != currentLayout) || (lastLayoutId != currentLayoutId) ) {
- lastLayout = currentLayout;
- lastLayoutId = currentLayoutId;
- uchr = NULL;
- KCHR = NULL;
- if ((KLGetKeyboardLayoutProperty(currentLayout, kKLuchrData, (const void**)&uchr) == noErr) && (uchr != NULL)) {
- // done
- } else if ((KLGetKeyboardLayoutProperty(currentLayout, kKLKCHRData, (const void**)&KCHR) == noErr) && (KCHR != NULL)) {
- // done
- }
- // FIXME No Layout property found. Now we have a problem.
- }
- }
- if (hasLayoutChanged) {
- //deadKeyStateUp = deadKeyStateDown = 0;
- if (KCHR != NULL) {
- // FIXME this must not happen
- } else if (uchr == NULL) {
- KCHR = (Ptr) GetScriptManagerVariable(smKCHRCache);
- }
- }
- if (uchr != NULL) {
- // this is what I expect
- resource = uchr;
- } else {
- resource = KCHR;
- encoding = lastEncoding;
- // this is actually not supported by the following code and will likely crash
- }
-
- // now apply that keyboard mapping to our keycode
-
- int action;
- //OptionBits options = 0;
- // not used yet: OptionBits options = kUCKeyTranslateNoDeadKeysMask;
- unsigned long keyboardType;
- keycode &= 0xFF;
- modifiers = (modifiers >> 8) & 0xFF;
- keyboardType = LMGetKbdType();
- OSStatus status;
- UniCharCount actuallength;
- UniChar utext[10];
-
- switch(eKind) {
- case kEventRawKeyDown: action = kUCKeyActionDown; break;
- case kEventRawKeyUp: action = kUCKeyActionUp; break;
- case kEventRawKeyRepeat: action = kUCKeyActionAutoKey; break;
- default: return 0;
- }
-
- UInt32 deadKeyState = *deadKeyStatePtr;
- if ((action==kUCKeyActionUp)&&(*deadKeyStatePtr))
- deadKeyStatePtr = &deadKeyState;
-
- status = UCKeyTranslate(
- (const UCKeyboardLayout *) uchr,
- keycode, action, modifiers, keyboardType,
- 0, deadKeyStatePtr,
- 10, &actuallength, utext);
-
- if (noErr != status) {
- fprintf(stderr,"UCKeyTranslate failed: %d\n", (int) status);
- actuallength = 0;
- }
-
- // convert the list of unicode chars into utf8
- // FIXME no bounds check (see maxchars)
- unsigned i;
- for (i=0; i<actuallength; ++i) {
- len += fl_utf8encode(utext[i], uniChars+len);
- }
- uniChars[len] = 0;
- return len;
-}
-
-/*
- * keycode_function for pre-10.5 systems, this is the "historic" fltk Mac key handling
- */
-static int keycode_wrap_old(
- char * buffer,
- int, EventKind, UInt32, // not used in this function
- UInt32, UInt32 *, // not used in this function
- unsigned char key,
- unsigned short sym)
-{
- if ( (sym >= FL_KP && sym <= FL_KP_Last) || !(sym & 0xff00) ||
- sym == FL_Tab || sym == FL_Enter) {
- buffer[0] = key;
- return 1;
- } else {
- buffer[0] = 0;
- return 0;
- }
-} /* keycode_wrap_old */
-/*
- * Stub pointer to select appropriate keycode_function per operating system version. This function pointer
- * is initialised in fl_open_display, based on the runtime identification of the host OS version. This is
- * intended to allow us to utilise 10.5 services dynamically to improve Unicode handling, whilst still
- * allowing code to run satisfactorily on older systems.
- */
-static int (*keycode_function)(char*, int, EventKind, UInt32, UInt32, UInt32*, unsigned char, unsigned short) = keycode_wrap_old;
-
-
-// EXPERIMENTAL!
-pascal OSStatus carbonTextHandler(
- EventHandlerCallRef nextHandler, EventRef event, void *userData )
-{
- Fl_Window *window = (Fl_Window*)userData;
- Fl::first_window(window);
- fl_lock_function();
- //int kind = GetEventKind(event);
- unsigned short buf[200];
- ByteCount size;
- GetEventParameter( event, kEventParamTextInputSendText, typeUnicodeText,
- NULL, 100, &size, &buf );
-// printf("TextEvent: %02x %02x %02x %02x\n", buf[0], buf[1], buf[2], buf[3]);
- // FIXME: oversimplified!
- unsigned ucs = buf[0];
- char utf8buf[20];
- int len = fl_utf8encode(ucs, utf8buf);
- Fl::e_length = len;
- Fl::e_text = utf8buf;
- while (window->parent()) window = window->window();
- Fl::handle(FL_KEYBOARD, window);
- fl_unlock_function();
- fl_lock_function();
- Fl::handle(FL_KEYUP, window);
- fl_unlock_function();
- // 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();
- return noErr;
-}
-
-/**
- * handle carbon keyboard events
- */
-pascal OSStatus carbonKeyboardHandler(
- EventHandlerCallRef nextHandler, EventRef event, void *userData )
-{
- static char buffer[32];
- int sendEvent = 0;
- Fl_Window *window = (Fl_Window*)userData;
- Fl::first_window(window);
- UInt32 mods;
- static UInt32 prevMods = mods_to_e_state( GetCurrentKeyModifiers() );
-
- fl_lock_function();
-
- int kind = GetEventKind(event);
-
- // get the modifiers for any of the events
- GetEventParameter( event, kEventParamKeyModifiers, typeUInt32,
- NULL, sizeof(UInt32), NULL, &mods );
-
- // get the key code only for key events
- UInt32 keyCode = 0, maskedKeyCode = 0;
- unsigned char key = 0;
- unsigned short sym = 0;
- if (kind!=kEventRawKeyModifiersChanged) {
- GetEventParameter( event, kEventParamKeyCode, typeUInt32,
- NULL, sizeof(UInt32), NULL, &keyCode );
- GetEventParameter( event, kEventParamKeyMacCharCodes, typeChar,
- NULL, sizeof(char), NULL, &key );
- }
- // extended keyboards can also send sequences on key-up to generate Kanji etc. codes.
- // Some observed prefixes are 0x81 to 0x83, followed by an 8 bit keycode.
- // In this mode, there seem to be no key-down codes
-// printf("%08x %08x %08x\n", keyCode, mods, key);
- maskedKeyCode = keyCode & 0x7f;
- /* output a human readable event identifier for debugging
- const char *ev = "";
- switch (kind) {
- case kEventRawKeyDown: ev = "kEventRawKeyDown"; break;
- case kEventRawKeyRepeat: ev = "kEventRawKeyRepeat"; break;
- case kEventRawKeyUp: ev = "kEventRawKeyUp"; break;
- case kEventRawKeyModifiersChanged: ev = "kEventRawKeyModifiersChanged"; break;
- default: ev = "unknown";
- }
- printf("%08x %08x %08x '%c' %s \n", mods, keyCode, key, key, ev);
- */
- switch (kind)
- {
- case kEventRawKeyDown:
- case kEventRawKeyRepeat:
-/*
- // FIXME Matt: For 10.5, the keycode_function will handle all this. This is untested for ealier versions of OS X.
- // When the user presses a "dead key", no information is send about
- // which dead key symbol was created. So we need to trick Carbon into
- // giving us the code by sending a "space" after the "dead key".
- if (key==0) {
- UInt32 ktState = 0;
- KeyboardLayoutRef klr;
- KLGetCurrentKeyboardLayout(&klr);
- const void *kchar = 0; KLGetKeyboardLayoutProperty(klr, kKLKCHRData, &kchar);
- KeyTranslate(kchar, (mods&0xff00) | keyCode, &ktState); // send the dead key
- key = KeyTranslate(kchar, 0x31, &ktState); // fake a space key press
- Fl::e_state |= 0x40000000; // mark this as a dead key
- } else {
- Fl::e_state &= 0xbfffffff; // clear the deadkey flag
- }
-*/
- sendEvent = FL_KEYBOARD;
- // fall through
- case kEventRawKeyUp:
- if ( !sendEvent ) {
- sendEvent = FL_KEYUP;
- Fl::e_state &= 0xbfffffff; // clear the deadkey flag
- }
- // if the user pressed alt/option, event_key should have the keycap,
- // but event_text should generate the international symbol
- sym = macKeyLookUp[maskedKeyCode];
- if ( isalpha(key) )
- sym = tolower(key);
- else if ( Fl::e_state&FL_CTRL && key<32 && sym<0xff00)
- sym = key+96;
- else if ( Fl::e_state&FL_ALT && sym<0xff00) // find the keycap of this key
- sym = keycode_to_sym( maskedKeyCode, 0, macKeyLookUp[ maskedKeyCode ] );
- Fl::e_keysym = Fl::e_original_keysym = sym;
- // Handle FL_KP_Enter on regular keyboards and on Powerbooks
- if ( maskedKeyCode==0x4c || maskedKeyCode==0x34) key=0x0d;
- // Handle the Delete key on the keypad
- // Matt: the Mac has no concept of a NumLock key, or at least not visible
- // Matt: to Carbon. The kEventKeyModifierNumLockMask is only set when
- // Matt: a numeric keypad key is pressed and does not correspond with
- // Matt: the NumLock light in PowerBook keyboards.
-
- // Matt: attempt to get the correct Unicode character(s) from our keycode
- // imm: keycode_function function pointer added to allow us to use different functions
- // imm: depending on which OS version we are running on (tested and set in fl_open_display)
- static UInt32 deadKeyState = 0; // must be cleared when losing focus
- Fl::e_length = (*keycode_function)(buffer, 31, kind, keyCode, mods, &deadKeyState, key, sym);
- Fl::e_text = buffer;
- buffer[Fl::e_length] = 0; // just in case...
- break;
- case kEventRawKeyModifiersChanged: {
- UInt32 tMods = prevMods ^ mods;
- if ( tMods )
- {
- mods_to_e_keysym( tMods );
- if ( Fl::e_keysym )
- sendEvent = ( prevMods<mods ) ? FL_KEYBOARD : FL_KEYUP;
- Fl::e_length = 0;
- buffer[0] = 0;
- prevMods = mods;
- }
- mods_to_e_state( mods );
- break; }
- }
- while (window->parent()) window = window->window();
- if (sendEvent && Fl::handle(sendEvent,window)) {
- fl_unlock_function();
- return noErr; // return noErr if FLTK handled the event
- } else {
- fl_unlock_function();
- //return CallNextEventHandler( nextHandler, event );;
- // Matt: I had better results (no duplicate events) always returning
- // Matt: 'noErr'. System keyboard events still seem to work just fine.
- return noErr;
- }
-}
-
-
-
-/**
- * Open callback function to call...
- */
-
-static void (*open_cb)(const char *) = 0;
-
-
-/**
- * Event handler for Apple-O key combination and also for file opens
- * via the finder...
- */
-
-static OSErr OpenAppleEventHandler(const AppleEvent *appleEvt,
- AppleEvent *reply,
- UInt32 refcon) {
- OSErr err;
- AEDescList documents;
- long i, n;
- FSSpec fileSpec;
- AEKeyword keyWd;
- DescType typeCd;
- Size actSz;
- char filename[1024];
-
- if (!open_cb) return noErr;
-
- // Initialize the document list...
- AECreateDesc(typeNull, NULL, 0, &documents);
-
- // Get the open parameter(s)...
- err = AEGetParamDesc(appleEvt, keyDirectObject, typeAEList, &documents);
- if (err != noErr) {
- AEDisposeDesc(&documents);
- return err;
- }
-
- // Lock access to FLTK in this thread...
- fl_lock_function();
-
- // Open the documents via the callback...
- if (AECountItems(&documents, &n) == noErr) {
- for (i = 1; i <= n; i ++) {
- // Get the next FSSpec record...
- AEGetNthPtr(&documents, i, typeFSS, &keyWd, &typeCd,
- (Ptr)&fileSpec, sizeof(fileSpec),
- (actSz = sizeof(fileSpec), &actSz));
-
- // Convert to a UNIX path...
- FSSpec2UnixPath(&fileSpec, filename);
-
- // Call the callback with the filename...
- (*open_cb)(filename);
- }
- }
-
- // Unlock access to FLTK for all threads...
- fl_unlock_function();
-
- // Get rid of the document list...
- AEDisposeDesc(&documents);
-
- return noErr;
-}
-
-
-/**
- * Install an open documents event handler...
- */
-
-void fl_open_callback(void (*cb)(const char *)) {
- open_cb = cb;
- if (cb) {
- AEInstallEventHandler(kCoreEventClass, kAEOpenDocuments,
- NewAEEventHandlerUPP((AEEventHandlerProcPtr)
- OpenAppleEventHandler), 0, false);
- } else {
- AERemoveEventHandler(kCoreEventClass, kAEOpenDocuments,
- NewAEEventHandlerUPP((AEEventHandlerProcPtr)
- OpenAppleEventHandler), false);
- }
-}
-
-
-/**
- * initialize the Mac toolboxes, dock status, and set the default menubar
- */
-
-extern "C" {
- extern OSErr CPSEnableForegroundOperation(ProcessSerialNumber *psn, UInt32 _arg2,
- UInt32 _arg3, UInt32 _arg4, UInt32 _arg5);
-}
-
-void fl_open_display() {
- static char beenHereDoneThat = 0;
- if ( !beenHereDoneThat ) {
- beenHereDoneThat = 1;
-
- FlushEvents(everyEvent,0);
-
- MoreMasters(); // \todo Carbon suggests MoreMasterPointers()
- AEInstallEventHandler( kCoreEventClass, kAEQuitApplication, NewAEEventHandlerUPP((AEEventHandlerProcPtr)QuitAppleEventHandler), 0, false );
-
- // create the Mac Handle for the default cursor (a pointer to a pointer)
- GetQDGlobalsArrow(&default_cursor);
- default_cursor_ptr = &default_cursor;
- fl_default_cursor = &default_cursor_ptr;
-
- ClearMenuBar();
- AppendResMenu( GetMenuHandle( 1 ), 'DRVR' );
- DrawMenuBar();
-
- // bring the application into foreground without a 'CARB' resource
- Boolean same_psn;
- ProcessSerialNumber cur_psn, front_psn;
- if( !GetCurrentProcess( &cur_psn ) && !GetFrontProcess( &front_psn ) &&
- !SameProcess( &front_psn, &cur_psn, &same_psn ) && !same_psn )
- {
- // only transform the application type for unbundled apps
- CFBundleRef bundle = CFBundleGetMainBundle();
- if( bundle )
- {
- FSRef execFs;
- CFURLRef execUrl = CFBundleCopyExecutableURL( bundle );
- CFURLGetFSRef( execUrl, &execFs );
-
- FSRef bundleFs;
- GetProcessBundleLocation( &cur_psn, &bundleFs );
-
- if( !FSCompareFSRefs( &execFs, &bundleFs ) )
- bundle = NULL;
-
- CFRelease(execUrl);
- }
-
- if( !bundle )
- {
- // Earlier versions of this code tried to use weak linking, however it
- // appears that this does not work on 10.2. Since 10.3 and higher provide
- // both TransformProcessType and CPSEnableForegroundOperation, the following
- // conditional code compiled on 10.2 will still work on newer releases...
- OSErr err;
-
-#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2
- if (TransformProcessType != NULL) {
- err = TransformProcessType(&cur_psn, kProcessTransformToForegroundApplication);
- } else
-#endif // MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2
- err = CPSEnableForegroundOperation(&cur_psn, 0x03, 0x3C, 0x2C, 0x1103);
-
- if (err == noErr) {
- SetFrontProcess( &cur_psn );
- }
- }
- }
-
- // imm: keycode handler stub setting - use Gestalt to determine the running system version,
- // then set the keycode_function pointer accordingly
- keycode_function = keycode_wrap_old; // default to pre-10.5 mechanism
- SInt32 MacVersion;
- if (Gestalt(gestaltSystemVersion, &MacVersion) == noErr)
- {
- if(MacVersion >= 0x1050) { // 10.5.0 or later
- keycode_function = keycodeToUnicode;
- }
- }
- }
-}
-
-
-/**
- * get rid of allocated resources
- */
-void fl_close_display() {
-}
-
-
-/**
- * smallest x ccordinate in screen space
- */
-int Fl::x() {
- BitMap r;
- GetQDGlobalsScreenBits(&r);
- return r.bounds.left;
-}
-
-
-/**
- * smallest y ccordinate in screen space
- */
-int Fl::y() {
- BitMap r;
- GetQDGlobalsScreenBits(&r);
- return r.bounds.top + 20; // \todo 20 pixel menu bar?
-}
-
-
-/**
- * screen width (single monitor!?)
- */
-int Fl::w() {
- BitMap r;
- GetQDGlobalsScreenBits(&r);
- return r.bounds.right - r.bounds.left;
-}
-
-
-/**
- * screen height (single monitor!?)
- */
-int Fl::h() {
- BitMap r;
- GetQDGlobalsScreenBits(&r);
- return r.bounds.bottom - r.bounds.top - 20;
-}
-
-
-/**
- * get the current mouse pointer world coordinates
- */
-void Fl::get_mouse(int &x, int &y)
-{
- fl_open_display();
- Point loc;
- GetMouse( &loc );
- LocalToGlobal( &loc );
- x = loc.h;
- y = loc.v;
-}
-
-
-/**
- * convert Mac keystrokes to FLTK
- */
-unsigned short mac2fltk(ulong macKey)
-{
- unsigned short cc = macKeyLookUp[(macKey>>8)&0x7f];
- if (cc) return cc;
- return macKey&0xff;
-}
-
-
-/**
- * Initialize the given port for redraw and call the windw's flush() to actually draw the content
- */
-void Fl_X::flush()
-{
- w->flush();
- if (fl_gc)
- CGContextFlush(fl_gc);
- SetOrigin( 0, 0 );
-}
-
-
-/**
- * Handle all clipping and redraw for the given port
- * There are two different callers for this event:
- * 1: the OS can request a redraw and provides all clipping itself
- * 2: Fl::flush() wants all redraws now
- */
-void handleUpdateEvent( WindowPtr xid )
-{
- Fl_Window *window = fl_find( xid );
- if ( !window ) return;
- GrafPtr oldPort;
- GetPort( &oldPort );
- SetPort( GetWindowPort(xid) );
- Fl_X *i = Fl_X::i( window );
- i->wait_for_expose = 0;
- if ( window->damage() ) {
- if ( i->region ) {
- InvalWindowRgn( xid, i->region );
- }
- }
- if ( i->region ) { // no region, so the sytem will take the update region from the OS
- DisposeRgn( i->region );
- i->region = 0;
- }
- for ( Fl_X *cx = i->xidChildren; cx; cx = cx->xidNext )
- {
- cx->w->clear_damage(window->damage()|FL_DAMAGE_EXPOSE);
- cx->flush();
- cx->w->clear_damage();
- }
- window->clear_damage(window->damage()|FL_DAMAGE_EXPOSE);
- i->flush();
- window->clear_damage();
- SetPort( oldPort );
-}
-
-// Gets the border sizes and the titlebar size
-static void get_window_frame_sizes(int &bx, int &by, int &bt) {
-#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2
- static HIRect contentRect = { {50,50}, {100,100} }; // a rect to stand in for the content rect of a real window
- static HIThemeWindowDrawInfo metrics= {0,
- kThemeStateActive, kThemeDocumentWindow,
- kThemeWindowHasFullZoom + kThemeWindowHasCloseBox +
- kThemeWindowHasCollapseBox + kThemeWindowHasTitleText,
- 0, 0};
- HIShapeRef shape1=0, shape2=0, shape3=0;
- HIRect rect1, rect2, rect3;
- OSStatus status;
- status = HIThemeGetWindowShape(&contentRect, &metrics, kWindowStructureRgn, &shape1);
- status |= HIThemeGetWindowShape(&contentRect, &metrics, kWindowContentRgn, &shape2);
- status |= HIThemeGetWindowShape(&contentRect, &metrics, kWindowTitleBarRgn, &shape3);
-
- if (!status)
- {
- HIShapeGetBounds(shape1, &rect1);
- HIShapeGetBounds(shape2, &rect2);
- HIShapeGetBounds(shape3, &rect3);
- bt = rect3.size.height;
- bx = rect2.origin.x - rect1.origin.x;
- by = rect2.origin.y - rect1.origin.y - bt;
- // fprintf(stderr, "HIThemeGetWindowShape succeeded bx=%d by=%d bt=%d\n", bx, by, bt);
- }
- else
-#endif // MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2
- {
- // sets default dimensions
- bx = by = 6;
- bt = 22;
- // fprintf(stderr, "HIThemeGetWindowShape failed, bx=%d by=%d bt=%d\n", bx, by, bt);
- }
-#if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2
- CFRelease(shape1); // we must free HIThemeGetWindowShape() (copied) handles
- CFRelease(shape2);
- CFRelease(shape3);
-#endif // MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_2
-}
-
-/**
- * \todo this is a leftover from OS9 times. Please check how much applies to Carbon!
- */
-int Fl_X::fake_X_wm(const Fl_Window* w,int &X,int &Y, int &bt,int &bx, int &by) {
- int W, H, xoff, yoff, dx, dy;
- int ret = bx = by = bt = 0;
- if (w->border() && !w->parent()) {
- if (w->maxw != w->minw || w->maxh != w->minh) {
- ret = 2;
- get_window_frame_sizes(bx, by, bt);
- /*
- bx = 6; // \todo Mac : GetSystemMetrics(SM_CXSIZEFRAME);
- by = 6; // \todo Mac : get Mac window frame size GetSystemMetrics(SM_CYSIZEFRAME);
- */
- } else {
- ret = 1;
- get_window_frame_sizes(bx, by, bt);
- /*
- bx = 6; // \todo Mac : GetSystemMetrics(SM_CXFIXEDFRAME);
- by = 6; // \todo Mac : GetSystemMetrics(SM_CYFIXEDFRAME);
- */
- }
- }
- //The coordinates of the whole window, including non-client area
- xoff = bx;
- yoff = by + bt;
- dx = 2*bx;
- dy = 2*by + bt;
- X = w->x()-xoff;
- Y = w->y()-yoff;
- W = w->w()+dx;
- H = w->h()+dy;
-
- //Proceed to positioning the window fully inside the screen, if possible
-
- // let's get a little elaborate here. Mac OS X puts a lot of stuff on the desk
- // that we want to avoid when positioning our window, namely the Dock and the
- // top menu bar (and even more stuff in 10.4 Tiger). So we will go through the
- // list of all available screens and find the one that this window is most
- // likely to go to, and then reposition it to fit withing the 'good' area.
- Rect r;
- // find the screen, that the center of this window will fall into
- int R = X+W, B = Y+H; // right and bottom
- int cx = (X+R)/2, cy = (Y+B)/2; // center of window;
- GDHandle gd = 0L;
- for (gd = GetDeviceList(); gd; gd = GetNextDevice(gd)) {
- GDPtr gp = *gd;
- if ( cx >= gp->gdRect.left && cx <= gp->gdRect.right
- && cy >= gp->gdRect.top && cy <= gp->gdRect.bottom)
- break;
- }
- // if the center doesn't fall on a screen, try the top left
- if (!gd) {
- for (gd = GetDeviceList(); gd; gd = GetNextDevice(gd)) {
- GDPtr gp = *gd;
- if ( X >= gp->gdRect.left && X <= gp->gdRect.right
- && Y >= gp->gdRect.top && Y <= gp->gdRect.bottom)
- break;
- }
- }
- // if that doesn't fall on a screen, try the top right
- if (!gd) {
- for (gd = GetDeviceList(); gd; gd = GetNextDevice(gd)) {
- GDPtr gp = *gd;
- if ( R >= gp->gdRect.left && R <= gp->gdRect.right
- && Y >= gp->gdRect.top && Y <= gp->gdRect.bottom)
- break;
- }
- }
- // if that doesn't fall on a screen, try the bottom left
- if (!gd) {
- for (gd = GetDeviceList(); gd; gd = GetNextDevice(gd)) {
- GDPtr gp = *gd;
- if ( X >= gp->gdRect.left && X <= gp->gdRect.right
- && B >= gp->gdRect.top && B <= gp->gdRect.bottom)
- break;
- }
- }
- // last resort, try the bottom right
- if (!gd) {
- for (gd = GetDeviceList(); gd; gd = GetNextDevice(gd)) {
- GDPtr gp = *gd;
- if ( R >= gp->gdRect.left && R <= gp->gdRect.right
- && B >= gp->gdRect.top && B <= gp->gdRect.bottom)
- break;
- }
- }
- // if we still have not found a screen, we will use the main
- // screen, the one that has the application menu bar.
- if (!gd) gd = GetMainDevice();
- if (gd) {
- GetAvailableWindowPositioningBounds(gd, &r);
- if ( R > r.right ) X -= R - r.right;
- if ( B > r.bottom ) Y -= B - r.bottom;
- if ( X < r.left ) X = r.left;
- if ( Y < r.top ) Y = r.top;
- }
-
- //Return the client area's top left corner in (X,Y)
- X+=xoff;
- Y+=yoff;
-
- return ret;
-}
-
-/**
- * convert a Mac FSSpec structure into a Unix filename
- */
-static int FSSpec2UnixPath( FSSpec *fs, char *dst )
-{
- FSRef fsRef;
- FSpMakeFSRef( fs, &fsRef );
- FSRefMakePath( &fsRef, (UInt8*)dst, 1024 );
- return strlen(dst);
-}
-static void convert_crlf(char * s, size_t len)
-{
- // turn all \r characters into \n:
- for (size_t x = 0; x < len; x++) if (s[x] == '\r') s[x] = '\n';
-}
-
-
-static DragReference currDragRef = 0;
-static char *currDragData = 0L;
-static int currDragSize = 0;
-static OSErr currDragErr = noErr;
-Fl_Window *fl_dnd_target_window = 0;
-#include <FL/fl_draw.H>
-
-/**
- * Fill the currDrag* variables with the current DnD ASCII text.
- */
-static OSErr fillCurrentDragData(DragReference dragRef)
-{
- OSErr ret = noErr;
- char *dst = 0L;
-
- // shortcut through this whole procedure if this is still the same drag event
- if (dragRef==currDragRef)
- return currDragErr;
-
- // clear currDrag* for a new drag event
- currDragRef = dragRef;
- if (currDragData) free(currDragData);
- currDragData = 0;
- currDragSize = 0;
-
- // fill currDRag* with ASCII data, if available
- UInt16 i, nItem;
- ItemReference itemRef;
- FlavorFlags flags;
- Size itemSize, size = 0;
- CountDragItems( dragRef, &nItem );
-
- for ( i = 1; i <= nItem; i++ )
- {
- GetDragItemReferenceNumber( dragRef, i, &itemRef );
- ret = GetFlavorFlags( dragRef, itemRef, 'utf8', &flags );
- if ( ret == noErr )
- {
- GetFlavorDataSize( dragRef, itemRef, 'utf8', &itemSize );
- size += itemSize;
- continue;
- }
- ret = GetFlavorFlags( dragRef, itemRef, 'utxt', &flags );
- if ( ret == noErr )
- {
- GetFlavorDataSize( dragRef, itemRef, 'utxt', &itemSize );
- size += itemSize;
- continue;
- }
- ret = GetFlavorFlags( dragRef, itemRef, 'TEXT', &flags );
- if ( ret == noErr )
- {
- GetFlavorDataSize( dragRef, itemRef, 'TEXT', &itemSize );
- size += itemSize;
- continue;
- }
- ret = GetFlavorFlags( dragRef, itemRef, 'hfs ', &flags );
- if ( ret == noErr )
- {
- size += 1024; //++ ouch! We should create the full pathname and figure out its length
- continue;
- }
- }
-
- if ( !size )
- {
- currDragErr = userCanceledErr;
- return currDragErr;
- }
-
- currDragSize = size + nItem - 1;
- currDragData = dst = (char*)malloc( size+nItem );;
-
- for ( i = 1; i <= nItem; i++ )
- {
- GetDragItemReferenceNumber( dragRef, i, &itemRef );
- ret = GetFlavorFlags( dragRef, itemRef, 'utf8', &flags );
- if ( ret == noErr )
- {
- GetFlavorDataSize( dragRef, itemRef, 'utf8', &itemSize );
- GetFlavorData( dragRef, itemRef, 'utf8', dst, &itemSize, 0L );
- dst += itemSize;
- *dst++ = '\n'; // add our element separator
- continue;
- }
- GetDragItemReferenceNumber( dragRef, i, &itemRef );
- ret = GetFlavorFlags( dragRef, itemRef, 'utxt', &flags );
- if ( ret == noErr )
- {
- GetFlavorDataSize( dragRef, itemRef, 'utxt', &itemSize );
- GetFlavorData( dragRef, itemRef, 'utxt', dst, &itemSize, 0L );
- dst += itemSize;
- *dst++ = '\n'; // add our element separator
- continue;
- }
- ret = GetFlavorFlags( dragRef, itemRef, 'TEXT', &flags );
- if ( ret == noErr )
- {
- GetFlavorDataSize( dragRef, itemRef, 'TEXT', &itemSize );
- GetFlavorData( dragRef, itemRef, 'TEXT', dst, &itemSize, 0L );
- dst += itemSize;
- *dst++ = '\n'; // add our element separator
- continue;
- }
- ret = GetFlavorFlags( dragRef, itemRef, 'hfs ', &flags );
- if ( ret == noErr )
- {
- HFSFlavor hfs; itemSize = sizeof( hfs );
- GetFlavorData( dragRef, itemRef, 'hfs ', &hfs, &itemSize, 0L );
- itemSize = FSSpec2UnixPath( &hfs.fileSpec, dst ); // return the path name in UTF8
- dst += itemSize;
- if ( itemSize>1 && ( hfs.fileType=='fold' || hfs.fileType=='disk' ) )
- *dst++ = '/';
- *dst++ = '\n'; // add our element separator
- continue;
- }
- }
-
- dst[-1] = 0;
- currDragSize = dst - currDragData - 1;
- currDragErr = ret;
- return ret;
-}
-
-/**
- * Drag'n'drop tracking handler
- */
-static pascal OSErr dndTrackingHandler( DragTrackingMessage msg, WindowPtr w, void *userData, DragReference dragRef )
-{
- Fl_Window *target = (Fl_Window*)userData;
- Fl::first_window(target);
- Point mp;
- static int px, py;
-
- fillCurrentDragData(dragRef);
- Fl::e_length = currDragSize;
- Fl::e_text = currDragData;
-
- switch ( msg )
- {
- case kDragTrackingEnterWindow:
- // check if 'TEXT' is available
- GetDragMouse( dragRef, &mp, 0 );
- Fl::e_x_root = px = mp.h;
- Fl::e_y_root = py = mp.v;
- Fl::e_x = px - target->x();
- Fl::e_y = py - target->y();
- fl_dnd_target_window = target;
- if ( Fl::handle( FL_DND_ENTER, target ) )
- fl_cursor( FL_CURSOR_HAND ); //ShowDragHilite( ); // modify the mouse cursor?!
- else
- fl_cursor( FL_CURSOR_DEFAULT ); //HideDragHilite( dragRef );
- breakMacEventLoop();
- return noErr;
- case kDragTrackingInWindow:
- GetDragMouse( dragRef, &mp, 0 );
- if ( mp.h==px && mp.v==py )
- break; //+ return previous condition for dnd hiliting
- Fl::e_x_root = px = mp.h;
- Fl::e_y_root = py = mp.v;
- Fl::e_x = px - target->x();
- Fl::e_y = py - target->y();
- fl_dnd_target_window = target;
- if ( Fl::handle( FL_DND_DRAG, target ) )
- fl_cursor( FL_CURSOR_HAND ); //ShowDragHilite( ); // modify the mouse cursor?!
- else
- fl_cursor( FL_CURSOR_DEFAULT ); //HideDragHilite( dragRef );
- breakMacEventLoop();
- return noErr;
- break;
- case kDragTrackingLeaveWindow:
- // HideDragHilite()
- fl_cursor( FL_CURSOR_DEFAULT ); //HideDragHilite( dragRef );
- if ( fl_dnd_target_window )
- {
- Fl::handle( FL_DND_LEAVE, fl_dnd_target_window );
- fl_dnd_target_window = 0;
- }
- breakMacEventLoop();
- return noErr;
- }
- return noErr;
-}
-
-
-/**
- * Drag'n'drop receive handler
- */
-static pascal OSErr dndReceiveHandler( WindowPtr w, void *userData, DragReference dragRef )
-{
- Point mp;
- OSErr ret;
-
- Fl_Window *target = fl_dnd_target_window = (Fl_Window*)userData;
- Fl::first_window(target);
- GetDragMouse( dragRef, &mp, 0 );
- Fl::e_x_root = mp.h;
- Fl::e_y_root = mp.v;
- Fl::e_x = Fl::e_x_root - target->x();
- Fl::e_y = Fl::e_y_root - target->y();
- if ( !Fl::handle( FL_DND_RELEASE, target ) )
- return userCanceledErr;
-
- ret = fillCurrentDragData(dragRef);
- if (ret==userCanceledErr)
- return userCanceledErr;
-
- Fl::e_length = currDragSize;
- Fl::e_text = currDragData;
-// printf("Sending following text to widget %p:\n%s\n", Fl::belowmouse(), Fl::e_text);
- int old_event = Fl::e_number;
- Fl::belowmouse()->handle(Fl::e_number = FL_PASTE);
- Fl::e_number = old_event;
-
- if (currDragData) {
- free(currDragData);
- }
- currDragData = 0L;
- currDragRef = 0;
- Fl::e_text = 0L;
- Fl::e_length = 0;
- fl_dnd_target_window = 0L;
-
- breakMacEventLoop();
- return noErr;
-}
-// fc:
-static void q_set_window_title(Window xid, const char * name ) {
-#if 1
- CFStringRef utf8_title = CFStringCreateWithCString(NULL, (name ? name : ""), kCFStringEncodingUTF8);
- SetWindowTitleWithCFString(xid, utf8_title);
- CFRelease(utf8_title);
-#else // old non-utf8 code to remove after new utf8 code approval :
- Str255 pTitle;
- if (name) {
- if (strlen(name) > 255) pTitle[0] = 255;
- else pTitle[0] = strlen(name);
- memcpy(pTitle+1, name, pTitle[0]);
- }
- else
- pTitle[0] = 0;
- SetWTitle(xid, pTitle);
-#endif
-}
-
-/**
- * go ahead, create that (sub)window
- * \todo we should make menu windows slightly transparent for the new Mac look
- */
-void Fl_X::make(Fl_Window* w)
-{
- static int xyPos = 100;
- if ( w->parent() ) // create a subwindow
- {
- Fl_Group::current(0);
- Rect wRect;
- wRect.top = w->y();
- wRect.left = w->x();
- wRect.bottom = w->y() + w->h(); if (wRect.bottom<=wRect.top) wRect.bottom = wRect.top+1;
- wRect.right = w->x() + w->w(); if (wRect.right<=wRect.left) wRect.right = wRect.left+1;
- // our subwindow needs this structure to know about its clipping.
- Fl_X* x = new Fl_X;
- x->other_xid = 0;
- 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();
- Fl_X *xo = Fl_X::i(win);
- if (xo) {
- x->xidNext = xo->xidChildren;
- x->xidChildren = 0L;
- xo->xidChildren = x;
- x->xid = fl_xid(win);
- x->w = w; w->i = x;
- x->wait_for_expose = 0;
- x->next = Fl_X::first; // must be in the list for ::flush()
- Fl_X::first = x;
- int old_event = Fl::e_number;
- w->handle(Fl::e_number = FL_SHOW);
- Fl::e_number = old_event;
- w->redraw(); // force draw to happen
- }
- fl_show_iconic = 0;
- }
- else // create a desktop window
- {
- Fl_Group::current(0);
- fl_open_display();
- int winclass = kDocumentWindowClass;
- int winattr = kWindowStandardHandlerAttribute | kWindowCloseBoxAttribute | kWindowCollapseBoxAttribute;
- int xp = w->x();
- int yp = w->y();
- int wp = w->w();
- int hp = w->h();
- if (w->size_range_set) {
- if ( w->minh != w->maxh || w->minw != w->maxw)
- winattr |= kWindowFullZoomAttribute | kWindowResizableAttribute | kWindowLiveResizeAttribute;
- } else {
- if (w->resizable()) {
- Fl_Widget *o = w->resizable();
- int minw = o->w(); if (minw > 100) minw = 100;
- int minh = o->h(); if (minh > 100) minh = 100;
- w->size_range(w->w() - o->w() + minw, w->h() - o->h() + minh, 0, 0);
- winattr |= kWindowFullZoomAttribute | kWindowResizableAttribute | kWindowLiveResizeAttribute;
- } else {
- w->size_range(w->w(), w->h(), w->w(), w->h());
- }
- }
- int xwm = xp, ywm = yp, bt, bx, by;
-
- if (!fake_X_wm(w, xwm, ywm, bt, bx, by)) {
- // menu windows and tooltips
- if (w->modal()||w->override()) {
- winclass = kHelpWindowClass;
- winattr = 0;
- } else {
- winattr = 512; // kWindowNoTitleBarAttribute;
- }
- } else if (w->modal()) {
- winclass = kMovableModalWindowClass;
- }
-
- if (by+bt) {
- wp += 2*bx;
- hp += 2*by+bt;
- }
- if (!(w->flags() & Fl_Widget::FORCE_POSITION)) {
- // use the Carbon functions below for default window positioning
- w->x(xyPos+Fl::x());
- w->y(xyPos+Fl::y());
- xyPos += 25;
- if (xyPos>200) xyPos = 100;
- } else {
- if (!Fl::grab()) {
- xp = xwm; yp = ywm;
- w->x(xp);w->y(yp);
- }
- xp -= bx;
- yp -= by+bt;
- }
-
- if (w->non_modal() && Fl_X::first && !fl_disable_transient_for) {
- // find some other window to be "transient for":
- Fl_Window* w = Fl_X::first->w;
- while (w->parent()) w = w->window(); // todo: this code does not make any sense! (w!=w??)
- }
-
- Rect wRect;
- wRect.top = w->y();
- wRect.left = w->x();
- wRect.bottom = w->y() + w->h(); if (wRect.bottom<=wRect.top) wRect.bottom = wRect.top+1;
- wRect.right = w->x() + w->w(); if (wRect.right<=wRect.left) wRect.right = wRect.left+1;
-
- const char *name = w->label();
-
- Fl_X* x = new Fl_X;
- x->other_xid = 0; // room for doublebuffering image map. On OS X this is only used by overlay windows
- x->region = 0;
- x->subRegion = 0;
- x->cursor = fl_default_cursor;
- x->xidChildren = 0;
- x->xidNext = 0;
- x->gc = 0;
-
- winattr &= GetAvailableWindowAttributes( winclass ); // make sure that the window will open
- CreateNewWindow( winclass, winattr, &wRect, &(x->xid) );
- q_set_window_title(x->xid, name);
- MoveWindow(x->xid, wRect.left, wRect.top, 1); // avoid Carbon Bug on old OS
- if (w->non_modal() && !w->modal()) {
- // Major kludge: this is to have the regular look, but stay above the document windows
- SetWindowClass(x->xid, kFloatingWindowClass);
- SetWindowActivationScope(x->xid, kWindowActivationScopeAll);
- }
- if (!(w->flags() & Fl_Widget::FORCE_POSITION))
- {
- WindowRef pw = Fl_X::first ? Fl_X::first->xid : 0 ;
- if (w->modal()) {
- RepositionWindow(x->xid, pw, kWindowAlertPositionOnParentWindowScreen);
- } else if (w->non_modal()) {
- RepositionWindow(x->xid, pw, kWindowCenterOnParentWindowScreen);
- } else {
- RepositionWindow(x->xid, pw, kWindowCascadeOnParentWindowScreen);
- }
- }
- x->w = w; w->i = x;
- x->wait_for_expose = 1;
- x->next = Fl_X::first;
- Fl_X::first = x;
- { // Install Carbon Event handlers
- OSStatus ret;
- EventHandlerUPP mousewheelHandler = NewEventHandlerUPP( carbonMousewheelHandler ); // will not be disposed by Carbon...
- static EventTypeSpec mousewheelEvents[] = {
- { kEventClassMouse, kEventMouseWheelMoved } };
- ret = InstallWindowEventHandler( x->xid, mousewheelHandler,
- (int)(sizeof(mousewheelEvents)/sizeof(mousewheelEvents[0])),
- mousewheelEvents, w, 0L );
- EventHandlerUPP mouseHandler = NewEventHandlerUPP( carbonMouseHandler ); // will not be disposed by Carbon...
- static EventTypeSpec mouseEvents[] = {
- { kEventClassMouse, kEventMouseDown },
- { kEventClassMouse, kEventMouseUp },
- { kEventClassMouse, kEventMouseMoved },
- { kEventClassMouse, kEventMouseDragged } };
- ret = InstallWindowEventHandler( x->xid, mouseHandler, 4, mouseEvents, w, 0L );
-
- EventHandlerUPP keyboardHandler = NewEventHandlerUPP( carbonKeyboardHandler ); // will not be disposed by Carbon...
- static EventTypeSpec keyboardEvents[] = {
- { kEventClassKeyboard, kEventRawKeyDown },
- { kEventClassKeyboard, kEventRawKeyRepeat },
- { kEventClassKeyboard, kEventRawKeyUp },
- { kEventClassKeyboard, kEventRawKeyModifiersChanged } };
- ret = InstallWindowEventHandler( x->xid, keyboardHandler, 4, keyboardEvents, w, 0L );
-
- EventHandlerUPP textHandler = NewEventHandlerUPP( carbonTextHandler ); // will not be disposed by Carbon...
- static EventTypeSpec textEvents[] = {
- { kEventClassTextInput, kEventTextInputUnicodeForKeyEvent } };
- ret = InstallWindowEventHandler( x->xid, textHandler, 1, textEvents, w, 0L );
-
- EventHandlerUPP windowHandler = NewEventHandlerUPP( carbonWindowHandler ); // will not be disposed by Carbon...
- static EventTypeSpec windowEvents[] = {
- { kEventClassWindow, kEventWindowDrawContent },
- { kEventClassWindow, kEventWindowShown },
- { kEventClassWindow, kEventWindowHidden },
- { kEventClassWindow, kEventWindowActivated },
- { kEventClassWindow, kEventWindowDeactivated },
- { kEventClassWindow, kEventWindowClose },
- { kEventClassWindow, kEventWindowCollapsed },
- { kEventClassWindow, kEventWindowExpanded },
- { kEventClassWindow, kEventWindowBoundsChanging },
- { kEventClassWindow, kEventWindowBoundsChanged } };
- ret = InstallWindowEventHandler( x->xid, windowHandler, 10, windowEvents, w, 0L );
- ret = InstallTrackingHandler( dndTrackingHandler, x->xid, w );
- ret = InstallReceiveHandler( dndReceiveHandler, x->xid, w );
- }
-
- if ( ! Fl_X::first->next ) // if this is the first window, we need to bring the application to the front
- {
- ProcessSerialNumber psn;
- OSErr err = GetCurrentProcess( &psn );
- if ( err==noErr ) SetFrontProcess( &psn );
- }
-
- if (w->size_range_set) w->size_range_();
-
- if (winclass != kHelpWindowClass) {
- Fl_Tooltip::enter(0);
- }
- if (w->size_range_set) w->size_range_();
- ShowWindow(x->xid);
- if (fl_show_iconic) {
- fl_show_iconic = 0;
- CollapseWindow( x->xid, true ); // \todo Mac ; untested
- } else {
- w->set_visible();
- }
-
- Rect rect;
- GetWindowBounds(x->xid, kWindowContentRgn, &rect);
- w->x(rect.left); w->y(rect.top);
- w->w(rect.right-rect.left); w->h(rect.bottom-rect.top);
-
- int old_event = Fl::e_number;
- w->handle(Fl::e_number = FL_SHOW);
- Fl::e_number = old_event;
- w->redraw(); // force draw to happen
-
- if (w->modal()) { Fl::modal_ = w; fl_fix_focus(); }
- }
-}
-
-
-/**
- * Tell the OS what window sizes we want to allow
- */
-void Fl_Window::size_range_() {
- size_range_set = 1;
- HISize minSize = { minw, minh };
- HISize maxSize = { maxw?maxw:32000, maxh?maxh:32000 };
- if (i && i->xid)
- SetWindowResizeLimits(i->xid, &minSize, &maxSize);
-}
-
-
-/**
- * returns pointer to the filename, or null if name ends with ':'
- */
-const char *fl_filename_name( const char *name )
-{
- const char *p, *q;
- if (!name) return (0);
- for ( p = q = name ; *p ; )
- {
- if ( ( p[0] == ':' ) && ( p[1] == ':' ) )
- {
- q = p+2;
- p++;
- }
- else if (p[0] == '/')
- q = p + 1;
- p++;
- }
- return q;
-}
-
-
-/**
- * set the window title bar
- * \todo make the titlebar icon work!
- */
-void Fl_Window::label(const char *name,const char */*iname*/) {
- Fl_Widget::label(name);
-
- if (shown() || i) {
- q_set_window_title(fl_xid(this), name);
- }
-}
-
-
-/**
- * make a window visible
- */
-void Fl_Window::show() {
- image(Fl::scheme_bg_);
- if (Fl::scheme_bg_) {
- labeltype(FL_NORMAL_LABEL);
- align(FL_ALIGN_CENTER | FL_ALIGN_INSIDE | FL_ALIGN_CLIP);
- } else {
- labeltype(FL_NO_LABEL);
- }
- Fl_Tooltip::exit(this);
- if (!shown() || !i) {
- Fl_X::make(this);
- } else {
- if ( !parent() )
- {
- if ( IsWindowCollapsed( i->xid ) ) CollapseWindow( i->xid, false );
- if (!fl_capture) {
- BringToFront(i->xid);
- SelectWindow(i->xid);
- }
- }
- }
-}
-
-
-/**
- * resize a window
- */
-void Fl_Window::resize(int X,int Y,int W,int H) {
- if (W<=0) W = 1; // OS X does not like zero width windows
- if (H<=0) H = 1;
- int is_a_resize = (W != w() || H != h());
-// printf("Fl_Winodw::resize(X=%d, Y=%d, W=%d, H=%d), is_a_resize=%d, resize_from_system=%p, this=%p\n",
-// X, Y, W, H, is_a_resize, resize_from_system, this);
- if (X != x() || Y != y()) set_flag(FORCE_POSITION);
- else if (!is_a_resize) return;
- if ( (resize_from_system!=this) && (!parent()) && shown()) {
- if (is_a_resize) {
- if (resizable()) {
- if (W<minw) minw = W; // user request for resize takes priority
- if (W>maxw) maxw = W; // over a previously set size_range
- if (H<minh) minh = H;
- if (H>maxh) maxh = H;
- size_range(minw, minh, maxw, maxh);
- } else {
- size_range(W, H, W, H);
- }
- Rect dim; dim.left=X; dim.top=Y; dim.right=X+W; dim.bottom=Y+H;
- SetWindowBounds(i->xid, kWindowContentRgn, &dim);
- Rect all; all.top=-32000; all.bottom=32000; all.left=-32000; all.right=32000;
- InvalWindowRect( i->xid, &all );
- } else {
- MoveWindow(i->xid, X, Y, 0);
- }
- }
- resize_from_system = 0;
- if (is_a_resize) {
- Fl_Group::resize(X,Y,W,H);
- if (shown()) {
- redraw();
- }
- } else {
- x(X); y(Y);
- }
-}
-
-
-/**
- * make all drawing go into this window (called by subclass flush() impl.)
- */
-void Fl_Window::make_current()
-{
- OSStatus err;
- Fl_X::q_release_context();
- if ( !fl_window_region )
- fl_window_region = NewRgn();
- fl_window = i->xid;
- current_ = this;
-
- SetPort( GetWindowPort(i->xid) ); // \todo check for the handling of doublebuffered windows
-
- int xp = 0, yp = 0;
- Fl_Window *win = this;
- while ( win )
- {
- if ( !win->window() )
- break;
- xp += win->x();
- yp += win->y();
- win = (Fl_Window*)win->window();
- }
- SetOrigin( -xp, -yp );
-
- SetRectRgn( fl_window_region, 0, 0, w(), h() );
-
- // \todo for performance reasons: we don't have to create this unless the child windows moved
- for ( Fl_X *cx = i->xidChildren; cx; cx = cx->xidNext )
- {
- Fl_Window *cw = cx->w;
- if (!cw->visible_r()) continue;
- Fl_Region r = NewRgn();
- SetRectRgn( r, cw->x() - xp, cw->y() - yp,
- cw->x() + cw->w() - xp, cw->y() + cw->h() - yp );
- DiffRgn( fl_window_region, r, fl_window_region );
- DisposeRgn( r );
- }
-
- err = QDBeginCGContext(GetWindowPort(i->xid), &i->gc);
- if (err!=noErr)
- fprintf(stderr, "Error %d in QDBeginCGContext\n", (int)err);
- fl_gc = i->gc;
- CGContextSaveGState(fl_gc);
- Fl_X::q_fill_context();
-#if defined(USE_CAIRO)
- if (Fl::cairo_autolink_context()) Fl::cairo_make_current(this); // capture gc changes automatically to update the cairo context adequately
-#endif
-
- fl_clip_region( 0 );
- SetPortClipRegion( GetWindowPort(i->xid), fl_window_region );
-
-#if defined(USE_CAIRO)
- // update the cairo_t context
- if (Fl::cairo_autolink_context()) Fl::cairo_make_current(this);
-#endif
-}
-
-// helper function to manage the current CGContext fl_gc
-extern Fl_Color fl_color_;
-extern class Fl_Font_Descriptor *fl_fontsize;
-extern void fl_font(class Fl_Font_Descriptor*);
-extern void fl_quartz_restore_line_style_();
-
-// FLTK has only one global graphics state. This function copies the FLTK state into the
-// current Quartz context
-void Fl_X::q_fill_context() {
- if (!fl_gc) return;
- int hgt = 0;
- if (fl_window) {
- Rect portRect;
- GetPortBounds(GetWindowPort( fl_window ), &portRect);
- hgt = portRect.bottom-portRect.top;
- } else {
- hgt = CGBitmapContextGetHeight(fl_gc);
- }
- CGContextTranslateCTM(fl_gc, 0.5, hgt-0.5f);
- CGContextScaleCTM(fl_gc, 1.0f, -1.0f);
- fl_font(fl_fontsize);
- fl_color(fl_color_);
- fl_quartz_restore_line_style_();
-}
-
-// The only way to reset clipping to its original state is to pop the current graphics
-// state and restore the global state.
-void Fl_X::q_clear_clipping() {
- if (!fl_gc) return;
- CGContextRestoreGState(fl_gc);
- CGContextSaveGState(fl_gc);
-}
-
-// Give the Quartz context back to the system
-void Fl_X::q_release_context(Fl_X *x) {
- if (x && x->gc!=fl_gc) return;
- if (!fl_gc) return;
- CGContextRestoreGState(fl_gc);
- if (fl_window) {
- OSStatus err = QDEndCGContext(GetWindowPort(fl_window), &fl_gc);
- if (err!=noErr)
- fprintf(stderr, "Error %d in QDEndCGContext\n", (int)err);
- }
- fl_gc = 0;
-#if defined(USE_CAIRO)
- if (Fl::cairo_autolink_context()) Fl::cairo_make_current((Fl_Window*) 0); // capture gc changes automatically to update the cairo context adequately
-#endif
-}
-
-void Fl_X::q_begin_image(CGRect &rect, int cx, int cy, int w, int h) {
- CGContextSaveGState(fl_gc);
- CGAffineTransform mx = CGContextGetCTM(fl_gc);
- CGRect r2 = rect;
- r2.origin.x -= 0.5f;
- r2.origin.y -= 0.5f;
- CGContextClipToRect(fl_gc, r2);
- mx.d = -1.0; mx.tx = -mx.tx;
- CGContextConcatCTM(fl_gc, mx);
- rect.origin.x = -(mx.tx+0.5f) + rect.origin.x - cx;
- rect.origin.y = (mx.ty+0.5f) - rect.origin.y - h + cy;
- rect.size.width = w;
- rect.size.height = h;
-}
-
-void Fl_X::q_end_image() {
- CGContextRestoreGState(fl_gc);
-}
-
-////////////////////////////////////////////////////////////////
-// Copy & Paste fltk implementation.
-////////////////////////////////////////////////////////////////
-
-// fltk 1.3 clipboard support constant definitions:
-const CFStringRef flavorNames[] = {
- CFSTR("public.utf16-plain-text"),
- CFSTR("public.utf8-plain-text"),
- CFSTR("com.apple.traditional-mac-plain-text") };
-const CFStringEncoding encodings[] = {
- kCFStringEncodingUTF16,
- kCFStringEncodingUTF8,
- kCFStringEncodingMacRoman};
-const size_t handledFlavorsCount = sizeof(encodings)/sizeof(CFStringEncoding);
-
-// clipboard variables definitions :
-Fl_Widget *fl_selection_requestor = 0;
-char *fl_selection_buffer[2];
-int fl_selection_length[2];
-static int fl_selection_buffer_length[2];
-
-#ifdef USE_PASTEBOARD
-static PasteboardRef myPasteboard = 0;
-static void allocatePasteboard() {
- if (!myPasteboard)
- PasteboardCreate(kPasteboardClipboard, &myPasteboard);
-}
-#else
-#endif
-
-#ifndef USE_PASTEBOARD
-static ScrapRef myScrap = 0;
-#endif
-
-/**
- * create a selection
- * owner: widget that created the selection
- * stuff: pointer to selected data
- * size of selected data
- */
-void Fl::copy(const char *stuff, int len, int clipboard) {
- if (!stuff || len<0) return;
- if (len+1 > fl_selection_buffer_length[clipboard]) {
- delete[] fl_selection_buffer[clipboard];
- fl_selection_buffer[clipboard] = new char[len+100];
- fl_selection_buffer_length[clipboard] = len+100;
- }
- memcpy(fl_selection_buffer[clipboard], stuff, len);
- fl_selection_buffer[clipboard][len] = 0; // needed for direct paste
- fl_selection_length[clipboard] = len;
- if (clipboard) {
-#ifdef USE_PASTEBOARD
- // FIXME no error checking done yet!
- allocatePasteboard();
- OSStatus err = PasteboardClear(myPasteboard);
- if (err!=noErr) return; // clear did not work, maybe not owner of clipboard.
- PasteboardSynchronize(myPasteboard);
- CFDataRef text = CFDataCreate(kCFAllocatorDefault, (UInt8*)fl_selection_buffer[1], len);
- if (text==NULL) return; // there was a pb creating the object, abort.
- err=PasteboardPutItemFlavor(myPasteboard, (PasteboardItemID)1, CFSTR("public.utf8-plain-text"), text, 0);
- CFRelease(text);
-#else
- OSStatus err = ClearCurrentScrap(); // whatever happens we should clear the current scrap.
- if(err!=noErr) {myScrap=0; return;} // don't get current scrap if a prev err occured.
- err = GetCurrentScrap( &myScrap );
- if ( err != noErr ) {
- myScrap = 0;
- return;
- }
- // Previous version changed \n to \r before sending the text, but I would
- // prefer to leave the local buffer alone, so a copied buffer may be
- // needed. Check to see if this is necessary on OS/X.
- PutScrapFlavor( myScrap, kScrapFlavorTypeText, 0,
- len, fl_selection_buffer[1] );
-#endif
- }
-}
-
-// Call this when a "paste" operation happens:
-void Fl::paste(Fl_Widget &receiver, int clipboard) {
- if (clipboard) {
- // see if we own the selection, if not go get it:
- fl_selection_length[1] = 0;
-#ifdef USE_PASTEBOARD
- OSStatus err = noErr;
- Boolean found = false;
- CFDataRef flavorData = NULL;
- CFStringEncoding encoding = 0;
-
- allocatePasteboard();
- PasteboardSynchronize(myPasteboard);
- ItemCount nFlavor = 0, i, j;
- err = PasteboardGetItemCount(myPasteboard, &nFlavor);
- if (err==noErr) {
- for (i=1; i<=nFlavor; i++) {
- PasteboardItemID itemID = 0;
- CFArrayRef flavorTypeArray = NULL;
- found = false;
- err = PasteboardGetItemIdentifier(myPasteboard, i, &itemID);
- if (err!=noErr) continue;
- err = PasteboardCopyItemFlavors(myPasteboard, itemID, &flavorTypeArray);
- if (err!=noErr) {
- if (flavorTypeArray) {CFRelease(flavorTypeArray); flavorTypeArray = NULL;}
- continue;
- }
- CFIndex flavorCount = CFArrayGetCount(flavorTypeArray);
- for (j = 0; j < handledFlavorsCount; j++) {
- for (CFIndex flavorIndex=0; flavorIndex<flavorCount; flavorIndex++) {
- CFStringRef flavorType = (CFStringRef)CFArrayGetValueAtIndex(flavorTypeArray, flavorIndex);
- if (UTTypeConformsTo(flavorType, flavorNames[j])) {
- err = PasteboardCopyItemFlavorData( myPasteboard, itemID, flavorNames[j], &flavorData );
- if(err != noErr) continue;
- encoding = encodings[j];
- found = true;
- break;
- }
- }
- if(found) break;
- }
- if (flavorTypeArray) {CFRelease(flavorTypeArray); flavorTypeArray = NULL;}
- if (found) break;
- }
- if(found) {
- CFIndex len = CFDataGetLength(flavorData);
- CFStringRef mycfs = CFStringCreateWithBytes(NULL, CFDataGetBytePtr(flavorData), len, encoding, false);
- CFRelease(flavorData);
- len = CFStringGetMaximumSizeForEncoding(CFStringGetLength(mycfs), kCFStringEncodingUTF8) + 1;
- if ( len >= fl_selection_buffer_length[1] ) {
- fl_selection_buffer_length[1] = len;
- delete[] fl_selection_buffer[1];
- fl_selection_buffer[1] = new char[len];
- }
- CFStringGetCString(mycfs, fl_selection_buffer[1], len, kCFStringEncodingUTF8);
- CFRelease(mycfs);
- len = strlen(fl_selection_buffer[1]);
- fl_selection_length[1] = len;
- convert_crlf(fl_selection_buffer[1],len); // turn all \r characters into \n:
- }
- }
-#else
- ScrapRef scrap = 0;
- if (GetCurrentScrap(&scrap) == noErr && scrap != myScrap &&
- GetScrapFlavorSize(scrap, kScrapFlavorTypeText, &len) == noErr) {
- if ( len >= fl_selection_buffer_length[1] ) {
- fl_selection_buffer_length[1] = len + 32;
- delete[] fl_selection_buffer[1];
- fl_selection_buffer[1] = new char[len + 32];
- }
- fl_selection_length[1] = len; len++;
- GetScrapFlavorData( scrap, kScrapFlavorTypeText, &len,
- fl_selection_buffer[1] );
- fl_selection_buffer[1][fl_selection_length[1]] = 0;
- convert_crlf(fl_selection_buffer[1],len);
- }
-#endif
- }
- Fl::e_text = fl_selection_buffer[clipboard];
- Fl::e_length = fl_selection_length[clipboard];
- if (!Fl::e_text) Fl::e_text = (char *)"";
- receiver.handle(FL_PASTE);
-}
-
-void Fl::add_timeout(double time, Fl_Timeout_Handler cb, void* data)
-{
- // check, if this timer slot exists already
- for (int i = 0; i < mac_timer_used; ++i) {
- MacTimeout& t = mac_timers[i];
- // if so, simply change the fire interval
- if (t.callback == cb && t.data == data) {
- SetEventLoopTimerNextFireTime(t.timer, (EventTimerInterval)time);
- t.pending = 1;
- return;
- }
- }
- // no existing timer to use. Create a new one:
- int timer_id = -1;
- // find an empty slot in the timer array
- for (int i = 0; i < mac_timer_used; ++i) {
- if ( !mac_timers[i].timer ) {
- timer_id = i;
- break;
- }
- }
- // if there was no empty slot, append a new timer
- if (timer_id == -1) {
- // make space if needed
- if (mac_timer_used == mac_timer_alloc) {
- realloc_timers();
- }
- timer_id = mac_timer_used++;
- }
- // now install a brand new timer
- MacTimeout& t = mac_timers[timer_id];
- EventTimerInterval fireDelay = (EventTimerInterval)time;
- EventLoopTimerUPP timerUPP = NewEventLoopTimerUPP(do_timer);
- EventLoopTimerRef timerRef = 0;
- OSStatus err = InstallEventLoopTimer(GetMainEventLoop(), fireDelay, 0, timerUPP, data, &timerRef);
- if (err == noErr) {
- t.callback = cb;
- t.data = data;
- t.timer = timerRef;
- t.upp = timerUPP;
- t.pending = 1;
- } else {
- if (timerRef)
- RemoveEventLoopTimer(timerRef);
- if (timerUPP)
- DisposeEventLoopTimerUPP(timerUPP);
- }
-}
-
-void Fl::repeat_timeout(double time, Fl_Timeout_Handler cb, void* data)
-{
- // currently, repeat_timeout does not subtract the trigger time of the previous timer event as it should.
- add_timeout(time, cb, data);
-}
-
-int Fl::has_timeout(Fl_Timeout_Handler cb, void* data)
-{
- for (int i = 0; i < mac_timer_used; ++i) {
- MacTimeout& t = mac_timers[i];
- if (t.callback == cb && t.data == data && t.pending) {
- return 1;
- }
- }
- return 0;
-}
-
-void Fl::remove_timeout(Fl_Timeout_Handler cb, void* data)
-{
- for (int i = 0; i < mac_timer_used; ++i) {
- MacTimeout& t = mac_timers[i];
- if (t.callback == cb && ( t.data == data || data == NULL)) {
- delete_timer(t);
- }
- }
-}
-
-int MacUnlinkWindow(Fl_X *ip, Fl_X *start) {
- if (!ip) return 0;
- if (start) {
- Fl_X *pc = start;
- while (pc) {
- if (pc->xidNext == ip) {
- pc->xidNext = ip->xidNext;
- return 1;
- }
- if (pc->xidChildren) {
- if (pc->xidChildren == ip) {
- pc->xidChildren = ip->xidNext;
- return 1;
- }
- if (MacUnlinkWindow(ip, pc->xidChildren))
- return 1;
- }
- pc = pc->xidNext;
- }
- } else {
- for ( Fl_X *pc = Fl_X::first; pc; pc = pc->next ) {
- if (MacUnlinkWindow(ip, pc))
- return 1;
- }
- }
- return 0;
-}
-
-static void MacRelinkWindow(Fl_X *x, Fl_X *p) {
- if (!x || !p) return;
- // first, check if 'x' is already registered as a child of 'p'
- for (Fl_X *i = p->xidChildren; i; i=i->xidNext) {
- if (i == x) return;
- }
- // now add 'x' as the first child of 'p'
- x->xidNext = p->xidChildren;
- p->xidChildren = x;
-}
-
-void MacDestroyWindow(Fl_Window *w, WindowPtr p) {
- MacUnmapWindow(w, p);
- if (w && !w->parent() && p)
- DisposeWindow(p);
-}
-
-void MacMapWindow(Fl_Window *w, WindowPtr p) {
- if (w && p)
- ShowWindow(p);
- //+ link to window list
- if (w && w->parent()) {
- MacRelinkWindow(Fl_X::i(w), Fl_X::i(w->window()));
- w->redraw();
- }
-}
-
-void MacUnmapWindow(Fl_Window *w, WindowPtr p) {
- if (w && !w->parent() && p)
- HideWindow(p);
- if (w && Fl_X::i(w))
- MacUnlinkWindow(Fl_X::i(w));
-}
-#endif // FL_DOXYGEN
-
-//
-// End of "$Id: Fl_mac.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $".
-//
diff --git a/src/Fl_win32.cxx b/src/Fl_win32.cxx
index fa1fc26..23f1422 100644
--- a/src/Fl_win32.cxx
+++ b/src/Fl_win32.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: Fl_win32.cxx 9624 2012-06-21 08:52:29Z manolo $"
+// "$Id: Fl_win32.cxx 10387 2014-10-20 15:14:12Z ossman $"
//
// WIN32-specific code for the Fast Light Tool Kit (FLTK).
//
@@ -36,6 +36,7 @@
#include <stdlib.h>
#include <sys/types.h>
#include <time.h>
+#include <signal.h>
#ifdef __CYGWIN__
# include <sys/time.h>
# include <unistd.h>
@@ -59,8 +60,6 @@
#include <ole2.h>
#include <shellapi.h>
-#include "aimm.h"
-
//
// USE_ASYNC_SELECT - define it if you have WSAAsyncSelect()...
// USE_ASYNC_SELECT is OBSOLETED in 1.3 for the following reasons:
@@ -83,10 +82,20 @@
for async mode proper operation, not mentioning the side effects...
*/
+// Internal functions
+static void fl_clipboard_notify_target(HWND wnd);
+static void fl_clipboard_notify_untarget(HWND wnd);
+
+// Internal variables
static Fl_GDI_Graphics_Driver fl_gdi_driver;
static Fl_Display_Device fl_gdi_display(&fl_gdi_driver);
Fl_Display_Device *Fl_Display_Device::_display = &fl_gdi_display; // the platform display
+static HWND clipboard_wnd = 0;
+static HWND next_clipboard_wnd = 0;
+
+static bool initial_clipboard = true;
+
// dynamic wsock dll handling api:
#if defined(__CYGWIN__) && !defined(SOCKET)
# define SOCKET int
@@ -120,27 +129,24 @@ static HMODULE get_wsock_mod() {
* size and link dependencies.
*/
static HMODULE s_imm_module = 0;
+typedef BOOL (WINAPI* flTypeImmAssociateContextEx)(HWND, HIMC, DWORD);
+static flTypeImmAssociateContextEx flImmAssociateContextEx = 0;
typedef HIMC (WINAPI* flTypeImmGetContext)(HWND);
static flTypeImmGetContext flImmGetContext = 0;
typedef BOOL (WINAPI* flTypeImmSetCompositionWindow)(HIMC, LPCOMPOSITIONFORM);
static flTypeImmSetCompositionWindow flImmSetCompositionWindow = 0;
typedef BOOL (WINAPI* flTypeImmReleaseContext)(HWND, HIMC);
static flTypeImmReleaseContext flImmReleaseContext = 0;
-typedef BOOL (WINAPI* flTypeImmIsIME)(HKL);
-static flTypeImmIsIME flImmIsIME = 0;
-
-static HMODULE get_imm_module() {
- if (!s_imm_module) {
- s_imm_module = LoadLibrary("IMM32.DLL");
- if (!s_imm_module)
- Fl::fatal("FLTK Lib Error: IMM32.DLL file not found!\n\n"
- "Please check your input method manager library accessibility.");
- flImmGetContext = (flTypeImmGetContext)GetProcAddress(s_imm_module, "ImmGetContext");
- flImmSetCompositionWindow = (flTypeImmSetCompositionWindow)GetProcAddress(s_imm_module, "ImmSetCompositionWindow");
- flImmReleaseContext = (flTypeImmReleaseContext)GetProcAddress(s_imm_module, "ImmReleaseContext");
- flImmIsIME = (flTypeImmIsIME)GetProcAddress(s_imm_module, "ImmIsIME");
- }
- return s_imm_module;
+
+static void get_imm_module() {
+ s_imm_module = LoadLibrary("IMM32.DLL");
+ if (!s_imm_module)
+ Fl::fatal("FLTK Lib Error: IMM32.DLL file not found!\n\n"
+ "Please check your input method manager library accessibility.");
+ flImmAssociateContextEx = (flTypeImmAssociateContextEx)GetProcAddress(s_imm_module, "ImmAssociateContextEx");
+ flImmGetContext = (flTypeImmGetContext)GetProcAddress(s_imm_module, "ImmGetContext");
+ flImmSetCompositionWindow = (flTypeImmSetCompositionWindow)GetProcAddress(s_imm_module, "ImmSetCompositionWindow");
+ flImmReleaseContext = (flTypeImmReleaseContext)GetProcAddress(s_imm_module, "ImmReleaseContext");
}
// USE_TRACK_MOUSE - define NO_TRACK_MOUSE if you don't have
@@ -205,6 +211,9 @@ static Fl_Window *track_mouse_win=0; // current TrackMouseEvent() window
# define WHEEL_DELTA 120 // according to MSDN.
#endif
+#ifndef SM_CXPADDEDBORDER
+# define SM_CXPADDEDBORDER (92) // STR #3061
+#endif
//
// WM_FLSELECT is the user-defined message that we get when one of
@@ -258,7 +267,9 @@ void fl_set_spot(int font, int size, int X, int Y, int W, int H, Fl_Window *win)
Fl_Window* tw = win;
while (tw->parent()) tw = tw->window(); // find top level window
- get_imm_module();
+ if (!tw->shown())
+ return;
+
HIMC himc = flImmGetContext(fl_xid(tw));
if (himc) {
@@ -335,7 +346,8 @@ void* Fl::thread_message() {
return r;
}
-IActiveIMMApp *fl_aimm = NULL;
+extern int fl_send_system_handlers(void *e);
+
MSG fl_msg;
// This is never called with time_to_wait < 0.0.
@@ -400,23 +412,25 @@ int fl_wait(double time_to_wait) {
// Execute the message we got, and all other pending messages:
// have_message = PeekMessage(&fl_msg, NULL, 0, 0, PM_REMOVE);
- have_message = PeekMessageW(&fl_msg, NULL, 0, 0, PM_REMOVE);
- if (have_message > 0) {
- while (have_message != 0 && have_message != -1) {
- if (fl_msg.message == fl_wake_msg) {
- // Used for awaking wait() from another thread
- thread_message_ = (void*)fl_msg.wParam;
- Fl_Awake_Handler func;
- void *data;
- while (Fl::get_awake_handler_(func, data)==0) {
- func(data);
- }
- }
-
- TranslateMessage(&fl_msg);
- DispatchMessageW(&fl_msg);
- have_message = PeekMessageW(&fl_msg, NULL, 0, 0, PM_REMOVE);
+ while ((have_message = PeekMessageW(&fl_msg, NULL, 0, 0, PM_REMOVE)) > 0) {
+ if (fl_send_system_handlers(&fl_msg))
+ continue;
+
+ // Let applications treat WM_QUIT identical to SIGTERM on *nix
+ if (fl_msg.message == WM_QUIT)
+ raise(SIGTERM);
+
+ if (fl_msg.message == fl_wake_msg) {
+ // Used for awaking wait() from another thread
+ thread_message_ = (void*)fl_msg.wParam;
+ Fl_Awake_Handler func;
+ void *data;
+ while (Fl::get_awake_handler_(func, data)==0)
+ func(data);
}
+
+ TranslateMessage(&fl_msg);
+ DispatchMessageW(&fl_msg);
}
Fl::flush();
@@ -436,6 +450,63 @@ int fl_ready() {
return get_wsock_mod() ? s_wsock_select(0,&fdt[0],&fdt[1],&fdt[2],&t) : 0;
}
+void fl_open_display() {
+ static char beenHereDoneThat = 0;
+
+ if (beenHereDoneThat)
+ return;
+
+ beenHereDoneThat = 1;
+
+ OleInitialize(0L);
+
+ get_imm_module();
+}
+
+class Fl_Win32_At_Exit {
+public:
+ Fl_Win32_At_Exit() { }
+ ~Fl_Win32_At_Exit() {
+ fl_free_fonts(); // do some WIN32 cleanup
+ fl_cleanup_pens();
+ OleUninitialize();
+ fl_brush_action(1);
+ fl_cleanup_dc_list();
+ // This is actually too late in the cleanup process to remove the
+ // clipboard notifications, but we have no earlier hook so we try
+ // to work around it anyway.
+ if (clipboard_wnd != NULL)
+ fl_clipboard_notify_untarget(clipboard_wnd);
+ }
+};
+static Fl_Win32_At_Exit win32_at_exit;
+
+static char im_enabled = 1;
+
+void Fl::enable_im() {
+ fl_open_display();
+
+ Fl_X* i = Fl_X::first;
+ while (i) {
+ flImmAssociateContextEx(i->xid, 0, IACE_DEFAULT);
+ i = i->next;
+ }
+
+ im_enabled = 1;
+}
+
+void Fl::disable_im() {
+ fl_open_display();
+
+ Fl_X* i = Fl_X::first;
+ while (i) {
+ flImmAssociateContextEx(i->xid, 0, 0);
+ i = i->next;
+ }
+
+ im_enabled = 0;
+}
+
////////////////////////////////////////////////////////////////
int Fl::x()
@@ -531,8 +602,39 @@ public:
const char* GetValue() const { return(out); }
};
+void fl_update_clipboard(void) {
+ Fl_Window *w1 = Fl::first_window();
+ if (!w1)
+ return;
+
+ HWND hwnd = fl_xid(w1);
+
+ if (!OpenClipboard(hwnd))
+ return;
+
+ EmptyClipboard();
+
+ int utf16_len = fl_utf8toUtf16(fl_selection_buffer[1],
+ fl_selection_length[1], 0, 0);
+
+ HGLOBAL hMem = GlobalAlloc(GHND, utf16_len * 2 + 2); // moveable and zero'ed mem alloc.
+ LPVOID memLock = GlobalLock(hMem);
+
+ fl_utf8toUtf16(fl_selection_buffer[1], fl_selection_length[1],
+ (unsigned short*) memLock, utf16_len + 1);
+
+ GlobalUnlock(hMem);
+ SetClipboardData(CF_UNICODETEXT, hMem);
+
+ CloseClipboard();
+
+ // In case Windows managed to lob of a WM_DESTROYCLIPBOARD during
+ // the above.
+ fl_i_own_selection[1] = 1;
+}
+
// call this when you create a selection:
-void Fl::copy(const char *stuff, int len, int clipboard) {
+void Fl::copy(const char *stuff, int len, int clipboard, const char *type) {
if (!stuff || len<0) return;
// Convert \n -> \r\n (for old apps like Notepad, DOS)
@@ -548,35 +650,17 @@ void Fl::copy(const char *stuff, int len, int clipboard) {
memcpy(fl_selection_buffer[clipboard], stuff, len);
fl_selection_buffer[clipboard][len] = 0; // needed for direct paste
fl_selection_length[clipboard] = len;
- if (clipboard) {
- // set up for "delayed rendering":
- if (OpenClipboard(NULL)) {
- // if the system clipboard works, use it
- int utf16_len = fl_utf8toUtf16(fl_selection_buffer[clipboard], fl_selection_length[clipboard], 0, 0);
- EmptyClipboard();
- HGLOBAL hMem = GlobalAlloc(GHND, utf16_len * 2 + 2); // moveable and zero'ed mem alloc.
- LPVOID memLock = GlobalLock(hMem);
- fl_utf8toUtf16(fl_selection_buffer[clipboard], fl_selection_length[clipboard], (unsigned short*) memLock, utf16_len + 1);
- GlobalUnlock(hMem);
- SetClipboardData(CF_UNICODETEXT, hMem);
- CloseClipboard();
- GlobalFree(hMem);
- fl_i_own_selection[clipboard] = 0;
- } else {
- // only if it fails, instruct paste() to use the internal buffers
- fl_i_own_selection[clipboard] = 1;
- }
- }
+ fl_i_own_selection[clipboard] = 1;
+ if (clipboard)
+ fl_update_clipboard();
}
// Call this when a "paste" operation happens:
-void Fl::paste(Fl_Widget &receiver, int clipboard) {
- if (!clipboard || fl_i_own_selection[clipboard]) {
+void Fl::paste(Fl_Widget &receiver, int clipboard, const char *type) {
+ if (!clipboard || (fl_i_own_selection[clipboard] && strcmp(type, Fl::clipboard_plain_text) == 0)) {
// We already have it, do it quickly without window server.
// Notice that the text is clobbered if set_selection is
// called in response to FL_PASTE!
-
- // Convert \r\n -> \n
char *i = fl_selection_buffer[clipboard];
if (i==0L) {
Fl::e_text = 0;
@@ -584,43 +668,209 @@ void Fl::paste(Fl_Widget &receiver, int clipboard) {
}
Fl::e_text = new char[fl_selection_length[clipboard]+1];
char *o = Fl::e_text;
- while (*i) {
+ while (*i) { // Convert \r\n -> \n
if ( *i == '\r' && *(i+1) == '\n') i++;
else *o++ = *i++;
}
*o = 0;
Fl::e_length = (int) (o - Fl::e_text);
+ Fl::e_clipboard_type = Fl::clipboard_plain_text;
receiver.handle(FL_PASTE);
delete [] Fl::e_text;
Fl::e_text = 0;
- } else {
+ } else if (clipboard) {
+ HANDLE h;
if (!OpenClipboard(NULL)) return;
- HANDLE h = GetClipboardData(CF_UNICODETEXT);
- if (h) {
- wchar_t *memLock = (wchar_t*) GlobalLock(h);
- size_t utf16_len = wcslen(memLock);
- Fl::e_text = (char*) malloc (utf16_len * 4 + 1);
- unsigned utf8_len = fl_utf8fromwc(Fl::e_text, (unsigned) (utf16_len * 4), memLock, (unsigned) utf16_len);
- *(Fl::e_text + utf8_len) = 0;
- LPSTR a,b;
- a = b = Fl::e_text;
- while (*a) { // strip the CRLF pairs ($%$#@^)
- if (*a == '\r' && a[1] == '\n') a++;
- else *b++ = *a++;
+ if (strcmp(type, Fl::clipboard_plain_text) == 0) { // we want plain text from clipboard
+ if ((h = GetClipboardData(CF_UNICODETEXT))) { // there's text in the clipboard
+ wchar_t *memLock = (wchar_t*) GlobalLock(h);
+ size_t utf16_len = wcslen(memLock);
+ Fl::e_text = new char[utf16_len * 4 + 1];
+ unsigned utf8_len = fl_utf8fromwc(Fl::e_text, (unsigned) (utf16_len * 4), memLock, (unsigned) utf16_len);
+ *(Fl::e_text + utf8_len) = 0;
+ GlobalUnlock(h);
+ LPSTR a,b;
+ a = b = Fl::e_text;
+ while (*a) { // strip the CRLF pairs ($%$#@^)
+ if (*a == '\r' && a[1] == '\n') a++;
+ else *b++ = *a++;
+ }
+ *b = 0;
+ Fl::e_length = (int) (b - Fl::e_text);
+ Fl::e_clipboard_type = Fl::clipboard_plain_text; // indicates that the paste event is for plain UTF8 text
+ receiver.handle(FL_PASTE); // send the FL_PASTE event to the widget
+ delete[] Fl::e_text;
+ Fl::e_text = 0;
+ }
+ }
+ else if (strcmp(type, Fl::clipboard_image) == 0) { // we want an image from clipboard
+ uchar *rgb = NULL;
+ int width, height, depth;
+ if ( (h = GetClipboardData(CF_DIB)) ) { // if there's a DIB in clipboard
+ LPBITMAPINFO lpBI = (LPBITMAPINFO)GlobalLock(h) ;
+ width = lpBI->bmiHeader.biWidth; // bitmap width & height
+ height = lpBI->bmiHeader.biHeight;
+ if ( (lpBI->bmiHeader.biBitCount == 24 || lpBI->bmiHeader.biBitCount == 32) &&
+ lpBI->bmiHeader.biCompression == BI_RGB &&
+ lpBI->bmiHeader.biClrUsed == 0) { // direct use of the DIB data if it's RGB or RGBA
+ int linewidth; // row length
+ depth = lpBI->bmiHeader.biBitCount/8; // 3 or 4
+ if (depth == 3) linewidth = 4 * ((3*width + 3)/4); // row length: series of groups of 3 bytes, rounded to multiple of 4 bytes
+ else linewidth = 4*width;
+ rgb = new uchar[width * height * depth]; // will hold the image data
+ uchar *p = rgb, *r, rr, gg, bb;
+ for (int i=height-1; i>=0; i--) { // for each row, from last to first
+ r = (uchar*)(lpBI->bmiColors) + i*linewidth; // beginning of pixel data for the ith row
+ for (int j=0; j<width; j++) { // for each pixel in a row
+ bb = *r++; // BGR is in DIB
+ gg = *r++;
+ rr = *r++;
+ *p++ = rr; // we want RGB
+ *p++ = gg;
+ *p++ = bb;
+ if (depth == 4) *p++ = *r++; // copy alpha if present
+ }
+ }
+ }
+ else { // the system will decode a complex DIB
+ void *pDIBBits = (void*)(lpBI->bmiColors);
+ if (lpBI->bmiHeader.biCompression == BI_BITFIELDS) pDIBBits = (void*)(lpBI->bmiColors + 3);
+ else if (lpBI->bmiHeader.biClrUsed > 0) pDIBBits = (void*)(lpBI->bmiColors + lpBI->bmiHeader.biClrUsed);
+ Fl_Offscreen off = fl_create_offscreen(width, height);
+ fl_begin_offscreen(off);
+ SetDIBitsToDevice(fl_gc, 0, 0, width, height, 0, 0, 0, height, pDIBBits, lpBI, DIB_RGB_COLORS);
+ rgb = fl_read_image(NULL, 0, 0, width, height);
+ depth = 3;
+ fl_end_offscreen();
+ fl_delete_offscreen(off);
+ }
+ GlobalUnlock(h);
+ }
+ else if ((h = GetClipboardData(CF_ENHMETAFILE))) { // if there's an enhanced metafile in clipboard
+ ENHMETAHEADER header;
+ GetEnhMetaFileHeader((HENHMETAFILE)h, sizeof(header), &header); // get structure containing metafile dimensions
+ width = (header.rclFrame.right - header.rclFrame.left + 1); // in .01 mm units
+ height = (header.rclFrame.bottom - header.rclFrame.top + 1);
+ HDC hdc = GetDC(NULL); // get unit correspondance between .01 mm and screen pixels
+ int hmm = GetDeviceCaps(hdc, HORZSIZE);
+ int hdots = GetDeviceCaps(hdc, HORZRES);
+ int vmm = GetDeviceCaps(hdc, VERTSIZE);
+ int vdots = GetDeviceCaps(hdc, VERTRES);
+ ReleaseDC(NULL, hdc);
+ float factorw = (100. * hmm) / hdots;
+ float factorh = (100. * vmm) / vdots + 0.5;
+ width /= factorw; height /= factorh; // convert to screen pixel unit
+ RECT rect = {0, 0, width, height};
+ Fl_Offscreen off = fl_create_offscreen(width, height);
+ fl_begin_offscreen(off);
+ fl_color(FL_WHITE); fl_rectf(0,0,width, height); // draw white background
+ PlayEnhMetaFile(fl_gc, (HENHMETAFILE)h, &rect); // draw metafile to offscreen buffer
+ rgb = fl_read_image(NULL, 0, 0, width, height); // read pixels from offscreen buffer
+ depth = 3;
+ fl_end_offscreen();
+ fl_delete_offscreen(off);
+ }
+ if (rgb) {
+ Fl_RGB_Image *image = new Fl_RGB_Image(rgb, width, height, depth); // create new image from pixel data
+ image->alloc_array = 1;
+ Fl::e_clipboard_data = image;
+ Fl::e_clipboard_type = Fl::clipboard_image; // indicates that the paste event is for image data
+ int done = receiver.handle(FL_PASTE); // send FL_PASTE event to widget
+ Fl::e_clipboard_type = "";
+ if (done == 0) { // if widget did not handle the event, delete the image
+ Fl::e_clipboard_data = NULL;
+ delete image;
+ }
+ }
}
- *b = 0;
- Fl::e_length = (int) (b - Fl::e_text);
- receiver.handle(FL_PASTE);
- GlobalUnlock(h);
- free(Fl::e_text);
- Fl::e_text = 0;
+ CloseClipboard();
+ }
+}
+
+int Fl::clipboard_contains(const char *type)
+{
+ int retval = 0;
+ if (!OpenClipboard(NULL)) return 0;
+ if (strcmp(type, Fl::clipboard_plain_text) == 0 || type[0] == 0) {
+ retval = IsClipboardFormatAvailable(CF_UNICODETEXT);
+ }
+ else if (strcmp(type, Fl::clipboard_image) == 0) {
+ retval = IsClipboardFormatAvailable(CF_DIB) || IsClipboardFormatAvailable(CF_ENHMETAFILE);
+ }
+ CloseClipboard();
+ return retval;
+}
+
+static 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);
+}
+
+static void fl_clipboard_notify_untarget(HWND wnd) {
+ if (wnd != clipboard_wnd)
+ return;
+
+ // We might be called late in the cleanup where Windows has already
+ // implicitly destroyed our clipboard window. At that point we need
+ // to do some extra work to manually repair the clipboard chain.
+ if (IsWindow(wnd))
+ ChangeClipboardChain(wnd, next_clipboard_wnd);
+ else {
+ HWND tmp, head;
+
+ tmp = CreateWindow("STATIC", "Temporary FLTK Clipboard Window", 0,
+ 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL);
+ if (tmp == NULL)
+ return;
+
+ head = SetClipboardViewer(tmp);
+ if (head == NULL)
+ ChangeClipboardChain(tmp, next_clipboard_wnd);
+ else {
+ SendMessage(head, WM_CHANGECBCHAIN, (WPARAM)wnd, (LPARAM)next_clipboard_wnd);
+ ChangeClipboardChain(tmp, head);
}
- CloseClipboard();
+
+ DestroyWindow(tmp);
+ }
+
+ clipboard_wnd = next_clipboard_wnd = 0;
+}
+
+void fl_clipboard_notify_retarget(HWND wnd) {
+ // The given window is getting destroyed. If it's part of the
+ // clipboard chain then we need to unregister it and find a
+ // replacement window.
+ if (wnd != clipboard_wnd)
+ return;
+
+ fl_clipboard_notify_untarget(wnd);
+
+ if (Fl::first_window())
+ fl_clipboard_notify_target(fl_xid(Fl::first_window()));
+}
+
+void fl_clipboard_notify_change() {
+ // untarget clipboard monitor if no handlers are registered
+ if (clipboard_wnd != NULL && fl_clipboard_notify_empty()) {
+ fl_clipboard_notify_untarget(clipboard_wnd);
+ return;
}
+
+ // if there are clipboard notify handlers but no window targeted
+ // target first window if available
+ if (clipboard_wnd == NULL && Fl::first_window())
+ fl_clipboard_notify_target(fl_xid(Fl::first_window()));
}
////////////////////////////////////////////////////////////////
-char fl_is_ime = 0;
void fl_get_codepage()
{
HKL hkl = GetKeyboardLayout(0);
@@ -628,14 +878,7 @@ void fl_get_codepage()
GetLocaleInfo (LOWORD(hkl), LOCALE_IDEFAULTANSICODEPAGE, ld, 6);
DWORD ccp = atol(ld);
- fl_is_ime = 0;
-
fl_codepage = ccp;
- if (fl_aimm) {
- fl_aimm->GetCodePageA(GetKeyboardLayout(0), &fl_codepage);
- } else if (get_imm_module() && flImmIsIME(hkl)) {
- fl_is_ime = 1;
- }
}
HWND fl_capture;
@@ -856,7 +1099,6 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
case WM_CLOSE: // user clicked close box
Fl::handle(FL_CLOSE, window);
- PostQuitMessage(0);
return 0;
case WM_SYNCPAINT :
@@ -942,6 +1184,10 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
break;
case WM_SETFOCUS:
+ if ((Fl::modal_) && (Fl::modal_ != window)) {
+ SetFocus(fl_xid(Fl::modal_));
+ return 0;
+ }
Fl::handle(FL_FOCUS, window);
break;
@@ -1191,38 +1437,31 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lPar
fl_i_own_selection[1] = 0;
return 1;
- case WM_RENDERALLFORMATS:
- fl_i_own_selection[1] = 0;
- // Windoze seems unhappy unless I do these two steps. Documentation
- // seems to vary on whether opening the clipboard is necessary or
- // is in fact wrong:
- CloseClipboard();
- OpenClipboard(NULL);
- // fall through...
- case WM_RENDERFORMAT: {
- HANDLE h;
-
-// int l = fl_utf_nb_char((unsigned char*)fl_selection_buffer[1], fl_selection_length[1]);
- int l = fl_utf8toUtf16(fl_selection_buffer[1], fl_selection_length[1], NULL, 0); // Pass NULL buffer to query length required
- h = GlobalAlloc(GHND, (l+1) * sizeof(unsigned short));
- if (h) {
- unsigned short *g = (unsigned short*) GlobalLock(h);
-// fl_utf2unicode((unsigned char *)fl_selection_buffer[1], fl_selection_length[1], (xchar*)g);
- l = fl_utf8toUtf16(fl_selection_buffer[1], fl_selection_length[1], g, (l+1));
- g[l] = 0;
- GlobalUnlock(h);
- SetClipboardData(CF_UNICODETEXT, h);
- }
-
- // Windoze also seems unhappy if I don't do this. Documentation very
- // unclear on what is correct:
- if (fl_msg.message == WM_RENDERALLFORMATS) CloseClipboard();
- return 1;}
case WM_DISPLAYCHANGE: // occurs when screen configuration (number, position) changes
Fl::call_screen_init();
Fl::handle(FL_SCREEN_CONFIGURATION_CHANGED, NULL);
return 0;
+ case WM_CHANGECBCHAIN:
+ if ((hWnd == clipboard_wnd) && (next_clipboard_wnd == (HWND)wParam))
+ next_clipboard_wnd = (HWND)lParam;
+ else
+ SendMessage(next_clipboard_wnd, WM_CHANGECBCHAIN, wParam, lParam);
+ return 0;
+
+ case WM_DRAWCLIPBOARD:
+ // When the clipboard moves between two FLTK windows,
+ // fl_i_own_selection will temporarily be false as we are
+ // processing this message. Hence the need to use fl_find().
+ if (!initial_clipboard && !fl_find(GetClipboardOwner()))
+ fl_trigger_clipboard_notify(1);
+ initial_clipboard = false;
+
+ if (next_clipboard_wnd)
+ SendMessage(next_clipboard_wnd, WM_DRAWCLIPBOARD, wParam, lParam);
+
+ return 0;
+
default:
if (Fl::handle(0,0)) return 0;
break;
@@ -1290,13 +1529,17 @@ int Fl_X::fake_X_wm(const Fl_Window* w,int &X,int &Y, int &bt,int &bx, int &by)
if (fallback) {
if (w->border() && !w->parent()) {
if (w->size_range_set && (w->maxw != w->minw || w->maxh != w->minh)) {
- ret = 2;
- bx = GetSystemMetrics(SM_CXSIZEFRAME);
- by = GetSystemMetrics(SM_CYSIZEFRAME);
+ ret = 2;
+ bx = GetSystemMetrics(SM_CXSIZEFRAME);
+ by = GetSystemMetrics(SM_CYSIZEFRAME);
} else {
- ret = 1;
- bx = GetSystemMetrics(SM_CXFIXEDFRAME);
- by = GetSystemMetrics(SM_CYFIXEDFRAME);
+ ret = 1;
+ int padding = GetSystemMetrics(SM_CXPADDEDBORDER);
+ NONCLIENTMETRICS ncm;
+ ncm.cbSize = sizeof(NONCLIENTMETRICS);
+ SystemParametersInfo(SPI_GETNONCLIENTMETRICS, 0, &ncm, 0);
+ bx = GetSystemMetrics(SM_CXFIXEDFRAME) + (padding ? padding + ncm.iBorderWidth : 0);
+ by = GetSystemMetrics(SM_CYFIXEDFRAME) + (padding ? padding + ncm.iBorderWidth : 0);
}
bt = GetSystemMetrics(SM_CYCAPTION);
}
@@ -1333,7 +1576,6 @@ int Fl_X::fake_X_wm(const Fl_Window* w,int &X,int &Y, int &bt,int &bx, int &by)
Y+=yoff;
if (w->fullscreen_active()) {
- X = Y = 0;
bx = by = bt = 0;
}
@@ -1387,19 +1629,42 @@ void Fl_Window::resize(int X,int Y,int W,int H) {
}
}
-static void make_fullscreen(Fl_Window *w, Window xid, int X, int Y, int W, int H) {
+void Fl_X::make_fullscreen(int X, int Y, int W, int H) {
+ int top, bottom, left, right;
int sx, sy, sw, sh;
- Fl::screen_xywh(sx, sy, sw, sh, X, Y, W, H);
+
+ top = w->fullscreen_screen_top;
+ bottom = w->fullscreen_screen_bottom;
+ left = w->fullscreen_screen_left;
+ right = w->fullscreen_screen_right;
+
+ if ((top < 0) || (bottom < 0) || (left < 0) || (right < 0)) {
+ top = Fl::screen_num(X, Y, W, H);
+ bottom = top;
+ left = top;
+ right = top;
+ }
+
+ Fl::screen_xywh(sx, sy, sw, sh, top);
+ Y = sy;
+ Fl::screen_xywh(sx, sy, sw, sh, bottom);
+ H = sy + sh - Y;
+ Fl::screen_xywh(sx, sy, sw, sh, left);
+ X = sx;
+ Fl::screen_xywh(sx, sy, sw, sh, right);
+ W = sx + sw - X;
+
DWORD flags = GetWindowLong(xid, GWL_STYLE);
flags = flags & ~(WS_THICKFRAME|WS_CAPTION);
SetWindowLong(xid, GWL_STYLE, flags);
+
// SWP_NOSENDCHANGING is so that we can override size limits
- SetWindowPos(xid, HWND_TOP, sx, sy, sw, sh, SWP_NOSENDCHANGING | SWP_FRAMECHANGED);
+ SetWindowPos(xid, HWND_TOP, X, Y, W, H, SWP_NOSENDCHANGING | SWP_FRAMECHANGED);
}
void Fl_Window::fullscreen_x() {
_set_fullscreen();
- make_fullscreen(this, fl_xid(this), x(), y(), w(), h());
+ i->make_fullscreen(x(), y(), w(), h());
Fl::handle(FL_FULLSCREEN, this);
}
@@ -1477,13 +1742,14 @@ void fl_fix_focus(); // in Fl.cxx
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
Fl_X* Fl_X::make(Fl_Window* w) {
Fl_Group::current(0); // get rid of very common user bug: forgot end()
+ fl_open_display();
+
// if the window is a subwindow and our parent is not mapped yet, we
// mark this window visible, so that mapping the parent at a later
// point in time will call this function again to finally map the subwindow.
@@ -1526,7 +1792,7 @@ Fl_X* Fl_X::make(Fl_Window* w) {
if (!w->icon())
w->icon((void *)LoadIcon(NULL, IDI_APPLICATION));
wcw.hIcon = wcw.hIconSm = (HICON)w->icon();
- wcw.hCursor = fl_default_cursor = LoadCursor(NULL, IDC_ARROW);
+ 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));
wcw.hbrBackground = NULL;
@@ -1618,7 +1884,8 @@ Fl_X* Fl_X::make(Fl_Window* w) {
x->setwindow(w);
x->region = 0;
x->private_dc = 0;
- x->cursor = fl_default_cursor;
+ x->cursor = LoadCursor(NULL, IDC_ARROW);
+ x->custom_cursor = 0;
if (!fl_codepage) fl_get_codepage();
WCHAR *lab = NULL;
@@ -1644,6 +1911,11 @@ Fl_X* Fl_X::make(Fl_Window* w) {
);
if (lab) free(lab);
+ x->next = Fl_X::first;
+ Fl_X::first = x;
+
+ x->set_icons();
+
if (w->fullscreen_active()) {
/* We need to make sure that the fullscreen is created on the
default monitor, ie the desktop where the shortcut is located
@@ -1652,12 +1924,14 @@ Fl_X* Fl_X::make(Fl_Window* w) {
monitor the window was placed on. */
RECT rect;
GetWindowRect(x->xid, &rect);
- make_fullscreen(w, x->xid, rect.left, rect.top,
- rect.right - rect.left, rect.bottom - rect.top);
+ x->make_fullscreen(rect.left, rect.top,
+ rect.right - rect.left, rect.bottom - rect.top);
}
- x->next = Fl_X::first;
- Fl_X::first = x;
+ // Setup clipboard monitor target if there are registered handlers and
+ // no window is targeted.
+ if (!fl_clipboard_notify_empty() && clipboard_wnd == NULL)
+ fl_clipboard_notify_target(x->xid);
x->wait_for_expose = 1;
if (fl_show_iconic) {showit = 0; fl_show_iconic = 0;}
@@ -1668,24 +1942,22 @@ Fl_X* Fl_X::make(Fl_Window* w) {
Fl::e_number = old_event;
w->redraw(); // force draw to happen
}
+
+ // Needs to be done before ShowWindow() to get the correct behaviour
+ // when we get WM_SETFOCUS.
+ if (w->modal()) {Fl::modal_ = w; fl_fix_focus();}
+
// If we've captured the mouse, we dont want to activate any
// other windows from the code, or we lose the capture.
ShowWindow(x->xid, !showit ? SW_SHOWMINNOACTIVE :
(Fl::grab() || (styleEx & WS_EX_TOOLWINDOW)) ? SW_SHOWNOACTIVATE : SW_SHOWNORMAL);
// Register all windows for potential drag'n'drop operations
- fl_OleInitialize();
RegisterDragDrop(x->xid, flIDropTarget);
- if (!fl_aimm) {
- CoCreateInstance(CLSID_CActiveIMM, NULL, CLSCTX_INPROC_SERVER,
- IID_IActiveIMMApp, (void**) &fl_aimm);
- if (fl_aimm) {
- fl_aimm->Activate(TRUE);
- }
- }
+ if (!im_enabled)
+ flImmAssociateContextEx(x->xid, 0, 0);
- if (w->modal()) {Fl::modal_ = w; fl_fix_focus();}
return x;
}
@@ -1867,6 +2139,329 @@ void Fl_Window::label(const char *name,const char *iname) {
}
////////////////////////////////////////////////////////////////
+
+static HICON image_to_icon(const Fl_RGB_Image *image, bool is_icon,
+ int hotx, int hoty) {
+ BITMAPV5HEADER bi;
+ HBITMAP bitmap, mask;
+ DWORD *bits;
+ HICON icon;
+
+ if (!is_icon) {
+ if ((hotx < 0) || (hotx >= image->w()))
+ return NULL;
+ if ((hoty < 0) || (hoty >= image->h()))
+ return NULL;
+ }
+
+ memset(&bi, 0, sizeof(BITMAPV5HEADER));
+
+ bi.bV5Size = sizeof(BITMAPV5HEADER);
+ bi.bV5Width = image->w();
+ bi.bV5Height = -image->h(); // Negative for top-down
+ 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);
+
+ if (bits == NULL)
+ return NULL;
+
+ 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);
+ if (mask == NULL) {
+ DeleteObject(bitmap);
+ return NULL;
+ }
+
+ ICONINFO ii;
+
+ ii.fIcon = is_icon;
+ ii.xHotspot = hotx;
+ ii.yHotspot = hoty;
+ ii.hbmMask = mask;
+ ii.hbmColor = bitmap;
+
+ icon = CreateIconIndirect(&ii);
+
+ DeleteObject(bitmap);
+ DeleteObject(mask);
+
+ if (icon == NULL)
+ return NULL;
+
+ return icon;
+}
+
+////////////////////////////////////////////////////////////////
+
+static HICON default_big_icon = NULL;
+static HICON default_small_icon = NULL;
+
+static const Fl_RGB_Image *find_best_icon(int ideal_width,
+ const Fl_RGB_Image *icons[],
+ int count) {
+ const Fl_RGB_Image *best;
+
+ best = NULL;
+
+ for (int i = 0;i < count;i++) {
+ if (best == NULL)
+ best = icons[i];
+ else {
+ if (best->w() < ideal_width) {
+ if (icons[i]->w() > best->w())
+ best = icons[i];
+ } else {
+ if ((icons[i]->w() >= ideal_width) &&
+ (icons[i]->w() < best->w()))
+ best = icons[i];
+ }
+ }
+ }
+
+ return best;
+}
+
+void Fl_X::set_default_icons(const Fl_RGB_Image *icons[], int count) {
+ const Fl_RGB_Image *best_big, *best_small;
+
+ if (default_big_icon != NULL)
+ DestroyIcon(default_big_icon);
+ if (default_small_icon != NULL)
+ DestroyIcon(default_small_icon);
+
+ default_big_icon = NULL;
+ default_small_icon = NULL;
+
+ best_big = find_best_icon(GetSystemMetrics(SM_CXICON), icons, count);
+ best_small = find_best_icon(GetSystemMetrics(SM_CXSMICON), icons, count);
+
+ if (best_big != NULL)
+ default_big_icon = image_to_icon(best_big, true, 0, 0);
+
+ if (best_small != NULL)
+ default_small_icon = image_to_icon(best_small, true, 0, 0);
+}
+
+void Fl_X::set_default_icons(HICON big_icon, HICON small_icon) {
+ if (default_big_icon != NULL)
+ DestroyIcon(default_big_icon);
+ if (default_small_icon != NULL)
+ DestroyIcon(default_small_icon);
+
+ default_big_icon = NULL;
+ default_small_icon = NULL;
+
+ if (big_icon != NULL)
+ default_big_icon = CopyIcon(big_icon);
+ if (small_icon != NULL)
+ default_small_icon = CopyIcon(small_icon);
+}
+
+void Fl_X::set_icons() {
+ HICON big_icon, small_icon;
+
+ // Windows doesn't copy the icons, so we have to "leak" them when
+ // setting, and clean up when we change to some other icons.
+ big_icon = (HICON)SendMessage(xid, WM_GETICON, ICON_BIG, 0);
+ if ((big_icon != NULL) && (big_icon != default_big_icon))
+ DestroyIcon(big_icon);
+ small_icon = (HICON)SendMessage(xid, WM_GETICON, ICON_SMALL, 0);
+ if ((small_icon != NULL) && (small_icon != default_small_icon))
+ DestroyIcon(small_icon);
+
+ big_icon = NULL;
+ small_icon = NULL;
+
+ if (w->icon_->count) {
+ const Fl_RGB_Image *best_big, *best_small;
+
+ best_big = find_best_icon(GetSystemMetrics(SM_CXICON),
+ (const Fl_RGB_Image **)w->icon_->icons,
+ w->icon_->count);
+ best_small = find_best_icon(GetSystemMetrics(SM_CXSMICON),
+ (const Fl_RGB_Image **)w->icon_->icons,
+ w->icon_->count);
+
+ if (best_big != NULL)
+ big_icon = image_to_icon(best_big, true, 0, 0);
+ if (best_small != NULL)
+ small_icon = image_to_icon(best_small, true, 0, 0);
+ } else {
+ if ((w->icon_->big_icon != NULL) || (w->icon_->small_icon != NULL)) {
+ big_icon = w->icon_->big_icon;
+ small_icon = w->icon_->small_icon;
+ } else {
+ big_icon = default_big_icon;
+ small_icon = default_small_icon;
+ }
+ }
+
+ SendMessage(xid, WM_SETICON, ICON_BIG, (LPARAM)big_icon);
+ SendMessage(xid, WM_SETICON, ICON_SMALL, (LPARAM)small_icon);
+}
+
+/** Sets the default window icons.
+
+ Convenience function to set the default icons using Windows'
+ native HICON icon handles.
+
+ The given icons are copied. You can free the icons immediately after
+ this call.
+
+ \param[in] big_icon default large icon for all windows
+ subsequently created
+ \param[in] small_icon default small icon for all windows
+ subsequently created
+
+ \see Fl_Window::default_icon(const Fl_RGB_Image *)
+ \see Fl_Window::default_icons(const Fl_RGB_Image *[], int)
+ \see Fl_Window::icon(const Fl_RGB_Image *)
+ \see Fl_Window::icons(const Fl_RGB_Image *[], int)
+ \see Fl_Window::icons(HICON, HICON)
+ */
+void Fl_Window::default_icons(HICON big_icon, HICON small_icon) {
+ Fl_X::set_default_icons(big_icon, small_icon);
+}
+
+/** Sets the window icons.
+
+ Convenience function to set this window's icons using Windows'
+ native HICON icon handles.
+
+ The given icons are copied. You can free the icons immediately after
+ this call.
+
+ \param[in] big_icon large icon for this window
+ \param[in] small_icon small icon for this windows
+
+ \see Fl_Window::default_icon(const Fl_RGB_Image *)
+ \see Fl_Window::default_icons(const Fl_RGB_Image *[], int)
+ \see Fl_Window::default_icons(HICON, HICON)
+ \see Fl_Window::icon(const Fl_RGB_Image *)
+ \see Fl_Window::icons(const Fl_RGB_Image *[], int)
+ */
+void Fl_Window::icons(HICON big_icon, HICON small_icon) {
+ free_icons();
+
+ if (big_icon != NULL)
+ icon_->big_icon = CopyIcon(big_icon);
+ if (small_icon != NULL)
+ icon_->small_icon = CopyIcon(small_icon);
+
+ if (i)
+ i->set_icons();
+}
+
+////////////////////////////////////////////////////////////////
+
+#ifndef IDC_HAND
+# define IDC_HAND MAKEINTRESOURCE(32649)
+#endif // !IDC_HAND
+
+int Fl_X::set_cursor(Fl_Cursor c) {
+ LPSTR n;
+ HCURSOR new_cursor;
+
+ if (c == FL_CURSOR_NONE)
+ new_cursor = NULL;
+ else {
+ switch (c) {
+ case FL_CURSOR_ARROW: n = IDC_ARROW; break;
+ case FL_CURSOR_CROSS: n = IDC_CROSS; break;
+ case FL_CURSOR_WAIT: n = IDC_WAIT; break;
+ case FL_CURSOR_INSERT: n = IDC_IBEAM; break;
+ case FL_CURSOR_HAND: n = IDC_HAND; break;
+ case FL_CURSOR_HELP: n = IDC_HELP; break;
+ case FL_CURSOR_MOVE: n = IDC_SIZEALL; break;
+ case FL_CURSOR_N:
+ case FL_CURSOR_S:
+ // FIXME: Should probably have fallbacks for these instead
+ case FL_CURSOR_NS: n = IDC_SIZENS; break;
+ case FL_CURSOR_NE:
+ case FL_CURSOR_SW:
+ // FIXME: Dito.
+ case FL_CURSOR_NESW: n = IDC_SIZENESW; break;
+ case FL_CURSOR_E:
+ case FL_CURSOR_W:
+ // FIXME: Dito.
+ case FL_CURSOR_WE: n = IDC_SIZEWE; break;
+ case FL_CURSOR_SE:
+ case FL_CURSOR_NW:
+ // FIXME: Dito.
+ case FL_CURSOR_NWSE: n = IDC_SIZENWSE; break;
+ default:
+ return 0;
+ }
+
+ new_cursor = LoadCursor(NULL, n);
+ if (new_cursor == NULL)
+ return 0;
+ }
+
+ if ((cursor != NULL) && custom_cursor)
+ DestroyIcon(cursor);
+
+ cursor = new_cursor;
+ custom_cursor = 0;
+
+ SetCursor(cursor);
+
+ return 1;
+}
+
+int Fl_X::set_cursor(const Fl_RGB_Image *image, int hotx, int hoty) {
+ HCURSOR new_cursor;
+
+ new_cursor = image_to_icon(image, false, hotx, hoty);
+ if (new_cursor == NULL)
+ return 0;
+
+ if ((cursor != NULL) && custom_cursor)
+ DestroyIcon(cursor);
+
+ cursor = new_cursor;
+ custom_cursor = 1;
+
+ SetCursor(cursor);
+
+ return 1;
+}
+
+////////////////////////////////////////////////////////////////
// Implement the virtual functions for the base Fl_Window class:
// If the box is a filled rectangle, we can make the redisplay *look*
@@ -2166,5 +2761,5 @@ void preparePrintFront(void)
#endif // FL_DOXYGEN
//
-// End of "$Id: Fl_win32.cxx 9624 2012-06-21 08:52:29Z manolo $".
+// End of "$Id: Fl_win32.cxx 10387 2014-10-20 15:14:12Z ossman $".
//
diff --git a/src/Fl_x.cxx b/src/Fl_x.cxx
index 5d8a8af..11d1b2f 100644
--- a/src/Fl_x.cxx
+++ b/src/Fl_x.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: Fl_x.cxx 9699 2012-10-16 15:35:34Z manolo $"
+// "$Id: Fl_x.cxx 10412 2014-10-29 20:25:46Z cand $"
//
// X specific code for the Fast Light Tool Kit (FLTK).
//
@@ -19,7 +19,7 @@
#ifdef WIN32
//# include "Fl_win32.cxx"
#elif defined(__APPLE__)
-//# include "Fl_mac.cxx"
+//# include "Fl_mac.cxx" // now Fl_cocoa.mm
#elif !defined(FL_DOXYGEN)
# define CONSOLIDATE_MOTION 1
@@ -34,15 +34,20 @@
# include <FL/Fl_Tooltip.H>
# include <FL/fl_draw.H>
# include <FL/Fl_Paged_Device.H>
+# include <FL/Fl_Shared_Image.H>
+# include <FL/fl_ask.H>
+# include <FL/filename.H>
# include <stdio.h>
# include <stdlib.h>
# include "flstring.h"
# include <unistd.h>
+# include <time.h>
# include <sys/time.h>
# include <X11/Xmd.h>
# include <X11/Xlocale.h>
# include <X11/Xlib.h>
# include <X11/keysym.h>
+# include "Xutf8.h"
#define USE_XRANDR (HAVE_DLSYM && HAVE_DLFCN_H) // means attempt to dynamically load libXrandr.so
#if USE_XRANDR
#include <dlfcn.h>
@@ -53,6 +58,17 @@ static XRRUpdateConfiguration_type XRRUpdateConfiguration_f;
static int randrEventBase; // base of RandR-defined events
#endif
+# if HAVE_XFIXES
+# include <X11/extensions/Xfixes.h>
+static int xfixes_event_base = 0;
+static bool have_xfixes = false;
+# endif
+
+# include <X11/cursorfont.h>
+
+# if HAVE_XCURSOR
+# include <X11/Xcursor/Xcursor.h>
+# endif
static Fl_Xlib_Graphics_Driver fl_xlib_driver;
static Fl_Display_Device fl_xlib_display(&fl_xlib_driver);
Fl_Display_Device *Fl_Display_Device::_display = &fl_xlib_display;// the platform display
@@ -177,6 +193,8 @@ void Fl::remove_fd(int n) {
remove_fd(n, -1);
}
+extern int fl_send_system_handlers(void *e);
+
#if CONSOLIDATE_MOTION
static Fl_Window* send_motion;
extern Fl_Window* fl_xmousewin;
@@ -187,6 +205,8 @@ static void do_queued_events() {
while (XEventsQueued(fl_display,QueuedAfterReading)) {
XEvent xevent;
XNextEvent(fl_display, &xevent);
+ if (fl_send_system_handlers(&xevent))
+ continue;
fl_handle(xevent);
}
// we send FL_LEAVE only if the mouse did not enter some other window:
@@ -296,9 +316,10 @@ Window fl_message_window = 0;
int fl_screen;
XVisualInfo *fl_visual;
Colormap fl_colormap;
-XIM fl_xim_im = 0;
+static XIM fl_xim_im = 0;
XIC fl_xim_ic = 0;
-char fl_is_over_the_spot = 0;
+static Window fl_xim_win = 0;
+static char fl_is_over_the_spot = 0;
static XRectangle status_area;
static Atom WM_DELETE_WINDOW;
@@ -306,6 +327,9 @@ static Atom WM_PROTOCOLS;
static Atom fl_MOTIF_WM_HINTS;
static Atom TARGETS;
static Atom CLIPBOARD;
+static Atom TIMESTAMP;
+static Atom PRIMARY_TIMESTAMP;
+static Atom CLIPBOARD_TIMESTAMP;
Atom fl_XdndAware;
Atom fl_XdndSelection;
Atom fl_XdndEnter;
@@ -318,19 +342,25 @@ Atom fl_XdndActionCopy;
Atom fl_XdndFinished;
//Atom fl_XdndProxy;
Atom fl_XdndURIList;
-Atom fl_Xatextplainutf;
-Atom fl_Xatextplainutf2; // STR#2930
-Atom fl_Xatextplain;
+static Atom fl_Xatextplainutf;
+static Atom fl_Xatextplainutf2; // STR#2930
+static Atom fl_Xatextplain;
static Atom fl_XaText;
-Atom fl_XaCompoundText;
+static Atom fl_XaCompoundText;
Atom fl_XaUtf8String;
-Atom fl_XaTextUriList;
-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;
-Atom fl_NET_WORKAREA;
+static Atom fl_XaTextUriList;
+static Atom fl_XaImageBmp;
+static Atom fl_XaImagePNG;
+static Atom fl_INCR;
+static Atom fl_NET_WM_NAME; // utf8 aware window label
+static Atom fl_NET_WM_ICON_NAME; // utf8 aware window icon name
+static Atom fl_NET_SUPPORTING_WM_CHECK;
+static Atom fl_NET_WM_STATE;
+static Atom fl_NET_WM_STATE_FULLSCREEN;
+static Atom fl_NET_WM_FULLSCREEN_MONITORS;
+static Atom fl_NET_WORKAREA;
+static Atom fl_NET_WM_ICON;
+static Atom fl_NET_ACTIVE_WINDOW;
/*
X defines 32-bit-entities to have a format value of max. 32,
@@ -362,14 +392,14 @@ extern "C" {
extern char *fl_get_font_xfld(int fnum, int size);
-void fl_new_ic()
+static void fl_new_ic()
{
XVaNestedList preedit_attr = NULL;
XVaNestedList status_attr = NULL;
static XFontSet fs = NULL;
char *fnt;
- char **missing_list;
- int missing_count;
+ char **missing_list = 0;
+ int missing_count = 0;
char *def_string;
static XRectangle spot;
int predit = 0;
@@ -397,6 +427,9 @@ void fl_new_ic()
if (must_free_fnt) free(fnt);
}
#endif
+
+ if (missing_list) XFreeStringList(missing_list);
+
preedit_attr = XVaCreateNestedList(0,
XNSpotLocation, &spot,
XNFontSet, fs, NULL);
@@ -539,7 +572,7 @@ void fl_set_status(int x, int y, int w, int h)
XFree(status_attr);
}
-void fl_init_xim() {
+static void fl_init_xim() {
static int xim_warning = 2;
if (xim_warning > 0) xim_warning--;
@@ -584,6 +617,55 @@ void fl_init_xim() {
if(xim_styles) XFree(xim_styles);
}
+void fl_xim_deactivate(void);
+
+void fl_xim_activate(Window xid) {
+ if (!fl_xim_im)
+ return;
+
+ // If the focused window has changed, then use the brute force method
+ // of completely recreating the input context.
+ if (fl_xim_win != xid) {
+ fl_xim_deactivate();
+
+ fl_new_ic();
+ fl_xim_win = xid;
+
+ XSetICValues(fl_xim_ic,
+ XNFocusWindow, fl_xim_win,
+ XNClientWindow, fl_xim_win,
+ NULL);
+ }
+
+ fl_set_spot(spotf, spots, spot.x, spot.y, spot.width, spot.height);
+}
+
+void fl_xim_deactivate(void) {
+ if (!fl_xim_ic)
+ return;
+
+ XDestroyIC(fl_xim_ic);
+ fl_xim_ic = NULL;
+
+ fl_xim_win = 0;
+}
+
+void Fl::enable_im() {
+ Fl_Window *win;
+
+ win = Fl::first_window();
+ if (win && win->shown()) {
+ fl_xim_activate(fl_xid(win));
+ XSetICFocus(fl_xim_ic);
+ } else {
+ fl_new_ic();
+ }
+}
+
+void Fl::disable_im() {
+ fl_xim_deactivate();
+}
+
void fl_open_display() {
if (fl_display) return;
@@ -608,6 +690,9 @@ void fl_open_display(Display* d) {
fl_MOTIF_WM_HINTS = XInternAtom(d, "_MOTIF_WM_HINTS", 0);
TARGETS = XInternAtom(d, "TARGETS", 0);
CLIPBOARD = XInternAtom(d, "CLIPBOARD", 0);
+ TIMESTAMP = XInternAtom(d, "TIMESTAMP", 0);
+ PRIMARY_TIMESTAMP = XInternAtom(d, "PRIMARY_TIMESTAMP", 0);
+ CLIPBOARD_TIMESTAMP = XInternAtom(d, "CLIPBOARD_TIMESTAMP", 0);
fl_XdndAware = XInternAtom(d, "XdndAware", 0);
fl_XdndSelection = XInternAtom(d, "XdndSelection", 0);
fl_XdndEnter = XInternAtom(d, "XdndEnter", 0);
@@ -628,12 +713,18 @@ void fl_open_display(Display* d) {
fl_XaCompoundText = XInternAtom(d, "COMPOUND_TEXT", 0);
fl_XaUtf8String = XInternAtom(d, "UTF8_STRING", 0);
fl_XaTextUriList = XInternAtom(d, "text/uri-list", 0);
+ fl_XaImageBmp = XInternAtom(d, "image/bmp", 0);
+ fl_XaImagePNG = XInternAtom(d, "image/png", 0);
+ fl_INCR = XInternAtom(d, "INCR", 0);
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);
+ fl_NET_WM_FULLSCREEN_MONITORS = XInternAtom(d, "_NET_WM_FULLSCREEN_MONITORS", 0);
fl_NET_WORKAREA = XInternAtom(d, "_NET_WORKAREA", 0);
+ fl_NET_WM_ICON = XInternAtom(d, "_NET_WM_ICON", 0);
+ fl_NET_ACTIVE_WINDOW = XInternAtom(d, "_NET_ACTIVE_WINDOW", 0);
if (sizeof(Atom) < 4)
atom_bits = sizeof(Atom) * 8;
@@ -655,6 +746,15 @@ void fl_open_display(Display* d) {
#if !USE_COLORMAP
Fl::visual(FL_RGB);
#endif
+
+#if HAVE_XFIXES
+ int error_base;
+ if (XFixesQueryExtension(fl_display, &xfixes_event_base, &error_base))
+ have_xfixes = true;
+ else
+ have_xfixes = false;
+#endif
+
#if USE_XRANDR
void *libxrandr_addr = dlopen("libXrandr.so.2", RTLD_LAZY);
if (!libxrandr_addr) libxrandr_addr = dlopen("libXrandr.so", RTLD_LAZY);
@@ -688,7 +788,7 @@ static void fl_init_workarea() {
Atom actual;
unsigned long count, remaining;
int format;
- unsigned *xywh;
+ long *xywh = 0;
/* If there are several screens, the _NET_WORKAREA property
does not give the work area of the main screen, but that of all screens together.
@@ -696,7 +796,7 @@ static void fl_init_workarea() {
and fall back to the main screen full area when there are several screens.
*/
if (Fl::screen_count() > 1 || XGetWindowProperty(fl_display, RootWindow(fl_display, fl_screen),
- fl_NET_WORKAREA, 0, 4 * sizeof(unsigned), False,
+ fl_NET_WORKAREA, 0, 4, False,
XA_CARDINAL, &actual, &format, &count, &remaining,
(unsigned char **)&xywh) || !xywh || !xywh[2] ||
!xywh[3])
@@ -712,8 +812,8 @@ static void fl_init_workarea() {
fl_workarea_xywh[1] = (int)xywh[1];
fl_workarea_xywh[2] = (int)xywh[2];
fl_workarea_xywh[3] = (int)xywh[3];
- XFree(xywh);
}
+ if ( xywh ) { XFree(xywh); xywh = 0; }
}
int Fl::x() {
@@ -751,15 +851,18 @@ void Fl::get_mouse(int &xx, int &yy) {
Fl_Widget *fl_selection_requestor;
char *fl_selection_buffer[2];
int fl_selection_length[2];
+const char * fl_selection_type[2];
int fl_selection_buffer_length[2];
char fl_i_own_selection[2] = {0,0};
// Call this when a "paste" operation happens:
-void Fl::paste(Fl_Widget &receiver, int clipboard) {
+void Fl::paste(Fl_Widget &receiver, int clipboard, const char *type) {
if (fl_i_own_selection[clipboard]) {
// We already have it, do it quickly without window server.
// Notice that the text is clobbered if set_selection is
// called in response to FL_PASTE!
+ // However, for now, we only paste text in this function
+ if (fl_selection_type[clipboard] != Fl::clipboard_plain_text) return; //TODO: allow copy/paste of image within same app
Fl::e_text = fl_selection_buffer[clipboard];
Fl::e_length = fl_selection_length[clipboard];
if (!Fl::e_text) Fl::e_text = (char *)"";
@@ -769,15 +872,65 @@ void Fl::paste(Fl_Widget &receiver, int clipboard) {
// otherwise get the window server to return it:
fl_selection_requestor = &receiver;
Atom property = clipboard ? CLIPBOARD : XA_PRIMARY;
+ Fl::e_clipboard_type = type;
XConvertSelection(fl_display, property, TARGETS, property,
fl_xid(Fl::first_window()), fl_event_time);
}
-Window fl_dnd_source_window;
-Atom *fl_dnd_source_types; // null-terminated list of data types being supplied
-Atom fl_dnd_type;
-Atom fl_dnd_source_action;
-Atom fl_dnd_action;
+int Fl::clipboard_contains(const char *type)
+{
+ XEvent event;
+ Atom actual; int format; unsigned long count, remaining, i = 0;
+ unsigned char* portion = NULL;
+ Fl_Window *win = Fl::first_window();
+ if (!win || !fl_xid(win)) return 0;
+ XConvertSelection(fl_display, CLIPBOARD, TARGETS, CLIPBOARD, fl_xid(win), CurrentTime);
+ XFlush(fl_display);
+ do {
+ XNextEvent(fl_display, &event);
+ if (event.type == SelectionNotify && event.xselection.property == None) return 0;
+ i++;
+ }
+ while (i < 10 && event.type != SelectionNotify);
+ if (i >= 10) return 0;
+ XGetWindowProperty(fl_display,
+ event.xselection.requestor,
+ event.xselection.property,
+ 0, 4000, 0, 0,
+ &actual, &format, &count, &remaining, &portion);
+ if (actual != XA_ATOM) return 0;
+ Atom t;
+ int retval = 0;
+ if (strcmp(type, Fl::clipboard_plain_text) == 0) {
+ for (i = 0; i<count; i++) { // searching for text data
+ t = ((Atom*)portion)[i];
+ if (t == fl_Xatextplainutf ||
+ t == fl_Xatextplainutf2 ||
+ t == fl_Xatextplain ||
+ t == fl_XaUtf8String) {
+ retval = 1;
+ break;
+ }
+ }
+ }
+ else if (strcmp(type, Fl::clipboard_image) == 0) {
+ for (i = 0; i<count; i++) { // searching for image data
+ t = ((Atom*)portion)[i];
+ if (t == fl_XaImageBmp || t == fl_XaImagePNG) {
+ retval = 1;
+ break;
+ }
+ }
+ }
+ XFree(portion);
+ return retval;
+}
+
+static Window fl_dnd_source_window;
+static Atom *fl_dnd_source_types; // null-terminated list of data types being supplied
+static Atom fl_dnd_type;
+static Atom fl_dnd_source_action;
+static Atom fl_dnd_action;
void fl_sendClientMessage(Window window, Atom message,
unsigned long d0,
@@ -800,9 +953,19 @@ void fl_sendClientMessage(Window window, Atom message,
}
-/*
- Get window property value (32 bit format)
+/*
+ Get window property value (32 bit format)
Returns zero on success, -1 on error
+
+ 'data' should be freed with XFree() using this pattern:
+
+ unsigned long *data = 0;
+ if (0 == get_xwinprop(....., &nitems, &data) ) { ..success.. }
+ else { ..fail.. }
+ if ( data ) { XFree(data); data=0; }
+
+ Note: 'data' can be non-zero, even if the return value is -1 (error) and
+ should hence be XFree'd *after* the if/else statement, as described above.
*/
static int get_xwinprop(Window wnd, Atom prop, long max_length,
unsigned long *nitems, unsigned long **data) {
@@ -827,7 +990,7 @@ static int get_xwinprop(Window wnd, Atom prop, long max_length,
////////////////////////////////////////////////////////////////
// Code for copying to clipboard and DnD out of the program:
-void Fl::copy(const char *stuff, int len, int clipboard) {
+void Fl::copy(const char *stuff, int len, int clipboard, const char *type) {
if (!stuff || len<0) return;
if (len+1 > fl_selection_buffer_length[clipboard]) {
delete[] fl_selection_buffer[clipboard];
@@ -838,11 +1001,183 @@ void Fl::copy(const char *stuff, int len, int clipboard) {
fl_selection_buffer[clipboard][len] = 0; // needed for direct paste
fl_selection_length[clipboard] = len;
fl_i_own_selection[clipboard] = 1;
+ fl_selection_type[clipboard] = Fl::clipboard_plain_text;
+ Atom property = clipboard ? CLIPBOARD : XA_PRIMARY;
+ XSetSelectionOwner(fl_display, property, fl_message_window, fl_event_time);
+}
+
+static void write_short(unsigned char **cp,short i){
+ unsigned char *c=*cp;
+ *c++=i&0xFF;i>>=8;
+ *c++=i&0xFF;i>>=8;
+ *cp=c;
+}
+
+static void write_int(unsigned char **cp,int i){
+ unsigned char *c=*cp;
+ *c++=i&0xFF;i>>=8;
+ *c++=i&0xFF;i>>=8;
+ *c++=i&0xFF;i>>=8;
+ *c++=i&0xFF;i>>=8;
+ *cp=c;
+}
+
+static unsigned char *create_bmp(const unsigned char *data, int W, int H, int *return_size){
+ int R=(3*W+3)/4 * 4; // the number of bytes per row, rounded up to multiple of 4
+ int s=H*R;
+ int fs=14+40+s;
+ unsigned char *b=new unsigned char[fs];
+ unsigned char *c=b;
+ // BMP header
+ *c++='B';
+ *c++='M';
+ write_int(&c,fs);
+ write_int(&c,0);
+ write_int(&c,14+40);
+ // DIB header:
+ write_int(&c,40);
+ write_int(&c,W);
+ write_int(&c,H);
+ write_short(&c,1);
+ write_short(&c,24);//bits ber pixel
+ write_int(&c,0);//RGB
+ write_int(&c,s);
+ write_int(&c,0);// horizontal resolution
+ write_int(&c,0);// vertical resolution
+ write_int(&c,0);//number of colors. 0 -> 1<<bits_per_pixel
+ write_int(&c,0);
+ // Pixel data
+ data+=3*W*H;
+ for (int y=0;y<H;++y){
+ data-=3*W;
+ const unsigned char *s=data;
+ unsigned char *p=c;
+ for (int x=0;x<W;++x){
+ *p++=s[2];
+ *p++=s[1];
+ *p++=s[0];
+ s+=3;
+ }
+ c+=R;
+ }
+ *return_size = fs;
+ return b;
+}
+
+void Fl::copy_image(const unsigned char *data, int W, int H, int clipboard){
+ if(!data || W<=0 || H<=0) return;
+ delete[] fl_selection_buffer[clipboard];
+ fl_selection_buffer[clipboard] = (char *) create_bmp(data,W,H,&fl_selection_length[clipboard]);
+ fl_selection_buffer_length[clipboard] = fl_selection_length[clipboard];
+ fl_i_own_selection[clipboard] = 1;
+ fl_selection_type[clipboard] = Fl::clipboard_image;
+
Atom property = clipboard ? CLIPBOARD : XA_PRIMARY;
XSetSelectionOwner(fl_display, property, fl_message_window, fl_event_time);
}
////////////////////////////////////////////////////////////////
+// Code for tracking clipboard changes:
+
+static Time primary_timestamp = (Time)-1;
+static Time clipboard_timestamp = (Time)-1;
+
+extern bool fl_clipboard_notify_empty(void);
+extern void fl_trigger_clipboard_notify(int source);
+
+static void poll_clipboard_owner(void) {
+ Window xid;
+
+#if HAVE_XFIXES
+ // No polling needed with Xfixes
+ if (have_xfixes)
+ return;
+#endif
+
+ // No one is interested, so no point polling
+ if (fl_clipboard_notify_empty())
+ return;
+
+ // We need a window for this to work
+ if (!Fl::first_window())
+ return;
+ xid = fl_xid(Fl::first_window());
+ if (!xid)
+ return;
+
+ // Request an update of the selection time for both the primary and
+ // clipboard selections. Magic continues when we get a SelectionNotify.
+ if (!fl_i_own_selection[0])
+ XConvertSelection(fl_display, XA_PRIMARY, TIMESTAMP, PRIMARY_TIMESTAMP,
+ xid, fl_event_time);
+ if (!fl_i_own_selection[1])
+ XConvertSelection(fl_display, CLIPBOARD, TIMESTAMP, CLIPBOARD_TIMESTAMP,
+ xid, fl_event_time);
+}
+
+static void clipboard_timeout(void *data)
+{
+ // No one is interested, so stop polling
+ if (fl_clipboard_notify_empty())
+ return;
+
+ poll_clipboard_owner();
+
+ Fl::repeat_timeout(0.5, clipboard_timeout);
+}
+
+static void handle_clipboard_timestamp(int clipboard, Time time)
+{
+ Time *timestamp;
+
+ timestamp = clipboard ? &clipboard_timestamp : &primary_timestamp;
+
+#if HAVE_XFIXES
+ if (!have_xfixes)
+#endif
+ {
+ // Initial scan, just store the value
+ if (*timestamp == (Time)-1) {
+ *timestamp = time;
+ return;
+ }
+ }
+
+ // Same selection
+ if (time == *timestamp)
+ return;
+
+ *timestamp = time;
+
+ // The clipboard change is the event that caused us to request
+ // the clipboard data, so use that time as the latest event.
+ if (time > fl_event_time)
+ fl_event_time = time;
+
+ // Something happened! Let's tell someone!
+ fl_trigger_clipboard_notify(clipboard);
+}
+
+void fl_clipboard_notify_change() {
+ // Reset the timestamps if we've going idle so that you don't
+ // get a bogus immediate trigger next time they're activated.
+ if (fl_clipboard_notify_empty()) {
+ primary_timestamp = (Time)-1;
+ clipboard_timestamp = (Time)-1;
+ } else {
+#if HAVE_XFIXES
+ if (!have_xfixes)
+#endif
+ {
+ poll_clipboard_owner();
+
+ if (!Fl::has_timeout(clipboard_timeout))
+ Fl::add_timeout(0.5, clipboard_timeout);
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////
const XEvent* fl_xevent; // the current x event
ulong fl_event_time; // the last timestamp from an x event
@@ -914,16 +1249,78 @@ static int wasXExceptionRaised() {
}
+static bool getNextEvent(XEvent *event_return)
+{
+ time_t t = time(NULL);
+ while(!XPending(fl_display))
+ {
+ if(time(NULL) - t > 10.0)
+ {
+ //fprintf(stderr,"Error: The XNextEvent never came...\n");
+ return false;
+ }
+ }
+ XNextEvent(fl_display, event_return);
+ return true;
+}
+
+static long getIncrData(uchar* &data, const XSelectionEvent& selevent, long lower_bound)
+{
+//fprintf(stderr,"Incremental transfer starting due to INCR property\n");
+ size_t total = 0;
+ XEvent event;
+ XDeleteProperty(fl_display, selevent.requestor, selevent.property);
+ data = (uchar*)realloc(data, lower_bound);
+ for (;;)
+ {
+ if (!getNextEvent(&event)) break;
+ if (event.type == PropertyNotify)
+ {
+ if (event.xproperty.state != PropertyNewValue) continue;
+ Atom actual_type;
+ int actual_format;
+ unsigned long nitems;
+ unsigned long bytes_after;
+ unsigned char* prop = 0;
+ long offset = 0;
+ size_t num_bytes;
+ //size_t slice_size = 0;
+ do
+ {
+ XGetWindowProperty(fl_display, selevent.requestor, selevent.property, offset, 70000, True,
+ AnyPropertyType, &actual_type, &actual_format, &nitems, &bytes_after, &prop);
+ num_bytes = nitems * (actual_format / 8);
+ offset += num_bytes/4;
+ //slice_size += num_bytes;
+ if (total + num_bytes > (size_t)lower_bound) data = (uchar*)realloc(data, total + num_bytes);
+ memcpy(data + total, prop, num_bytes); total += num_bytes;
+ if (prop) XFree(prop);
+ } while (bytes_after != 0);
+//fprintf(stderr,"INCR data size:%ld\n", slice_size);
+ if (num_bytes == 0) break;
+ }
+ else break;
+ }
+ XDeleteProperty(fl_display, selevent.requestor, selevent.property);
+ return (long)total;
+}
+
+/* Internal function to reduce "deprecated" warnings for XKeycodeToKeysym().
+ This way we get only one warning. The option to use XkbKeycodeToKeysym()
+ instead would not help much - see STR #2913 for more information.
+*/
+static KeySym fl_KeycodeToKeysym(Display *d, KeyCode k, unsigned i) {
+ return XKeycodeToKeysym(d, k, i);
+}
int fl_handle(const XEvent& thisevent)
{
XEvent xevent = thisevent;
fl_xevent = &thisevent;
Window xid = xevent.xany.window;
- static Window xim_win = 0;
if (fl_xim_ic && xevent.type == DestroyNotify &&
- xid != xim_win && !fl_find(xid))
+ xid != fl_xim_win && !fl_find(xid))
{
XIM xim_im;
xim_im = XOpenIM(fl_display, NULL, NULL, NULL);
@@ -939,46 +1336,9 @@ int fl_handle(const XEvent& thisevent)
}
if (fl_xim_ic && (xevent.type == FocusIn))
- {
-#define POOR_XIM
-#ifdef POOR_XIM
- if (xim_win != xid)
- {
- xim_win = xid;
- XDestroyIC(fl_xim_ic);
- fl_xim_ic = NULL;
- fl_new_ic();
- XSetICValues(fl_xim_ic,
- XNFocusWindow, xevent.xclient.window,
- XNClientWindow, xid,
- NULL);
- }
- fl_set_spot(spotf, spots, spot.x, spot.y, spot.width, spot.height);
-#else
- if (Fl::first_window() && Fl::first_window()->modal()) {
- Window x = fl_xid(Fl::first_window());
- if (x != xim_win) {
- xim_win = x;
- XSetICValues(fl_xim_ic,
- XNFocusWindow, xim_win,
- XNClientWindow, xim_win,
- NULL);
- fl_set_spot(spotf, spots, spot.x, spot.y, spot.width, spot.height);
- }
- } else if (xim_win != xid && xid) {
- xim_win = xid;
- XSetICValues(fl_xim_ic,
- XNFocusWindow, xevent.xclient.window,
- XNClientWindow, xid,
- //XNFocusWindow, xim_win,
- //XNClientWindow, xim_win,
- NULL);
- fl_set_spot(spotf, spots, spot.x, spot.y, spot.width, spot.height);
- }
-#endif
- }
+ fl_xim_activate(xid);
- if ( XFilterEvent((XEvent *)&xevent, 0) )
+ if (fl_xim_ic && XFilterEvent((XEvent *)&xevent, 0))
return(1);
#if USE_XRANDR
@@ -1005,9 +1365,9 @@ int fl_handle(const XEvent& thisevent)
return 0;
case SelectionNotify: {
- if (!fl_selection_requestor) return 0;
- static unsigned char* buffer = 0;
- if (buffer) {XFree(buffer); buffer = 0;}
+ static unsigned char* sn_buffer = 0;
+ //static const char *buffer_format = 0;
+ if (sn_buffer) {XFree(sn_buffer); sn_buffer = 0;}
long bytesread = 0;
if (fl_xevent->xselection.property) for (;;) {
// The Xdnd code pastes 64K chunks together, possibly to avoid
@@ -1018,13 +1378,42 @@ int fl_handle(const XEvent& thisevent)
if (XGetWindowProperty(fl_display,
fl_xevent->xselection.requestor,
fl_xevent->xselection.property,
- bytesread/4, 65536, 1, 0,
+ bytesread/4, 65536, 1, AnyPropertyType,
&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);
+ }
+ XFree(portion); portion = 0;
+ return true;
+ }
+
if (actual == TARGETS || actual == XA_ATOM) {
- Atom type = XA_STRING;
- for (unsigned i = 0; i<count; i++) {
- Atom t = ((Atom*)portion)[i];
+/*for (unsigned i = 0; i<count; i++) {
+ fprintf(stderr," %s", XGetAtomName(fl_display, ((Atom*)portion)[i]) );
+ }
+fprintf(stderr,"\n");*/
+ Atom t, type = XA_STRING;
+ if (Fl::e_clipboard_type == Fl::clipboard_image) { // searching for image data
+ for (unsigned i = 0; i<count; i++) {
+ t = ((Atom*)portion)[i];
+ if (t == fl_XaImageBmp || t == fl_XaImagePNG) {
+ type = t;
+ goto found;
+ }
+ }
+ XFree(portion);
+ return true;
+ }
+ for (unsigned i = 0; i<count; i++) { // searching for text data
+ t = ((Atom*)portion)[i];
if (t == fl_Xatextplainutf ||
t == fl_Xatextplainutf2 ||
t == fl_Xatextplain ||
@@ -1037,39 +1426,84 @@ int fl_handle(const XEvent& thisevent)
t == fl_XaTextUriList ||
t == fl_XaCompoundText) type = t;
}
- XFree(portion);
+ found:
+ XFree(portion); portion = 0;
Atom property = xevent.xselection.property;
XConvertSelection(fl_display, property, type, property,
fl_xid(Fl::first_window()),
fl_event_time);
+ if (type == fl_XaImageBmp) {
+ Fl::e_clipboard_type = Fl::clipboard_image;
+ //buffer_format = "image/bmp";
+ }
+ else if (type == fl_XaImagePNG) {
+ Fl::e_clipboard_type = Fl::clipboard_image;
+ //buffer_format = "image/png";
+ }
+ else {
+ Fl::e_clipboard_type = Fl::clipboard_plain_text;
+ //buffer_format = Fl::clipboard_plain_text;
+ }
+//fprintf(stderr,"used format=%s\n", buffer_format);
return true;
}
- // Make sure we got something sane...
+ if (actual == fl_INCR) {
+ bytesread = getIncrData(sn_buffer, xevent.xselection, *(long*)portion);
+ XFree(portion);
+ break;
+ }
+ // Make sure we got something sane...
if ((portion == NULL) || (format != 8) || (count == 0)) {
- if (portion) XFree(portion);
+ if (portion) { XFree(portion); portion = 0; }
return true;
- }
- buffer = (unsigned char*)realloc(buffer, bytesread+count+remaining+1);
- memcpy(buffer+bytesread, portion, count);
- XFree(portion);
+ }
+ sn_buffer = (unsigned char*)realloc(sn_buffer, bytesread+count+remaining+1);
+ memcpy(sn_buffer+bytesread, portion, count);
+ if (portion) { XFree(portion); portion = 0; }
bytesread += count;
// Cannot trust data to be null terminated
- buffer[bytesread] = '\0';
+ sn_buffer[bytesread] = '\0';
if (!remaining) break;
}
- if (buffer) {
- buffer[bytesread] = 0;
- convert_crlf(buffer, bytesread);
+ if (sn_buffer && Fl::e_clipboard_type == Fl::clipboard_plain_text) {
+ sn_buffer[bytesread] = 0;
+ convert_crlf(sn_buffer, bytesread);
+ }
+ if (Fl::e_clipboard_type == Fl::clipboard_image) {
+ if (bytesread == 0) return 0;
+ Fl_Image *image = 0;
+ static char tmp_fname[21];
+ static Fl_Shared_Image *shared = 0;
+ strcpy(tmp_fname, "/tmp/clipboardXXXXXX");
+ int fd = mkstemp(tmp_fname);
+ if (fd == -1) return 0;
+ uchar *p = sn_buffer; ssize_t towrite = bytesread, written;
+ while (towrite) {
+ written = write(fd, p, towrite);
+ p += written; towrite -= written;
+ }
+ close(fd);
+ free(sn_buffer); sn_buffer = 0;
+ shared = Fl_Shared_Image::get(tmp_fname);
+ unlink(tmp_fname);
+ if (!shared) return 0;
+ image = shared->copy();
+ shared->release();
+ Fl::e_clipboard_data = (void*)image;
}
- Fl::e_text = buffer ? (char*)buffer : (char *)"";
- Fl::e_length = bytesread;
+ if (!fl_selection_requestor) return 0;
+
+ if (Fl::e_clipboard_type == Fl::clipboard_plain_text) {
+ Fl::e_text = sn_buffer ? (char*)sn_buffer : (char *)"";
+ Fl::e_length = bytesread;
+ }
int old_event = Fl::e_number;
fl_selection_requestor->handle(Fl::e_number = FL_PASTE);
Fl::e_number = old_event;
// Detect if this paste is due to Xdnd by the property name (I use
// XA_SECONDARY for that) and send an XdndFinished message. It is not
// clear if this has to be delayed until now or if it can be done
- // immediatly after calling XConvertSelection.
+ // immediately after calling XConvertSelection.
if (fl_xevent->xselection.property == XA_SECONDARY &&
fl_dnd_source_window) {
fl_sendClientMessage(fl_dnd_source_window, fl_XdndFinished,
@@ -1081,6 +1515,7 @@ int fl_handle(const XEvent& thisevent)
case SelectionClear: {
int clipboard = fl_xevent->xselectionclear.selection == CLIPBOARD;
fl_i_own_selection[clipboard] = 0;
+ poll_clipboard_owner();
return 1;}
case SelectionRequest: {
@@ -1092,32 +1527,51 @@ int fl_handle(const XEvent& thisevent)
e.target = fl_xevent->xselectionrequest.target;
e.time = fl_xevent->xselectionrequest.time;
e.property = fl_xevent->xselectionrequest.property;
- if (e.target == TARGETS) {
- Atom a[3] = {fl_XaUtf8String, XA_STRING, fl_XaText};
- XChangeProperty(fl_display, e.requestor, e.property,
- XA_ATOM, atom_bits, 0, (unsigned char*)a, 3);
- } else if (/*e.target == XA_STRING &&*/ fl_selection_length[clipboard]) {
- if (e.target == fl_XaUtf8String ||
- e.target == XA_STRING ||
- e.target == fl_XaCompoundText ||
- e.target == fl_XaText ||
- e.target == fl_Xatextplain ||
- e.target == fl_Xatextplainutf ||
- e.target == fl_Xatextplainutf2) {
- // clobber the target type, this seems to make some applications
- // behave that insist on asking for XA_TEXT instead of UTF8_STRING
- // Does not change XA_STRING as that breaks xclipboard.
- if (e.target != XA_STRING) e.target = fl_XaUtf8String;
+ if (fl_selection_type[clipboard] == Fl::clipboard_plain_text) {
+ if (e.target == TARGETS) {
+ Atom a[3] = {fl_XaUtf8String, XA_STRING, fl_XaText};
+ XChangeProperty(fl_display, e.requestor, e.property,
+ XA_ATOM, atom_bits, 0, (unsigned char*)a, 3);
+ } else {
+ if (/*e.target == XA_STRING &&*/ fl_selection_length[clipboard]) {
+ if (e.target == fl_XaUtf8String ||
+ e.target == XA_STRING ||
+ e.target == fl_XaCompoundText ||
+ e.target == fl_XaText ||
+ e.target == fl_Xatextplain ||
+ e.target == fl_Xatextplainutf ||
+ e.target == fl_Xatextplainutf2) {
+ // clobber the target type, this seems to make some applications
+ // behave that insist on asking for XA_TEXT instead of UTF8_STRING
+ // Does not change XA_STRING as that breaks xclipboard.
+ if (e.target != XA_STRING) e.target = fl_XaUtf8String;
+ XChangeProperty(fl_display, e.requestor, e.property,
+ e.target, 8, 0,
+ (unsigned char *)fl_selection_buffer[clipboard],
+ fl_selection_length[clipboard]);
+ }
+ } else {
+ // char* x = XGetAtomName(fl_display,e.target);
+ // fprintf(stderr,"selection request of %s\n",x);
+ // XFree(x);
+ e.property = 0;
+ }
+ }
+ } else { // image in clipboard
+ if (e.target == TARGETS) {
+ Atom a[1] = {fl_XaImageBmp};
XChangeProperty(fl_display, e.requestor, e.property,
- e.target, 8, 0,
- (unsigned char *)fl_selection_buffer[clipboard],
- fl_selection_length[clipboard]);
+ XA_ATOM, atom_bits, 0, (unsigned char*)a, 1);
+ } else {
+ if (e.target == fl_XaImageBmp && fl_selection_length[clipboard]) {
+ XChangeProperty(fl_display, e.requestor, e.property,
+ e.target, 8, 0,
+ (unsigned char *)fl_selection_buffer[clipboard],
+ fl_selection_length[clipboard]);
+ } else {
+ e.property = 0;
+ }
}
- } else {
-// char* x = XGetAtomName(fl_display,e.target);
-// fprintf(stderr,"selection request of %s\n",x);
-// XFree(x);
- e.property = 0;
}
XSendEvent(fl_display, e.requestor, 0, 0, (XEvent *)&e);}
return 1;
@@ -1170,18 +1624,21 @@ int fl_handle(const XEvent& thisevent)
if (data[1]&1) {
// get list of data types:
Atom actual; int format; unsigned long count, remaining;
- unsigned char *buffer = 0;
+ unsigned char *cm_buffer = 0;
XGetWindowProperty(fl_display, fl_dnd_source_window, fl_XdndTypeList,
0, 0x8000000L, False, XA_ATOM, &actual, &format,
- &count, &remaining, &buffer);
- if (actual != XA_ATOM || format != 32 || count<4 || !buffer)
+ &count, &remaining, &cm_buffer);
+ if (actual != XA_ATOM || format != 32 || count<4 || !cm_buffer) {
+ if ( cm_buffer ) { XFree(cm_buffer); cm_buffer = 0; }
goto FAILED;
+ }
delete [] fl_dnd_source_types;
fl_dnd_source_types = new Atom[count+1];
for (unsigned i = 0; i < count; i++) {
- fl_dnd_source_types[i] = ((Atom*)buffer)[i];
+ fl_dnd_source_types[i] = ((Atom*)cm_buffer)[i];
}
fl_dnd_source_types[count] = 0;
+ XFree(cm_buffer); cm_buffer = 0;
} else {
FAILED:
// less than four data types, or if the above messes up:
@@ -1258,6 +1715,7 @@ int fl_handle(const XEvent& thisevent)
Fl::e_length = unknown_len;
if (Fl::handle(FL_DND_RELEASE, window)) {
fl_selection_requestor = Fl::belowmouse();
+ Fl::e_clipboard_type = Fl::clipboard_plain_text;
XConvertSelection(fl_display, fl_XdndSelection,
fl_dnd_type, XA_SECONDARY,
to_window, fl_event_time);
@@ -1295,6 +1753,9 @@ int fl_handle(const XEvent& thisevent)
case FocusIn:
if (fl_xim_ic) XSetICFocus(fl_xim_ic);
event = FL_FOCUS;
+ // If the user has toggled from another application to this one,
+ // then it's a good time to check for clipboard changes.
+ poll_clipboard_owner();
break;
case FocusOut:
@@ -1307,13 +1768,13 @@ int fl_handle(const XEvent& thisevent)
KEYPRESS:
int keycode = xevent.xkey.keycode;
fl_key_vector[keycode/8] |= (1 << (keycode%8));
- static char *buffer = NULL;
- static int buffer_len = 0;
+ static char *kp_buffer = NULL;
+ static int kp_buffer_len = 0;
int len=0;
KeySym keysym;
- if (buffer_len == 0) {
- buffer_len = 4096;
- buffer = (char*) malloc(buffer_len);
+ if (kp_buffer_len == 0) {
+ kp_buffer_len = 4096;
+ kp_buffer = (char*) malloc(kp_buffer_len);
}
if (xevent.type == KeyPress) {
event = FL_KEYDOWN;
@@ -1322,34 +1783,31 @@ int fl_handle(const XEvent& thisevent)
if (fl_xim_ic) {
Status status;
len = XUtf8LookupString(fl_xim_ic, (XKeyPressedEvent *)&xevent.xkey,
- buffer, buffer_len, &keysym, &status);
+ kp_buffer, kp_buffer_len, &keysym, &status);
- while (status == XBufferOverflow && buffer_len < 50000) {
- buffer_len = buffer_len * 5 + 1;
- buffer = (char*)realloc(buffer, buffer_len);
+ while (status == XBufferOverflow && kp_buffer_len < 50000) {
+ kp_buffer_len = kp_buffer_len * 5 + 1;
+ kp_buffer = (char*)realloc(kp_buffer, kp_buffer_len);
len = XUtf8LookupString(fl_xim_ic, (XKeyPressedEvent *)&xevent.xkey,
- buffer, buffer_len, &keysym, &status);
+ kp_buffer, kp_buffer_len, &keysym, &status);
}
- keysym = XKeycodeToKeysym(fl_display, keycode, 0);
+ keysym = fl_KeycodeToKeysym(fl_display, keycode, 0);
} else {
//static XComposeStatus compose;
len = XLookupString((XKeyEvent*)&(xevent.xkey),
- buffer, buffer_len, &keysym, 0/*&compose*/);
+ kp_buffer, kp_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) {kp_buffer[0] = char(keysym); len = 1;}
+ len = fl_utf8encode(XKeysymToUcs(keysym), kp_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);
+ keysym = fl_KeycodeToKeysym(fl_display, keycode, 0);
}
}
- // MRS: Can't use Fl::event_state(FL_CTRL) since the state is not
- // set until set_event_xy() is called later...
- if ((xevent.xkey.state & ControlMask) && keysym == '-') buffer[0] = 0x1f; // ^_
- buffer[len] = 0;
- Fl::e_text = buffer;
+ kp_buffer[len] = 0;
+ Fl::e_text = kp_buffer;
Fl::e_length = len;
} else {
// Stupid X sends fake key-up events when a repeating key is held
@@ -1357,17 +1815,17 @@ int fl_handle(const XEvent& thisevent)
// we can detect this because the repeating KeyPress event is in
// the queue, get it and execute it instead:
- // Bool XkbSetDetectableAutorepeat ( display, detectable, supported_rtrn )
+ // Bool XkbSetDetectableAutoRepeat ( display, detectable, supported_rtrn )
// Display * display ;
// Bool detectable ;
// Bool * supported_rtrn ;
- // ...would be the easy way to corrct this isuue. Unfortunatly, this call is also
+ // ...would be the easy way to correct this issue. Unfortunately, this call is also
// broken on many Unix distros including Ubuntu and Solaris (as of Dec 2009)
// Bogus KeyUp events are generated by repeated KeyDown events. One
- // neccessary condition is an identical key event pending right after
+ // necessary condition is an identical key event pending right after
// the bogus KeyUp.
- // The new code introduced Dec 2009 differs in that it only check the very
+ // The new code introduced Dec 2009 differs in that it only checks the very
// next event in the queue, not the entire queue of events.
// This function wrongly detects a repeat key if a software keyboard
// sends a burst of events containing two consecutive equal keys. However,
@@ -1388,7 +1846,7 @@ int fl_handle(const XEvent& thisevent)
event = FL_KEYUP;
fl_key_vector[keycode/8] &= ~(1 << (keycode%8));
// keyup events just get the unshifted keysym:
- keysym = XKeycodeToKeysym(fl_display, keycode, 0);
+ keysym = fl_KeycodeToKeysym(fl_display, keycode, 0);
}
# ifdef __sgi
// You can plug a microsoft keyboard into an sgi but the extra shift
@@ -1481,14 +1939,14 @@ int fl_handle(const XEvent& thisevent)
if (keysym >= 0xff91 && keysym <= 0xff9f) {
// Map keypad keysym to character or keysym depending on
// numlock state...
- unsigned long keysym1 = XKeycodeToKeysym(fl_display, keycode, 1);
+ unsigned long keysym1 = fl_KeycodeToKeysym(fl_display, keycode, 1);
if (keysym1 <= 0x7f || (keysym1 > 0xff9f && keysym1 <= FL_KP_Last))
Fl::e_original_keysym = (int)(keysym1 | FL_KP);
if ((xevent.xkey.state & Mod2Mask) &&
(keysym1 <= 0x7f || (keysym1 > 0xff9f && keysym1 <= FL_KP_Last))) {
// Store ASCII numeric keypad value...
keysym = keysym1 | FL_KP;
- buffer[0] = char(keysym1) & 0x7F;
+ kp_buffer[0] = char(keysym1) & 0x7F;
len = 1;
} else {
// Map keypad to special key...
@@ -1551,6 +2009,7 @@ int fl_handle(const XEvent& thisevent)
}
}
}
+ if ( words ) { XFree(words); words = 0; }
}
if (window->fullscreen_active() && !fullscreen_state) {
window->_clear_fullscreen();
@@ -1663,6 +2122,25 @@ int fl_handle(const XEvent& thisevent)
}
}
+#if HAVE_XFIXES
+ switch (xevent.type - xfixes_event_base) {
+ case XFixesSelectionNotify: {
+ // Someone feeding us bogus events?
+ if (!have_xfixes)
+ return true;
+
+ XFixesSelectionNotifyEvent *selection_notify = (XFixesSelectionNotifyEvent *)&xevent;
+
+ if ((selection_notify->selection == XA_PRIMARY) && !fl_i_own_selection[0])
+ handle_clipboard_timestamp(0, selection_notify->selection_timestamp);
+ else if ((selection_notify->selection == CLIPBOARD) && !fl_i_own_selection[1])
+ handle_clipboard_timestamp(1, selection_notify->selection_timestamp);
+
+ return true;
+ }
+ }
+#endif
+
return Fl::handle(event, window);
}
@@ -1705,22 +2183,30 @@ void Fl_Window::resize(int X,int Y,int W,int H) {
#define _NET_WM_STATE_ADD 1 /* add/set property */
#define _NET_WM_STATE_TOGGLE 2 /* toggle property */
-static void send_wm_state_event(Window wnd, int add, Atom prop) {
+static void send_wm_event(Window wnd, Atom message,
+ unsigned long d0, unsigned long d1=0,
+ unsigned long d2=0, unsigned long d3=0,
+ unsigned long d4=0) {
XEvent e;
e.xany.type = ClientMessage;
e.xany.window = wnd;
- e.xclient.message_type = fl_NET_WM_STATE;
+ e.xclient.message_type = message;
e.xclient.format = 32;
- e.xclient.data.l[0] = add ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE;
- e.xclient.data.l[1] = prop;
- e.xclient.data.l[2] = 0;
- e.xclient.data.l[3] = 0;
- e.xclient.data.l[4] = 0;
+ e.xclient.data.l[0] = d0;
+ e.xclient.data.l[1] = d1;
+ e.xclient.data.l[2] = d2;
+ e.xclient.data.l[3] = d3;
+ e.xclient.data.l[4] = d4;
XSendEvent(fl_display, RootWindow(fl_display, fl_screen),
0, SubstructureNotifyMask | SubstructureRedirectMask,
&e);
}
+static void send_wm_state_event(Window wnd, int add, Atom prop) {
+ send_wm_event(wnd, fl_NET_WM_STATE,
+ add ? _NET_WM_STATE_ADD : _NET_WM_STATE_REMOVE, prop);
+}
+
int Fl_X::ewmh_supported() {
static int result = -1;
@@ -1731,19 +2217,56 @@ int Fl_X::ewmh_supported() {
if (0 == get_xwinprop(XRootWindow(fl_display, fl_screen), fl_NET_SUPPORTING_WM_CHECK, 64,
&nitems, &words) && nitems == 1) {
Window child = words[0];
+ if ( words ) { XFree(words); words = 0; }
if (0 == get_xwinprop(child, fl_NET_SUPPORTING_WM_CHECK, 64,
- &nitems, &words) && nitems == 1) {
- result = (child == words[0]);
+ &nitems, &words) ) {
+ if ( nitems == 1) result = (child == words[0]);
}
}
+ if ( words ) { XFree(words); words = 0; }
}
return result;
}
+extern Fl_Window *fl_xfocus;
+
+void Fl_X::activate_window(Window w) {
+ if (!ewmh_supported())
+ return;
+
+ Window prev = 0;
+
+ if (fl_xfocus) {
+ Fl_X *x = Fl_X::i(fl_xfocus);
+ if (!x)
+ return;
+ prev = x->xid;
+ }
+
+ send_wm_event(w, fl_NET_ACTIVE_WINDOW, 1 /* application */,
+ 0 /* timestamp */, prev /* previously active window */);
+}
+
/* Change an existing window to fullscreen */
void Fl_Window::fullscreen_x() {
if (Fl_X::ewmh_supported()) {
+ int top, bottom, left, right;
+
+ top = fullscreen_screen_top;
+ bottom = fullscreen_screen_bottom;
+ left = fullscreen_screen_left;
+ right = fullscreen_screen_right;
+
+ if ((top < 0) || (bottom < 0) || (left < 0) || (right < 0)) {
+ top = Fl::screen_num(x(), y(), w(), h());
+ bottom = top;
+ left = top;
+ right = top;
+ }
+
+ send_wm_event(fl_xid(this), fl_NET_WM_FULLSCREEN_MONITORS,
+ top, bottom, left, right);
send_wm_state_event(fl_xid(this), 1, fl_NET_WM_STATE_FULLSCREEN);
} else {
_set_fullscreen();
@@ -1830,7 +2353,7 @@ void Fl_X::make_xid(Fl_Window* win, XVisualInfo *visual, Colormap colormap)
// force the window to be on-screen. Usually the X window manager
// does this, but a few don't, so we do it here for consistency:
int scr_x, scr_y, scr_w, scr_h;
- Fl::screen_xywh(scr_x, scr_y, scr_w, scr_h, X, Y);
+ Fl::screen_xywh(scr_x, scr_y, scr_w, scr_h, X, Y, W, H);
if (win->border()) {
// ensure border is on screen:
@@ -1859,6 +2382,23 @@ void Fl_X::make_xid(Fl_Window* win, XVisualInfo *visual, Colormap colormap)
return;
}
+ // Compute which screen(s) we should be on if we want to go fullscreen
+ int fullscreen_top, fullscreen_bottom, fullscreen_left, fullscreen_right;
+
+ fullscreen_top = win->fullscreen_screen_top;
+ fullscreen_bottom = win->fullscreen_screen_bottom;
+ fullscreen_left = win->fullscreen_screen_left;
+ fullscreen_right = win->fullscreen_screen_right;
+
+ if ((fullscreen_top < 0) || (fullscreen_bottom < 0) ||
+ (fullscreen_left < 0) || (fullscreen_right < 0)) {
+ fullscreen_top = Fl::screen_num(X, Y, W, H);
+ fullscreen_bottom = fullscreen_top;
+ fullscreen_left = fullscreen_top;
+ fullscreen_right = fullscreen_top;
+ }
+
+
ulong root = win->parent() ?
fl_xid(win->window()) : RootWindow(fl_display, fl_screen);
@@ -1882,9 +2422,17 @@ void Fl_X::make_xid(Fl_Window* win, XVisualInfo *visual, Colormap colormap)
// border, and cannot grab without an existing window. Besides,
// there is no clear_override().
if (win->fullscreen_active() && !Fl_X::ewmh_supported()) {
+ int sx, sy, sw, sh;
attr.override_redirect = 1;
mask |= CWOverrideRedirect;
- Fl::screen_xywh(X, Y, W, H, X, Y, W, H);
+ Fl::screen_xywh(sx, sy, sw, sh, fullscreen_left);
+ X = sx;
+ Fl::screen_xywh(sx, sy, sw, sh, fullscreen_right);
+ W = sx + sw - X;
+ Fl::screen_xywh(sx, sy, sw, sh, fullscreen_top);
+ Y = sy;
+ Fl::screen_xywh(sx, sy, sw, sh, fullscreen_bottom);
+ H = sy + sh - Y;
}
if (fl_background_pixel >= 0) {
@@ -1937,6 +2485,12 @@ void Fl_X::make_xid(Fl_Window* win, XVisualInfo *visual, Colormap colormap)
while (wp->parent()) wp = wp->window();
XSetTransientForHint(fl_display, xp->xid, fl_xid(wp));
if (!wp->visible()) showit = 0; // guess that wm will not show it
+ if (win->modal()) {
+ Atom net_wm_state = XInternAtom (fl_display, "_NET_WM_STATE", 0);
+ Atom net_wm_state_skip_taskbar = XInternAtom (fl_display, "_NET_WM_STATE_MODAL", 0);
+ XChangeProperty (fl_display, xp->xid, net_wm_state, XA_ATOM, 32,
+ PropModeAppend, (unsigned char*) &net_wm_state_skip_taskbar, 1);
+ }
}
// Make sure that borderless windows do not show in the task bar
@@ -1949,6 +2503,13 @@ void Fl_X::make_xid(Fl_Window* win, XVisualInfo *visual, Colormap colormap)
// If asked for, create fullscreen
if (win->fullscreen_active() && Fl_X::ewmh_supported()) {
+ unsigned long data[4];
+ data[0] = fullscreen_top;
+ data[1] = fullscreen_bottom;
+ data[2] = fullscreen_left;
+ data[3] = fullscreen_right;
+ XChangeProperty (fl_display, xp->xid, fl_NET_WM_FULLSCREEN_MONITORS, XA_ATOM, 32,
+ PropModeReplace, (unsigned char*) data, 4);
XChangeProperty (fl_display, xp->xid, fl_NET_WM_STATE, XA_ATOM, 32,
PropModeAppend, (unsigned char*) &fl_NET_WM_STATE_FULLSCREEN, 1);
}
@@ -1967,12 +2528,14 @@ void Fl_X::make_xid(Fl_Window* win, XVisualInfo *visual, Colormap colormap)
fl_show_iconic = 0;
showit = 0;
}
- if (win->icon()) {
- hints->icon_pixmap = (Pixmap)win->icon();
+ if (win->icon_->legacy_icon) {
+ hints->icon_pixmap = (Pixmap)win->icon_->legacy_icon;
hints->flags |= IconPixmapHint;
}
XSetWMHints(fl_display, xp->xid, hints);
XFree(hints);
+
+ xp->set_icons();
}
// set the window type for menu and tooltip windows to avoid animations (compiz)
@@ -1982,6 +2545,19 @@ void Fl_X::make_xid(Fl_Window* win, XVisualInfo *visual, Colormap colormap)
XChangeProperty(fl_display, xp->xid, net_wm_type, XA_ATOM, 32, PropModeReplace, (unsigned char*)&net_wm_type_kind, 1);
}
+#if HAVE_XFIXES
+ // register for clipboard change notifications
+ if (have_xfixes && !win->parent()) {
+ XFixesSelectSelectionInput(fl_display, xp->xid, XA_PRIMARY,
+ XFixesSetSelectionOwnerNotifyMask);
+ XFixesSelectSelectionInput(fl_display, xp->xid, CLIPBOARD,
+ XFixesSetSelectionOwnerNotifyMask);
+ }
+#endif
+
+ if (win->shape_data_) {
+ win->combine_mask();
+ }
XMapWindow(fl_display, xp->xid);
if (showit) {
win->set_visible();
@@ -2082,6 +2658,207 @@ void Fl_Window::size_range_() {
////////////////////////////////////////////////////////////////
+static unsigned long *default_net_wm_icons = 0L;
+static size_t default_net_wm_icons_size = 0;
+
+static void icons_to_property(const Fl_RGB_Image *icons[], int count,
+ unsigned long **property, size_t *len) {
+ size_t sz;
+ unsigned long *data;
+
+ sz = 0;
+ for (int i = 0;i < count;i++)
+ sz += 2 + icons[i]->w() * icons[i]->h();
+
+ // FIXME: Might want to sort the icons
+
+ *property = data = new unsigned long[sz];
+ *len = sz;
+
+ for (int i = 0;i < count;i++) {
+ const Fl_RGB_Image *image;
+
+ image = icons[i];
+
+ data[0] = image->w();
+ data[1] = image->h();
+ data += 2;
+
+ const uchar *in = (const uchar*)*image->data();
+ for (int y = 0;y < image->h();y++) {
+ for (int x = 0;x < image->w();x++) {
+ switch (image->d()) {
+ case 1:
+ *data = ( 0xff<<24) | (in[0]<<16) | (in[0]<<8) | in[0];
+ break;
+ case 2:
+ *data = (in[1]<<24) | (in[0]<<16) | (in[0]<<8) | in[0];
+ break;
+ case 3:
+ *data = ( 0xff<<24) | (in[0]<<16) | (in[1]<<8) | in[2];
+ break;
+ case 4:
+ *data = (in[3]<<24) | (in[0]<<16) | (in[1]<<8) | in[2];
+ break;
+ }
+ in += image->d();
+ data++;
+ }
+ in += image->ld();
+ }
+ }
+}
+
+void Fl_X::set_default_icons(const Fl_RGB_Image *icons[], int count) {
+ if (default_net_wm_icons) {
+ delete [] default_net_wm_icons;
+ default_net_wm_icons = 0L;
+ default_net_wm_icons_size = 0;
+ }
+
+ if (count > 0)
+ icons_to_property(icons, count,
+ &default_net_wm_icons, &default_net_wm_icons_size);
+}
+
+void Fl_X::set_icons() {
+ unsigned long *net_wm_icons;
+ size_t net_wm_icons_size;
+
+ if (w->icon_->count) {
+ icons_to_property((const Fl_RGB_Image **)w->icon_->icons, w->icon_->count,
+ &net_wm_icons, &net_wm_icons_size);
+ } else {
+ net_wm_icons = default_net_wm_icons;
+ net_wm_icons_size = default_net_wm_icons_size;
+ }
+
+ XChangeProperty (fl_display, xid, fl_NET_WM_ICON, XA_CARDINAL, 32,
+ PropModeReplace, (unsigned char*) net_wm_icons, net_wm_icons_size);
+
+ if (w->icon_->count) {
+ delete [] net_wm_icons;
+ net_wm_icons = 0L;
+ net_wm_icons_size = 0;
+ }
+}
+
+////////////////////////////////////////////////////////////////
+
+int Fl_X::set_cursor(Fl_Cursor c) {
+
+ /* The cursors are cached, because creating one takes 0.5ms including
+ opening, reading, and closing theme files. They are kept until program
+ exit by design, which valgrind will note as reachable. */
+ static Cursor xc_arrow = None;
+ static Cursor xc_cross = None;
+ static Cursor xc_wait = None;
+ static Cursor xc_insert = None;
+ static Cursor xc_hand = None;
+ static Cursor xc_help = None;
+ static Cursor xc_move = None;
+ static Cursor xc_ns = None;
+ static Cursor xc_we = None;
+ static Cursor xc_ne = None;
+ static Cursor xc_n = None;
+ static Cursor xc_nw = None;
+ static Cursor xc_e = None;
+ static Cursor xc_w = None;
+ static Cursor xc_se = None;
+ static Cursor xc_s = None;
+ static Cursor xc_sw = None;
+
+ Cursor xc;
+
+#define cache_cursor(name, var) if (var == None) { \
+ var = XCreateFontCursor(fl_display, name); \
+ } \
+ xc = var
+
+ switch (c) {
+ case FL_CURSOR_ARROW: cache_cursor(XC_left_ptr, xc_arrow); break;
+ case FL_CURSOR_CROSS: cache_cursor(XC_tcross, xc_cross); break;
+ case FL_CURSOR_WAIT: cache_cursor(XC_watch, xc_wait); break;
+ case FL_CURSOR_INSERT: cache_cursor(XC_xterm, xc_insert); break;
+ case FL_CURSOR_HAND: cache_cursor(XC_hand2, xc_hand); break;
+ case FL_CURSOR_HELP: cache_cursor(XC_question_arrow, xc_help); break;
+ case FL_CURSOR_MOVE: cache_cursor(XC_fleur, xc_move); break;
+ case FL_CURSOR_NS: cache_cursor(XC_sb_v_double_arrow, xc_ns); break;
+ case FL_CURSOR_WE: cache_cursor(XC_sb_h_double_arrow, xc_we); break;
+ case FL_CURSOR_NE: cache_cursor(XC_top_right_corner, xc_ne); break;
+ case FL_CURSOR_N: cache_cursor(XC_top_side, xc_n); break;
+ case FL_CURSOR_NW: cache_cursor(XC_top_left_corner, xc_nw); break;
+ case FL_CURSOR_E: cache_cursor(XC_right_side, xc_e); break;
+ case FL_CURSOR_W: cache_cursor(XC_left_side, xc_w); break;
+ case FL_CURSOR_SE: cache_cursor(XC_bottom_right_corner, xc_se); break;
+ case FL_CURSOR_S: cache_cursor(XC_bottom_side, xc_s); break;
+ case FL_CURSOR_SW: cache_cursor(XC_bottom_left_corner, xc_sw); break;
+ default:
+ return 0;
+ }
+
+#undef cache_cursor
+
+ XDefineCursor(fl_display, xid, 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) {
const char *p,*q;
@@ -2132,7 +2909,7 @@ void Fl_Window::show() {
if (!shown()) {
fl_open_display();
// Don't set background pixel for double-buffered windows...
- if (type() == FL_WINDOW && can_boxcheat(box())) {
+ if (type() != FL_DOUBLE_WINDOW && can_boxcheat(box())) {
fl_background_pixel = int(fl_xpixel(color()));
}
Fl_X::make_xid(this);
@@ -2152,6 +2929,10 @@ GC fl_gc;
// make X drawing go into this window (called by subclass flush() impl.)
void Fl_Window::make_current() {
static GC gc; // the GC used by all X windows
+ if (!shown()) {
+ fl_alert("Fl_Window::make_current(), but window is not shown().");
+ Fl::fatal("Fl_Window::make_current(), but window is not shown().");
+ }
if (!gc) gc = XCreateGC(fl_display, i->xid, 0, 0);
fl_window = i->xid;
fl_gc = gc;
@@ -2164,7 +2945,7 @@ void Fl_Window::make_current() {
#endif
}
-Window fl_xid_(const Fl_Window *w) {
+FL_EXPORT Window fl_xid_(const Fl_Window *w) {
Fl_X *temp = Fl_X::i(w);
return temp ? temp->xid : 0;
}
@@ -2309,5 +3090,5 @@ void preparePrintFront(void)
#endif
//
-// End of "$Id: Fl_x.cxx 9699 2012-10-16 15:35:34Z manolo $".
+// End of "$Id: Fl_x.cxx 10412 2014-10-29 20:25:46Z cand $".
//
diff --git a/src/Makefile b/src/Makefile
index c80a016..672cb60 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1,9 +1,9 @@
#
-# "$Id: Makefile 9707 2012-11-06 21:13:54Z matt $"
+# "$Id: Makefile 10419 2014-10-30 16:05:22Z AlbrechtS $"
#
# Library makefile for the Fast Light Tool Kit (FLTK).
#
-# Copyright 1998-2010 by Bill Spitzak and others.
+# Copyright 1998-2014 by Bill Spitzak and others.
#
# This library is free software. Distribution and use rights are outlined in
# the file "COPYING" which should have been included with this file. If this
@@ -31,6 +31,7 @@ CPPFILES = \
Fl_Choice.cxx \
Fl_Clock.cxx \
Fl_Color_Chooser.cxx \
+ Fl_Copy_Surface.cxx \
Fl_Counter.cxx \
Fl_Dial.cxx \
Fl_Device.cxx \
@@ -43,13 +44,13 @@ CPPFILES = \
Fl_Group.cxx \
Fl_Help_View.cxx \
Fl_Image.cxx \
+ Fl_Image_Surface.cxx \
Fl_Input.cxx \
Fl_Input_.cxx \
Fl_Light_Button.cxx \
Fl_Menu.cxx \
Fl_Menu_.cxx \
Fl_Menu_Bar.cxx \
- Fl_Sys_Menu_Bar.cxx \
Fl_Menu_Button.cxx \
Fl_Menu_Window.cxx \
Fl_Menu_add.cxx \
@@ -60,6 +61,7 @@ CPPFILES = \
Fl_Pack.cxx \
Fl_Paged_Device.cxx \
Fl_Pixmap.cxx \
+ Fl_PostScript.cxx \
Fl_Positioner.cxx \
Fl_Preferences.cxx \
Fl_Printer.cxx \
@@ -95,6 +97,7 @@ CPPFILES = \
Fl_Window_fullscreen.cxx \
Fl_Window_hotspot.cxx \
Fl_Window_iconize.cxx \
+ Fl_Window_shape.cxx \
Fl_Wizard.cxx \
Fl_XBM_Image.cxx \
Fl_XPM_Image.cxx \
@@ -134,6 +137,7 @@ CPPFILES = \
fl_engraved_label.cxx \
fl_file_dir.cxx \
fl_font.cxx \
+ fl_gleam.cxx \
fl_gtk.cxx \
fl_labeltype.cxx \
fl_line_style.cxx \
@@ -157,12 +161,13 @@ CPPFILES = \
screen_xywh.cxx \
fl_utf8.cxx \
ps_image.cxx
-
+
OBJCPPFILES = \
Fl_cocoa.mm \
Fl_Quartz_Printer.mm \
- Fl_Native_File_Chooser_MAC.mm
-
+ Fl_Native_File_Chooser_MAC.mm \
+ Fl_Sys_Menu_Bar.mm
+
FLCPPFILES = \
forms_compatability.cxx \
forms_bitmap.cxx \
@@ -248,7 +253,7 @@ libfltk.1.3.dylib: $(OBJECTS)
echo $(DSOCOMMAND) $@ ...
$(DSOCOMMAND) $@ \
-install_name $(libdir)/$@ \
- -current_version 1.3.1 \
+ -current_version 1.3.3 \
-compatibility_version 1.3.0 \
$(OBJECTS) $(LDLIBS)
$(RM) libfltk.dylib
@@ -270,7 +275,7 @@ $(FLLIBNAME): $(FLOBJECTS)
libfltk_forms.so.1.3: $(FLOBJECTS) libfltk.so.1.3
echo $(DSOCOMMAND) $@ ...
- $(DSOCOMMAND) $@ $(FLOBJECTS) -L. -lfltk
+ $(DSOCOMMAND) $@ $(FLOBJECTS) -L. -lfltk $(LDLIBS)
$(RM) libfltk_forms.so
$(LN) libfltk_forms.so.1.3 libfltk_forms.so
@@ -284,7 +289,7 @@ libfltk_forms.1.3.dylib: $(FLOBJECTS) libfltk.1.3.dylib
echo $(DSOCOMMAND) $@ ...
$(DSOCOMMAND) $@ \
-install_name $(libdir)/$@ \
- -current_version 1.3.1 \
+ -current_version 1.3.3 \
-compatibility_version 1.3.0 \
$(FLOBJECTS) -L. $(LDLIBS) -lfltk
$(RM) libfltk_forms.dylib
@@ -320,7 +325,7 @@ libfltk_gl.1.3.dylib: $(GLOBJECTS) libfltk.1.3.dylib
echo $(DSOCOMMAND) $@ ...
$(DSOCOMMAND) $@ \
-install_name $(libdir)/$@ \
- -current_version 1.3.1 \
+ -current_version 1.3.3 \
-compatibility_version 1.3.0 \
$(GLOBJECTS) -L. $(GLDLIBS) -lfltk
$(RM) libfltk_gl.dylib
@@ -342,7 +347,7 @@ $(IMGLIBNAME): $(IMGOBJECTS)
libfltk_images.so.1.3: $(IMGOBJECTS) libfltk.so.1.3
echo $(DSOCOMMAND) $@ ...
- $(DSOCOMMAND) $@ $(IMGOBJECTS) -L. $(IMAGELIBS) -lfltk
+ $(DSOCOMMAND) $@ $(IMGOBJECTS) -L. $(IMAGELIBS) -lfltk $(LDLIBS)
$(RM) libfltk_images.so
$(LN) libfltk_images.so.1.3 libfltk_images.so
@@ -356,7 +361,7 @@ libfltk_images.1.3.dylib: $(IMGOBJECTS) libfltk.1.3.dylib
echo $(DSOCOMMAND) $@ ...
$(DSOCOMMAND) $@ \
-install_name $(libdir)/$@ \
- -current_version 1.3.1 \
+ -current_version 1.3.3 \
-compatibility_version 1.3.0 \
$(IMGOBJECTS) -L. $(LDLIBS) $(IMAGELIBS) -lfltk
$(RM) libfltk_images.dylib
@@ -800,5 +805,5 @@ uninstall:
fi
#
-# End of "$Id: Makefile 9707 2012-11-06 21:13:54Z matt $".
+# End of "$Id: Makefile 10419 2014-10-30 16:05:22Z AlbrechtS $".
#
diff --git a/src/Xutf8.h b/src/Xutf8.h
new file mode 100644
index 0000000..7e5d357
--- /dev/null
+++ b/src/Xutf8.h
@@ -0,0 +1,184 @@
+/* "$Id: Xutf8.h 10248 2014-08-23 08:41:58Z cand $"
+ *
+ * Author: Jean-Marc Lienher ( http://oksid.ch )
+ * Copyright 2000-2010 by O'ksi'D.
+ *
+ * This library is free software. Distribution and use rights are outlined in
+ * the file "COPYING" which should have been included with this file. If this
+ * file is missing or damaged, see the license at:
+ *
+ * http://www.fltk.org/COPYING.php
+ *
+ * Please report all bugs and problems on the following page:
+ *
+ * http://www.fltk.org/str.php
+ */
+
+#if ! ( defined(_Xutf8_h) || defined(FL_DOXYGEN) )
+#define _Xutf8_h
+
+# ifdef __cplusplus
+extern "C" {
+# endif
+
+#include <X11/X.h>
+#include <X11/Xlib.h>
+#include <X11/Xlocale.h>
+#include <X11/Xutil.h>
+
+typedef struct {
+ int nb_font;
+ char **font_name_list;
+ int *encodings;
+ XFontStruct **fonts;
+ Font fid;
+ int ascent;
+ int descent;
+ int *ranges;
+} XUtf8FontStruct;
+
+XUtf8FontStruct *
+XCreateUtf8FontStruct (
+ Display *dpy,
+ const char *base_font_name_list);
+
+void
+XUtf8DrawString(
+ Display *display,
+ Drawable d,
+ XUtf8FontStruct *font_set,
+ GC gc,
+ int x,
+ int y,
+ const char *string,
+ int num_bytes);
+
+void
+XUtf8_measure_extents(
+ Display *display,
+ Drawable d,
+ XUtf8FontStruct *font_set,
+ GC gc,
+ int *xx,
+ int *yy,
+ int *ww,
+ int *hh,
+ const char *string,
+ int num_bytes);
+
+void
+XUtf8DrawRtlString(
+ Display *display,
+ Drawable d,
+ XUtf8FontStruct *font_set,
+ GC gc,
+ int x,
+ int y,
+ const char *string,
+ int num_bytes);
+
+void
+XUtf8DrawImageString(
+ Display *display,
+ Drawable d,
+ XUtf8FontStruct *font_set,
+ GC gc,
+ int x,
+ int y,
+ const char *string,
+ int num_bytes);
+
+int
+XUtf8TextWidth(
+ XUtf8FontStruct *font_set,
+ const char *string,
+ int num_bytes);
+int
+XUtf8UcsWidth(
+ XUtf8FontStruct *font_set,
+ unsigned int ucs);
+
+int
+XGetUtf8FontAndGlyph(
+ XUtf8FontStruct *font_set,
+ unsigned int ucs,
+ XFontStruct **fnt,
+ unsigned short *id);
+
+void
+XFreeUtf8FontStruct(
+ Display *dpy,
+ XUtf8FontStruct *font_set);
+
+
+int
+XConvertUtf8ToUcs(
+ const unsigned char *buf,
+ int len,
+ unsigned int *ucs);
+
+int
+XConvertUcsToUtf8(
+ unsigned int ucs,
+ char *buf);
+
+int
+XUtf8CharByteLen(
+ const unsigned char *buf,
+ int len);
+
+int
+XCountUtf8Char(
+ const unsigned char *buf,
+ int len);
+
+int
+XFastConvertUtf8ToUcs(
+ const unsigned char *buf,
+ int len,
+ unsigned int *ucs);
+
+long
+XKeysymToUcs(
+ KeySym keysym);
+
+#ifdef X_HAVE_UTF8_STRING
+#define XUtf8LookupString Xutf8LookupString
+#else
+int
+XUtf8LookupString(
+ XIC ic,
+ XKeyPressedEvent* event,
+ char* buffer_return,
+ int bytes_buffer,
+ KeySym* keysym,
+ Status* status_return);
+#endif
+
+unsigned short
+XUtf8IsNonSpacing(
+ unsigned int ucs);
+
+unsigned short
+XUtf8IsRightToLeft(
+ unsigned int ucs);
+
+
+int
+XUtf8Tolower(
+ int ucs);
+
+int
+XUtf8Toupper(
+ int ucs);
+
+
+# ifdef __cplusplus
+}
+# endif
+
+#endif
+
+/*
+ * End of "$Id: Xutf8.h 10248 2014-08-23 08:41:58Z cand $".
+ */
diff --git a/src/aimm.h b/src/aimm.h
deleted file mode 100644
index b7de2d9..0000000
--- a/src/aimm.h
+++ /dev/null
@@ -1,422 +0,0 @@
-//
-// "$Id: aimm.h 8864 2011-07-19 04:49:30Z greg.ercolano $"
-//
-// Standard dialog header file for the UTF-8 Fast Light Tool Kit (FLTK-UTF8).
-//
-// Copyright 2009-2010 by Bill Spitzak and others.
-//
-// This library is free software. Distribution and use rights are outlined in
-// the file "COPYING" which should have been included with this file. If this
-// file is missing or damaged, see the license at:
-//
-// http://www.fltk.org/COPYING.php
-//
-// Please report all bugs and problems on the following page:
-//
-// http://www.fltk.org/str.php
-//
-
-#ifndef AIMM_H
-# define AIMM_H
-//# define HANDLE_PTR HANDLE*
-//# define DWORD_PTR DWORD*
-//# define CLSCTX_INPROC_SERVER 0x1
-const GUID IID_IActiveIMMApp = { 0x8c0e040, 0x62d1, 0x11d1, {0x93, 0x26, 0x00, 0x60, 0xb0, 0x67, 0xb8, 0x6e}};
-const GUID CLSID_CActiveIMM = { 0x4955dd33, 0xb159, 0x11d0, {0x8f, 0xcf, 0x00, 0xaa, 0x00, 0x6b, 0xcc, 0x59}};
-/*
- class IUnknown
- {
- public:
-
- virtual long __stdcall QueryInterface(
- const GUID & riid,
- void **ppvObject) = 0;
-
- virtual ULONG __stdcall AddRef( void) = 0;
-
- virtual ULONG __stdcall Release( void) = 0;
- };
-
-extern "C" __declspec(dllimport) long __stdcall CoInitialize(void far *pvReserved);
-extern "C" __declspec(dllimport) long __stdcall CoCreateInstance(const GUID & rclsid, IUnknown * pUnkOuter,
- DWORD dwClsContext, const GUID & riid, LPVOID FAR* ppv);
-
-*/
-
- class IActiveIMMApp : public IUnknown
- {
- public:
- virtual long __stdcall AssociateContext(
- HWND hWnd,
- HIMC hIME,
- HIMC *phPrev) = 0;
-
- virtual long __stdcall ConfigureIMEA(
- HKL hKL,
- HWND hWnd,
- DWORD dwMode,
- void *pData) = 0;
-
- virtual long __stdcall ConfigureIMEW(
- HKL hKL,
- HWND hWnd,
- DWORD dwMode,
- void *pData) = 0;
-
- virtual long __stdcall CreateContext(
- HIMC *phIMC) = 0;
-
- virtual long __stdcall DestroyContext(
- HIMC hIME) = 0;
-
- virtual long __stdcall EnumRegisterWordA(
- HKL hKL,
- LPSTR szReading,
- DWORD dwStyle,
- LPSTR szRegister,
- LPVOID pData,
- void **pEnum) = 0;
-
- virtual long __stdcall EnumRegisterWordW(
- HKL hKL,
- LPWSTR szReading,
- DWORD dwStyle,
- LPWSTR szRegister,
- LPVOID pData,
- void **pEnum) = 0;
-
- virtual long __stdcall EscapeA(
- HKL hKL,
- HIMC hIMC,
- UINT uEscape,
- /* [out][in] */ LPVOID pData,
- LRESULT *plResult) = 0;
-
- virtual long __stdcall EscapeW(
- HKL hKL,
- HIMC hIMC,
- UINT uEscape,
- /* [out][in] */ LPVOID pData,
- LRESULT *plResult) = 0;
-
- virtual long __stdcall GetCandidateListA(
- HIMC hIMC,
- DWORD dwIndex,
- UINT uBufLen,
- void *pCandList,
- UINT *puCopied) = 0;
-
- virtual long __stdcall GetCandidateListW(
- HIMC hIMC,
- DWORD dwIndex,
- UINT uBufLen,
- void *pCandList,
- UINT *puCopied) = 0;
-
- virtual long __stdcall GetCandidateListCountA(
- HIMC hIMC,
- DWORD *pdwListSize,
- DWORD *pdwBufLen) = 0;
-
- virtual long __stdcall GetCandidateListCountW(
- HIMC hIMC,
- DWORD *pdwListSize,
- DWORD *pdwBufLen) = 0;
-
- virtual long __stdcall GetCandidateWindow(
- HIMC hIMC,
- DWORD dwIndex,
- void *pCandidate) = 0;
-
- virtual long __stdcall GetCompositionFontA(
- HIMC hIMC,
- LOGFONTA *plf) = 0;
-
- virtual long __stdcall GetCompositionFontW(
- HIMC hIMC,
- LOGFONTW *plf) = 0;
-
- virtual long __stdcall GetCompositionStringA(
- HIMC hIMC,
- DWORD dwIndex,
- DWORD dwBufLen,
- LONG *plCopied,
- LPVOID pBuf) = 0;
-
- virtual long __stdcall GetCompositionStringW(
- HIMC hIMC,
- DWORD dwIndex,
- DWORD dwBufLen,
- LONG *plCopied,
- LPVOID pBuf) = 0;
-
- virtual long __stdcall GetCompositionWindow(
- HIMC hIMC,
- void *pCompForm) = 0;
-
- virtual long __stdcall GetContext(
- HWND hWnd,
- HIMC *phIMC) = 0;
-
- virtual long __stdcall GetConversionListA(
- HKL hKL,
- HIMC hIMC,
- LPSTR pSrc,
- UINT uBufLen,
- UINT uFlag,
- void *pDst,
- UINT *puCopied) = 0;
-
- virtual long __stdcall GetConversionListW(
- HKL hKL,
- HIMC hIMC,
- LPWSTR pSrc,
- UINT uBufLen,
- UINT uFlag,
- void *pDst,
- UINT *puCopied) = 0;
-
- virtual long __stdcall GetConversionStatus(
- HIMC hIMC,
- DWORD *pfdwConversion,
- DWORD *pfdwSentence) = 0;
-
- virtual long __stdcall GetDefaultIMEWnd(
- HWND hWnd,
- HWND *phDefWnd) = 0;
-
- virtual long __stdcall GetDescriptionA(
- HKL hKL,
- UINT uBufLen,
- LPSTR szDescription,
- UINT *puCopied) = 0;
-
- virtual long __stdcall GetDescriptionW(
- HKL hKL,
- UINT uBufLen,
- LPWSTR szDescription,
- UINT *puCopied) = 0;
-
- virtual long __stdcall GetGuideLineA(
- HIMC hIMC,
- DWORD dwIndex,
- DWORD dwBufLen,
- LPSTR pBuf,
- DWORD *pdwResult) = 0;
-
- virtual long __stdcall GetGuideLineW(
- HIMC hIMC,
- DWORD dwIndex,
- DWORD dwBufLen,
- LPWSTR pBuf,
- DWORD *pdwResult) = 0;
-
- virtual long __stdcall GetIMEFileNameA(
- HKL hKL,
- UINT uBufLen,
- LPSTR szFileName,
- UINT *puCopied) = 0;
-
- virtual long __stdcall GetIMEFileNameW(
- HKL hKL,
- UINT uBufLen,
- LPWSTR szFileName,
- UINT *puCopied) = 0;
-
- virtual long __stdcall GetOpenStatus(
- HIMC hIMC) = 0;
-
- virtual long __stdcall GetProperty(
- HKL hKL,
- DWORD fdwIndex,
- DWORD *pdwProperty) = 0;
-
- virtual long __stdcall GetRegisterWordStyleA(
- HKL hKL,
- UINT nItem,
- STYLEBUFA *pStyleBuf,
- UINT *puCopied) = 0;
-
- virtual long __stdcall GetRegisterWordStyleW(
- HKL hKL,
- UINT nItem,
- STYLEBUFW *pStyleBuf,
- UINT *puCopied) = 0;
-
- virtual long __stdcall GetStatusWindowPos(
- HIMC hIMC,
- POINT *pptPos) = 0;
-
- virtual long __stdcall GetVirtualKey(
- HWND hWnd,
- UINT *puVirtualKey) = 0;
-
- virtual long __stdcall InstallIMEA(
- LPSTR szIMEFileName,
- LPSTR szLayoutText,
- HKL *phKL) = 0;
-
- virtual long __stdcall InstallIMEW(
- LPWSTR szIMEFileName,
- LPWSTR szLayoutText,
- HKL *phKL) = 0;
-
- virtual long __stdcall IsIME(
- HKL hKL) = 0;
-
- virtual long __stdcall IsUIMessageA(
- HWND hWndIME,
- UINT msg,
- WPARAM wParam,
- LPARAM lParam) = 0;
-
- virtual long __stdcall IsUIMessageW(
- HWND hWndIME,
- UINT msg,
- WPARAM wParam,
- LPARAM lParam) = 0;
-
- virtual long __stdcall NotifyIME(
- HIMC hIMC,
- DWORD dwAction,
- DWORD dwIndex,
- DWORD dwValue) = 0;
-
- virtual long __stdcall RegisterWordA(
- HKL hKL,
- LPSTR szReading,
- DWORD dwStyle,
- LPSTR szRegister) = 0;
-
- virtual long __stdcall RegisterWordW(
- HKL hKL,
- LPWSTR szReading,
- DWORD dwStyle,
- LPWSTR szRegister) = 0;
-
- virtual long __stdcall ReleaseContext(
- HWND hWnd,
- HIMC hIMC) = 0;
-
- virtual long __stdcall SetCandidateWindow(
- HIMC hIMC,
- void *pCandidate) = 0;
-
- virtual long __stdcall SetCompositionFontA(
- HIMC hIMC,
- LOGFONTA *plf) = 0;
-
- virtual long __stdcall SetCompositionFontW(
- HIMC hIMC,
- LOGFONTW *plf) = 0;
-
- virtual long __stdcall SetCompositionStringA(
- HIMC hIMC,
- DWORD dwIndex,
- LPVOID pComp,
- DWORD dwCompLen,
- LPVOID pRead,
- DWORD dwReadLen) = 0;
-
- virtual long __stdcall SetCompositionStringW(
- HIMC hIMC,
- DWORD dwIndex,
- LPVOID pComp,
- DWORD dwCompLen,
- LPVOID pRead,
- DWORD dwReadLen) = 0;
-
- virtual long __stdcall SetCompositionWindow(
- HIMC hIMC,
- void *pCompForm) = 0;
-
- virtual long __stdcall SetConversionStatus(
- HIMC hIMC,
- DWORD fdwConversion,
- DWORD fdwSentence) = 0;
-
- virtual long __stdcall SetOpenStatus(
- HIMC hIMC,
- BOOL fOpen) = 0;
-
- virtual long __stdcall SetStatusWindowPos(
- HIMC hIMC,
- POINT *pptPos) = 0;
-
- virtual long __stdcall SimulateHotKey(
- HWND hWnd,
- DWORD dwHotKeyID) = 0;
-
- virtual long __stdcall UnregisterWordA(
- HKL hKL,
- LPSTR szReading,
- DWORD dwStyle,
- LPSTR szUnregister) = 0;
-
- virtual long __stdcall UnregisterWordW(
- HKL hKL,
- LPWSTR szReading,
- DWORD dwStyle,
- LPWSTR szUnregister) = 0;
-
- virtual long __stdcall Activate(
- BOOL fRestoreLayout) = 0;
-
- virtual long __stdcall Deactivate( void) = 0;
-
- virtual long __stdcall OnDefWindowProc(
- HWND hWnd,
- UINT Msg,
- WPARAM wParam,
- LPARAM lParam,
- LRESULT *plResult) = 0;
-
- virtual long __stdcall FilterClientWindows(
- ATOM *aaClassList,
- UINT uSize) = 0;
-
- virtual long __stdcall GetCodePageA(
- HKL hKL,
- UINT *uCodePage) = 0;
-
- virtual long __stdcall GetLangId(
- HKL hKL,
- WORD *plid) = 0;
-
- virtual long __stdcall AssociateContextEx(
- HWND hWnd,
- HIMC hIMC,
- DWORD dwFlags) = 0;
-
- virtual long __stdcall DisableIME(
- DWORD idThread) = 0;
-
- virtual long __stdcall GetImeMenuItemsA(
- HIMC hIMC,
- DWORD dwFlags,
- DWORD dwType,
- void *pImeParentMenu,
- void *pImeMenu,
- DWORD dwSize,
- DWORD *pdwResult) = 0;
-
- virtual long __stdcall GetImeMenuItemsW(
- HIMC hIMC,
- DWORD dwFlags,
- DWORD dwType,
- void *pImeParentMenu,
- void *pImeMenu,
- DWORD dwSize,
- DWORD *pdwResult) = 0;
-
- virtual long __stdcall EnumInputContext(
- DWORD idThread,
- void **ppEnum) = 0;
-
- };
-
-#endif
-
-//
-// End of "$Id: aimm.h 8864 2011-07-19 04:49:30Z greg.ercolano $".
-//
diff --git a/src/fastarrow.h b/src/fastarrow.h
index e381acd..9af76dd 100644
--- a/src/fastarrow.h
+++ b/src/fastarrow.h
@@ -1,6 +1,6 @@
#define fastarrow_width 16
#define fastarrow_height 16
-static unsigned char fastarrow_bits[] = {
+static const unsigned char fastarrow_bits[] = {
0x00, 0x00, 0x00, 0x07, 0xe0, 0x07, 0xfc, 0x03, 0xff, 0xff, 0xfc, 0x03,
0xe0, 0x07, 0x00, 0x07, 0xe0, 0x00, 0xe0, 0x07, 0xc0, 0x3f, 0xff, 0xff,
0xc0, 0x3f, 0xe0, 0x07, 0xe0, 0x00, 0x00, 0x00};
diff --git a/src/fl_ask.cxx b/src/fl_ask.cxx
index cd9de23..051b67f 100644
--- a/src/fl_ask.cxx
+++ b/src/fl_ask.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: fl_ask.cxx 9373 2012-04-22 02:45:09Z fabien $"
+// "$Id: fl_ask.cxx 10232 2014-08-21 12:13:47Z cand $"
//
// Standard dialog functions for the Fast Light Tool Kit (FLTK).
//
@@ -16,6 +16,11 @@
// http://www.fltk.org/str.php
//
+/**
+ \file fl_ask.cxx
+ \brief Utility functions for common dialogs.
+ */
+
// Implementation of fl_message, fl_ask, fl_choice, fl_input
// The three-message fl_show_x functions are for forms compatibility
// mostly. In most cases it is easier to get a multi-line message
@@ -61,8 +66,8 @@ static char avoidRecursion = 0;
// The first argument (Fl_Widget *) can either be an Fl_Button*
// pointer to one of the buttons or an Fl_Window* pointer to the
// message window (message_form).
-static void button_cb(Fl_Widget *, void *val) {
- ret_val = (int) (fl_intptr_t)val;
+static void button_cb(Fl_Widget *, long val) {
+ ret_val = (int) val;
message_form->hide();
}
@@ -77,7 +82,7 @@ static Fl_Window *makeform() {
Fl_Group::current(0);
// create a new top level window
Fl_Window *w = message_form = new Fl_Window(410,103);
- message_form->callback(button_cb,(void *)0);
+ message_form->callback(button_cb);
// w->clear_border();
// w->box(FL_UP_BOX);
(message = new Fl_Box(60, 25, 340, 20))
@@ -99,11 +104,7 @@ static Fl_Window *makeform() {
else
button[b] = new Fl_Button(x, 70, 90, 23);
button[b]->align(FL_ALIGN_INSIDE|FL_ALIGN_WRAP);
-#if defined (__LP64__)
- button[b]->callback(button_cb,(void *)(long long) b);
-#else
- button[b]->callback(button_cb,(void *)b);
-#endif
+ button[b]->callback(button_cb, b);
}
}
button[0]->shortcut(FL_Escape);
@@ -125,7 +126,7 @@ static Fl_Window *makeform() {
* that is asked of them...
*/
-void resizeform() {
+static void resizeform() {
int i;
int message_w, message_h;
int text_height;
@@ -272,6 +273,7 @@ const char* fl_close= "Close"; ///< string pointer used in common dialogs, you
// fltk functions:
/**
Emits a system beep message.
+ \param[in] type The beep type from the \ref Fl_Beep enumeration.
\note \#include <FL/fl_ask.H>
*/
void fl_beep(int type) {
@@ -566,5 +568,5 @@ void fl_message_title_default(const char *title) {
/** @} */
//
-// End of "$Id: fl_ask.cxx 9373 2012-04-22 02:45:09Z fabien $".
+// End of "$Id: fl_ask.cxx 10232 2014-08-21 12:13:47Z cand $".
//
diff --git a/src/fl_boxtype.cxx b/src/fl_boxtype.cxx
index fadd3b5..6d688b5 100644
--- a/src/fl_boxtype.cxx
+++ b/src/fl_boxtype.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: fl_boxtype.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $"
+// "$Id: fl_boxtype.cxx 10253 2014-08-23 09:27:30Z cand $"
//
// Box drawing code for the Fast Light Tool Kit (FLTK).
//
@@ -32,14 +32,14 @@
////////////////////////////////////////////////////////////////
-static uchar active_ramp[24] = {
+static const uchar active_ramp[24] = {
FL_GRAY_RAMP+0, FL_GRAY_RAMP+1, FL_GRAY_RAMP+2, FL_GRAY_RAMP+3,
FL_GRAY_RAMP+4, FL_GRAY_RAMP+5, FL_GRAY_RAMP+6, FL_GRAY_RAMP+7,
FL_GRAY_RAMP+8, FL_GRAY_RAMP+9, FL_GRAY_RAMP+10,FL_GRAY_RAMP+11,
FL_GRAY_RAMP+12,FL_GRAY_RAMP+13,FL_GRAY_RAMP+14,FL_GRAY_RAMP+15,
FL_GRAY_RAMP+16,FL_GRAY_RAMP+17,FL_GRAY_RAMP+18,FL_GRAY_RAMP+19,
FL_GRAY_RAMP+20,FL_GRAY_RAMP+21,FL_GRAY_RAMP+22,FL_GRAY_RAMP+23};
-static uchar inactive_ramp[24] = {
+static const uchar inactive_ramp[24] = {
43, 43, 44, 44,
44, 45, 45, 46,
46, 46, 47, 47,
@@ -54,7 +54,7 @@ static int draw_it_active = 1;
*/
int Fl::draw_box_active() { return draw_it_active; }
-uchar *fl_gray_ramp() {return (draw_it_active?active_ramp:inactive_ramp)-'A';}
+const uchar *fl_gray_ramp() {return (draw_it_active?active_ramp:inactive_ramp)-'A';}
/**
Draws a series of line segments around the given box.
@@ -69,7 +69,7 @@ uchar *fl_gray_ramp() {return (draw_it_active?active_ramp:inactive_ramp)-'A';}
\param[in] x, y, w, h position and size
*/
void fl_frame(const char* s, int x, int y, int w, int h) {
- uchar *g = fl_gray_ramp();
+ const uchar *g = fl_gray_ramp();
if (h > 0 && w > 0) for (;*s;) {
// draw top line:
fl_color(g[(int)*s++]);
@@ -103,7 +103,7 @@ void fl_frame(const char* s, int x, int y, int w, int h) {
\param[in] x, y, w, h position and size
*/
void fl_frame2(const char* s, int x, int y, int w, int h) {
- uchar *g = fl_gray_ramp();
+ const uchar *g = fl_gray_ramp();
if (h > 0 && w > 0) for (;*s;) {
// draw bottom line:
fl_color(g[(int)*s++]);
@@ -416,5 +416,5 @@ void Fl_Widget::draw_box(Fl_Boxtype t, int X, int Y, int W, int H, Fl_Color c) c
}
//
-// End of "$Id: fl_boxtype.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $".
+// End of "$Id: fl_boxtype.cxx 10253 2014-08-23 09:27:30Z cand $".
//
diff --git a/src/fl_call_main.c b/src/fl_call_main.c
index 4476c38..b300696 100644
--- a/src/fl_call_main.c
+++ b/src/fl_call_main.c
@@ -1,5 +1,5 @@
/*
- * "$Id: fl_call_main.c 9325 2012-04-05 05:12:30Z fabien $"
+ * "$Id: fl_call_main.c 9984 2013-09-22 17:20:48Z greg.ercolano $"
*
* Copyright 1998-2010 by Bill Spitzak and others.
*
@@ -123,12 +123,12 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
return rc;
}
-#elif defined(__hpux)
-/* This code to prevent "empty translation unit" or similar warnings... */
-static void dummy(void) {}
+#else
+/* STR# 2973: solves "empty translation unit" error (Sun, HP-UX..) */
+typedef int dummy;
#endif /* WIN32 && !FL_DLL && !__GNUC__ */
/*
- * End of "$Id: fl_call_main.c 9325 2012-04-05 05:12:30Z fabien $".
+ * End of "$Id: fl_call_main.c 9984 2013-09-22 17:20:48Z greg.ercolano $".
*/
diff --git a/src/fl_cursor.cxx b/src/fl_cursor.cxx
index c9b6c98..d563fce 100644
--- a/src/fl_cursor.cxx
+++ b/src/fl_cursor.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: fl_cursor.cxx 9278 2012-03-12 11:55:50Z manolo $"
+// "$Id: fl_cursor.cxx 10405 2014-10-29 15:53:52Z manolo $"
//
// Mouse cursor support for the Fast Light Tool Kit (FLTK).
//
@@ -24,298 +24,173 @@
#include <FL/Fl.H>
#include <FL/Fl_Window.H>
+#include <FL/Fl_Pixmap.H>
+#include <FL/Fl_RGB_Image.H>
#include <FL/x.H>
-#if !defined(WIN32) && !defined(__APPLE__)
-# include <X11/cursorfont.h>
-#endif
#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) {
- if (Fl::first_window()) Fl::first_window()->cursor(c,fg,bg);
+ fl_cursor(c);
}
+
+
/**
- Sets the default window cursor as well as its color.
+ 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.
- For back compatibility only.
+ \see cursor(const Fl_RGB_Image*, int, int), default_cursor()
*/
-void Fl_Window::default_cursor(Fl_Cursor c, Fl_Color fg, Fl_Color bg) {
-// if (c == FL_CURSOR_DEFAULT) c = FL_CURSOR_ARROW;
-
+void Fl_Window::default_cursor(Fl_Cursor c) {
cursor_default = c;
- cursor_fg = fg;
- cursor_bg = bg;
+ cursor(c);
+}
+
+
+static 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 = 7;
+ hoty = 9;
+ 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);
- cursor(c, fg, bg);
+ w->cursor(&image, hotx, hoty);
}
-#ifdef WIN32
-# ifndef IDC_HAND
-# define IDC_HAND MAKEINTRESOURCE(32649)
-# endif // !IDC_HAND
+void Fl_Window::cursor(Fl_Cursor c) {
+ int ret;
-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;
+
+ while (w) {
+ toplevel = w;
+ w = w->window();
}
- 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);
+
+ if (toplevel != this) {
+ toplevel->cursor(c);
+ return;
}
- 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
-
-CGContextRef Fl_X::help_cursor_image(void)
-{
- int w = 20, h = 20;
- Fl_Offscreen off = Fl_Quartz_Graphics_Driver::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;
-}
+ if (c == FL_CURSOR_DEFAULT)
+ c = cursor_default;
-CGContextRef Fl_X::none_cursor_image(void)
-{
- int w = 20, h = 20;
- Fl_Offscreen off = Fl_Quartz_Graphics_Driver::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;
-}
+ if (!i)
+ return;
-CGContextRef Fl_X::watch_cursor_image(void)
-{
- int w, h, r = 5;
- w = 2*r+6;
- h = 4*r;
- Fl_Offscreen off = Fl_Quartz_Graphics_Driver::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;
-}
+ ret = i->set_cursor(c);
+ if (ret)
+ return;
-CGContextRef Fl_X::nesw_cursor_image(void)
-{
- int c = 7, r = 2*c;
- int w = r, h = r;
- Fl_Offscreen off = Fl_Quartz_Graphics_Driver::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;
+ fallback_cursor(this, c);
}
-CGContextRef Fl_X::nwse_cursor_image(void)
-{
- int c = 7, r = 2*c;
- int w = r, h = r;
- Fl_Offscreen off = Fl_Quartz_Graphics_Driver::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;
-}
+/**
+ 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.
-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);
-}
+ The default cursor will be used if the provided image cannot be used
+ as a cursor.
-#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
-};
+ \see cursor(Fl_Cursor), default_cursor()
+*/
+void Fl_Window::cursor(const Fl_RGB_Image *image, int hotx, int hoty) {
+ int ret;
-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;
+ // 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 (!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);
+ if (toplevel != this) {
+ toplevel->cursor(image, hotx, hoty);
+ return;
}
- XDefineCursor(fl_display, fl_xid(this), xc);
- if (deleteit) XFreeCursor(fl_display, xc);
+
+ if (!i)
+ return;
+
+ ret = i->set_cursor(image, hotx, hoty);
+ if (ret)
+ return;
+
+ cursor(FL_CURSOR_DEFAULT);
}
-#endif
+/**
+ For back compatibility only.
+ Same as Fl_Window::cursor(Fl_Cursor)
+*/
+void Fl_Window::cursor(Fl_Cursor c, Fl_Color, Fl_Color) {
+ cursor(c);
+};
+
+/**
+ For back compatibility only.
+ same as Fl_Window::default_cursor(Fl_Cursor)
+*/
+void Fl_Window::default_cursor(Fl_Cursor c, Fl_Color, Fl_Color) {
+ default_cursor(c);
+};
+
//
-// End of "$Id: fl_cursor.cxx 9278 2012-03-12 11:55:50Z manolo $".
+// End of "$Id: fl_cursor.cxx 10405 2014-10-29 15:53:52Z manolo $".
//
diff --git a/src/fl_cursor_help.xpm b/src/fl_cursor_help.xpm
new file mode 100644
index 0000000..2c21983
--- /dev/null
+++ b/src/fl_cursor_help.xpm
@@ -0,0 +1,39 @@
+/* XPM */
+static const char * const fl_cursor_help_xpm[] = {
+"16 27 9 1",
+" c None",
+". c #FFFFFF",
+"+ c #DBDBDB",
+"@ c #242424",
+"# c #000000",
+"$ c #494949",
+"% c #6D6D6D",
+"& c #929292",
+"* c #B6B6B6",
+" ",
+". ",
+".+ ",
+".@+ ",
+".#@+ ",
+".##@. ",
+".###@. ",
+".####@. ",
+".#####$. ",
+".######$. ",
+".#######$. ",
+".#####@@@%. ",
+".#####+..... ",
+".##$%#%. ",
+".#$..@#. ",
+".$. .&#%. ",
+".. .##. .... ",
+". .&#.+%$%&. ",
+" ...*#@##%.",
+" ++.*#@.",
+" .%#$.",
+" .%#@. ",
+" .##+ ",
+" .++. ",
+" +##. ",
+" +##. ",
+" .... "};
diff --git a/src/fl_cursor_nesw.xpm b/src/fl_cursor_nesw.xpm
new file mode 100644
index 0000000..4fbdcc9
--- /dev/null
+++ b/src/fl_cursor_nesw.xpm
@@ -0,0 +1,46 @@
+/* XPM */
+static const char * const fl_cursor_nesw_xpm[] = {
+"15 15 28 1",
+" c None",
+". c #FFFFFF",
+"+ c #767676",
+"@ c #000000",
+"# c #4E4E4E",
+"$ c #0C0C0C",
+"% c #494949",
+"& c #4D4D4D",
+"* c #1B1B1B",
+"= c #515151",
+"- c #646464",
+"; c #363636",
+"> c #6A6A6A",
+", c #545454",
+"' c #585858",
+") c #242424",
+"! c #797979",
+"~ c #2E2E2E",
+"{ c #444444",
+"] c #3B3B3B",
+"^ c #0A0A0A",
+"/ c #595959",
+"( c #F7F7F7",
+"_ c #080808",
+": c #6B6B6B",
+"< c #FDFDFD",
+"[ c #FCFCFC",
+"} c #FEFEFE",
+" ..........",
+" .+@@@@@@.",
+" .#@@@@@.",
+" .$@@@@.",
+" .%@@@@@.",
+". .&@@@*@@.",
+".. .=@@@-.;@.",
+".>. .,@@@'. .).",
+".@!.'@@@#. ..",
+".@@~@@@{. .",
+".@@@@@]. ",
+".@@@@^. ",
+".@@@@@/( ",
+".______:( ",
+"<[[[[[[[[} "};
diff --git a/src/fl_cursor_none.xpm b/src/fl_cursor_none.xpm
new file mode 100644
index 0000000..fb53c6d
--- /dev/null
+++ b/src/fl_cursor_none.xpm
@@ -0,0 +1,19 @@
+/* XPM */
+static const char * const fl_cursor_none_xpm[] = {
+"15 15 1 1",
+" c None",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" ",
+" "};
diff --git a/src/fl_cursor_nwse.xpm b/src/fl_cursor_nwse.xpm
new file mode 100644
index 0000000..f5e4ebb
--- /dev/null
+++ b/src/fl_cursor_nwse.xpm
@@ -0,0 +1,46 @@
+/* XPM */
+static const char * const fl_cursor_nwse_xpm[] = {
+"15 15 28 1",
+" c None",
+". c #FFFFFF",
+"+ c #000000",
+"@ c #767676",
+"# c #4E4E4E",
+"$ c #0C0C0C",
+"% c #494949",
+"& c #1B1B1B",
+"* c #4D4D4D",
+"= c #363636",
+"- c #646464",
+"; c #515151",
+"> c #242424",
+", c #585858",
+"' c #545454",
+") c #6A6A6A",
+"! c #797979",
+"~ c #444444",
+"{ c #2E2E2E",
+"] c #3B3B3B",
+"^ c #0A0A0A",
+"/ c #F7F7F7",
+"( c #595959",
+"_ c #6B6B6B",
+": c #080808",
+"< c #FEFEFE",
+"[ c #FCFCFC",
+"} c #FDFDFD",
+".......... ",
+".++++++@. ",
+".+++++#. ",
+".++++$. ",
+".+++++%. ",
+".++&+++*. .",
+".+=.-+++;. ..",
+".>. .,+++'. .).",
+".. .#+++,.!+.",
+". .~+++{++.",
+" .]+++++.",
+" .^++++.",
+" /(+++++.",
+" /_::::::.",
+" <[[[[[[[[}"};
diff --git a/src/fl_cursor_wait.xpm b/src/fl_cursor_wait.xpm
new file mode 100644
index 0000000..da02784
--- /dev/null
+++ b/src/fl_cursor_wait.xpm
@@ -0,0 +1,28 @@
+/* XPM */
+static const char * const fl_cursor_wait_xpm[] = {
+/* width height ncolors chars_per_pixel */
+"13 18 3 1",
+/* colors */
+" c None",
+". c #FFFFFF",
+"B c #000000",
+/* pixels */
+" ........ ",
+" .BBBBBB. ",
+" .BBBBBB. ",
+" .BBBBBB. ",
+" .BBBBBB. ",
+" .B......B. ",
+".B....B...B. ",
+".B....B...B. ",
+".B....B...BB.",
+".B.BBBB...BB.",
+".B........B. ",
+".B........B. ",
+" .B......B. ",
+" .BBBBBB. ",
+" .BBBBBB. ",
+" .BBBBBB. ",
+" .BBBBBB. ",
+" ........ ",
+};
diff --git a/src/fl_diamond_box.cxx b/src/fl_diamond_box.cxx
index b775e05..db2bfb2 100644
--- a/src/fl_diamond_box.cxx
+++ b/src/fl_diamond_box.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: fl_diamond_box.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $"
+// "$Id: fl_diamond_box.cxx 10306 2014-09-13 16:49:47Z manolo $"
//
// Diamond box code for the Fast Light Tool Kit (FLTK).
//
@@ -25,7 +25,7 @@
#include <FL/Fl.H>
#include <FL/fl_draw.H>
-extern uchar* fl_gray_ramp();
+extern const uchar* fl_gray_ramp();
static void fl_diamond_up_box(int x,int y,int w,int h,Fl_Color bgcolor) {
w &= -2;
@@ -33,14 +33,14 @@ static void fl_diamond_up_box(int x,int y,int w,int h,Fl_Color bgcolor) {
int x1 = x+w/2;
int y1 = y+h/2;
fl_color(bgcolor); fl_polygon(x+3, y1, x1,y+3, x+w-3,y1, x1,y+h-3);
- uchar *g = fl_gray_ramp();
- fl_color(g['W']); fl_line(x+1, y1, x1, y+1, x+w-1, y1);
- fl_color(g['U']); fl_line(x+2, y1, x1, y+2, x+w-2, y1);
- fl_color(g['S']); fl_line(x+3, y1, x1, y+3, x+w-3, y1);
- fl_color(g['P']); fl_line(x+3, y1, x1, y+h-3, x+w-3, y1);
- fl_color(g['N']); fl_line(x+2, y1, x1, y+h-2, x+w-2, y1);
- fl_color(g['H']); fl_line(x+1, y1, x1, y+h-1, x+w-1, y1);
- fl_color(g['A']); fl_loop(x, y1, x1, y, x+w, y1, x1, y+h);
+ const uchar *g = fl_gray_ramp();
+ fl_color(g[(int)'W']); fl_line(x+1, y1, x1, y+1, x+w-1, y1);
+ fl_color(g[(int)'U']); fl_line(x+2, y1, x1, y+2, x+w-2, y1);
+ fl_color(g[(int)'S']); fl_line(x+3, y1, x1, y+3, x+w-3, y1);
+ fl_color(g[(int)'P']); fl_line(x+3, y1, x1, y+h-3, x+w-3, y1);
+ fl_color(g[(int)'N']); fl_line(x+2, y1, x1, y+h-2, x+w-2, y1);
+ fl_color(g[(int)'H']); fl_line(x+1, y1, x1, y+h-1, x+w-1, y1);
+ fl_color(g[(int)'A']); fl_loop(x, y1, x1, y, x+w, y1, x1, y+h);
}
static void fl_diamond_down_box(int x,int y,int w,int h,Fl_Color bgcolor) {
@@ -48,15 +48,15 @@ static void fl_diamond_down_box(int x,int y,int w,int h,Fl_Color bgcolor) {
h &= -2;
int x1 = x+w/2;
int y1 = y+h/2;
- uchar *g = fl_gray_ramp();
- fl_color(g['P']); fl_line(x+0, y1, x1, y+0, x+w-0, y1);
- fl_color(g['N']); fl_line(x+1, y1, x1, y+1, x+w-1, y1);
- fl_color(g['H']); fl_line(x+2, y1, x1, y+2, x+w-2, y1);
- fl_color(g['W']); fl_line(x+2, y1, x1, y+h-2, x+w-2, y1);
- fl_color(g['U']); fl_line(x+1, y1, x1, y+h-1, x+w-1, y1);
- fl_color(g['S']); fl_line(x+0, y1, x1, y+h-0, x+w-0, y1);
+ const uchar *g = fl_gray_ramp();
+ fl_color(g[(int)'P']); fl_line(x+0, y1, x1, y+0, x+w-0, y1);
+ fl_color(g[(int)'N']); fl_line(x+1, y1, x1, y+1, x+w-1, y1);
+ fl_color(g[(int)'H']); fl_line(x+2, y1, x1, y+2, x+w-2, y1);
+ fl_color(g[(int)'W']); fl_line(x+2, y1, x1, y+h-2, x+w-2, y1);
+ fl_color(g[(int)'U']); fl_line(x+1, y1, x1, y+h-1, x+w-1, y1);
+ fl_color(g[(int)'S']); fl_line(x+0, y1, x1, y+h-0, x+w-0, y1);
fl_color(bgcolor); fl_polygon(x+3, y1, x1,y+3, x+w-3,y1, x1,y+h-3);
- fl_color(g['A']); fl_loop(x+3, y1, x1, y+3, x+w-3, y1, x1, y+h-3);
+ fl_color(g[(int)'A']); fl_loop(x+3, y1, x1, y+3, x+w-3, y1, x1, y+h-3);
}
extern void fl_internal_boxtype(Fl_Boxtype, Fl_Box_Draw_F*);
@@ -67,5 +67,5 @@ Fl_Boxtype fl_define_FL_DIAMOND_BOX() {
}
//
-// End of "$Id: fl_diamond_box.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $".
+// End of "$Id: fl_diamond_box.cxx 10306 2014-09-13 16:49:47Z manolo $".
//
diff --git a/src/fl_dnd_x.cxx b/src/fl_dnd_x.cxx
index 6d47a46..b5fe857 100644
--- a/src/fl_dnd_x.cxx
+++ b/src/fl_dnd_x.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: fl_dnd_x.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $"
+// "$Id: fl_dnd_x.cxx 9979 2013-09-20 03:36:02Z greg.ercolano $"
//
// Drag & Drop code for the Fast Light Tool Kit (FLTK).
//
@@ -55,9 +55,11 @@ static int dnd_aware(Window& window) {
0, 4, False, XA_ATOM,
&actual, &format,
&count, &remaining, &data);
+ int ret = 0;
if (actual == XA_ATOM && format==32 && count && data)
- return int(*(Atom*)data);
- return 0;
+ ret = int(*(Atom*)data);
+ if (data) { XFree(data); data = 0; }
+ return ret;
}
static int grabfunc(int event) {
@@ -189,5 +191,5 @@ int Fl::dnd() {
//
-// End of "$Id: fl_dnd_x.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $".
+// End of "$Id: fl_dnd_x.cxx 9979 2013-09-20 03:36:02Z greg.ercolano $".
//
diff --git a/src/fl_draw.cxx b/src/fl_draw.cxx
index 2fa499b..355b04a 100644
--- a/src/fl_draw.cxx
+++ b/src/fl_draw.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: fl_draw.cxx 9326 2012-04-05 14:30:19Z AlbrechtS $"
+// "$Id: fl_draw.cxx 10265 2014-09-03 10:07:33Z AlbrechtS $"
//
// Label drawing code for the Fast Light Tool Kit (FLTK).
//
@@ -32,83 +32,28 @@
#include <ctype.h>
#include <math.h>
-#define MAXBUF 1024
char fl_draw_shortcut; // set by fl_labeltypes.cxx
static char* underline_at;
-/**
- utf8 multibyte char seq. detection an pass-thru routine.
- \retval false if no utf8 seq detected, no change made. true if utf8 and d copied with s seq.
- note that for n bytes copied dest incremented of n, but s of n-1 for compatible loop use see below.
-*/
-#define C_IN(c,a,b) ((c)>=(a) && (c)<=(b))
-#define C_UTF8(c) C_IN(c,0x80,0xBF)
-
-static bool handle_utf8_seq(const char * &s,char * &d) {
- register const unsigned char* p=(const unsigned char*)s;
- if (p[0] < 0xc2 || p[0] > 0xf4)
- return false; // not adressed in this function
- else if ( C_IN(p[0], 0xc2, 0xdf) && C_UTF8(p[1]) ) {
- d[0]=s[0]; d[1]=s[1];
- d+=2; s++;
- // non-overlong 2-byte
- }
- else if ( p[0]==0xe0 && C_IN(p[1], 0xa0, 0xbf) && C_UTF8(p[2]) ) {
- d[0]=s[0]; d[1]=s[1];d[2]=s[2];
- d+=3; s+=2;
- // excluding overlongs
- }
- else if (p[0]==0xed && C_IN(p[1], 0x80, 0x9f) && C_UTF8(p[2]) ) {
- d[0]=s[0]; d[1]=s[1];d[2]=s[2];
- d+=3; s+=2;
- // excluding surrogates
- }
- else if (p[0]!=0xed && C_IN(p[0], 0xe1, 0xef) && C_UTF8(p[1]) && C_UTF8(p[2]) ) {
- d[0]=s[0]; d[1]=s[1];d[2]=s[2];
- d+=3; s+=2;
- // straight 3-byte
- }
- else if (p[0]==0xf0 && C_IN(p[1], 0x90, 0xbf) && C_UTF8(p[2]) && C_UTF8(p[3]) ) {
- d[0]=s[0]; d[1]=s[1]; d[2]=s[2]; d[3]=s[3];
- d+=4; s+=3;
- // planes 1-3
- }
- else if (C_IN(p[0], 0xf1, 0xf3) && C_UTF8(p[1]) && C_UTF8(p[2]) && C_UTF8(p[3]) ) {
- d[0]=s[0]; d[1]=s[1]; d[2]=s[2]; d[3]=s[3];
- d+=4; s+=3;
- // planes 4-15
- }
- else if (p[0]==0xf4 && C_IN(p[1], 0x80, 0x8f) && C_UTF8(p[2]) && C_UTF8(p[3]) ) {
- d[0]=s[0]; d[1]=s[1]; d[2]=s[2]; d[3]=s[3];
- d+=4; s+=3;
- // planes 16
- } else { // non utf8 compliant, maybe CP125x or broken utf8 string
- // fprintf(stderr, "Not UTF8 char \n");
- return false;
- }
- return true; // we did handled and copied the utf8 multibyte char seq.
-}
-
-/**
- Copy \p from to \p buf, replacing unprintable characters with ^X and \\nnn.
-
- Stop at a newline or if MAXBUF characters written to buffer.
- Also word-wrap if width exceeds maxw.
- Returns a pointer to the start of the next line of characters.
- Sets n to the number of characters put into the buffer.
- Sets width to the width of the string in the current font.
-*/
-const char*
-fl_expand_text(const char* from, char* buf, int maxbuf, double maxw, int& n,
- double &width, int wrap, int draw_symbols) {
- char* o = buf;
+/* If called with maxbuf==0, use an internally allocated buffer and enlarge it as needed.
+ Otherwise, use buf as buffer but don't go beyond its length of maxbuf.
+ */
+static const char* expand_text_(const char* from, char*& buf, int maxbuf, double maxw, int& n,
+ double &width, int wrap, int draw_symbols) {
char* e = buf+(maxbuf-4);
underline_at = 0;
+ double w = 0;
+ static int l_local_buff = 500;
+ static char *local_buf = (char*)malloc(l_local_buff); // initial buffer allocation
+ if (maxbuf == 0) {
+ buf = local_buf;
+ e = buf + l_local_buff - 4;
+ }
+ char* o = buf;
char* word_end = o;
const char* word_start = from;
- double w = 0;
const char* p = from;
for (;; p++) {
@@ -132,10 +77,18 @@ fl_expand_text(const char* from, char* buf, int maxbuf, double maxw, int& n,
word_start = p+1;
}
- if (o > e) break; // don't overflow buffer
+ if (o > e) {
+ if (maxbuf) break; // don't overflow buffer
+ l_local_buff += (o - e) + 200; // enlarge buffer
+ buf = (char*)realloc(local_buf, l_local_buff);
+ e = buf + l_local_buff - 4; // update pointers to buffer content
+ o = buf + (o - local_buf);
+ word_end = buf + (word_end - local_buf);
+ local_buf = buf;
+ }
if (c == '\t') {
- for (c = fl_utf_nb_char((uchar*)buf, (int) (o-buf) )%8; c<8 && o<e; c++)
+ for (c = fl_utf_nb_char((uchar*)buf, (int) (o-buf) )%8; c<8 && o<e; c++)
*o++ = ' ';
} else if (c == '&' && fl_draw_shortcut && *(p+1)) {
if (*(p+1) == '&') {p++; *o++ = '&';}
@@ -143,14 +96,17 @@ fl_expand_text(const char* from, char* buf, int maxbuf, double maxw, int& n,
} else if (c < ' ' || c == 127) { // ^X
*o++ = '^';
*o++ = c ^ 0x40;
- } else if (handle_utf8_seq(p, o)) { // figure out if we have an utf8 valid sequence before we determine the nbsp test validity:
+/* This is in fact not useful: the point is that a valid UTF-8 sequence for a non-ascii char contains no ascii char,
+ thus no tab, space, control, & or @ we want to process differently.
+ Also, invalid UTF-8 sequences are copied unchanged by this procedure.
+ Therefore, checking for tab, space, control, & or @, and copying the byte otherwise, is enough.
+ } else if (handle_utf8_seq(p, o)) { // figure out if we have an utf8 valid sequence before we determine the nbsp test validity:
#ifdef __APPLE__
} else if (c == 0xCA) { // non-breaking space in MacRoman
#else
} else if (c == 0xA0) { // non-breaking space in ISO 8859
#endif
- *o++ = ' ';
-
+ *o++ = ' ';*/
} else if (c == '@' && draw_symbols) { // Symbol???
if (p[1] && p[1] != '@') break;
*o++ = c;
@@ -167,6 +123,21 @@ fl_expand_text(const char* from, char* buf, int maxbuf, double maxw, int& n,
}
/**
+ Copy \p from to \p buf, replacing control characters with ^X.
+
+ Stop at a newline or if \p maxbuf characters written to buffer.
+ Also word-wrap if width exceeds maxw.
+ Returns a pointer to the start of the next line of characters.
+ Sets n to the number of characters put into the buffer.
+ Sets width to the width of the string in the current font.
+ */
+const char*
+fl_expand_text(const char* from, char* buf, int maxbuf, double maxw, int& n,
+ double &width, int wrap, int draw_symbols) {
+ return expand_text_(from, buf, maxbuf, maxw, n, width, wrap, draw_symbols);
+}
+
+/**
The same as fl_draw(const char*,int,int,int,int,Fl_Align,Fl_Image*,int) with
the addition of the \p callthis parameter, which is a pointer to a text drawing
function such as fl_draw(const char*, int, int, int) to do the real work
@@ -176,11 +147,11 @@ void fl_draw(
int x, int y, int w, int h, // bounding box
Fl_Align align,
void (*callthis)(const char*,int,int,int),
- Fl_Image* img, int draw_symbols)
+ Fl_Image* img, int draw_symbols)
{
+ char *linebuf = NULL;
const char* p;
const char* e;
- char buf[MAXBUF];
int buflen;
char symbol[2][255], *symptr;
int symwidth[2], symoffset, symtotal, imgtotal;
@@ -191,7 +162,7 @@ void fl_draw(
// if the image is set as a backdrop, ignore it here
if (img && (align & FL_ALIGN_IMAGE_BACKDROP)) img = 0;
-
+
symbol[0][0] = '\0';
symwidth[0] = 0;
@@ -217,13 +188,13 @@ void fl_draw(
symtotal = symwidth[0] + symwidth[1];
imgtotal = (img && (align&FL_ALIGN_IMAGE_NEXT_TO_TEXT)) ? img->w() : 0;
-
+
int strw = 0;
int strh;
if (str) {
for (p = str, lines=0; p;) {
- e = fl_expand_text(p, buf, MAXBUF, w - symtotal - imgtotal, buflen, width,
+ e = expand_text_(p, linebuf, 0, w - symtotal - imgtotal, buflen, width,
align&FL_ALIGN_WRAP, draw_symbols);
if (strw<width) strw = (int)width;
lines++;
@@ -231,7 +202,7 @@ void fl_draw(
p = e;
}
} else lines = 0;
-
+
if ((symwidth[0] || symwidth[1]) && lines) {
if (symwidth[0]) symwidth[0] = lines * fl_height();
if (symwidth[1]) symwidth[1] = lines * fl_height();
@@ -239,7 +210,7 @@ void fl_draw(
symtotal = symwidth[0] + symwidth[1];
strh = lines * fl_height();
-
+
// figure out vertical position of the first line:
int xpos;
int ypos;
@@ -285,12 +256,12 @@ void fl_draw(
else yimg += (strh - img->h() - 1) / 2;
img->draw(xpos, yimg);
}
-
+
// now draw all the lines:
if (str) {
int desc = fl_descent();
for (p=str; ; ypos += height) {
- if (lines>1) e = fl_expand_text(p, buf, MAXBUF, w - symtotal - imgtotal, buflen,
+ if (lines>1) e = expand_text_(p, linebuf, 0, w - symtotal - imgtotal, buflen,
width, align&FL_ALIGN_WRAP, draw_symbols);
else e = "";
@@ -300,10 +271,10 @@ void fl_draw(
else if (align & FL_ALIGN_RIGHT) xpos = x + w - (int)(width + .5) - symwidth[1] - imgw[1];
else xpos = x + (w - (int)(width + .5) - symtotal - imgw[0] - imgw[1]) / 2 + symwidth[0] + imgw[0];
- callthis(buf,buflen,xpos,ypos-desc);
+ callthis(linebuf,buflen,xpos,ypos-desc);
- if (underline_at && underline_at >= buf && underline_at < (buf + buflen))
- callthis("_",1,xpos+int(fl_width(buf,(int) (underline_at-buf))),ypos-desc);
+ if (underline_at && underline_at >= linebuf && underline_at < (linebuf + buflen))
+ callthis("_",1,xpos+int(fl_width(linebuf,(int) (underline_at-linebuf))),ypos-desc);
if (!*e || (*e == '@' && e[1] != '@')) break;
p = e;
@@ -361,7 +332,6 @@ void fl_draw(
below the text as specified by the \p align value.
The \p draw_symbols argument specifies whether or not to look for symbol
names starting with the '\@' character'
- The text length is limited to 1024 characters per line.
*/
void fl_draw(
const char* str,
@@ -372,10 +342,10 @@ void fl_draw(
{
if ((!str || !*str) && !img) return;
if (w && h && !fl_not_clipped(x, y, w, h) && (align & FL_ALIGN_INSIDE)) return;
- if (align & FL_ALIGN_CLIP)
+ if (align & FL_ALIGN_CLIP)
fl_push_clip(x, y, w, h);
fl_draw(str, x, y, w, h, align, fl_draw, img, draw_symbols);
- if (align & FL_ALIGN_CLIP)
+ if (align & FL_ALIGN_CLIP)
fl_pop_clip();
}
@@ -383,7 +353,7 @@ void fl_draw(
Measure how wide and tall the string will be when printed by the
fl_draw() function with \p align parameter. If the incoming \p w
is non-zero it will wrap to that width.
-
+
The 'current font' is used to do the width/height calculations,
so unless its value is known at the time fl_measure() is called,
it is advised to first set the current font with fl_font().
@@ -406,45 +376,38 @@ void fl_draw(
void fl_measure(const char* str, int& w, int& h, int draw_symbols) {
if (!str || !*str) {w = 0; h = 0; return;}
h = fl_height();
+ char *linebuf = NULL;
const char* p;
const char* e;
- char buf[MAXBUF];
int buflen;
int lines;
double width=0;
int W = 0;
- char symbol[2][255], *symptr;
int symwidth[2], symtotal;
- // count how many lines and put the last one into the buffer:
- symbol[0][0] = '\0';
- symwidth[0] = 0;
-
- symbol[1][0] = '\0';
- symwidth[1] = 0;
+ symwidth[0] = 0; // size of symbol at beginning of string (if any)
+ symwidth[1] = 0; // size of symbol at end of string (if any)
if (draw_symbols) {
- if (str && str[0] == '@' && str[1] && str[1] != '@') {
- // Start with a symbol...
- for (symptr = symbol[0];
- *str && !isspace(*str) && symptr < (symbol[0] + sizeof(symbol[0]) - 1);
- *symptr++ = *str++);
- *symptr = '\0';
- if (isspace(*str)) str++;
+ // Symbol at beginning of string?
+ const char *sym2 = (str[0]=='@' && str[1]=='@') ? str+2 : str; // sym2 check will skip leading @@
+ if (str[0] == '@' && str[1] != '@') {
+ while (*str && !isspace(*str)) { ++str; } // skip over symbol
+ if (isspace(*str)) ++str; // skip over trailing space
+ sym2 = str; // sym2 check will skip leading symbol
symwidth[0] = h;
}
-
- if (str && (p = strrchr(str, '@')) != NULL && p > (str + 1) && p[-1]!='@') {
- strlcpy(symbol[1], p, sizeof(symbol[1]));
+ // Symbol at end of string?
+ if ((p=strchr(sym2,'@')) != NULL && p[1] != '@') {
symwidth[1] = h;
}
}
symtotal = symwidth[0] + symwidth[1];
-
+
for (p = str, lines=0; p;) {
-// e = expand(p, buf, w - symtotal, buflen, width, w != 0, draw_symbols);
- e = fl_expand_text(p, buf, MAXBUF, w - symtotal, buflen, width,
+// e = expand(p, linebuf, w - symtotal, buflen, width, w != 0, draw_symbols);
+ e = expand_text_(p, linebuf, 0, w - symtotal, buflen, width,
w != 0, draw_symbols);
if ((int)ceil(width) > W) W = (int)ceil(width);
lines++;
@@ -469,13 +432,13 @@ void fl_measure(const char* str, int& w, int& h, int draw_symbols) {
but with the advent of XFT, there are (currently) complexities
that seem to only be solved by asking the font what its actual
font height is. (See STR#2115)
-
+
This function was originally undocumented in 1.1.x, and was used
only by Fl_Text_Display. We're now documenting it in 1.3.x so that
apps that need precise height info can get it with this function.
\returns the height of the font in pixels.
-
+
\todo In the future, when the XFT issues are resolved, this function
should simply return the 'size' value.
*/
@@ -489,5 +452,5 @@ int fl_height(int font, int size) {
}
//
-// End of "$Id: fl_draw.cxx 9326 2012-04-05 14:30:19Z AlbrechtS $".
+// End of "$Id: fl_draw.cxx 10265 2014-09-03 10:07:33Z AlbrechtS $".
//
diff --git a/src/fl_draw_pixmap.cxx b/src/fl_draw_pixmap.cxx
index 7a85b76..8440d55 100644
--- a/src/fl_draw_pixmap.cxx
+++ b/src/fl_draw_pixmap.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: fl_draw_pixmap.cxx 9375 2012-04-22 03:09:31Z fabien $"
+// "$Id: fl_draw_pixmap.cxx 10242 2014-08-22 10:28:50Z AlbrechtS $"
//
// Pixmap drawing code for the Fast Light Tool Kit (FLTK).
//
@@ -16,6 +16,9 @@
// http://www.fltk.org/str.php
//
+// NOTE: I believe many of the following comments (between the dash markers)
+// are no longer accurate:
+// --------------------------------------------------------------------
// Implemented without using the xpm library (which I can't use because
// it interferes with the color cube used by fl_draw_image).
// Current implementation is cheap and slow, and works best on a full-color
@@ -25,6 +28,9 @@
// Notice that there is no pixmap file interface. This is on purpose,
// as I want to discourage programs that require support files to work.
// All data needed by a program ui should be compiled in!!!
+// --------------------------------------------------------------------
+// The above comments were checked in as r2, and much has changed since then;
+// transparency added, color cube not required, etc. -erco Oct 20 2013
#include <FL/Fl.H>
#include <FL/fl_draw.H>
@@ -37,7 +43,7 @@ static int ncolors, chars_per_pixel;
/**
Get the dimensions of a pixmap.
An XPM image contains the dimensions in its data. This function
- returns te width and height.
+ returns the width and height.
\param[in] data pointer to XPM image data.
\param[out] w,h width and height of image
\returns non-zero if the dimensions were parsed OK
@@ -58,99 +64,6 @@ int fl_measure_pixmap(const char * const *cdata, int &w, int &h) {
return 1;
}
-#ifdef U64
-
-// The callback from fl_draw_image to get a row of data passes this:
-struct pixmap_data {
- int w, h;
- const uchar*const* data;
- union {
- U64 colors[256];
- U64* byte1[256];
- };
-};
-
-// callback for 1 byte per pixel:
-static void cb1(void*v, int x, int y, int w, uchar* buf) {
- pixmap_data& d = *(pixmap_data*)v;
- const uchar* p = d.data[y]+x;
- U64* q = (U64*)buf;
- for (int X=w; X>0; X-=2, p += 2) {
- if (X>1) {
-# if WORDS_BIGENDIAN
- *q++ = (d.colors[p[0]]<<32) | d.colors[p[1]];
-# else
- *q++ = (d.colors[p[1]]<<32) | d.colors[p[0]];
-# endif
- } else {
-# if WORDS_BIGENDIAN
- *q++ = d.colors[p[0]]<<32;
-# else
- *q++ = d.colors[p[0]];
-# endif
- }
- }
-}
-
-// callback for 2 bytes per pixel:
-static void cb2(void*v, int x, int y, int w, uchar* buf) {
- pixmap_data& d = *(pixmap_data*)v;
- const uchar* p = d.data[y]+2*x;
- U64* q = (U64*)buf;
- for (int X=w; X>0; X-=2) {
- U64* colors = d.byte1[*p++];
- int index = *p++;
- if (X>1) {
- U64* colors1 = d.byte1[*p++];
- int index1 = *p++;
-# if WORDS_BIGENDIAN
- *q++ = (colors[index]<<32) | colors1[index1];
-# else
- *q++ = (colors1[index1]<<32) | colors[index];
-# endif
- } else {
-# if WORDS_BIGENDIAN
- *q++ = colors[index]<<32;
-# else
- *q++ = colors[index];
-# endif
- }
- }
-}
-
-#else // U32
-
-// The callback from fl_draw_image to get a row of data passes this:
-struct pixmap_data {
- int w, h;
- const uchar*const* data;
- union {
- U32 colors[256];
- U32* byte1[256];
- };
-};
-
-// callback for 1 byte per pixel:
-static void cb1(void*v, int x, int y, int w, uchar* buf) {
- pixmap_data& d = *(pixmap_data*)v;
- const uchar* p = d.data[y]+x;
- U32* q = (U32*)buf;
- for (int X=w; X--;) *q++ = d.colors[*p++];
-}
-
-// callback for 2 bytes per pixel:
-static void cb2(void*v, int x, int y, int w, uchar* buf) {
- pixmap_data& d = *(pixmap_data*)v;
- const uchar* p = d.data[y]+2*x;
- U32* q = (U32*)buf;
- for (int X=w; X--;) {
- U32* colors = d.byte1[*p++];
- *q++ = colors[*p++];
- }
-}
-
-#endif // U64 else U32
-
uchar **fl_mask_bitmap; // if non-zero, create bitmap and store pointer here
/**
@@ -169,50 +82,58 @@ int fl_draw_pixmap(/*const*/ char* const* data, int x,int y,Fl_Color bg) {
#ifdef WIN32
// to compute an unused color to be used for the pixmap background
FL_EXPORT UINT win_pixmap_bg_color; // the RGB() of the pixmap background color
-static int color_count; // # of non-transparent colors used in pixmap
-static uchar *used_colors; // used_colors[3*i+j] j=0,1,2 are the RGB values of the ith used color
+static int color_count; // # of non-transparent colors used in pixmap
+typedef struct { uchar r; uchar g; uchar b; } UsedColor;
+static UsedColor *used_colors;
-static void make_unused_color(uchar &r, uchar &g, uchar &b)
-// makes an RGB triplet different from all the colors used in the pixmap
+// Makes an RGB triplet different from all the colors used in the pixmap
// and compute win_pixmap_bg_color from this triplet
-{
+static void make_unused_color(uchar &r, uchar &g, uchar &b) {
int i;
r = 2; g = 3; b = 4;
while (1) {
- for ( i = 0; i < color_count; i++) {
- if(used_colors[3*i] == r && used_colors[3*i+1] == g && used_colors[3*i+2] == b) break;
- }
+ for ( i=0; i<color_count; i++ )
+ if ( used_colors[i].r == r &&
+ used_colors[i].g == g &&
+ used_colors[i].b == b )
+ break;
if (i >= color_count) {
- free(used_colors);
+ free((void*)used_colors); used_colors = NULL;
win_pixmap_bg_color = RGB(r, g, b);
return;
- }
- if (r < 255) r++;
- else {
+ }
+ if (r < 255) {
+ r++;
+ } else {
r = 0;
- if (g < 255) g++;
- else {
+ if (g < 255) {
+ g++;
+ } else {
g = 0;
b++;
- }
}
}
+ }
}
#endif
-/**
- Draw XPM image data, with the top-left corner at the given position.
- \see fl_draw_pixmap(char* const* data, int x, int y, Fl_Color bg)
- */
-int fl_draw_pixmap(const char*const* cdata, int x, int y, Fl_Color bg) {
- pixmap_data d;
- if (!fl_measure_pixmap(cdata, d.w, d.h)) return 0;
+int fl_convert_pixmap(const char*const* cdata, uchar* out, Fl_Color bg) {
+ int w, h;
const uchar*const* data = (const uchar*const*)(cdata+1);
- int transparent_index = -1;
+
+ if (!fl_measure_pixmap(cdata, w, h))
+ return 0;
+
+ if ((chars_per_pixel < 1) || (chars_per_pixel > 2))
+ return 0;
+
+ typedef uchar uchar4[4];
+ uchar4 *colors = new uchar4[1<<(chars_per_pixel*8)];
+
#ifdef WIN32
uchar *transparent_c = (uchar *)0; // such that transparent_c[0,1,2] are the RGB of the transparent color
color_count = 0;
- used_colors = (uchar *)malloc(abs(ncolors)*3*sizeof(uchar));
+ used_colors = (UsedColor*)malloc(abs(ncolors) * sizeof(UsedColor));
#endif
if (ncolors < 0) { // FLTK (non standard) compressed colormap
@@ -221,14 +142,7 @@ int fl_draw_pixmap(const char*const* cdata, int x, int y, Fl_Color bg) {
// if first color is ' ' it is transparent (put it later to make
// it not be transparent):
if (*p == ' ') {
- uchar* c = (uchar*)&d.colors[(int)' '];
-#ifdef U64
- *(U64*)c = 0;
-# if WORDS_BIGENDIAN
- c += 4;
-# endif
-#endif
- transparent_index = ' ';
+ uchar* c = colors[(int)' '];
Fl::get_color(bg, c[0], c[1], c[2]); c[3] = 0;
#ifdef WIN32
transparent_c = c;
@@ -238,48 +152,27 @@ int fl_draw_pixmap(const char*const* cdata, int x, int y, Fl_Color bg) {
}
// read all the rest of the colors:
for (int i=0; i < ncolors; i++) {
- uchar* c = (uchar*)&d.colors[*p++];
-#ifdef U64
- *(U64*)c = 0;
-# if WORDS_BIGENDIAN
- c += 4;
-# endif
-#endif
+ uchar* c = colors[*p++];
#ifdef WIN32
- used_colors[3*color_count] = *p;
- used_colors[3*color_count+1] = *(p+1);
- used_colors[3*color_count+2] = *(p+2);
+ used_colors[color_count].r = *(p+0);
+ used_colors[color_count].g = *(p+1);
+ used_colors[color_count].b = *(p+2);
color_count++;
#endif
*c++ = *p++;
*c++ = *p++;
*c++ = *p++;
-#ifdef __APPLE_QUARTZ__
*c = 255;
-#else
- *c = 0;
-#endif
}
} else { // normal XPM colormap with names
- if (chars_per_pixel>1) memset(d.byte1, 0, sizeof(d.byte1));
for (int i=0; i<ncolors; i++) {
const uchar *p = *data++;
// the first 1 or 2 characters are the color index:
int ind = *p++;
uchar* c;
- if (chars_per_pixel>1) {
-#ifdef U64
- U64* colors = d.byte1[ind];
- if (!colors) colors = d.byte1[ind] = new U64[256];
-#else
- U32* colors = d.byte1[ind];
- if (!colors) colors = d.byte1[ind] = new U32[256];
-#endif
- c = (uchar*)&colors[*p];
+ if (chars_per_pixel>1)
ind = (ind<<8)|*p++;
- } else {
- c = (uchar *)&d.colors[ind];
- }
+ c = colors[ind];
// look for "c word", or last word if none:
const uchar *previous_word = p;
for (;;) {
@@ -292,122 +185,109 @@ int fl_draw_pixmap(const char*const* cdata, int x, int y, Fl_Color bg) {
previous_word = p;
while (*p && !isspace(*p)) p++;
}
-#ifdef U64
- *(U64*)c = 0;
-# if WORDS_BIGENDIAN
- c += 4;
-# endif
-#endif
-#ifdef __APPLE_QUARTZ__
- c[3] = 255;
-#endif
int parse = fl_parse_color((const char*)p, c[0], c[1], c[2]);
+ c[3] = 255;
if (parse) {
#ifdef WIN32
- used_colors[3*color_count] = c[0];
- used_colors[3*color_count+1] = c[1];
- used_colors[3*color_count+2] = c[2];
+ used_colors[color_count].r = c[0];
+ used_colors[color_count].g = c[1];
+ used_colors[color_count].b = c[2];
color_count++;
#endif
- }
- else {
+ } else {
// assume "None" or "#transparent" for any errors
// "bg" should be transparent...
Fl::get_color(bg, c[0], c[1], c[2]);
-#ifdef __APPLE_QUARTZ__
c[3] = 0;
-#endif
- transparent_index = ind;
#ifdef WIN32
transparent_c = c;
#endif
- }
- }
- }
- d.data = data;
+ } // if parse
+ } // for ncolors
+ } // if ncolors
#ifdef WIN32
if (transparent_c) {
make_unused_color(transparent_c[0], transparent_c[1], transparent_c[2]);
- }
- else {
+ } else {
uchar r, g, b;
make_unused_color(r, g, b);
}
#endif
-
-#ifdef __APPLE_QUARTZ__
- if (Fl_Surface_Device::surface() == Fl_Display_Device::display_device()) {
- U32 *array = new U32[d.w * d.h], *q = array;
- for (int Y = 0; Y < d.h; Y++) {
+
+ 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 < d.w; X++) {
- *q++ = d.colors[*p++];
- }
+ for (int X = 0; X < w; X++)
+ memcpy(q++, colors[*p++], 4);
} else {
- for (int X = 0; X < d.w; X++) {
- U32* colors = (U32*)d.byte1[*p++];
- *q++ = colors[*p++];
+ for (int X = 0; X < w; X++) {
+ int ind = (*p++)<<8;
+ ind |= *p++;
+ memcpy(q++, colors[ind], 4);
}
}
}
- Fl_RGB_Image* rgb = new Fl_RGB_Image((uchar*)array, d.w, d.h, 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_Surface_Device::surface() == Fl_Display_Device::display_device()) {
+ Fl_RGB_Image* rgb = new Fl_RGB_Image(buffer, w, h, 4);
rgb->draw(x, y);
delete rgb;
- delete[] array;
- }
- else {
+ } else {
#endif // __APPLE_QUARTZ__
-
// build the mask bitmap used by Fl_Pixmap:
- if (fl_mask_bitmap && transparent_index >= 0) {
- int W = (d.w+7)/8;
- uchar* bitmap = new uchar[W * d.h];
+ if (fl_mask_bitmap) {
+ int W = (w+7)/8;
+ uchar* bitmap = new uchar[W * h];
*fl_mask_bitmap = bitmap;
- for (int Y = 0; Y < d.h; Y++) {
- const uchar* p = data[Y];
- if (chars_per_pixel <= 1) {
- int dw = d.w;
- for (int X = 0; X < W; X++) {
- uchar b = (dw-->0 && *p++ != transparent_index);
- if (dw-->0 && *p++ != transparent_index) b |= 2;
- if (dw-->0 && *p++ != transparent_index) b |= 4;
- if (dw-->0 && *p++ != transparent_index) b |= 8;
- if (dw-->0 && *p++ != transparent_index) b |= 16;
- if (dw-->0 && *p++ != transparent_index) b |= 32;
- if (dw-->0 && *p++ != transparent_index) b |= 64;
- if (dw-->0 && *p++ != transparent_index) b |= 128;
- *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 {
+ const uchar *p = &buffer[3];
+ uchar b = 0;
+ for (int Y = 0; Y < h; Y++) {
+ b = 0;
+ for (int X = 0, bit = 1; X < w; X++, p += 4) {
+ if (*p > 127)
+ b |= bit;
+ bit <<= 1;
+ if (bit > 0x80 || X == w-1) {
*bitmap++ = b;
+ bit = 1;
b = 0;
- bit = 1;
}
- }
-
- if (bit > 1) *bitmap++ = b;
- }
- }
+ } // if chars_per_pixel
+ } // for Y
}
- fl_draw_image(chars_per_pixel==1 ? cb1 : cb2, &d, x, y, d.w, d.h, 4);
+ fl_draw_image(buffer, x, y, w, h, 4);
+
#ifdef __APPLE_QUARTZ__
- }
+ }
#endif
-
- if (chars_per_pixel > 1) for (int i = 0; i < 256; i++) delete[] d.byte1[i];
+ delete[] buffer;
return 1;
}
//
-// End of "$Id: fl_draw_pixmap.cxx 9375 2012-04-22 03:09:31Z fabien $".
+// End of "$Id: fl_draw_pixmap.cxx 10242 2014-08-22 10:28:50Z AlbrechtS $".
//
diff --git a/src/fl_engraved_label.cxx b/src/fl_engraved_label.cxx
index 9a95daf..c94bfb6 100644
--- a/src/fl_engraved_label.cxx
+++ b/src/fl_engraved_label.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: fl_engraved_label.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $"
+// "$Id: fl_engraved_label.cxx 10252 2014-08-23 09:22:17Z cand $"
//
// Engraved label drawing routines for the Fast Light Tool Kit (FLTK).
//
@@ -26,7 +26,7 @@
static void innards(
const Fl_Label* o, int X, int Y, int W, int H, Fl_Align align,
- int data[][3], int n)
+ const int data[][3], int n)
{
Fl_Align a1 = align;
if (a1 & FL_ALIGN_CLIP) {
@@ -42,14 +42,14 @@ static void innards(
static void fl_shadow_label(
const Fl_Label* o, int X, int Y, int W, int H, Fl_Align align)
{
- static int data[2][3] = {{2,2,FL_DARK3},{0,0,0}};
+ static const int data[2][3] = {{2,2,FL_DARK3},{0,0,0}};
innards(o, X, Y, W, H, align, data, 2);
}
static void fl_engraved_label(
const Fl_Label* o, int X, int Y, int W, int H, Fl_Align align)
{
- static int data[7][3] = {
+ static const int data[7][3] = {
{1,0,FL_LIGHT3},{1,1,FL_LIGHT3},{0,1,FL_LIGHT3},
{-1,0,FL_DARK3},{-1,-1,FL_DARK3},{0,-1,FL_DARK3},
{0,0,0}};
@@ -59,7 +59,7 @@ static void fl_engraved_label(
static void fl_embossed_label(
const Fl_Label* o, int X, int Y, int W, int H, Fl_Align align)
{
- static int data[7][3] = {
+ static const int data[7][3] = {
{-1,0,FL_LIGHT3},{-1,-1,FL_LIGHT3},{0,-1,FL_LIGHT3},
{1,0,FL_DARK3},{1,1,FL_DARK3},{0,1,FL_DARK3},
{0,0,0}};
@@ -80,5 +80,5 @@ Fl_Labeltype fl_define_FL_EMBOSSED_LABEL() {
}
//
-// End of "$Id: fl_engraved_label.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $".
+// End of "$Id: fl_engraved_label.cxx 10252 2014-08-23 09:22:17Z cand $".
//
diff --git a/src/fl_font_mac.cxx b/src/fl_font_mac.cxx
index 624c98d..dac6f81 100644
--- a/src/fl_font_mac.cxx
+++ b/src/fl_font_mac.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: fl_font_mac.cxx 9120 2011-10-03 09:22:57Z manolo $"
+// "$Id: fl_font_mac.cxx 10193 2014-06-14 11:06:42Z manolo $"
//
// MacOS font selection routines for the Fast Light Tool Kit (FLTK).
//
@@ -26,6 +26,8 @@ static CGAffineTransform font_mx = { 1, 0, 0, -1, 0, 0 };
static CFMutableDictionaryRef attributes = NULL;
#endif
+const int Fl_X::CoreText_threshold = 100500; // this represents Mac OS 10.5
+
Fl_Font_Descriptor::Fl_Font_Descriptor(const char* name, Fl_Fontsize Size) {
next = 0;
# if HAVE_GL
@@ -34,10 +36,9 @@ Fl_Font_Descriptor::Fl_Font_Descriptor(const char* name, Fl_Fontsize Size) {
// knowWidths = 0;
// OpenGL needs those for its font handling
- q_name = strdup(name);
size = Size;
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
-if (fl_mac_os_version >= 100500) {//unfortunately, CTFontCreateWithName != NULL on 10.4 also!
+if (fl_mac_os_version >= Fl_X::CoreText_threshold) {
CFStringRef str = CFStringCreateWithCString(NULL, name, kCFStringEncodingUTF8);
fontref = CTFontCreateWithName(str, size, NULL);
CGGlyph glyph[2];
@@ -88,22 +89,9 @@ else {
#if ! __LP64__
OSStatus err;
// fill our structure with a few default values
- ascent = Size*3/4;
+ ascent = Size*3/4.;
descent = Size-ascent;
- q_width = Size*2/3;
- // now use ATS to get the actual Glyph size information
- // say that our passed-in name is encoded as UTF-8, since this works for plain ASCII names too...
- CFStringRef cfname = CFStringCreateWithCString(0L, name, kCFStringEncodingUTF8);
- ATSFontRef font = ATSFontFindFromName(cfname, kATSOptionFlagsDefault);
- if (font) {
- ATSFontMetrics m = { 0 };
- ATSFontGetHorizontalMetrics(font, kATSOptionFlagsDefault, &m);
- if (m.avgAdvanceWidth) q_width = int(m.avgAdvanceWidth*Size);
- // playing with the offsets a little to make standard sizes fit
- if (m.ascent) ascent = int(m.ascent*Size-0.5f);
- if (m.descent) descent = -int(m.descent*Size-1.5f);
- }
- CFRelease(cfname);
+ q_width = Size*2/3.;
// now we allocate everything needed to render text in this font later
// get us the default layout and style
err = ATSUCreateTextLayout(&layout);
@@ -115,15 +103,15 @@ else {
// render our font up-side-down, so when rendered through our inverted CGContext,
// text will appear normal again.
Fixed fsize = IntToFixed(Size);
-// ATSUFontID fontID = FMGetFontFromATSFontRef(font);
ATSUFontID fontID;
- ATSUFindFontFromName(name, strlen(name), kFontFullName, kFontMacintoshPlatform, kFontRomanScript, kFontEnglishLanguage, &fontID);
+ ATSUFindFontFromName(name, strlen(name), kFontFullName, kFontMacintoshPlatform, kFontNoScriptCode, kFontEnglishLanguage, &fontID);
// draw the font upside-down... Compensate for fltk/OSX origin differences
ATSUAttributeTag sTag[] = { kATSUFontTag, kATSUSizeTag, kATSUFontMatrixTag };
ByteCount sBytes[] = { sizeof(ATSUFontID), sizeof(Fixed), sizeof(CGAffineTransform) };
ATSUAttributeValuePtr sAttr[] = { &fontID, &fsize, &font_mx };
- err = ATSUSetAttributes(style, 3, sTag, sBytes, sAttr);
+ if (fontID != kATSUInvalidFontID) err = ATSUSetAttributes(style, 1, sTag, sBytes, sAttr); // set the font attribute
+ err = ATSUSetAttributes(style, 2, sTag + 1, sBytes + 1, sAttr + 1); // then the size and matrix attributes
// next, make sure that Quartz will only render at integer coordinates
ATSLineLayoutOptions llo = kATSLineUseDeviceMetrics | kATSLineDisableAllLayoutOperations;
ATSUAttributeTag aTag[] = { kATSULineLayoutOptionsTag };
@@ -176,7 +164,7 @@ Fl_Font_Descriptor::~Fl_Font_Descriptor() {
*/
if (this == fl_graphics_driver->font_descriptor()) fl_graphics_driver->font_descriptor(NULL);
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
- if (fl_mac_os_version >= 100500) {
+ if (fl_mac_os_version >= Fl_X::CoreText_threshold) {
CFRelease(fontref);
for (unsigned i = 0; i < sizeof(width)/sizeof(float*); i++) {
if (width[i]) free(width[i]);
@@ -187,23 +175,44 @@ Fl_Font_Descriptor::~Fl_Font_Descriptor() {
////////////////////////////////////////////////////////////////
-static Fl_Fontdesc built_in_table[] = {
-{"Arial"},
-{"Arial Bold"},
-{"Arial Italic"},
-{"Arial Bold Italic"},
-{"Courier New"},
-{"Courier New Bold"},
-{"Courier New Italic"},
-{"Courier New Bold Italic"},
-{"Times New Roman"},
-{"Times New Roman Bold"},
-{"Times New Roman Italic"},
-{"Times New Roman Bold Italic"},
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+static Fl_Fontdesc built_in_table_PS[] = { // PostScript font names preferred when Mac OS ≥ 10.5
+{"ArialMT"},
+{"Arial-BoldMT"},
+{"Arial-ItalicMT"},
+{"Arial-BoldItalicMT"},
+{"CourierNewPSMT"},
+{"CourierNewPS-BoldMT"},
+{"CourierNewPS-ItalicMT"},
+{"CourierNewPS-BoldItalicMT"},
+{"TimesNewRomanPSMT"},
+{"TimesNewRomanPS-BoldMT"},
+{"TimesNewRomanPS-ItalicMT"},
+{"TimesNewRomanPS-BoldItalicMT"},
{"Symbol"},
{"Monaco"},
-{"Andale Mono"}, // there is no bold Monaco font on standard Mac
-{"Webdings"},
+{"AndaleMono"}, // there is no bold Monaco font on standard Mac
+{"ZapfDingbatsITC"}
+};
+#endif
+
+static Fl_Fontdesc built_in_table_full[] = { // full font names used before 10.5
+ {"Arial"},
+ {"Arial Bold"},
+ {"Arial Italic"},
+ {"Arial Bold Italic"},
+ {"Courier New"},
+ {"Courier New Bold"},
+ {"Courier New Italic"},
+ {"Courier New Bold Italic"},
+ {"Times New Roman"},
+ {"Times New Roman Bold"},
+ {"Times New Roman Italic"},
+ {"Times New Roman Bold Italic"},
+ {"Symbol"},
+ {"Monaco"},
+ {"Andale Mono"}, // there is no bold Monaco font on standard Mac
+ {"Webdings"}
};
static UniChar *utfWbuf = 0;
@@ -223,7 +232,14 @@ static UniChar *mac_Utf8_to_Utf16(const char *txt, int len, int *new_len)
return utfWbuf;
} // mac_Utf8_to_Utf16
-Fl_Fontdesc* fl_fonts = built_in_table;
+Fl_Fontdesc* Fl_X::calc_fl_fonts(void)
+{
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+ return (fl_mac_os_version >= Fl_X::CoreText_threshold ? built_in_table_PS : built_in_table_full);
+#else
+ return built_in_table_full;
+#endif
+}
static Fl_Font_Descriptor* find(Fl_Font fnum, Fl_Fontsize size) {
Fl_Fontdesc* s = fl_fonts+fnum;
@@ -287,7 +303,7 @@ static CGFloat surrogate_width(const UniChar *txt, Fl_Font_Descriptor *fl_fontsi
static double fl_mac_width(const UniChar* txt, int n, Fl_Font_Descriptor *fl_fontsize) {
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
-if (fl_mac_os_version >= 100500) {
+if (fl_mac_os_version >= Fl_X::CoreText_threshold) {
double retval = 0;
UniChar uni;
int i;
@@ -302,7 +318,7 @@ if (fl_mac_os_version >= 100500) {
// r: index of the character block containing uni
unsigned int r = uni >> 7; // change 7 if sizeof(width) is changed
if (!fl_fontsize->width[r]) { // this character block has not been hit yet
- //fprintf(stderr,"r=%d size=%d name=%s\n",r,fl_fontsize->size, fl_fontsize->q_name);
+ //fprintf(stderr,"r=%d size=%d name=%s\n",r,fl_fontsize->size,fl_fonts[fl_font()].name);
// allocate memory to hold width of each character in the block
fl_fontsize->width[r] = (float*) malloc(sizeof(float) * block);
UniChar ii = r * block;
@@ -406,7 +422,7 @@ void Fl_Quartz_Graphics_Driver::text_extents(const char *str8, int n, int &dx, i
Fl_Font_Descriptor *fl_fontsize = font_descriptor();
UniChar *txt = mac_Utf8_to_Utf16(str8, n, &n);
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
-if (fl_mac_os_version >= 100500) {
+if (fl_mac_os_version >= Fl_X::CoreText_threshold) {
CFStringRef str16 = CFStringCreateWithCharactersNoCopy(NULL, txt, n, kCFAllocatorNull);
CFDictionarySetValue (attributes, kCTFontAttributeName, fl_fontsize->fontref);
CFAttributedStringRef mastr = CFAttributedStringCreate(kCFAllocatorDefault, str16, attributes);
@@ -474,7 +490,7 @@ static void fl_mac_draw(const char *str, int n, float x, float y, Fl_Graphics_Dr
// convert to UTF-16 first
UniChar *uniStr = mac_Utf8_to_Utf16(str, n, &n);
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
- if (fl_mac_os_version >= 100500) {
+ if (fl_mac_os_version >= Fl_X::CoreText_threshold) {
CFStringRef str16 = CFStringCreateWithCharactersNoCopy(NULL, uniStr, n, kCFAllocatorNull);
if (str16 == NULL) return; // shd not happen
CGColorRef color = flcolortocgcolor(driver->color());
@@ -540,5 +556,5 @@ void Fl_Quartz_Graphics_Driver::rtl_draw(const char* c, int n, int x, int y) {
}
//
-// End of "$Id: fl_font_mac.cxx 9120 2011-10-03 09:22:57Z manolo $".
+// End of "$Id: fl_font_mac.cxx 10193 2014-06-14 11:06:42Z manolo $".
//
diff --git a/src/fl_font_win32.cxx b/src/fl_font_win32.cxx
index f526105..3970f08 100644
--- a/src/fl_font_win32.cxx
+++ b/src/fl_font_win32.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: fl_font_win32.cxx 9293 2012-03-18 18:48:29Z manolo $"
+// "$Id: fl_font_win32.cxx 10226 2014-08-19 12:36:12Z AlbrechtS $"
//
// WIN32 font selection routines for the Fast Light Tool Kit (FLTK).
//
@@ -55,7 +55,7 @@ Fl_Font_Descriptor::Fl_Font_Descriptor(const char* name, Fl_Fontsize fsize) {
// ...would be the right call, but is not implemented into Window95! (WinNT?)
//GetCharWidth(fl_gc, 0, 255, width);
int i;
- for (i = 0; i < 64; i++) width[i] = NULL;
+ memset(width, 0, 64 * sizeof(int*));
#if HAVE_GL
listbase = 0;
for (i = 0; i < 64; i++) glok[i] = 0;
@@ -77,8 +77,9 @@ Fl_Font_Descriptor::~Fl_Font_Descriptor() {
#endif
if (this == fl_graphics_driver->font_descriptor()) fl_graphics_driver->font_descriptor(NULL);
DeleteObject(fid);
- int i;
- for (i = 0; i < 64; i++) free(width[i]);
+ for (int i = 0; i < 64; i++) {
+ if ( width[i] ) free(width[i]);
+ }
}
////////////////////////////////////////////////////////////////
@@ -203,30 +204,32 @@ double Fl_GDI_Graphics_Driver::width(unsigned int c) {
r = (c & 0xFC00) >> 10;
if (!fl_fontsize->width[r]) {
fl_fontsize->width[r] = (int*) malloc(sizeof(int) * 0x0400);
- unsigned short i = 0, ii = r * 0x400;
- // The following code makes a best effort attempt to obtain a valid fl_gc.
- // If no fl_gc is available at the time we call fl_width(), then we first
- // try to obtain a gc from the first fltk window.
- // If that is null then we attempt to obtain the gc from the current screen
- // using (GetDC(NULL)).
- // This should resolve STR #2086
- HDC gc = fl_gc;
- HWND hWnd = 0;
- if (!gc) { // We have no valid gc, try and obtain one
- // Use our first fltk window, or fallback to using the screen via GetDC(NULL)
- hWnd = Fl::first_window() ? fl_xid(Fl::first_window()) : NULL;
- gc = GetDC(hWnd);
- }
- if (!gc)
- Fl::fatal("Invalid graphic context: fl_width() failed because no valid HDC was found!");
- SelectObject(gc, fl_fontsize->fid);
- for (; i < 0x400; i++) {
- GetTextExtentPoint32W(gc, (WCHAR*)&ii, 1, &s);
- fl_fontsize->width[r][i] = s.cx;
- ii++;
+ for (int i = 0; i < 0x0400; i++) fl_fontsize->width[r][i] = -1;
+ } else {
+ if ( fl_fontsize->width[r][c&0x03FF] >= 0 ) { // already cached
+ return (double) fl_fontsize->width[r][c & 0x03FF];
}
- if (gc && gc!=fl_gc) ReleaseDC(hWnd, gc);
}
+ unsigned short ii = r * 0x400;
+ // The following code makes a best effort attempt to obtain a valid fl_gc.
+ // If no fl_gc is available at the time we call fl_width(), then we first
+ // try to obtain a gc from the first fltk window.
+ // If that is null then we attempt to obtain the gc from the current screen
+ // using (GetDC(NULL)).
+ // This should resolve STR #2086
+ HDC gc = fl_gc;
+ HWND hWnd = 0;
+ if (!gc) { // We have no valid gc, try and obtain one
+ // Use our first fltk window, or fallback to using the screen via GetDC(NULL)
+ hWnd = Fl::first_window() ? fl_xid(Fl::first_window()) : NULL;
+ gc = GetDC(hWnd);
+ }
+ if (!gc) Fl::fatal("Invalid graphic context: fl_width() failed because no valid HDC was found!");
+ SelectObject(gc, fl_fontsize->fid);
+ ii += c &0x03FF;
+ GetTextExtentPoint32W(gc, (WCHAR*)&ii, 1, &s);
+ fl_fontsize->width[r][c&0x03FF] = s.cx;
+ if (gc && gc!=fl_gc) ReleaseDC(hWnd, gc);
return (double) fl_fontsize->width[r][c & 0x03FF];
}
@@ -439,5 +442,5 @@ void Fl_GDI_Graphics_Driver::rtl_draw(const char* c, int n, int x, int y) {
}
#endif
//
-// End of "$Id: fl_font_win32.cxx 9293 2012-03-18 18:48:29Z manolo $".
+// End of "$Id: fl_font_win32.cxx 10226 2014-08-19 12:36:12Z AlbrechtS $".
//
diff --git a/src/fl_font_xft.cxx b/src/fl_font_xft.cxx
index 7e4824c..1f2bbda 100644
--- a/src/fl_font_xft.cxx
+++ b/src/fl_font_xft.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: fl_font_xft.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $"
+// "$Id: fl_font_xft.cxx 10232 2014-08-21 12:13:47Z cand $"
//
// Xft font code for the Fast Light Tool Kit (FLTK).
//
@@ -101,8 +101,8 @@ Fl_Fontdesc* fl_fonts = built_in_table;
Fl_XFont_On_Demand fl_xfont;
void *fl_xftfont = 0;
-//const char* fl_encoding_ = "iso8859-1";
-const char* fl_encoding_ = "iso10646-1";
+//static const char* fl_encoding_ = "iso8859-1";
+static const char* fl_encoding_ = "iso10646-1";
static void fl_xft_font(Fl_Xlib_Graphics_Driver *driver, Fl_Font fnum, Fl_Fontsize size, int angle) {
if (fnum==-1) { // special case to stop font caching
@@ -153,7 +153,7 @@ static XftFont* fontopen(const char* name, Fl_Fontsize size, bool core, int angl
fl_open_display();
if(!is_xlfd) { // Not an XLFD - open as a XFT style name
- XftFont *the_font; // the font we will return;
+ XftFont *the_font = NULL; // the font we will return;
XftPattern *fnt_pat = XftPatternCreate(); // the pattern we will use for matching
int slant = XFT_SLANT_ROMAN;
int weight = XFT_WEIGHT_MEDIUM;
@@ -270,7 +270,10 @@ static XftFont* fontopen(const char* name, Fl_Fontsize size, bool core, int angl
free(picked_name);
#endif
- if (!match_pat) {
+ // open the matched font
+ if (match_pat) the_font = XftFontOpenPattern(fl_display, match_pat);
+
+ if (!match_pat || !the_font) {
// last chance, just open any font in the right size
the_font = XftFontOpen (fl_display, fl_screen,
XFT_FAMILY, XftTypeString, "sans",
@@ -284,9 +287,6 @@ static XftFont* fontopen(const char* name, Fl_Fontsize size, bool core, int angl
return the_font;
}
- // open the matched font
- the_font = XftFontOpenPattern(fl_display, match_pat);
-
#if 0 // diagnostic to print the "full name" of the font we actually opened. This works.
FcChar8 *picked_name2 = FcNameUnparse(the_font->pattern);
printf("Open : %s\n", picked_name2);
@@ -673,9 +673,9 @@ void Fl_Xlib_Graphics_Driver::rtl_draw(const char* c, int n, int x, int y) {
if (num_chars < n) n = num_chars; // limit drawing to usable characters in input array
FcChar32 *ucs_txt = new FcChar32[n+1];
FcChar32* pu;
- int in, out, sz;
+ int out, sz;
ucs_txt[n] = 0;
- in = 0; out = n-1;
+ out = n-1;
while ((out >= 0) && (utf_len > 0))
{
pu = &ucs_txt[out];
@@ -693,5 +693,5 @@ void Fl_Xlib_Graphics_Driver::rtl_draw(const char* c, int n, int x, int y) {
#endif
//
-// End of "$Id: fl_font_xft.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $"
+// End of "$Id: fl_font_xft.cxx 10232 2014-08-21 12:13:47Z cand $"
//
diff --git a/src/fl_gleam.cxx b/src/fl_gleam.cxx
new file mode 100644
index 0000000..b1c3bc5
--- /dev/null
+++ b/src/fl_gleam.cxx
@@ -0,0 +1,137 @@
+//
+// "$Id: fl_gleam.cxx 10143 2014-05-02 09:13:29Z ianmacarthur $"
+//
+// "Gleam" drawing routines for the Fast Light Tool Kit (FLTK).
+//
+// Copyright 1998-2010 by Bill Spitzak and others.
+//
+// This library is free software. Distribution and use rights are outlined in
+// the file "COPYING" which should have been included with this file. If this
+// file is missing or damaged, see the license at:
+//
+// http://www.fltk.org/COPYING.php
+//
+// Please report all bugs and problems on the following page:
+//
+// http://www.fltk.org/str.php
+//
+// These box types provide a sort of Clearlooks Glossy scheme
+// for FLTK.
+//
+// Copyright 2001-2005 by Colin Jones.
+//
+// Modified 2012-2013 by Edmanuel Torres
+// This is a new version of the fl_gleam. The gradients are on the top
+// an the bottom, the text area looks like in the classic FLTK way.
+//
+
+#include <FL/Fl.H>
+#include <FL/fl_draw.H>
+
+
+static void gleam_color(Fl_Color c) {
+ if (Fl::draw_box_active()) fl_color(c);
+ else fl_color(fl_inactive(c));
+}
+
+static void shade_rect_top_bottom(int x, int y, int w, int h, Fl_Color fg1, Fl_Color fg2, float th) {
+ // Draws the shiny using maximum limits
+ int h_top = ((h/2) < (20) ? (h/2) : (20)); // min(h/2,20);
+ int h_bottom = ((h/6) < (15) ? (h/6) : (15)); // min(h/6,15);
+ int h_flat = h-(h_top+h_bottom);
+ int j = 0;
+ float step_size_top = h_top>1?(0.999/(float)(h_top)):1;
+ float step_size_bottom = h_bottom>1?(0.999/(float)(h_bottom)):1;
+ // This loop generates the gradient at the top of the widget
+ for (float k = 1; k >= 0; k -= step_size_top){
+ gleam_color(fl_color_average(fl_color_average(fg1, fg2, th), fg1, k));
+ fl_line(x, y+j, x+w, y+j);
+ j++;
+ }
+ gleam_color(fg1);
+ fl_rectf(x, y+h_top, w+1, h_flat);
+ // This loop generates the gradient at the bottom of the widget
+ for (float k = 1; k >= 0; k -= step_size_bottom){
+ gleam_color(fl_color_average(fg1,fl_color_average(fg1, fg2, th), k));
+ fl_line(x, y+j+h_flat-1, x+w, y+j+h_flat-1);
+ j++;
+ }
+}
+
+static void shade_rect_top_bottom_up(int x, int y, int w, int h, Fl_Color bc, float th) {
+ shade_rect_top_bottom(x,y,w,h,bc,FL_WHITE,th);
+}
+
+static void shade_rect_top_bottom_down(int x, int y, int w, int h, Fl_Color bc, float th) {
+ shade_rect_top_bottom(x,y,w,h,bc,FL_BLACK,th);
+}
+
+static void frame_rect(int x, int y, int w, int h, Fl_Color fg1, Fl_Color fg2, Fl_Color lc) {
+ gleam_color(fg1);
+ fl_line(x, y+h-1, x, y+1); //Go from bottom to top left side
+ fl_line(x+w, y+h-1, x+w, y+1); //Go from bottom to top right side
+ fl_line(x+1, y, x+w-1, y); //Go across the top
+ fl_line(x+1, y+h, x+w-1, y+h); //Go across the bottom
+ gleam_color(fg2);
+ fl_line(x+1, y+h-2, x+1, y+2); //Go from bottom to top left side
+ fl_line(x+w-1, y+h-2, x+w-1, y+2); //Go from bottom to top right side
+ gleam_color(lc);
+ fl_line(x+2, y+1, x+w-3, y+1); //Go across the top
+ fl_line(x+2, y+h-1, x+w-3, y+h-1); //Go across the bottom
+}
+
+static void frame_rect_up(int x, int y, int w, int h, Fl_Color bc, Fl_Color lc, float th1, float th2) {
+ frame_rect(x,y,w,h,fl_color_average(fl_darker(bc), FL_BLACK, th1),fl_color_average(bc, FL_WHITE, th2),lc);
+}
+
+static void frame_rect_down(int x, int y, int w, int h, Fl_Color bc, Fl_Color lc, float th1, float th2) {
+ frame_rect(x,y,w,h,fl_color_average(bc, FL_WHITE, th1),fl_color_average(FL_BLACK, bc, th2),lc);
+}
+
+static void up_frame(int x, int y, int w, int h, Fl_Color c) {
+ frame_rect_up(x, y, w-1, h-1, c, fl_color_average(c, FL_WHITE, .25f), .55f, .05f);
+}
+
+static void up_box(int x, int y, int w, int h, Fl_Color c) {
+ shade_rect_top_bottom_up(x+2, y+1, w-5, h-3, c, .15f);
+ frame_rect_up(x, y, w-1, h-1, c, fl_color_average(c, FL_WHITE, .05f), .15f, .05f);
+}
+
+static void thin_up_box(int x, int y, int w, int h, Fl_Color c) {
+ shade_rect_top_bottom_up(x+2, y+1, w-5, h-3, c, .25f);
+ frame_rect_up(x, y, w-1, h-1, c, fl_color_average(c, FL_WHITE, .45f), .25f, .15f);
+}
+
+static void down_frame(int x, int y, int w, int h, Fl_Color c) {
+ frame_rect_down(x, y, w-1, h-1, fl_darker(c), fl_darker(c), .25f, .95f);
+}
+
+static void down_box(int x, int y, int w, int h, Fl_Color c) {
+ shade_rect_top_bottom_down(x+1, y+1, w-3, h-3, c, .65f);
+ frame_rect_down(x, y, w-1, h-1, c, fl_color_average(c, FL_BLACK, .05f), .05f, .95f);
+}
+
+static void thin_down_box(int x, int y, int w, int h, Fl_Color c) {
+ shade_rect_top_bottom_down(x+1, y+1, w-3, h-3, c, .85f);
+ frame_rect_down(x, y, w-1, h-1, c, fl_color_average(c, FL_BLACK, .45f), .35f, 0.85f);
+}
+
+extern void fl_internal_boxtype(Fl_Boxtype, Fl_Box_Draw_F*);
+
+Fl_Boxtype fl_define_FL_GLEAM_UP_BOX() {
+ fl_internal_boxtype(_FL_GLEAM_UP_BOX, up_box);
+ fl_internal_boxtype(_FL_GLEAM_DOWN_BOX, down_box);
+ fl_internal_boxtype(_FL_GLEAM_UP_FRAME, up_frame);
+ fl_internal_boxtype(_FL_GLEAM_DOWN_FRAME, down_frame);
+ fl_internal_boxtype(_FL_GLEAM_THIN_UP_BOX, thin_up_box);
+ fl_internal_boxtype(_FL_GLEAM_THIN_DOWN_BOX, thin_down_box);
+ fl_internal_boxtype(_FL_GLEAM_ROUND_UP_BOX, up_box);
+ fl_internal_boxtype(_FL_GLEAM_ROUND_DOWN_BOX, down_box);
+ return _FL_GLEAM_UP_BOX;
+}
+
+
+//
+// End of "$Id: fl_gleam.cxx 10143 2014-05-02 09:13:29Z ianmacarthur $".
+//
+
diff --git a/src/fl_gtk.cxx b/src/fl_gtk.cxx
index ce44136..ac7780d 100644
--- a/src/fl_gtk.cxx
+++ b/src/fl_gtk.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: fl_gtk.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $"
+// "$Id: fl_gtk.cxx 10232 2014-08-21 12:13:47Z cand $"
//
// "GTK" drawing routines for the Fast Light Tool Kit (FLTK).
//
@@ -203,7 +203,7 @@ static void draw(int which, int x,int y,int w,int h, int inset)
}
}
-void gtk_round_up_box(int x, int y, int w, int h, Fl_Color c) {
+static void gtk_round_up_box(int x, int y, int w, int h, Fl_Color c) {
fl_color(c);
draw(FILL, x, y, w, h, 2);
@@ -234,7 +234,7 @@ void gtk_round_up_box(int x, int y, int w, int h, Fl_Color c) {
draw(CLOSED, x, y, w, h, 0);
}
-void gtk_round_down_box(int x, int y, int w, int h, Fl_Color c) {
+static void gtk_round_down_box(int x, int y, int w, int h, Fl_Color c) {
fl_color(c);
draw(FILL, x, y, w, h, 2);
@@ -291,5 +291,5 @@ Fl_Boxtype fl_define_FL_GTK_UP_BOX() {
//
-// End of "$Id: fl_gtk.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $".
+// End of "$Id: fl_gtk.cxx 10232 2014-08-21 12:13:47Z cand $".
//
diff --git a/src/fl_open_uri.cxx b/src/fl_open_uri.cxx
index c5b7fd0..cff26b8 100644
--- a/src/fl_open_uri.cxx
+++ b/src/fl_open_uri.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: fl_open_uri.cxx 9580 2012-06-10 09:24:33Z manolo $"
+// "$Id: fl_open_uri.cxx 9995 2013-10-04 16:48:08Z greg.ercolano $"
//
// fl_open_uri() code for FLTK.
//
@@ -68,6 +68,14 @@ static int run_program(const char *program, char **argv, char *msg, int msglen);
*
* On failure, the msg buffer is filled with an English error message.
*
+ * \note
+ * \b Platform \b Specific \b Issues: \b Windows \n
+ * With "file:" based URIs on Windows, you may encounter issues with
+ * anchors being ignored. Example: "file:///c:/some/index.html#anchor"
+ * may open in the browser without the "#anchor" suffix. The behavior
+ * seems to vary across different Windows versions. Workaround: open a link
+ * to a separate html file that redirects to the desired "file:" URI.
+ *
* \b Example
* \code
* #include <FL/filename.H>
@@ -395,5 +403,5 @@ int main(int argc, char **argv) {
//
-// End of "$Id: fl_open_uri.cxx 9580 2012-06-10 09:24:33Z manolo $".
+// End of "$Id: fl_open_uri.cxx 9995 2013-10-04 16:48:08Z greg.ercolano $".
//
diff --git a/src/fl_plastic.cxx b/src/fl_plastic.cxx
index 1b1df7e..e749b54 100644
--- a/src/fl_plastic.cxx
+++ b/src/fl_plastic.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: fl_plastic.cxx 9326 2012-04-05 14:30:19Z AlbrechtS $"
+// "$Id: fl_plastic.cxx 10307 2014-09-13 17:04:20Z manolo $"
//
// "Plastic" drawing routines for the Fast Light Tool Kit (FLTK).
//
@@ -35,7 +35,7 @@
//#define USE_OLD_PLASTIC_BOX
#define USE_OLD_PLASTIC_COLOR
-extern uchar *fl_gray_ramp();
+extern const uchar *fl_gray_ramp();
inline Fl_Color shade_color(uchar gc, Fl_Color bc) {
#ifdef USE_OLD_PLASTIC_COLOR
@@ -71,7 +71,7 @@ inline Fl_Color shade_color(uchar gc, Fl_Color bc) {
static void frame_rect(int x, int y, int w, int h, const char *c, Fl_Color bc) {
- uchar *g = fl_gray_ramp();
+ const uchar *g = fl_gray_ramp();
int b = ((int) strlen(c)) / 4 + 1;
for (x += b, y += b, w -= 2 * b, h -= 2 * b; b > 1; b --)
@@ -91,7 +91,7 @@ static void frame_rect(int x, int y, int w, int h, const char *c, Fl_Color bc) {
static void frame_round(int x, int y, int w, int h, const char *c, Fl_Color bc) {
- uchar *g = fl_gray_ramp();
+ const uchar *g = fl_gray_ramp();
size_t b = strlen(c) / 4 + 1;
if (w==h) {
@@ -145,7 +145,7 @@ static void frame_round(int x, int y, int w, int h, const char *c, Fl_Color bc)
static void shade_rect(int x, int y, int w, int h, const char *c, Fl_Color bc) {
- uchar *g = fl_gray_ramp();
+ const uchar *g = fl_gray_ramp();
int i, j;
int clen = (int) strlen(c) - 1;
int chalf = clen / 2;
@@ -217,7 +217,7 @@ static void shade_rect(int x, int y, int w, int h, const char *c, Fl_Color bc) {
}
static void shade_round(int x, int y, int w, int h, const char *c, Fl_Color bc) {
- uchar *g = fl_gray_ramp();
+ const uchar *g = fl_gray_ramp();
int i;
int clen = (int) (strlen(c) - 1);
int chalf = clen / 2;
@@ -277,10 +277,10 @@ static void up_frame(int x, int y, int w, int h, Fl_Color c) {
static void narrow_thin_box(int x, int y, int w, int h, Fl_Color c) {
if (h<=0 || w<=0) return;
- uchar *g = fl_gray_ramp();
- fl_color(shade_color(g['R'], c));
+ const uchar *g = fl_gray_ramp();
+ fl_color(shade_color(g[(int)'R'], c));
fl_rectf(x+1, y+1, w-2, h-2);
- fl_color(shade_color(g['I'], c));
+ fl_color(shade_color(g[(int)'I'], c));
if (w > 1) {
fl_xyline(x+1, y, x+w-2);
fl_xyline(x+1, y+h-1, x+w-2);
@@ -368,5 +368,5 @@ Fl_Boxtype fl_define_FL_PLASTIC_UP_BOX() {
//
-// End of "$Id: fl_plastic.cxx 9326 2012-04-05 14:30:19Z AlbrechtS $".
+// End of "$Id: fl_plastic.cxx 10307 2014-09-13 17:04:20Z manolo $".
//
diff --git a/src/fl_read_image.cxx b/src/fl_read_image.cxx
index 41d5458..9a12aa0 100644
--- a/src/fl_read_image.cxx
+++ b/src/fl_read_image.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: fl_read_image.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $"
+// "$Id: fl_read_image.cxx 10388 2014-10-22 16:27:20Z manolo $"
//
// X11 image reading routines for the Fast Light Tool Kit (FLTK).
//
@@ -70,8 +70,10 @@ fl_subimage_offsets(int a, int aw, int b, int bw, int &obw)
// this handler will catch and ignore exceptions during XGetImage
// to avoid an application crash
-static int xgetimageerrhandler(Display *display, XErrorEvent *error) {
- return 0;
+extern "C" {
+ static int xgetimageerrhandler(Display *display, XErrorEvent *error) {
+ return 0;
+ }
}
//
@@ -135,7 +137,7 @@ fl_read_image(uchar *p, // I - Pixel buffer or NULL to allocate
// screen dimensions
Fl::screen_xywh(sx, sy, sw, sh, fl_screen);
}
- if (!win || (dx >= sx && dy >= sy && dx + w <= sw && dy + h <= sh)) {
+ if (!win || (dx >= sx && dy >= sy && dx + w <= sx+sw && dy + h <= sy+sh)) {
// the image is fully contained, we can use the traditional method
// however, if the window is obscured etc. the function will still fail. Make sure we
// catch the error and continue, otherwise an exception will be thrown.
@@ -496,5 +498,5 @@ fl_read_image(uchar *p, // I - Pixel buffer or NULL to allocate
#endif
//
-// End of "$Id: fl_read_image.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $".
+// End of "$Id: fl_read_image.cxx 10388 2014-10-22 16:27:20Z manolo $".
//
diff --git a/src/fl_read_image_mac.cxx b/src/fl_read_image_mac.cxx
index ae2963f..d9a20df 100644
--- a/src/fl_read_image_mac.cxx
+++ b/src/fl_read_image_mac.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: fl_read_image_mac.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $"
+// "$Id: fl_read_image_mac.cxx 10078 2014-01-22 20:39:21Z manolo $"
//
// WIN32 image reading routines for the Fast Light Tool Kit (FLTK).
//
@@ -45,6 +45,7 @@ fl_read_image(uchar *p, // I - Pixel buffer or NULL to allocate
Fl_Window *window = Fl_Window::current();
while(window->window()) window = window->window();
base = Fl_X::bitmap_from_window_rect(window,x,y,w,h,&delta);
+ if (!base) return NULL;
rowBytes = delta*w;
x = y = 0;
}
@@ -69,5 +70,5 @@ fl_read_image(uchar *p, // I - Pixel buffer or NULL to allocate
//
-// End of "$Id: fl_read_image_mac.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $".
+// End of "$Id: fl_read_image_mac.cxx 10078 2014-01-22 20:39:21Z manolo $".
//
diff --git a/src/fl_rect.cxx b/src/fl_rect.cxx
index e63ca13..d96b35f 100644
--- a/src/fl_rect.cxx
+++ b/src/fl_rect.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: fl_rect.cxx 9293 2012-03-18 18:48:29Z manolo $"
+// "$Id: fl_rect.cxx 10401 2014-10-28 13:44:09Z manolo $"
//
// Rectangle drawing routines for the Fast Light Tool Kit (FLTK).
//
@@ -188,7 +188,7 @@ void Fl_Graphics_Driver::rectf(int x, int y, int w, int h) {
rect.right = x + w; rect.bottom = y + h;
FillRect(fl_gc, &rect, fl_brush());
#elif defined(__APPLE_QUARTZ__)
- CGRect rect = CGRectMake(x, y, w - 0.9 , h - 0.9);
+ CGRect rect = CGRectMake(x - 0.5, y - 0.5, w , h);
CGContextFillRect(fl_gc, rect);
#else
# error unsupported platform
@@ -708,5 +708,5 @@ int Fl_Graphics_Driver::clip_box(int x, int y, int w, int h, int& X, int& Y, int
}
//
-// End of "$Id: fl_rect.cxx 9293 2012-03-18 18:48:29Z manolo $".
+// End of "$Id: fl_rect.cxx 10401 2014-10-28 13:44:09Z manolo $".
//
diff --git a/src/fl_round_box.cxx b/src/fl_round_box.cxx
index e143e0b..eb0b31a 100644
--- a/src/fl_round_box.cxx
+++ b/src/fl_round_box.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: fl_round_box.cxx 9211 2011-12-21 12:01:50Z AlbrechtS $"
+// "$Id: fl_round_box.cxx 10307 2014-09-13 17:04:20Z manolo $"
//
// Round box drawing routines for the Fast Light Tool Kit (FLTK).
//
@@ -71,34 +71,34 @@ static void draw(int which, int x,int y,int w,int h, int inset, Fl_Color color)
}
}
-extern uchar* fl_gray_ramp();
+extern const uchar* fl_gray_ramp();
void fl_round_down_box(int x, int y, int w, int h, Fl_Color bgcolor) {
- uchar *g = fl_gray_ramp();
+ const uchar *g = fl_gray_ramp();
draw(FILL, x, y, w, h, 2, bgcolor);
- draw(UPPER_LEFT, x+1, y, w-2, h, 0, (Fl_Color)g['N']);
- draw(UPPER_LEFT, x+1, y, w-2, h, 1, (Fl_Color)g['H']);
- draw(UPPER_LEFT, x, y, w, h, 0, (Fl_Color)g['N']);
- draw(UPPER_LEFT, x, y, w, h, 1, (Fl_Color)g['H']);
- draw(LOWER_RIGHT, x, y, w, h, 0, (Fl_Color)g['S']);
- draw(LOWER_RIGHT, x+1, y, w-2, h, 0, (Fl_Color)g['U']);
- draw(LOWER_RIGHT, x, y, w, h, 1, (Fl_Color)g['U']);
- draw(LOWER_RIGHT, x+1, y, w-2, h, 1, (Fl_Color)g['W']);
- draw(CLOSED, x, y, w, h, 2, (Fl_Color)g['A']);
+ draw(UPPER_LEFT, x+1, y, w-2, h, 0, (Fl_Color)g[(int)'N']);
+ draw(UPPER_LEFT, x+1, y, w-2, h, 1, (Fl_Color)g[(int)'H']);
+ draw(UPPER_LEFT, x, y, w, h, 0, (Fl_Color)g[(int)'N']);
+ draw(UPPER_LEFT, x, y, w, h, 1, (Fl_Color)g[(int)'H']);
+ draw(LOWER_RIGHT, x, y, w, h, 0, (Fl_Color)g[(int)'S']);
+ draw(LOWER_RIGHT, x+1, y, w-2, h, 0, (Fl_Color)g[(int)'U']);
+ draw(LOWER_RIGHT, x, y, w, h, 1, (Fl_Color)g[(int)'U']);
+ draw(LOWER_RIGHT, x+1, y, w-2, h, 1, (Fl_Color)g[(int)'W']);
+ draw(CLOSED, x, y, w, h, 2, (Fl_Color)g[(int)'A']);
}
void fl_round_up_box(int x, int y, int w, int h, Fl_Color bgcolor) {
- uchar *g = fl_gray_ramp();
+ const uchar *g = fl_gray_ramp();
draw(FILL, x, y, w, h, 2, bgcolor);
- draw(LOWER_RIGHT, x+1, y, w-2, h, 0, (Fl_Color)g['H']);
- draw(LOWER_RIGHT, x+1, y, w-2, h, 1, (Fl_Color)g['N']);
- draw(LOWER_RIGHT, x, y, w, h, 1, (Fl_Color)g['H']);
- draw(LOWER_RIGHT, x, y, w, h, 2, (Fl_Color)g['N']);
- draw(UPPER_LEFT, x, y, w, h, 2, (Fl_Color)g['U']);
- draw(UPPER_LEFT, x+1, y, w-2, h, 1, (Fl_Color)g['S']);
- draw(UPPER_LEFT, x, y, w, h, 1, (Fl_Color)g['W']);
- draw(UPPER_LEFT, x+1, y, w-2, h, 0, (Fl_Color)g['U']);
- draw(CLOSED, x, y, w, h, 0, (Fl_Color)g['A']);
+ draw(LOWER_RIGHT, x+1, y, w-2, h, 0, (Fl_Color)g[(int)'H']);
+ draw(LOWER_RIGHT, x+1, y, w-2, h, 1, (Fl_Color)g[(int)'N']);
+ draw(LOWER_RIGHT, x, y, w, h, 1, (Fl_Color)g[(int)'H']);
+ draw(LOWER_RIGHT, x, y, w, h, 2, (Fl_Color)g[(int)'N']);
+ draw(UPPER_LEFT, x, y, w, h, 2, (Fl_Color)g[(int)'U']);
+ draw(UPPER_LEFT, x+1, y, w-2, h, 1, (Fl_Color)g[(int)'S']);
+ draw(UPPER_LEFT, x, y, w, h, 1, (Fl_Color)g[(int)'W']);
+ draw(UPPER_LEFT, x+1, y, w-2, h, 0, (Fl_Color)g[(int)'U']);
+ draw(CLOSED, x, y, w, h, 0, (Fl_Color)g[(int)'A']);
}
extern void fl_internal_boxtype(Fl_Boxtype, Fl_Box_Draw_F*);
@@ -109,5 +109,5 @@ Fl_Boxtype fl_define_FL_ROUND_UP_BOX() {
}
//
-// End of "$Id: fl_round_box.cxx 9211 2011-12-21 12:01:50Z AlbrechtS $".
+// End of "$Id: fl_round_box.cxx 10307 2014-09-13 17:04:20Z manolo $".
//
diff --git a/src/fl_scroll_area.cxx b/src/fl_scroll_area.cxx
index 99d0640..a694da2 100644
--- a/src/fl_scroll_area.cxx
+++ b/src/fl_scroll_area.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: fl_scroll_area.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $"
+// "$Id: fl_scroll_area.cxx 10078 2014-01-22 20:39:21Z manolo $"
//
// Scrolling routines for the Fast Light Tool Kit (FLTK).
//
@@ -143,11 +143,13 @@ void fl_scroll(int X, int Y, int W, int H, int dx, int dy,
#elif defined(__APPLE_QUARTZ__)
CGImageRef img = Fl_X::CGImage_from_window_rect(Fl_Window::current(), src_x, src_y, src_w, src_h);
- CGRect rect = { { dest_x, dest_y }, { src_w, src_h } };
- Fl_X::q_begin_image(rect, 0, 0, src_w, src_h);
- CGContextDrawImage(fl_gc, rect, img);
- Fl_X::q_end_image();
- CFRelease(img);
+ if (img) {
+ CGRect rect = { { dest_x, dest_y }, { src_w, src_h } };
+ Fl_X::q_begin_image(rect, 0, 0, src_w, src_h);
+ CGContextDrawImage(fl_gc, rect, img);
+ Fl_X::q_end_image();
+ CFRelease(img);
+ }
#else
# error unsupported platform
#endif
@@ -156,5 +158,5 @@ void fl_scroll(int X, int Y, int W, int H, int dx, int dy,
}
//
-// End of "$Id: fl_scroll_area.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $".
+// End of "$Id: fl_scroll_area.cxx 10078 2014-01-22 20:39:21Z manolo $".
//
diff --git a/src/fl_set_fonts_mac.cxx b/src/fl_set_fonts_mac.cxx
index 43a5fcb..81f4207 100644
--- a/src/fl_set_fonts_mac.cxx
+++ b/src/fl_set_fonts_mac.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: fl_set_fonts_mac.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $"
+// "$Id: fl_set_fonts_mac.cxx 10014 2013-10-30 13:36:16Z manolo $"
//
// MacOS font utilities for the Fast Light Tool Kit (FLTK).
//
@@ -20,27 +20,35 @@
// #inclde <SFNTTypes.h>
-// This function fills in the fltk font table with all the fonts that
-// are found on the X server. It tries to place the fonts into families
-// and to sort them so the first 4 in a family are normal, bold, italic,
-// and bold italic.
// Bug: older versions calculated the value for *ap as a side effect of
// making the name, and then forgot about it. To avoid having to change
// the header files I decided to store this value in the last character
// of the font name array.
-#define ENDOFBUFFER 127 // sizeof(Fl_Font.fontname)-1
+#define ENDOFBUFFER sizeof(fl_fonts->fontname)-1
// turn a stored font name into a pretty name:
const char* Fl::get_font_name(Fl_Font fnum, int* ap) {
Fl_Fontdesc *f = fl_fonts + fnum;
if (!f->fontname[0]) {
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+ if (fl_mac_os_version >= Fl_X::CoreText_threshold) {
+ CFStringRef cfname = CFStringCreateWithCString(NULL, f->name, kCFStringEncodingUTF8);
+ CTFontRef ctfont = CTFontCreateWithName(cfname, 0, NULL);
+ CFRelease(cfname);
+ cfname = CTFontCopyFullName(ctfont);
+ CFRelease(ctfont);
+ CFStringGetCString(cfname, f->fontname, ENDOFBUFFER, kCFStringEncodingUTF8);
+ CFRelease(cfname);
+ }
+ else
+#endif
+ strlcpy(f->fontname, f->name, ENDOFBUFFER);
const char* p = f->name;
if (!p || !*p) {if (ap) *ap = 0; return "";}
- strlcpy(f->fontname, p, ENDOFBUFFER);
int type = 0;
if (strstr(f->name, "Bold")) type |= FL_BOLD;
- if (strstr(f->name, "Italic")) type |= FL_ITALIC;
+ if (strstr(f->name, "Italic") || strstr(f->name, "Oblique")) type |= FL_ITALIC;
f->fontname[ENDOFBUFFER] = (char)type;
}
if (ap) *ap = f->fontname[ENDOFBUFFER];
@@ -48,21 +56,55 @@ const char* Fl::get_font_name(Fl_Font fnum, int* ap) {
}
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
+
+static char *skip(char *p, int& derived)
+{
+ if (memcmp(p, "-BoldItalic", 11) == 0) { p += 11; derived = 3; }
+ else if (memcmp(p, "-BoldOblique", 12) == 0) { p += 12; derived = 3; }
+ else if (memcmp(p, "-Bold", 5) == 0) {p += 5; derived = 1; }
+ else if (memcmp(p, "-Italic", 7) == 0) {p += 7; derived = 2; }
+ else if (memcmp(p, "-Oblique", 8) == 0) {p += 8; derived = 2; }
+ else if (memcmp(p, "-Regular", 8) == 0) {p += 8; }
+ else if (memcmp(p, "-Roman", 6) == 0) {p += 6; }
+ return p;
+}
+
static int name_compare(const void *a, const void *b)
{
- return strcmp(*(char**)a, *(char**)b);
+ /* Compare PostScript font names.
+ First compare font family names ignoring bold, italic and oblique qualifiers.
+ When families are identical, order them according to regular, bold, italic, bolditalic.
+ */
+ char *n1 = *(char**)a;
+ char *n2 = *(char**)b;
+ int derived1 = 0;
+ int derived2 = 0;
+ while (true) {
+ if (*n1 == '-') n1 = skip(n1, derived1);
+ if (*n2 == '-') n2 = skip(n2, derived2);
+ if (*n1 < *n2) return -1;
+ if (*n1 > *n2) return +1;
+ if (*n1 == 0) {
+ return derived1 - derived2;
+ }
+ n1++; n2++;
+ }
}
#endif
static int fl_free_font = FL_FREE_FONT;
+// This function fills in the fltk font table with all the fonts that
+// are found on the X server. It tries to place the fonts into families
+// and to sort them so the first 4 in a family are normal, bold, italic,
+// and bold italic.
+
Fl_Font Fl::set_fonts(const char* xstarname) {
#pragma unused ( xstarname )
if (fl_free_font > FL_FREE_FONT) return (Fl_Font)fl_free_font; // if already called
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5
-if(fl_mac_os_version >= 100500) {
-//if(CTFontCreateWithFontDescriptor != NULL) {// CTFontCreateWithFontDescriptor != NULL on 10.4 also!
+if(fl_mac_os_version >= Fl_X::CoreText_threshold) {
int value[1] = {1};
CFDictionaryRef dict = CFDictionaryCreate(NULL,
(const void **)kCTFontCollectionRemoveDuplicatesOption,
@@ -77,9 +119,9 @@ if(fl_mac_os_version >= 100500) {
for (i = 0; i < count; i++) {
CTFontDescriptorRef fdesc = (CTFontDescriptorRef)CFArrayGetValueAtIndex(arrayref, i);
CTFontRef font = CTFontCreateWithFontDescriptor(fdesc, 0., NULL);
- CFStringRef cfname = CTFontCopyFullName(font);
+ CFStringRef cfname = CTFontCopyPostScriptName(font);
CFRelease(font);
- static char fname[100];
+ static char fname[200];
CFStringGetCString(cfname, fname, sizeof(fname), kCFStringEncodingUTF8);
tabfontnames[i] = strdup(fname); // never free'ed
CFRelease(cfname);
@@ -151,5 +193,5 @@ int Fl::get_font_sizes(Fl_Font fnum, int*& sizep) {
}
//
-// End of "$Id: fl_set_fonts_mac.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $".
+// End of "$Id: fl_set_fonts_mac.cxx 10014 2013-10-30 13:36:16Z manolo $".
//
diff --git a/src/fl_set_fonts_xft.cxx b/src/fl_set_fonts_xft.cxx
index dbaf1b9..87dfeed 100644
--- a/src/fl_set_fonts_xft.cxx
+++ b/src/fl_set_fonts_xft.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: fl_set_fonts_xft.cxx 9396 2012-04-24 03:52:00Z fabien $"
+// "$Id: fl_set_fonts_xft.cxx 10041 2014-01-03 16:17:05Z AlbrechtS $"
//
// More font utilities for the Fast Light Tool Kit (FLTK).
//
@@ -29,7 +29,7 @@
// of the font name array.
#define ENDOFBUFFER 127 // sizeof(Fl_Font.fontname)-1
-// turn a stored font name into a pretty name:
+// turn a stored font name in "fltk format" into a pretty name:
const char* Fl::get_font_name(Fl_Font fnum, int* ap) {
Fl_Fontdesc *f = fl_fonts + fnum;
if (!f->fontname[0]) {
@@ -82,7 +82,6 @@ static void make_raw_name(char *raw, char *pretty)
// italic, bold, bold italic or normal - this seems to be the fltk way...
char *style = strchr(pretty, ':');
- char *last = style + strlen(style) - 2;
if (style)
{
@@ -102,12 +101,16 @@ static void make_raw_name(char *raw, char *pretty)
nm2 = strchr(nm1, ',');
}
raw[0] = ' '; raw[1] = 0; // Default start of "raw name" text
- strncat(raw, nm1, LOCAL_RAW_NAME_MAX);
+ strncat(raw, nm1, LOCAL_RAW_NAME_MAX-1); // only copy MAX-1 chars, we have already set cell 0
+ // Ensure raw is terminated, just in case the given name is infeasibly long...
+ raw[LOCAL_RAW_NAME_MAX-1] = 0;
#else // keep the first remaining name entry
char *nm2 = strchr(pretty, ',');
if(nm2) *nm2 = 0; // terminate name after first entry
raw[0] = ' '; raw[1] = 0; // Default start of "raw name" text
- strncat(raw, pretty, LOCAL_RAW_NAME_MAX-1);
+ strncat(raw, pretty, LOCAL_RAW_NAME_MAX-1); // only copy MAX-1 chars, we have already set cell 0
+ // Ensure raw is terminated, just in case the given name is infeasibly long...
+ raw[LOCAL_RAW_NAME_MAX-1] = 0;
#endif
// At this point, the name is "marked" as regular...
if (style)
@@ -116,7 +119,10 @@ static void make_raw_name(char *raw, char *pretty)
#define BOLD 1
#define ITALIC 2
#define BITALIC (BOLD | ITALIC)
+
int mods = PLAIN;
+ char *last = style + strlen(style) - 2;
+
// Now try and parse the style string - look for the "=" sign
style = strchr(style, '=');
while ((style) && (style < last))
@@ -153,14 +159,14 @@ static void make_raw_name(char *raw, char *pretty)
mods |= ITALIC;
}
goto NEXT_STYLE;
-
- case 's':
+
+ case 'S':
if (strncasecmp(style, "SuperBold", 9) == 0)
{
mods |= BOLD;
}
goto NEXT_STYLE;
-
+
default: // find the next gap
goto NEXT_STYLE;
} // switch end
@@ -202,17 +208,17 @@ Fl_Font Fl::set_fonts(const char* pattern_name)
{
FcFontSet *fnt_set; // Will hold the list of fonts we find
FcPattern *fnt_pattern; // Holds the generic "match all names" pattern
- FcObjectSet *fnt_obj_set = 0; // Holds the generic "match all objects"
-
+ FcObjectSet *fnt_obj_set = 0; // Holds the generic "match all objects"
+
int j; // loop iterator variable
int font_count; // Total number of fonts found to process
char **full_list; // The list of font names we build
if (fl_free_font > FL_FREE_FONT) // already been here
return (Fl_Font)fl_free_font;
-
+
fl_open_display(); // Just in case...
-
+
// Make sure fontconfig is ready... is this necessary? The docs say it is
// safe to call it multiple times, so just go for it anyway!
if (!FcInit())
@@ -228,10 +234,10 @@ Fl_Font Fl::set_fonts(const char* pattern_name)
// "pattern_name"?
fnt_pattern = FcPatternCreate();
fnt_obj_set = FcObjectSetBuild(FC_FAMILY, FC_STYLE, (void *)0);
-
+
// Hopefully, this is a set of all the fonts...
fnt_set = FcFontList(0, fnt_pattern, fnt_obj_set);
-
+
// We don't need the fnt_pattern and fnt_obj_set any more, release them
FcPatternDestroy(fnt_pattern);
FcObjectSetDestroy(fnt_obj_set);
@@ -242,22 +248,22 @@ Fl_Font Fl::set_fonts(const char* pattern_name)
char *stop;
char *start;
char *first;
-
+
font_count = fnt_set->nfont; // How many fonts?
-
+
// Allocate array of char*'s to hold the name strings
full_list = (char **)malloc(sizeof(char *) * font_count);
-
+
// iterate through all the font patterns and get the names out...
for (j = 0; j < font_count; j++)
{
// NOTE: FcChar8 is a typedef of "unsigned char"...
FcChar8 *font; // String to hold the font's name
-
+
// Convert from fontconfig internal pattern to human readable name
// NOTE: This WILL malloc storage, so we need to free it later...
font = FcNameUnparse(fnt_set->fonts[j]);
-
+
// The returned strings look like this...
// Century Schoolbook:style=Bold Italic,fed kursiv,Fett Kursiv,...
// So the bit we want is up to the first comma - BUT some strings have
@@ -300,13 +306,13 @@ Fl_Font Fl::set_fonts(const char* pattern_name)
if (reg) reg[1]='.';
}
}
-
+
// Release the fnt_set - we don't need it any more
FcFontSetDestroy(fnt_set);
-
+
// Sort the list into alphabetic order
qsort(full_list, font_count, sizeof(*full_list), name_sort);
-
+
// Now let us add the names we got to fltk's font list...
for (j = 0; j < font_count; j++)
{
@@ -321,7 +327,7 @@ Fl_Font Fl::set_fonts(const char* pattern_name)
stored_name = strdup(xft_name);
Fl::set_font((Fl_Font)(j + FL_FREE_FONT), stored_name);
fl_free_font ++;
-
+
free(full_list[j]); // release that name from our internal array
}
}
@@ -374,5 +380,5 @@ int Fl::get_font_sizes(Fl_Font fnum, int*& sizep) {
}
//
-// End of "$Id: fl_set_fonts_xft.cxx 9396 2012-04-24 03:52:00Z fabien $".
+// End of "$Id: fl_set_fonts_xft.cxx 10041 2014-01-03 16:17:05Z AlbrechtS $".
//
diff --git a/src/fl_shortcut.cxx b/src/fl_shortcut.cxx
index 4c91c6e..28e59a9 100644
--- a/src/fl_shortcut.cxx
+++ b/src/fl_shortcut.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: fl_shortcut.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $"
+// "$Id: fl_shortcut.cxx 10250 2014-08-23 09:10:50Z cand $"
//
// Shortcut support routines for the Fast Light Tool Kit (FLTK).
//
@@ -179,7 +179,7 @@ const char* fl_shortcut_label(unsigned int shortcut) {
\see fl_shortcut_label(unsigned int shortcut)
*/
const char* fl_shortcut_label(unsigned int shortcut, const char **eom) {
- static char buf[20];
+ static char buf[40];
char *p = buf;
if (eom) *eom = p;
if (!shortcut) {*p = 0; return buf;}
@@ -189,11 +189,11 @@ const char* fl_shortcut_label(unsigned int shortcut, const char **eom) {
shortcut |= FL_SHIFT;
}
#ifdef __APPLE__
- // this column contains utf8 characters - v
- if (shortcut & FL_SHIFT) {strcpy(p,"\xe2\x87\xa7"); p += 3;} // upwards white arrow
- if (shortcut & FL_CTRL) {strcpy(p,"\xe2\x8c\x83"); p += 3;} // up arrowhead
- if (shortcut & FL_ALT) {strcpy(p,"\xe2\x8c\xa5"); p += 3;} // alternative key symbol
- if (shortcut & FL_META) {strcpy(p,"\xe2\x8c\x98"); p += 3;} // place of interest sign
+ // this column contains utf8 characters - v
+ if (shortcut & FL_SHIFT) {strcpy(p,"\xe2\x87\xa7"); p += 3;} // U+21E7 (upwards white arrow)
+ if (shortcut & FL_CTRL) {strcpy(p,"\xe2\x8c\x83"); p += 3;} // U+2303 (up arrowhead)
+ if (shortcut & FL_ALT) {strcpy(p,"\xe2\x8c\xa5"); p += 3;} // U+2325 (option key)
+ if (shortcut & FL_META) {strcpy(p,"\xe2\x8c\x98"); p += 3;} // U+2318 (place of interest sign)
#else
if (shortcut & FL_META) {strcpy(p,"Meta+"); p += 5;}
if (shortcut & FL_ALT) {strcpy(p,"Alt+"); p += 4;}
@@ -270,14 +270,73 @@ const char* fl_shortcut_label(unsigned int shortcut, const char **eom) {
# - Alt
+ - Shift
^ - Control
+ ! - Meta
+ @ - Command (Ctrl on linux/win, Meta on OSX)
\endverbatim
+
+ These special characters can be combined to form chords of modifier
+ keys. (See 'Remarks' below)
+
+ After the optional modifier key prefixes listed above, one can either
+ specify a single keyboard character to use as the shortcut, or a
+ numeric sequence in hex, decimal or octal.
+
+ Examples:
+ \verbatim
+ "c" -- Uses 'c' as the shortcut
+ "#^c" -- Same as FL_ALT|FL_CTRL|'c'
+ "#^!c" -- Same as FL_ALT|FL_CTRL|FL_META|'c'
+ "@c" -- Same as FL_COMMAND|'c' (see FL_COMMAND for platform specific behavior)
+ "0x63" -- Same as "c" (hex 63=='c')
+ "99" -- Same as "c" (dec 99=='c')
+ "0143" -- Same as "c" (octal 0143=='c')
+ "^0x63" -- Same as (FL_CTRL|'c'), or (FL_CTRL|0x63)
+ "^99" -- Same as (FL_CTRL|'c'), or (FL_CTRL|99)
+ "^0143" -- Same as (FL_CTRL|'c'), or (FL_CTRL|0143)
+ \endverbatim
+
+ \remarks
+ Due to XForms legacy, there are some odd things to consider
+ when using the modifier characters.
+ \remarks
+ (1) You can use the special modifier keys for chords *only*
+ if the modifiers are provided in this order: #, +, ^, !, \@.
+ Other ordering can yield undefined results.
+ \remarks
+ So for instance, Ctrl-Alt-c must be specified as "#^c" (and not
+ "^#c"), due to the above ordering rule.
+ \remarks
+ (2) If you want to make a shortcut that uses one of the special
+ modifier characters (as the character being modified), then to
+ avoid confusion, specify the numeric equivalent, e.g.
+ \remarks
+ \verbatim
+ If you want.. Then use..
+ ----------------------------- ------------------------------
+ '#' as the shortcut.. "0x23" (instead of just "#").
+ '+' as the shortcut.. "0x2b" (instead of just "+").
+ '^' as the shortcut.. "0x5e" (instead of just "^").
+ Alt-+ as the shortcut.. "#0x2b" (instead of "#+").
+ Alt-^ as the shortcut.. "#0x5e" (instead of "#^").
+ ..etc..
+ \endverbatim
+ \remarks
+ As a general rule that's easy to remember, unless the shortcut
+ key to be modified is a single alpha-numeric character [A-Z,a-z,0-9),
+ it's probably best to use the numeric equivalents.
+
+ \todo Fix these silly legacy issues in a future release
+ to support more predictable behavior for the modifier keys.
*/
unsigned int fl_old_shortcut(const char* s) {
if (!s || !*s) return 0;
+ if (s[1]==0 && strchr("@!",s[0])) return s[0]; // maintain legacy behavior for "!" and "@"
unsigned int n = 0;
if (*s == '#') {n |= FL_ALT; s++;}
if (*s == '+') {n |= FL_SHIFT; s++;}
if (*s == '^') {n |= FL_CTRL; s++;}
+ if (*s == '!') {n |= FL_META; s++;} // added in 1.3.3
+ if (*s == '@') {n |= FL_COMMAND; s++;} // added in 1.3.3
if (*s && s[1]) return n | (int)strtol(s,0,0); // allow 0xf00 to get any key
return n | *s;
}
@@ -373,5 +432,5 @@ int Fl_Widget::test_shortcut() {
}
//
-// End of "$Id: fl_shortcut.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $".
+// End of "$Id: fl_shortcut.cxx 10250 2014-08-23 09:10:50Z cand $".
//
diff --git a/src/fl_utf8.cxx b/src/fl_utf8.cxx
index 857642f..8ad2f3b 100644
--- a/src/fl_utf8.cxx
+++ b/src/fl_utf8.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: fl_utf8.cxx 9704 2012-10-19 11:23:51Z manolo $"
+// "$Id: fl_utf8.cxx 10248 2014-08-23 08:41:58Z cand $"
//
// Unicode to UTF-8 conversion functions.
//
@@ -58,7 +58,7 @@ extern "C" {
#else // X-windows platform
-# include <FL/Xutf8.h>
+# include "Xutf8.h"
# include <sys/types.h>
# include <sys/stat.h>
# include <fcntl.h>
@@ -609,7 +609,7 @@ int fl_execvp(const char *file, char *const *argv)
return _execvp(fl_utf2mbcs(file), argv);
#else
size_t l = strlen(file);
- int i, n, ret;
+ int i, n;
xchar **ar;
// wbuf = (xchar*)realloc(wbuf, sizeof(xchar) * (l+1));
// wbuf[fl_utf2unicode((const unsigned char*)file, l, wbuf)] = 0;
@@ -634,14 +634,14 @@ int fl_execvp(const char *file, char *const *argv)
i++;
}
ar[n] = NULL;
- ret = _wexecvp(wbuf, ar);
+ _wexecvp(wbuf, ar); // STR #3040
i = 0;
while (i <= n) {
free(ar[i]);
i++;
}
free(ar);
- return ret;
+ return -1; // STR #3040
#endif
#else
return execvp(file, argv);
@@ -825,5 +825,5 @@ void fl_make_path_for_file( const char *path )
/** @} */
//
-// End of "$Id: fl_utf8.cxx 9704 2012-10-19 11:23:51Z manolo $".
+// End of "$Id: fl_utf8.cxx 10248 2014-08-23 08:41:58Z cand $".
//
diff --git a/src/flstring.h b/src/flstring.h
index cc0e1ee..2c6aff4 100644
--- a/src/flstring.h
+++ b/src/flstring.h
@@ -1,5 +1,5 @@
/*
- * "$Id: flstring.h 9573 2012-06-06 03:38:02Z fabien $"
+ * "$Id: flstring.h 10074 2014-01-21 11:07:43Z AlbrechtS $"
*
* Common string header file for the Fast Light Tool Kit (FLTK).
*
@@ -39,7 +39,7 @@
# undef index
# endif /* index */
-# if defined(WIN32) && !defined(__CYGWIN__)
+# if defined(WIN32) && !defined(__CYGWIN__) && !defined(__MINGW32__)
# define strcasecmp(s,t) _stricmp((s), (t))
# define strncasecmp(s,t,n) _strnicmp((s), (t), (n))
/* Visual C++ 2005 incorrectly displays a warning about the use of POSIX APIs
@@ -97,5 +97,5 @@ FL_EXPORT extern int fl_ascii_strcasecmp(const char *s, const char *t);
#endif /* !flstring_h */
/*
- * End of "$Id: flstring.h 9573 2012-06-06 03:38:02Z fabien $".
+ * End of "$Id: flstring.h 10074 2014-01-21 11:07:43Z AlbrechtS $".
*/
diff --git a/src/forms_timer.cxx b/src/forms_timer.cxx
index 6fad755..6b66eeb 100644
--- a/src/forms_timer.cxx
+++ b/src/forms_timer.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: forms_timer.cxx 9325 2012-04-05 05:12:30Z fabien $"
+// "$Id: forms_timer.cxx 10413 2014-10-30 09:16:49Z cand $"
//
// Forms timer object for the Fast Light Tool Kit (FLTK).
//
@@ -23,6 +23,7 @@
#include <FL/Fl.H>
#include <FL/Fl_Timer.H>
#include <FL/fl_draw.H>
+#include <FL/forms.H>
#ifdef WIN32
# ifdef __MWERKS__
# include <time.h>
@@ -173,5 +174,5 @@ void Fl_Timer::suspended(char d) {
}
//
-// End of "$Id: forms_timer.cxx 9325 2012-04-05 05:12:30Z fabien $".
+// End of "$Id: forms_timer.cxx 10413 2014-10-30 09:16:49Z cand $".
//
diff --git a/src/gl_draw.cxx b/src/gl_draw.cxx
index 2bc8c7b..5f78902 100644
--- a/src/gl_draw.cxx
+++ b/src/gl_draw.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: gl_draw.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $"
+// "$Id: gl_draw.cxx 10414 2014-10-30 09:18:45Z cand $"
//
// OpenGL drawing support routines for the Fast Light Tool Kit (FLTK).
//
@@ -24,6 +24,7 @@
#include <FL/Fl.H>
#include <FL/gl.h>
+#include <FL/gl_draw.H>
#include <FL/x.H>
#include <FL/fl_draw.H>
#include <FL/Fl_Device.H>
@@ -32,7 +33,7 @@
#include <FL/fl_utf8.h>
#if !defined(WIN32) && !defined(__APPLE__)
-#include <FL/Xutf8.h>
+#include "Xutf8.h"
#endif
#if USE_XFT
@@ -101,8 +102,9 @@ void gl_font(int fontid, int size) {
//http://developer.apple.com/mac/library/documentation/Carbon/Conceptual/Carbon64BitGuide/OtherAPIChanges/OtherAPIChanges.html
short font, face, size;
uchar fn[256];
- fn[0]=strlen(fl_fontsize->q_name);
- strcpy((char*)(fn+1), fl_fontsize->q_name);
+ const char *pname = Fl::get_font_name(fontid, NULL);
+ fn[0]=strlen(pname);
+ strcpy((char*)(fn+1), pname);
GetFNum(fn, &font);
face = 0;
size = fl_fontsize->size;
@@ -472,6 +474,7 @@ int gl_texture_fifo::compute_texture(const char* str, int n)
CGColorSpaceRef lut = CGColorSpaceCreateDeviceRGB();
void *base = calloc(4*fifo[current].width, fifo[current].height);
if (base == NULL) return -1;
+ CGContextRef save_gc = fl_gc;
fl_gc = CGBitmapContextCreate(base, fifo[current].width, fifo[current].height, 8, fifo[current].width*4, lut, kCGImageAlphaPremultipliedLast);
CGColorSpaceRelease(lut);
fl_graphics_driver->font_descriptor(gl_fontsize);
@@ -487,7 +490,7 @@ int gl_texture_fifo::compute_texture(const char* str, int n)
glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, 0, GL_RGBA, fifo[current].width, fifo[current].height, 0, GL_RGBA, GL_UNSIGNED_BYTE, base);
glPopAttrib();
CGContextRelease(fl_gc);
- fl_gc = NULL;
+ fl_gc = save_gc;
free(base);
fifo[current].fdesc = gl_fontsize;
return current;
@@ -567,5 +570,5 @@ void gl_texture_reset()
#endif // HAVE_GL
//
-// End of "$Id: gl_draw.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $".
+// End of "$Id: gl_draw.cxx 10414 2014-10-30 09:18:45Z cand $".
//
diff --git a/src/gl_start.cxx b/src/gl_start.cxx
index 515d95c..416b3f6 100644
--- a/src/gl_start.cxx
+++ b/src/gl_start.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: gl_start.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $"
+// "$Id: gl_start.cxx 10414 2014-10-30 09:18:45Z cand $"
//
// OpenGL context routines for the Fast Light Tool Kit (FLTK).
//
@@ -35,6 +35,7 @@
#include <FL/Fl_Window.H>
#include <FL/x.H>
#include <FL/fl_draw.H>
+#include <FL/gl.h>
#include "Fl_Gl_Choice.H"
static GLContext context;
@@ -119,5 +120,5 @@ int Fl::gl_visual(int mode, int *alist) {
#endif
//
-// End of "$Id: gl_start.cxx 8864 2011-07-19 04:49:30Z greg.ercolano $".
+// End of "$Id: gl_start.cxx 10414 2014-10-30 09:18:45Z cand $".
//
diff --git a/src/makedepend b/src/makedepend
index 74c05fb..32d5ff0 100644
--- a/src/makedepend
+++ b/src/makedepend
@@ -1,98 +1,102 @@
-# DO NOT DELETE THIS LINE -- make depend depends on it.
+# DO NOT DELETE
Fl.o: ../config.h ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H
-Fl.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Window.H
-Fl.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Tooltip.H ../FL/Fl_Widget.H
-Fl.o: ../FL/x.H ../FL/Fl_Window.H flstring.h ../FL/Fl_Export.H
-Fl.o: ../FL/fl_draw.H ../FL/Enumerations.H ../FL/Fl_Device.H
-Fl.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
-Fl.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Pixmap.H
+Fl.o: ../FL/fl_types.h ../FL/Enumerations.H ../FL/Fl_Window.H
+Fl.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H
+Fl.o: ../FL/Fl_Tooltip.H ../FL/Fl_Widget.H ../FL/x.H ../FL/Fl_Window.H
+Fl.o: flstring.h ../FL/Fl_Export.H ../FL/fl_draw.H ../FL/Enumerations.H
+Fl.o: ../FL/Fl_Device.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H
+Fl.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H
Fl.o: ../FL/Fl_RGB_Image.H
Fl_Adjuster.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
-Fl_Adjuster.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Adjuster.H
-Fl_Adjuster.o: ../FL/Fl_Valuator.H ../FL/Fl_Widget.H ../FL/Fl_Bitmap.H
-Fl_Adjuster.o: ../FL/Fl_Image.H ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H
-Fl_Adjuster.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Group.H
+Fl_Adjuster.o: ../FL/Enumerations.H ../FL/Fl_Adjuster.H ../FL/Fl_Valuator.H
+Fl_Adjuster.o: ../FL/Fl_Widget.H ../FL/Fl_Bitmap.H ../FL/fl_draw.H ../FL/x.H
+Fl_Adjuster.o: ../FL/Fl_Window.H ../FL/Enumerations.H ../FL/Fl_Window.H
+Fl_Adjuster.o: ../FL/Fl_Group.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H
Fl_Adjuster.o: ../FL/Fl_Device.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H
Fl_Adjuster.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
Fl_Adjuster.o: fastarrow.h mediumarrow.h slowarrow.h
Fl_Bitmap.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
-Fl_Bitmap.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/x.H ../FL/Fl_Window.H
-Fl_Bitmap.o: ../FL/fl_draw.H ../FL/Enumerations.H ../FL/Fl_Window.H
-Fl_Bitmap.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Device.H
-Fl_Bitmap.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
-Fl_Bitmap.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Pixmap.H
+Fl_Bitmap.o: ../FL/Enumerations.H ../FL/x.H ../FL/Fl_Window.H ../FL/fl_draw.H
+Fl_Bitmap.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Group.H
+Fl_Bitmap.o: ../FL/Fl_Widget.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H
+Fl_Bitmap.o: ../FL/Fl_Device.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H
+Fl_Bitmap.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H
Fl_Bitmap.o: ../FL/Fl_RGB_Image.H ../FL/Fl_Widget.H ../FL/Fl_Menu_Item.H
Fl_Bitmap.o: ../FL/Fl_Printer.H ../FL/Fl_Paged_Device.H ../FL/Fl_PostScript.H
Fl_Bitmap.o: flstring.h ../FL/Fl_Export.H ../config.h
Fl_Browser.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
-Fl_Browser.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Browser.H
-Fl_Browser.o: ../FL/Fl_Browser_.H ../FL/Fl_Group.H ../FL/Fl_Widget.H
-Fl_Browser.o: ../FL/Fl_Scrollbar.H ../FL/Fl_Slider.H ../FL/Fl_Valuator.H
-Fl_Browser.o: ../FL/Fl_Image.H ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H
-Fl_Browser.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Device.H
-Fl_Browser.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
-Fl_Browser.o: ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
-Fl_Browser.o: flstring.h ../FL/Fl_Export.H ../config.h
+Fl_Browser.o: ../FL/Enumerations.H ../FL/Fl_Browser.H ../FL/Fl_Browser_.H
+Fl_Browser.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Scrollbar.H
+Fl_Browser.o: ../FL/Fl_Slider.H ../FL/Fl_Valuator.H ../FL/Fl_Image.H
+Fl_Browser.o: ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H
+Fl_Browser.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Bitmap.H
+Fl_Browser.o: ../FL/Fl_Device.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H
+Fl_Browser.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H
+Fl_Browser.o: ../FL/Fl_RGB_Image.H flstring.h ../FL/Fl_Export.H ../config.h
+Fl_Browser.o: ../FL/Fl_Hold_Browser.H ../FL/Fl_Browser.H
+Fl_Browser.o: ../FL/Fl_Multi_Browser.H ../FL/Fl_Select_Browser.H
Fl_Browser_.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
-Fl_Browser_.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Widget.H
-Fl_Browser_.o: ../FL/Fl_Browser_.H ../FL/Fl_Group.H ../FL/Fl_Widget.H
-Fl_Browser_.o: ../FL/Fl_Scrollbar.H ../FL/Fl_Slider.H ../FL/Fl_Valuator.H
-Fl_Browser_.o: ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H
-Fl_Browser_.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Device.H
-Fl_Browser_.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
-Fl_Browser_.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Pixmap.H
+Fl_Browser_.o: ../FL/Enumerations.H ../FL/Fl_Widget.H ../FL/Fl_Browser_.H
+Fl_Browser_.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Scrollbar.H
+Fl_Browser_.o: ../FL/Fl_Slider.H ../FL/Fl_Valuator.H ../FL/fl_draw.H
+Fl_Browser_.o: ../FL/x.H ../FL/Fl_Window.H ../FL/Enumerations.H
+Fl_Browser_.o: ../FL/Fl_Window.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H
+Fl_Browser_.o: ../FL/Fl_Device.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H
+Fl_Browser_.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H
Fl_Browser_.o: ../FL/Fl_RGB_Image.H
Fl_Browser_load.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H
-Fl_Browser_load.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H
-Fl_Browser_load.o: ../FL/Fl_Browser.H ../FL/Fl_Browser_.H ../FL/Fl_Group.H
-Fl_Browser_load.o: ../FL/Fl_Widget.H ../FL/Fl_Scrollbar.H ../FL/Fl_Slider.H
-Fl_Browser_load.o: ../FL/Fl_Valuator.H ../FL/Fl_Image.H ../FL/fl_utf8.h
+Fl_Browser_load.o: ../FL/fl_types.h ../FL/Enumerations.H ../FL/Fl_Browser.H
+Fl_Browser_load.o: ../FL/Fl_Browser_.H ../FL/Fl_Group.H ../FL/Fl_Widget.H
+Fl_Browser_load.o: ../FL/Fl_Scrollbar.H ../FL/Fl_Slider.H ../FL/Fl_Valuator.H
+Fl_Browser_load.o: ../FL/Fl_Image.H ../FL/fl_utf8.h
Fl_Box.o: ../FL/Fl_Widget.H ../FL/Fl_Box.H ../FL/Fl_Widget.H
Fl_Box.o: ../FL/Enumerations.H ../FL/Fl_Export.H ../FL/fl_types.h
Fl_Button.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
-Fl_Button.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Button.H
-Fl_Button.o: ../FL/Fl_Widget.H ../FL/Fl_Group.H ../FL/Fl_Window.H
-Fl_Button.o: ../FL/Fl_Group.H
+Fl_Button.o: ../FL/Enumerations.H ../FL/Fl_Button.H ../FL/Fl_Widget.H
+Fl_Button.o: ../FL/Fl_Group.H ../FL/Fl_Window.H ../FL/Fl_Group.H
+Fl_Button.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Radio_Button.H
+Fl_Button.o: ../FL/Fl_Button.H ../FL/Fl_Toggle_Button.H
Fl_Chart.o: ../FL/math.h ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H
-Fl_Chart.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H
-Fl_Chart.o: ../FL/Fl_Chart.H ../FL/Fl_Widget.H ../FL/fl_draw.H ../FL/x.H
-Fl_Chart.o: ../FL/Fl_Window.H ../FL/Enumerations.H ../FL/Fl_Window.H
-Fl_Chart.o: ../FL/Fl_Group.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
-Fl_Chart.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
-Fl_Chart.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
+Fl_Chart.o: ../FL/fl_types.h ../FL/Enumerations.H ../FL/Fl_Chart.H
+Fl_Chart.o: ../FL/Fl_Widget.H ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H
+Fl_Chart.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Group.H
+Fl_Chart.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Device.H
+Fl_Chart.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
+Fl_Chart.o: ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
Fl_Chart.o: flstring.h ../FL/Fl_Export.H ../config.h
Fl_Check_Browser.o: flstring.h ../FL/Fl_Export.H ../config.h ../FL/fl_draw.H
Fl_Check_Browser.o: ../FL/x.H ../FL/Enumerations.H ../FL/Fl_Export.H
-Fl_Check_Browser.o: ../FL/fl_types.h ../FL/Fl_Window.H ../FL/Xutf8.h
-Fl_Check_Browser.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Group.H
-Fl_Check_Browser.o: ../FL/Fl_Widget.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
-Fl_Check_Browser.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
-Fl_Check_Browser.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
+Fl_Check_Browser.o: ../FL/fl_types.h ../FL/Fl_Window.H ../FL/Enumerations.H
+Fl_Check_Browser.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Widget.H
+Fl_Check_Browser.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Device.H
+Fl_Check_Browser.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
+Fl_Check_Browser.o: ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
Fl_Check_Browser.o: ../FL/Fl_Check_Browser.H ../FL/Fl.H ../FL/fl_utf8.h
Fl_Check_Browser.o: ../FL/Fl_Browser_.H ../FL/Fl_Scrollbar.H
Fl_Check_Browser.o: ../FL/Fl_Slider.H ../FL/Fl_Valuator.H ../FL/Fl.H
Fl_Check_Button.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H
-Fl_Check_Button.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H
+Fl_Check_Button.o: ../FL/fl_types.h ../FL/Enumerations.H
Fl_Check_Button.o: ../FL/Fl_Check_Button.H ../FL/Fl_Light_Button.H
-Fl_Check_Button.o: ../FL/Fl_Button.H ../FL/Fl_Widget.H
+Fl_Check_Button.o: ../FL/Fl_Button.H
Fl_Choice.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
-Fl_Choice.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Choice.H
-Fl_Choice.o: ../FL/Fl_Menu_.H ../FL/Fl_Widget.H ../FL/Fl_Menu_Item.H
-Fl_Choice.o: ../FL/Fl_Image.H ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H
-Fl_Choice.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Group.H
+Fl_Choice.o: ../FL/Enumerations.H ../FL/Fl_Choice.H ../FL/Fl_Menu_.H
+Fl_Choice.o: ../FL/Fl_Widget.H ../FL/Fl_Menu_Item.H ../FL/Fl_Image.H
+Fl_Choice.o: ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H ../FL/Enumerations.H
+Fl_Choice.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Bitmap.H
Fl_Choice.o: ../FL/Fl_Device.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H
Fl_Choice.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H
Fl_Choice.o: ../FL/Fl_RGB_Image.H flstring.h ../FL/Fl_Export.H ../config.h
Fl_Clock.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
-Fl_Clock.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Clock.H
-Fl_Clock.o: ../FL/Fl_Widget.H ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H
-Fl_Clock.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Group.H
+Fl_Clock.o: ../FL/Enumerations.H ../FL/Fl_Clock.H ../FL/Fl_Widget.H
+Fl_Clock.o: ../FL/Fl_Round_Clock.H ../FL/Fl_Clock.H ../FL/fl_draw.H ../FL/x.H
+Fl_Clock.o: ../FL/Fl_Window.H ../FL/Enumerations.H ../FL/Fl_Window.H
+Fl_Clock.o: ../FL/Fl_Group.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H
Fl_Clock.o: ../FL/Fl_Device.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H
-Fl_Clock.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H
-Fl_Clock.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
+Fl_Clock.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H
+Fl_Clock.o: ../FL/Fl_RGB_Image.H
Fl_Color_Chooser.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H
-Fl_Color_Chooser.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H
+Fl_Color_Chooser.o: ../FL/fl_types.h ../FL/Enumerations.H
Fl_Color_Chooser.o: ../FL/Fl_Color_Chooser.H ../FL/Fl_Group.H ../FL/Fl_Box.H
Fl_Color_Chooser.o: ../FL/Fl_Widget.H ../FL/Fl_Return_Button.H
Fl_Color_Chooser.o: ../FL/Fl_Button.H ../FL/Fl_Choice.H ../FL/Fl_Menu_.H
@@ -100,210 +104,238 @@ Fl_Color_Chooser.o: ../FL/Fl_Menu_Item.H ../FL/Fl_Image.H
Fl_Color_Chooser.o: ../FL/Fl_Value_Input.H ../FL/Fl_Valuator.H
Fl_Color_Chooser.o: ../FL/Fl_Input.H ../FL/Fl_Input_.H ../FL/fl_draw.H
Fl_Color_Chooser.o: ../FL/x.H ../FL/Fl_Window.H ../FL/Enumerations.H
-Fl_Color_Chooser.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Device.H
-Fl_Color_Chooser.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
-Fl_Color_Chooser.o: ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
-Fl_Color_Chooser.o: ../FL/math.h
+Fl_Color_Chooser.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Bitmap.H
+Fl_Color_Chooser.o: ../FL/Fl_Device.H ../FL/Fl_Plugin.H
+Fl_Color_Chooser.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
+Fl_Color_Chooser.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H ../FL/math.h
+Fl_Copy_Surface.o: ../FL/Fl_Copy_Surface.H ../FL/Fl_Paged_Device.H
+Fl_Copy_Surface.o: ../FL/Fl_Device.H ../FL/x.H ../FL/Enumerations.H
+Fl_Copy_Surface.o: ../FL/Fl_Export.H ../FL/fl_types.h ../FL/Fl_Window.H
+Fl_Copy_Surface.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
+Fl_Copy_Surface.o: ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H ../FL/Fl_Image.H
+Fl_Copy_Surface.o: ../FL/Fl_RGB_Image.H ../FL/Fl_Window.H ../FL/Fl_Group.H
+Fl_Copy_Surface.o: ../FL/Fl_Widget.H ../FL/Fl_Bitmap.H ../FL/Fl_Printer.H
+Fl_Copy_Surface.o: ../FL/fl_draw.H ../FL/Enumerations.H ../FL/Fl_PostScript.H
+Fl_Copy_Surface.o: ../FL/Fl.H ../FL/fl_utf8.h
Fl_Counter.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
-Fl_Counter.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Counter.H
-Fl_Counter.o: ../FL/Fl_Valuator.H ../FL/Fl_Widget.H ../FL/fl_draw.H ../FL/x.H
-Fl_Counter.o: ../FL/Fl_Window.H ../FL/Enumerations.H ../FL/Fl_Window.H
-Fl_Counter.o: ../FL/Fl_Group.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
-Fl_Counter.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
-Fl_Counter.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
+Fl_Counter.o: ../FL/Enumerations.H ../FL/Fl_Counter.H ../FL/Fl_Valuator.H
+Fl_Counter.o: ../FL/Fl_Widget.H ../FL/Fl_Simple_Counter.H ../FL/Fl_Counter.H
+Fl_Counter.o: ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H
+Fl_Counter.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Group.H
+Fl_Counter.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Device.H
+Fl_Counter.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
+Fl_Counter.o: ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
Fl_Dial.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
-Fl_Dial.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Dial.H
-Fl_Dial.o: ../FL/Fl_Valuator.H ../FL/Fl_Widget.H ../FL/fl_draw.H ../FL/x.H
-Fl_Dial.o: ../FL/Fl_Window.H ../FL/Enumerations.H ../FL/Fl_Window.H
-Fl_Dial.o: ../FL/Fl_Group.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
-Fl_Dial.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
-Fl_Dial.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
+Fl_Dial.o: ../FL/Enumerations.H ../FL/Fl_Dial.H ../FL/Fl_Valuator.H
+Fl_Dial.o: ../FL/Fl_Widget.H ../FL/Fl_Fill_Dial.H ../FL/Fl_Dial.H
+Fl_Dial.o: ../FL/Fl_Line_Dial.H ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H
+Fl_Dial.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Group.H
+Fl_Dial.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Device.H
+Fl_Dial.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
+Fl_Dial.o: ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
Fl_Dial.o: ../FL/math.h
Fl_Device.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
-Fl_Device.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Device.H ../FL/x.H
+Fl_Device.o: ../FL/Enumerations.H ../FL/Fl_Device.H ../FL/x.H
Fl_Device.o: ../FL/Fl_Window.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H
-Fl_Device.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H
-Fl_Device.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
+Fl_Device.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H
+Fl_Device.o: ../FL/Fl_Image.H ../FL/Fl_RGB_Image.H
Fl_Double_Window.o: ../config.h ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H
-Fl_Double_Window.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H
+Fl_Double_Window.o: ../FL/fl_types.h ../FL/Enumerations.H
Fl_Double_Window.o: ../FL/Fl_Double_Window.H ../FL/Fl_Window.H
+Fl_Double_Window.o: ../FL/Fl_Overlay_Window.H ../FL/Fl_Double_Window.H
Fl_Double_Window.o: ../FL/Fl_Printer.H ../FL/x.H ../FL/Fl_Paged_Device.H
Fl_Double_Window.o: ../FL/Fl_Device.H ../FL/Fl_Plugin.H
Fl_Double_Window.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
-Fl_Double_Window.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
+Fl_Double_Window.o: ../FL/Fl_Pixmap.H ../FL/Fl_Image.H ../FL/Fl_RGB_Image.H
Fl_Double_Window.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Widget.H
-Fl_Double_Window.o: ../FL/fl_draw.H ../FL/Enumerations.H
+Fl_Double_Window.o: ../FL/Fl_Bitmap.H ../FL/fl_draw.H ../FL/Enumerations.H
Fl_Double_Window.o: ../FL/Fl_PostScript.H
Fl_File_Browser.o: ../FL/Fl_File_Browser.H ../FL/Fl_Browser.H
-Fl_File_Browser.o: ../FL/Fl_Browser_.H ../FL/Fl_Group.H ../FL/Fl_Widget.H
-Fl_File_Browser.o: ../FL/Enumerations.H ../FL/Fl_Export.H ../FL/fl_types.h
-Fl_File_Browser.o: ../FL/Fl_Scrollbar.H ../FL/Fl_Slider.H ../FL/Fl_Valuator.H
-Fl_File_Browser.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Xutf8.h ../FL/Fl_Image.H
-Fl_File_Browser.o: ../FL/Fl_File_Icon.H ../FL/Fl.H ../FL/filename.H
-Fl_File_Browser.o: ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H
-Fl_File_Browser.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Device.H
-Fl_File_Browser.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
-Fl_File_Browser.o: ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
-Fl_File_Browser.o: ../FL/filename.H flstring.h ../FL/Fl_Export.H ../config.h
+Fl_File_Browser.o: ../FL/Fl_File_Icon.H ../FL/Fl.H ../FL/fl_utf8.h
+Fl_File_Browser.o: ../FL/Fl_Export.H ../FL/fl_types.h ../FL/Enumerations.H
+Fl_File_Browser.o: ../FL/filename.H ../FL/fl_draw.H ../FL/x.H
+Fl_File_Browser.o: ../FL/Fl_Window.H ../FL/Enumerations.H ../FL/Fl_Window.H
+Fl_File_Browser.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Bitmap.H
+Fl_File_Browser.o: ../FL/Fl_Image.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
+Fl_File_Browser.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
+Fl_File_Browser.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H ../FL/filename.H
+Fl_File_Browser.o: flstring.h ../FL/Fl_Export.H ../config.h
Fl_File_Chooser.o: ../FL/Fl_File_Chooser.H ../FL/Fl.H ../FL/fl_utf8.h
-Fl_File_Chooser.o: ../FL/Fl_Export.H ../FL/fl_types.h ../FL/Xutf8.h
-Fl_File_Chooser.o: ../FL/Enumerations.H ../FL/Fl_Double_Window.H
-Fl_File_Chooser.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Choice.H
-Fl_File_Chooser.o: ../FL/Fl_Menu_.H ../FL/Fl_Widget.H ../FL/Fl_Menu_Item.H
-Fl_File_Chooser.o: ../FL/Fl_Image.H ../FL/Fl_Menu_Button.H ../FL/Fl_Button.H
+Fl_File_Chooser.o: ../FL/Fl_Export.H ../FL/fl_types.h ../FL/Enumerations.H
+Fl_File_Chooser.o: ../FL/Fl_Double_Window.H ../FL/Fl_Window.H
+Fl_File_Chooser.o: ../FL/Fl_Group.H ../FL/Fl_Choice.H ../FL/Fl_Menu_.H
+Fl_File_Chooser.o: ../FL/Fl_Widget.H ../FL/Fl_Menu_Item.H ../FL/Fl_Image.H
+Fl_File_Chooser.o: ../FL/Fl_Menu_Button.H ../FL/Fl_Button.H
Fl_File_Chooser.o: ../FL/Fl_Preferences.H ../FL/Fl_Tile.H ../FL/Fl_Group.H
Fl_File_Chooser.o: ../FL/Fl_File_Browser.H ../FL/Fl_Browser.H
-Fl_File_Chooser.o: ../FL/Fl_Browser_.H ../FL/Fl_Scrollbar.H ../FL/Fl_Slider.H
-Fl_File_Chooser.o: ../FL/Fl_Valuator.H ../FL/Fl_File_Icon.H ../FL/Fl.H
-Fl_File_Chooser.o: ../FL/filename.H ../FL/Fl_Box.H ../FL/Fl_Check_Button.H
+Fl_File_Chooser.o: ../FL/Fl_File_Icon.H ../FL/Fl.H ../FL/filename.H
+Fl_File_Chooser.o: ../FL/Fl_Box.H ../FL/Fl_Check_Button.H
Fl_File_Chooser.o: ../FL/Fl_Light_Button.H ../FL/Fl_Button.H
Fl_File_Chooser.o: ../FL/Fl_File_Input.H ../FL/Fl_Input.H ../FL/Fl_Input_.H
Fl_File_Chooser.o: ../FL/Fl_Return_Button.H ../FL/fl_ask.H ../FL/fl_draw.H
Fl_File_Chooser.o: ../FL/x.H ../FL/Enumerations.H ../FL/Fl_Window.H
-Fl_File_Chooser.o: ../FL/Fl_Device.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H
-Fl_File_Chooser.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H
-Fl_File_Chooser.o: ../FL/Fl_RGB_Image.H
+Fl_File_Chooser.o: ../FL/Fl_Bitmap.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
+Fl_File_Chooser.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
+Fl_File_Chooser.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
Fl_File_Chooser2.o: ../FL/Fl_File_Chooser.H ../FL/Fl.H ../FL/fl_utf8.h
-Fl_File_Chooser2.o: ../FL/Fl_Export.H ../FL/fl_types.h ../FL/Xutf8.h
-Fl_File_Chooser2.o: ../FL/Enumerations.H ../FL/Fl_Double_Window.H
-Fl_File_Chooser2.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Choice.H
-Fl_File_Chooser2.o: ../FL/Fl_Menu_.H ../FL/Fl_Widget.H ../FL/Fl_Menu_Item.H
-Fl_File_Chooser2.o: ../FL/Fl_Image.H ../FL/Fl_Menu_Button.H ../FL/Fl_Button.H
+Fl_File_Chooser2.o: ../FL/Fl_Export.H ../FL/fl_types.h ../FL/Enumerations.H
+Fl_File_Chooser2.o: ../FL/Fl_Double_Window.H ../FL/Fl_Window.H
+Fl_File_Chooser2.o: ../FL/Fl_Group.H ../FL/Fl_Choice.H ../FL/Fl_Menu_.H
+Fl_File_Chooser2.o: ../FL/Fl_Widget.H ../FL/Fl_Menu_Item.H ../FL/Fl_Image.H
+Fl_File_Chooser2.o: ../FL/Fl_Menu_Button.H ../FL/Fl_Button.H
Fl_File_Chooser2.o: ../FL/Fl_Preferences.H ../FL/Fl_Tile.H ../FL/Fl_Group.H
Fl_File_Chooser2.o: ../FL/Fl_File_Browser.H ../FL/Fl_Browser.H
-Fl_File_Chooser2.o: ../FL/Fl_Browser_.H ../FL/Fl_Scrollbar.H
-Fl_File_Chooser2.o: ../FL/Fl_Slider.H ../FL/Fl_Valuator.H
Fl_File_Chooser2.o: ../FL/Fl_File_Icon.H ../FL/Fl.H ../FL/filename.H
Fl_File_Chooser2.o: ../FL/Fl_Box.H ../FL/Fl_Check_Button.H
Fl_File_Chooser2.o: ../FL/Fl_Light_Button.H ../FL/Fl_Button.H
Fl_File_Chooser2.o: ../FL/Fl_File_Input.H ../FL/Fl_Input.H ../FL/Fl_Input_.H
Fl_File_Chooser2.o: ../FL/Fl_Return_Button.H ../FL/fl_ask.H ../FL/filename.H
Fl_File_Chooser2.o: ../FL/x.H ../FL/Fl_Shared_Image.H ../FL/fl_draw.H
-Fl_File_Chooser2.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Device.H
-Fl_File_Chooser2.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
-Fl_File_Chooser2.o: ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
-Fl_File_Chooser2.o: flstring.h ../FL/Fl_Export.H ../config.h
+Fl_File_Chooser2.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Bitmap.H
+Fl_File_Chooser2.o: ../FL/Fl_Device.H ../FL/Fl_Plugin.H
+Fl_File_Chooser2.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
+Fl_File_Chooser2.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H flstring.h
+Fl_File_Chooser2.o: ../FL/Fl_Export.H ../config.h
Fl_File_Icon.o: ../FL/fl_utf8.h flstring.h ../FL/Fl_Export.H ../config.h
Fl_File_Icon.o: ../FL/Fl_File_Icon.H ../FL/Fl.H ../FL/fl_utf8.h
-Fl_File_Icon.o: ../FL/Fl_Export.H ../FL/fl_types.h ../FL/Xutf8.h
-Fl_File_Icon.o: ../FL/Enumerations.H ../FL/Fl_Widget.H ../FL/fl_draw.H
-Fl_File_Icon.o: ../FL/x.H ../FL/Fl_Window.H ../FL/Enumerations.H
-Fl_File_Icon.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Widget.H
+Fl_File_Icon.o: ../FL/Fl_Export.H ../FL/fl_types.h ../FL/Enumerations.H
+Fl_File_Icon.o: ../FL/Fl_Widget.H ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H
+Fl_File_Icon.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Group.H
+Fl_File_Icon.o: ../FL/Fl_Widget.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H
Fl_File_Icon.o: ../FL/Fl_Device.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H
-Fl_File_Icon.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H
-Fl_File_Icon.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H ../FL/filename.H
+Fl_File_Icon.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H
+Fl_File_Icon.o: ../FL/Fl_RGB_Image.H ../FL/filename.H
Fl_File_Input.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H
-Fl_File_Input.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H
-Fl_File_Input.o: ../FL/Fl_File_Input.H ../FL/Fl_Input.H ../FL/Fl_Input_.H
-Fl_File_Input.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Widget.H
-Fl_File_Input.o: ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H
+Fl_File_Input.o: ../FL/fl_types.h ../FL/Enumerations.H ../FL/Fl_File_Input.H
+Fl_File_Input.o: ../FL/Fl_Input.H ../FL/Fl_Input_.H ../FL/Fl_Window.H
+Fl_File_Input.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Bitmap.H
+Fl_File_Input.o: ../FL/Fl_Image.H ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H
Fl_File_Input.o: ../FL/Enumerations.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
Fl_File_Input.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
-Fl_File_Input.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
-Fl_File_Input.o: ../FL/filename.H flstring.h ../FL/Fl_Export.H ../config.h
+Fl_File_Input.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H ../FL/filename.H
+Fl_File_Input.o: flstring.h ../FL/Fl_Export.H ../config.h
Fl_Group.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
-Fl_Group.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Group.H
-Fl_Group.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Widget.H
-Fl_Group.o: ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H ../FL/Enumerations.H
-Fl_Group.o: ../FL/Fl_Device.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H
-Fl_Group.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H
-Fl_Group.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
+Fl_Group.o: ../FL/Enumerations.H ../FL/Fl_Group.H ../FL/Fl_Window.H
+Fl_Group.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Bitmap.H
+Fl_Group.o: ../FL/Fl_Image.H ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H
+Fl_Group.o: ../FL/Enumerations.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
+Fl_Group.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
+Fl_Group.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H ../FL/Fl_Input_Choice.H
+Fl_Group.o: ../FL/Fl_Input.H ../FL/Fl_Input_.H ../FL/Fl_Menu_Button.H
+Fl_Group.o: ../FL/Fl_Menu_.H ../FL/Fl_Menu_Item.H ../FL/Fl_Spinner.H
+Fl_Group.o: ../FL/Fl_Repeat_Button.H ../FL/Fl.H ../FL/Fl_Button.H
Fl_Help_View.o: ../FL/Fl_Help_View.H ../FL/Fl.H ../FL/fl_utf8.h
-Fl_Help_View.o: ../FL/Fl_Export.H ../FL/fl_types.h ../FL/Xutf8.h
-Fl_Help_View.o: ../FL/Enumerations.H ../FL/Fl_Group.H ../FL/Fl_Widget.H
-Fl_Help_View.o: ../FL/Fl_Scrollbar.H ../FL/Fl_Slider.H ../FL/Fl_Valuator.H
-Fl_Help_View.o: ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H
-Fl_Help_View.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Device.H
-Fl_Help_View.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
-Fl_Help_View.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Pixmap.H
+Fl_Help_View.o: ../FL/Fl_Export.H ../FL/fl_types.h ../FL/Enumerations.H
+Fl_Help_View.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Scrollbar.H
+Fl_Help_View.o: ../FL/Fl_Slider.H ../FL/Fl_Valuator.H ../FL/fl_draw.H
+Fl_Help_View.o: ../FL/x.H ../FL/Fl_Window.H ../FL/Enumerations.H
+Fl_Help_View.o: ../FL/Fl_Window.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H
+Fl_Help_View.o: ../FL/Fl_Device.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H
+Fl_Help_View.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H
Fl_Help_View.o: ../FL/Fl_RGB_Image.H ../FL/Fl_Shared_Image.H ../FL/filename.H
Fl_Help_View.o: ../FL/fl_utf8.h ../FL/filename.H flstring.h ../FL/Fl_Export.H
Fl_Help_View.o: ../config.h
Fl_Image.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
-Fl_Image.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/fl_draw.H ../FL/x.H
-Fl_Image.o: ../FL/Fl_Window.H ../FL/Enumerations.H ../FL/Fl_Window.H
-Fl_Image.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Device.H
-Fl_Image.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
-Fl_Image.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Pixmap.H
+Fl_Image.o: ../FL/Enumerations.H ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H
+Fl_Image.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Group.H
+Fl_Image.o: ../FL/Fl_Widget.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H
+Fl_Image.o: ../FL/Fl_Device.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H
+Fl_Image.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H
Fl_Image.o: ../FL/Fl_RGB_Image.H ../FL/Fl_Widget.H ../FL/Fl_Menu_Item.H
Fl_Image.o: flstring.h ../FL/Fl_Export.H ../config.h
+Fl_Image_Surface.o: ../FL/Fl_Image_Surface.H ../FL/Fl_Copy_Surface.H
+Fl_Image_Surface.o: ../FL/Fl_Paged_Device.H ../FL/Fl_Device.H ../FL/x.H
+Fl_Image_Surface.o: ../FL/Enumerations.H ../FL/Fl_Export.H ../FL/fl_types.h
+Fl_Image_Surface.o: ../FL/Fl_Window.H ../FL/Fl_Plugin.H
+Fl_Image_Surface.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
+Fl_Image_Surface.o: ../FL/Fl_Pixmap.H ../FL/Fl_Image.H ../FL/Fl_RGB_Image.H
+Fl_Image_Surface.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Widget.H
+Fl_Image_Surface.o: ../FL/Fl_Bitmap.H ../FL/Fl_Printer.H ../FL/fl_draw.H
+Fl_Image_Surface.o: ../FL/Enumerations.H ../FL/Fl_PostScript.H ../FL/Fl.H
+Fl_Image_Surface.o: ../FL/fl_utf8.h
Fl_Input.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
-Fl_Input.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Window.H
-Fl_Input.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Input.H
-Fl_Input.o: ../FL/Fl_Input_.H ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H
-Fl_Input.o: ../FL/Enumerations.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
-Fl_Input.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
-Fl_Input.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
+Fl_Input.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Group.H
+Fl_Input.o: ../FL/Fl_Widget.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H
+Fl_Input.o: ../FL/Fl_Input.H ../FL/Fl_Input_.H ../FL/fl_draw.H ../FL/x.H
+Fl_Input.o: ../FL/Fl_Window.H ../FL/Enumerations.H ../FL/Fl_Device.H
+Fl_Input.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
+Fl_Input.o: ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
Fl_Input.o: ../FL/fl_ask.H flstring.h ../FL/Fl_Export.H ../config.h
+Fl_Input.o: ../FL/Fl_Float_Input.H ../FL/Fl_Input.H ../FL/Fl_Int_Input.H
+Fl_Input.o: ../FL/Fl_Multiline_Input.H ../FL/Fl_Output.H
+Fl_Input.o: ../FL/Fl_Multiline_Output.H ../FL/Fl_Output.H
+Fl_Input.o: ../FL/Fl_Secret_Input.H
Fl_Input_.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
-Fl_Input_.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Input_.H
-Fl_Input_.o: ../FL/Fl_Widget.H ../FL/Fl_Window.H ../FL/Fl_Group.H
-Fl_Input_.o: ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H ../FL/Enumerations.H
-Fl_Input_.o: ../FL/Fl_Device.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H
-Fl_Input_.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H
+Fl_Input_.o: ../FL/Enumerations.H ../FL/Fl_Input_.H ../FL/Fl_Widget.H
+Fl_Input_.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Bitmap.H
+Fl_Input_.o: ../FL/Fl_Image.H ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H
+Fl_Input_.o: ../FL/Enumerations.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
+Fl_Input_.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
Fl_Input_.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H ../FL/fl_ask.H
Fl_Input_.o: ../FL/fl_utf8.h flstring.h ../FL/Fl_Export.H ../config.h
Fl_Light_Button.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H
-Fl_Light_Button.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H
+Fl_Light_Button.o: ../FL/fl_types.h ../FL/Enumerations.H
Fl_Light_Button.o: ../FL/Fl_Light_Button.H ../FL/Fl_Button.H
-Fl_Light_Button.o: ../FL/Fl_Widget.H ../FL/fl_draw.H ../FL/x.H
-Fl_Light_Button.o: ../FL/Fl_Window.H ../FL/Enumerations.H ../FL/Fl_Window.H
-Fl_Light_Button.o: ../FL/Fl_Group.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
-Fl_Light_Button.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
-Fl_Light_Button.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
-Fl_Light_Button.o: flstring.h ../FL/Fl_Export.H ../config.h
+Fl_Light_Button.o: ../FL/Fl_Radio_Light_Button.H ../FL/Fl_Light_Button.H
+Fl_Light_Button.o: ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H
+Fl_Light_Button.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Group.H
+Fl_Light_Button.o: ../FL/Fl_Widget.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H
+Fl_Light_Button.o: ../FL/Fl_Device.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H
+Fl_Light_Button.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H
+Fl_Light_Button.o: ../FL/Fl_RGB_Image.H flstring.h ../FL/Fl_Export.H
+Fl_Light_Button.o: ../config.h
Fl_Menu.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
-Fl_Menu.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Menu_Window.H
+Fl_Menu.o: ../FL/Enumerations.H ../FL/Fl_Menu_Window.H
Fl_Menu.o: ../FL/Fl_Single_Window.H ../FL/Fl_Window.H ../FL/Fl_Menu_.H
Fl_Menu.o: ../FL/Fl_Widget.H ../FL/Fl_Menu_Item.H ../FL/Fl_Image.H
Fl_Menu.o: ../FL/fl_draw.H ../FL/x.H ../FL/Enumerations.H ../FL/Fl_Window.H
-Fl_Menu.o: ../FL/Fl_Group.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
-Fl_Menu.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
-Fl_Menu.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H flstring.h
-Fl_Menu.o: ../FL/Fl_Export.H ../config.h
+Fl_Menu.o: ../FL/Fl_Group.H ../FL/Fl_Bitmap.H ../FL/Fl_Device.H
+Fl_Menu.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
+Fl_Menu.o: ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
+Fl_Menu.o: flstring.h ../FL/Fl_Export.H ../config.h
Fl_Menu_.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
-Fl_Menu_.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Menu_.H
-Fl_Menu_.o: ../FL/Fl_Widget.H ../FL/Fl_Menu_Item.H ../FL/Fl_Image.H
-Fl_Menu_.o: flstring.h ../FL/Fl_Export.H ../config.h
+Fl_Menu_.o: ../FL/Enumerations.H ../FL/Fl_Menu_.H ../FL/Fl_Widget.H
+Fl_Menu_.o: ../FL/Fl_Menu_Item.H ../FL/Fl_Image.H flstring.h
+Fl_Menu_.o: ../FL/Fl_Export.H ../config.h
Fl_Menu_Bar.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
-Fl_Menu_Bar.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Menu_Bar.H
-Fl_Menu_Bar.o: ../FL/Fl_Menu_.H ../FL/Fl_Widget.H ../FL/Fl_Menu_Item.H
-Fl_Menu_Bar.o: ../FL/Fl_Image.H ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H
+Fl_Menu_Bar.o: ../FL/Enumerations.H ../FL/Fl_Menu_Bar.H ../FL/Fl_Menu_.H
+Fl_Menu_Bar.o: ../FL/Fl_Widget.H ../FL/Fl_Menu_Item.H ../FL/Fl_Image.H
+Fl_Menu_Bar.o: ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H
Fl_Menu_Bar.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Group.H
-Fl_Menu_Bar.o: ../FL/Fl_Device.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H
-Fl_Menu_Bar.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H
-Fl_Menu_Bar.o: ../FL/Fl_RGB_Image.H
+Fl_Menu_Bar.o: ../FL/Fl_Bitmap.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
+Fl_Menu_Bar.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
+Fl_Menu_Bar.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
Fl_Menu_Button.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H
-Fl_Menu_Button.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H
+Fl_Menu_Button.o: ../FL/fl_types.h ../FL/Enumerations.H
Fl_Menu_Button.o: ../FL/Fl_Menu_Button.H ../FL/Fl_Menu_.H ../FL/Fl_Widget.H
Fl_Menu_Button.o: ../FL/Fl_Menu_Item.H ../FL/Fl_Image.H ../FL/fl_draw.H
Fl_Menu_Button.o: ../FL/x.H ../FL/Fl_Window.H ../FL/Enumerations.H
-Fl_Menu_Button.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Device.H
-Fl_Menu_Button.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
-Fl_Menu_Button.o: ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
+Fl_Menu_Button.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Bitmap.H
+Fl_Menu_Button.o: ../FL/Fl_Device.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H
+Fl_Menu_Button.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H
+Fl_Menu_Button.o: ../FL/Fl_RGB_Image.H
Fl_Menu_Window.o: ../config.h ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H
-Fl_Menu_Window.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H
-Fl_Menu_Window.o: ../FL/x.H ../FL/Fl_Window.H ../FL/fl_draw.H
-Fl_Menu_Window.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Group.H
-Fl_Menu_Window.o: ../FL/Fl_Widget.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
-Fl_Menu_Window.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
-Fl_Menu_Window.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
+Fl_Menu_Window.o: ../FL/fl_types.h ../FL/Enumerations.H ../FL/x.H
+Fl_Menu_Window.o: ../FL/Fl_Window.H ../FL/fl_draw.H ../FL/Enumerations.H
+Fl_Menu_Window.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Widget.H
+Fl_Menu_Window.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Device.H
+Fl_Menu_Window.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
+Fl_Menu_Window.o: ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
Fl_Menu_Window.o: ../FL/Fl_Menu_Window.H ../FL/Fl_Single_Window.H
Fl_Menu_add.o: ../FL/Fl_Menu_.H ../FL/Fl_Widget.H ../FL/Enumerations.H
Fl_Menu_add.o: ../FL/Fl_Export.H ../FL/fl_types.h ../FL/Fl_Menu_Item.H
Fl_Menu_add.o: ../FL/Fl_Image.H flstring.h ../FL/Fl_Export.H ../config.h
Fl_Menu_global.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H
-Fl_Menu_global.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H
-Fl_Menu_global.o: ../FL/Fl_Menu_.H ../FL/Fl_Widget.H ../FL/Fl_Menu_Item.H
-Fl_Menu_global.o: ../FL/Fl_Image.H
+Fl_Menu_global.o: ../FL/fl_types.h ../FL/Enumerations.H ../FL/Fl_Menu_.H
+Fl_Menu_global.o: ../FL/Fl_Widget.H ../FL/Fl_Menu_Item.H ../FL/Fl_Image.H
Fl_Multi_Label.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H
-Fl_Multi_Label.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H
-Fl_Multi_Label.o: ../FL/Fl_Widget.H ../FL/Fl_Menu_Item.H ../FL/Fl_Widget.H
-Fl_Multi_Label.o: ../FL/Fl_Image.H ../FL/Fl_Multi_Label.H
-Fl_Native_File_Chooser.o: Fl_Native_File_Chooser_FLTK.cxx
+Fl_Multi_Label.o: ../FL/fl_types.h ../FL/Enumerations.H ../FL/Fl_Widget.H
+Fl_Multi_Label.o: ../FL/Fl_Menu_Item.H ../FL/Fl_Widget.H ../FL/Fl_Image.H
+Fl_Multi_Label.o: ../FL/Fl_Multi_Label.H
+Fl_Native_File_Chooser.o: Fl_Native_File_Chooser_FLTK.cxx ../config.h
Fl_Native_File_Chooser.o: ../FL/Fl_Native_File_Chooser.H
Fl_Native_File_Chooser.o: ../FL/Fl_File_Chooser.H ../FL/Fl.H ../FL/fl_utf8.h
-Fl_Native_File_Chooser.o: ../FL/Fl_Export.H ../FL/fl_types.h ../FL/Xutf8.h
+Fl_Native_File_Chooser.o: ../FL/Fl_Export.H ../FL/fl_types.h
Fl_Native_File_Chooser.o: ../FL/Enumerations.H ../FL/Fl_Double_Window.H
Fl_Native_File_Chooser.o: ../FL/Fl_Window.H ../FL/Fl_Group.H
Fl_Native_File_Chooser.o: ../FL/Fl_Choice.H ../FL/Fl_Menu_.H
@@ -312,8 +344,6 @@ Fl_Native_File_Chooser.o: ../FL/Fl_Image.H ../FL/Fl_Menu_Button.H
Fl_Native_File_Chooser.o: ../FL/Fl_Button.H ../FL/Fl_Preferences.H
Fl_Native_File_Chooser.o: ../FL/Fl_Tile.H ../FL/Fl_Group.H
Fl_Native_File_Chooser.o: ../FL/Fl_File_Browser.H ../FL/Fl_Browser.H
-Fl_Native_File_Chooser.o: ../FL/Fl_Browser_.H ../FL/Fl_Scrollbar.H
-Fl_Native_File_Chooser.o: ../FL/Fl_Slider.H ../FL/Fl_Valuator.H
Fl_Native_File_Chooser.o: ../FL/Fl_File_Icon.H ../FL/Fl.H ../FL/filename.H
Fl_Native_File_Chooser.o: ../FL/Fl_Box.H ../FL/Fl_Check_Button.H
Fl_Native_File_Chooser.o: ../FL/Fl_Light_Button.H ../FL/Fl_Button.H
@@ -321,355 +351,381 @@ Fl_Native_File_Chooser.o: ../FL/Fl_File_Input.H ../FL/Fl_Input.H
Fl_Native_File_Chooser.o: ../FL/Fl_Input_.H ../FL/Fl_Return_Button.H
Fl_Native_File_Chooser.o: ../FL/fl_ask.H ../FL/Fl_File_Icon.H
Fl_Native_File_Chooser.o: Fl_Native_File_Chooser_common.cxx
-Fl_Native_File_Chooser.o: ../FL/Enumerations.H
+Fl_Native_File_Chooser.o: ../FL/Enumerations.H Fl_Native_File_Chooser_GTK.cxx
+Fl_Native_File_Chooser.o: ../FL/x.H
Fl_Overlay_Window.o: ../config.h ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H
-Fl_Overlay_Window.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H
+Fl_Overlay_Window.o: ../FL/fl_types.h ../FL/Enumerations.H
Fl_Overlay_Window.o: ../FL/Fl_Overlay_Window.H ../FL/Fl_Double_Window.H
Fl_Overlay_Window.o: ../FL/Fl_Window.H ../FL/fl_draw.H ../FL/x.H
Fl_Overlay_Window.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Group.H
-Fl_Overlay_Window.o: ../FL/Fl_Widget.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
+Fl_Overlay_Window.o: ../FL/Fl_Widget.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H
+Fl_Overlay_Window.o: ../FL/Fl_Device.H ../FL/Fl_Plugin.H
Fl_Overlay_Window.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H
-Fl_Overlay_Window.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Pixmap.H
-Fl_Overlay_Window.o: ../FL/Fl_RGB_Image.H
+Fl_Overlay_Window.o: ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
Fl_Pack.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
-Fl_Pack.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Pack.H
-Fl_Pack.o: ../FL/Fl_Group.H ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H
-Fl_Pack.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Group.H
-Fl_Pack.o: ../FL/Fl_Widget.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
-Fl_Pack.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
-Fl_Pack.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
+Fl_Pack.o: ../FL/Enumerations.H ../FL/Fl_Pack.H ../FL/Fl_Group.H
+Fl_Pack.o: ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H ../FL/Enumerations.H
+Fl_Pack.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Widget.H
+Fl_Pack.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Device.H
+Fl_Pack.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
+Fl_Pack.o: ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
Fl_Paged_Device.o: ../FL/Fl_Paged_Device.H ../FL/Fl_Device.H ../FL/x.H
Fl_Paged_Device.o: ../FL/Enumerations.H ../FL/Fl_Export.H ../FL/fl_types.h
-Fl_Paged_Device.o: ../FL/Fl_Window.H ../FL/Xutf8.h ../FL/Fl_Plugin.H
-Fl_Paged_Device.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
-Fl_Paged_Device.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
-Fl_Paged_Device.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Widget.H
+Fl_Paged_Device.o: ../FL/Fl_Window.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H
+Fl_Paged_Device.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H
+Fl_Paged_Device.o: ../FL/Fl_Image.H ../FL/Fl_RGB_Image.H ../FL/Fl_Window.H
+Fl_Paged_Device.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Bitmap.H
Fl_Paged_Device.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/fl_draw.H
Fl_Paged_Device.o: ../FL/Enumerations.H
Fl_Pixmap.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
-Fl_Pixmap.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/fl_draw.H ../FL/x.H
-Fl_Pixmap.o: ../FL/Fl_Window.H ../FL/Enumerations.H ../FL/Fl_Window.H
-Fl_Pixmap.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Device.H
-Fl_Pixmap.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
-Fl_Pixmap.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Pixmap.H
+Fl_Pixmap.o: ../FL/Enumerations.H ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H
+Fl_Pixmap.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Group.H
+Fl_Pixmap.o: ../FL/Fl_Widget.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H
+Fl_Pixmap.o: ../FL/Fl_Device.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H
+Fl_Pixmap.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H
Fl_Pixmap.o: ../FL/Fl_RGB_Image.H ../FL/Fl_Widget.H ../FL/Fl_Menu_Item.H
Fl_Pixmap.o: ../FL/Fl_Printer.H ../FL/Fl_Paged_Device.H ../FL/Fl_PostScript.H
Fl_Pixmap.o: flstring.h ../FL/Fl_Export.H ../config.h
+Fl_PostScript.o: ../FL/Fl_Printer.H ../FL/x.H ../FL/Enumerations.H
+Fl_PostScript.o: ../FL/Fl_Export.H ../FL/fl_types.h ../FL/Fl_Window.H
+Fl_PostScript.o: ../FL/Fl_Paged_Device.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
+Fl_PostScript.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
+Fl_PostScript.o: ../FL/Fl_Pixmap.H ../FL/Fl_Image.H ../FL/Fl_RGB_Image.H
+Fl_PostScript.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Widget.H
+Fl_PostScript.o: ../FL/Fl_Bitmap.H ../FL/fl_draw.H ../FL/Enumerations.H
+Fl_PostScript.o: ../FL/Fl_PostScript.H ../config.h ../FL/Fl.H ../FL/fl_utf8.h
+Fl_PostScript.o: ../FL/fl_ask.H ../FL/Fl_Native_File_Chooser.H
+Fl_PostScript.o: ../FL/Fl_File_Chooser.H ../FL/Fl_Double_Window.H
+Fl_PostScript.o: ../FL/Fl_Group.H ../FL/Fl_Choice.H ../FL/Fl_Menu_.H
+Fl_PostScript.o: ../FL/Fl_Menu_Item.H ../FL/Fl_Menu_Button.H
+Fl_PostScript.o: ../FL/Fl_Button.H ../FL/Fl_Preferences.H ../FL/Fl_Tile.H
+Fl_PostScript.o: ../FL/Fl_File_Browser.H ../FL/Fl_Browser.H
+Fl_PostScript.o: ../FL/Fl_File_Icon.H ../FL/Fl.H ../FL/filename.H
+Fl_PostScript.o: ../FL/Fl_Box.H ../FL/Fl_Check_Button.H
+Fl_PostScript.o: ../FL/Fl_Light_Button.H ../FL/Fl_Button.H
+Fl_PostScript.o: ../FL/Fl_File_Input.H ../FL/Fl_Input.H ../FL/Fl_Input_.H
+Fl_PostScript.o: ../FL/Fl_Return_Button.H Fl_Font.H print_panel.cxx
+Fl_PostScript.o: print_panel.h ../FL/Fl_Round_Button.H ../FL/Fl_Spinner.H
+Fl_PostScript.o: ../FL/Fl_Repeat_Button.H ../FL/Fl_Progress.H
+Fl_PostScript.o: ../src/flstring.h ../FL/Fl_Export.H ../FL/Fl_Int_Input.H
+Fl_PostScript.o: ../FL/Fl_Input.H
Fl_Positioner.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H
-Fl_Positioner.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H
-Fl_Positioner.o: ../FL/Fl_Positioner.H ../FL/Fl_Widget.H ../FL/fl_draw.H
-Fl_Positioner.o: ../FL/x.H ../FL/Fl_Window.H ../FL/Enumerations.H
-Fl_Positioner.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Device.H
-Fl_Positioner.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
-Fl_Positioner.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Pixmap.H
+Fl_Positioner.o: ../FL/fl_types.h ../FL/Enumerations.H ../FL/Fl_Positioner.H
+Fl_Positioner.o: ../FL/Fl_Widget.H ../FL/fl_draw.H ../FL/x.H
+Fl_Positioner.o: ../FL/Fl_Window.H ../FL/Enumerations.H ../FL/Fl_Window.H
+Fl_Positioner.o: ../FL/Fl_Group.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H
+Fl_Positioner.o: ../FL/Fl_Device.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H
+Fl_Positioner.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H
Fl_Positioner.o: ../FL/Fl_RGB_Image.H
Fl_Preferences.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H
-Fl_Preferences.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H
+Fl_Preferences.o: ../FL/fl_types.h ../FL/Enumerations.H
Fl_Preferences.o: ../FL/Fl_Preferences.H ../FL/Fl_Plugin.H
Fl_Preferences.o: ../FL/Fl_Preferences.H ../FL/filename.H ../FL/fl_utf8.h
Fl_Preferences.o: flstring.h ../FL/Fl_Export.H ../config.h
Fl_Printer.o: ../FL/Fl_Printer.H ../FL/x.H ../FL/Enumerations.H
Fl_Printer.o: ../FL/Fl_Export.H ../FL/fl_types.h ../FL/Fl_Window.H
-Fl_Printer.o: ../FL/Xutf8.h ../FL/Fl_Paged_Device.H ../FL/Fl_Device.H
-Fl_Printer.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
-Fl_Printer.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Pixmap.H
-Fl_Printer.o: ../FL/Fl_RGB_Image.H ../FL/Fl_Window.H ../FL/Fl_Group.H
-Fl_Printer.o: ../FL/Fl_Widget.H ../FL/fl_draw.H ../FL/Enumerations.H
-Fl_Printer.o: ../FL/Fl_PostScript.H Fl_PostScript.cxx ../config.h ../FL/Fl.H
-Fl_Printer.o: ../FL/fl_utf8.h ../FL/fl_ask.H ../FL/Fl_Native_File_Chooser.H
-Fl_Printer.o: ../FL/Fl_File_Chooser.H ../FL/Fl_Double_Window.H
-Fl_Printer.o: ../FL/Fl_Group.H ../FL/Fl_Choice.H ../FL/Fl_Menu_.H
-Fl_Printer.o: ../FL/Fl_Menu_Item.H ../FL/Fl_Menu_Button.H ../FL/Fl_Button.H
-Fl_Printer.o: ../FL/Fl_Preferences.H ../FL/Fl_Tile.H ../FL/Fl_File_Browser.H
-Fl_Printer.o: ../FL/Fl_Browser.H ../FL/Fl_Browser_.H ../FL/Fl_Scrollbar.H
-Fl_Printer.o: ../FL/Fl_Slider.H ../FL/Fl_Valuator.H ../FL/Fl_File_Icon.H
-Fl_Printer.o: ../FL/Fl.H ../FL/filename.H ../FL/Fl_Box.H
-Fl_Printer.o: ../FL/Fl_Check_Button.H ../FL/Fl_Light_Button.H
-Fl_Printer.o: ../FL/Fl_Button.H ../FL/Fl_File_Input.H ../FL/Fl_Input.H
-Fl_Printer.o: ../FL/Fl_Input_.H ../FL/Fl_Return_Button.H Fl_Font.H
-Fl_Printer.o: print_panel.cxx print_panel.h ../FL/Fl_Round_Button.H
-Fl_Printer.o: ../FL/Fl_Spinner.H ../FL/Fl_Repeat_Button.H ../FL/Fl_Progress.H
-Fl_Printer.o: ../src/flstring.h ../FL/Fl_Export.H ../FL/Fl_Int_Input.H
-Fl_Printer.o: ../FL/Fl_Input.H
+Fl_Printer.o: ../FL/Fl_Paged_Device.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
+Fl_Printer.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
+Fl_Printer.o: ../FL/Fl_Pixmap.H ../FL/Fl_Image.H ../FL/Fl_RGB_Image.H
+Fl_Printer.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Widget.H
+Fl_Printer.o: ../FL/Fl_Bitmap.H ../FL/fl_draw.H ../FL/Enumerations.H
+Fl_Printer.o: ../FL/Fl_PostScript.H
Fl_Progress.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
-Fl_Progress.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Progress.H
-Fl_Progress.o: ../FL/Fl_Widget.H ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H
+Fl_Progress.o: ../FL/Enumerations.H ../FL/Fl_Progress.H ../FL/Fl_Widget.H
+Fl_Progress.o: ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H
Fl_Progress.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Group.H
-Fl_Progress.o: ../FL/Fl_Device.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H
-Fl_Progress.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H
-Fl_Progress.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
+Fl_Progress.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Device.H
+Fl_Progress.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
+Fl_Progress.o: ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
Fl_Repeat_Button.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H
-Fl_Repeat_Button.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H
+Fl_Repeat_Button.o: ../FL/fl_types.h ../FL/Enumerations.H
Fl_Repeat_Button.o: ../FL/Fl_Repeat_Button.H ../FL/Fl.H ../FL/Fl_Button.H
-Fl_Repeat_Button.o: ../FL/Fl_Widget.H
Fl_Return_Button.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H
-Fl_Return_Button.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H
+Fl_Return_Button.o: ../FL/fl_types.h ../FL/Enumerations.H
Fl_Return_Button.o: ../FL/Fl_Return_Button.H ../FL/Fl_Button.H
-Fl_Return_Button.o: ../FL/Fl_Widget.H ../FL/fl_draw.H ../FL/x.H
-Fl_Return_Button.o: ../FL/Fl_Window.H ../FL/Enumerations.H ../FL/Fl_Window.H
-Fl_Return_Button.o: ../FL/Fl_Group.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
+Fl_Return_Button.o: ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H
+Fl_Return_Button.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Group.H
+Fl_Return_Button.o: ../FL/Fl_Widget.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H
+Fl_Return_Button.o: ../FL/Fl_Device.H ../FL/Fl_Plugin.H
Fl_Return_Button.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
-Fl_Return_Button.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
+Fl_Return_Button.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
Fl_Roller.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
-Fl_Roller.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Roller.H
-Fl_Roller.o: ../FL/Fl_Valuator.H ../FL/Fl_Widget.H ../FL/fl_draw.H ../FL/x.H
-Fl_Roller.o: ../FL/Fl_Window.H ../FL/Enumerations.H ../FL/Fl_Window.H
-Fl_Roller.o: ../FL/Fl_Group.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
-Fl_Roller.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
-Fl_Roller.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
+Fl_Roller.o: ../FL/Enumerations.H ../FL/Fl_Roller.H ../FL/Fl_Valuator.H
+Fl_Roller.o: ../FL/Fl_Widget.H ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H
+Fl_Roller.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Group.H
+Fl_Roller.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Device.H
+Fl_Roller.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
+Fl_Roller.o: ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
Fl_Round_Button.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H
-Fl_Round_Button.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H
+Fl_Round_Button.o: ../FL/fl_types.h ../FL/Enumerations.H
Fl_Round_Button.o: ../FL/Fl_Round_Button.H ../FL/Fl_Light_Button.H
-Fl_Round_Button.o: ../FL/Fl_Button.H ../FL/Fl_Widget.H
+Fl_Round_Button.o: ../FL/Fl_Button.H ../FL/Fl_Radio_Round_Button.H
+Fl_Round_Button.o: ../FL/Fl_Round_Button.H
Fl_Scroll.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
-Fl_Scroll.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Tiled_Image.H
-Fl_Scroll.o: ../FL/Fl_Image.H ../FL/Fl_Scroll.H ../FL/Fl_Group.H
-Fl_Scroll.o: ../FL/Fl_Widget.H ../FL/Fl_Scrollbar.H ../FL/Fl_Slider.H
-Fl_Scroll.o: ../FL/Fl_Valuator.H ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H
-Fl_Scroll.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Device.H
+Fl_Scroll.o: ../FL/Enumerations.H ../FL/Fl_Tiled_Image.H ../FL/Fl_Image.H
+Fl_Scroll.o: ../FL/Fl_Scroll.H ../FL/Fl_Group.H ../FL/Fl_Widget.H
+Fl_Scroll.o: ../FL/Fl_Scrollbar.H ../FL/Fl_Slider.H ../FL/Fl_Valuator.H
+Fl_Scroll.o: ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H ../FL/Enumerations.H
+Fl_Scroll.o: ../FL/Fl_Window.H ../FL/Fl_Bitmap.H ../FL/Fl_Device.H
Fl_Scroll.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
Fl_Scroll.o: ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
Fl_Scrollbar.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
-Fl_Scrollbar.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Scrollbar.H
-Fl_Scrollbar.o: ../FL/Fl_Slider.H ../FL/Fl_Valuator.H ../FL/Fl_Widget.H
-Fl_Scrollbar.o: ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H
-Fl_Scrollbar.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Group.H
-Fl_Scrollbar.o: ../FL/Fl_Device.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H
-Fl_Scrollbar.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H
+Fl_Scrollbar.o: ../FL/Enumerations.H ../FL/Fl_Scrollbar.H ../FL/Fl_Slider.H
+Fl_Scrollbar.o: ../FL/Fl_Valuator.H ../FL/Fl_Widget.H ../FL/fl_draw.H
+Fl_Scrollbar.o: ../FL/x.H ../FL/Fl_Window.H ../FL/Enumerations.H
+Fl_Scrollbar.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Bitmap.H
+Fl_Scrollbar.o: ../FL/Fl_Image.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
+Fl_Scrollbar.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
Fl_Scrollbar.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H flstring.h
Fl_Scrollbar.o: ../FL/Fl_Export.H ../config.h
Fl_Shared_Image.o: ../FL/fl_utf8.h flstring.h ../FL/Fl_Export.H ../config.h
Fl_Shared_Image.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H
-Fl_Shared_Image.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H
+Fl_Shared_Image.o: ../FL/fl_types.h ../FL/Enumerations.H
Fl_Shared_Image.o: ../FL/Fl_Shared_Image.H ../FL/Fl_Image.H
Fl_Shared_Image.o: ../FL/Fl_XBM_Image.H ../FL/Fl_Bitmap.H
Fl_Shared_Image.o: ../FL/Fl_XPM_Image.H ../FL/Fl_Pixmap.H
Fl_Single_Window.o: ../FL/Fl_Single_Window.H ../FL/Fl_Window.H
Fl_Slider.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
-Fl_Slider.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Slider.H
-Fl_Slider.o: ../FL/Fl_Valuator.H ../FL/Fl_Widget.H ../FL/fl_draw.H ../FL/x.H
-Fl_Slider.o: ../FL/Fl_Window.H ../FL/Enumerations.H ../FL/Fl_Window.H
-Fl_Slider.o: ../FL/Fl_Group.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
+Fl_Slider.o: ../FL/Enumerations.H ../FL/Fl_Slider.H ../FL/Fl_Valuator.H
+Fl_Slider.o: ../FL/Fl_Widget.H ../FL/Fl_Fill_Slider.H ../FL/Fl_Slider.H
+Fl_Slider.o: ../FL/Fl_Hor_Slider.H ../FL/Fl_Hor_Fill_Slider.H
+Fl_Slider.o: ../FL/Fl_Hor_Nice_Slider.H ../FL/Fl_Nice_Slider.H
+Fl_Slider.o: ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H ../FL/Enumerations.H
+Fl_Slider.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Bitmap.H
+Fl_Slider.o: ../FL/Fl_Image.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
Fl_Slider.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
-Fl_Slider.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
-Fl_Slider.o: flstring.h ../FL/Fl_Export.H ../config.h
+Fl_Slider.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H flstring.h
+Fl_Slider.o: ../FL/Fl_Export.H ../config.h
Fl_Table.o: ../FL/fl_draw.H ../FL/x.H ../FL/Enumerations.H ../FL/Fl_Export.H
-Fl_Table.o: ../FL/fl_types.h ../FL/Fl_Window.H ../FL/Xutf8.h
-Fl_Table.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Group.H
-Fl_Table.o: ../FL/Fl_Widget.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
-Fl_Table.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
-Fl_Table.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
+Fl_Table.o: ../FL/fl_types.h ../FL/Fl_Window.H ../FL/Enumerations.H
+Fl_Table.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Widget.H
+Fl_Table.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Device.H
+Fl_Table.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
+Fl_Table.o: ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
Fl_Table.o: ../FL/Fl_Table.H ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Group.H
Fl_Table.o: ../FL/Fl_Scroll.H ../FL/Fl_Scrollbar.H ../FL/Fl_Slider.H
Fl_Table.o: ../FL/Fl_Valuator.H ../FL/Fl_Box.H ../FL/Fl_Scrollbar.H
Fl_Table_Row.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
-Fl_Table_Row.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/fl_draw.H ../FL/x.H
+Fl_Table_Row.o: ../FL/Enumerations.H ../FL/fl_draw.H ../FL/x.H
Fl_Table_Row.o: ../FL/Fl_Window.H ../FL/Enumerations.H ../FL/Fl_Window.H
-Fl_Table_Row.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Device.H
-Fl_Table_Row.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
-Fl_Table_Row.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Pixmap.H
-Fl_Table_Row.o: ../FL/Fl_RGB_Image.H ../FL/Fl_Table_Row.H ../FL/Fl_Table.H
-Fl_Table_Row.o: ../FL/Fl_Group.H ../FL/Fl_Scroll.H ../FL/Fl_Scrollbar.H
-Fl_Table_Row.o: ../FL/Fl_Slider.H ../FL/Fl_Valuator.H ../FL/Fl_Box.H
-Fl_Table_Row.o: ../FL/Fl_Scrollbar.H
+Fl_Table_Row.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Bitmap.H
+Fl_Table_Row.o: ../FL/Fl_Image.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
+Fl_Table_Row.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
+Fl_Table_Row.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H ../FL/Fl_Table_Row.H
+Fl_Table_Row.o: ../FL/Fl_Table.H ../FL/Fl_Group.H ../FL/Fl_Scroll.H
+Fl_Table_Row.o: ../FL/Fl_Scrollbar.H ../FL/Fl_Slider.H ../FL/Fl_Valuator.H
+Fl_Table_Row.o: ../FL/Fl_Box.H ../FL/Fl_Scrollbar.H
Fl_Tabs.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
-Fl_Tabs.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Tabs.H
-Fl_Tabs.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/fl_draw.H ../FL/x.H
-Fl_Tabs.o: ../FL/Fl_Window.H ../FL/Enumerations.H ../FL/Fl_Window.H
-Fl_Tabs.o: ../FL/Fl_Device.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H
-Fl_Tabs.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H
+Fl_Tabs.o: ../FL/Enumerations.H ../FL/Fl_Tabs.H ../FL/Fl_Group.H
+Fl_Tabs.o: ../FL/Fl_Widget.H ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H
+Fl_Tabs.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Bitmap.H
+Fl_Tabs.o: ../FL/Fl_Image.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
+Fl_Tabs.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
Fl_Tabs.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H ../FL/Fl_Tooltip.H
Fl_Tabs.o: ../FL/Fl_Widget.H
Fl_Text_Buffer.o: ../FL/fl_utf8.h flstring.h ../FL/Fl_Export.H ../config.h
Fl_Text_Buffer.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H
-Fl_Text_Buffer.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H
+Fl_Text_Buffer.o: ../FL/fl_types.h ../FL/Enumerations.H
Fl_Text_Buffer.o: ../FL/Fl_Text_Buffer.H ../FL/fl_ask.H
Fl_Text_Display.o: ../FL/fl_utf8.h flstring.h ../FL/Fl_Export.H ../config.h
Fl_Text_Display.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H
-Fl_Text_Display.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H
+Fl_Text_Display.o: ../FL/fl_types.h ../FL/Enumerations.H
Fl_Text_Display.o: ../FL/Fl_Text_Buffer.H ../FL/Fl_Text_Display.H
Fl_Text_Display.o: ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H
Fl_Text_Display.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Group.H
-Fl_Text_Display.o: ../FL/Fl_Widget.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
-Fl_Text_Display.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
-Fl_Text_Display.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
-Fl_Text_Display.o: ../FL/Fl_Scrollbar.H ../FL/Fl_Slider.H ../FL/Fl_Valuator.H
+Fl_Text_Display.o: ../FL/Fl_Widget.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H
+Fl_Text_Display.o: ../FL/Fl_Device.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H
+Fl_Text_Display.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H
+Fl_Text_Display.o: ../FL/Fl_RGB_Image.H ../FL/Fl_Scrollbar.H
+Fl_Text_Display.o: ../FL/Fl_Slider.H ../FL/Fl_Valuator.H
Fl_Text_Display.o: ../FL/Fl_Text_Buffer.H ../FL/Fl_Printer.H
Fl_Text_Display.o: ../FL/Fl_Paged_Device.H ../FL/fl_draw.H
Fl_Text_Display.o: ../FL/Fl_PostScript.H
Fl_Text_Editor.o: flstring.h ../FL/Fl_Export.H ../config.h ../FL/Fl.H
Fl_Text_Editor.o: ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
-Fl_Text_Editor.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Window.H
-Fl_Text_Editor.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Text_Editor.H
-Fl_Text_Editor.o: ../FL/Fl_Text_Display.H ../FL/fl_draw.H ../FL/x.H
-Fl_Text_Editor.o: ../FL/Fl_Window.H ../FL/Enumerations.H ../FL/Fl_Device.H
-Fl_Text_Editor.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
-Fl_Text_Editor.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Pixmap.H
-Fl_Text_Editor.o: ../FL/Fl_RGB_Image.H ../FL/Fl_Scrollbar.H ../FL/Fl_Slider.H
-Fl_Text_Editor.o: ../FL/Fl_Valuator.H ../FL/Fl_Text_Buffer.H ../FL/fl_ask.H
+Fl_Text_Editor.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Group.H
+Fl_Text_Editor.o: ../FL/Fl_Widget.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H
+Fl_Text_Editor.o: ../FL/Fl_Text_Editor.H ../FL/Fl_Text_Display.H
+Fl_Text_Editor.o: ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H
+Fl_Text_Editor.o: ../FL/Enumerations.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
+Fl_Text_Editor.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
+Fl_Text_Editor.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H ../FL/Fl_Scrollbar.H
+Fl_Text_Editor.o: ../FL/Fl_Slider.H ../FL/Fl_Valuator.H
+Fl_Text_Editor.o: ../FL/Fl_Text_Buffer.H ../FL/fl_ask.H
Fl_Tile.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
-Fl_Tile.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Tile.H
-Fl_Tile.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Window.H
+Fl_Tile.o: ../FL/Enumerations.H ../FL/Fl_Tile.H ../FL/Fl_Group.H
+Fl_Tile.o: ../FL/Fl_Widget.H ../FL/Fl_Window.H ../FL/Fl_Bitmap.H
+Fl_Tile.o: ../FL/Fl_Image.H
Fl_Tiled_Image.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H
-Fl_Tiled_Image.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H
-Fl_Tiled_Image.o: ../FL/Fl_Tiled_Image.H ../FL/Fl_Image.H ../FL/fl_draw.H
-Fl_Tiled_Image.o: ../FL/x.H ../FL/Fl_Window.H ../FL/Enumerations.H
-Fl_Tiled_Image.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Widget.H
-Fl_Tiled_Image.o: ../FL/Fl_Device.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H
-Fl_Tiled_Image.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H
-Fl_Tiled_Image.o: ../FL/Fl_RGB_Image.H
+Fl_Tiled_Image.o: ../FL/fl_types.h ../FL/Enumerations.H
+Fl_Tiled_Image.o: ../FL/Fl_Tiled_Image.H ../FL/Fl_Image.H ../FL/Fl_Window.H
+Fl_Tiled_Image.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Bitmap.H
+Fl_Tiled_Image.o: ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H
+Fl_Tiled_Image.o: ../FL/Enumerations.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
+Fl_Tiled_Image.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
+Fl_Tiled_Image.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
Fl_Tree.o: ../FL/Fl_Tree.H ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H
-Fl_Tree.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H
-Fl_Tree.o: ../FL/Fl_Group.H ../FL/Fl_Scrollbar.H ../FL/Fl_Slider.H
-Fl_Tree.o: ../FL/Fl_Valuator.H ../FL/Fl_Widget.H ../FL/fl_draw.H ../FL/x.H
-Fl_Tree.o: ../FL/Fl_Window.H ../FL/Enumerations.H ../FL/Fl_Window.H
-Fl_Tree.o: ../FL/Fl_Group.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
-Fl_Tree.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
-Fl_Tree.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
+Fl_Tree.o: ../FL/fl_types.h ../FL/Enumerations.H ../FL/Fl_Group.H
+Fl_Tree.o: ../FL/Fl_Scrollbar.H ../FL/Fl_Slider.H ../FL/Fl_Valuator.H
+Fl_Tree.o: ../FL/Fl_Widget.H ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H
+Fl_Tree.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Group.H
+Fl_Tree.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Device.H
+Fl_Tree.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
+Fl_Tree.o: ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
Fl_Tree.o: ../FL/Fl_Tree_Item.H ../FL/Fl_Widget.H ../FL/Fl_Tree_Item_Array.H
Fl_Tree.o: ../FL/Fl_Tree_Prefs.H ../FL/Fl_Preferences.H
Fl_Tree_Item.o: ../FL/Fl_Widget.H ../FL/Fl_Tree_Item.H ../FL/Fl.H
Fl_Tree_Item.o: ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
-Fl_Tree_Item.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Image.H
-Fl_Tree_Item.o: ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H
-Fl_Tree_Item.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Group.H
-Fl_Tree_Item.o: ../FL/Fl_Widget.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
-Fl_Tree_Item.o: ../FL/Fl_Preferences.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H
+Fl_Tree_Item.o: ../FL/Enumerations.H ../FL/Fl_Image.H ../FL/fl_draw.H
+Fl_Tree_Item.o: ../FL/x.H ../FL/Fl_Window.H ../FL/Enumerations.H
+Fl_Tree_Item.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Widget.H
+Fl_Tree_Item.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Device.H
+Fl_Tree_Item.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Bitmap.H
Fl_Tree_Item.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
Fl_Tree_Item.o: ../FL/Fl_Tree_Item_Array.H ../FL/Fl_Tree_Prefs.H
-Fl_Tree_Item_Array.o: ../FL/Fl_Tree_Item_Array.H ../FL/Fl_Export.H
-Fl_Tree_Item_Array.o: ../FL/Fl_Tree_Item.H ../FL/Fl.H ../FL/fl_utf8.h
-Fl_Tree_Item_Array.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H
-Fl_Tree_Item_Array.o: ../FL/Fl_Widget.H ../FL/Fl_Image.H ../FL/fl_draw.H
-Fl_Tree_Item_Array.o: ../FL/x.H ../FL/Fl_Window.H ../FL/Enumerations.H
-Fl_Tree_Item_Array.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Widget.H
+Fl_Tree_Item.o: ../FL/Fl_Tree.H ../FL/Fl_Group.H ../FL/Fl_Scrollbar.H
+Fl_Tree_Item.o: ../FL/Fl_Slider.H ../FL/Fl_Valuator.H
+Fl_Tree_Item_Array.o: ../FL/Fl_Tree_Item_Array.H ../FL/Fl.H ../FL/fl_utf8.h
+Fl_Tree_Item_Array.o: ../FL/Fl_Export.H ../FL/fl_types.h ../FL/Enumerations.H
+Fl_Tree_Item_Array.o: ../FL/Fl_Tree_Item.H ../FL/Fl_Widget.H ../FL/Fl_Image.H
+Fl_Tree_Item_Array.o: ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H
+Fl_Tree_Item_Array.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Group.H
+Fl_Tree_Item_Array.o: ../FL/Fl_Widget.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H
Fl_Tree_Item_Array.o: ../FL/Fl_Device.H ../FL/Fl_Plugin.H
Fl_Tree_Item_Array.o: ../FL/Fl_Preferences.H ../FL/Fl_Bitmap.H
-Fl_Tree_Item_Array.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
+Fl_Tree_Item_Array.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
Fl_Tree_Item_Array.o: ../FL/Fl_Tree_Prefs.H
Fl_Tree_Prefs.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H
-Fl_Tree_Prefs.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H
-Fl_Tree_Prefs.o: ../FL/Fl_Pixmap.H ../FL/Fl_Image.H ../FL/Fl_Tree_Prefs.H
+Fl_Tree_Prefs.o: ../FL/fl_types.h ../FL/Enumerations.H ../FL/Fl_Pixmap.H
+Fl_Tree_Prefs.o: ../FL/Fl_Image.H ../FL/Fl_Tree_Prefs.H
Fl_Tooltip.o: ../FL/Fl_Tooltip.H ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H
-Fl_Tooltip.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H
-Fl_Tooltip.o: ../FL/Fl_Widget.H ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H
+Fl_Tooltip.o: ../FL/fl_types.h ../FL/Enumerations.H ../FL/Fl_Widget.H
+Fl_Tooltip.o: ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H
Fl_Tooltip.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Group.H
-Fl_Tooltip.o: ../FL/Fl_Widget.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
-Fl_Tooltip.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
-Fl_Tooltip.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
-Fl_Tooltip.o: ../FL/Fl_Menu_Window.H ../FL/Fl_Single_Window.H
+Fl_Tooltip.o: ../FL/Fl_Widget.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H
+Fl_Tooltip.o: ../FL/Fl_Device.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H
+Fl_Tooltip.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H
+Fl_Tooltip.o: ../FL/Fl_RGB_Image.H ../FL/Fl_Menu_Window.H
+Fl_Tooltip.o: ../FL/Fl_Single_Window.H
Fl_Valuator.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
-Fl_Valuator.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Valuator.H
-Fl_Valuator.o: ../FL/Fl_Widget.H ../FL/math.h flstring.h ../FL/Fl_Export.H
-Fl_Valuator.o: ../config.h
+Fl_Valuator.o: ../FL/Enumerations.H ../FL/Fl_Valuator.H ../FL/Fl_Widget.H
+Fl_Valuator.o: ../FL/math.h flstring.h ../FL/Fl_Export.H ../config.h
Fl_Value_Input.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H
-Fl_Value_Input.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H
+Fl_Value_Input.o: ../FL/fl_types.h ../FL/Enumerations.H
Fl_Value_Input.o: ../FL/Fl_Value_Input.H ../FL/Fl_Valuator.H
Fl_Value_Input.o: ../FL/Fl_Widget.H ../FL/Fl_Input.H ../FL/Fl_Input_.H
Fl_Value_Input.o: ../FL/Fl_Group.H ../FL/math.h
Fl_Value_Output.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H
-Fl_Value_Output.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H
+Fl_Value_Output.o: ../FL/fl_types.h ../FL/Enumerations.H
Fl_Value_Output.o: ../FL/Fl_Value_Output.H ../FL/Fl_Valuator.H
Fl_Value_Output.o: ../FL/Fl_Widget.H ../FL/fl_draw.H ../FL/x.H
Fl_Value_Output.o: ../FL/Fl_Window.H ../FL/Enumerations.H ../FL/Fl_Window.H
-Fl_Value_Output.o: ../FL/Fl_Group.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
-Fl_Value_Output.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
-Fl_Value_Output.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
+Fl_Value_Output.o: ../FL/Fl_Group.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H
+Fl_Value_Output.o: ../FL/Fl_Device.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H
+Fl_Value_Output.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H
+Fl_Value_Output.o: ../FL/Fl_RGB_Image.H
Fl_Value_Slider.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H
-Fl_Value_Slider.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H
+Fl_Value_Slider.o: ../FL/fl_types.h ../FL/Enumerations.H
Fl_Value_Slider.o: ../FL/Fl_Value_Slider.H ../FL/Fl_Slider.H
-Fl_Value_Slider.o: ../FL/Fl_Valuator.H ../FL/Fl_Widget.H ../FL/fl_draw.H
-Fl_Value_Slider.o: ../FL/x.H ../FL/Fl_Window.H ../FL/Enumerations.H
-Fl_Value_Slider.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Device.H
+Fl_Value_Slider.o: ../FL/Fl_Valuator.H ../FL/Fl_Widget.H
+Fl_Value_Slider.o: ../FL/Fl_Hor_Value_Slider.H ../FL/Fl_Value_Slider.H
+Fl_Value_Slider.o: ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H
+Fl_Value_Slider.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Group.H
+Fl_Value_Slider.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Device.H
Fl_Value_Slider.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
-Fl_Value_Slider.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Pixmap.H
-Fl_Value_Slider.o: ../FL/Fl_RGB_Image.H
+Fl_Value_Slider.o: ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
Fl_Widget.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
-Fl_Widget.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Widget.H
-Fl_Widget.o: ../FL/Fl_Group.H ../FL/Fl_Tooltip.H ../FL/fl_draw.H ../FL/x.H
-Fl_Widget.o: ../FL/Fl_Window.H ../FL/Enumerations.H ../FL/Fl_Window.H
-Fl_Widget.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Device.H
-Fl_Widget.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
-Fl_Widget.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Pixmap.H
+Fl_Widget.o: ../FL/Enumerations.H ../FL/Fl_Widget.H ../FL/Fl_Group.H
+Fl_Widget.o: ../FL/Fl_Tooltip.H ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H
+Fl_Widget.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Group.H
+Fl_Widget.o: ../FL/Fl_Widget.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H
+Fl_Widget.o: ../FL/Fl_Device.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H
+Fl_Widget.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H
Fl_Widget.o: ../FL/Fl_RGB_Image.H flstring.h ../FL/Fl_Export.H ../config.h
Fl_Window.o: ../config.h ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H
-Fl_Window.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H ../FL/x.H
-Fl_Window.o: ../FL/Fl_Window.H ../FL/Fl_Window.H ../FL/Fl_Group.H
-Fl_Window.o: ../FL/Fl_Widget.H flstring.h ../FL/Fl_Export.H
+Fl_Window.o: ../FL/fl_types.h ../FL/Enumerations.H ../FL/x.H
+Fl_Window.o: ../FL/Fl_Window.H ../FL/Fl_RGB_Image.H ../FL/Fl_Image.H
+Fl_Window.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Widget.H
+Fl_Window.o: ../FL/Fl_Bitmap.H flstring.h ../FL/Fl_Export.H
Fl_Window_fullscreen.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H
-Fl_Window_fullscreen.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H
-Fl_Window_fullscreen.o: ../FL/x.H ../FL/Fl_Window.H ../config.h
+Fl_Window_fullscreen.o: ../FL/fl_types.h ../FL/Enumerations.H ../FL/x.H
+Fl_Window_fullscreen.o: ../FL/Fl_Window.H ../config.h
Fl_Window_hotspot.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H
-Fl_Window_hotspot.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H
-Fl_Window_hotspot.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Widget.H
-Fl_Window_hotspot.o: ../FL/x.H ../FL/Fl_Window.H
+Fl_Window_hotspot.o: ../FL/fl_types.h ../FL/Enumerations.H ../FL/Fl_Window.H
+Fl_Window_hotspot.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Bitmap.H
+Fl_Window_hotspot.o: ../FL/Fl_Image.H ../FL/x.H ../FL/Fl_Window.H
Fl_Window_iconize.o: ../FL/x.H ../FL/Enumerations.H ../FL/Fl_Export.H
-Fl_Window_iconize.o: ../FL/fl_types.h ../FL/Fl_Window.H ../FL/Xutf8.h
+Fl_Window_iconize.o: ../FL/fl_types.h ../FL/Fl_Window.H
+Fl_Window_shape.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H
+Fl_Window_shape.o: ../FL/fl_types.h ../FL/Enumerations.H ../FL/fl_draw.H
+Fl_Window_shape.o: ../FL/x.H ../FL/Fl_Window.H ../FL/Enumerations.H
+Fl_Window_shape.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Widget.H
+Fl_Window_shape.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Device.H
+Fl_Window_shape.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
+Fl_Window_shape.o: ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
+Fl_Window_shape.o: ../config.h
Fl_Wizard.o: ../FL/Fl_Wizard.H ../FL/Fl_Group.H ../FL/Fl_Window.H
Fl_Wizard.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Enumerations.H
-Fl_Wizard.o: ../FL/Fl_Export.H ../FL/fl_types.h ../FL/fl_draw.H ../FL/x.H
-Fl_Wizard.o: ../FL/Fl_Window.H ../FL/Xutf8.h ../FL/Enumerations.H
-Fl_Wizard.o: ../FL/Fl_Device.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H
-Fl_Wizard.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H
+Fl_Wizard.o: ../FL/Fl_Export.H ../FL/fl_types.h ../FL/Fl_Bitmap.H
+Fl_Wizard.o: ../FL/Fl_Image.H ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H
+Fl_Wizard.o: ../FL/Enumerations.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
+Fl_Wizard.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
Fl_Wizard.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
Fl_XBM_Image.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
-Fl_XBM_Image.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_XBM_Image.H
-Fl_XBM_Image.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/fl_utf8.h flstring.h
-Fl_XBM_Image.o: ../FL/Fl_Export.H ../config.h
+Fl_XBM_Image.o: ../FL/Enumerations.H ../FL/Fl_XBM_Image.H ../FL/Fl_Bitmap.H
+Fl_XBM_Image.o: ../FL/Fl_Image.H ../FL/fl_utf8.h flstring.h ../FL/Fl_Export.H
+Fl_XBM_Image.o: ../config.h
Fl_XPM_Image.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
-Fl_XPM_Image.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_XPM_Image.H
-Fl_XPM_Image.o: ../FL/Fl_Pixmap.H ../FL/Fl_Image.H ../FL/fl_utf8.h flstring.h
-Fl_XPM_Image.o: ../FL/Fl_Export.H ../config.h
+Fl_XPM_Image.o: ../FL/Enumerations.H ../FL/Fl_XPM_Image.H ../FL/Fl_Pixmap.H
+Fl_XPM_Image.o: ../FL/Fl_Image.H ../FL/fl_utf8.h flstring.h ../FL/Fl_Export.H
+Fl_XPM_Image.o: ../config.h
Fl_abort.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
-Fl_abort.o: ../FL/Xutf8.h ../FL/Enumerations.H flstring.h ../FL/Fl_Export.H
-Fl_abort.o: ../config.h
+Fl_abort.o: ../FL/Enumerations.H flstring.h ../FL/Fl_Export.H ../config.h
Fl_add_idle.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
-Fl_add_idle.o: ../FL/Xutf8.h ../FL/Enumerations.H
+Fl_add_idle.o: ../FL/Enumerations.H
Fl_arg.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
-Fl_arg.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/x.H ../FL/Fl_Window.H
-Fl_arg.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Widget.H
-Fl_arg.o: ../FL/Fl_Tooltip.H ../FL/Fl_Widget.H ../FL/filename.H
-Fl_arg.o: ../FL/fl_draw.H ../FL/Enumerations.H ../FL/Fl_Device.H
-Fl_arg.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
-Fl_arg.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Pixmap.H
+Fl_arg.o: ../FL/Enumerations.H ../FL/x.H ../FL/Fl_Window.H ../FL/Fl_Window.H
+Fl_arg.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Bitmap.H
+Fl_arg.o: ../FL/Fl_Image.H ../FL/Fl_Tooltip.H ../FL/Fl_Widget.H
+Fl_arg.o: ../FL/filename.H ../FL/fl_draw.H ../FL/Enumerations.H
+Fl_arg.o: ../FL/Fl_Device.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H
+Fl_arg.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H
Fl_arg.o: ../FL/Fl_RGB_Image.H flstring.h ../FL/Fl_Export.H ../config.h
Fl_compose.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
-Fl_compose.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/x.H ../FL/Fl_Window.H
+Fl_compose.o: ../FL/Enumerations.H ../FL/x.H ../FL/Fl_Window.H
Fl_display.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
-Fl_display.o: ../FL/Xutf8.h ../FL/Enumerations.H flstring.h ../FL/Fl_Export.H
-Fl_display.o: ../config.h
+Fl_display.o: ../FL/Enumerations.H flstring.h ../FL/Fl_Export.H ../config.h
Fl_get_key.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
-Fl_get_key.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/x.H ../FL/Fl_Window.H
+Fl_get_key.o: ../FL/Enumerations.H ../FL/x.H ../FL/Fl_Window.H
Fl_get_system_colors.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H
-Fl_get_system_colors.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H
-Fl_get_system_colors.o: ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H
-Fl_get_system_colors.o: ../FL/Enumerations.H ../FL/Fl_Window.H
-Fl_get_system_colors.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Device.H
+Fl_get_system_colors.o: ../FL/fl_types.h ../FL/Enumerations.H ../FL/fl_draw.H
+Fl_get_system_colors.o: ../FL/x.H ../FL/Fl_Window.H ../FL/Enumerations.H
+Fl_get_system_colors.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Widget.H
+Fl_get_system_colors.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Device.H
Fl_get_system_colors.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H
-Fl_get_system_colors.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H
-Fl_get_system_colors.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H ../FL/math.h
-Fl_get_system_colors.o: ../FL/fl_utf8.h flstring.h ../FL/Fl_Export.H
-Fl_get_system_colors.o: ../config.h ../FL/Fl_Tiled_Image.H tile.xpm
+Fl_get_system_colors.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H
+Fl_get_system_colors.o: ../FL/Fl_RGB_Image.H ../FL/math.h ../FL/fl_utf8.h
+Fl_get_system_colors.o: flstring.h ../FL/Fl_Export.H ../config.h
+Fl_get_system_colors.o: ../FL/Fl_Tiled_Image.H tile.xpm
Fl_grab.o: ../config.h ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H
-Fl_grab.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H ../FL/x.H
-Fl_grab.o: ../FL/Fl_Window.H
+Fl_grab.o: ../FL/fl_types.h ../FL/Enumerations.H ../FL/x.H ../FL/Fl_Window.H
Fl_lock.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
-Fl_lock.o: ../FL/Xutf8.h ../FL/Enumerations.H ../config.h
+Fl_lock.o: ../FL/Enumerations.H ../config.h
Fl_own_colormap.o: ../config.h ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H
-Fl_own_colormap.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H
-Fl_own_colormap.o: ../FL/x.H ../FL/Fl_Window.H
+Fl_own_colormap.o: ../FL/fl_types.h ../FL/Enumerations.H ../FL/x.H
+Fl_own_colormap.o: ../FL/Fl_Window.H
Fl_visual.o: ../config.h ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H
-Fl_visual.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H ../FL/x.H
+Fl_visual.o: ../FL/fl_types.h ../FL/Enumerations.H ../FL/x.H
Fl_visual.o: ../FL/Fl_Window.H
Fl_x.o: ../config.h ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H
-Fl_x.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H ../FL/x.H
-Fl_x.o: ../FL/Fl_Window.H ../FL/Fl_Window.H ../FL/Fl_Group.H
-Fl_x.o: ../FL/Fl_Widget.H ../FL/fl_utf8.h ../FL/Fl_Tooltip.H
+Fl_x.o: ../FL/fl_types.h ../FL/Enumerations.H ../FL/x.H ../FL/Fl_Window.H
+Fl_x.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Widget.H
+Fl_x.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/fl_utf8.h ../FL/Fl_Tooltip.H
Fl_x.o: ../FL/Fl_Widget.H ../FL/fl_draw.H ../FL/Enumerations.H
Fl_x.o: ../FL/Fl_Device.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H
-Fl_x.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Pixmap.H
-Fl_x.o: ../FL/Fl_RGB_Image.H ../FL/Fl_Paged_Device.H flstring.h
-Fl_x.o: ../FL/Fl_Export.H
+Fl_x.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H
+Fl_x.o: ../FL/Fl_RGB_Image.H ../FL/Fl_Paged_Device.H ../FL/Fl_Shared_Image.H
+Fl_x.o: ../FL/fl_ask.H ../FL/filename.H flstring.h ../FL/Fl_Export.H Xutf8.h
filename_absolute.o: ../FL/filename.H ../FL/fl_utf8.h flstring.h
filename_absolute.o: ../FL/Fl_Export.H ../config.h
filename_expand.o: ../FL/filename.H ../FL/fl_utf8.h flstring.h
@@ -682,305 +738,313 @@ filename_list.o: ../FL/Fl_Export.H ../config.h
filename_match.o: ../FL/filename.H
filename_setext.o: ../FL/filename.H flstring.h ../FL/Fl_Export.H ../config.h
fl_arc.o: ../FL/fl_draw.H ../FL/x.H ../FL/Enumerations.H ../FL/Fl_Export.H
-fl_arc.o: ../FL/fl_types.h ../FL/Fl_Window.H ../FL/Xutf8.h
-fl_arc.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Group.H
-fl_arc.o: ../FL/Fl_Widget.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
-fl_arc.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
-fl_arc.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
+fl_arc.o: ../FL/fl_types.h ../FL/Fl_Window.H ../FL/Enumerations.H
+fl_arc.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Widget.H
+fl_arc.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Device.H
+fl_arc.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
+fl_arc.o: ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
fl_arc.o: ../FL/math.h
fl_arci.o: ../FL/fl_draw.H ../FL/x.H ../FL/Enumerations.H ../FL/Fl_Export.H
-fl_arci.o: ../FL/fl_types.h ../FL/Fl_Window.H ../FL/Xutf8.h
-fl_arci.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Group.H
-fl_arci.o: ../FL/Fl_Widget.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
-fl_arci.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
-fl_arci.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
+fl_arci.o: ../FL/fl_types.h ../FL/Fl_Window.H ../FL/Enumerations.H
+fl_arci.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Widget.H
+fl_arci.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Device.H
+fl_arci.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
+fl_arci.o: ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
fl_arci.o: ../config.h
fl_ask.o: flstring.h ../FL/Fl_Export.H ../config.h ../FL/Fl.H ../FL/fl_utf8.h
-fl_ask.o: ../FL/Fl_Export.H ../FL/fl_types.h ../FL/Xutf8.h
-fl_ask.o: ../FL/Enumerations.H ../FL/fl_ask.H ../FL/Fl_Box.H
-fl_ask.o: ../FL/Fl_Widget.H ../FL/Fl_Button.H ../FL/Fl_Return_Button.H
-fl_ask.o: ../FL/Fl_Button.H ../FL/Fl_Window.H ../FL/Fl_Group.H
+fl_ask.o: ../FL/Fl_Export.H ../FL/fl_types.h ../FL/Enumerations.H
+fl_ask.o: ../FL/fl_ask.H ../FL/Fl_Box.H ../FL/Fl_Widget.H ../FL/Fl_Button.H
+fl_ask.o: ../FL/Fl_Return_Button.H ../FL/Fl_Button.H ../FL/Fl_Window.H
+fl_ask.o: ../FL/Fl_Group.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H
fl_ask.o: ../FL/Fl_Input.H ../FL/Fl_Input_.H ../FL/Fl_Secret_Input.H
fl_ask.o: ../FL/Fl_Input.H ../FL/x.H ../FL/Fl_Window.H ../FL/fl_draw.H
fl_ask.o: ../FL/Enumerations.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
fl_ask.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
-fl_ask.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
+fl_ask.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
fl_boxtype.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
-fl_boxtype.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Widget.H
-fl_boxtype.o: ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H
-fl_boxtype.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Group.H
-fl_boxtype.o: ../FL/Fl_Widget.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
-fl_boxtype.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
-fl_boxtype.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
+fl_boxtype.o: ../FL/Enumerations.H ../FL/Fl_Widget.H ../FL/fl_draw.H
+fl_boxtype.o: ../FL/x.H ../FL/Fl_Window.H ../FL/Enumerations.H
+fl_boxtype.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Widget.H
+fl_boxtype.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Device.H
+fl_boxtype.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
+fl_boxtype.o: ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
fl_boxtype.o: ../config.h
-fl_color.o: Fl_XColor.H ../config.h ../FL/Enumerations.H ../FL/Fl.H
-fl_color.o: ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h ../FL/Xutf8.h
-fl_color.o: ../FL/Enumerations.H ../FL/x.H ../FL/Fl_Window.H ../FL/fl_draw.H
-fl_color.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Widget.H
-fl_color.o: ../FL/Fl_Device.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H
-fl_color.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H
+fl_color.o: Fl_XColor.H ../config.h ../FL/Enumerations.H ../FL/Fl_Export.H
+fl_color.o: ../FL/fl_types.h ../FL/Fl.H ../FL/fl_utf8.h ../FL/Enumerations.H
+fl_color.o: ../FL/x.H ../FL/Fl_Window.H ../FL/fl_draw.H ../FL/Fl_Window.H
+fl_color.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Bitmap.H
+fl_color.o: ../FL/Fl_Image.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
+fl_color.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
fl_color.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H fl_cmap.h
fl_cursor.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
-fl_cursor.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Window.H
-fl_cursor.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/x.H ../FL/Fl_Window.H
-fl_cursor.o: ../FL/fl_draw.H ../FL/Enumerations.H ../FL/Fl_Device.H
-fl_cursor.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
-fl_cursor.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Pixmap.H
-fl_cursor.o: ../FL/Fl_RGB_Image.H
+fl_cursor.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Group.H
+fl_cursor.o: ../FL/Fl_Widget.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H
+fl_cursor.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H ../FL/x.H
+fl_cursor.o: ../FL/Fl_Window.H ../FL/fl_draw.H ../FL/Enumerations.H
+fl_cursor.o: ../FL/Fl_Device.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H
+fl_cursor.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H fl_cursor_wait.xpm
+fl_cursor.o: fl_cursor_help.xpm fl_cursor_nwse.xpm fl_cursor_nesw.xpm
+fl_cursor.o: fl_cursor_none.xpm
fl_curve.o: ../FL/fl_draw.H ../FL/x.H ../FL/Enumerations.H ../FL/Fl_Export.H
-fl_curve.o: ../FL/fl_types.h ../FL/Fl_Window.H ../FL/Xutf8.h
-fl_curve.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Group.H
-fl_curve.o: ../FL/Fl_Widget.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
-fl_curve.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
-fl_curve.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
+fl_curve.o: ../FL/fl_types.h ../FL/Fl_Window.H ../FL/Enumerations.H
+fl_curve.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Widget.H
+fl_curve.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Device.H
+fl_curve.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
+fl_curve.o: ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
fl_diamond_box.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H
-fl_diamond_box.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H
-fl_diamond_box.o: ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H
-fl_diamond_box.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Group.H
-fl_diamond_box.o: ../FL/Fl_Widget.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
-fl_diamond_box.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
-fl_diamond_box.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
+fl_diamond_box.o: ../FL/fl_types.h ../FL/Enumerations.H ../FL/fl_draw.H
+fl_diamond_box.o: ../FL/x.H ../FL/Fl_Window.H ../FL/Enumerations.H
+fl_diamond_box.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Widget.H
+fl_diamond_box.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Device.H
+fl_diamond_box.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
+fl_diamond_box.o: ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
fl_dnd.o: fl_dnd_x.cxx ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H
-fl_dnd.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H
-fl_dnd.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/x.H
-fl_dnd.o: ../FL/Fl_Window.H flstring.h ../FL/Fl_Export.H ../config.h
+fl_dnd.o: ../FL/fl_types.h ../FL/Enumerations.H ../FL/Fl_Window.H
+fl_dnd.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Bitmap.H
+fl_dnd.o: ../FL/Fl_Image.H ../FL/x.H ../FL/Fl_Window.H flstring.h
+fl_dnd.o: ../FL/Fl_Export.H ../config.h
fl_draw.o: ../FL/fl_utf8.h ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H
-fl_draw.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H
-fl_draw.o: ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H ../FL/Enumerations.H
-fl_draw.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Widget.H
-fl_draw.o: ../FL/Fl_Device.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H
-fl_draw.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H
+fl_draw.o: ../FL/fl_types.h ../FL/Enumerations.H ../FL/fl_draw.H ../FL/x.H
+fl_draw.o: ../FL/Fl_Window.H ../FL/Enumerations.H ../FL/Fl_Window.H
+fl_draw.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Bitmap.H
+fl_draw.o: ../FL/Fl_Image.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
+fl_draw.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
fl_draw.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H flstring.h
fl_draw.o: ../FL/Fl_Export.H ../config.h
fl_draw_image.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H
-fl_draw_image.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H
-fl_draw_image.o: ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H
-fl_draw_image.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Group.H
-fl_draw_image.o: ../FL/Fl_Widget.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
-fl_draw_image.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
-fl_draw_image.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
+fl_draw_image.o: ../FL/fl_types.h ../FL/Enumerations.H ../FL/fl_draw.H
+fl_draw_image.o: ../FL/x.H ../FL/Fl_Window.H ../FL/Enumerations.H
+fl_draw_image.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Widget.H
+fl_draw_image.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Device.H
+fl_draw_image.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
+fl_draw_image.o: ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
fl_draw_image.o: Fl_XColor.H ../config.h flstring.h ../FL/Fl_Export.H
fl_draw_pixmap.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H
-fl_draw_pixmap.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H
-fl_draw_pixmap.o: ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H
-fl_draw_pixmap.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Group.H
-fl_draw_pixmap.o: ../FL/Fl_Widget.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
-fl_draw_pixmap.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
-fl_draw_pixmap.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
+fl_draw_pixmap.o: ../FL/fl_types.h ../FL/Enumerations.H ../FL/fl_draw.H
+fl_draw_pixmap.o: ../FL/x.H ../FL/Fl_Window.H ../FL/Enumerations.H
+fl_draw_pixmap.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Widget.H
+fl_draw_pixmap.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Device.H
+fl_draw_pixmap.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
+fl_draw_pixmap.o: ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
fl_draw_pixmap.o: flstring.h ../FL/Fl_Export.H ../config.h
fl_encoding_latin1.o: ../FL/fl_draw.H ../FL/x.H ../FL/Enumerations.H
fl_encoding_latin1.o: ../FL/Fl_Export.H ../FL/fl_types.h ../FL/Fl_Window.H
-fl_encoding_latin1.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Window.H
-fl_encoding_latin1.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Device.H
-fl_encoding_latin1.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H
-fl_encoding_latin1.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H
-fl_encoding_latin1.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H flstring.h
-fl_encoding_latin1.o: ../FL/Fl_Export.H ../config.h
+fl_encoding_latin1.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Group.H
+fl_encoding_latin1.o: ../FL/Fl_Widget.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H
+fl_encoding_latin1.o: ../FL/Fl_Device.H ../FL/Fl_Plugin.H
+fl_encoding_latin1.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H
+fl_encoding_latin1.o: ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H
+fl_encoding_latin1.o: ../FL/Fl_RGB_Image.H flstring.h ../FL/Fl_Export.H
+fl_encoding_latin1.o: ../config.h
fl_encoding_mac_roman.o: ../FL/fl_draw.H ../FL/x.H ../FL/Enumerations.H
fl_encoding_mac_roman.o: ../FL/Fl_Export.H ../FL/fl_types.h ../FL/Fl_Window.H
-fl_encoding_mac_roman.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Window.H
-fl_encoding_mac_roman.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Device.H
-fl_encoding_mac_roman.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H
-fl_encoding_mac_roman.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H
-fl_encoding_mac_roman.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H flstring.h
-fl_encoding_mac_roman.o: ../FL/Fl_Export.H ../config.h
+fl_encoding_mac_roman.o: ../FL/Enumerations.H ../FL/Fl_Window.H
+fl_encoding_mac_roman.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Bitmap.H
+fl_encoding_mac_roman.o: ../FL/Fl_Image.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
+fl_encoding_mac_roman.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H
+fl_encoding_mac_roman.o: ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H
+fl_encoding_mac_roman.o: ../FL/Fl_RGB_Image.H flstring.h ../FL/Fl_Export.H
+fl_encoding_mac_roman.o: ../config.h
fl_engraved_label.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H
-fl_engraved_label.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H
-fl_engraved_label.o: ../FL/Fl_Widget.H ../FL/fl_draw.H ../FL/x.H
-fl_engraved_label.o: ../FL/Fl_Window.H ../FL/Enumerations.H ../FL/Fl_Window.H
-fl_engraved_label.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Device.H
-fl_engraved_label.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H
-fl_engraved_label.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H
-fl_engraved_label.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
+fl_engraved_label.o: ../FL/fl_types.h ../FL/Enumerations.H ../FL/Fl_Widget.H
+fl_engraved_label.o: ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H
+fl_engraved_label.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Group.H
+fl_engraved_label.o: ../FL/Fl_Widget.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H
+fl_engraved_label.o: ../FL/Fl_Device.H ../FL/Fl_Plugin.H
+fl_engraved_label.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H
+fl_engraved_label.o: ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
fl_file_dir.o: flstring.h ../FL/Fl_Export.H ../config.h ../FL/filename.H
fl_file_dir.o: ../FL/Fl_File_Chooser.H ../FL/Fl.H ../FL/fl_utf8.h
-fl_file_dir.o: ../FL/Fl_Export.H ../FL/fl_types.h ../FL/Xutf8.h
-fl_file_dir.o: ../FL/Enumerations.H ../FL/Fl_Double_Window.H
-fl_file_dir.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Choice.H
-fl_file_dir.o: ../FL/Fl_Menu_.H ../FL/Fl_Widget.H ../FL/Fl_Menu_Item.H
-fl_file_dir.o: ../FL/Fl_Image.H ../FL/Fl_Menu_Button.H ../FL/Fl_Button.H
-fl_file_dir.o: ../FL/Fl_Preferences.H ../FL/Fl_Tile.H ../FL/Fl_Group.H
-fl_file_dir.o: ../FL/Fl_File_Browser.H ../FL/Fl_Browser.H ../FL/Fl_Browser_.H
-fl_file_dir.o: ../FL/Fl_Scrollbar.H ../FL/Fl_Slider.H ../FL/Fl_Valuator.H
+fl_file_dir.o: ../FL/Fl_Export.H ../FL/fl_types.h ../FL/Enumerations.H
+fl_file_dir.o: ../FL/Fl_Double_Window.H ../FL/Fl_Window.H ../FL/Fl_Group.H
+fl_file_dir.o: ../FL/Fl_Choice.H ../FL/Fl_Menu_.H ../FL/Fl_Widget.H
+fl_file_dir.o: ../FL/Fl_Menu_Item.H ../FL/Fl_Image.H ../FL/Fl_Menu_Button.H
+fl_file_dir.o: ../FL/Fl_Button.H ../FL/Fl_Preferences.H ../FL/Fl_Tile.H
+fl_file_dir.o: ../FL/Fl_Group.H ../FL/Fl_File_Browser.H ../FL/Fl_Browser.H
fl_file_dir.o: ../FL/Fl_File_Icon.H ../FL/Fl.H ../FL/filename.H
fl_file_dir.o: ../FL/Fl_Box.H ../FL/Fl_Check_Button.H ../FL/Fl_Light_Button.H
fl_file_dir.o: ../FL/Fl_Button.H ../FL/Fl_File_Input.H ../FL/Fl_Input.H
fl_file_dir.o: ../FL/Fl_Input_.H ../FL/Fl_Return_Button.H ../FL/fl_ask.H
fl_font.o: flstring.h ../FL/Fl_Export.H ../config.h ../FL/Fl.H
-fl_font.o: ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h ../FL/Xutf8.h
+fl_font.o: ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
fl_font.o: ../FL/Enumerations.H ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H
fl_font.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Group.H
-fl_font.o: ../FL/Fl_Widget.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
-fl_font.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
-fl_font.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H Fl_Font.H
-fl_font.o: fl_font_xft.cxx
+fl_font.o: ../FL/Fl_Widget.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H
+fl_font.o: ../FL/Fl_Device.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H
+fl_font.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H
+fl_font.o: ../FL/Fl_RGB_Image.H Fl_Font.H fl_font_xft.cxx
+fl_gleam.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
+fl_gleam.o: ../FL/Enumerations.H ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H
+fl_gleam.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Group.H
+fl_gleam.o: ../FL/Fl_Widget.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H
+fl_gleam.o: ../FL/Fl_Device.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H
+fl_gleam.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H
+fl_gleam.o: ../FL/Fl_RGB_Image.H
fl_gtk.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
-fl_gtk.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/fl_draw.H ../FL/x.H
-fl_gtk.o: ../FL/Fl_Window.H ../FL/Enumerations.H ../FL/Fl_Window.H
-fl_gtk.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Device.H
-fl_gtk.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
-fl_gtk.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Pixmap.H
+fl_gtk.o: ../FL/Enumerations.H ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H
+fl_gtk.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Group.H
+fl_gtk.o: ../FL/Fl_Widget.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H
+fl_gtk.o: ../FL/Fl_Device.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H
+fl_gtk.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H
fl_gtk.o: ../FL/Fl_RGB_Image.H
fl_labeltype.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
-fl_labeltype.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Widget.H
-fl_labeltype.o: ../FL/Fl_Group.H ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H
+fl_labeltype.o: ../FL/Enumerations.H ../FL/Fl_Widget.H ../FL/Fl_Group.H
+fl_labeltype.o: ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H
fl_labeltype.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Group.H
-fl_labeltype.o: ../FL/Fl_Widget.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
-fl_labeltype.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
-fl_labeltype.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
-fl_labeltype.o: ../FL/Fl_Input_.H
+fl_labeltype.o: ../FL/Fl_Widget.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H
+fl_labeltype.o: ../FL/Fl_Device.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H
+fl_labeltype.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H
+fl_labeltype.o: ../FL/Fl_RGB_Image.H ../FL/Fl_Input_.H
fl_line_style.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H
-fl_line_style.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H
-fl_line_style.o: ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H
-fl_line_style.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Group.H
-fl_line_style.o: ../FL/Fl_Widget.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
-fl_line_style.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
-fl_line_style.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
+fl_line_style.o: ../FL/fl_types.h ../FL/Enumerations.H ../FL/fl_draw.H
+fl_line_style.o: ../FL/x.H ../FL/Fl_Window.H ../FL/Enumerations.H
+fl_line_style.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Widget.H
+fl_line_style.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Device.H
+fl_line_style.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
+fl_line_style.o: ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
fl_line_style.o: ../FL/Fl_Printer.H ../FL/Fl_Paged_Device.H
fl_line_style.o: ../FL/Fl_PostScript.H flstring.h ../FL/Fl_Export.H
fl_line_style.o: ../config.h
fl_open_uri.o: ../FL/filename.H flstring.h ../FL/Fl_Export.H ../config.h
fl_oval_box.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
-fl_oval_box.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/fl_draw.H ../FL/x.H
+fl_oval_box.o: ../FL/Enumerations.H ../FL/fl_draw.H ../FL/x.H
fl_oval_box.o: ../FL/Fl_Window.H ../FL/Enumerations.H ../FL/Fl_Window.H
-fl_oval_box.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Device.H
-fl_oval_box.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
-fl_oval_box.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Pixmap.H
-fl_oval_box.o: ../FL/Fl_RGB_Image.H
+fl_oval_box.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Bitmap.H
+fl_oval_box.o: ../FL/Fl_Image.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
+fl_oval_box.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
+fl_oval_box.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
fl_overlay.o: ../FL/x.H ../FL/Enumerations.H ../FL/Fl_Export.H
-fl_overlay.o: ../FL/fl_types.h ../FL/Fl_Window.H ../FL/Xutf8.h
-fl_overlay.o: ../FL/fl_draw.H ../FL/Enumerations.H ../FL/Fl_Window.H
-fl_overlay.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Device.H
-fl_overlay.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
-fl_overlay.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Pixmap.H
+fl_overlay.o: ../FL/fl_types.h ../FL/Fl_Window.H ../FL/fl_draw.H
+fl_overlay.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Group.H
+fl_overlay.o: ../FL/Fl_Widget.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H
+fl_overlay.o: ../FL/Fl_Device.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H
+fl_overlay.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H
fl_overlay.o: ../FL/Fl_RGB_Image.H
fl_overlay_visual.o: ../config.h
fl_plastic.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
-fl_plastic.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/fl_draw.H ../FL/x.H
+fl_plastic.o: ../FL/Enumerations.H ../FL/fl_draw.H ../FL/x.H
fl_plastic.o: ../FL/Fl_Window.H ../FL/Enumerations.H ../FL/Fl_Window.H
-fl_plastic.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Device.H
-fl_plastic.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
-fl_plastic.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Pixmap.H
-fl_plastic.o: ../FL/Fl_RGB_Image.H flstring.h ../FL/Fl_Export.H ../config.h
+fl_plastic.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Bitmap.H
+fl_plastic.o: ../FL/Fl_Image.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
+fl_plastic.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
+fl_plastic.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H flstring.h
+fl_plastic.o: ../FL/Fl_Export.H ../config.h
fl_read_image.o: ../FL/x.H ../FL/Enumerations.H ../FL/Fl_Export.H
-fl_read_image.o: ../FL/fl_types.h ../FL/Fl_Window.H ../FL/Xutf8.h ../FL/Fl.H
+fl_read_image.o: ../FL/fl_types.h ../FL/Fl_Window.H ../FL/Fl.H
fl_read_image.o: ../FL/fl_utf8.h ../FL/fl_draw.H ../FL/Enumerations.H
fl_read_image.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Widget.H
-fl_read_image.o: ../FL/Fl_Device.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H
-fl_read_image.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H
-fl_read_image.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H flstring.h
-fl_read_image.o: ../FL/Fl_Export.H ../config.h
+fl_read_image.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Device.H
+fl_read_image.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
+fl_read_image.o: ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
+fl_read_image.o: flstring.h ../FL/Fl_Export.H ../config.h
fl_rect.o: ../config.h ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H
-fl_rect.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H
-fl_rect.o: ../FL/Fl_Widget.H ../FL/Fl_Printer.H ../FL/x.H ../FL/Fl_Window.H
+fl_rect.o: ../FL/fl_types.h ../FL/Enumerations.H ../FL/Fl_Widget.H
+fl_rect.o: ../FL/Fl_Printer.H ../FL/x.H ../FL/Fl_Window.H
fl_rect.o: ../FL/Fl_Paged_Device.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
fl_rect.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
-fl_rect.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
+fl_rect.o: ../FL/Fl_Pixmap.H ../FL/Fl_Image.H ../FL/Fl_RGB_Image.H
fl_rect.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Widget.H
-fl_rect.o: ../FL/fl_draw.H ../FL/Enumerations.H ../FL/Fl_PostScript.H
+fl_rect.o: ../FL/Fl_Bitmap.H ../FL/fl_draw.H ../FL/Enumerations.H
+fl_rect.o: ../FL/Fl_PostScript.H
fl_round_box.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
-fl_round_box.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/fl_draw.H ../FL/x.H
+fl_round_box.o: ../FL/Enumerations.H ../FL/fl_draw.H ../FL/x.H
fl_round_box.o: ../FL/Fl_Window.H ../FL/Enumerations.H ../FL/Fl_Window.H
-fl_round_box.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Device.H
-fl_round_box.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
-fl_round_box.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Pixmap.H
-fl_round_box.o: ../FL/Fl_RGB_Image.H
+fl_round_box.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Bitmap.H
+fl_round_box.o: ../FL/Fl_Image.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
+fl_round_box.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
+fl_round_box.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
fl_rounded_box.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H
-fl_rounded_box.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H
-fl_rounded_box.o: ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H
-fl_rounded_box.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Group.H
-fl_rounded_box.o: ../FL/Fl_Widget.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
-fl_rounded_box.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
-fl_rounded_box.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
+fl_rounded_box.o: ../FL/fl_types.h ../FL/Enumerations.H ../FL/fl_draw.H
+fl_rounded_box.o: ../FL/x.H ../FL/Fl_Window.H ../FL/Enumerations.H
+fl_rounded_box.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Widget.H
+fl_rounded_box.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Device.H
+fl_rounded_box.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
+fl_rounded_box.o: ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
fl_set_font.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
-fl_set_font.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/x.H ../FL/Fl_Window.H
+fl_set_font.o: ../FL/Enumerations.H ../FL/x.H ../FL/Fl_Window.H
fl_set_font.o: ../FL/fl_draw.H ../FL/Enumerations.H ../FL/Fl_Window.H
-fl_set_font.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Device.H
-fl_set_font.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
-fl_set_font.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Pixmap.H
-fl_set_font.o: ../FL/Fl_RGB_Image.H flstring.h ../FL/Fl_Export.H ../config.h
-fl_set_font.o: Fl_Font.H
+fl_set_font.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Bitmap.H
+fl_set_font.o: ../FL/Fl_Image.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
+fl_set_font.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
+fl_set_font.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H flstring.h
+fl_set_font.o: ../FL/Fl_Export.H ../config.h Fl_Font.H
fl_set_fonts.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
-fl_set_fonts.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/x.H
-fl_set_fonts.o: ../FL/Fl_Window.H Fl_Font.H ../config.h flstring.h
-fl_set_fonts.o: ../FL/Fl_Export.H fl_set_fonts_xft.cxx
+fl_set_fonts.o: ../FL/Enumerations.H ../FL/x.H ../FL/Fl_Window.H Fl_Font.H
+fl_set_fonts.o: ../config.h flstring.h ../FL/Fl_Export.H fl_set_fonts_xft.cxx
fl_scroll_area.o: ../config.h ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H
-fl_scroll_area.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H
-fl_scroll_area.o: ../FL/x.H ../FL/Fl_Window.H ../FL/fl_draw.H
-fl_scroll_area.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Group.H
-fl_scroll_area.o: ../FL/Fl_Widget.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
-fl_scroll_area.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
-fl_scroll_area.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
+fl_scroll_area.o: ../FL/fl_types.h ../FL/Enumerations.H ../FL/x.H
+fl_scroll_area.o: ../FL/Fl_Window.H ../FL/fl_draw.H ../FL/Enumerations.H
+fl_scroll_area.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Widget.H
+fl_scroll_area.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Device.H
+fl_scroll_area.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
+fl_scroll_area.o: ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
fl_shadow_box.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H
-fl_shadow_box.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H
-fl_shadow_box.o: ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H
-fl_shadow_box.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Group.H
-fl_shadow_box.o: ../FL/Fl_Widget.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
-fl_shadow_box.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
-fl_shadow_box.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
+fl_shadow_box.o: ../FL/fl_types.h ../FL/Enumerations.H ../FL/fl_draw.H
+fl_shadow_box.o: ../FL/x.H ../FL/Fl_Window.H ../FL/Enumerations.H
+fl_shadow_box.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Widget.H
+fl_shadow_box.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Device.H
+fl_shadow_box.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
+fl_shadow_box.o: ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
fl_shortcut.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
-fl_shortcut.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Widget.H
-fl_shortcut.o: ../FL/Fl_Button.H ../FL/Fl_Widget.H ../FL/fl_draw.H ../FL/x.H
-fl_shortcut.o: ../FL/Fl_Window.H ../FL/Enumerations.H ../FL/Fl_Window.H
-fl_shortcut.o: ../FL/Fl_Group.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
-fl_shortcut.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
-fl_shortcut.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
+fl_shortcut.o: ../FL/Enumerations.H ../FL/Fl_Widget.H ../FL/Fl_Button.H
+fl_shortcut.o: ../FL/Fl_Widget.H ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H
+fl_shortcut.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Group.H
+fl_shortcut.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Device.H
+fl_shortcut.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
+fl_shortcut.o: ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
fl_shortcut.o: flstring.h ../FL/Fl_Export.H ../config.h
fl_show_colormap.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H
-fl_show_colormap.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H
+fl_show_colormap.o: ../FL/fl_types.h ../FL/Enumerations.H
fl_show_colormap.o: ../FL/Fl_Single_Window.H ../FL/Fl_Window.H
fl_show_colormap.o: ../FL/fl_draw.H ../FL/x.H ../FL/Enumerations.H
fl_show_colormap.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Widget.H
-fl_show_colormap.o: ../FL/Fl_Device.H ../FL/Fl_Plugin.H
-fl_show_colormap.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
-fl_show_colormap.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
+fl_show_colormap.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Device.H
+fl_show_colormap.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
+fl_show_colormap.o: ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
fl_show_colormap.o: ../FL/fl_show_colormap.H ../config.h
fl_symbols.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
-fl_symbols.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/fl_draw.H ../FL/x.H
+fl_symbols.o: ../FL/Enumerations.H ../FL/fl_draw.H ../FL/x.H
fl_symbols.o: ../FL/Fl_Window.H ../FL/Enumerations.H ../FL/Fl_Window.H
-fl_symbols.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Device.H
-fl_symbols.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
-fl_symbols.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Pixmap.H
-fl_symbols.o: ../FL/Fl_RGB_Image.H ../FL/math.h flstring.h ../FL/Fl_Export.H
-fl_symbols.o: ../config.h
+fl_symbols.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Bitmap.H
+fl_symbols.o: ../FL/Fl_Image.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
+fl_symbols.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
+fl_symbols.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H ../FL/math.h flstring.h
+fl_symbols.o: ../FL/Fl_Export.H ../config.h
fl_vertex.o: ../config.h ../FL/fl_draw.H ../FL/x.H ../FL/Enumerations.H
fl_vertex.o: ../FL/Fl_Export.H ../FL/fl_types.h ../FL/Fl_Window.H
-fl_vertex.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Window.H
-fl_vertex.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Device.H
-fl_vertex.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
-fl_vertex.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Pixmap.H
+fl_vertex.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Group.H
+fl_vertex.o: ../FL/Fl_Widget.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H
+fl_vertex.o: ../FL/Fl_Device.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H
+fl_vertex.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H
fl_vertex.o: ../FL/Fl_RGB_Image.H ../FL/Fl.H ../FL/fl_utf8.h ../FL/math.h
screen_xywh.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
-screen_xywh.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/x.H ../FL/Fl_Window.H
-screen_xywh.o: ../config.h
-fl_utf8.o: ../config.h ../FL/filename.H ../FL/Xutf8.h ../FL/fl_utf8.h
+screen_xywh.o: ../FL/Enumerations.H ../FL/x.H ../FL/Fl_Window.H ../config.h
+fl_utf8.o: ../config.h ../FL/filename.H Xutf8.h ../FL/fl_utf8.h
ps_image.o: ../FL/Fl_PostScript.H ../FL/Fl_Paged_Device.H ../FL/Fl_Device.H
ps_image.o: ../FL/x.H ../FL/Enumerations.H ../FL/Fl_Export.H ../FL/fl_types.h
-ps_image.o: ../FL/Fl_Window.H ../FL/Xutf8.h ../FL/Fl_Plugin.H
-ps_image.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
-ps_image.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
-ps_image.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Widget.H
+ps_image.o: ../FL/Fl_Window.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H
+ps_image.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H
+ps_image.o: ../FL/Fl_Image.H ../FL/Fl_RGB_Image.H ../FL/Fl_Window.H
+ps_image.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Bitmap.H
ps_image.o: ../FL/fl_draw.H ../FL/Enumerations.H ../FL/Fl.H ../FL/fl_utf8.h
forms_compatability.o: ../FL/forms.H ../FL/Fl.H ../FL/fl_utf8.h
-forms_compatability.o: ../FL/Fl_Export.H ../FL/fl_types.h ../FL/Xutf8.h
+forms_compatability.o: ../FL/Fl_Export.H ../FL/fl_types.h
forms_compatability.o: ../FL/Enumerations.H ../FL/Fl_Group.H
forms_compatability.o: ../FL/Fl_Widget.H ../FL/Fl_Window.H ../FL/fl_draw.H
forms_compatability.o: ../FL/x.H ../FL/Enumerations.H ../FL/Fl_Window.H
-forms_compatability.o: ../FL/Fl_Device.H ../FL/Fl_Plugin.H
-forms_compatability.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H
-forms_compatability.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Pixmap.H
+forms_compatability.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Device.H
+forms_compatability.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H
+forms_compatability.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H
forms_compatability.o: ../FL/Fl_RGB_Image.H ../FL/Fl_FormsBitmap.H
-forms_compatability.o: ../FL/Fl_Bitmap.H ../FL/Fl_FormsPixmap.H
-forms_compatability.o: ../FL/Fl_Pixmap.H ../FL/Fl_Box.H ../FL/Fl_Browser.H
-forms_compatability.o: ../FL/Fl_Browser_.H ../FL/Fl_Scrollbar.H
-forms_compatability.o: ../FL/Fl_Slider.H ../FL/Fl_Valuator.H ../FL/Fl.H
-forms_compatability.o: ../FL/Fl_Button.H ../FL/Fl_Light_Button.H
-forms_compatability.o: ../FL/Fl_Round_Button.H ../FL/Fl_Check_Button.H
-forms_compatability.o: ../FL/Fl_Chart.H ../FL/Fl_Choice.H ../FL/Fl_Menu_.H
+forms_compatability.o: ../FL/Fl_FormsPixmap.H ../FL/Fl_Pixmap.H
+forms_compatability.o: ../FL/Fl_Box.H ../FL/Fl_Browser.H ../FL/Fl_Button.H
+forms_compatability.o: ../FL/Fl_Light_Button.H ../FL/Fl_Round_Button.H
+forms_compatability.o: ../FL/Fl_Check_Button.H ../FL/Fl_Chart.H
+forms_compatability.o: ../FL/Fl_Choice.H ../FL/Fl_Menu_.H
forms_compatability.o: ../FL/Fl_Menu_Item.H ../FL/Fl_Clock.H
forms_compatability.o: ../FL/Fl_Counter.H ../FL/Fl_Dial.H ../FL/Fl_Free.H
forms_compatability.o: ../FL/fl_ask.H ../FL/fl_show_colormap.H
-forms_compatability.o: ../FL/filename.H ../FL/Fl_File_Chooser.H
+forms_compatability.o: ../FL/filename.H ../FL/Fl_File_Chooser.H ../FL/Fl.H
forms_compatability.o: ../FL/Fl_Double_Window.H ../FL/Fl_Group.H
forms_compatability.o: ../FL/Fl_Choice.H ../FL/Fl_Menu_Button.H
forms_compatability.o: ../FL/Fl_Button.H ../FL/Fl_Preferences.H
@@ -990,230 +1054,238 @@ forms_compatability.o: ../FL/Fl_Check_Button.H ../FL/Fl_File_Input.H
forms_compatability.o: ../FL/Fl_Input.H ../FL/Fl_Input_.H
forms_compatability.o: ../FL/Fl_Return_Button.H ../FL/fl_ask.H
forms_compatability.o: ../FL/Fl_Input.H ../FL/Fl_Menu_Button.H
-forms_compatability.o: ../FL/Fl_Positioner.H ../FL/Fl_Value_Slider.H
+forms_compatability.o: ../FL/Fl_Positioner.H ../FL/Fl_Slider.H
+forms_compatability.o: ../FL/Fl_Valuator.H ../FL/Fl_Value_Slider.H
forms_compatability.o: ../FL/Fl_Timer.H ../FL/Fl_Repeat_Button.H
forms_bitmap.o: ../FL/forms.H ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H
-forms_bitmap.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H
-forms_bitmap.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Window.H
-forms_bitmap.o: ../FL/fl_draw.H ../FL/x.H ../FL/Enumerations.H
-forms_bitmap.o: ../FL/Fl_Window.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
+forms_bitmap.o: ../FL/fl_types.h ../FL/Enumerations.H ../FL/Fl_Group.H
+forms_bitmap.o: ../FL/Fl_Widget.H ../FL/Fl_Window.H ../FL/fl_draw.H ../FL/x.H
+forms_bitmap.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Bitmap.H
+forms_bitmap.o: ../FL/Fl_Image.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
forms_bitmap.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
-forms_bitmap.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
-forms_bitmap.o: ../FL/Fl_FormsBitmap.H ../FL/Fl_Bitmap.H
+forms_bitmap.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H ../FL/Fl_FormsBitmap.H
forms_bitmap.o: ../FL/Fl_FormsPixmap.H ../FL/Fl_Pixmap.H ../FL/Fl_Box.H
-forms_bitmap.o: ../FL/Fl_Browser.H ../FL/Fl_Browser_.H ../FL/Fl_Scrollbar.H
-forms_bitmap.o: ../FL/Fl_Slider.H ../FL/Fl_Valuator.H ../FL/Fl.H
-forms_bitmap.o: ../FL/Fl_Button.H ../FL/Fl_Light_Button.H
+forms_bitmap.o: ../FL/Fl_Browser.H ../FL/Fl_Button.H ../FL/Fl_Light_Button.H
forms_bitmap.o: ../FL/Fl_Round_Button.H ../FL/Fl_Check_Button.H
forms_bitmap.o: ../FL/Fl_Chart.H ../FL/Fl_Choice.H ../FL/Fl_Menu_.H
forms_bitmap.o: ../FL/Fl_Menu_Item.H ../FL/Fl_Clock.H ../FL/Fl_Counter.H
forms_bitmap.o: ../FL/Fl_Dial.H ../FL/Fl_Free.H ../FL/fl_ask.H
forms_bitmap.o: ../FL/fl_show_colormap.H ../FL/filename.H
-forms_bitmap.o: ../FL/Fl_File_Chooser.H ../FL/Fl_Double_Window.H
+forms_bitmap.o: ../FL/Fl_File_Chooser.H ../FL/Fl.H ../FL/Fl_Double_Window.H
forms_bitmap.o: ../FL/Fl_Group.H ../FL/Fl_Choice.H ../FL/Fl_Menu_Button.H
forms_bitmap.o: ../FL/Fl_Button.H ../FL/Fl_Preferences.H ../FL/Fl_Tile.H
forms_bitmap.o: ../FL/Fl_File_Browser.H ../FL/Fl_File_Icon.H ../FL/Fl_Box.H
forms_bitmap.o: ../FL/Fl_Check_Button.H ../FL/Fl_File_Input.H
forms_bitmap.o: ../FL/Fl_Input.H ../FL/Fl_Input_.H ../FL/Fl_Return_Button.H
forms_bitmap.o: ../FL/fl_ask.H ../FL/Fl_Input.H ../FL/Fl_Menu_Button.H
-forms_bitmap.o: ../FL/Fl_Positioner.H ../FL/Fl_Value_Slider.H
-forms_bitmap.o: ../FL/Fl_Timer.H
+forms_bitmap.o: ../FL/Fl_Positioner.H ../FL/Fl_Slider.H ../FL/Fl_Valuator.H
+forms_bitmap.o: ../FL/Fl_Value_Slider.H ../FL/Fl_Timer.H
forms_free.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
-forms_free.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Free.H
-forms_free.o: ../FL/Fl_Widget.H
+forms_free.o: ../FL/Enumerations.H ../FL/Fl_Free.H ../FL/Fl_Widget.H
forms_fselect.o: ../FL/forms.H ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H
-forms_fselect.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H
-forms_fselect.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Window.H
-forms_fselect.o: ../FL/fl_draw.H ../FL/x.H ../FL/Enumerations.H
-forms_fselect.o: ../FL/Fl_Window.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
-forms_fselect.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
-forms_fselect.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
-forms_fselect.o: ../FL/Fl_FormsBitmap.H ../FL/Fl_Bitmap.H
-forms_fselect.o: ../FL/Fl_FormsPixmap.H ../FL/Fl_Pixmap.H ../FL/Fl_Box.H
-forms_fselect.o: ../FL/Fl_Browser.H ../FL/Fl_Browser_.H ../FL/Fl_Scrollbar.H
-forms_fselect.o: ../FL/Fl_Slider.H ../FL/Fl_Valuator.H ../FL/Fl.H
+forms_fselect.o: ../FL/fl_types.h ../FL/Enumerations.H ../FL/Fl_Group.H
+forms_fselect.o: ../FL/Fl_Widget.H ../FL/Fl_Window.H ../FL/fl_draw.H
+forms_fselect.o: ../FL/x.H ../FL/Enumerations.H ../FL/Fl_Window.H
+forms_fselect.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Device.H
+forms_fselect.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
+forms_fselect.o: ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
+forms_fselect.o: ../FL/Fl_FormsBitmap.H ../FL/Fl_FormsPixmap.H
+forms_fselect.o: ../FL/Fl_Pixmap.H ../FL/Fl_Box.H ../FL/Fl_Browser.H
forms_fselect.o: ../FL/Fl_Button.H ../FL/Fl_Light_Button.H
forms_fselect.o: ../FL/Fl_Round_Button.H ../FL/Fl_Check_Button.H
forms_fselect.o: ../FL/Fl_Chart.H ../FL/Fl_Choice.H ../FL/Fl_Menu_.H
forms_fselect.o: ../FL/Fl_Menu_Item.H ../FL/Fl_Clock.H ../FL/Fl_Counter.H
forms_fselect.o: ../FL/Fl_Dial.H ../FL/Fl_Free.H ../FL/fl_ask.H
forms_fselect.o: ../FL/fl_show_colormap.H ../FL/filename.H
-forms_fselect.o: ../FL/Fl_File_Chooser.H ../FL/Fl_Double_Window.H
+forms_fselect.o: ../FL/Fl_File_Chooser.H ../FL/Fl.H ../FL/Fl_Double_Window.H
forms_fselect.o: ../FL/Fl_Group.H ../FL/Fl_Choice.H ../FL/Fl_Menu_Button.H
forms_fselect.o: ../FL/Fl_Button.H ../FL/Fl_Preferences.H ../FL/Fl_Tile.H
forms_fselect.o: ../FL/Fl_File_Browser.H ../FL/Fl_File_Icon.H ../FL/Fl_Box.H
forms_fselect.o: ../FL/Fl_Check_Button.H ../FL/Fl_File_Input.H
forms_fselect.o: ../FL/Fl_Input.H ../FL/Fl_Input_.H ../FL/Fl_Return_Button.H
forms_fselect.o: ../FL/fl_ask.H ../FL/Fl_Input.H ../FL/Fl_Menu_Button.H
-forms_fselect.o: ../FL/Fl_Positioner.H ../FL/Fl_Value_Slider.H
-forms_fselect.o: ../FL/Fl_Timer.H flstring.h ../FL/Fl_Export.H ../config.h
+forms_fselect.o: ../FL/Fl_Positioner.H ../FL/Fl_Slider.H ../FL/Fl_Valuator.H
+forms_fselect.o: ../FL/Fl_Value_Slider.H ../FL/Fl_Timer.H flstring.h
+forms_fselect.o: ../FL/Fl_Export.H ../config.h
forms_pixmap.o: ../FL/forms.H ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H
-forms_pixmap.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H
-forms_pixmap.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Window.H
-forms_pixmap.o: ../FL/fl_draw.H ../FL/x.H ../FL/Enumerations.H
-forms_pixmap.o: ../FL/Fl_Window.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
+forms_pixmap.o: ../FL/fl_types.h ../FL/Enumerations.H ../FL/Fl_Group.H
+forms_pixmap.o: ../FL/Fl_Widget.H ../FL/Fl_Window.H ../FL/fl_draw.H ../FL/x.H
+forms_pixmap.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Bitmap.H
+forms_pixmap.o: ../FL/Fl_Image.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
forms_pixmap.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
-forms_pixmap.o: ../FL/Fl_Image.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
-forms_pixmap.o: ../FL/Fl_FormsBitmap.H ../FL/Fl_Bitmap.H
+forms_pixmap.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H ../FL/Fl_FormsBitmap.H
forms_pixmap.o: ../FL/Fl_FormsPixmap.H ../FL/Fl_Pixmap.H ../FL/Fl_Box.H
-forms_pixmap.o: ../FL/Fl_Browser.H ../FL/Fl_Browser_.H ../FL/Fl_Scrollbar.H
-forms_pixmap.o: ../FL/Fl_Slider.H ../FL/Fl_Valuator.H ../FL/Fl.H
-forms_pixmap.o: ../FL/Fl_Button.H ../FL/Fl_Light_Button.H
+forms_pixmap.o: ../FL/Fl_Browser.H ../FL/Fl_Button.H ../FL/Fl_Light_Button.H
forms_pixmap.o: ../FL/Fl_Round_Button.H ../FL/Fl_Check_Button.H
forms_pixmap.o: ../FL/Fl_Chart.H ../FL/Fl_Choice.H ../FL/Fl_Menu_.H
forms_pixmap.o: ../FL/Fl_Menu_Item.H ../FL/Fl_Clock.H ../FL/Fl_Counter.H
forms_pixmap.o: ../FL/Fl_Dial.H ../FL/Fl_Free.H ../FL/fl_ask.H
forms_pixmap.o: ../FL/fl_show_colormap.H ../FL/filename.H
-forms_pixmap.o: ../FL/Fl_File_Chooser.H ../FL/Fl_Double_Window.H
+forms_pixmap.o: ../FL/Fl_File_Chooser.H ../FL/Fl.H ../FL/Fl_Double_Window.H
forms_pixmap.o: ../FL/Fl_Group.H ../FL/Fl_Choice.H ../FL/Fl_Menu_Button.H
forms_pixmap.o: ../FL/Fl_Button.H ../FL/Fl_Preferences.H ../FL/Fl_Tile.H
forms_pixmap.o: ../FL/Fl_File_Browser.H ../FL/Fl_File_Icon.H ../FL/Fl_Box.H
forms_pixmap.o: ../FL/Fl_Check_Button.H ../FL/Fl_File_Input.H
forms_pixmap.o: ../FL/Fl_Input.H ../FL/Fl_Input_.H ../FL/Fl_Return_Button.H
forms_pixmap.o: ../FL/fl_ask.H ../FL/Fl_Input.H ../FL/Fl_Menu_Button.H
-forms_pixmap.o: ../FL/Fl_Positioner.H ../FL/Fl_Value_Slider.H
-forms_pixmap.o: ../FL/Fl_Timer.H
+forms_pixmap.o: ../FL/Fl_Positioner.H ../FL/Fl_Slider.H ../FL/Fl_Valuator.H
+forms_pixmap.o: ../FL/Fl_Value_Slider.H ../FL/Fl_Timer.H
forms_timer.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
-forms_timer.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_Timer.H
-forms_timer.o: ../FL/Fl_Widget.H ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H
+forms_timer.o: ../FL/Enumerations.H ../FL/Fl_Timer.H ../FL/Fl_Widget.H
+forms_timer.o: ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H
forms_timer.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Group.H
-forms_timer.o: ../FL/Fl_Device.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H
-forms_timer.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H
-forms_timer.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
+forms_timer.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Device.H
+forms_timer.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
+forms_timer.o: ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
+forms_timer.o: ../FL/forms.H ../FL/Fl.H ../FL/fl_draw.H
+forms_timer.o: ../FL/Fl_FormsBitmap.H ../FL/Fl_FormsPixmap.H
+forms_timer.o: ../FL/Fl_Pixmap.H ../FL/Fl_Box.H ../FL/Fl_Browser.H
+forms_timer.o: ../FL/Fl_Button.H ../FL/Fl_Light_Button.H
+forms_timer.o: ../FL/Fl_Round_Button.H ../FL/Fl_Check_Button.H
+forms_timer.o: ../FL/Fl_Chart.H ../FL/Fl_Choice.H ../FL/Fl_Menu_.H
+forms_timer.o: ../FL/Fl_Menu_Item.H ../FL/Fl_Clock.H ../FL/Fl_Counter.H
+forms_timer.o: ../FL/Fl_Dial.H ../FL/Fl_Free.H ../FL/fl_ask.H
+forms_timer.o: ../FL/fl_show_colormap.H ../FL/filename.H
+forms_timer.o: ../FL/Fl_File_Chooser.H ../FL/Fl_Double_Window.H
+forms_timer.o: ../FL/Fl_Group.H ../FL/Fl_Choice.H ../FL/Fl_Menu_Button.H
+forms_timer.o: ../FL/Fl_Button.H ../FL/Fl_Preferences.H ../FL/Fl_Tile.H
+forms_timer.o: ../FL/Fl_File_Browser.H ../FL/Fl_File_Icon.H ../FL/Fl_Box.H
+forms_timer.o: ../FL/Fl_Check_Button.H ../FL/Fl_File_Input.H ../FL/Fl_Input.H
+forms_timer.o: ../FL/Fl_Input_.H ../FL/Fl_Return_Button.H ../FL/fl_ask.H
+forms_timer.o: ../FL/Fl_Input.H ../FL/Fl_Menu_Button.H ../FL/Fl_Positioner.H
+forms_timer.o: ../FL/Fl_Slider.H ../FL/Fl_Valuator.H ../FL/Fl_Value_Slider.H
+forms_timer.o: ../FL/Fl_Timer.H
Fl_Gl_Choice.o: ../config.h ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H
-Fl_Gl_Choice.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H ../FL/x.H
+Fl_Gl_Choice.o: ../FL/fl_types.h ../FL/Enumerations.H ../FL/x.H
Fl_Gl_Choice.o: ../FL/Fl_Window.H Fl_Gl_Choice.H ../FL/gl_draw.H ../FL/gl.h
Fl_Gl_Choice.o: flstring.h ../FL/Fl_Export.H ../FL/fl_utf8.h
Fl_Gl_Overlay.o: ../config.h ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H
-Fl_Gl_Overlay.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H
-Fl_Gl_Overlay.o: ../FL/x.H ../FL/Fl_Window.H Fl_Gl_Choice.H
-Fl_Gl_Overlay.o: ../FL/Fl_Gl_Window.H
+Fl_Gl_Overlay.o: ../FL/fl_types.h ../FL/Enumerations.H ../FL/x.H
+Fl_Gl_Overlay.o: ../FL/Fl_Window.H Fl_Gl_Choice.H ../FL/Fl_Gl_Window.H
Fl_Gl_Device_Plugin.o: ../config.h ../FL/Fl_Printer.H ../FL/x.H
Fl_Gl_Device_Plugin.o: ../FL/Enumerations.H ../FL/Fl_Export.H
-Fl_Gl_Device_Plugin.o: ../FL/fl_types.h ../FL/Fl_Window.H ../FL/Xutf8.h
+Fl_Gl_Device_Plugin.o: ../FL/fl_types.h ../FL/Fl_Window.H
Fl_Gl_Device_Plugin.o: ../FL/Fl_Paged_Device.H ../FL/Fl_Device.H
Fl_Gl_Device_Plugin.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H
-Fl_Gl_Device_Plugin.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H
-Fl_Gl_Device_Plugin.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
+Fl_Gl_Device_Plugin.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H
+Fl_Gl_Device_Plugin.o: ../FL/Fl_Image.H ../FL/Fl_RGB_Image.H
Fl_Gl_Device_Plugin.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Widget.H
-Fl_Gl_Device_Plugin.o: ../FL/fl_draw.H ../FL/Enumerations.H
+Fl_Gl_Device_Plugin.o: ../FL/Fl_Bitmap.H ../FL/fl_draw.H ../FL/Enumerations.H
Fl_Gl_Device_Plugin.o: ../FL/Fl_PostScript.H ../FL/Fl_Gl_Window.H
Fl_Gl_Device_Plugin.o: Fl_Gl_Choice.H ../FL/Fl.H ../FL/fl_utf8.h
Fl_Gl_Window.o: flstring.h ../FL/Fl_Export.H ../config.h ../FL/Fl.H
Fl_Gl_Window.o: ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
-Fl_Gl_Window.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/x.H
-Fl_Gl_Window.o: ../FL/Fl_Window.H Fl_Gl_Choice.H ../FL/Fl_Gl_Window.H
-Fl_Gl_Window.o: ../FL/fl_utf8.h
+Fl_Gl_Window.o: ../FL/Enumerations.H ../FL/x.H ../FL/Fl_Window.H
+Fl_Gl_Window.o: Fl_Gl_Choice.H ../FL/Fl_Gl_Window.H ../FL/fl_utf8.h
freeglut_geometry.o: ../FL/glut.H ../FL/gl.h ../FL/Enumerations.H
freeglut_geometry.o: ../FL/Fl_Export.H ../FL/fl_types.h ../FL/Fl.H
-freeglut_geometry.o: ../FL/fl_utf8.h ../FL/Xutf8.h ../FL/Fl_Gl_Window.H
-freeglut_geometry.o: ../FL/Fl_Window.H ../FL/math.h
+freeglut_geometry.o: ../FL/fl_utf8.h ../FL/Fl_Gl_Window.H ../FL/Fl_Window.H
+freeglut_geometry.o: ../FL/math.h
freeglut_stroke_mono_roman.o: ../FL/glut.H ../FL/gl.h ../FL/Enumerations.H
freeglut_stroke_mono_roman.o: ../FL/Fl_Export.H ../FL/fl_types.h ../FL/Fl.H
-freeglut_stroke_mono_roman.o: ../FL/fl_utf8.h ../FL/Xutf8.h
-freeglut_stroke_mono_roman.o: ../FL/Fl_Gl_Window.H ../FL/Fl_Window.H
+freeglut_stroke_mono_roman.o: ../FL/fl_utf8.h ../FL/Fl_Gl_Window.H
+freeglut_stroke_mono_roman.o: ../FL/Fl_Window.H
freeglut_stroke_roman.o: ../FL/glut.H ../FL/gl.h ../FL/Enumerations.H
freeglut_stroke_roman.o: ../FL/Fl_Export.H ../FL/fl_types.h ../FL/Fl.H
-freeglut_stroke_roman.o: ../FL/fl_utf8.h ../FL/Xutf8.h ../FL/Fl_Gl_Window.H
+freeglut_stroke_roman.o: ../FL/fl_utf8.h ../FL/Fl_Gl_Window.H
freeglut_stroke_roman.o: ../FL/Fl_Window.H
freeglut_teapot.o: ../FL/glut.H ../FL/gl.h ../FL/Enumerations.H
freeglut_teapot.o: ../FL/Fl_Export.H ../FL/fl_types.h ../FL/Fl.H
-freeglut_teapot.o: ../FL/fl_utf8.h ../FL/Xutf8.h ../FL/Fl_Gl_Window.H
-freeglut_teapot.o: ../FL/Fl_Window.H freeglut_teapot_data.h
+freeglut_teapot.o: ../FL/fl_utf8.h ../FL/Fl_Gl_Window.H ../FL/Fl_Window.H
+freeglut_teapot.o: freeglut_teapot_data.h
gl_draw.o: flstring.h ../FL/Fl_Export.H ../config.h ../FL/Fl.H
-gl_draw.o: ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h ../FL/Xutf8.h
-gl_draw.o: ../FL/Enumerations.H ../FL/gl.h ../FL/x.H ../FL/Fl_Window.H
-gl_draw.o: ../FL/fl_draw.H ../FL/Enumerations.H ../FL/Fl_Window.H
-gl_draw.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Device.H
+gl_draw.o: ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
+gl_draw.o: ../FL/Enumerations.H ../FL/gl.h ../FL/gl_draw.H ../FL/gl.h
+gl_draw.o: ../FL/x.H ../FL/Fl_Window.H ../FL/fl_draw.H ../FL/Enumerations.H
+gl_draw.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Widget.H
+gl_draw.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Device.H
gl_draw.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
-gl_draw.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Pixmap.H
-gl_draw.o: ../FL/Fl_RGB_Image.H Fl_Gl_Choice.H Fl_Font.H ../FL/fl_utf8.h
-gl_draw.o: ../FL/Xutf8.h
+gl_draw.o: ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
+gl_draw.o: Fl_Gl_Choice.H Fl_Font.H ../FL/fl_utf8.h Xutf8.h
gl_start.o: ../config.h ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H
-gl_start.o: ../FL/fl_types.h ../FL/Xutf8.h ../FL/Enumerations.H
-gl_start.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/x.H
-gl_start.o: ../FL/Fl_Window.H ../FL/fl_draw.H ../FL/Enumerations.H
-gl_start.o: ../FL/Fl_Device.H ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H
-gl_start.o: ../FL/Fl_Image.H ../FL/Fl_Bitmap.H ../FL/Fl_Image.H
-gl_start.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H Fl_Gl_Choice.H
+gl_start.o: ../FL/fl_types.h ../FL/Enumerations.H ../FL/Fl_Window.H
+gl_start.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Bitmap.H
+gl_start.o: ../FL/Fl_Image.H ../FL/x.H ../FL/Fl_Window.H ../FL/fl_draw.H
+gl_start.o: ../FL/Enumerations.H ../FL/Fl_Device.H ../FL/Fl_Plugin.H
+gl_start.o: ../FL/Fl_Preferences.H ../FL/Fl_Image.H ../FL/Fl_Bitmap.H
+gl_start.o: ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H ../FL/gl.h Fl_Gl_Choice.H
glut_compatability.o: flstring.h ../FL/Fl_Export.H ../config.h ../FL/glut.H
glut_compatability.o: ../FL/gl.h ../FL/Enumerations.H ../FL/Fl_Export.H
glut_compatability.o: ../FL/fl_types.h ../FL/Fl.H ../FL/fl_utf8.h
-glut_compatability.o: ../FL/Xutf8.h ../FL/Fl_Gl_Window.H ../FL/Fl_Window.H
+glut_compatability.o: ../FL/Fl_Gl_Window.H ../FL/Fl_Window.H
glut_compatability.o: ../FL/Fl_Menu_Item.H ../FL/Fl_Widget.H ../FL/Fl_Image.H
glut_font.o: ../config.h ../FL/glut.H ../FL/gl.h ../FL/Enumerations.H
glut_font.o: ../FL/Fl_Export.H ../FL/fl_types.h ../FL/Fl.H ../FL/fl_utf8.h
-glut_font.o: ../FL/Xutf8.h ../FL/Fl_Gl_Window.H ../FL/Fl_Window.H
+glut_font.o: ../FL/Fl_Gl_Window.H ../FL/Fl_Window.H
fl_images_core.o: ../FL/Fl_Shared_Image.H ../FL/Fl_Image.H
+fl_images_core.o: ../FL/Enumerations.H ../FL/Fl_Export.H ../FL/fl_types.h
fl_images_core.o: ../FL/Fl_BMP_Image.H ../FL/Fl_GIF_Image.H ../FL/Fl_Pixmap.H
fl_images_core.o: ../FL/Fl_JPEG_Image.H ../FL/Fl_PNG_Image.H
fl_images_core.o: ../FL/Fl_PNM_Image.H flstring.h ../FL/Fl_Export.H
fl_images_core.o: ../config.h
-Fl_BMP_Image.o: ../FL/Fl_BMP_Image.H ../FL/Fl_Image.H ../FL/fl_utf8.h
-Fl_BMP_Image.o: ../config.h
+Fl_BMP_Image.o: ../FL/Fl_BMP_Image.H ../FL/Fl_Image.H ../FL/Enumerations.H
+Fl_BMP_Image.o: ../FL/Fl_Export.H ../FL/fl_types.h ../FL/fl_utf8.h ../FL/Fl.H
+Fl_BMP_Image.o: ../FL/fl_utf8.h ../config.h
Fl_File_Icon2.o: ../FL/fl_utf8.h flstring.h ../FL/Fl_Export.H ../config.h
Fl_File_Icon2.o: ../FL/math.h ../FL/Fl_File_Icon.H ../FL/Fl.H ../FL/fl_utf8.h
-Fl_File_Icon2.o: ../FL/Fl_Export.H ../FL/fl_types.h ../FL/Xutf8.h
-Fl_File_Icon2.o: ../FL/Enumerations.H ../FL/Fl_Shared_Image.H
-Fl_File_Icon2.o: ../FL/Fl_Image.H ../FL/Fl_Widget.H ../FL/fl_draw.H ../FL/x.H
-Fl_File_Icon2.o: ../FL/Fl_Window.H ../FL/Enumerations.H ../FL/Fl_Window.H
-Fl_File_Icon2.o: ../FL/Fl_Group.H ../FL/Fl_Widget.H ../FL/Fl_Device.H
+Fl_File_Icon2.o: ../FL/Fl_Export.H ../FL/fl_types.h ../FL/Enumerations.H
+Fl_File_Icon2.o: ../FL/Fl_Shared_Image.H ../FL/Fl_Image.H ../FL/Fl_Widget.H
+Fl_File_Icon2.o: ../FL/fl_draw.H ../FL/x.H ../FL/Fl_Window.H
+Fl_File_Icon2.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Group.H
+Fl_File_Icon2.o: ../FL/Fl_Widget.H ../FL/Fl_Bitmap.H ../FL/Fl_Device.H
Fl_File_Icon2.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
Fl_File_Icon2.o: ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
Fl_File_Icon2.o: ../FL/filename.H
Fl_GIF_Image.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
-Fl_GIF_Image.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_GIF_Image.H
-Fl_GIF_Image.o: ../FL/Fl_Pixmap.H ../FL/Fl_Image.H ../FL/fl_utf8.h flstring.h
-Fl_GIF_Image.o: ../FL/Fl_Export.H ../config.h
+Fl_GIF_Image.o: ../FL/Enumerations.H ../FL/Fl_GIF_Image.H ../FL/Fl_Pixmap.H
+Fl_GIF_Image.o: ../FL/Fl_Image.H ../FL/fl_utf8.h flstring.h ../FL/Fl_Export.H
+Fl_GIF_Image.o: ../config.h
Fl_Help_Dialog.o: ../FL/Fl_Help_Dialog.H ../FL/Fl.H ../FL/fl_utf8.h
-Fl_Help_Dialog.o: ../FL/Fl_Export.H ../FL/fl_types.h ../FL/Xutf8.h
-Fl_Help_Dialog.o: ../FL/Enumerations.H ../FL/Fl_Double_Window.H
-Fl_Help_Dialog.o: ../FL/Fl_Window.H ../FL/Fl_Group.H ../FL/Fl_Button.H
-Fl_Help_Dialog.o: ../FL/Fl_Widget.H ../FL/Fl_Input.H ../FL/Fl_Input_.H
-Fl_Help_Dialog.o: ../FL/Fl_Box.H ../FL/Fl_Help_View.H ../FL/Fl.H
-Fl_Help_Dialog.o: ../FL/Fl_Group.H ../FL/Fl_Scrollbar.H ../FL/Fl_Slider.H
-Fl_Help_Dialog.o: ../FL/Fl_Valuator.H ../FL/fl_draw.H ../FL/x.H
-Fl_Help_Dialog.o: ../FL/Enumerations.H ../FL/Fl_Window.H ../FL/Fl_Device.H
+Fl_Help_Dialog.o: ../FL/Fl_Export.H ../FL/fl_types.h ../FL/Enumerations.H
+Fl_Help_Dialog.o: ../FL/Fl_Double_Window.H ../FL/Fl_Window.H ../FL/Fl_Group.H
+Fl_Help_Dialog.o: ../FL/Fl_Button.H ../FL/Fl_Widget.H ../FL/Fl_Input.H
+Fl_Help_Dialog.o: ../FL/Fl_Input_.H ../FL/Fl_Box.H ../FL/Fl_Help_View.H
+Fl_Help_Dialog.o: ../FL/Fl.H ../FL/Fl_Group.H ../FL/Fl_Scrollbar.H
+Fl_Help_Dialog.o: ../FL/Fl_Slider.H ../FL/Fl_Valuator.H ../FL/fl_draw.H
+Fl_Help_Dialog.o: ../FL/x.H ../FL/Enumerations.H ../FL/Fl_Window.H
+Fl_Help_Dialog.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Device.H
Fl_Help_Dialog.o: ../FL/Fl_Plugin.H ../FL/Fl_Preferences.H ../FL/Fl_Image.H
-Fl_Help_Dialog.o: ../FL/Fl_Bitmap.H ../FL/Fl_Image.H ../FL/Fl_Pixmap.H
-Fl_Help_Dialog.o: ../FL/Fl_RGB_Image.H ../FL/Fl_Shared_Image.H
-Fl_Help_Dialog.o: ../FL/filename.H flstring.h ../FL/Fl_Export.H ../config.h
-Fl_Help_Dialog.o: ../FL/fl_ask.H
-Fl_JPEG_Image.o: ../FL/Fl_JPEG_Image.H ../FL/Fl_Image.H
-Fl_JPEG_Image.o: ../FL/Fl_Shared_Image.H ../FL/fl_utf8.h ../config.h
+Fl_Help_Dialog.o: ../FL/Fl_Bitmap.H ../FL/Fl_Pixmap.H ../FL/Fl_RGB_Image.H
+Fl_Help_Dialog.o: ../FL/Fl_Shared_Image.H ../FL/filename.H flstring.h
+Fl_Help_Dialog.o: ../FL/Fl_Export.H ../config.h ../FL/fl_ask.H
+Fl_JPEG_Image.o: ../FL/Fl_JPEG_Image.H ../FL/Fl_Image.H ../FL/Enumerations.H
+Fl_JPEG_Image.o: ../FL/Fl_Export.H ../FL/fl_types.h ../FL/Fl_Shared_Image.H
+Fl_JPEG_Image.o: ../FL/fl_utf8.h ../FL/Fl.H ../FL/fl_utf8.h ../config.h
Fl_PNG_Image.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
-Fl_PNG_Image.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_PNG_Image.H
-Fl_PNG_Image.o: ../FL/Fl_Image.H ../FL/Fl_Shared_Image.H ../config.h
-Fl_PNG_Image.o: ../FL/fl_utf8.h
+Fl_PNG_Image.o: ../FL/Enumerations.H ../FL/Fl_PNG_Image.H ../FL/Fl_Image.H
+Fl_PNG_Image.o: ../FL/Fl_Shared_Image.H ../config.h ../FL/fl_utf8.h
Fl_PNM_Image.o: ../FL/Fl.H ../FL/fl_utf8.h ../FL/Fl_Export.H ../FL/fl_types.h
-Fl_PNM_Image.o: ../FL/Xutf8.h ../FL/Enumerations.H ../FL/Fl_PNM_Image.H
-Fl_PNM_Image.o: ../FL/Fl_Image.H ../FL/fl_utf8.h flstring.h ../FL/Fl_Export.H
-Fl_PNM_Image.o: ../config.h
+Fl_PNM_Image.o: ../FL/Enumerations.H ../FL/Fl_PNM_Image.H ../FL/Fl_Image.H
+Fl_PNM_Image.o: ../FL/fl_utf8.h flstring.h ../FL/Fl_Export.H ../config.h
flstring.o: flstring.h ../FL/Fl_Export.H ../config.h
-scandir.o: flstring.h ../FL/Fl_Export.H ../config.h
-numericsort.o: ../config.h
+scandir.o: ../config.h
+numericsort.o: ../config.h ../FL/filename.H
vsnprintf.o: flstring.h ../FL/Fl_Export.H ../config.h
fl_utf.o: ../FL/fl_utf8.h xutf8/mk_wcwidth.c
xutf8/case.o: xutf8/headers/case.h
+xutf8/is_right2left.o: Xutf8.h
xutf8/is_spacing.o: xutf8/headers/spacing.h
-xutf8/keysym2Ucs.o: ../FL/Xutf8.h xutf8/imKStoUCS.c xutf8/Xlibint.h
-xutf8/keysym2Ucs.o: xutf8/Ximint.h
-xutf8/utf8Input.o: ../config.h ../FL/Xutf8.h xutf8/lcUniConv/big5.h
+xutf8/keysym2Ucs.o: Xutf8.h xutf8/imKStoUCS.c xutf8/Xlibint.h xutf8/Ximint.h
+xutf8/utf8Input.o: ../config.h Xutf8.h xutf8/lcUniConv/big5.h
xutf8/utf8Input.o: xutf8/lcUniConv/gb2312.h xutf8/lcUniConv/cp936ext.h
xutf8/utf8Input.o: xutf8/lcUniConv/jisx0201.h xutf8/lcUniConv/jisx0208.h
xutf8/utf8Input.o: xutf8/lcUniConv/jisx0212.h xutf8/lcUniConv/ksc5601.h
-xutf8/utf8Utils.o: ../FL/Xutf8.h
-xutf8/utf8Wrap.o: ../FL/Xutf8.h xutf8/ucs2fontmap.c
-xutf8/utf8Wrap.o: xutf8/lcUniConv/cp936ext.h xutf8/lcUniConv/big5.h
-xutf8/utf8Wrap.o: xutf8/lcUniConv/gb2312.h xutf8/lcUniConv/iso8859_10.h
-xutf8/utf8Wrap.o: xutf8/lcUniConv/iso8859_11.h xutf8/lcUniConv/iso8859_13.h
-xutf8/utf8Wrap.o: xutf8/lcUniConv/iso8859_14.h xutf8/lcUniConv/iso8859_15.h
-xutf8/utf8Wrap.o: xutf8/lcUniConv/iso8859_2.h xutf8/lcUniConv/iso8859_3.h
-xutf8/utf8Wrap.o: xutf8/lcUniConv/iso8859_4.h xutf8/lcUniConv/iso8859_5.h
-xutf8/utf8Wrap.o: xutf8/lcUniConv/iso8859_6.h xutf8/lcUniConv/iso8859_7.h
-xutf8/utf8Wrap.o: xutf8/lcUniConv/iso8859_8.h xutf8/lcUniConv/iso8859_9.h
-xutf8/utf8Wrap.o: xutf8/lcUniConv/jisx0201.h xutf8/lcUniConv/jisx0208.h
-xutf8/utf8Wrap.o: xutf8/lcUniConv/jisx0212.h xutf8/lcUniConv/koi8_r.h
-xutf8/utf8Wrap.o: xutf8/lcUniConv/koi8_u.h xutf8/lcUniConv/ksc5601.h
-xutf8/utf8Wrap.o: xutf8/lcUniConv/cp1251.h xutf8/headers/symbol_.h
-xutf8/utf8Wrap.o: xutf8/headers/dingbats_.h
+xutf8/utf8Utils.o: Xutf8.h
+xutf8/utf8Wrap.o: Xutf8.h xutf8/ucs2fontmap.c xutf8/lcUniConv/cp936ext.h
+xutf8/utf8Wrap.o: xutf8/lcUniConv/big5.h xutf8/lcUniConv/gb2312.h
+xutf8/utf8Wrap.o: xutf8/lcUniConv/iso8859_10.h xutf8/lcUniConv/iso8859_11.h
+xutf8/utf8Wrap.o: xutf8/lcUniConv/iso8859_13.h xutf8/lcUniConv/iso8859_14.h
+xutf8/utf8Wrap.o: xutf8/lcUniConv/iso8859_15.h xutf8/lcUniConv/iso8859_2.h
+xutf8/utf8Wrap.o: xutf8/lcUniConv/iso8859_3.h xutf8/lcUniConv/iso8859_4.h
+xutf8/utf8Wrap.o: xutf8/lcUniConv/iso8859_5.h xutf8/lcUniConv/iso8859_6.h
+xutf8/utf8Wrap.o: xutf8/lcUniConv/iso8859_7.h xutf8/lcUniConv/iso8859_8.h
+xutf8/utf8Wrap.o: xutf8/lcUniConv/iso8859_9.h xutf8/lcUniConv/jisx0201.h
+xutf8/utf8Wrap.o: xutf8/lcUniConv/jisx0208.h xutf8/lcUniConv/jisx0212.h
+xutf8/utf8Wrap.o: xutf8/lcUniConv/koi8_r.h xutf8/lcUniConv/koi8_u.h
+xutf8/utf8Wrap.o: xutf8/lcUniConv/ksc5601.h xutf8/lcUniConv/cp1251.h
+xutf8/utf8Wrap.o: xutf8/headers/symbol_.h xutf8/headers/dingbats_.h
diff --git a/src/mediumarrow.h b/src/mediumarrow.h
index 8a1fe8c..a25f728 100644
--- a/src/mediumarrow.h
+++ b/src/mediumarrow.h
@@ -1,6 +1,6 @@
#define mediumarrow_width 16
#define mediumarrow_height 16
-static unsigned char mediumarrow_bits[] = {
+static const unsigned char mediumarrow_bits[] = {
0x40, 0x00, 0x60, 0x00, 0x70, 0x00, 0x78, 0x00, 0xfc, 0x3f, 0x78, 0x00,
0x70, 0x00, 0x60, 0x02, 0x40, 0x06, 0x00, 0x0e, 0x00, 0x1e, 0xfc, 0x3f,
0x00, 0x1e, 0x00, 0x0e, 0x00, 0x06, 0x00, 0x02};
diff --git a/src/numericsort.c b/src/numericsort.c
index 84172a3..bd37d6e 100644
--- a/src/numericsort.c
+++ b/src/numericsort.c
@@ -1,5 +1,5 @@
/*
- * "$Id: numericsort.c 8864 2011-07-19 04:49:30Z greg.ercolano $"
+ * "$Id: numericsort.c 10236 2014-08-21 12:29:48Z cand $"
*
* Numeric sorting routine for the Fast Light Tool Kit (FLTK).
*
@@ -39,10 +39,10 @@
# include <ndir.h>
# endif /* HAVE_NDIR_H */
# endif /* HAVE_DIRENT_H */
-#else /* For WIN32 variants */
-# include <FL/filename.H>
#endif /* !WIN32 || __CYGWIN__ */
+#include <FL/filename.H>
+
/*
* 'numericsort()' - Compare two directory entries, possibly with
* a case-insensitive comparison...
@@ -98,5 +98,5 @@ int fl_numericsort(struct dirent **A, struct dirent **B) {
}
/*
- * End of "$Id: numericsort.c 8864 2011-07-19 04:49:30Z greg.ercolano $".
+ * End of "$Id: numericsort.c 10236 2014-08-21 12:29:48Z cand $".
*/
diff --git a/src/print_panel.cxx b/src/print_panel.cxx
index 478b7b5..ec622ca 100644
--- a/src/print_panel.cxx
+++ b/src/print_panel.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: print_panel.cxx 9158 2011-10-29 14:50:04Z manolo $"
+// "$Id: print_panel.cxx 10234 2014-08-21 12:18:32Z cand $"
//
// Print panel for the Fast Light Tool Kit (FLTK).
//
@@ -110,7 +110,7 @@ static void cb_print_properties_panel(Fl_Double_Window*, void*) {
print_update_status();
}
-static Fl_Menu_Item menu_print_page_size[] = {
+static const Fl_Menu_Item menu_print_page_size[] = {
{"Letter", 0, 0, 0, 0, FL_NORMAL_LABEL, 0, 14, 0},
{"A4", 0, 0, 0, 0, FL_NORMAL_LABEL, 0, 14, 0},
{"Legal", 0, 0, 0, 0, FL_NORMAL_LABEL, 0, 14, 0},
@@ -124,7 +124,7 @@ static Fl_Menu_Item menu_print_page_size[] = {
};
#include <FL/Fl_Pixmap.H>
-static const char *idata_print_color[] = {
+static const char * const idata_print_color[] = {
"24 24 17 1",
" \tc None",
".\tc #FFFF00",
@@ -170,7 +170,7 @@ static const char *idata_print_color[] = {
};
static Fl_Pixmap image_print_color(idata_print_color);
-static const char *idata_print_gray[] = {
+static const char * const idata_print_gray[] = {
"24 24 17 1",
" \tc None",
".\tc #E3E3E3",
@@ -591,5 +591,5 @@ void print_update_status() {
}
//
-// End of "$Id: print_panel.cxx 9158 2011-10-29 14:50:04Z manolo $".
+// End of "$Id: print_panel.cxx 10234 2014-08-21 12:18:32Z cand $".
//
diff --git a/src/ps_image.cxx b/src/ps_image.cxx
index 35d0d0e..41dc299 100644
--- a/src/ps_image.cxx
+++ b/src/ps_image.cxx
@@ -185,72 +185,38 @@ static inline uchar swap_byte(const uchar b) {
extern uchar **fl_mask_bitmap;
+struct callback_data {
+ const uchar *data;
+ int D, LD;
+};
-void Fl_PostScript_Graphics_Driver::draw_image(const uchar *data, int ix, int iy, int iw, int ih, int D, int LD) {
- double x = ix, y = iy, w = iw, h = ih;
- if (D<3){ //mono
- draw_image_mono(data, ix, iy, iw, ih, D, LD);
- return;
- }
+static void draw_image_cb(void *data, int x, int y, int w, uchar *buf) {
+ struct callback_data *cb_data;
+ const uchar *curdata;
+ cb_data = (struct callback_data*)data;
+ curdata = cb_data->data + x*cb_data->D + y*cb_data->LD;
- int i,j, k;
+ memcpy(buf, curdata, w*cb_data->D);
+}
- fprintf(output,"save\n");
- const char * interpol;
- if (lang_level_>1){
- if (interpolate_)
- interpol="true";
- else
- interpol="false";
- if (mask && lang_level_>2)
- fprintf(output, "%g %g %g %g %i %i %i %i %s CIM\n", x , y+h , w , -h , iw , ih, mx, my, interpol);
- else
- fprintf(output, "%g %g %g %g %i %i %s CII\n", x , y+h , w , -h , iw , ih, interpol);
- } else
- fprintf(output , "%g %g %g %g %i %i CI", x , y+h , w , -h , iw , ih);
+void Fl_PostScript_Graphics_Driver::draw_image(const uchar *data, int ix, int iy, int iw, int ih, int D, int LD) {
+ if (D<3){ //mono
+ draw_image_mono(data, ix, iy, iw, ih, D, LD);
+ return;
+ }
+ struct callback_data cb_data;
if (!LD) LD = iw*D;
- uchar *curmask=mask;
-
- for (j=0; j<ih;j++){
- if (mask){
-
- for (k=0;k<my/ih;k++){
- for (i=0; i<((mx+7)/8);i++){
- if (!(i%80)) fprintf(output, "\n");
- fprintf(output, "%.2x",swap_byte(*curmask));
- curmask++;
- }
- fprintf(output,"\n");
- }
- }
- const uchar *curdata=data+j*LD;
- for (i=0 ; i<iw ; i++) {
- uchar r = curdata[0];
- uchar g = curdata[1];
- uchar b = curdata[2];
- if (lang_level_<3 && D>3) { //can do mixing using bg_* colors)
- unsigned int a2 = curdata[3]; //must be int
- unsigned int a = 255-a2;
- r = (a2 * r + bg_r * a)/255;
- g = (a2 * g + bg_g * a)/255;
- b = (a2 * b + bg_b * a)/255;
- }
- if (!(i%40)) fprintf(output, "\n");
- fprintf(output, "%.2x%.2x%.2x", r, g, b);
- curdata +=D;
- }
- fprintf(output,"\n");
-
- }
-
- fprintf(output," >\nrestore\n" );
+ cb_data.data = data;
+ cb_data.D = D;
+ cb_data.LD = LD;
+ draw_image(draw_image_cb, &cb_data, ix, iy, iw, ih, D);
}
void Fl_PostScript_Graphics_Driver::draw_image(Fl_Draw_Image_Cb call, void *data, int ix, int iy, int iw, int ih, int D) {
@@ -325,6 +291,14 @@ void Fl_PostScript_Graphics_Driver::draw_image(Fl_Draw_Image_Cb call, void *data
uchar g = curdata[1];
uchar b = curdata[2];
+ if (lang_level_<3 && D>3) { //can do mixing using bg_* colors)
+ unsigned int a2 = curdata[3]; //must be int
+ unsigned int a = 255-a2;
+ r = (a2 * r + bg_r * a)/255;
+ g = (a2 * g + bg_g * a)/255;
+ b = (a2 * b + bg_b * a)/255;
+ }
+
if (!(i%40)) fputs("\n", output);
fprintf(output, "%.2x%.2x%.2x", r, g, b);
diff --git a/src/scandir.c b/src/scandir.c
index e39c6ca..27d40dc 100644
--- a/src/scandir.c
+++ b/src/scandir.c
@@ -1,10 +1,10 @@
/*
- * "$Id: scandir.c 9210 2011-12-21 10:42:14Z ianmacarthur $"
+ * "$Id: scandir.c 9858 2013-04-05 14:14:08Z manolo $"
*
- * This is a placekeeper stub that puuls in scandir implementations for host
+ * This is a placekeeper stub that pulls in scandir implementations for host
* systems that do not provide a compatible one natively
*
- * Copyright 1998-2010 by Bill Spitzak and others.
+ * Copyright 1998-2013 by Bill Spitzak and others.
*
* This library is free software. Distribution and use rights are outlined in
* the file "COPYING" which should have been included with this file. If this
@@ -21,42 +21,12 @@
#if defined(WIN32) && !defined(__CYGWIN__)
# include "scandir_win32.c"
#else
-
-# include "flstring.h"
-
-/* NOTE: Most (all?) modern non-WIN32 hosts DO have a usable scandir */
-# if !HAVE_SCANDIR
-# include <stdlib.h>
-# include <sys/types.h>
-# include <errno.h>
-
-# if HAVE_DIRENT_H
-# include <dirent.h>
-# define NAMLEN(dirent) strlen((dirent)->d_name)
-# else /* HAVE_DIRENT_H */
-# define dirent direct
-# define NAMLEN(dirent) (dirent)->d_namlen
-# if HAVE_SYS_NDIR_H
-# include <sys/ndir.h>
-# endif /* HAVE_SYS_NDIR_H */
-# if HAVE_SYS_DIR_H
-# include <sys/dir.h>
-# endif /* HAVE_SYS_DIR_H */
-# if HAVE_NDIR_H
-# include <ndir.h>
-# endif /* HAVE_NDIR_H */
-# endif
-
-/* This warning added to help identify any non-WIN32 hosts that actually try to use
- * our "private" implementation of the scandir function, which was suspect... */
-# if defined(__GNUC__)
-# warning Attempting to use the deprecated scandir() replacement function
-# endif /*__GNUC__*/
-# error No compatible scandir implementation found (STR 2687 applies!)
-
-# endif /* !HAVE_SCANDIR */
+# include <config.h>
+# ifndef HAVE_SCANDIR
+# include "scandir_posix.c"
+# endif /* HAVE_SCANDIR */
#endif
/*
- * End of "$Id: scandir.c 9210 2011-12-21 10:42:14Z ianmacarthur $".
+ * End of "$Id: scandir.c 9858 2013-04-05 14:14:08Z manolo $".
*/
diff --git a/src/scandir_posix.c b/src/scandir_posix.c
new file mode 100644
index 0000000..f032d7f
--- /dev/null
+++ b/src/scandir_posix.c
@@ -0,0 +1,205 @@
+/*
+ * "$Id: scandir_posix.c 9832 2013-03-06 22:15:01Z ianmacarthur $"
+ *
+ * This implementation of 'scandir()' is intended to be POSIX.1-2008 compliant.
+ * A POSIX.1-1990 compliant system is required as minimum base.
+ * Note:
+ * The 'const' declarations were removed to match FLTK 1.3 wrapper (STR #2931)
+ *
+ * Copyright (c) 2013 by Michael Baeuerle
+ *
+ * This library is free software. Distribution and use rights are outlined in
+ * the file "COPYING" which should have been included with this file. If this
+ * file is missing or damaged, see the license at:
+ *
+ * http://www.fltk.org/COPYING.php
+ *
+ * Please report all bugs and problems on the following page:
+ *
+ * http://www.fltk.org/str.php
+ *
+ * It is required that 'SIZE_MAX' is at least 'INT_MAX'.
+ * Don't use a C++ compiler to build this module.
+ *
+ * The build system must define 'HAVE_PTHREAD' and link against a potentially
+ * required library to switch this implementation into thread-safe mode.
+ * The POSIX.1c-1995 extension is required if 'HAVE_PTHREAD' is defined.
+ *
+ * Note:
+ * In theory, a system that provide threads should also provide 'readdir_r()',
+ * a thread-safe version of 'readdir()'. In reality this is not always the case.
+ * In addition there may be a race condition that can lead to a buffer overflow:
+ * http://womble.decadent.org.uk/readdir_r-advisory.html
+ */
+
+#ifndef HAVE_PTHREAD
+ /* Switch system headers into POSIX.1-1990 mode */
+# define _POSIX_SOURCE
+#else /* HAVE_PTHREAD */
+ /* Switch system headers into POSIX.1c-1995 mode */
+# define _POSIX_C_SOURCE 199506L
+#endif /* HAVE_PTHREAD */
+
+#include <sys/types.h> /* XPG2 require this for '*dir()' functions */
+#include <dirent.h>
+#include <errno.h>
+#include <stdlib.h> /* For 'malloc()', 'realloc()' and 'qsort()' */
+#include <stddef.h> /* For 'offsetof()', 'NULL' and 'size_t' */
+#include <limits.h> /* For 'INT_MAX' */
+#include <string.h> /* For 'memcpy()' */
+#if defined(HAVE_PTHREAD) && defined(HAVE_PTHREAD_H)
+# include <pthread.h>
+#endif /* HAVE_PTHREAD */
+
+
+/* ========================================================================== */
+/* At startup allocate memory for this number of result array elements */
+#define ENTRIES_MIN (size_t) 32
+
+
+/* ========================================================================== */
+#ifdef HAVE_PTHREAD
+static pthread_mutex_t scandir_mutex = PTHREAD_MUTEX_INITIALIZER;
+#endif /* HAVE_PTHREAD */
+
+
+/* ========================================================================== */
+/*
+ * This function reads the next entry from the directory referenced by 'dirp',
+ * allocate a buffer for the entry and copy it into this buffer.
+ * A pointer to this buffer is written to 'entryp' and the size of the buffer is
+ * written to 'len'.
+ * Success and a NULL pointer is returned for 'entryp' if there are no more
+ * entries in the directory.
+ * On sucess zero is returned and the caller is responsible for 'free()'ing the
+ * buffer after use.
+ * On error the return value is nonzero, 'entryp' and 'len' are invalid.
+ *
+ * Should be declared as 'static inline' if the compiler support that.
+ */
+static int
+readentry(DIR *dirp, struct dirent **entryp, size_t *len)
+{
+ int result = -1;
+ struct dirent *e;
+
+#ifdef HAVE_PTHREAD
+ if (!pthread_mutex_lock(&scandir_mutex))
+ {
+ /* Ensure that there is no code path that bypass the '_unlock()' call! */
+#endif /* HAVE_PTHREAD */
+ errno = 0;
+ e = readdir(dirp);
+ if (NULL == e)
+ {
+ if (!errno)
+ {
+ /* No more entries in directory */
+ *entryp = NULL;
+ *len = 0;
+ result = 0;
+ }
+ }
+ else
+ {
+ /* Entry found, allocate local buffer */
+ *len = offsetof(struct dirent, d_name) + strlen(e->d_name) + (size_t) 1;
+ *entryp = (struct dirent *) malloc(*len);
+ if (NULL != *entryp)
+ {
+ memcpy((void *) *entryp, (void *) e, *len);
+ /* Force NUL termination at end of buffer */
+ ((char *) *entryp)[*len - (size_t) 1] = 0;
+ result = 0;
+ }
+ }
+#ifdef HAVE_PTHREAD
+ /*
+ * In a multithreading environment the systems dirent buffer may be shared
+ * between all threads. Therefore the mutex must stay locked until we have
+ * copied the data to our thread local buffer.
+ */
+ pthread_mutex_unlock(&scandir_mutex);
+ }
+#endif /* HAVE_PTHREAD */
+
+ return result;
+}
+
+
+/* ========================================================================== */
+int
+fl_scandir(const char *dir, struct dirent ***namelist,
+ int (*sel)(struct dirent *),
+ int (*compar)(struct dirent **, struct dirent **))
+{
+ int result = -1;
+ DIR *dirp;
+ size_t len, num = 0, max = ENTRIES_MIN;
+ struct dirent *entryp, **entries, **p;
+
+ entries = (struct dirent **) malloc(sizeof(*entries) * max);
+ if (NULL != entries)
+ {
+ /* Open directory 'dir' (and verify that it really is a directory) */
+ dirp = opendir(dir);
+ if (NULL != dirp)
+ {
+ /* Read next directory entry */
+ while (!readentry(dirp, &entryp, &len))
+ {
+ if (NULL == entryp)
+ {
+ /* EOD => Return number of directory entries */
+ result = (int) num;
+ break;
+ }
+ /* Apply select function if there is one provided */
+ if (NULL != sel) { if (!sel(entryp)) continue; }
+ entries[num++] = entryp;
+ if (num >= max)
+ {
+ /* Allocate exponentially increasing sized memory chunks */
+ if (INT_MAX / 2 >= (int) max) { max *= (size_t) 2; }
+ else
+ {
+ errno = ENOMEM;
+ break;
+ }
+ p = (struct dirent **) realloc((void *) entries,
+ sizeof(*entries) * max);
+ if (NULL != p) { entries = p; }
+ else break;
+ }
+ }
+ closedir(dirp);
+ /*
+ * A standard compliant 'closedir()' is allowed to fail with 'EINTR', but
+ * the state of the directory structure is undefined in this case.
+ * Therefore we ignore the return value because we can't call 'closedir()'
+ * again and must hope that the system has released all ressources.
+ */
+ }
+ /* Sort entries in array if there is a compare function provided */
+ if (NULL != compar)
+ {
+ qsort((void *) entries, num, sizeof(*entries),
+ (int (*)(const void *, const void *)) compar);
+ }
+ *namelist = entries;
+ }
+
+ /* Check for error */
+ if (-1 == result)
+ {
+ /* Free all memory we have allocated */
+ while (num--) { free(entries[num]); }
+ free(entries);
+ }
+
+ return result;
+}
+
+/*
+ * End of "$Id: scandir_posix.c 9832 2013-03-06 22:15:01Z ianmacarthur $".
+ */
diff --git a/src/scandir_win32.c b/src/scandir_win32.c
index 9f2e582..adf21c1 100644
--- a/src/scandir_win32.c
+++ b/src/scandir_win32.c
@@ -1,5 +1,5 @@
/*
- * "$Id: scandir_win32.c 9325 2012-04-05 05:12:30Z fabien $"
+ * "$Id: scandir_win32.c 10082 2014-01-25 23:04:36Z AlbrechtS $"
*
* WIN32 scandir function for the Fast Light Tool Kit (FLTK).
*
@@ -44,7 +44,7 @@ int fl_scandir(const char *dirname, struct dirent ***namelist,
/* #warning FIXME This probably needs to be MORE UTF8 aware now */
/* #endif */
for (d = findIn; *d; d++) if (*d=='/') *d='\\';
- if ((len==0)) { strcpy(findIn, ".\\*"); }
+ if (len==0) { strcpy(findIn, ".\\*"); }
if ((len==2)&&findIn[1]==':'&&isalpha(findIn[0])) { *d++ = '\\'; *d = 0; }
if ((len==1)&& (d[-1]=='.')) { strcpy(findIn, ".\\*"); is_dir = 1; }
if ((len>0) && (d[-1]=='\\')) { *d++ = '*'; *d = 0; is_dir = 1; }
@@ -122,5 +122,5 @@ int fl_scandir(const char *dirname, struct dirent ***namelist,
#endif
/*
- * End of "$Id: scandir_win32.c 9325 2012-04-05 05:12:30Z fabien $".
+ * End of "$Id: scandir_win32.c 10082 2014-01-25 23:04:36Z AlbrechtS $".
*/
diff --git a/src/screen_xywh.cxx b/src/screen_xywh.cxx
index bae6a2f..67f7ed7 100644
--- a/src/screen_xywh.cxx
+++ b/src/screen_xywh.cxx
@@ -1,5 +1,5 @@
//
-// "$Id: screen_xywh.cxx 9299 2012-03-23 16:47:53Z manolo $"
+// "$Id: screen_xywh.cxx 10228 2014-08-21 08:14:19Z cand $"
//
// Screen/monitor bounding box API for the Fast Light Tool Kit (FLTK).
//
@@ -58,7 +58,7 @@ static BOOL CALLBACK screen_cb(HMONITOR mon, HDC, LPRECT r, LPARAM) {
mi.cbSize = sizeof(mi);
// GetMonitorInfo(mon, &mi);
-// (but we use our self-aquired function pointer instead)
+// (but we use our self-acquired function pointer instead)
if (fl_gmi(mon, &mi)) {
screens[num_screens] = mi.rcMonitor;
// If we also want to record the work area, we would also store mi.rcWork at this point
@@ -97,7 +97,7 @@ static void screen_init() {
if (fl_gmi) {
// We have GetMonitorInfoA, enumerate all the screens...
// EnumDisplayMonitors(0,0,screen_cb,0);
-// (but we use our self-aquired function pointer instead)
+// (but we use our self-acquired function pointer instead)
// NOTE: num_screens is incremented in screen_cb so we must first reset it here...
num_screens = 0;
fl_edm(0, 0, screen_cb, 0);
@@ -135,10 +135,9 @@ static void screen_init() {
CGSize s = CGDisplayScreenSize(displays[i]); // from 10.3
dpi_h[i] = screens[i].width / (s.width/25.4);
dpi_v[i] = screens[i].height / (s.height/25.4);
- }
- else {
+ } else {
dpi_h[i] = dpi_v[i] = 75.;
- }
+ }
}
num_screens = count;
}
@@ -149,11 +148,11 @@ static void screen_init() {
# include <X11/extensions/Xinerama.h>
#endif
typedef struct {
- short x_org;
- short y_org;
- short width;
- short height;
- } FLScreenInfo;
+ short x_org;
+ short y_org;
+ short width;
+ short height;
+} FLScreenInfo;
static FLScreenInfo screens[MAX_SCREENS];
static float dpi[MAX_SCREENS][2];
@@ -215,21 +214,6 @@ int Fl::screen_count() {
return num_screens ? num_screens : 1;
}
-static int find_screen_with_point(int mx, int my) {
- int screen = 0;
- if (num_screens < 0) screen_init();
-
- for (int i = 0; i < num_screens; i ++) {
- int sx, sy, sw, sh;
- Fl::screen_xywh(sx, sy, sw, sh, i);
- if ((mx >= sx) && (mx < (sx+sw)) && (my >= sy) && (my < (sy+sh))) {
- screen = i;
- break;
- }
- }
- return screen;
-}
-
/**
Gets the bounding box of a screen
that contains the specified screen position \p mx, \p my
@@ -237,7 +221,7 @@ static int find_screen_with_point(int mx, int my) {
\param[in] mx, my the absolute screen position
*/
void Fl::screen_xywh(int &X, int &Y, int &W, int &H, int mx, int my) {
- screen_xywh(X, Y, W, H, find_screen_with_point(mx, my));
+ screen_xywh(X, Y, W, H, screen_num(mx, my));
}
@@ -248,7 +232,7 @@ void Fl::screen_xywh(int &X, int &Y, int &W, int &H, int mx, int my) {
\param[in] mx, my the absolute screen position
*/
void Fl::screen_work_area(int &X, int &Y, int &W, int &H, int mx, int my) {
- screen_work_area(X, Y, W, H, find_screen_with_point(mx, my));
+ screen_work_area(X, Y, W, H, screen_num(mx, my));
}
/**
@@ -273,10 +257,9 @@ void Fl::screen_work_area(int &X, int &Y, int &W, int &H, int n) {
Y = Fl::y();
W = Fl::w();
H = Fl::h();
- }
- else { // for other screens, work area is full screen,
+ } else { // for other screens, work area is full screen,
screen_xywh(X, Y, W, H, n);
- }
+ }
#endif
}
@@ -307,10 +290,10 @@ void Fl::screen_xywh(int &X, int &Y, int &W, int &H, int n) {
H = GetSystemMetrics(SM_CYSCREEN);
}
#elif defined(__APPLE__)
- X = screens[n].x;
- Y = screens[n].y;
- W = screens[n].width;
- H = screens[n].height;
+ X = screens[n].x;
+ Y = screens[n].y;
+ W = screens[n].width;
+ H = screens[n].height;
#else
if (num_screens > 0) {
X = screens[n].x_org;
@@ -321,8 +304,41 @@ void Fl::screen_xywh(int &X, int &Y, int &W, int &H, int n) {
#endif // WIN32
}
+/**
+ Gets the screen bounding rect for the screen
+ which intersects the most with the rectangle
+ defined by \p mx, \p my, \p mw, \p mh.
+ \param[out] X,Y,W,H the corresponding screen bounding box
+ \param[in] mx, my, mw, mh the rectangle to search for intersection with
+ \see void screen_xywh(int &X, int &Y, int &W, int &H, int n)
+ */
+void Fl::screen_xywh(int &X, int &Y, int &W, int &H, int mx, int my, int mw, int mh) {
+ screen_xywh(X, Y, W, H, screen_num(mx, my, mw, mh));
+}
+
+/**
+ Gets the screen number of a screen
+ that contains the specified screen position \p x, \p y
+ \param[in] x, y the absolute screen position
+*/
+int Fl::screen_num(int x, int y) {
+ int screen = 0;
+ if (num_screens < 0) screen_init();
+
+ for (int i = 0; i < num_screens; i ++) {
+ int sx, sy, sw, sh;
+ Fl::screen_xywh(sx, sy, sw, sh, i);
+ if ((x >= sx) && (x < (sx+sw)) && (y >= sy) && (y < (sy+sh))) {
+ screen = i;
+ break;
+ }
+ }
+ return screen;
+}
+
+// Return the number of pixels common to the two rectangular areas
static inline float fl_intersection(int x1, int y1, int w1, int h1,
- int x2, int y2, int w2, int h2) {
+ int x2, int y2, int w2, int h2) {
if(x1+w1 < x2 || x2+w2 < x1 || y1+h1 < y2 || y2+h2 < y1)
return 0.;
int int_left = x1 > x2 ? x1 : x2;
@@ -333,30 +349,26 @@ static inline float fl_intersection(int x1, int y1, int w1, int h1,
}
/**
- Gets the screen bounding rect for the screen
+ Gets the screen number for the screen
which intersects the most with the rectangle
- defined by \p mx, \p my, \p mw, \p mh.
- \param[out] X,Y,W,H the corresponding screen bounding box
- \param[in] mx, my, mw, mh the rectangle to search for intersection with
- \see void screen_xywh(int &X, int &Y, int &W, int &H, int n)
+ defined by \p x, \p y, \p w, \p h.
+ \param[in] x, y, w, h the rectangle to search for intersection with
*/
-void Fl::screen_xywh(int &X, int &Y, int &W, int &H, int mx, int my, int mw, int mh) {
+int Fl::screen_num(int x, int y, int w, int h) {
int best_screen = 0;
float best_intersection = 0.;
- for(int i = 0; i < Fl::screen_count(); i++) {
+ for (int i = 0; i < Fl::screen_count(); i++) {
int sx, sy, sw, sh;
Fl::screen_xywh(sx, sy, sw, sh, i);
- float sintersection = fl_intersection(mx, my, mw, mh, sx, sy, sw, sh);
- if(sintersection > best_intersection) {
+ float sintersection = fl_intersection(x, y, w, h, sx, sy, sw, sh);
+ if (sintersection > best_intersection) {
best_screen = i;
best_intersection = sintersection;
}
}
- screen_xywh(X, Y, W, H, best_screen);
+ return best_screen;
}
-
-
/**
Gets the screen resolution in dots-per-inch for the given screen.
\param[out] h, v horizontal and vertical resolution
@@ -389,5 +401,5 @@ void Fl::screen_dpi(float &h, float &v, int n)
//
-// End of "$Id: screen_xywh.cxx 9299 2012-03-23 16:47:53Z manolo $".
+// End of "$Id: screen_xywh.cxx 10228 2014-08-21 08:14:19Z cand $".
//
diff --git a/src/slowarrow.h b/src/slowarrow.h
index 46a572c..4ad428a 100644
--- a/src/slowarrow.h
+++ b/src/slowarrow.h
@@ -1,6 +1,6 @@
#define slowarrow_width 16
#define slowarrow_height 16
-static unsigned char slowarrow_bits[] = {
+static const unsigned char slowarrow_bits[] = {
0x40, 0x00, 0x40, 0x00, 0x60, 0x00, 0x60, 0x00, 0xf0, 0x0f, 0x60, 0x00,
0x60, 0x00, 0x40, 0x02, 0x40, 0x02, 0x00, 0x06, 0x00, 0x06, 0xf0, 0x0f,
0x00, 0x06, 0x00, 0x06, 0x00, 0x02, 0x00, 0x02};
diff --git a/src/tile.xpm b/src/tile.xpm
index 872e0f7..1fa410c 100644
--- a/src/tile.xpm
+++ b/src/tile.xpm
@@ -4,7 +4,7 @@ static char tile_cmap[3][32] = {
"o c #EFEFEF",
". c #E8E8E8"
};
-static const char * tile_xpm[] = {
+static const char * const tile_xpm[] = {
"64 64 3 1",
tile_cmap[0],
tile_cmap[1],
diff --git a/src/vsnprintf.c b/src/vsnprintf.c
index be93ba6..bbf4229 100644
--- a/src/vsnprintf.c
+++ b/src/vsnprintf.c
@@ -1,5 +1,5 @@
/*
- * "$Id: vsnprintf.c 9325 2012-04-05 05:12:30Z fabien $"
+ * "$Id: vsnprintf.c 10229 2014-08-21 12:01:46Z cand $"
*
* snprintf() and vsnprintf() functions for the Fast Light Tool Kit (FLTK).
*
@@ -28,6 +28,9 @@ extern "C" {
#endif
int fl_vsnprintf(char* buffer, size_t bufsize, const char* format, va_list ap) {
+#if defined(HAVE_VSNPRINTF) && defined(__linux__)
+ return vsnprintf(buffer, bufsize, format, ap);
+#else
char *bufptr, /* Pointer to position in buffer */
*bufend, /* Pointer to end of buffer */
sign, /* Sign of format width */
@@ -251,6 +254,7 @@ int fl_vsnprintf(char* buffer, size_t bufsize, const char* format, va_list ap) {
if (bufptr) *bufptr = '\0';
return (bytes);
+#endif //HAVE_VSNPRINTF
}
int fl_snprintf(char* str, size_t size, const char* fmt, ...) {
@@ -267,6 +271,6 @@ int fl_snprintf(char* str, size_t size, const char* fmt, ...) {
#endif
/*
- * End of "$Id: vsnprintf.c 9325 2012-04-05 05:12:30Z fabien $".
+ * End of "$Id: vsnprintf.c 10229 2014-08-21 12:01:46Z cand $".
*/
diff --git a/src/xutf8/headers/dingbats_.h b/src/xutf8/headers/dingbats_.h
index 9f1f225..a08bbf0 100644
--- a/src/xutf8/headers/dingbats_.h
+++ b/src/xutf8/headers/dingbats_.h
@@ -133,23 +133,23 @@ static const char unicode_to_dingbats_1b_0020[] = {
};
static const char unicode_to_dingbats_1b_2192[] = {
-/* U+2192 */ 0xD5,
+/* U+2192 */ (char)0xD5,
0x00,
-/* U+2194 */ 0xD6,
-/* U+2195 */ 0xD7,
+/* U+2194 */ (char)0xD6,
+/* U+2195 */ (char)0xD7,
};
static const char unicode_to_dingbats_1b_2460[] = {
-/* U+2460 */ 0xAC,
-/* U+2461 */ 0xAD,
-/* U+2462 */ 0xAE,
-/* U+2463 */ 0xAF,
-/* U+2464 */ 0xB0,
-/* U+2465 */ 0xB1,
-/* U+2466 */ 0xB2,
-/* U+2467 */ 0xB3,
-/* U+2468 */ 0xB4,
-/* U+2469 */ 0xB5,
+/* U+2460 */ (char)0xAC,
+/* U+2461 */ (char)0xAD,
+/* U+2462 */ (char)0xAE,
+/* U+2463 */ (char)0xAF,
+/* U+2464 */ (char)0xB0,
+/* U+2465 */ (char)0xB1,
+/* U+2466 */ (char)0xB2,
+/* U+2467 */ (char)0xB3,
+/* U+2468 */ (char)0xB4,
+/* U+2469 */ (char)0xB5,
};
static const char unicode_to_dingbats_1b_25A0[] = {
@@ -345,13 +345,13 @@ static const char unicode_to_dingbats_1b_25A0[] = {
0x00,
0x00,
0x00,
-/* U+2660 */ 0xAB,
+/* U+2660 */ (char)0xAB,
0x00,
0x00,
-/* U+2663 */ 0xA8,
+/* U+2663 */ (char)0xA8,
0x00,
-/* U+2665 */ 0xAA,
-/* U+2666 */ 0xA9,
+/* U+2665 */ (char)0xAA,
+/* U+2666 */ (char)0xA9,
};
static const char unicode_to_dingbats_1b_2701[] = {
@@ -451,115 +451,115 @@ static const char unicode_to_dingbats_1b_2701[] = {
/* U+275E */ 0x7E,
0x00,
0x00,
-/* U+2761 */ 0xA1,
-/* U+2762 */ 0xA2,
-/* U+2763 */ 0xA3,
-/* U+2764 */ 0xA4,
-/* U+2765 */ 0xA5,
-/* U+2766 */ 0xA6,
-/* U+2767 */ 0xA7,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-0x00,
-/* U+2776 */ 0xB6,
-/* U+2777 */ 0xB7,
-/* U+2778 */ 0xB8,
-/* U+2779 */ 0xB9,
-/* U+277A */ 0xBA,
-/* U+277B */ 0xBB,
-/* U+277C */ 0xBC,
-/* U+277D */ 0xBD,
-/* U+277E */ 0xBE,
-/* U+277F */ 0xBF,
-/* U+2780 */ 0xC0,
-/* U+2781 */ 0xC1,
-/* U+2782 */ 0xC2,
-/* U+2783 */ 0xC3,
-/* U+2784 */ 0xC4,
-/* U+2785 */ 0xC5,
-/* U+2786 */ 0xC6,
-/* U+2787 */ 0xC7,
-/* U+2788 */ 0xC8,
-/* U+2789 */ 0xC9,
-/* U+278A */ 0xCA,
-/* U+278B */ 0xCB,
-/* U+278C */ 0xCC,
-/* U+278D */ 0xCD,
-/* U+278E */ 0xCE,
-/* U+278F */ 0xCF,
-/* U+2790 */ 0xD0,
-/* U+2791 */ 0xD1,
-/* U+2792 */ 0xD2,
-/* U+2793 */ 0xD3,
-/* U+2794 */ 0xD4,
-0x00,
-0x00,
-0x00,
-/* U+2798 */ 0xD8,
-/* U+2799 */ 0xD9,
-/* U+279A */ 0xDA,
-/* U+279B */ 0xDB,
-/* U+279C */ 0xDC,
-/* U+279D */ 0xDD,
-/* U+279E */ 0xDE,
-/* U+279F */ 0xDF,
-/* U+27A0 */ 0xE0,
-/* U+27A1 */ 0xE1,
-/* U+27A2 */ 0xE2,
-/* U+27A3 */ 0xE3,
-/* U+27A4 */ 0xE4,
-/* U+27A5 */ 0xE5,
-/* U+27A6 */ 0xE6,
-/* U+27A7 */ 0xE7,
-/* U+27A8 */ 0xE8,
-/* U+27A9 */ 0xE9,
-/* U+27AA */ 0xEA,
-/* U+27AB */ 0xEB,
-/* U+27AC */ 0xEC,
-/* U+27AD */ 0xED,
-/* U+27AE */ 0xEE,
-/* U+27AF */ 0xEF,
-0x00,
-/* U+27B1 */ 0xF1,
-/* U+27B2 */ 0xF2,
-/* U+27B3 */ 0xF3,
-/* U+27B4 */ 0xF4,
-/* U+27B5 */ 0xF5,
-/* U+27B6 */ 0xF6,
-/* U+27B7 */ 0xF7,
-/* U+27B8 */ 0xF8,
-/* U+27B9 */ 0xF9,
-/* U+27BA */ 0xFA,
-/* U+27BB */ 0xFB,
-/* U+27BC */ 0xFC,
-/* U+27BD */ 0xFD,
-/* U+27BE */ 0xFE,
+/* U+2761 */ (char)0xA1,
+/* U+2762 */ (char)0xA2,
+/* U+2763 */ (char)0xA3,
+/* U+2764 */ (char)0xA4,
+/* U+2765 */ (char)0xA5,
+/* U+2766 */ (char)0xA6,
+/* U+2767 */ (char)0xA7,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+0x00,
+/* U+2776 */ (char)0xB6,
+/* U+2777 */ (char)0xB7,
+/* U+2778 */ (char)0xB8,
+/* U+2779 */ (char)0xB9,
+/* U+277A */ (char)0xBA,
+/* U+277B */ (char)0xBB,
+/* U+277C */ (char)0xBC,
+/* U+277D */ (char)0xBD,
+/* U+277E */ (char)0xBE,
+/* U+277F */ (char)0xBF,
+/* U+2780 */ (char)0xC0,
+/* U+2781 */ (char)0xC1,
+/* U+2782 */ (char)0xC2,
+/* U+2783 */ (char)0xC3,
+/* U+2784 */ (char)0xC4,
+/* U+2785 */ (char)0xC5,
+/* U+2786 */ (char)0xC6,
+/* U+2787 */ (char)0xC7,
+/* U+2788 */ (char)0xC8,
+/* U+2789 */ (char)0xC9,
+/* U+278A */ (char)0xCA,
+/* U+278B */ (char)0xCB,
+/* U+278C */ (char)0xCC,
+/* U+278D */ (char)0xCD,
+/* U+278E */ (char)0xCE,
+/* U+278F */ (char)0xCF,
+/* U+2790 */ (char)0xD0,
+/* U+2791 */ (char)0xD1,
+/* U+2792 */ (char)0xD2,
+/* U+2793 */ (char)0xD3,
+/* U+2794 */ (char)0xD4,
+0x00,
+0x00,
+0x00,
+/* U+2798 */ (char)0xD8,
+/* U+2799 */ (char)0xD9,
+/* U+279A */ (char)0xDA,
+/* U+279B */ (char)0xDB,
+/* U+279C */ (char)0xDC,
+/* U+279D */ (char)0xDD,
+/* U+279E */ (char)0xDE,
+/* U+279F */ (char)0xDF,
+/* U+27A0 */ (char)0xE0,
+/* U+27A1 */ (char)0xE1,
+/* U+27A2 */ (char)0xE2,
+/* U+27A3 */ (char)0xE3,
+/* U+27A4 */ (char)0xE4,
+/* U+27A5 */ (char)0xE5,
+/* U+27A6 */ (char)0xE6,
+/* U+27A7 */ (char)0xE7,
+/* U+27A8 */ (char)0xE8,
+/* U+27A9 */ (char)0xE9,
+/* U+27AA */ (char)0xEA,
+/* U+27AB */ (char)0xEB,
+/* U+27AC */ (char)0xEC,
+/* U+27AD */ (char)0xED,
+/* U+27AE */ (char)0xEE,
+/* U+27AF */ (char)0xEF,
+0x00,
+/* U+27B1 */ (char)0xF1,
+/* U+27B2 */ (char)0xF2,
+/* U+27B3 */ (char)0xF3,
+/* U+27B4 */ (char)0xF4,
+/* U+27B5 */ (char)0xF5,
+/* U+27B6 */ (char)0xF6,
+/* U+27B7 */ (char)0xF7,
+/* U+27B8 */ (char)0xF8,
+/* U+27B9 */ (char)0xF9,
+/* U+27BA */ (char)0xFA,
+/* U+27BB */ (char)0xFB,
+/* U+27BC */ (char)0xFC,
+/* U+27BD */ (char)0xFD,
+/* U+27BE */ (char)0xFE,
};
static const char unicode_to_dingbats_1b_F8D7[] = {
-/* U+F8D7 */ 0x80,
-/* U+F8D8 */ 0x81,
-/* U+F8D9 */ 0x82,
-/* U+F8DA */ 0x83,
-/* U+F8DB */ 0x84,
-/* U+F8DC */ 0x85,
-/* U+F8DD */ 0x86,
-/* U+F8DE */ 0x87,
-/* U+F8DF */ 0x88,
-/* U+F8E0 */ 0x89,
-/* U+F8E1 */ 0x8A,
-/* U+F8E2 */ 0x8B,
-/* U+F8E3 */ 0x8C,
-/* U+F8E4 */ 0x8D,
+/* U+F8D7 */ (char)0x80,
+/* U+F8D8 */ (char)0x81,
+/* U+F8D9 */ (char)0x82,
+/* U+F8DA */ (char)0x83,
+/* U+F8DB */ (char)0x84,
+/* U+F8DC */ (char)0x85,
+/* U+F8DD */ (char)0x86,
+/* U+F8DE */ (char)0x87,
+/* U+F8DF */ (char)0x88,
+/* U+F8E0 */ (char)0x89,
+/* U+F8E1 */ (char)0x8A,
+/* U+F8E2 */ (char)0x8B,
+/* U+F8E3 */ (char)0x8C,
+/* U+F8E4 */ (char)0x8D,
};
diff --git a/src/xutf8/headers/symbol_.h b/src/xutf8/headers/symbol_.h
index a9d8fd3..481c5e7 100644
--- a/src/xutf8/headers/symbol_.h
+++ b/src/xutf8/headers/symbol_.h
@@ -141,12 +141,12 @@ static const char unicode_to_symbol_1b_0020[] = {
0x00,
0x00,
0x00,
-/* U+00AC */ 0xD8,
+/* U+00AC */ (char)0xD8,
0x00,
0x00,
0x00,
-/* U+00B0 */ 0xB0,
-/* U+00B1 */ 0xB1,
+/* U+00B0 */ (char)0xB0,
+/* U+00B1 */ (char)0xB1,
0x00,
0x00,
0x00,
@@ -184,7 +184,7 @@ static const char unicode_to_symbol_1b_0020[] = {
0x00,
0x00,
0x00,
-/* U+00D7 */ 0xB4,
+/* U+00D7 */ (char)0xB4,
0x00,
0x00,
0x00,
@@ -216,11 +216,11 @@ static const char unicode_to_symbol_1b_0020[] = {
0x00,
0x00,
0x00,
-/* U+00F7 */ 0xB8,
+/* U+00F7 */ (char)0xB8,
};
static const char unicode_to_symbol_1b_0192[] = {
-/* U+0192 */ 0xA6,
+/* U+0192 */ (char)0xA6,
};
static const char unicode_to_symbol_1b_0391[] = {
@@ -289,7 +289,7 @@ static const char unicode_to_symbol_1b_0391[] = {
0x00,
0x00,
/* U+03D1 */ 0x4A,
-/* U+03D2 */ 0xA1,
+/* U+03D2 */ (char)0xA1,
0x00,
0x00,
/* U+03D5 */ 0x6A,
@@ -297,11 +297,11 @@ static const char unicode_to_symbol_1b_0391[] = {
};
static const char unicode_to_symbol_1b_2022[] = {
-/* U+2022 */ 0xB7,
+/* U+2022 */ (char)0xB7,
0x00,
0x00,
0x00,
-/* U+2026 */ 0xBC,
+/* U+2026 */ (char)0xBC,
0x00,
0x00,
0x00,
@@ -313,8 +313,8 @@ static const char unicode_to_symbol_1b_2022[] = {
0x00,
0x00,
0x00,
-/* U+2032 */ 0xA2,
-/* U+2033 */ 0xB2,
+/* U+2032 */ (char)0xA2,
+/* U+2033 */ (char)0xB2,
0x00,
0x00,
0x00,
@@ -331,7 +331,7 @@ static const char unicode_to_symbol_1b_2022[] = {
0x00,
0x00,
0x00,
-/* U+2044 */ 0xA4,
+/* U+2044 */ (char)0xA4,
0x00,
0x00,
0x00,
@@ -435,7 +435,7 @@ static const char unicode_to_symbol_1b_2022[] = {
0x00,
0x00,
0x00,
-/* U+20AC */ 0xA0,
+/* U+20AC */ (char)0xA0,
0x00,
0x00,
0x00,
@@ -536,18 +536,18 @@ static const char unicode_to_symbol_1b_2022[] = {
0x00,
0x00,
0x00,
-/* U+2111 */ 0xC1,
+/* U+2111 */ (char)0xC1,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
-/* U+2118 */ 0xC3,
+/* U+2118 */ (char)0xC3,
0x00,
0x00,
0x00,
-/* U+211C */ 0xC2,
+/* U+211C */ (char)0xC2,
0x00,
0x00,
0x00,
@@ -572,7 +572,7 @@ static const char unicode_to_symbol_1b_2022[] = {
0x00,
0x00,
0x00,
-/* U+2135 */ 0xC0,
+/* U+2135 */ (char)0xC0,
0x00,
0x00,
0x00,
@@ -663,11 +663,11 @@ static const char unicode_to_symbol_1b_2022[] = {
0x00,
0x00,
0x00,
-/* U+2190 */ 0xAC,
-/* U+2191 */ 0xAD,
-/* U+2192 */ 0xAE,
-/* U+2193 */ 0xAF,
-/* U+2194 */ 0xAB,
+/* U+2190 */ (char)0xAC,
+/* U+2191 */ (char)0xAD,
+/* U+2192 */ (char)0xAE,
+/* U+2193 */ (char)0xAF,
+/* U+2194 */ (char)0xAB,
0x00,
0x00,
0x00,
@@ -700,7 +700,7 @@ static const char unicode_to_symbol_1b_2022[] = {
0x00,
0x00,
0x00,
-/* U+21B5 */ 0xBF,
+/* U+21B5 */ (char)0xBF,
0x00,
0x00,
0x00,
@@ -727,11 +727,11 @@ static const char unicode_to_symbol_1b_2022[] = {
0x00,
0x00,
0x00,
-/* U+21D0 */ 0xDC,
-/* U+21D1 */ 0xDD,
-/* U+21D2 */ 0xDE,
-/* U+21D3 */ 0xDF,
-/* U+21D4 */ 0xDB,
+/* U+21D0 */ (char)0xDC,
+/* U+21D1 */ (char)0xDD,
+/* U+21D2 */ (char)0xDE,
+/* U+21D3 */ (char)0xDF,
+/* U+21D4 */ (char)0xDB,
0x00,
0x00,
0x00,
@@ -777,48 +777,48 @@ static const char unicode_to_symbol_1b_2022[] = {
0x00,
/* U+2200 */ 0x22,
0x00,
-/* U+2202 */ 0xB6,
+/* U+2202 */ (char)0xB6,
/* U+2203 */ 0x24,
0x00,
-/* U+2205 */ 0xC6,
+/* U+2205 */ (char)0xC6,
/* U+2206 */ 0x44,
-/* U+2207 */ 0xD1,
-/* U+2208 */ 0xCE,
-/* U+2209 */ 0xCF,
+/* U+2207 */ (char)0xD1,
+/* U+2208 */ (char)0xCE,
+/* U+2209 */ (char)0xCF,
0x00,
/* U+220B */ 0x27,
0x00,
0x00,
0x00,
-/* U+220F */ 0xD5,
+/* U+220F */ (char)0xD5,
0x00,
-/* U+2211 */ 0xE5,
+/* U+2211 */ (char)0xE5,
/* U+2212 */ 0x2D,
0x00,
0x00,
-/* U+2215 */ 0xA4,
+/* U+2215 */ (char)0xA4,
0x00,
/* U+2217 */ 0x2A,
0x00,
0x00,
-/* U+221A */ 0xD6,
+/* U+221A */ (char)0xD6,
0x00,
0x00,
-/* U+221D */ 0xB5,
-/* U+221E */ 0xA5,
+/* U+221D */ (char)0xB5,
+/* U+221E */ (char)0xA5,
0x00,
-/* U+2220 */ 0xD0,
+/* U+2220 */ (char)0xD0,
0x00,
0x00,
0x00,
0x00,
0x00,
0x00,
-/* U+2227 */ 0xD9,
-/* U+2228 */ 0xDA,
-/* U+2229 */ 0xC7,
-/* U+222A */ 0xC8,
-/* U+222B */ 0xF2,
+/* U+2227 */ (char)0xD9,
+/* U+2228 */ (char)0xDA,
+/* U+2229 */ (char)0xC7,
+/* U+222A */ (char)0xC8,
+/* U+222B */ (char)0xF2,
0x00,
0x00,
0x00,
@@ -847,7 +847,7 @@ static const char unicode_to_symbol_1b_2022[] = {
/* U+2245 */ 0x40,
0x00,
0x00,
-/* U+2248 */ 0xBB,
+/* U+2248 */ (char)0xBB,
0x00,
0x00,
0x00,
@@ -871,12 +871,12 @@ static const char unicode_to_symbol_1b_2022[] = {
0x00,
0x00,
0x00,
-/* U+2260 */ 0xB9,
-/* U+2261 */ 0xBA,
+/* U+2260 */ (char)0xB9,
+/* U+2261 */ (char)0xBA,
0x00,
0x00,
-/* U+2264 */ 0xA3,
-/* U+2265 */ 0xB3,
+/* U+2264 */ (char)0xA3,
+/* U+2265 */ (char)0xB3,
0x00,
0x00,
0x00,
@@ -905,12 +905,12 @@ static const char unicode_to_symbol_1b_2022[] = {
0x00,
0x00,
0x00,
-/* U+2282 */ 0xCC,
-/* U+2283 */ 0xC9,
-/* U+2284 */ 0xCB,
+/* U+2282 */ (char)0xCC,
+/* U+2283 */ (char)0xC9,
+/* U+2284 */ (char)0xCB,
0x00,
-/* U+2286 */ 0xCD,
-/* U+2287 */ 0xCA,
+/* U+2286 */ (char)0xCD,
+/* U+2287 */ (char)0xCA,
0x00,
0x00,
0x00,
@@ -924,9 +924,9 @@ static const char unicode_to_symbol_1b_2022[] = {
0x00,
0x00,
0x00,
-/* U+2295 */ 0xC5,
+/* U+2295 */ (char)0xC5,
0x00,
-/* U+2297 */ 0xC4,
+/* U+2297 */ (char)0xC4,
0x00,
0x00,
0x00,
@@ -972,7 +972,7 @@ static const char unicode_to_symbol_1b_2022[] = {
0x00,
0x00,
0x00,
-/* U+22C5 */ 0xD7,
+/* U+22C5 */ (char)0xD7,
0x00,
0x00,
0x00,
@@ -1063,8 +1063,8 @@ static const char unicode_to_symbol_1b_2022[] = {
0x00,
0x00,
0x00,
-/* U+2320 */ 0xF3,
-/* U+2321 */ 0xF5,
+/* U+2320 */ (char)0xF3,
+/* U+2321 */ (char)0xF5,
0x00,
0x00,
0x00,
@@ -1072,55 +1072,55 @@ static const char unicode_to_symbol_1b_2022[] = {
0x00,
0x00,
0x00,
-/* U+2329 */ 0xE1,
-/* U+232A */ 0xF1,
+/* U+2329 */ (char)0xE1,
+/* U+232A */ (char)0xF1,
};
static const char unicode_to_symbol_1b_25CA[] = {
-/* U+25CA */ 0xE0,
+/* U+25CA */ (char)0xE0,
};
static const char unicode_to_symbol_1b_2660[] = {
-/* U+2660 */ 0xAA,
+/* U+2660 */ (char)0xAA,
0x00,
0x00,
-/* U+2663 */ 0xA7,
+/* U+2663 */ (char)0xA7,
0x00,
-/* U+2665 */ 0xA9,
-/* U+2666 */ 0xA8,
+/* U+2665 */ (char)0xA9,
+/* U+2666 */ (char)0xA8,
};
static const char unicode_to_symbol_1b_F6D9[] = {
-/* U+F6D9 */ 0xD3,
-/* U+F6DA */ 0xD2,
-/* U+F6DB */ 0xD4,
+/* U+F6D9 */ (char)0xD3,
+/* U+F6DA */ (char)0xD2,
+/* U+F6DB */ (char)0xD4,
};
static const char unicode_to_symbol_1b_F8E5[] = {
/* U+F8E5 */ 0x60,
-/* U+F8E6 */ 0xBD,
-/* U+F8E7 */ 0xBE,
-/* U+F8E8 */ 0xE2,
-/* U+F8E9 */ 0xE3,
-/* U+F8EA */ 0xE4,
-/* U+F8EB */ 0xE6,
-/* U+F8EC */ 0xE7,
-/* U+F8ED */ 0xE8,
-/* U+F8EE */ 0xE9,
-/* U+F8EF */ 0xEA,
-/* U+F8F0 */ 0xEB,
-/* U+F8F1 */ 0xEC,
-/* U+F8F2 */ 0xED,
-/* U+F8F3 */ 0xEE,
-/* U+F8F4 */ 0xEF,
-/* U+F8F5 */ 0xF4,
-/* U+F8F6 */ 0xF6,
-/* U+F8F7 */ 0xF7,
-/* U+F8F8 */ 0xF8,
-/* U+F8F9 */ 0xF9,
-/* U+F8FA */ 0xFA,
-/* U+F8FB */ 0xFB,
-/* U+F8FC */ 0xFC,
-/* U+F8FD */ 0xFD,
-/* U+F8FE */ 0xFE,
+/* U+F8E6 */ (char)0xBD,
+/* U+F8E7 */ (char)0xBE,
+/* U+F8E8 */ (char)0xE2,
+/* U+F8E9 */ (char)0xE3,
+/* U+F8EA */ (char)0xE4,
+/* U+F8EB */ (char)0xE6,
+/* U+F8EC */ (char)0xE7,
+/* U+F8ED */ (char)0xE8,
+/* U+F8EE */ (char)0xE9,
+/* U+F8EF */ (char)0xEA,
+/* U+F8F0 */ (char)0xEB,
+/* U+F8F1 */ (char)0xEC,
+/* U+F8F2 */ (char)0xED,
+/* U+F8F3 */ (char)0xEE,
+/* U+F8F4 */ (char)0xEF,
+/* U+F8F5 */ (char)0xF4,
+/* U+F8F6 */ (char)0xF6,
+/* U+F8F7 */ (char)0xF7,
+/* U+F8F8 */ (char)0xF8,
+/* U+F8F9 */ (char)0xF9,
+/* U+F8FA */ (char)0xFA,
+/* U+F8FB */ (char)0xFB,
+/* U+F8FC */ (char)0xFC,
+/* U+F8FD */ (char)0xFD,
+/* U+F8FE */ (char)0xFE,
};
diff --git a/src/xutf8/imKStoUCS.c b/src/xutf8/imKStoUCS.c
index 0af9a80..aa67020 100644
--- a/src/xutf8/imKStoUCS.c
+++ b/src/xutf8/imKStoUCS.c
@@ -266,7 +266,7 @@ static unsigned short const keysym_to_unicode_20a0_20ac[] = {
0x20a8, 0x20a9, 0x20aa, 0x20ab, 0x20ac /* 0x20a8-0x20af */
};
-unsigned int
+static unsigned int
KeySymToUcs4(KeySym keysym)
{
/* 'Unicode keysym' */
diff --git a/src/xutf8/is_right2left.c b/src/xutf8/is_right2left.c
index 7b49af1..69a612a 100644
--- a/src/xutf8/is_right2left.c
+++ b/src/xutf8/is_right2left.c
@@ -18,7 +18,11 @@
* This file is required on all platforms for utf8 support
*/
-unsigned short
+#if !defined(WIN32) && !defined(__APPLE__)
+# include "../Xutf8.h"
+#endif /* !defined(WIN32) && !defined(__APPLE__) */
+
+unsigned short
XUtf8IsRightToLeft(unsigned int ucs) {
#if 0
@@ -34,7 +38,7 @@ XUtf8IsRightToLeft(unsigned int ucs) {
if (ucs >= 0x0591) return 1;
return 0;
}
-
+
/* ARABIC */
if (ucs <= 0x06ED) {
if (ucs >= 0x060C) return 1;
@@ -56,7 +60,7 @@ XUtf8IsRightToLeft(unsigned int ucs) {
if (ucs >= 0xFB1E) return 1;
return 0;
}
-
+
if (ucs <= 0xFDFB) {
if (ucs >= 0xFB50) return 1;
return 0;
diff --git a/src/xutf8/keysym2Ucs.c b/src/xutf8/keysym2Ucs.c
index 052a7c7..d01a3a7 100644
--- a/src/xutf8/keysym2Ucs.c
+++ b/src/xutf8/keysym2Ucs.c
@@ -18,7 +18,7 @@
#if !defined(WIN32) && !defined(__APPLE__)
-#include "../../FL/Xutf8.h"
+#include "../Xutf8.h"
#include "imKStoUCS.c"
long XKeysymToUcs(KeySym keysym) {
diff --git a/src/xutf8/ucs2fontmap.c b/src/xutf8/ucs2fontmap.c
index da08052..8446b08 100644
--- a/src/xutf8/ucs2fontmap.c
+++ b/src/xutf8/ucs2fontmap.c
@@ -57,13 +57,12 @@ typedef struct {
/*************** conv_gen.c ************/
/*const*/
-int ucs2fontmap(char *s, unsigned int ucs, int enc) {
+static int ucs2fontmap(char *s, unsigned int ucs, int enc) {
switch(enc) {
case 0: /* iso10646-1 */
s[0] = (char) ((ucs & 0xFF00) >> 8);
s[1] = (char) (ucs & 0xFF);
return 0;
- break;
case 1: /* iso8859-1 */
if (ucs <= 0x00FF) {
if (ucs >= 0x0001) {
@@ -299,7 +298,7 @@ int ucs2fontmap(char *s, unsigned int ucs, int enc) {
}
/*const*/
-int encoding_number(const char *enc) {
+static int encoding_number(const char *enc) {
if (!enc || !strncmp(enc, "iso10646-1", 10)) {
return 0;
} else if (!strcmp(enc, "iso8859-1")) {
diff --git a/src/xutf8/utf8Input.c b/src/xutf8/utf8Input.c
index ee2c229..5682ac7 100644
--- a/src/xutf8/utf8Input.c
+++ b/src/xutf8/utf8Input.c
@@ -17,7 +17,7 @@
#if !defined(WIN32) && !defined(__APPLE__)
#include <config.h>
-#include "../../FL/Xutf8.h"
+#include "../Xutf8.h"
#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
@@ -43,6 +43,7 @@ typedef struct {
unsigned short used;
} Summary16;
+#ifndef X_HAVE_UTF8_STRING
#define NEED_TOWC /* indicates what part of these include files is needed here (avoid compilation warnings) */
#include "lcUniConv/big5.h"
#include "lcUniConv/gb2312.h"
@@ -52,7 +53,7 @@ typedef struct {
#include "lcUniConv/jisx0212.h"
#include "lcUniConv/ksc5601.h"
-int
+static int
XConvertEucTwToUtf8(char* buffer_return, int len) {
/* FIXME */
#if HAVE_LIBC_ICONV
@@ -119,7 +120,7 @@ XConvertEucTwToUtf8(char* buffer_return, int len) {
return l;
}
-int
+static int
XConvertEucKrToUtf8(char* buffer_return, int len) {
int i = 0, l = 0;
char *buf;
@@ -159,7 +160,7 @@ XConvertEucKrToUtf8(char* buffer_return, int len) {
return l;
}
-int
+static int
XConvertBig5ToUtf8(char* buffer_return, int len) {
int i = 0, l = 0;
char *buf;
@@ -188,7 +189,7 @@ XConvertBig5ToUtf8(char* buffer_return, int len) {
return l;
}
-int
+static int
XConvertCp936extToUtf8(char* buffer_return, int len)
{
int i = 0, l = 0;
@@ -225,7 +226,7 @@ XConvertCp936extToUtf8(char* buffer_return, int len)
return l;
}
-int
+static int
XConvertGb2312ToUtf8(char* buffer_return, int len) {
int i = 0, l = 0;
char *buf;
@@ -260,7 +261,7 @@ XConvertGb2312ToUtf8(char* buffer_return, int len) {
return l;
}
-int
+static int
XConvertEucCnToUtf8(char* buffer_return, int len) {
int i = 0, l = 0;
char *buf;
@@ -299,7 +300,7 @@ XConvertEucCnToUtf8(char* buffer_return, int len) {
return l;
}
-int
+static int
XConvertEucJpToUtf8(char* buffer_return, int len) {
int i = 0, l = 0;
char *buf;
@@ -372,7 +373,7 @@ XConvertEucJpToUtf8(char* buffer_return, int len) {
return l;
}
-int
+static int
XConvertEucToUtf8(const char* locale,
char* buffer_return,
int len,
@@ -447,6 +448,7 @@ XUtf8LookupString(XIC ic,
}
return len;
}
+#endif /* X11 has utf-8 */
#endif /* X11 only */
diff --git a/src/xutf8/utf8Utils.c b/src/xutf8/utf8Utils.c
index 1e60b76..54bbccf 100644
--- a/src/xutf8/utf8Utils.c
+++ b/src/xutf8/utf8Utils.c
@@ -20,7 +20,7 @@
#if !defined(WIN32) && !defined(__APPLE__)
-#include "../../FL/Xutf8.h"
+#include "../Xutf8.h"
/*** NOTE : all functions are LIMITED to 24 bits Unicode values !!! ***/
diff --git a/src/xutf8/utf8Wrap.c b/src/xutf8/utf8Wrap.c
index 9c44f47..d26eba1 100644
--- a/src/xutf8/utf8Wrap.c
+++ b/src/xutf8/utf8Wrap.c
@@ -1,4 +1,4 @@
-/* "$Id: utf8Wrap.c 9549 2012-05-26 22:51:07Z greg.ercolano $"
+/* "$Id: utf8Wrap.c 10248 2014-08-23 08:41:58Z cand $"
*
* Author: Jean-Marc Lienher ( http://oksid.ch )
* Copyright 2000-2003 by O'ksi'D.
@@ -19,7 +19,7 @@
*/
#if !defined(WIN32) && !defined(__APPLE__)
-#include "../../FL/Xutf8.h"
+#include "../Xutf8.h"
#include <X11/Xlib.h>
#include <ctype.h>
#include <stdlib.h>
@@ -79,7 +79,7 @@ get_font_list(
while (*ptr) {
int l = 0, i = 0;
- while(isspace(*ptr)) ptr++;
+ while(isspace((int)(unsigned char)*ptr)) ptr++;
p = ptr;
while (*ptr && *ptr != ',') { ptr++; l++; }
if (l > 2) {
@@ -203,7 +203,7 @@ get_encodings(char **font_name_list,
/*********************************************************************/
/** find the first font which matches the name and load it. **/
/*********************************************************************/
-XFontStruct *
+static XFontStruct *
find_best_font(Display *dpy,
char **name) {
@@ -1039,5 +1039,5 @@ XFreeUtf8FontStruct(Display *dpy,
#endif /* X11 only */
/*
- * End of "$Id: utf8Wrap.c 9549 2012-05-26 22:51:07Z greg.ercolano $".
+ * End of "$Id: utf8Wrap.c 10248 2014-08-23 08:41:58Z cand $".
*/