Create class Fl_Unix_Screen_Driver used by X11 and Wayland platforms

This commit is contained in:
ManoloFLTK 2022-11-07 06:49:40 +01:00
parent b663e272e7
commit 37bf3835b0
38 changed files with 659 additions and 489 deletions

View File

@ -202,7 +202,7 @@ if (FLTK_USE_X11 AND NOT OPTION_USE_WAYLAND)
drivers/X11/Fl_X11_Window_Driver.cxx
drivers/Posix/Fl_Posix_System_Driver.cxx
drivers/Unix/Fl_Unix_System_Driver.cxx
drivers/X11/Fl_X11_System_Driver.cxx
drivers/Unix/Fl_Unix_Screen_Driver.cxx
drivers/Xlib/Fl_Xlib_Copy_Surface_Driver.cxx
drivers/Xlib/Fl_Xlib_Image_Surface_Driver.cxx
drivers/X11/fl_X11_platform_init.cxx
@ -250,7 +250,6 @@ if (FLTK_USE_X11 AND NOT OPTION_USE_WAYLAND)
drivers/Posix/Fl_Posix_System_Driver.H
drivers/X11/Fl_X11_Screen_Driver.H
drivers/X11/Fl_X11_Window_Driver.H
drivers/X11/Fl_X11_System_Driver.H
drivers/Xlib/Fl_Xlib_Graphics_Driver.H
drivers/Xlib/Fl_Font.H
drivers/Xlib/Fl_Xlib_Copy_Surface_Driver.H
@ -273,9 +272,9 @@ elseif (OPTION_USE_WAYLAND)
set (DRIVER_FILES
drivers/Posix/Fl_Posix_System_Driver.cxx
drivers/Posix/Fl_Posix_Printer_Driver.cxx
drivers/Unix/Fl_Unix_Screen_Driver.cxx
drivers/Wayland/Fl_Wayland_Screen_Driver.cxx
drivers/Wayland/Fl_Wayland_Window_Driver.cxx
drivers/Wayland/Fl_Wayland_System_Driver.cxx
drivers/Unix/Fl_Unix_System_Driver.cxx
drivers/Wayland/Fl_Wayland_Graphics_Driver.cxx
drivers/Wayland/Fl_Wayland_Copy_Surface_Driver.cxx
@ -292,7 +291,6 @@ elseif (OPTION_USE_WAYLAND)
drivers/Cairo/Fl_Display_Cairo_Graphics_Driver.cxx
drivers/X11/Fl_X11_Screen_Driver.cxx
drivers/X11/Fl_X11_Window_Driver.cxx
drivers/X11/Fl_X11_System_Driver.cxx
drivers/Xlib/Fl_Xlib_Copy_Surface_Driver.cxx
drivers/Xlib/Fl_Xlib_Image_Surface_Driver.cxx
Fl_x.cxx
@ -302,7 +300,6 @@ elseif (OPTION_USE_WAYLAND)
endif (FLTK_USE_X11)
set (DRIVER_HEADER_FILES
drivers/Posix/Fl_Posix_System_Driver.H
drivers/Wayland/Fl_Wayland_System_Driver.H
drivers/Wayland/Fl_Wayland_Screen_Driver.H
drivers/Wayland/Fl_Wayland_Window_Driver.H
drivers/Wayland/Fl_Wayland_Graphics_Driver.H

View File

@ -2011,11 +2011,11 @@ int Fl::dnd()
}
int Fl::event_key(int k) {
return system_driver()->event_key(k);
return screen_driver()->event_key(k);
}
int Fl::get_key(int k) {
return system_driver()->get_key(k);
return screen_driver()->get_key(k);
}
void Fl::get_mouse(int &x, int &y) {

View File

@ -21,7 +21,7 @@
// Fl_Menu_ widget.
#include <FL/Fl.H>
#include "Fl_System_Driver.H"
#include "Fl_Screen_Driver.H"
#include "Fl_Window_Driver.H"
#include <FL/Fl_Menu_Window.H>
#include <FL/Fl_Menu_.H>
@ -696,11 +696,11 @@ int menuwindow::handle(int e) {
then STR #2619 does not occur. need_menu_handle_part1_extra() activates this fix.
FLTK 1.3.4 behavior:
Fl::system_driver()->need_menu_handle_part2() returns true on Mac + X11
Fl::system_driver()->need_menu_handle_part1_extra() returns true on X11
Fl::screen_driver()->need_menu_handle_part2() returns true on Mac + X11
Fl::screen_driver()->need_menu_handle_part1_extra() returns true on X11
Alternative behavior that seems equally correct:
Fl::system_driver()->need_menu_handle_part2() returns true on Mac
Fl::screen_driver()->need_menu_handle_part2() returns true on Mac
need_menu_handle_part1_extra() does not exist
Other alternative:
@ -710,7 +710,7 @@ int menuwindow::handle(int e) {
the menu disappears after the end of the resize rather than at its beginning.
Apple applications do close popups at the beginning of resizes.
*/
static int use_part2 = Fl::system_driver()->need_menu_handle_part2();
static int use_part2 = Fl::screen_driver()->need_menu_handle_part2();
int ret = handle_part1(e);
if (use_part2) ret = handle_part2(e, ret);
return ret;
@ -810,7 +810,7 @@ int menuwindow::handle_part1(int e) {
}
break;
case FL_MOVE: {
static int use_part1_extra = Fl::system_driver()->need_menu_handle_part1_extra();
static int use_part1_extra = Fl::screen_driver()->need_menu_handle_part1_extra();
if (use_part1_extra && pp.state == DONE_STATE) {
return 1; // Fix for STR #2619
}

View File

@ -28,7 +28,8 @@
#include <FL/fl_draw.H>
#include <FL/fl_string_functions.h>
#include <dlfcn.h> // for dlopen et al
#include "drivers/X11/Fl_X11_System_Driver.H"
#include "drivers/Unix/Fl_Unix_System_Driver.H"
#include "drivers/Unix/Fl_Unix_Screen_Driver.H"
#include "Fl_Window_Driver.H"
#include "Fl_Screen_Driver.H"
@ -774,7 +775,7 @@ int Fl_GTK_Native_File_Chooser_Driver::fl_gtk_chooser_wrapper()
Fl_Event_Dispatch old_dispatch = Fl::event_dispatch();
// prevent FLTK from processing any event
Fl::event_dispatch(fnfc_dispatch);
void *control = ((Fl_Unix_System_Driver*)Fl::system_driver())->control_maximize_button(NULL);
void *control = ((Fl_Unix_Screen_Driver*)Fl::screen_driver())->control_maximize_button(NULL);
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
@ -838,7 +839,7 @@ int Fl_GTK_Native_File_Chooser_Driver::fl_gtk_chooser_wrapper()
while (fl_gtk_events_pending ()) fl_gtk_main_iteration ();
Fl::event_dispatch(old_dispatch);
if (control) ((Fl_Unix_System_Driver*)Fl::system_driver())->control_maximize_button(control);
if (control) ((Fl_Unix_Screen_Driver*)Fl::screen_driver())->control_maximize_button(control);
return result;
} // fl_gtk_chooser_wrapper

View File

@ -18,7 +18,7 @@
#include <FL/Fl_Native_File_Chooser.H>
#include "Fl_Native_File_Chooser_Kdialog.H"
#include "Fl_Window_Driver.H"
#include "drivers/Unix/Fl_Unix_System_Driver.H"
#include "drivers/Unix/Fl_Unix_Screen_Driver.H"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@ -136,14 +136,14 @@ int Fl_Kdialog_Native_File_Chooser_Driver::show() {
Fl_Event_Dispatch old_dispatch = Fl::event_dispatch();
// prevent FLTK from processing any event
Fl::event_dispatch(fnfc_dispatch);
void *control = ((Fl_Unix_System_Driver*)Fl::system_driver())->control_maximize_button(NULL);
void *control = ((Fl_Unix_Screen_Driver*)Fl::screen_driver())->control_maximize_button(NULL);
// run event loop until pipe finishes
while (data.fd >= 0) Fl::wait();
Fl::remove_fd(fileno(pipe));
pclose(pipe);
// return to previous event processing by FLTK
Fl::event_dispatch(old_dispatch);
if (control) ((Fl_Unix_System_Driver*)Fl::system_driver())->control_maximize_button(control);
if (control) ((Fl_Unix_Screen_Driver*)Fl::screen_driver())->control_maximize_button(control);
if (data.all_files) {
// process text received from pipe
if (data.all_files[strlen(data.all_files)-1] == '\n') data.all_files[strlen(data.all_files)-1] = 0;

View File

@ -70,12 +70,40 @@ public:
static char bg2_set;
static char fg_set;
static Fl_System_Driver *system_driver;
// These flags are useful after calling XParseGeometry(). They indicate which of its
// arguments contain meaningful data upon return.
static const int fl_NoValue;
static const int fl_WidthValue;
static const int fl_HeightValue;
static const int fl_XValue;
static const int fl_YValue;
static const int fl_XNegative;
static const int fl_YNegative;
// key_table and key_table_size are used in fl_shortcut to translate key names
struct Keyname {
unsigned int key;
const char* name;
} *key_table;
int key_table_size;
virtual float scale(int) { return 1; }
virtual void scale(int /*n*/, float /*f*/) {}
static Fl_Screen_Driver *newScreenDriver();
// --- display management
virtual void display(const char *disp);
// implement to process the -display argument and support the DISPLAY env var
virtual void display(const char *) { }
// default implementation should be enough
virtual int XParseGeometry(const char* string, int* x, int* y, unsigned int* width, unsigned int* height);
// the default implementation is most probably enough
virtual void own_colormap() {}
// the default implementation of shortcut_add_key_name() is in src/fl_shortcut.cxx
virtual const char *shortcut_add_key_name(unsigned key, char *p, char *buf, const char **);
// whether a platform uses additional code in Fl_Menu::handle_part1(int e)
virtual int need_menu_handle_part1_extra() {return 0;}
// whether a platform uses additional code in Fl_Menu::handle(int e)
virtual int need_menu_handle_part2() {return 0;}
// implement functions telling whether a key is pressed
virtual int event_key(int) {return 0;}
virtual int get_key(int) {return 0;}
virtual int visual(int flags);
// --- screen configuration
virtual void init() {}

View File

@ -35,23 +35,71 @@ char Fl_Screen_Driver::bg_set = 0;
char Fl_Screen_Driver::bg2_set = 0;
char Fl_Screen_Driver::fg_set = 0;
Fl_System_Driver *Fl_Screen_Driver::system_driver = NULL;
const int Fl_Screen_Driver::fl_NoValue = 0x0000;
const int Fl_Screen_Driver::fl_WidthValue = 0x0004;
const int Fl_Screen_Driver::fl_HeightValue = 0x0008;
const int Fl_Screen_Driver::fl_XValue = 0x0001;
const int Fl_Screen_Driver::fl_YValue = 0x0002;
const int Fl_Screen_Driver::fl_XNegative = 0x0010;
const int Fl_Screen_Driver::fl_YNegative = 0x0020;
// This default key table is used for all system drivers that don't define
// and/or use their own table. It is defined here "static" and assigned
// in the constructor to avoid static initialization race conditions.
//
// As of January 2022, the Windows and Wayland platforms use this table.
// X11 does not use a key table at all; macOS has its own table.
// Platforms that use their own key tables must assign them in their
// constructors (which overwrites the pointer and size).
static Fl_Screen_Driver::Keyname default_key_table[] = {
{' ', "Space"},
{FL_BackSpace, "Backspace"},
{FL_Tab, "Tab"},
{0xff0b/*XK_Clear*/, "Clear"},
{FL_Enter, "Enter"}, // X says "Enter"
{FL_Pause, "Pause"},
{FL_Scroll_Lock, "Scroll_Lock"},
{FL_Escape, "Escape"},
{FL_Home, "Home"},
{FL_Left, "Left"},
{FL_Up, "Up"},
{FL_Right, "Right"},
{FL_Down, "Down"},
{FL_Page_Up, "Page_Up"}, // X says "Prior"
{FL_Page_Down, "Page_Down"}, // X says "Next"
{FL_End, "End"},
{FL_Print, "Print"},
{FL_Insert, "Insert"},
{FL_Menu, "Menu"},
{FL_Num_Lock, "Num_Lock"},
{FL_KP_Enter, "KP_Enter"},
{FL_Shift_L, "Shift_L"},
{FL_Shift_R, "Shift_R"},
{FL_Control_L, "Control_L"},
{FL_Control_R, "Control_R"},
{FL_Caps_Lock, "Caps_Lock"},
{FL_Meta_L, "Meta_L"},
{FL_Meta_R, "Meta_R"},
{FL_Alt_L, "Alt_L"},
{FL_Alt_R, "Alt_R"},
{FL_Delete, "Delete"}
};
int Fl_Screen_Driver::keyboard_screen_scaling = 1;
Fl_Screen_Driver::Fl_Screen_Driver() :
num_screens(-1), text_editor_extra_key_bindings(NULL)
{
// initialize default key table (used in fl_shortcut.cxx)
key_table = default_key_table;
key_table_size = sizeof(default_key_table)/sizeof(*default_key_table);
}
Fl_Screen_Driver::~Fl_Screen_Driver() {
}
void Fl_Screen_Driver::display(const char *) {
// blank
}
int Fl_Screen_Driver::visual(int) {
// blank
return 1;
@ -525,6 +573,142 @@ void Fl_Screen_Driver::set_status(int X, int Y, int W, int H) {}
/** see fl_reset_spot() */
void Fl_Screen_Driver::reset_spot() {}
/* the following function was stolen from the X sources as indicated. */
/* Copyright Massachusetts Institute of Technology 1985, 1986, 1987 */
/* $XConsortium: XParseGeom.c,v 11.18 91/02/21 17:23:05 rws Exp $ */
/*
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation, and that the name of M.I.T. not be used in advertising or
publicity pertaining to distribution of the software without specific,
written prior permission. M.I.T. makes no representations about the
suitability of this software for any purpose. It is provided "as is"
without express or implied warranty.
*/
/*
XParseGeometry parses strings of the form
"=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
width, height, xoffset, and yoffset are unsigned integers.
Example: "=80x24+300-49"
The equal sign is optional.
It returns a bitmask that indicates which of the four values
were actually found in the string. For each value found,
the corresponding argument is updated; for each value
not found, the corresponding argument is left unchanged.
*/
static int ReadInteger(char* string, char** NextString)
{
int Result = 0;
int Sign = 1;
if (*string == '+')
string++;
else if (*string == '-') {
string++;
Sign = -1;
}
for (; (*string >= '0') && (*string <= '9'); string++) {
Result = (Result * 10) + (*string - '0');
}
*NextString = string;
if (Sign >= 0)
return (Result);
else
return (-Result);
}
int Fl_Screen_Driver::XParseGeometry(const char* string, int* x, int* y,
unsigned int* width, unsigned int* height)
{
int mask = Fl_Screen_Driver::fl_NoValue;
char *strind;
unsigned int tempWidth = 0, tempHeight = 0;
int tempX = 0, tempY = 0;
char *nextCharacter;
if ( (string == NULL) || (*string == '\0')) return(mask);
if (*string == '=')
string++; /* ignore possible '=' at beg of geometry spec */
strind = (char *)string;
if (*strind != '+' && *strind != '-' && *strind != 'x') {
tempWidth = ReadInteger(strind, &nextCharacter);
if (strind == nextCharacter)
return (0);
strind = nextCharacter;
mask |= fl_WidthValue;
}
if (*strind == 'x' || *strind == 'X') {
strind++;
tempHeight = ReadInteger(strind, &nextCharacter);
if (strind == nextCharacter)
return (0);
strind = nextCharacter;
mask |= fl_HeightValue;
}
if ((*strind == '+') || (*strind == '-')) {
if (*strind == '-') {
strind++;
tempX = -ReadInteger(strind, &nextCharacter);
if (strind == nextCharacter)
return (0);
strind = nextCharacter;
mask |= fl_XNegative;
} else {
strind++;
tempX = ReadInteger(strind, &nextCharacter);
if (strind == nextCharacter)
return(0);
strind = nextCharacter;
}
mask |= fl_XValue;
if ((*strind == '+') || (*strind == '-')) {
if (*strind == '-') {
strind++;
tempY = -ReadInteger(strind, &nextCharacter);
if (strind == nextCharacter)
return(0);
strind = nextCharacter;
mask |= fl_YNegative;
} else {
strind++;
tempY = ReadInteger(strind, &nextCharacter);
if (strind == nextCharacter)
return(0);
strind = nextCharacter;
}
mask |= fl_YValue;
}
}
/* If strind isn't at the end of the string the it's an invalid
geometry specification. */
if (*strind != '\0') return (0);
if (mask & fl_XValue)
*x = tempX;
if (mask & fl_YValue)
*y = tempY;
if (mask & fl_WidthValue)
*width = tempWidth;
if (mask & fl_HeightValue)
*height = tempHeight;
return (mask);
}
/**
\}
\endcond

View File

@ -29,8 +29,6 @@
+ Fl_System_Driver
| + Fl_Posix_System_Driver
| | + Fl_Unix_System_Driver
| | | + Fl_X11_System_Driver
| | | + Fl_Wayland_System_Driver
| | + Fl_Darwin_System_Driver
| + Fl_WinAPI_System_Driver
*/
@ -61,29 +59,12 @@ class Fl_Sys_Menu_Bar_Driver;
*/
class Fl_System_Driver {
friend class Fl;
public:
struct Keyname {
unsigned int key;
const char* name;
};
protected:
// implement once for each platform
static Fl_System_Driver *newSystemDriver();
Fl_System_Driver();
// key_table and key_table_size are used in fl_shortcut to translate key names
Keyname *key_table;
int key_table_size;
public:
virtual ~Fl_System_Driver();
// These flags are useful after calling XParseGeometry(). They indicate which of its arguments
// contain meaningful data upon return.
static const int fl_NoValue;
static const int fl_WidthValue;
static const int fl_HeightValue;
static const int fl_XValue;
static const int fl_YValue;
static const int fl_XNegative;
static const int fl_YNegative;
static int command_key;
static int control_key;
@ -91,8 +72,6 @@ public:
virtual int single_arg(const char *) { return 0; }
// implement if the system adds unwanted program argument pair(s)
virtual int arg_and_value(const char * /*name*/, const char * /*value*/) { return 0; }
// default implementation should be enough
virtual int XParseGeometry(const char* string, int* x, int* y, unsigned int* width, unsigned int* height);
static void warning(const char* format, ...);
// implement to set the default effect of Fl::warning()
virtual void warning(const char* format, va_list args);
@ -140,9 +119,6 @@ public:
virtual int clocale_vprintf(FILE *output, const char *format, va_list args);
virtual int clocale_vsnprintf(char *output, size_t output_size, const char *format, va_list args);
virtual int clocale_vsscanf(const char *input, const char *format, va_list args);
// implement functions telling whether a key is pressed
virtual int event_key(int) {return 0;}
virtual int get_key(int) {return 0;}
// implement scandir-like function
virtual int filename_list(const char * /*d*/, dirent ***,
int (* /*sort*/)(struct dirent **, struct dirent **),
@ -166,18 +142,12 @@ public:
virtual const char *filename_ext(const char *buf);
// implement to support fl_filename_name()
virtual const char *filename_name(const char *buf) {return buf;}
// whether a platform uses additional code in Fl_Menu::handle(int e)
virtual int need_menu_handle_part2() {return 0;}
// whether a platform uses additional code in Fl_Menu::handle_part1(int e)
virtual int need_menu_handle_part1_extra() {return 0;}
// implement to support fl_open_uri()
virtual int open_uri(const char * /*uri*/, char * /*msg*/, int /*msglen*/) {return 0;}
// the default implementation of use_tooltip_timeout_condition() may be enough
virtual int use_tooltip_timeout_condition() {return 0;}
// the default implementation of use_recent_tooltip_fix() may be enough
virtual int use_recent_tooltip_fix() {return 0;}
// the default implementation of shortcut_add_key_name() is in src/fl_shortcut.cxx
virtual const char *shortcut_add_key_name(unsigned key, char *p, char *buf, const char **);
// the default implementation of need_test_shortcut_extra() may be enough
virtual int need_test_shortcut_extra() {return 0;}
// implement to support Fl_File_Browser::load()
@ -225,8 +195,6 @@ public:
// the implementations of local_to_mac_roman() and mac_roman_to_local() are in fl_encoding_mac_roman.cxx
virtual const char *local_to_mac_roman(const char *t, int n);
virtual const char *mac_roman_to_local(const char *t, int n);
// the default implementation is most probably enough
virtual void own_colormap() {}
// the default implementations of tree_openpixmap() and tree_closepixmap() are
// in Fl_Tree_Prefs.cxx and can be enough
virtual Fl_Pixmap *tree_openpixmap();

View File

@ -32,57 +32,6 @@
#include "flstring.h"
#include <time.h>
const int Fl_System_Driver::fl_NoValue = 0x0000;
const int Fl_System_Driver::fl_WidthValue = 0x0004;
const int Fl_System_Driver::fl_HeightValue = 0x0008;
const int Fl_System_Driver::fl_XValue = 0x0001;
const int Fl_System_Driver::fl_YValue = 0x0002;
const int Fl_System_Driver::fl_XNegative = 0x0010;
const int Fl_System_Driver::fl_YNegative = 0x0020;
// This default key table is used for all system drivers that don't define
// and/or use their own table. It is defined here "static" and assigned
// in the constructor to avoid static initialization race conditions.
//
// As of January 2022 the only platform is Windows. X11 does not
// use a key table at all.
// Platforms that use their own key tables must assign them in their
// constructors (which overwrites the pointer and size).
static Fl_System_Driver::Keyname default_key_table[] = {
{' ', "Space"},
{FL_BackSpace, "Backspace"},
{FL_Tab, "Tab"},
{0xff0b/*XK_Clear*/, "Clear"},
{FL_Enter, "Enter"}, // X says "Enter"
{FL_Pause, "Pause"},
{FL_Scroll_Lock, "Scroll_Lock"},
{FL_Escape, "Escape"},
{FL_Home, "Home"},
{FL_Left, "Left"},
{FL_Up, "Up"},
{FL_Right, "Right"},
{FL_Down, "Down"},
{FL_Page_Up, "Page_Up"}, // X says "Prior"
{FL_Page_Down, "Page_Down"}, // X says "Next"
{FL_End, "End"},
{FL_Print, "Print"},
{FL_Insert, "Insert"},
{FL_Menu, "Menu"},
{FL_Num_Lock, "Num_Lock"},
{FL_KP_Enter, "KP_Enter"},
{FL_Shift_L, "Shift_L"},
{FL_Shift_R, "Shift_R"},
{FL_Control_L, "Control_L"},
{FL_Control_R, "Control_R"},
{FL_Caps_Lock, "Caps_Lock"},
{FL_Meta_L, "Meta_L"},
{FL_Meta_R, "Meta_R"},
{FL_Alt_L, "Alt_L"},
{FL_Alt_R, "Alt_R"},
{FL_Delete, "Delete"}
};
int Fl_System_Driver::command_key = 0;
int Fl_System_Driver::control_key = 0;
@ -102,9 +51,6 @@ int fl_control_modifier() {
Fl_System_Driver::Fl_System_Driver()
{
// initialize default key table (used in fl_shortcut.cxx)
key_table = default_key_table;
key_table_size = sizeof(default_key_table)/sizeof(*default_key_table);
command_key = FL_CTRL;
control_key = FL_META;
}
@ -153,140 +99,6 @@ void Fl_System_Driver::fatal(const char *format, va_list args) {
exit(1);
}
/* the following function was stolen from the X sources as indicated. */
/* Copyright Massachusetts Institute of Technology 1985, 1986, 1987 */
/* $XConsortium: XParseGeom.c,v 11.18 91/02/21 17:23:05 rws Exp $ */
/*
Permission to use, copy, modify, distribute, and sell this software and its
documentation for any purpose is hereby granted without fee, provided that
the above copyright notice appear in all copies and that both that
copyright notice and this permission notice appear in supporting
documentation, and that the name of M.I.T. not be used in advertising or
publicity pertaining to distribution of the software without specific,
written prior permission. M.I.T. makes no representations about the
suitability of this software for any purpose. It is provided "as is"
without express or implied warranty.
*/
/*
XParseGeometry parses strings of the form
"=<width>x<height>{+-}<xoffset>{+-}<yoffset>", where
width, height, xoffset, and yoffset are unsigned integers.
Example: "=80x24+300-49"
The equal sign is optional.
It returns a bitmask that indicates which of the four values
were actually found in the string. For each value found,
the corresponding argument is updated; for each value
not found, the corresponding argument is left unchanged.
*/
static int ReadInteger(char* string, char** NextString)
{
int Result = 0;
int Sign = 1;
if (*string == '+')
string++;
else if (*string == '-') {
string++;
Sign = -1;
}
for (; (*string >= '0') && (*string <= '9'); string++) {
Result = (Result * 10) + (*string - '0');
}
*NextString = string;
if (Sign >= 0)
return (Result);
else
return (-Result);
}
int Fl_System_Driver::XParseGeometry(const char* string, int* x, int* y,
unsigned int* width, unsigned int* height)
{
int mask = Fl_System_Driver::fl_NoValue;
char *strind;
unsigned int tempWidth = 0, tempHeight = 0;
int tempX = 0, tempY = 0;
char *nextCharacter;
if ( (string == NULL) || (*string == '\0')) return(mask);
if (*string == '=')
string++; /* ignore possible '=' at beg of geometry spec */
strind = (char *)string;
if (*strind != '+' && *strind != '-' && *strind != 'x') {
tempWidth = ReadInteger(strind, &nextCharacter);
if (strind == nextCharacter)
return (0);
strind = nextCharacter;
mask |= fl_WidthValue;
}
if (*strind == 'x' || *strind == 'X') {
strind++;
tempHeight = ReadInteger(strind, &nextCharacter);
if (strind == nextCharacter)
return (0);
strind = nextCharacter;
mask |= fl_HeightValue;
}
if ((*strind == '+') || (*strind == '-')) {
if (*strind == '-') {
strind++;
tempX = -ReadInteger(strind, &nextCharacter);
if (strind == nextCharacter)
return (0);
strind = nextCharacter;
mask |= fl_XNegative;
} else {
strind++;
tempX = ReadInteger(strind, &nextCharacter);
if (strind == nextCharacter)
return(0);
strind = nextCharacter;
}
mask |= fl_XValue;
if ((*strind == '+') || (*strind == '-')) {
if (*strind == '-') {
strind++;
tempY = -ReadInteger(strind, &nextCharacter);
if (strind == nextCharacter)
return(0);
strind = nextCharacter;
mask |= fl_YNegative;
} else {
strind++;
tempY = ReadInteger(strind, &nextCharacter);
if (strind == nextCharacter)
return(0);
strind = nextCharacter;
}
mask |= fl_YValue;
}
}
/* If strind isn't at the end of the string the it's an invalid
geometry specification. */
if (*strind != '\0') return (0);
if (mask & fl_XValue)
*x = tempX;
if (mask & fl_YValue)
*y = tempY;
if (mask & fl_WidthValue)
*width = tempWidth;
if (mask & fl_HeightValue)
*height = tempHeight;
return (mask);
}
unsigned Fl_System_Driver::utf8towc(const char* src, unsigned srclen, wchar_t* dst, unsigned dstlen) {
const char* p = src;
const char* e = src+srclen;

View File

@ -165,7 +165,7 @@ int Fl::arg(int argc, char **argv, int &i) {
if (fl_match(s, "geometry")) {
int flags, gx, gy; unsigned int gw, gh;
flags = Fl::system_driver()->XParseGeometry(v, &gx, &gy, &gw, &gh);
flags = Fl::screen_driver()->XParseGeometry(v, &gx, &gy, &gw, &gh);
if (!flags) return 0;
geometry = v;
@ -281,16 +281,16 @@ void Fl_Window::show(int argc, char **argv) {
if (!beenhere) {
if (geometry) {
int fl = 0, gx = x(), gy = y(); unsigned int gw = w(), gh = h();
fl = Fl::system_driver()->XParseGeometry(geometry, &gx, &gy, &gw, &gh);
if (fl & Fl_System_Driver::fl_XNegative) gx = Fl::w()-w()+gx;
if (fl & Fl_System_Driver::fl_YNegative) gy = Fl::h()-h()+gy;
fl = Fl::screen_driver()->XParseGeometry(geometry, &gx, &gy, &gw, &gh);
if (fl & Fl_Screen_Driver::fl_XNegative) gx = Fl::w()-w()+gx;
if (fl & Fl_Screen_Driver::fl_YNegative) gy = Fl::h()-h()+gy;
// int mw,mh; minsize(mw,mh);
// if (mw > gw) gw = mw;
// if (mh > gh) gh = mh;
Fl_Widget *r = resizable();
if (!r) resizable(this);
// for Windows we assume window is not mapped yet:
if (fl & (Fl_System_Driver::fl_XValue | Fl_System_Driver::fl_YValue))
if (fl & (Fl_Screen_Driver::fl_XValue | Fl_Screen_Driver::fl_YValue))
x(-1), resize(gx,gy,gw,gh);
else
size(gw,gh);

View File

@ -22,12 +22,12 @@
// and looks it up in the X key bit vector, which Fl_x.cxx keeps track of.
#include <FL/Fl.H>
#include "drivers/X11/Fl_X11_System_Driver.H"
#include "drivers/X11/Fl_X11_Screen_Driver.H"
#include <FL/platform.H> // for fl_display
extern char fl_key_vector[32]; // in Fl_x.cxx
int Fl_X11_System_Driver::event_key(int k) {
int Fl_X11_Screen_Driver::event_key(int k) {
if (k > FL_Button && k <= FL_Button+8)
return Fl::event_state(8<<(k-FL_Button));
int i;
@ -43,7 +43,7 @@ int Fl_X11_System_Driver::event_key(int k) {
return fl_key_vector[i/8] & (1 << (i%8));
}
int Fl_X11_System_Driver::get_key(int k) {
int Fl_X11_Screen_Driver::get_key(int k) {
fl_open_display();
XQueryKeymap(fl_display, fl_key_vector);
return event_key(k);

View File

@ -21,6 +21,7 @@
#include <FL/Fl.H>
#include <FL/platform.H>
#include "drivers/Darwin/Fl_Darwin_System_Driver.H"
#include "drivers/Cocoa/Fl_Cocoa_Screen_Driver.H"
// The list of Mac OS virtual keycodes appears with OS 10.5 in
// ...../Carbon.framework/Frameworks/HIToolbox.framework/Headers/Events.h
@ -235,12 +236,12 @@ static int fltk2mac(int fltk) {
}
//: returns true, if that key was pressed during the last event
int Fl_Darwin_System_Driver::event_key(int k) {
int Fl_Cocoa_Screen_Driver::event_key(int k) {
return get_key(k);
}
//: returns true, if that key is pressed right now
int Fl_Darwin_System_Driver::get_key(int k) {
int Fl_Cocoa_Screen_Driver::get_key(int k) {
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
if (&CGEventSourceKeyState != NULL) {
return (int)CGEventSourceKeyState(kCGEventSourceStateCombinedSessionState, fltk2mac(k) );

View File

@ -18,7 +18,7 @@
// which are actually X keysyms. So this has to translate to Windows
// VK_x symbols.
#include "drivers/WinAPI//Fl_WinAPI_System_Driver.H"
#include "drivers/WinAPI/Fl_WinAPI_Screen_Driver.H"
#include <FL/platform.H>
// Convert an FLTK (X) keysym to a Windows VK symbol:
@ -113,11 +113,11 @@ static int fltk2ms(int fltk) {
return 0;
}
int Fl_WinAPI_System_Driver::event_key(int k) {
int Fl_WinAPI_Screen_Driver::event_key(int k) {
return GetKeyState(fltk2ms(k))&~1;
}
int Fl_WinAPI_System_Driver::get_key(int k) {
int Fl_WinAPI_Screen_Driver::get_key(int k) {
uchar foo[256];
GetKeyboardState(foo);
return foo[fltk2ms(k)]&~1;

View File

@ -23,7 +23,7 @@
// get huge color changes when switching windows.
#include <FL/Fl.H>
#include "Fl_System_Driver.H"
#include "Fl_Screen_Driver.H"
/** \fn Fl::own_colormap()
Makes FLTK use its <a href="fltk-colormap.png">own colormap</a>. This may make FLTK display better
@ -33,5 +33,5 @@
<P>This does nothing if the current visual is not colormapped.
*/
void Fl::own_colormap() {
Fl::system_driver()->own_colormap();
Fl::screen_driver()->own_colormap();
}

View File

@ -40,7 +40,7 @@
# include "flstring.h"
# include "drivers/X11/Fl_X11_Screen_Driver.H"
# include "drivers/X11/Fl_X11_Window_Driver.H"
# include "drivers/X11/Fl_X11_System_Driver.H"
# include "drivers/Unix/Fl_Unix_System_Driver.H"
#if FLTK_USE_CAIRO
# include "drivers/Cairo/Fl_Display_Cairo_Graphics_Driver.H"
#else
@ -129,19 +129,18 @@ static void do_queued_events() {
// This is never called with time_to_wait < 0.0:
// It should return negative on error, 0 if nothing happens before
// timeout, and >0 if any callbacks were done.
int Fl_X11_System_Driver::poll_or_select_with_delay(double time_to_wait) {
int Fl_X11_Screen_Driver::poll_or_select_with_delay(double time_to_wait) {
// OpenGL and other broken libraries call XEventsQueued
// unnecessarily and thus cause the file descriptor to not be ready,
// so we must check for already-read events:
if (fl_display && XQLength(fl_display)) {do_queued_events(); return 1;}
return Fl_Unix_System_Driver::poll_or_select_with_delay(time_to_wait);
return Fl_Unix_Screen_Driver::poll_or_select_with_delay(time_to_wait);
}
// just like Fl_X11_System_Driver::poll_or_select_with_delay(0.0) except no callbacks are done:
int Fl_X11_System_Driver::poll_or_select() {
// just like Fl_X11_Screen_Driver::poll_or_select_with_delay(0.0) except no callbacks are done:
int Fl_X11_Screen_Driver::poll_or_select() {
if (XQLength(fl_display)) return 1;
return Fl_Unix_System_Driver::poll_or_select();
return Fl_Unix_Screen_Driver::poll_or_select();
}
// replace \r\n by \n

View File

@ -270,7 +270,7 @@ XLIBCPPFILES = \
drivers/X11/Fl_X11_Screen_Driver.cxx \
drivers/Posix/Fl_Posix_System_Driver.cxx \
drivers/Unix/Fl_Unix_System_Driver.cxx \
drivers/X11/Fl_X11_System_Driver.cxx \
drivers/Unix/Fl_Unix_Screen_Driver.cxx \
drivers/Posix/Fl_Posix_Printer_Driver.cxx \
drivers/X11/fl_X11_platform_init.cxx \
Fl_x.cxx \
@ -302,7 +302,7 @@ WLCPPFILES = \
Fl_Native_File_Chooser_Kdialog.cxx \
drivers/Posix/Fl_Posix_System_Driver.cxx \
drivers/Unix/Fl_Unix_System_Driver.cxx \
drivers/Wayland/Fl_Wayland_System_Driver.cxx \
drivers/Unix/Fl_Unix_Screen_Driver.cxx \
drivers/Wayland/Fl_Wayland_Screen_Driver.cxx \
drivers/Wayland/Fl_Wayland_Window_Driver.cxx \
drivers/Wayland/Fl_Wayland_Image_Surface_Driver.cxx \
@ -315,7 +315,6 @@ WLCPPFILES = \
WLX11CPPFILES = \
drivers/X11/Fl_X11_Screen_Driver.cxx \
drivers/X11/Fl_X11_Window_Driver.cxx \
drivers/X11/Fl_X11_System_Driver.cxx \
drivers/Cairo/Fl_Display_Cairo_Graphics_Driver.cxx \
drivers/Xlib/Fl_Xlib_Copy_Surface_Driver.cxx \
drivers/Xlib/Fl_Xlib_Image_Surface_Driver.cxx \

View File

@ -102,6 +102,10 @@ public:
virtual int clipboard_contains(const char *type);
virtual void set_spot(int font, int size, int X, int Y, int W, int H, Fl_Window *win);
virtual void reset_spot();
virtual int need_menu_handle_part2() {return 1;}
// these 2 are in Fl_get_key_mac.cxx
virtual int event_key(int);
virtual int get_key(int);
private:
float scale_;
};

View File

@ -35,6 +35,47 @@ extern void (*fl_unlock_function)();
int Fl_Cocoa_Screen_Driver::next_marked_length = 0;
// This key table is used for the Darwin system driver. It is defined here
// "static" and assigned in the constructor to avoid static initialization
// race conditions. It is used in fl_shortcut.cxx.
//
// This table must be in numeric order by fltk (X) keysym number:
Fl_Screen_Driver::Keyname darwin_key_table[] = {
// v - this column may contain UTF-8 characters
{' ', "Space"},
{FL_BackSpace, ""/*"\xe2\x8c\xab"*/}, // U+232B : erase to the left
{FL_Tab, ""/*"\xe2\x87\xa5"*/}, // U+21E5 rightwards arrow to bar
{FL_Enter, ""/*"\xe2\x86\xa9"*/}, // U+21A9 leftwards arrow with hook
{FL_Pause, "Pause"},
{FL_Scroll_Lock, "Scroll_Lock"},
{FL_Escape, ""/*"\xe2\x8e\x8b"*/}, // U+238B : broken circle with northwest arrow
{FL_Home, ""/*"\xe2\x86\x96"*/}, // U+2196 north west arrow
{FL_Left, ""/*"\xe2\x86\x90"*/}, // U+2190 leftwards arrow
{FL_Up, ""/*"\xe2\x86\x91"*/}, // U+2191 upwards arrow
{FL_Right, ""/*"\xe2\x86\x92"*/}, // U+2192 rightwards arrow
{FL_Down, ""/*"\xe2\x86\x93"*/}, // U+2193 downwards arrow
{FL_Page_Up, ""/*"\xe2\x87\x9e"*/}, // U+21DE upwards arrow with double stroke
{FL_Page_Down, ""/*"\xe2\x87\x9f"*/}, // U+21DF downwards arrow with double stroke
{FL_End, ""/*"\xe2\x86\x98"*/}, // U+2198 south east arrow
{FL_Print, "Print"},
{FL_Insert, "Insert"},
{FL_Menu, "Menu"},
{FL_Num_Lock, "Num_Lock"},
{FL_KP_Enter, ""/*"\xe2\x8c\xa4"*/}, // U+2324 up arrow head between two horizontal bars
{FL_Shift_L, "Shift_L"},
{FL_Shift_R, "Shift_R"},
{FL_Control_L, "Control_L"},
{FL_Control_R, "Control_R"},
{FL_Caps_Lock, ""/*"\xe2\x87\xaa"*/}, // U+21EA upwards white arrow from bar
{FL_Meta_L, "Meta_L"},
{FL_Meta_R, "Meta_R"},
{FL_Alt_L, "Alt_L"},
{FL_Alt_R, "Alt_R"},
{FL_Delete, ""/*"\xe2\x8c\xa6"*/} // U+2326 : erase to the right
};
static Fl_Text_Editor::Key_Binding extra_bindings[] = {
// Define CMD+key accelerators...
{ 'z', FL_COMMAND, Fl_Text_Editor::kf_undo ,0},
@ -58,6 +99,9 @@ Fl_Cocoa_Screen_Driver::Fl_Cocoa_Screen_Driver() {
text_editor_extra_key_bindings = extra_bindings;
scale_ = 1.;
default_icon = nil;
// initialize key table
key_table = darwin_key_table;
key_table_size = sizeof(darwin_key_table)/sizeof(*darwin_key_table);
}

View File

@ -51,9 +51,6 @@ public:
static int calc_mac_os_version(); // computes the fl_mac_os_version global variable
static unsigned short *compute_macKeyLookUp();
// these 2 are in Fl_get_key_mac.cxx
virtual int event_key(int k);
virtual int get_key(int k);
virtual int filename_list(const char *d, dirent ***list,
int (*sort)(struct dirent **, struct dirent **),
char *errmsg=NULL, int errmsg_sz=0);

View File

@ -35,45 +35,6 @@
#include <sys/mount.h>
#include <sys/stat.h>
// This key table is used for the Darwin system driver. It is defined here
// "static" and assigned in the constructor to avoid static initialization
// race conditions. It is used in fl_shortcut.cxx.
//
// This table must be in numeric order by fltk (X) keysym number:
Fl_System_Driver::Keyname darwin_key_table[] = {
// v - this column may contain UTF-8 characters
{' ', "Space"},
{FL_BackSpace, ""/*"\xe2\x8c\xab"*/}, // U+232B : erase to the left
{FL_Tab, ""/*"\xe2\x87\xa5"*/}, // U+21E5 rightwards arrow to bar
{FL_Enter, ""/*"\xe2\x86\xa9"*/}, // U+21A9 leftwards arrow with hook
{FL_Pause, "Pause"},
{FL_Scroll_Lock, "Scroll_Lock"},
{FL_Escape, ""/*"\xe2\x8e\x8b"*/}, // U+238B : broken circle with northwest arrow
{FL_Home, ""/*"\xe2\x86\x96"*/}, // U+2196 north west arrow
{FL_Left, ""/*"\xe2\x86\x90"*/}, // U+2190 leftwards arrow
{FL_Up, ""/*"\xe2\x86\x91"*/}, // U+2191 upwards arrow
{FL_Right, ""/*"\xe2\x86\x92"*/}, // U+2192 rightwards arrow
{FL_Down, ""/*"\xe2\x86\x93"*/}, // U+2193 downwards arrow
{FL_Page_Up, ""/*"\xe2\x87\x9e"*/}, // U+21DE upwards arrow with double stroke
{FL_Page_Down, ""/*"\xe2\x87\x9f"*/}, // U+21DF downwards arrow with double stroke
{FL_End, ""/*"\xe2\x86\x98"*/}, // U+2198 south east arrow
{FL_Print, "Print"},
{FL_Insert, "Insert"},
{FL_Menu, "Menu"},
{FL_Num_Lock, "Num_Lock"},
{FL_KP_Enter, ""/*"\xe2\x8c\xa4"*/}, // U+2324 up arrow head between two horizontal bars
{FL_Shift_L, "Shift_L"},
{FL_Shift_R, "Shift_R"},
{FL_Control_L, "Control_L"},
{FL_Control_R, "Control_R"},
{FL_Caps_Lock, ""/*"\xe2\x87\xaa"*/}, // U+21EA upwards white arrow from bar
{FL_Meta_L, "Meta_L"},
{FL_Meta_R, "Meta_R"},
{FL_Alt_L, "Alt_L"},
{FL_Alt_R, "Alt_R"},
{FL_Delete, ""/*"\xe2\x8c\xa6"*/} // U+2326 : erase to the right
};
const char *Fl_Darwin_System_Driver::shift_name() {
return "\\"; // "\xe2\x87\xa7\\"; // U+21E7 (upwards white arrow)
@ -90,9 +51,6 @@ const char *Fl_Darwin_System_Driver::control_name() {
Fl_Darwin_System_Driver::Fl_Darwin_System_Driver() : Fl_Posix_System_Driver() {
if (fl_mac_os_version == 0) fl_mac_os_version = calc_mac_os_version();
// initialize key table
key_table = darwin_key_table;
key_table_size = sizeof(darwin_key_table)/sizeof(*darwin_key_table);
command_key = FL_META;
control_key = FL_CTRL;
}

View File

@ -23,6 +23,7 @@
Fl_GDI_Image_Surface_Driver::Fl_GDI_Image_Surface_Driver(int w, int h, int high_res, Fl_Offscreen off) : Fl_Image_Surface_Driver(w, h, high_res, off) {
Fl_Display_Device::display_device(); // make sure fl_graphics_driver was initialized
float d = fl_graphics_driver->scale();
if (!off && d != 1 && high_res) {
w = int(w*d);

View File

@ -35,7 +35,7 @@ class Fl_Posix_Printer_Driver : public Fl_PostScript_File_Device {
#include <dlfcn.h> // for dlopen et al
#include <unistd.h> // for mkstemp
#include <FL/filename.H>
#include "../X11/Fl_X11_System_Driver.H"
#include "../Unix/Fl_Unix_System_Driver.H"
#define GTK_PAPER_NAME_LETTER "na_letter"
#define GTK_RESPONSE_NONE 0
#define GTK_RESPONSE_OK -5

View File

@ -64,7 +64,6 @@ public:
virtual int rmdir(const char* f) {return ::rmdir(f);}
virtual int rename(const char* f, const char *n) {return ::rename(f, n);}
virtual const char *getpwnam(const char *login);
virtual int need_menu_handle_part2() {return 1;}
#if HAVE_DLFCN_H
virtual void *load(const char *filename);
#if HAVE_DLSYM

View File

@ -0,0 +1,61 @@
//
// Definition of the part of the screen driver shared by X11 and Wayland platforms
// for the Fast Light Tool Kit (FLTK).
//
// Copyright 2021-2022 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:
//
// https://www.fltk.org/COPYING.php
//
// Please see the following page on how to report bugs and issues:
//
// https://www.fltk.org/bugs.php
//
#ifndef FL_UNIX_SCREEN_DRIVER_H
#define FL_UNIX_SCREEN_DRIVER_H
#include "../../Fl_Screen_Driver.H"
# if USE_POLL
# include <poll.h>
static pollfd *pollfds = 0;
# else
# if HAVE_SYS_SELECT_H
# include <sys/select.h>
# endif /* HAVE_SYS_SELECT_H */
// The following #define is only needed for HP-UX 9.x and earlier:
//#define select(a,b,c,d,e) select((a),(int *)(b),(int *)(c),(int *)(d),(e))
# define POLLIN 1
# define POLLOUT 4
# define POLLERR 8
# endif /* USE_POLL */
class Fl_Unix_Screen_Driver : public Fl_Screen_Driver {
public:
static fd_set fdsets[3];
static int maxfd;
static int nfds;
static struct FD {
# if !USE_POLL
int fd;
short events;
# endif
void (*cb)(int, void*);
void* arg;
} *fd;
virtual int poll_or_select_with_delay(double time_to_wait);
virtual int poll_or_select();
virtual void *control_maximize_button(void *) { return NULL; }
};
#endif /* FL_UNIX_SCREEN_DRIVER_H */

View File

@ -0,0 +1,96 @@
//
// Definition of the part of the Screen interface shared by X11/Wayland
//
// Copyright 2022 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:
//
// https://www.fltk.org/COPYING.php
//
// Please see the following page on how to report bugs and issues:
//
// https://www.fltk.org/bugs.php
//
#include <config.h>
#include "Fl_Unix_Screen_Driver.H"
fd_set Fl_Unix_Screen_Driver::fdsets[3];
int Fl_Unix_Screen_Driver::maxfd = 0;
int Fl_Unix_Screen_Driver::nfds = 0;
Fl_Unix_Screen_Driver::FD *Fl_Unix_Screen_Driver::fd = NULL;
// these pointers are set by the Fl::lock() function:
static void nothing() {}
void (*fl_lock_function)() = nothing;
void (*fl_unlock_function)() = nothing;
// This is never called with time_to_wait < 0.0:
// It should return negative on error, 0 if nothing happens before
// timeout, and >0 if any callbacks were done.
int Fl_Unix_Screen_Driver::poll_or_select_with_delay(double time_to_wait) {
# if !USE_POLL
fd_set fdt[3];
fdt[0] = fdsets[0];
fdt[1] = fdsets[1];
fdt[2] = fdsets[2];
# endif
int n;
fl_unlock_function();
if (time_to_wait < 2147483.648) {
# if USE_POLL
n = ::poll(pollfds, nfds, int(time_to_wait*1000 + .5));
# else
timeval t;
t.tv_sec = int(time_to_wait);
t.tv_usec = int(1000000 * (time_to_wait-t.tv_sec));
n = ::select(maxfd+1,&fdt[0],&fdt[1],&fdt[2],&t);
# endif
} else {
# if USE_POLL
n = ::poll(pollfds, nfds, -1);
# else
n = ::select(maxfd+1,&fdt[0],&fdt[1],&fdt[2],0);
# endif
}
fl_lock_function();
if (n > 0) {
for (int i=0; i<nfds; i++) {
# if USE_POLL
if (pollfds[i].revents) fd[i].cb(pollfds[i].fd, fd[i].arg);
# else
int f = fd[i].fd;
short revents = 0;
if (FD_ISSET(f,&fdt[0])) revents |= POLLIN;
if (FD_ISSET(f,&fdt[1])) revents |= POLLOUT;
if (FD_ISSET(f,&fdt[2])) revents |= POLLERR;
if (fd[i].events & revents) fd[i].cb(f, fd[i].arg);
# endif
}
}
return n;
}
int Fl_Unix_Screen_Driver::poll_or_select() {
if (!nfds) return 0; // nothing to select or poll
# if USE_POLL
return ::poll(pollfds, nfds, 0);
# else
timeval t;
t.tv_sec = 0;
t.tv_usec = 0;
fd_set fdt[3];
fdt[0] = fdsets[0];
fdt[1] = fdsets[1];
fdt[2] = fdsets[2];
return ::select(maxfd+1,&fdt[0],&fdt[1],&fdt[2],&t);
# endif
}

View File

@ -44,10 +44,6 @@ public:
virtual void remove_fd(int);
double wait(double time_to_wait);
int ready();
// 3 additional virtual members
virtual int poll_or_select_with_delay(double time_to_wait);
virtual int poll_or_select();
virtual void *control_maximize_button(void *data);
static unsigned char *create_bmp(const unsigned char *data, int W, int H, int *return_size);
static Fl_RGB_Image *own_bmp_to_RGB(char *bmp);
static void read_int(uchar *c, int& i);

View File

@ -16,6 +16,7 @@
//
#include "Fl_Unix_System_Driver.H"
#include "Fl_Unix_Screen_Driver.H"
#include <FL/Fl_File_Browser.H>
#include <FL/fl_string_functions.h> // fl_strdup
#include <FL/platform.H>
@ -641,55 +642,22 @@ const char *Fl_Unix_System_Driver::filename_name(const char *name) {
}
////////////////////////////////////////////////////////////////
// interface to poll/select call:
# if USE_POLL
# include <poll.h>
static pollfd *pollfds = 0;
# else
# if HAVE_SYS_SELECT_H
# include <sys/select.h>
# endif /* HAVE_SYS_SELECT_H */
// The following #define is only needed for HP-UX 9.x and earlier:
//#define select(a,b,c,d,e) select((a),(int *)(b),(int *)(c),(int *)(d),(e))
static fd_set fdsets[3];
static int maxfd;
# define POLLIN 1
# define POLLOUT 4
# define POLLERR 8
# endif /* USE_POLL */
static int nfds = 0;
static int fd_array_size = 0;
struct FD {
# if !USE_POLL
int fd;
short events;
# endif
void (*cb)(int, void*);
void* arg;
};
static FD *fd = 0;
void Fl_Unix_System_Driver::add_fd(int n, int events, void (*cb)(int, void*), void *v) {
remove_fd(n,events);
int i = nfds++;
int i = Fl_Unix_Screen_Driver::nfds++;
if (i >= fd_array_size) {
FD *temp;
Fl_Unix_Screen_Driver::FD *temp;
fd_array_size = 2*fd_array_size+1;
if (!fd) temp = (FD*)malloc(fd_array_size*sizeof(FD));
else temp = (FD*)realloc(fd, fd_array_size*sizeof(FD));
if (!Fl_Unix_Screen_Driver::fd) temp =
(Fl_Unix_Screen_Driver::FD*)malloc(fd_array_size*sizeof(Fl_Unix_Screen_Driver::FD));
else temp = (Fl_Unix_Screen_Driver::FD*)realloc(Fl_Unix_Screen_Driver::fd,
fd_array_size*sizeof(Fl_Unix_Screen_Driver::FD));
if (!temp) return;
fd = temp;
Fl_Unix_Screen_Driver::fd = temp;
# if USE_POLL
pollfd *tpoll;
@ -701,18 +669,18 @@ void Fl_Unix_System_Driver::add_fd(int n, int events, void (*cb)(int, void*), vo
pollfds = tpoll;
# endif
}
fd[i].cb = cb;
fd[i].arg = v;
Fl_Unix_Screen_Driver::fd[i].cb = cb;
Fl_Unix_Screen_Driver::fd[i].arg = v;
# if USE_POLL
pollfds[i].fd = n;
pollfds[i].events = events;
# else
fd[i].fd = n;
fd[i].events = events;
if (events & POLLIN) FD_SET(n, &fdsets[0]);
if (events & POLLOUT) FD_SET(n, &fdsets[1]);
if (events & POLLERR) FD_SET(n, &fdsets[2]);
if (n > maxfd) maxfd = n;
Fl_Unix_Screen_Driver::fd[i].fd = n;
Fl_Unix_Screen_Driver::fd[i].events = events;
if (events & POLLIN) FD_SET(n, &Fl_Unix_Screen_Driver::fdsets[0]);
if (events & POLLOUT) FD_SET(n, &Fl_Unix_Screen_Driver::fdsets[1]);
if (events & POLLERR) FD_SET(n, &Fl_Unix_Screen_Driver::fdsets[2]);
if (n > Fl_Unix_Screen_Driver::maxfd) Fl_Unix_Screen_Driver::maxfd = n;
# endif
}
@ -723,9 +691,9 @@ void Fl_Unix_System_Driver::add_fd(int n, void (*cb)(int, void*), void* v) {
void Fl_Unix_System_Driver::remove_fd(int n, int events) {
int i,j;
# if !USE_POLL
maxfd = -1; // recalculate maxfd on the fly
Fl_Unix_Screen_Driver::maxfd = -1; // recalculate maxfd on the fly
# endif
for (i=j=0; i<nfds; i++) {
for (i=j=0; i<Fl_Unix_Screen_Driver::nfds; i++) {
# if USE_POLL
if (pollfds[i].fd == n) {
int e = pollfds[i].events & ~events;
@ -733,27 +701,27 @@ void Fl_Unix_System_Driver::remove_fd(int n, int events) {
pollfds[j].events = e;
}
# else
if (fd[i].fd == n) {
int e = fd[i].events & ~events;
if (Fl_Unix_Screen_Driver::fd[i].fd == n) {
int e = Fl_Unix_Screen_Driver::fd[i].events & ~events;
if (!e) continue; // if no events left, delete this fd
fd[i].events = e;
Fl_Unix_Screen_Driver::fd[i].events = e;
}
if (fd[i].fd > maxfd) maxfd = fd[i].fd;
if (Fl_Unix_Screen_Driver::fd[i].fd > Fl_Unix_Screen_Driver::maxfd) Fl_Unix_Screen_Driver::maxfd = Fl_Unix_Screen_Driver::fd[i].fd;
# endif
// move it down in the array if necessary:
if (j<i) {
fd[j] = fd[i];
Fl_Unix_Screen_Driver::fd[j] = Fl_Unix_Screen_Driver::fd[i];
# if USE_POLL
pollfds[j] = pollfds[i];
# endif
}
j++;
}
nfds = j;
Fl_Unix_Screen_Driver::nfds = j;
# if !USE_POLL
if (events & POLLIN) FD_CLR(n, &fdsets[0]);
if (events & POLLOUT) FD_CLR(n, &fdsets[1]);
if (events & POLLERR) FD_CLR(n, &fdsets[2]);
if (events & POLLIN) FD_CLR(n, &Fl_Unix_Screen_Driver::fdsets[0]);
if (events & POLLOUT) FD_CLR(n, &Fl_Unix_Screen_Driver::fdsets[1]);
if (events & POLLERR) FD_CLR(n, &Fl_Unix_Screen_Driver::fdsets[2]);
# endif
}
@ -762,85 +730,13 @@ void Fl_Unix_System_Driver::remove_fd(int n) {
}
// these pointers are set by the Fl::lock() function:
static void nothing() {}
void (*fl_lock_function)() = nothing;
void (*fl_unlock_function)() = nothing;
// This is never called with time_to_wait < 0.0:
// It should return negative on error, 0 if nothing happens before
// timeout, and >0 if any callbacks were done.
int Fl_Unix_System_Driver::poll_or_select_with_delay(double time_to_wait) {
# if !USE_POLL
fd_set fdt[3];
fdt[0] = fdsets[0];
fdt[1] = fdsets[1];
fdt[2] = fdsets[2];
# endif
int n;
fl_unlock_function();
if (time_to_wait < 2147483.648) {
# if USE_POLL
n = ::poll(pollfds, nfds, int(time_to_wait*1000 + .5));
# else
timeval t;
t.tv_sec = int(time_to_wait);
t.tv_usec = int(1000000 * (time_to_wait-t.tv_sec));
n = ::select(maxfd+1,&fdt[0],&fdt[1],&fdt[2],&t);
# endif
} else {
# if USE_POLL
n = ::poll(pollfds, nfds, -1);
# else
n = ::select(maxfd+1,&fdt[0],&fdt[1],&fdt[2],0);
# endif
}
fl_lock_function();
if (n > 0) {
for (int i=0; i<nfds; i++) {
# if USE_POLL
if (pollfds[i].revents) fd[i].cb(pollfds[i].fd, fd[i].arg);
# else
int f = fd[i].fd;
short revents = 0;
if (FD_ISSET(f,&fdt[0])) revents |= POLLIN;
if (FD_ISSET(f,&fdt[1])) revents |= POLLOUT;
if (FD_ISSET(f,&fdt[2])) revents |= POLLERR;
if (fd[i].events & revents) fd[i].cb(f, fd[i].arg);
# endif
}
}
return n;
}
int Fl_Unix_System_Driver::poll_or_select() {
if (!nfds) return 0; // nothing to select or poll
# if USE_POLL
return ::poll(pollfds, nfds, 0);
# else
timeval t;
t.tv_sec = 0;
t.tv_usec = 0;
fd_set fdt[3];
fdt[0] = fdsets[0];
fdt[1] = fdsets[1];
fdt[2] = fdsets[2];
return ::select(maxfd+1,&fdt[0],&fdt[1],&fdt[2],&t);
# endif
}
double Fl_Unix_System_Driver::wait(double time_to_wait)
{
Fl_Unix_Screen_Driver *scr_dr = (Fl_Unix_Screen_Driver*)Fl::screen_driver();
time_to_wait = Fl_System_Driver::wait(time_to_wait);
if (time_to_wait <= 0.0) {
// do flush second so that the results of events are visible:
int ret = this->poll_or_select_with_delay(0.0);
int ret = scr_dr->poll_or_select_with_delay(0.0);
Fl::flush();
return ret;
} else {
@ -852,15 +748,16 @@ double Fl_Unix_System_Driver::wait(double time_to_wait)
Fl_Timeout::elapse_timeouts();
time_to_wait = Fl_Timeout::time_to_wait(time_to_wait);
}
return this->poll_or_select_with_delay(time_to_wait);
return scr_dr->poll_or_select_with_delay(time_to_wait);
}
}
int Fl_Unix_System_Driver::ready()
{
Fl_Unix_Screen_Driver *scr_dr = (Fl_Unix_Screen_Driver*)Fl::screen_driver();
Fl_Timeout::elapse_timeouts();
if (Fl_Timeout::time_to_wait(1.0) <= 0.0) return 1;
return this->poll_or_select();
return scr_dr->poll_or_select();
}
@ -954,8 +851,3 @@ Fl_RGB_Image *Fl_Unix_System_Driver::own_bmp_to_RGB(char *bmp) {
img->alloc_array = 1;
return img;
}
void *Fl_Unix_System_Driver::control_maximize_button(void *data) {
return NULL;
}

View File

@ -23,7 +23,7 @@
#ifndef FL_WAYLAND_SCREEN_DRIVER_H
#define FL_WAYLAND_SCREEN_DRIVER_H
#include "../../Fl_Screen_Driver.H"
#include "../Unix/Fl_Unix_Screen_Driver.H"
#include <wayland-client.h>
class Fl_Window;
@ -54,7 +54,7 @@ struct seat {
struct zwp_text_input_v3 *text_input;
};
class Fl_Wayland_Screen_Driver : public Fl_Screen_Driver
class Fl_Wayland_Screen_Driver : public Fl_Unix_Screen_Driver
{
friend class Fl_Screen_Driver;
friend class Fl_Wayland_Graphics_Driver;
@ -176,6 +176,9 @@ public:
static compositor_name compositor; // identifies the used Wayland compositor
void set_spot(int font, int height, int x, int y, int w, int h, Fl_Window *win);
void reset_spot();
virtual void *control_maximize_button(void *data);
int event_key(int k);
int get_key(int k);
};

View File

@ -17,10 +17,7 @@
#include <config.h>
#include "Fl_Wayland_Screen_Driver.H"
#include "Fl_Wayland_Window_Driver.H"
#include "Fl_Wayland_System_Driver.H"
#if FLTK_USE_X11
# include "../X11/Fl_X11_System_Driver.H"
#endif
#include "../Unix/Fl_Unix_System_Driver.H"
#include "Fl_Wayland_Graphics_Driver.H"
#include <wayland-cursor.h>
#include "../../../libdecor/src/libdecor.h"
@ -1086,7 +1083,7 @@ static void fd_callback(int fd, struct wl_display *display) {
}
Fl_Wayland_Screen_Driver::Fl_Wayland_Screen_Driver() : Fl_Screen_Driver() {
Fl_Wayland_Screen_Driver::Fl_Wayland_Screen_Driver() : Fl_Unix_Screen_Driver() {
libdecor_context = NULL;
seat = NULL;
text_input_base = NULL;
@ -1478,6 +1475,73 @@ void Fl_Wayland_Screen_Driver::display(const char *d)
}
void *Fl_Wayland_Screen_Driver::control_maximize_button(void *data) {
// The code below aims at removing the calling window's fullscreen button
// while dialog runs. Unfortunately, it doesn't work with some X11 window managers
// (e.g., KDE, xfce) because the button goes away but doesn't come back,
// so we move this code to a virtual member function.
// Noticeably, this code works OK under Wayland.
struct win_dims {
Fl_Widget_Tracker *tracker;
int minw, minh, maxw, maxh;
struct win_dims *next;
};
if (!data) { // this call turns each decorated window's maximize button off
struct win_dims *first_dim = NULL;
// consider all bordered, top-level FLTK windows
Fl_Window *win = Fl::first_window();
while (win) {
if (!win->parent() && win->border() &&
!( ((struct wld_window*)Fl_X::i(win)->xid)->state & LIBDECOR_WINDOW_STATE_MAXIMIZED) ) {
win_dims *dim = new win_dims;
dim->tracker = new Fl_Widget_Tracker(win);
Fl_Window_Driver *dr = Fl_Window_Driver::driver(win);
dim->minw = dr->minw();
dim->minh = dr->minh();
dim->maxw = dr->maxw();
dim->maxh = dr->maxh();
//make win un-resizable
win->size_range(win->w(), win->h(), win->w(), win->h());
dim->next = first_dim;
first_dim = dim;
}
win = Fl::next_window(win);
}
return first_dim;
} else { // this call returns each decorated window's maximize button to its previous state
win_dims *first_dim = (win_dims *)data;
while (first_dim) {
win_dims *dim = first_dim;
//give back win its resizing parameters
if (dim->tracker->exists()) {
Fl_Window *win = (Fl_Window*)dim->tracker->widget();
win->size_range(dim->minw, dim->minh, dim->maxw, dim->maxh);
}
first_dim = dim->next;
delete dim->tracker;
delete dim;
}
return NULL;
}
}
int Fl_Wayland_Screen_Driver::event_key(int k) {
if (k > FL_Button && k <= FL_Button+8)
return Fl::event_state(8<<(k-FL_Button));
int sym = Fl::event_key();
if (sym >= 'a' && sym <= 'z' ) sym -= 32;
if (k >= 'a' && k <= 'z' ) k -= 32;
return (Fl::event() == FL_KEYDOWN || Fl::event() == FL_SHORTCUT) && sym == k;
}
int Fl_Wayland_Screen_Driver::get_key(int k) {
return event_key(k);
}
struct wl_display *fl_wl_display() {
if (!Fl_Wayland_Screen_Driver::wl_display || !Fl_Wayland_Screen_Driver::wl_registry) return NULL;
return Fl_Wayland_Screen_Driver::wl_display;

View File

@ -19,7 +19,7 @@
#include "Fl_Wayland_Window_Driver.H"
#include "Fl_Wayland_Screen_Driver.H"
#include "Fl_Wayland_Graphics_Driver.H"
#include "Fl_Wayland_System_Driver.H"
#include "../Unix/Fl_Unix_System_Driver.H"
#include <wayland-cursor.h>
#include "../../../libdecor/src/libdecor.h"
#include "xdg-shell-client-protocol.h"

View File

@ -27,7 +27,7 @@
# include "../../flstring.h"
# include "Fl_Wayland_Screen_Driver.H"
# include "Fl_Wayland_Window_Driver.H"
# include "Fl_Wayland_System_Driver.H"
# include "../Unix/Fl_Unix_System_Driver.H"
# include "Fl_Wayland_Graphics_Driver.H"
# include <errno.h>

View File

@ -14,11 +14,11 @@
// https://www.fltk.org/bugs.php
//
#include <config.h>
#include "Fl_Wayland_Copy_Surface_Driver.H"
#include "Fl_Wayland_Graphics_Driver.H"
#include "Fl_Wayland_Screen_Driver.H"
#include "Fl_Wayland_System_Driver.H"
#include "../Unix/Fl_Unix_System_Driver.H"
#include "Fl_Wayland_Window_Driver.H"
#include "Fl_Wayland_Image_Surface_Driver.H"
#if FLTK_USE_X11
@ -26,7 +26,6 @@
# include <cairo-xlib.h>
# include "../Cairo/Fl_Display_Cairo_Graphics_Driver.H"
# include "../X11/Fl_X11_Screen_Driver.H"
# include "../X11/Fl_X11_System_Driver.H"
# include "../X11/Fl_X11_Window_Driver.H"
# include "../Xlib/Fl_Xlib_Image_Surface_Driver.H"
#endif
@ -114,10 +113,7 @@ static bool attempt_wayland() {
Fl_System_Driver *Fl_System_Driver::newSystemDriver() {
#if FLTK_USE_X11
if (!attempt_wayland()) return new Fl_X11_System_Driver();
#endif
return new Fl_Wayland_System_Driver();
return new Fl_Unix_System_Driver();
}

View File

@ -94,6 +94,9 @@ public:
virtual void clipboard_notify_change();
// this one is implemented in Fl_win32.cxx
void set_spot(int font, int size, int X, int Y, int W, int H, Fl_Window *win);
// these two are implemented in Fl_get_key_win32.cxx
virtual int event_key(int);
virtual int get_key(int);
};

View File

@ -69,9 +69,6 @@ public:
virtual int clocale_vprintf(FILE *output, const char *format, va_list args);
virtual int clocale_vsnprintf(char *output, size_t output_size, const char *format, va_list args);
virtual int clocale_vsscanf(const char *input, const char *format, va_list args);
// these 2 are in Fl_get_key_win32.cxx
virtual int event_key(int k);
virtual int get_key(int k);
virtual int filename_list(const char *d, dirent ***list,
int (*sort)(struct dirent **, struct dirent **),
char *errmsg=NULL, int errmsg_sz=0);

View File

@ -24,14 +24,14 @@
#define FL_X11_SCREEN_DRIVER_H
#include <config.h>
#include "../../Fl_Screen_Driver.H"
#include "../Unix/Fl_Unix_Screen_Driver.H"
#include <X11/Xlib.h>
class Fl_Window;
class Fl_X11_Screen_Driver : public Fl_Screen_Driver
class Fl_X11_Screen_Driver : public Fl_Unix_Screen_Driver
{
friend class Fl_Screen_Driver;
protected:
@ -58,10 +58,21 @@ public:
int screen_num_unscaled(int x, int y);
#endif
Fl_X11_Screen_Driver();
static int ewmh_supported();
static void copy_image(const unsigned char* data, int W, int H, int destination);
// --- display management
virtual void display(const char *disp);
virtual int XParseGeometry(const char*, int*, int*, unsigned int*, unsigned int*);
virtual int poll_or_select_with_delay(double time_to_wait);
virtual int poll_or_select();
virtual void own_colormap();
virtual const char *shortcut_add_key_name(unsigned key, char *p, char *buf, const char **);
virtual int need_menu_handle_part1_extra() {return 1;}
virtual int need_menu_handle_part2() {return 1;}
// these 2 are in Fl_get_key.cxx
virtual int event_key(int);
virtual int get_key(int);
virtual int visual(int flags);
// --- screen configuration
void init_workarea();

View File

@ -18,7 +18,6 @@
#include <config.h>
#include "Fl_X11_Screen_Driver.H"
#include "Fl_X11_Window_Driver.H"
#include "Fl_X11_System_Driver.H"
#include "../Posix/Fl_Posix_System_Driver.H"
#include <FL/Fl.H>
#include <FL/platform.H>
@ -69,6 +68,11 @@ char Fl_X11_Screen_Driver::fl_is_over_the_spot = 0;
Window Fl_X11_Screen_Driver::xim_win = 0;
Fl_X11_Screen_Driver::Fl_X11_Screen_Driver() : Fl_Unix_Screen_Driver() {
// X11 screen driver does not use a key table
key_table = NULL;
key_table_size = 0;
}
void Fl_X11_Screen_Driver::display(const char *d)
{
@ -76,6 +80,60 @@ void Fl_X11_Screen_Driver::display(const char *d)
}
int Fl_X11_Screen_Driver::XParseGeometry(const char* string, int* x, int* y,
unsigned int* width, unsigned int* height) {
return ::XParseGeometry(string, x, y, width, height);
}
void Fl_X11_Screen_Driver::own_colormap() {
fl_open_display();
#if USE_COLORMAP
switch (fl_visual->c_class) {
case GrayScale :
case PseudoColor :
case DirectColor :
break;
default:
return; // don't do anything for non-colormapped visuals
}
int i;
XColor colors[16];
// Get the first 16 colors from the default colormap...
for (i = 0; i < 16; i ++) colors[i].pixel = i;
XQueryColors(fl_display, fl_colormap, colors, 16);
// Create a new colormap...
fl_colormap = XCreateColormap(fl_display,
RootWindow(fl_display,fl_screen),
fl_visual->visual, AllocNone);
// Copy those first 16 colors to our own colormap:
for (i = 0; i < 16; i ++)
XAllocColor(fl_display, fl_colormap, colors + i);
#endif // USE_COLORMAP
}
const char *Fl_X11_Screen_Driver::shortcut_add_key_name(unsigned key, char *p, char *buf, const char **eom)
{
const char* q;
if (key == FL_Enter || key == '\r') q = "Enter"; // don't use Xlib's "Return":
else if (key > 32 && key < 0x100) q = 0;
else q = XKeysymToString(key);
if (!q) {
p += fl_utf8encode(fl_toupper(key), p);
*p = 0;
return buf;
}
if (p > buf) {
strcpy(p,q);
return buf;
} else {
if (eom) *eom = q;
return q;
}
}
static int test_visual(XVisualInfo& v, int flags) {
if (v.screen != fl_screen) return 0;
#if USE_COLORMAP

View File

@ -23,7 +23,7 @@
# include "../Xlib/Fl_Xlib_Graphics_Driver.H"
#endif
#include "Fl_X11_Screen_Driver.H"
#include "Fl_X11_System_Driver.H"
#include "../Unix/Fl_Unix_System_Driver.H"
#include "Fl_X11_Window_Driver.H"
#include "../Xlib/Fl_Xlib_Image_Surface_Driver.H"
#include "../Xlib/Fl_Font.H"
@ -155,7 +155,7 @@ Fl_Screen_Driver *Fl_Screen_Driver::newScreenDriver()
Fl_System_Driver *Fl_System_Driver::newSystemDriver()
{
return new Fl_X11_System_Driver();
return new Fl_Unix_System_Driver();
}

View File

@ -35,6 +35,7 @@
#include <FL/Fl_Button.H>
#include <FL/Fl.H>
#include "Fl_System_Driver.H"
#include "Fl_Screen_Driver.H"
#include <FL/fl_draw.H>
#include <stdlib.h>
#include <ctype.h>
@ -198,7 +199,7 @@ const char* fl_shortcut_label(unsigned int shortcut, const char **eom) {
if (eom) *eom = p;
// add key name
return Fl::system_driver()->shortcut_add_key_name(key, p, buf, eom);
return Fl::screen_driver()->shortcut_add_key_name(key, p, buf, eom);
}
/**
@ -376,7 +377,7 @@ int Fl_Widget::test_shortcut() {
\{
*/
const char *Fl_System_Driver::shortcut_add_key_name(unsigned key, char *p, char *buf, const char **eom)
const char *Fl_Screen_Driver::shortcut_add_key_name(unsigned key, char *p, char *buf, const char **eom)
{
if (key >= FL_F && key <= FL_F_Last) {
*p++ = 'F';
@ -390,7 +391,7 @@ const char *Fl_System_Driver::shortcut_add_key_name(unsigned key, char *p, char
int c = (a+b)/2;
if (key_table[c].key == key) {
if (p > buf) {
strcpy(p,key_table[c].name);
strcpy(p, key_table[c].name);
return buf;
} else {
const char *sp = key_table[c].name;