X11 platform: use Gnome printer dialog when the GTK library is available at run-time
The code to determine whether the GTK library is available is now in Fl_X11_System_Driver::probe_for_GTK() called both by Fl_Printer::begin_job() and Fl_Native_File_Chooser. New Fl::option OPTION_PRINTER_USES_GTK allows to deactivate use of the Gnome print dialog. Minor change in Fl_Native_File_Chooser: GTK version 3 is searched before version 2, whereas the search order was the opposite before.
This commit is contained in:
parent
000807cc1d
commit
c549b7acbd
4
FL/Fl.H
4
FL/Fl.H
@ -252,6 +252,10 @@ public:
|
||||
/// if the GTK library is available on the platform (linux/unix only).
|
||||
/// When switched off, GTK file dialogs aren't used even if the GTK library is available.
|
||||
OPTION_FNFC_USES_GTK,
|
||||
/// When switched on (default), Fl_Printer runs the GTK printer dialog
|
||||
/// if the GTK library is available on the platform (linux/unix only).
|
||||
/// When switched off, the GTK printer dialog isn't used even if the GTK library is available.
|
||||
OPTION_PRINTER_USES_GTK,
|
||||
/// When switched on (default), the library shows in a transient yellow window the zoom factor
|
||||
/// value.
|
||||
/// When switched off, no such window gets displayed.
|
||||
|
@ -555,6 +555,7 @@ static void refreshUI() {
|
||||
wShowTooltips->value(opt[Fl::OPTION_SHOW_TOOLTIPS][mode]);
|
||||
wDNDText->value(opt[Fl::OPTION_DND_TEXT][mode]);
|
||||
wGTKText->value(opt[Fl::OPTION_FNFC_USES_GTK][mode]);
|
||||
wPrintGTKText->value(opt[Fl::OPTION_PRINTER_USES_GTK][mode]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -570,6 +571,7 @@ static void readPrefs() {
|
||||
opt_prefs.get("DNDText", opt[Fl::OPTION_DND_TEXT][1], 2);
|
||||
opt_prefs.get("ShowTooltips", opt[Fl::OPTION_SHOW_TOOLTIPS][1], 2);
|
||||
opt_prefs.get("FNFCUsesGTK", opt[Fl::OPTION_FNFC_USES_GTK ][1], 2);
|
||||
opt_prefs.get("PrintUsesGTK", opt[Fl::OPTION_PRINTER_USES_GTK ][1], 2);
|
||||
}
|
||||
{
|
||||
Fl_Preferences prefs(Fl_Preferences::USER, "fltk.org", "fltk");
|
||||
@ -579,6 +581,7 @@ static void readPrefs() {
|
||||
opt_prefs.get("DNDText", opt[Fl::OPTION_DND_TEXT][0], 2);
|
||||
opt_prefs.get("ShowTooltips", opt[Fl::OPTION_SHOW_TOOLTIPS][0], 2);
|
||||
opt_prefs.get("FNFCUsesGTK", opt[Fl::OPTION_FNFC_USES_GTK ][0], 2);
|
||||
opt_prefs.get("PrintUsesGTK", opt[Fl::OPTION_PRINTER_USES_GTK ][0], 2);
|
||||
}
|
||||
refreshUI();
|
||||
}
|
||||
@ -601,6 +604,8 @@ static void writePrefs() {
|
||||
else opt_prefs.set("ShowTooltips", opt[Fl::OPTION_SHOW_TOOLTIPS][1]);
|
||||
if (opt[Fl::OPTION_FNFC_USES_GTK][1]==2) opt_prefs.deleteEntry("FNFCUsesGTK");
|
||||
else opt_prefs.set("FNFCUsesGTK", opt[Fl::OPTION_FNFC_USES_GTK][1]);
|
||||
if (opt[Fl::OPTION_PRINTER_USES_GTK][1]==2) opt_prefs.deleteEntry("PrintUsesGTK");
|
||||
else opt_prefs.set("PrintUsesGTK", opt[Fl::OPTION_PRINTER_USES_GTK][1]);
|
||||
}
|
||||
{
|
||||
Fl_Preferences prefs(Fl_Preferences::USER, "fltk.org", "fltk");
|
||||
@ -615,6 +620,8 @@ static void writePrefs() {
|
||||
else opt_prefs.set("ShowTooltips", opt[Fl::OPTION_SHOW_TOOLTIPS][0]);
|
||||
if (opt[Fl::OPTION_FNFC_USES_GTK][0]==2) opt_prefs.deleteEntry("FNFCUsesGTK");
|
||||
else opt_prefs.set("FNFCUsesGTK", opt[Fl::OPTION_FNFC_USES_GTK][0]);
|
||||
if (opt[Fl::OPTION_PRINTER_USES_GTK][0]==2) opt_prefs.deleteEntry("PrintUsesGTK");
|
||||
else opt_prefs.set("PrintUsesGTK", opt[Fl::OPTION_PRINTER_USES_GTK][0]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -705,6 +712,20 @@ Fl_Menu_Item menu_wGTKText[] = {
|
||||
{0,0,0,0,0,0,0,0,0}
|
||||
};
|
||||
|
||||
Fl_Choice *wPrintGTKText=(Fl_Choice *)0;
|
||||
|
||||
static void cb_wPrintGTKText(Fl_Choice*, void*) {
|
||||
int mode = wUserOrSystem->value();
|
||||
opt[Fl::OPTION_PRINTER_USES_GTK ][mode] = wPrintGTKText->value();
|
||||
}
|
||||
|
||||
Fl_Menu_Item menu_wPrintGTKText[] = {
|
||||
{"off", 0, 0, (void*)(0), 0, (uchar)FL_NORMAL_LABEL, 0, 14, 0},
|
||||
{"on", 0, 0, (void*)(1), 128, (uchar)FL_NORMAL_LABEL, 0, 14, 0},
|
||||
{"default", 0, 0, (void*)(2), 0, (uchar)FL_NORMAL_LABEL, 0, 14, 0},
|
||||
{0,0,0,0,0,0,0,0,0}
|
||||
};
|
||||
|
||||
Fl_Choice *wUserOrSystem=(Fl_Choice *)0;
|
||||
|
||||
static void cb_wUserOrSystem(Fl_Choice*, void*) {
|
||||
@ -727,7 +748,7 @@ global_settings_window->hide();
|
||||
}
|
||||
|
||||
Fl_Double_Window* make_global_settings_window() {
|
||||
{ global_settings_window = new Fl_Double_Window(400, 378, "FLTK Preferences");
|
||||
{ global_settings_window = new Fl_Double_Window(400, 455, "FLTK Preferences");
|
||||
global_settings_window->color(FL_LIGHT1);
|
||||
{ Fl_Group* o = new Fl_Group(10, 10, 380, 100, "Keyboard Focus Options");
|
||||
o->box(FL_GTK_DOWN_BOX);
|
||||
@ -798,7 +819,22 @@ s available.\n\nDefault is on.");
|
||||
} // Fl_Choice* wGTKText
|
||||
o->end();
|
||||
} // Fl_Group* o
|
||||
{ wUserOrSystem = new Fl_Choice(10, 345, 141, 25);
|
||||
{ Fl_Group* o = new Fl_Group(10, 345, 380, 66, "Print dialog Options");
|
||||
o->box(FL_GTK_DOWN_BOX);
|
||||
o->labelfont(2);
|
||||
o->align(Fl_Align(FL_ALIGN_TOP_LEFT|FL_ALIGN_INSIDE));
|
||||
{ wPrintGTKText = new Fl_Choice(245, 366, 100, 25, "Print dialog uses GTK:");
|
||||
wPrintGTKText->tooltip("OPTION_PRINTER_USES_GTK\n\nIf \'Print dialog uses GTK\' is enabled, the Fl_Pr\
|
||||
inter class\ncalls the GTK print dialog when it\'s available on the platfom. I\
|
||||
f disabled, the Fl_Printer class\nalways uses FLTK\'s own print dialog even if\
|
||||
GTK is available.\n\nDefault is on.");
|
||||
wPrintGTKText->down_box(FL_BORDER_BOX);
|
||||
wPrintGTKText->callback((Fl_Callback*)cb_wPrintGTKText);
|
||||
wPrintGTKText->menu(menu_wPrintGTKText);
|
||||
} // Fl_Choice* wPrintGTKText
|
||||
o->end();
|
||||
} // Fl_Group* o
|
||||
{ wUserOrSystem = new Fl_Choice(10, 420, 141, 25);
|
||||
wUserOrSystem->tooltip("Change settings for the current user, or default values for all users of this\
|
||||
computer. Individual users can override system options, if they set their opt\
|
||||
ions to specific values (not \'default\').");
|
||||
@ -806,10 +842,10 @@ ions to specific values (not \'default\').");
|
||||
wUserOrSystem->callback((Fl_Callback*)cb_wUserOrSystem);
|
||||
wUserOrSystem->menu(menu_wUserOrSystem);
|
||||
} // Fl_Choice* wUserOrSystem
|
||||
{ Fl_Button* o = new Fl_Button(230, 345, 75, 25, "Cancel");
|
||||
{ Fl_Button* o = new Fl_Button(230, 420, 75, 25, "Cancel");
|
||||
o->callback((Fl_Callback*)cb_Cancel1);
|
||||
} // Fl_Button* o
|
||||
{ Fl_Button* o = new Fl_Button(315, 345, 75, 25, "OK");
|
||||
{ Fl_Button* o = new Fl_Button(315, 420, 75, 25, "OK");
|
||||
o->callback((Fl_Callback*)cb_OK);
|
||||
} // Fl_Button* o
|
||||
global_settings_window->end();
|
||||
|
@ -484,7 +484,8 @@ wVisibleFocus->value(opt[Fl::OPTION_VISIBLE_FOCUS][mode]);
|
||||
wArrowFocus->value(opt[Fl::OPTION_ARROW_FOCUS][mode]);
|
||||
wShowTooltips->value(opt[Fl::OPTION_SHOW_TOOLTIPS][mode]);
|
||||
wDNDText->value(opt[Fl::OPTION_DND_TEXT][mode]);
|
||||
wGTKText->value(opt[Fl::OPTION_FNFC_USES_GTK][mode]);} {}
|
||||
wGTKText->value(opt[Fl::OPTION_FNFC_USES_GTK][mode]);
|
||||
wPrintGTKText->value(opt[Fl::OPTION_PRINTER_USES_GTK][mode]);} {}
|
||||
}
|
||||
|
||||
Function {readPrefs()} {
|
||||
@ -499,6 +500,7 @@ Function {readPrefs()} {
|
||||
opt_prefs.get("DNDText", opt[Fl::OPTION_DND_TEXT][1], 2);
|
||||
opt_prefs.get("ShowTooltips", opt[Fl::OPTION_SHOW_TOOLTIPS][1], 2);
|
||||
opt_prefs.get("FNFCUsesGTK", opt[Fl::OPTION_FNFC_USES_GTK ][1], 2);
|
||||
opt_prefs.get("PrintUsesGTK", opt[Fl::OPTION_PRINTER_USES_GTK ][1], 2);
|
||||
}
|
||||
{
|
||||
Fl_Preferences prefs(Fl_Preferences::USER, "fltk.org", "fltk");
|
||||
@ -508,6 +510,7 @@ Function {readPrefs()} {
|
||||
opt_prefs.get("DNDText", opt[Fl::OPTION_DND_TEXT][0], 2);
|
||||
opt_prefs.get("ShowTooltips", opt[Fl::OPTION_SHOW_TOOLTIPS][0], 2);
|
||||
opt_prefs.get("FNFCUsesGTK", opt[Fl::OPTION_FNFC_USES_GTK ][0], 2);
|
||||
opt_prefs.get("PrintUsesGTK", opt[Fl::OPTION_PRINTER_USES_GTK ][0], 2);
|
||||
}
|
||||
refreshUI();} {}
|
||||
}
|
||||
@ -529,6 +532,8 @@ Function {writePrefs()} {
|
||||
else opt_prefs.set("ShowTooltips", opt[Fl::OPTION_SHOW_TOOLTIPS][1]);
|
||||
if (opt[Fl::OPTION_FNFC_USES_GTK][1]==2) opt_prefs.deleteEntry("FNFCUsesGTK");
|
||||
else opt_prefs.set("FNFCUsesGTK", opt[Fl::OPTION_FNFC_USES_GTK][1]);
|
||||
if (opt[Fl::OPTION_PRINTER_USES_GTK][1]==2) opt_prefs.deleteEntry("PrintUsesGTK");
|
||||
else opt_prefs.set("PrintUsesGTK", opt[Fl::OPTION_PRINTER_USES_GTK][1]);
|
||||
}
|
||||
{
|
||||
Fl_Preferences prefs(Fl_Preferences::USER, "fltk.org", "fltk");
|
||||
@ -543,6 +548,8 @@ Function {writePrefs()} {
|
||||
else opt_prefs.set("ShowTooltips", opt[Fl::OPTION_SHOW_TOOLTIPS][0]);
|
||||
if (opt[Fl::OPTION_FNFC_USES_GTK][0]==2) opt_prefs.deleteEntry("FNFCUsesGTK");
|
||||
else opt_prefs.set("FNFCUsesGTK", opt[Fl::OPTION_FNFC_USES_GTK][0]);
|
||||
if (opt[Fl::OPTION_PRINTER_USES_GTK][0]==2) opt_prefs.deleteEntry("PrintUsesGTK");
|
||||
else opt_prefs.set("PrintUsesGTK", opt[Fl::OPTION_PRINTER_USES_GTK][0]);
|
||||
}} {}
|
||||
}
|
||||
|
||||
@ -565,7 +572,7 @@ global_settings_window->show();} {}
|
||||
Function {make_global_settings_window()} {} {
|
||||
Fl_Window global_settings_window {
|
||||
label {FLTK Preferences} open
|
||||
xywh {1147 190 400 378} type Double color 50 hide
|
||||
xywh {715 96 400 455} type Double color 50 hide
|
||||
} {
|
||||
Fl_Group {} {
|
||||
label {Keyboard Focus Options} open
|
||||
@ -719,9 +726,42 @@ Default is on.} xywh {245 300 100 25} down_box BORDER_BOX
|
||||
}
|
||||
}
|
||||
}
|
||||
Fl_Group {} {
|
||||
label {Print dialog Options} open
|
||||
xywh {10 345 380 66} box GTK_DOWN_BOX labelfont 2 align 21
|
||||
} {
|
||||
Fl_Choice wPrintGTKText {
|
||||
label {Print dialog uses GTK:}
|
||||
callback {int mode = wUserOrSystem->value();
|
||||
opt[Fl::OPTION_PRINTER_USES_GTK ][mode] = wPrintGTKText->value();} open
|
||||
tooltip {OPTION_PRINTER_USES_GTK
|
||||
|
||||
If 'Print dialog uses GTK' is enabled, the Fl_Printer class
|
||||
calls the GTK print dialog when it's available on the platfom. If disabled, the Fl_Printer class
|
||||
always uses FLTK's own print dialog even if GTK is available.
|
||||
|
||||
Default is on.} xywh {245 366 100 25} down_box BORDER_BOX
|
||||
} {
|
||||
MenuItem {} {
|
||||
label off
|
||||
user_data 0 user_data_type long selected
|
||||
xywh {30 30 31 20}
|
||||
}
|
||||
MenuItem {} {
|
||||
label on
|
||||
user_data 1 user_data_type long
|
||||
xywh {30 30 31 20} divider
|
||||
}
|
||||
MenuItem {} {
|
||||
label default
|
||||
user_data 2 user_data_type long
|
||||
xywh {30 30 31 20}
|
||||
}
|
||||
}
|
||||
}
|
||||
Fl_Choice wUserOrSystem {
|
||||
callback {refreshUI();} open
|
||||
tooltip {Change settings for the current user, or default values for all users of this computer. Individual users can override system options, if they set their options to specific values (not 'default').} xywh {10 345 141 25} down_box BORDER_BOX
|
||||
tooltip {Change settings for the current user, or default values for all users of this computer. Individual users can override system options, if they set their options to specific values (not 'default').} xywh {10 420 141 25} down_box BORDER_BOX
|
||||
} {
|
||||
MenuItem {} {
|
||||
label {User Settings}
|
||||
@ -737,13 +777,13 @@ Default is on.} xywh {245 300 100 25} down_box BORDER_BOX
|
||||
Fl_Button {} {
|
||||
label Cancel
|
||||
callback {global_settings_window->hide();}
|
||||
xywh {230 345 75 25}
|
||||
xywh {230 420 75 25}
|
||||
}
|
||||
Fl_Button {} {
|
||||
label OK
|
||||
callback {writePrefs();
|
||||
global_settings_window->hide();}
|
||||
xywh {315 345 75 25}
|
||||
xywh {315 420 75 25}
|
||||
}
|
||||
}
|
||||
code {readPrefs();
|
||||
|
@ -108,6 +108,7 @@ extern Fl_Choice *wArrowFocus;
|
||||
extern Fl_Choice *wShowTooltips;
|
||||
extern Fl_Choice *wDNDText;
|
||||
extern Fl_Choice *wGTKText;
|
||||
extern Fl_Choice *wPrintGTKText;
|
||||
extern Fl_Choice *wUserOrSystem;
|
||||
Fl_Double_Window* make_global_settings_window();
|
||||
extern Fl_Menu_Item menu_wVisibleFocus[];
|
||||
@ -115,6 +116,7 @@ extern Fl_Menu_Item menu_wArrowFocus[];
|
||||
extern Fl_Menu_Item menu_wShowTooltips[];
|
||||
extern Fl_Menu_Item menu_wDNDText[];
|
||||
extern Fl_Menu_Item menu_wGTKText[];
|
||||
extern Fl_Menu_Item menu_wPrintGTKText[];
|
||||
extern Fl_Menu_Item menu_wUserOrSystem[];
|
||||
#endif
|
||||
|
||||
|
@ -1866,7 +1866,9 @@ bool Fl::option(Fl_Option opt)
|
||||
options_[OPTION_SHOW_TOOLTIPS] = tmp;
|
||||
opt_prefs.get("FNFCUsesGTK", tmp, 1); // default: on
|
||||
options_[OPTION_FNFC_USES_GTK] = tmp;
|
||||
|
||||
opt_prefs.get("PrintUsesGTK", tmp, 1); // default: on
|
||||
options_[OPTION_PRINTER_USES_GTK] = tmp;
|
||||
|
||||
opt_prefs.get("ShowZoomFactor", tmp, 1); // default: on
|
||||
options_[OPTION_SHOW_SCALING] = tmp;
|
||||
}
|
||||
@ -1888,7 +1890,9 @@ bool Fl::option(Fl_Option opt)
|
||||
if (tmp >= 0) options_[OPTION_SHOW_TOOLTIPS] = tmp;
|
||||
opt_prefs.get("FNFCUsesGTK", tmp, -1);
|
||||
if (tmp >= 0) options_[OPTION_FNFC_USES_GTK] = tmp;
|
||||
|
||||
opt_prefs.get("PrintUsesGTK", tmp, -1);
|
||||
if (tmp >= 0) options_[OPTION_PRINTER_USES_GTK] = tmp;
|
||||
|
||||
opt_prefs.get("ShowZoomFactor", tmp, -1);
|
||||
if (tmp >= 0) options_[OPTION_SHOW_SCALING] = tmp;
|
||||
}
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
#if HAVE_DLSYM && HAVE_DLFCN_H
|
||||
#include <dlfcn.h> // for dlopen et al
|
||||
#include "drivers/X11/Fl_X11_System_Driver.H"
|
||||
#endif
|
||||
#include <locale.h> // for setlocale
|
||||
|
||||
@ -159,10 +160,6 @@ static XX_g_slist_length fl_g_slist_length = NULL;
|
||||
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;
|
||||
@ -262,9 +259,9 @@ static XX_gtk_widget_show_now fl_gtk_widget_show_now = NULL;
|
||||
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;
|
||||
// Window gdk_x11_drawable_get_xid(GdkWindow *); or gdk_x11_window_get_xid
|
||||
typedef Window (*gdk_to_X11_t)(GdkWindow*);
|
||||
static gdk_to_X11_t fl_gdk_to_X11 = NULL;
|
||||
|
||||
// GtkWidget *gtk_check_button_new_with_label(const gchar *);
|
||||
typedef GtkWidget* (*XX_gtk_check_button_new_with_label)(const gchar *);
|
||||
@ -492,15 +489,8 @@ static void run_response_handler(GtkDialog *dialog, gint response_id, gpointer d
|
||||
int Fl_GTK_Native_File_Chooser_Driver::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;
|
||||
@ -611,7 +601,7 @@ int Fl_GTK_Native_File_Chooser_Driver::fl_gtk_chooser_wrapper()
|
||||
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
|
||||
Window xw = fl_gdk_to_X11(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);
|
||||
@ -701,57 +691,22 @@ 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 // HAVE_DLSYM && HAVE_DLFCN_H
|
||||
|
||||
/*
|
||||
/*
|
||||
* 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_Native_File_Chooser_Driver::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
|
||||
void *ptr_gtk;
|
||||
if ( !Fl_X11_System_Driver::probe_for_GTK(2, 4, &ptr_gtk)) {
|
||||
did_find_GTK_libs = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
void *ptr_glib = ptr_gtk;
|
||||
char *pc_dl_error; // used to report errors by the GET_SYM macro...
|
||||
// items we need from GLib
|
||||
GET_SYM(g_free, ptr_glib);
|
||||
@ -759,7 +714,6 @@ void Fl_GTK_Native_File_Chooser_Driver::probe_for_GTK_libs(void) {
|
||||
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);
|
||||
@ -784,7 +738,9 @@ void Fl_GTK_Native_File_Chooser_Driver::probe_for_GTK_libs(void) {
|
||||
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);
|
||||
fl_gdk_to_X11 = (gdk_to_X11_t)dlsym(ptr_gtk, "gdk_x11_drawable_get_xid");
|
||||
if (!fl_gdk_to_X11) fl_gdk_to_X11 = (gdk_to_X11_t)dlsym(ptr_gtk, "gdk_x11_window_get_xid");
|
||||
if (!fl_gdk_to_X11) { did_find_GTK_libs = 0; return; }
|
||||
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);
|
||||
|
@ -31,8 +31,188 @@ class Fl_Posix_Printer_Driver : public Fl_PostScript_File_Device {
|
||||
virtual int begin_job(int pagecount, int *frompage = NULL, int *topage = NULL);
|
||||
};
|
||||
|
||||
#if HAVE_DLSYM && HAVE_DLFCN_H
|
||||
// GTK types
|
||||
#include <dlfcn.h> // for dlopen et al
|
||||
#include <unistd.h> // for mkstemp
|
||||
#include <FL/filename.H>
|
||||
#include "../X11/Fl_X11_System_Driver.H"
|
||||
#define GTK_PAPER_NAME_LETTER "na_letter"
|
||||
#define GTK_RESPONSE_NONE 0
|
||||
#define GTK_RESPONSE_OK -5
|
||||
#define GTK_PRINT_PAGES_RANGES 2
|
||||
class Fl_GTK_Printer_Driver : public Fl_PostScript_File_Device {
|
||||
public:
|
||||
typedef int gboolean;
|
||||
typedef struct _GtkPrintUnixDialog GtkPrintUnixDialog;
|
||||
typedef struct _GtkDialog GtkDialog;
|
||||
typedef struct _GtkPrintSettings GtkPrintSettings;
|
||||
typedef struct _GtkPageSetup GtkPageSetup;
|
||||
enum GtkPageOrientation {GTK_PAGE_ORIENTATION_PORTRAIT, GTK_PAGE_ORIENTATION_LANDSCAPE};
|
||||
typedef struct _GtkPaperSize GtkPaperSize;
|
||||
typedef struct _GtkPrinter GtkPrinter;
|
||||
typedef struct _GtkPrintJob GtkPrintJob;
|
||||
typedef struct _GtkWidget GtkWidget;
|
||||
struct GError;
|
||||
|
||||
GtkPrintJob *pjob; // data shared between begin_job() and end_job()
|
||||
char tmpfilename[50]; // name of temporary PostScript file containing to-be-printed data
|
||||
virtual int begin_job(int pagecount, int *frompage = NULL, int *topage = NULL);
|
||||
virtual void end_job();
|
||||
static bool probe_for_GTK();
|
||||
static void *ptr_gtk; // points to the GTK dynamic lib or NULL
|
||||
|
||||
typedef GtkPrintUnixDialog* (*gtk_print_unix_dialog_new_t)(const char*, void*);
|
||||
typedef int (*gtk_dialog_run_t)(GtkDialog*);
|
||||
typedef GtkPrintSettings *(*gtk_print_unix_dialog_get_settings_t)(GtkPrintUnixDialog*);
|
||||
typedef void (*gtk_print_unix_dialog_set_settings_t)(GtkPrintUnixDialog*, GtkPrintSettings*);
|
||||
typedef GtkPageSetup *(*gtk_print_unix_dialog_get_page_setup_t)(GtkPrintUnixDialog*);
|
||||
typedef GtkPageOrientation (*gtk_page_setup_get_orientation_t)(GtkPageSetup*);
|
||||
typedef GtkPaperSize* (*gtk_page_setup_get_paper_size_t)(GtkPageSetup*);
|
||||
typedef const char * (*gtk_paper_size_get_name_t)(GtkPaperSize*);
|
||||
typedef GtkPrinter * (*gtk_print_unix_dialog_get_selected_printer_t)(GtkPrintUnixDialog*);
|
||||
typedef int (*gtk_printer_accepts_ps_t)(GtkPrinter*);
|
||||
typedef int (*gtk_printer_is_active_t)(GtkPrinter*);
|
||||
typedef GtkPrintJob *(*gtk_print_job_new_t)(const char *, GtkPrinter *, GtkPrintSettings *, GtkPageSetup *);
|
||||
typedef void (*gtk_widget_hide_t)(GtkWidget*);
|
||||
typedef void (*gtk_widget_destroy_t)(GtkWidget*);
|
||||
typedef gboolean (*gtk_events_pending_t)(void);
|
||||
typedef void (*gtk_main_iteration_t)(void);
|
||||
typedef int (*gtk_print_job_set_source_file_t)(GtkPrintJob *job, const char *filename, GError **error);
|
||||
typedef void (*gtk_print_job_send_t)(GtkPrintJob *, void* , gboolean* , void* );
|
||||
typedef void (*gtk_print_settings_set_t) (GtkPrintSettings *settings, const char *key, const char *value);
|
||||
typedef const char * (*gtk_print_settings_get_t) (GtkPrintSettings *settings, const char *key );
|
||||
typedef int (*gtk_print_settings_get_print_pages_t)(GtkPrintSettings*);
|
||||
struct GtkPageRange { int start, end; };
|
||||
typedef GtkPageRange* (*gtk_print_settings_get_page_ranges_t)(GtkPrintSettings*, int*);
|
||||
typedef void (*g_object_unref_t)(void* object);
|
||||
};
|
||||
|
||||
// the CALL_GTK macro produces the source code to call a GTK function given its name
|
||||
// or to get a pointer to this function :
|
||||
// CALL_GTK(gtk_my_function) produces ((gtk_my_function_t)dlsym(ptr_gtk, "gtk_my_function"))
|
||||
#define CALL_GTK(NAME) ((NAME##_t)dlsym(ptr_gtk, #NAME))
|
||||
|
||||
void *Fl_GTK_Printer_Driver::ptr_gtk = NULL;
|
||||
|
||||
// test wether GTK is available at run-time
|
||||
bool Fl_GTK_Printer_Driver::probe_for_GTK() {
|
||||
return Fl_X11_System_Driver::probe_for_GTK(2, 10, &ptr_gtk);
|
||||
}
|
||||
|
||||
|
||||
int Fl_GTK_Printer_Driver::begin_job(int pagecount, int *firstpage, int *lastpage) {
|
||||
enum Fl_Paged_Device::Page_Format format = Fl_Paged_Device::A4;
|
||||
enum Fl_Paged_Device::Page_Layout layout = Fl_Paged_Device::PORTRAIT ;
|
||||
|
||||
GtkPrintUnixDialog *pdialog = CALL_GTK(gtk_print_unix_dialog_new)(Fl_Printer::dialog_title, NULL); //2.10
|
||||
GtkPrintSettings *psettings = CALL_GTK(gtk_print_unix_dialog_get_settings)(pdialog); //2.10
|
||||
CALL_GTK(gtk_print_settings_set)(psettings, "output-file-format", "ps"); //2.10
|
||||
char line[FL_PATH_MAX + 20], cwd[FL_PATH_MAX];
|
||||
sprintf(line, "file://%s/FLTK.ps", fl_getcwd(cwd, FL_PATH_MAX));
|
||||
CALL_GTK(gtk_print_settings_set)(psettings, "output-uri", line); //2.10
|
||||
CALL_GTK(gtk_print_unix_dialog_set_settings)(pdialog, psettings); //2.10
|
||||
CALL_GTK(g_object_unref)(psettings);
|
||||
int response_id = CALL_GTK(gtk_dialog_run)((GtkDialog*)pdialog);
|
||||
if (response_id == GTK_RESPONSE_OK) {
|
||||
GtkPageSetup *psetup = CALL_GTK(gtk_print_unix_dialog_get_page_setup)(pdialog); //2.10
|
||||
GtkPageOrientation orient = CALL_GTK(gtk_page_setup_get_orientation)(psetup); //2.10
|
||||
if (orient == GTK_PAGE_ORIENTATION_LANDSCAPE) layout = Fl_Paged_Device::LANDSCAPE;
|
||||
GtkPaperSize* psize = CALL_GTK(gtk_page_setup_get_paper_size)(psetup); //2.10
|
||||
const char *pname = CALL_GTK(gtk_paper_size_get_name)(psize); //2.10
|
||||
if (strcmp(pname, GTK_PAPER_NAME_LETTER) == 0) format = Fl_Paged_Device::LETTER;
|
||||
GtkPrinter *gprinter = CALL_GTK(gtk_print_unix_dialog_get_selected_printer)(pdialog); //2.10
|
||||
psettings = CALL_GTK(gtk_print_unix_dialog_get_settings)(pdialog); //2.10
|
||||
const char* p = CALL_GTK(gtk_print_settings_get)(psettings, "output-uri"); //2.10
|
||||
bool printing_to_file = (p != NULL);
|
||||
if (printing_to_file) {
|
||||
p += 6; // skip "file://" prefix
|
||||
strcpy(line, p);
|
||||
int l = strlen(p);
|
||||
if (strcmp(p+l-4, "/.ps") == 0) {
|
||||
line[l-3] = 0;
|
||||
strcat(line, "FLTK.ps");
|
||||
}
|
||||
}
|
||||
if (firstpage && lastpage) {
|
||||
*firstpage = 1; *lastpage = pagecount;
|
||||
if (CALL_GTK(gtk_print_settings_get_print_pages)(psettings) == GTK_PRINT_PAGES_RANGES) { // 2.10
|
||||
int num_ranges;
|
||||
GtkPageRange *ranges = CALL_GTK(gtk_print_settings_get_page_ranges)(psettings, &num_ranges); //2.10
|
||||
if (num_ranges > 0) {
|
||||
*firstpage = ranges[0].start + 1;
|
||||
*lastpage = ranges[0].end + 1;
|
||||
free(ranges);
|
||||
}
|
||||
}
|
||||
}
|
||||
response_id = GTK_RESPONSE_NONE;
|
||||
if (printing_to_file) {
|
||||
pjob = NULL;
|
||||
FILE *output = fopen(line, "w");
|
||||
if (output) {
|
||||
Fl_PostScript_File_Device::begin_job(output, 0, format, layout);
|
||||
response_id = GTK_RESPONSE_OK;
|
||||
}
|
||||
} else if ( CALL_GTK(gtk_printer_accepts_ps)(gprinter) && //2.10
|
||||
CALL_GTK(gtk_printer_is_active)(gprinter) ) { // 2.10
|
||||
strcpy(tmpfilename, "/tmp/FLTKprintjobXXXXXX");
|
||||
int fd = mkstemp(tmpfilename);
|
||||
if (fd >= 0) {
|
||||
FILE *output = fdopen(fd, "w");
|
||||
Fl_PostScript_File_Device::begin_job(output, 0, format, layout);
|
||||
pjob = CALL_GTK(gtk_print_job_new)("FLTK print job", gprinter, psettings, psetup); //2.10
|
||||
response_id = GTK_RESPONSE_OK;
|
||||
}
|
||||
}
|
||||
CALL_GTK(g_object_unref)(psettings);
|
||||
}
|
||||
CALL_GTK(gtk_widget_hide)((GtkWidget*)pdialog);
|
||||
gtk_events_pending_t fl_gtk_events_pending = CALL_GTK(gtk_events_pending);
|
||||
gtk_main_iteration_t fl_gtk_main_iteration = CALL_GTK(gtk_main_iteration);
|
||||
while (fl_gtk_events_pending()) fl_gtk_main_iteration();
|
||||
CALL_GTK(gtk_widget_destroy)((GtkWidget*)pdialog);
|
||||
Fl_Window *first = Fl::first_window();
|
||||
if (first) {
|
||||
Fl_Surface_Device::push_current(Fl_Display_Device::display_device());
|
||||
first->show();
|
||||
while (Fl::ready()) Fl::check();
|
||||
Fl_Surface_Device::pop_current();
|
||||
}
|
||||
return (response_id == GTK_RESPONSE_OK ? 0 : 1);
|
||||
}
|
||||
|
||||
static void pJobCompleteFunc(Fl_GTK_Printer_Driver::GtkPrintJob *print_job, Fl_GTK_Printer_Driver::gboolean *user_data, const Fl_GTK_Printer_Driver::GError *error) {
|
||||
*user_data = true;
|
||||
}
|
||||
static void pDestroyNotify(void* data) {}
|
||||
|
||||
void Fl_GTK_Printer_Driver::end_job() {
|
||||
Fl_PostScript_File_Device::end_job();
|
||||
Fl_PostScript_Graphics_Driver *psgd = driver();
|
||||
fclose(psgd->output);
|
||||
if (!pjob) return;
|
||||
GError *gerr;
|
||||
gboolean gb = CALL_GTK(gtk_print_job_set_source_file)(pjob, tmpfilename, &gerr); //2.10
|
||||
if (gb) {
|
||||
gb = false;
|
||||
CALL_GTK(gtk_print_job_send)(pjob, (void*)pJobCompleteFunc, &gb, (void*)pDestroyNotify); //2.10
|
||||
gtk_main_iteration_t fl_gtk_main_iteration = CALL_GTK(gtk_main_iteration);
|
||||
while (!gb) {
|
||||
fl_gtk_main_iteration();
|
||||
}
|
||||
}
|
||||
fl_unlink(tmpfilename);
|
||||
}
|
||||
#endif // HAVE_DLSYM && HAVE_DLFCN_H
|
||||
|
||||
|
||||
Fl_Paged_Device* Fl_Printer::newPrinterDriver(void)
|
||||
{
|
||||
#if HAVE_DLSYM && HAVE_DLFCN_H
|
||||
static bool gtk = ( Fl::option(Fl::OPTION_PRINTER_USES_GTK) ? Fl_GTK_Printer_Driver::probe_for_GTK() : false);
|
||||
if (gtk) return new Fl_GTK_Printer_Driver();
|
||||
#endif
|
||||
return new Fl_Posix_Printer_Driver();
|
||||
}
|
||||
|
||||
|
@ -20,6 +20,7 @@
|
||||
#ifndef FL_X11_SYSTEM_DRIVER_H
|
||||
#define FL_X11_SYSTEM_DRIVER_H
|
||||
|
||||
#include "../../config_lib.h"
|
||||
#include "../Posix/Fl_Posix_System_Driver.H"
|
||||
|
||||
class Fl_X11_System_Driver : public Fl_Posix_System_Driver {
|
||||
@ -63,6 +64,9 @@ public:
|
||||
virtual void add_fd(int fd, Fl_FD_Handler cb, void* = 0);
|
||||
virtual void remove_fd(int, int when);
|
||||
virtual void remove_fd(int);
|
||||
#if HAVE_DLSYM && HAVE_DLFCN_H
|
||||
static bool probe_for_GTK(int major, int minor, void **ptr_gtk);
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif /* FL_X11_SYSTEM_DRIVER_H */
|
||||
|
@ -517,6 +517,63 @@ int Fl_X11_System_Driver::utf8locale() {
|
||||
return ret;
|
||||
}
|
||||
|
||||
#if HAVE_DLSYM && HAVE_DLFCN_H
|
||||
#include <dlfcn.h> // for dlopen et al
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
bool Fl_X11_System_Driver::probe_for_GTK(int major, int minor, void **ptr_gtk) {
|
||||
typedef void (*init_t)(int*, void*);
|
||||
*ptr_gtk = NULL;
|
||||
// was GTK previously loaded?
|
||||
init_t init_f = (init_t)dlsym(RTLD_DEFAULT, "gtk_init_check");
|
||||
if (init_f) { // yes it was.
|
||||
*ptr_gtk = RTLD_DEFAULT; // Caution: NULL under linux, not-NULL under Darwin
|
||||
} else {
|
||||
// Try first with GTK3
|
||||
*ptr_gtk = fl_dlopen("libgtk-3.so", "libgtk-3.so.0");
|
||||
if (*ptr_gtk) {
|
||||
#ifdef DEBUG
|
||||
puts("selected GTK-3\n");
|
||||
#endif
|
||||
} else {
|
||||
// Try then 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) {
|
||||
#ifdef DEBUG
|
||||
puts("selected GTK-2\n");
|
||||
#endif
|
||||
} else {
|
||||
#ifdef DEBUG
|
||||
puts("Failure to load libgtk");
|
||||
#endif
|
||||
return false;
|
||||
}
|
||||
init_f = (init_t)dlsym(*ptr_gtk, "gtk_init_check");
|
||||
if (!init_f) return false;
|
||||
}
|
||||
int ac = 0;
|
||||
init_f(&ac, NULL);
|
||||
// now check if running version is high enough
|
||||
if (dlsym(*ptr_gtk, "gtk_get_major_version") == NULL) { // YES indicates V 3
|
||||
typedef const char* (*check_t)(int, int, int);
|
||||
check_t check_f = (check_t)dlsym(*ptr_gtk, "gtk_check_version");
|
||||
if (!check_f || check_f(major, minor, 0) ) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif // HAVE_DLSYM && HAVE_DLFCN_H
|
||||
|
||||
#if !defined(FL_DOXYGEN)
|
||||
|
||||
const char *Fl_X11_System_Driver::shortcut_add_key_name(unsigned key, char *p, char *buf, const char **eom)
|
||||
|
Loading…
Reference in New Issue
Block a user