From 64b3d26daa983b7a1394c82b080068cb1a056950 Mon Sep 17 00:00:00 2001 From: Manolo Gouy Date: Mon, 11 Apr 2016 19:14:47 +0000 Subject: [PATCH] Create Fl_X11_System_Driver.{cxx,.H} and share Fl_Posix_System_Driver.{cxx,.H} between Darwin and USE_X11 platforms. git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3-porting@11583 ea41ed52-d2ee-0310-a9c1-e6b18d33e121 --- FL/Fl_System_Driver.H | 2 +- src/CMakeLists.txt | 4 + src/Fl_get_key.cxx | 6 +- src/Fl_lock.cxx | 68 +-- src/Makefile | 2 + src/drivers/Darwin/Fl_Darwin_System_Driver.H | 31 +- .../Darwin/Fl_Darwin_System_Driver.cxx | 40 +- src/drivers/Posix/Fl_Posix_System_Driver.H | 21 +- src/drivers/Posix/Fl_Posix_System_Driver.cxx | 483 +---------------- src/drivers/X11/Fl_X11_System_Driver.H | 51 ++ src/drivers/X11/Fl_X11_System_Driver.cxx | 503 ++++++++++++++++++ src/fl_open_uri.cxx | 32 +- src/fl_shortcut.cxx | 4 +- 13 files changed, 598 insertions(+), 649 deletions(-) create mode 100644 src/drivers/X11/Fl_X11_System_Driver.H create mode 100644 src/drivers/X11/Fl_X11_System_Driver.cxx diff --git a/FL/Fl_System_Driver.H b/FL/Fl_System_Driver.H index f98e1c624..66e421f24 100644 --- a/FL/Fl_System_Driver.H +++ b/FL/Fl_System_Driver.H @@ -80,7 +80,7 @@ public: // implement these to support cross-platform file operations virtual char *utf2mbcs(const char *s) {return (char*)s;} virtual char *getenv(const char* v); - virtual int putenv(char* v) {return ::putenv(v);} + virtual int putenv(char* v) {return -1;} virtual int open(const char* f, int oflags, int pmode) {return -1;} virtual FILE *fopen(const char* f, const char *mode) {return NULL;} virtual int system(const char* cmd) {return -1;} diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 7039b6724..65649c596 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -172,6 +172,7 @@ if (USE_X11) drivers/Posix/Fl_Posix_Printer_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_Graphics_Driver.cxx drivers/Xlib/Fl_Xlib_Graphics_Driver_arci.cxx drivers/Xlib/Fl_Xlib_Graphics_Driver_color.cxx @@ -201,6 +202,7 @@ if (USE_X11) 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_Font.H ) @@ -251,10 +253,12 @@ elseif (APPLE) drivers/Quartz/Fl_Quartz_Image_Surface_Driver.cxx drivers/Cocoa/Fl_Cocoa_Window_Driver.cxx drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx + drivers/Posix/Fl_Posix_System_Driver.cxx drivers/Darwin/Fl_Darwin_System_Driver.cxx Fl_get_key_mac.cxx ) set (DRIVER_HEADER_FILES + drivers/Posix/Fl_Posix_System_Driver.H drivers/Darwin/Fl_Darwin_System_Driver.H drivers/Cocoa/Fl_Cocoa_Screen_Driver.H drivers/Cocoa/Fl_Cocoa_Window_Driver.H diff --git a/src/Fl_get_key.cxx b/src/Fl_get_key.cxx index 36f9bacfa..3d8acf79f 100644 --- a/src/Fl_get_key.cxx +++ b/src/Fl_get_key.cxx @@ -21,12 +21,12 @@ // and looks it up in the X key bit vector, which Fl_x.cxx keeps track of. #include -#include "drivers/Posix/Fl_Posix_System_Driver.H" +#include "drivers/X11/Fl_X11_System_Driver.H" #include // for fl_display extern char fl_key_vector[32]; // in Fl_x.cxx -int Fl_Posix_System_Driver::event_key(int k) { +int Fl_X11_System_Driver::event_key(int k) { if (k > FL_Button && k <= FL_Button+8) return Fl::event_state(8<<(k-FL_Button)); int i; @@ -42,7 +42,7 @@ int Fl_Posix_System_Driver::event_key(int k) { return fl_key_vector[i/8] & (1 << (i%8)); } -int Fl_Posix_System_Driver::get_key(int k) { +int Fl_X11_System_Driver::get_key(int k) { fl_open_display(); XQueryKeymap(fl_display, fl_key_vector); return event_key(k); diff --git a/src/Fl_lock.cxx b/src/Fl_lock.cxx index c80846d0c..5f1b79f41 100644 --- a/src/Fl_lock.cxx +++ b/src/Fl_lock.cxx @@ -21,9 +21,7 @@ #include -#if defined(FL_CFG_GFX_QUARTZ) -#include "drivers/Darwin/Fl_Darwin_System_Driver.H" -#elif defined(FL_CFG_GFX_XLIB) +#if defined(FL_CFG_SYS_POSIX) #include "drivers/Posix/Fl_Posix_System_Driver.H" #elif defined(FL_CFG_SYS_WIN32) #include "drivers/WinAPI/Fl_WinAPI_System_Driver.H" @@ -261,6 +259,9 @@ void Fl_WinAPI_System_Driver::awake(void* msg) { } #endif // FL_CFG_SYS_WIN32 + +#if defined(FL_CFG_SYS_POSIX) + //////////////////////////////////////////////////////////////// // POSIX threading... #if defined(HAVE_PTHREAD) @@ -314,12 +315,12 @@ static void unlock_function_rec() { } # endif // PTHREAD_MUTEX_RECURSIVE -static void posix_awake(void* msg) { +void Fl_Posix_System_Driver::awake(void* msg) { if (write(thread_filedes[1], &msg, sizeof(void*))==0) { /* ignore */ } } static void* thread_message_; -static void* posix_thread_message() { +void* Fl_Posix_System_Driver::thread_message() { void* r = thread_message_; thread_message_ = 0; return r; @@ -340,7 +341,7 @@ static void thread_awake_cb(int fd, void*) { extern void (*fl_lock_function)(); extern void (*fl_unlock_function)(); -static int posix_lock() { +int Fl_Posix_System_Driver::lock() { if (!thread_filedes[1]) { // Initialize thread communication pipe to let threads awake FLTK // from Fl::wait() @@ -378,7 +379,7 @@ static int posix_lock() { return 0; } -static void posix_unlock() { +void Fl_Posix_System_Driver::unlock() { fl_unlock_function(); } @@ -399,58 +400,15 @@ void lock_ring() { #else -#if defined(FL_CFG_GFX_QUARTZ) || defined(FL_CFG_GFX_XLIB) -static void posix_awake(void*) {} -static int posix_lock() { return 1; } -static void posix_unlock() {} -static void* posix_thread_message() { return NULL; } -#endif +static void Fl_Posix_System_Driver::awake(void*) {} +static int Fl_Posix_System_Driver::lock() { return 1; } +static void Fl_Posix_System_Driver::unlock() {} +static void* Fl_Posix_System_Driver::thread_message() { return NULL; } #endif // HAVE_PTHREAD -#if defined(FL_CFG_GFX_QUARTZ) -void Fl_Darwin_System_Driver::awake(void *v) -{ - posix_awake(v); -} -int Fl_Darwin_System_Driver::lock() -{ - return posix_lock(); -} - -void Fl_Darwin_System_Driver::unlock() -{ - posix_unlock(); -} - -void* Fl_Darwin_System_Driver::thread_message() -{ - return posix_thread_message(); -} -#endif // FL_CFG_GFX_QUARTZ - -#if defined(FL_CFG_GFX_XLIB) -void Fl_Posix_System_Driver::awake(void *v) -{ - posix_awake(v); -} - -int Fl_Posix_System_Driver::lock() -{ - return posix_lock(); -} - -void Fl_Posix_System_Driver::unlock() -{ - posix_unlock(); -} - -void* Fl_Posix_System_Driver::thread_message() -{ - return posix_thread_message(); -} -#endif // FL_CFG_GFX_XLIB +#endif // FL_CFG_SYS_POSIX void Fl::awake(void *v) { diff --git a/src/Makefile b/src/Makefile index 98c8b3fea..5684a85aa 100644 --- a/src/Makefile +++ b/src/Makefile @@ -230,6 +230,7 @@ QUARTZCPPFILES = \ drivers/Quartz/Fl_Quartz_Image_Surface_Driver.cxx \ drivers/Cocoa/Fl_Cocoa_Window_Driver.cxx \ drivers/Cocoa/Fl_Cocoa_Screen_Driver.cxx \ + drivers/Posix/Fl_Posix_System_Driver.cxx \ drivers/Darwin/Fl_Darwin_System_Driver.cxx \ Fl_get_key_mac.cxx @@ -248,6 +249,7 @@ XLIBCPPFILES = \ drivers/X11/Fl_X11_Window_Driver.cxx \ drivers/X11/Fl_X11_Screen_Driver.cxx \ drivers/Posix/Fl_Posix_System_Driver.cxx \ + drivers/X11/Fl_X11_System_Driver.cxx \ drivers/Posix/Fl_Posix_Printer_Driver.cxx \ Fl_x.cxx \ fl_dnd_x.cxx \ diff --git a/src/drivers/Darwin/Fl_Darwin_System_Driver.H b/src/drivers/Darwin/Fl_Darwin_System_Driver.H index d51fdeedf..ac08fd8f4 100644 --- a/src/drivers/Darwin/Fl_Darwin_System_Driver.H +++ b/src/drivers/Darwin/Fl_Darwin_System_Driver.H @@ -25,11 +25,9 @@ #ifndef FL_DARWIN_SYSTEM_DRIVER_H #define FL_DARWIN_SYSTEM_DRIVER_H -#include +#include "../Posix/Fl_Posix_System_Driver.H" #include #include -#include -#include /* Move everything here that manages the system interface. @@ -42,28 +40,12 @@ - multithreading */ -class Fl_Darwin_System_Driver : public Fl_System_Driver +class Fl_Darwin_System_Driver : public Fl_Posix_System_Driver { -private: - int run_program(const char *program, char **argv, char *msg, int msglen); public: Fl_Darwin_System_Driver(); virtual int single_arg(const char *arg); virtual int arg_and_value(const char *name, const char *value); - virtual int mkdir(const char* f, int mode) {return ::mkdir(f, mode);} - virtual int open(const char* f, int oflags, int pmode) { - return pmode == -1 ? ::open(f, oflags) : ::open(f, oflags, pmode); - } - virtual FILE *fopen(const char* f, const char *mode) {return ::fopen(f, mode);} - virtual int system(const char* cmd) {return ::system(cmd);} - virtual int execvp(const char *file, char *const *argv) {return ::execvp(file, argv);} - virtual int chmod(const char* f, int mode) {return ::chmod(f, mode);} - virtual int access(const char* f, int mode) { return ::access(f, mode);} - virtual int stat(const char* f, struct stat *b) { return ::stat(f, b);} - virtual char *getcwd(char* b, int l) {return ::getcwd(b, l);} - virtual int unlink(const char* f) {return ::unlink(f);} - virtual int rmdir(const char* f) {return ::rmdir(f);} - virtual int rename(const char* f, const char *n) {return ::rename(f, n);} virtual int clocale_printf(FILE *output, const char *format, va_list args); static void *get_carbon_function(const char *name); static int calc_mac_os_version(); // computes the fl_mac_os_version global variable @@ -71,21 +53,12 @@ public: 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 **) ); - virtual const char *getpwnam(const char *login); - virtual int need_menu_handle_part2() {return 1;} virtual int open_uri(const char *uri, char *msg, int msglen); virtual int need_test_shortcut_extra() {return 1;} virtual int file_browser_load_filesystem(Fl_File_Browser *browser, char *filename, Fl_File_Icon *icon); virtual void newUUID(char *uuidBuffer); virtual char *preference_rootnode(Fl_Preferences *prefs, Fl_Preferences::Root root, const char *vendor, const char *application); - virtual void *dlopen(const char *filename); - // these 4 are implemented in Fl_lock.cxx - virtual void awake(void*); - virtual int lock(); - virtual void unlock(); - virtual void* thread_message(); - virtual int file_type(const char *filename); }; #endif // FL_DARWIN_SYSTEM_DRIVER_H diff --git a/src/drivers/Darwin/Fl_Darwin_System_Driver.cxx b/src/drivers/Darwin/Fl_Darwin_System_Driver.cxx index e8082fbc6..806157103 100644 --- a/src/drivers/Darwin/Fl_Darwin_System_Driver.cxx +++ b/src/drivers/Darwin/Fl_Darwin_System_Driver.cxx @@ -61,7 +61,7 @@ Fl_System_Driver *Fl_System_Driver::newSystemDriver() return new Fl_Darwin_System_Driver(); } -Fl_Darwin_System_Driver::Fl_Darwin_System_Driver() { +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(); } @@ -146,12 +146,6 @@ int Fl_Darwin_System_Driver::filename_list(const char *d, dirent ***list, int (* } -const char *Fl_Darwin_System_Driver::getpwnam(const char *login) { - struct passwd *pwd; - pwd = ::getpwnam(login); - return pwd ? pwd->pw_dir : NULL; -} - int Fl_Darwin_System_Driver::open_uri(const char *uri, char *msg, int msglen) { char *argv[3]; // Command-line arguments @@ -226,38 +220,6 @@ char *Fl_Darwin_System_Driver::preference_rootnode(Fl_Preferences *prefs, Fl_Pre return filename; } -void *Fl_Darwin_System_Driver::dlopen(const char *filename) { - return ::dlopen(filename, RTLD_LAZY); -} - -int Fl_Darwin_System_Driver::file_type(const char *filename) -{ - int filetype; - struct stat fileinfo; // Information on file - if (!::stat(filename, &fileinfo)) - { - if (S_ISDIR(fileinfo.st_mode)) - filetype = Fl_File_Icon::DIRECTORY; -# ifdef S_ISFIFO - else if (S_ISFIFO(fileinfo.st_mode)) - filetype = Fl_File_Icon::FIFO; -# endif // S_ISFIFO -# if defined(S_ISCHR) && defined(S_ISBLK) - else if (S_ISCHR(fileinfo.st_mode) || S_ISBLK(fileinfo.st_mode)) - filetype = Fl_File_Icon::DEVICE; -# endif // S_ISCHR && S_ISBLK -# ifdef S_ISLNK - else if (S_ISLNK(fileinfo.st_mode)) - filetype = Fl_File_Icon::LINK; -# endif // S_ISLNK - else - filetype = Fl_File_Icon::PLAIN; - } - else - filetype = Fl_File_Icon::PLAIN; - return filetype; -} - // // End of "$Id$". // diff --git a/src/drivers/Posix/Fl_Posix_System_Driver.H b/src/drivers/Posix/Fl_Posix_System_Driver.H index 20c1e40a2..ad41d5f83 100644 --- a/src/drivers/Posix/Fl_Posix_System_Driver.H +++ b/src/drivers/Posix/Fl_Posix_System_Driver.H @@ -44,15 +44,15 @@ class Fl_Posix_System_Driver : public Fl_System_Driver { -private: +protected: int run_program(const char *program, char **argv, char *msg, int msglen); public: - virtual void display_arg(const char *arg); - virtual int XParseGeometry(const char*, int*, int*, unsigned int*, unsigned int*); + Fl_Posix_System_Driver() {} virtual int mkdir(const char* f, int mode) {return ::mkdir(f, mode);} virtual int open(const char* f, int oflags, int pmode) { return pmode == -1 ? ::open(f, oflags) : ::open(f, oflags, pmode); } + virtual int putenv(char* v) {return ::putenv(v);} virtual FILE *fopen(const char* f, const char *mode) {return ::fopen(f, mode);} virtual int system(const char* cmd) {return ::system(cmd);} virtual int execvp(const char *file, char *const *argv) {return ::execvp(file, argv);} @@ -63,23 +63,8 @@ public: virtual int unlink(const char* f) {return ::unlink(f);} virtual int rmdir(const char* f) {return ::rmdir(f);} virtual int rename(const char* f, const char *n) {return ::rename(f, n);} - virtual int clocale_printf(FILE *output, const char *format, va_list args); - // these 2 are in Fl_get_key.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 **) ); virtual const char *getpwnam(const char *login); virtual int need_menu_handle_part2() {return 1;} - virtual int need_menu_handle_part1_extra() {return 1;} - virtual int open_uri(const char *uri, char *msg, int msglen); - virtual int use_tooltip_timeout_condition() {return 1;} - // this one is in fl_shortcut.cxx - virtual const char *shortcut_add_key_name(unsigned key, char *p, char *buf, const char **); - virtual int file_browser_load_filesystem(Fl_File_Browser *browser, char *filename, Fl_File_Icon *icon); - virtual void newUUID(char *uuidBuffer); - virtual char *preference_rootnode(Fl_Preferences *prefs, Fl_Preferences::Root root, const char *vendor, - const char *application); - virtual int preferences_need_protection_check() {return 1;} virtual void *dlopen(const char *filename); // these 4 are implemented in Fl_lock.cxx virtual void awake(void*); diff --git a/src/drivers/Posix/Fl_Posix_System_Driver.cxx b/src/drivers/Posix/Fl_Posix_System_Driver.cxx index b9c171bc9..9fb0fc5cd 100644 --- a/src/drivers/Posix/Fl_Posix_System_Driver.cxx +++ b/src/drivers/Posix/Fl_Posix_System_Driver.cxx @@ -23,7 +23,6 @@ #include #include #include -#include #include #include #if HAVE_DLFCN_H @@ -35,32 +34,6 @@ #include #include -#if defined(_AIX) -extern "C" { -# include -# include -# include - // Older AIX versions don't expose this prototype - int mntctl(int, int, char *); -} -#endif // _AIX - -#if defined(__NetBSD__) -extern "C" { -# include // For '__NetBSD_Version__' definition -# if defined(__NetBSD_Version__) && (__NetBSD_Version__ >= 300000000) -# include -# include -# if defined(HAVE_PTHREAD) && defined(HAVE_PTHREAD_H) -# include -# 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__ - // // Define missing POSIX/XPG4 macros as needed... // @@ -72,458 +45,8 @@ extern "C" { # define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK) #endif /* !S_ISDIR */ -// Pointers you can use to change FLTK to another language. -// Note: Similar pointers are defined in FL/fl_ask.H and src/fl_ask.cxx -const char* fl_local_alt = "Alt"; -const char* fl_local_ctrl = "Ctrl"; -const char* fl_local_meta = "Meta"; -const char* fl_local_shift = "Shift"; - -#ifndef HAVE_SCANDIR -extern "C" { - int fl_scandir(const char *dirname, struct dirent ***namelist, - int (*select)(struct dirent *), - int (*compar)(struct dirent **, struct dirent **)); -} -#endif - -/** - Creates a driver that manages all screen and display related calls. - - This function must be implemented once for every platform. - */ -Fl_System_Driver *Fl_System_Driver::newSystemDriver() -{ - return new Fl_Posix_System_Driver(); -} - -void Fl_Posix_System_Driver::display_arg(const char *arg) { - Fl::display(arg); -} - -int Fl_Posix_System_Driver::XParseGeometry(const char* string, int* x, int* y, - unsigned int* width, unsigned int* height) { - return ::XParseGeometry(string, x, y, width, height); -} - -int Fl_Posix_System_Driver::clocale_printf(FILE *output, const char *format, va_list args) { - char *saved_locale = setlocale(LC_NUMERIC, NULL); - setlocale(LC_NUMERIC, "C"); - int retval = vfprintf(output, format, args); - setlocale(LC_NUMERIC, saved_locale); - return retval; -} - -int Fl_Posix_System_Driver::filename_list(const char *d, dirent ***list, int (*sort)(struct dirent **, struct dirent **) ) { - int dirlen; - char *dirloc; - - // Assume that locale encoding is no less dense than UTF-8 - dirlen = strlen(d); - dirloc = (char *)malloc(dirlen + 1); - fl_utf8to_mb(d, dirlen, dirloc, dirlen + 1); - -#ifndef HAVE_SCANDIR - // This version is when we define our own scandir - int n = fl_scandir(dirloc, list, 0, sort); -#elif defined(HAVE_SCANDIR_POSIX) - // POSIX (2008) defines the comparison function like this: - int n = scandir(dirloc, list, 0, (int(*)(const dirent **, const dirent **))sort); -#elif defined(__osf__) - // OSF, DU 4.0x - int n = scandir(dirloc, list, 0, (int(*)(dirent **, dirent **))sort); -#elif defined(_AIX) - // AIX is almost standard... - int n = scandir(dirloc, list, 0, (int(*)(void*, void*))sort); -#elif defined(__sgi) - int n = scandir(dirloc, list, 0, sort); -#else - // The vast majority of UNIX systems want the sort function to have this - // prototype, most likely so that it can be passed to qsort without any - // changes: - int n = scandir(dirloc, list, 0, (int(*)(const void*,const void*))sort); -#endif - - free(dirloc); - - // convert every filename to UTF-8, and append a '/' to all - // filenames that are directories - int i; - char *fullname = (char*)malloc(dirlen+FL_PATH_MAX+3); // Add enough extra for two /'s and a nul - // Use memcpy for speed since we already know the length of the string... - memcpy(fullname, d, dirlen+1); - - char *name = fullname + dirlen; - if (name!=fullname && name[-1]!='/') - *name++ = '/'; - - for (i=0; id_name); - newlen = fl_utf8from_mb(NULL, 0, de->d_name, len); - dirent *newde = (dirent*)malloc(de->d_name - (char*)de + newlen + 2); // Add space for a / and a nul - - // Conversion to UTF-8 - memcpy(newde, de, de->d_name - (char*)de); - fl_utf8from_mb(newde->d_name, newlen + 1, de->d_name, len); - - // Check if dir (checks done on "old" name as we need to interact with - // the underlying OS) - if (de->d_name[len-1]!='/' && len<=FL_PATH_MAX) { - // Use memcpy for speed since we already know the length of the string... - memcpy(name, de->d_name, len+1); - if (fl_filename_isdir(fullname)) { - char *dst = newde->d_name + newlen; - *dst++ = '/'; - *dst = 0; - } - } - - free(de); - (*list)[i] = newde; - } - free(fullname); - - return n; -} - -const char *Fl_Posix_System_Driver::getpwnam(const char *login) { - struct passwd *pwd; - pwd = ::getpwnam(login); - return pwd ? pwd->pw_dir : NULL; -} - -// Find a program in the path... -static char *path_find(const char *program, char *filename, int filesize) { - const char *path; // Search path - char *ptr, // Pointer into filename - *end; // End of filename buffer - - - if ((path = getenv("PATH")) == NULL) path = "/bin:/usr/bin"; - - for (ptr = filename, end = filename + filesize - 1; *path; path ++) { - if (*path == ':') { - if (ptr > filename && ptr[-1] != '/' && ptr < end) *ptr++ = '/'; - - strlcpy(ptr, program, end - ptr + 1); - - if (!access(filename, X_OK)) return filename; - - ptr = filename; - } else if (ptr < end) *ptr++ = *path; - } - - if (ptr > filename) { - if (ptr[-1] != '/' && ptr < end) *ptr++ = '/'; - - strlcpy(ptr, program, end - ptr + 1); - - if (!access(filename, X_OK)) return filename; - } - - return 0; -} -int Fl_Posix_System_Driver::open_uri(const char *uri, char *msg, int msglen) -{ - // Run any of several well-known commands to open the URI. - // - // We give preference to the Portland group's xdg-utils - // programs which run the user's preferred web browser, etc. - // based on the current desktop environment in use. We fall - // back on older standards and then finally test popular programs - // until we find one we can use. - // - // Note that we specifically do not support the MAILER and - // BROWSER environment variables because we have no idea whether - // we need to run the listed commands in a terminal program. - char command[FL_PATH_MAX], // Command to run... - *argv[4], // Command-line arguments - remote[1024]; // Remote-mode command... - const char * const *commands; // Array of commands to check... - int i; - static const char * const browsers[] = { - "xdg-open", // Portland - "htmlview", // Freedesktop.org - "firefox", - "mozilla", - "netscape", - "konqueror", // KDE - "opera", - "hotjava", // Solaris - "mosaic", - NULL - }; - static const char * const readers[] = { - "xdg-email", // Portland - "thunderbird", - "mozilla", - "netscape", - "evolution", // GNOME - "kmailservice", // KDE - NULL - }; - static const char * const managers[] = { - "xdg-open", // Portland - "fm", // IRIX - "dtaction", // CDE - "nautilus", // GNOME - "konqueror", // KDE - NULL - }; - - // Figure out which commands to check for... - if (!strncmp(uri, "file://", 7)) commands = managers; - else if (!strncmp(uri, "mailto:", 7) || - !strncmp(uri, "news:", 5)) commands = readers; - else commands = browsers; - - // Find the command to run... - for (i = 0; commands[i]; i ++) - if (path_find(commands[i], command, sizeof(command))) break; - - if (!commands[i]) { - if (msg) { - snprintf(msg, msglen, "No helper application found for \"%s\"", uri); - } - - return 0; - } - - // Handle command-specific arguments... - argv[0] = (char *)commands[i]; - - if (!strcmp(commands[i], "firefox") || - !strcmp(commands[i], "mozilla") || - !strcmp(commands[i], "netscape") || - !strcmp(commands[i], "thunderbird")) { - // program -remote openURL(uri) - snprintf(remote, sizeof(remote), "openURL(%s)", uri); - - argv[1] = (char *)"-remote"; - argv[2] = remote; - argv[3] = 0; - } else if (!strcmp(commands[i], "dtaction")) { - // dtaction open uri - argv[1] = (char *)"open"; - argv[2] = (char *)uri; - argv[3] = 0; - } else { - // program uri - argv[1] = (char *)uri; - argv[2] = 0; - } - - if (msg) { - strlcpy(msg, argv[0], msglen); - - for (i = 1; argv[i]; i ++) { - strlcat(msg, " ", msglen); - strlcat(msg, argv[i], msglen); - } - } - - return run_program(command, argv, msg, msglen) != 0; -} - - -int Fl_Posix_System_Driver::file_browser_load_filesystem(Fl_File_Browser *browser, char *filename, Fl_File_Icon *icon) -{ - int num_files = 0; -#if 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)); - browser->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 - browser->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)); - browser->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... - // - FILE *mtab; // /etc/mtab or /etc/mnttab file - char line[FL_PATH_MAX]; // Input line - - // - // Open the file that contains a list of mounted filesystems... - // - - mtab = fl_fopen("/etc/mnttab", "r"); // Fairly standard - if (mtab == NULL) - mtab = fl_fopen("/etc/mtab", "r"); // More standard - if (mtab == NULL) - mtab = fl_fopen("/etc/fstab", "r"); // Otherwise fallback to full list - if (mtab == NULL) - mtab = fl_fopen("/etc/vfstab", "r"); // Alternate full list file - - if (mtab != NULL) - { - while (fgets(line, sizeof(line), mtab) != NULL) - { - if (line[0] == '#' || line[0] == '\n') - continue; - if (sscanf(line, "%*s%4095s", filename) != 1) - continue; - - // 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); - browser->add(filename, icon); - num_files ++; - } - - 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. - browser->add("/", icon); - } -#endif // _AIX || ... - return num_files; -} - -void Fl_Posix_System_Driver::newUUID(char *uuidBuffer) -{ - // warning Unix implementation of Fl_Preferences::newUUID() incomplete! - // #include - // void uuid_generate(uuid_t out); - unsigned char b[16]; - time_t t = time(0); // first 4 byte - b[0] = (unsigned char)t; - b[1] = (unsigned char)(t>>8); - b[2] = (unsigned char)(t>>16); - b[3] = (unsigned char)(t>>24); - int r = rand(); // four more bytes - b[4] = (unsigned char)r; - b[5] = (unsigned char)(r>>8); - b[6] = (unsigned char)(r>>16); - b[7] = (unsigned char)(r>>24); - unsigned long a = (unsigned long)&t; // four more bytes - b[8] = (unsigned char)a; - b[9] = (unsigned char)(a>>8); - b[10] = (unsigned char)(a>>16); - b[11] = (unsigned char)(a>>24); - // Now we try to find 4 more "random" bytes. We extract the - // lower 4 bytes from the address of t - it is created on the - // stack so *might* be in a different place each time... - // This is now done via a union to make it compile OK on 64-bit systems. - union { void *pv; unsigned char a[sizeof(void*)]; } v; - v.pv = (void *)(&t); - // NOTE: May need to handle big- or little-endian systems here -# if WORDS_BIGENDIAN - b[8] = v.a[sizeof(void*) - 1]; - b[9] = v.a[sizeof(void*) - 2]; - b[10] = v.a[sizeof(void*) - 3]; - b[11] = v.a[sizeof(void*) - 4]; -# else // data ordered for a little-endian system - b[8] = v.a[0]; - b[9] = v.a[1]; - b[10] = v.a[2]; - b[11] = v.a[3]; -# endif - char name[80]; // last four bytes - gethostname(name, 79); - memcpy(b+12, name, 4); - sprintf(uuidBuffer, "%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X", - b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7], - b[8], b[9], b[10], b[11], b[12], b[13], b[14], b[15]); -} - -char *Fl_Posix_System_Driver::preference_rootnode(Fl_Preferences *prefs, Fl_Preferences::Root root, const char *vendor, - const char *application) -{ - static char filename[ FL_PATH_MAX ]; filename[0] = 0; - const char *e; - switch (root) { - case Fl_Preferences::USER: - if ((e = ::getenv("HOME")) != NULL) { - strlcpy(filename, e, sizeof(filename)); - - if (filename[strlen(filename)-1] != '/') { - strlcat(filename, "/.fltk/", sizeof(filename)); - } else { - strlcat(filename, ".fltk/", sizeof(filename)); - } - break; - } - case Fl_Preferences::SYSTEM: - strcpy(filename, "/etc/fltk/"); - break; - } - snprintf(filename + strlen(filename), sizeof(filename) - strlen(filename), - "%s/%s.prefs", vendor, application); - return filename; -} void *Fl_Posix_System_Driver::dlopen(const char *filename) { @@ -561,6 +84,12 @@ int Fl_Posix_System_Driver::file_type(const char *filename) return filetype; } +const char *Fl_Posix_System_Driver::getpwnam(const char *login) { + struct passwd *pwd; + pwd = ::getpwnam(login); + return pwd ? pwd->pw_dir : NULL; +} + // // End of "$Id$". // diff --git a/src/drivers/X11/Fl_X11_System_Driver.H b/src/drivers/X11/Fl_X11_System_Driver.H new file mode 100644 index 000000000..a36c3214c --- /dev/null +++ b/src/drivers/X11/Fl_X11_System_Driver.H @@ -0,0 +1,51 @@ +// +// "$Id: quartz.H 11017 2016-01-20 21:40:12Z matt $" +// +// Definition of Posix system driver +// for the Fast Light Tool Kit (FLTK). +// +// Copyright 2010-2016 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 FL_X11_SYSTEM_DRIVER_H +#define FL_X11_SYSTEM_DRIVER_H + +#include "../Posix/Fl_Posix_System_Driver.H" + +class Fl_X11_System_Driver : public Fl_Posix_System_Driver { +public: + Fl_X11_System_Driver() : Fl_Posix_System_Driver() {} + virtual void display_arg(const char *arg); + virtual int XParseGeometry(const char*, int*, int*, unsigned int*, unsigned int*); + virtual int clocale_printf(FILE *output, const char *format, va_list args); + // these 2 are in Fl_get_key.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 **) ); + virtual int need_menu_handle_part1_extra() {return 1;} + virtual int open_uri(const char *uri, char *msg, int msglen); + virtual int use_tooltip_timeout_condition() {return 1;} + // this one is in fl_shortcut.cxx + virtual const char *shortcut_add_key_name(unsigned key, char *p, char *buf, const char **); + virtual int file_browser_load_filesystem(Fl_File_Browser *browser, char *filename, Fl_File_Icon *icon); + virtual void newUUID(char *uuidBuffer); + virtual char *preference_rootnode(Fl_Preferences *prefs, Fl_Preferences::Root root, const char *vendor, + const char *application); + virtual int preferences_need_protection_check() {return 1;} +}; + +#endif /* FL_X11_SYSTEM_DRIVER_H */ + +// +// End of "$Id: quartz.H 11017 2016-01-20 21:40:12Z matt $". +// diff --git a/src/drivers/X11/Fl_X11_System_Driver.cxx b/src/drivers/X11/Fl_X11_System_Driver.cxx new file mode 100644 index 000000000..694d9d188 --- /dev/null +++ b/src/drivers/X11/Fl_X11_System_Driver.cxx @@ -0,0 +1,503 @@ +// +// "$Id: quartz.H 11017 2016-01-20 21:40:12Z matt $" +// +// Definition of Posix system driver +// for the Fast Light Tool Kit (FLTK). +// +// Copyright 2010-2016 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_X11_System_Driver.H" +#include + +#include +#include +#include + +#if defined(_AIX) +extern "C" { +# include +# include + // Older AIX versions don't expose this prototype + int mntctl(int, int, char *); +} +#endif // _AIX + +#if defined(__NetBSD__) +extern "C" { +# include // For '__NetBSD_Version__' definition +# if defined(__NetBSD_Version__) && (__NetBSD_Version__ >= 300000000) +# include +# include +# if defined(HAVE_PTHREAD) && defined(HAVE_PTHREAD_H) +# include +# 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__ + +#ifndef HAVE_SCANDIR +extern "C" { + int fl_scandir(const char *dirname, struct dirent ***namelist, + int (*select)(struct dirent *), + int (*compar)(struct dirent **, struct dirent **)); +} +#endif + +// Pointers you can use to change FLTK to another language. +// Note: Similar pointers are defined in FL/fl_ask.H and src/fl_ask.cxx +const char* fl_local_alt = "Alt"; +const char* fl_local_ctrl = "Ctrl"; +const char* fl_local_meta = "Meta"; +const char* fl_local_shift = "Shift"; + +/** + Creates a driver that manages all screen and display related calls. + + This function must be implemented once for every platform. + */ +Fl_System_Driver *Fl_System_Driver::newSystemDriver() +{ + return new Fl_X11_System_Driver(); +} + + +int Fl_X11_System_Driver::clocale_printf(FILE *output, const char *format, va_list args) { + char *saved_locale = setlocale(LC_NUMERIC, NULL); + setlocale(LC_NUMERIC, "C"); + int retval = vfprintf(output, format, args); + setlocale(LC_NUMERIC, saved_locale); + return retval; +} + + +// Find a program in the path... +static char *path_find(const char *program, char *filename, int filesize) { + const char *path; // Search path + char *ptr, // Pointer into filename + *end; // End of filename buffer + + + if ((path = getenv("PATH")) == NULL) path = "/bin:/usr/bin"; + + for (ptr = filename, end = filename + filesize - 1; *path; path ++) { + if (*path == ':') { + if (ptr > filename && ptr[-1] != '/' && ptr < end) *ptr++ = '/'; + + strlcpy(ptr, program, end - ptr + 1); + + if (!access(filename, X_OK)) return filename; + + ptr = filename; + } else if (ptr < end) *ptr++ = *path; + } + + if (ptr > filename) { + if (ptr[-1] != '/' && ptr < end) *ptr++ = '/'; + + strlcpy(ptr, program, end - ptr + 1); + + if (!access(filename, X_OK)) return filename; + } + + return 0; +} + + +int Fl_X11_System_Driver::open_uri(const char *uri, char *msg, int msglen) +{ + // Run any of several well-known commands to open the URI. + // + // We give preference to the Portland group's xdg-utils + // programs which run the user's preferred web browser, etc. + // based on the current desktop environment in use. We fall + // back on older standards and then finally test popular programs + // until we find one we can use. + // + // Note that we specifically do not support the MAILER and + // BROWSER environment variables because we have no idea whether + // we need to run the listed commands in a terminal program. + char command[FL_PATH_MAX], // Command to run... + *argv[4], // Command-line arguments + remote[1024]; // Remote-mode command... + const char * const *commands; // Array of commands to check... + int i; + static const char * const browsers[] = { + "xdg-open", // Portland + "htmlview", // Freedesktop.org + "firefox", + "mozilla", + "netscape", + "konqueror", // KDE + "opera", + "hotjava", // Solaris + "mosaic", + NULL + }; + static const char * const readers[] = { + "xdg-email", // Portland + "thunderbird", + "mozilla", + "netscape", + "evolution", // GNOME + "kmailservice", // KDE + NULL + }; + static const char * const managers[] = { + "xdg-open", // Portland + "fm", // IRIX + "dtaction", // CDE + "nautilus", // GNOME + "konqueror", // KDE + NULL + }; + + // Figure out which commands to check for... + if (!strncmp(uri, "file://", 7)) commands = managers; + else if (!strncmp(uri, "mailto:", 7) || + !strncmp(uri, "news:", 5)) commands = readers; + else commands = browsers; + + // Find the command to run... + for (i = 0; commands[i]; i ++) + if (path_find(commands[i], command, sizeof(command))) break; + + if (!commands[i]) { + if (msg) { + snprintf(msg, msglen, "No helper application found for \"%s\"", uri); + } + + return 0; + } + + // Handle command-specific arguments... + argv[0] = (char *)commands[i]; + + if (!strcmp(commands[i], "firefox") || + !strcmp(commands[i], "mozilla") || + !strcmp(commands[i], "netscape") || + !strcmp(commands[i], "thunderbird")) { + // program -remote openURL(uri) + snprintf(remote, sizeof(remote), "openURL(%s)", uri); + + argv[1] = (char *)"-remote"; + argv[2] = remote; + argv[3] = 0; + } else if (!strcmp(commands[i], "dtaction")) { + // dtaction open uri + argv[1] = (char *)"open"; + argv[2] = (char *)uri; + argv[3] = 0; + } else { + // program uri + argv[1] = (char *)uri; + argv[2] = 0; + } + + if (msg) { + strlcpy(msg, argv[0], msglen); + + for (i = 1; argv[i]; i ++) { + strlcat(msg, " ", msglen); + strlcat(msg, argv[i], msglen); + } + } + + return run_program(command, argv, msg, msglen) != 0; +} + + +int Fl_X11_System_Driver::file_browser_load_filesystem(Fl_File_Browser *browser, char *filename, Fl_File_Icon *icon) +{ + int num_files = 0; +#if 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)); + browser->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 + browser->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)); + browser->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... + // + FILE *mtab; // /etc/mtab or /etc/mnttab file + char line[FL_PATH_MAX]; // Input line + + // + // Open the file that contains a list of mounted filesystems... + // + + mtab = fopen("/etc/mnttab", "r"); // Fairly standard + if (mtab == NULL) + mtab = fopen("/etc/mtab", "r"); // More standard + if (mtab == NULL) + mtab = fopen("/etc/fstab", "r"); // Otherwise fallback to full list + if (mtab == NULL) + mtab = fopen("/etc/vfstab", "r"); // Alternate full list file + + if (mtab != NULL) + { + while (fgets(line, sizeof(line), mtab) != NULL) + { + if (line[0] == '#' || line[0] == '\n') + continue; + if (sscanf(line, "%*s%4095s", filename) != 1) + continue; + + // 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); + browser->add(filename, icon); + num_files ++; + } + + 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. + browser->add("/", icon); + } +#endif // _AIX || ... + return num_files; +} + +void Fl_X11_System_Driver::newUUID(char *uuidBuffer) +{ + // warning Unix implementation of Fl_Preferences::newUUID() incomplete! + // #include + // void uuid_generate(uuid_t out); + unsigned char b[16]; + time_t t = time(0); // first 4 byte + b[0] = (unsigned char)t; + b[1] = (unsigned char)(t>>8); + b[2] = (unsigned char)(t>>16); + b[3] = (unsigned char)(t>>24); + int r = rand(); // four more bytes + b[4] = (unsigned char)r; + b[5] = (unsigned char)(r>>8); + b[6] = (unsigned char)(r>>16); + b[7] = (unsigned char)(r>>24); + unsigned long a = (unsigned long)&t; // four more bytes + b[8] = (unsigned char)a; + b[9] = (unsigned char)(a>>8); + b[10] = (unsigned char)(a>>16); + b[11] = (unsigned char)(a>>24); + // Now we try to find 4 more "random" bytes. We extract the + // lower 4 bytes from the address of t - it is created on the + // stack so *might* be in a different place each time... + // This is now done via a union to make it compile OK on 64-bit systems. + union { void *pv; unsigned char a[sizeof(void*)]; } v; + v.pv = (void *)(&t); + // NOTE: May need to handle big- or little-endian systems here +# if WORDS_BIGENDIAN + b[8] = v.a[sizeof(void*) - 1]; + b[9] = v.a[sizeof(void*) - 2]; + b[10] = v.a[sizeof(void*) - 3]; + b[11] = v.a[sizeof(void*) - 4]; +# else // data ordered for a little-endian system + b[8] = v.a[0]; + b[9] = v.a[1]; + b[10] = v.a[2]; + b[11] = v.a[3]; +# endif + char name[80]; // last four bytes + gethostname(name, 79); + memcpy(b+12, name, 4); + sprintf(uuidBuffer, "%02X%02X%02X%02X-%02X%02X-%02X%02X-%02X%02X-%02X%02X%02X%02X%02X%02X", + b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7], + b[8], b[9], b[10], b[11], b[12], b[13], b[14], b[15]); +} + +char *Fl_X11_System_Driver::preference_rootnode(Fl_Preferences *prefs, Fl_Preferences::Root root, const char *vendor, + const char *application) +{ + static char filename[ FL_PATH_MAX ]; filename[0] = 0; + const char *e; + switch (root) { + case Fl_Preferences::USER: + if ((e = ::getenv("HOME")) != NULL) { + strlcpy(filename, e, sizeof(filename)); + + if (filename[strlen(filename)-1] != '/') { + strlcat(filename, "/.fltk/", sizeof(filename)); + } else { + strlcat(filename, ".fltk/", sizeof(filename)); + } + break; + } + case Fl_Preferences::SYSTEM: + strcpy(filename, "/etc/fltk/"); + break; + } + snprintf(filename + strlen(filename), sizeof(filename) - strlen(filename), + "%s/%s.prefs", vendor, application); + return filename; +} + +void Fl_X11_System_Driver::display_arg(const char *arg) { + Fl::display(arg); +} + +int Fl_X11_System_Driver::XParseGeometry(const char* string, int* x, int* y, + unsigned int* width, unsigned int* height) { + return ::XParseGeometry(string, x, y, width, height); +} + +int Fl_X11_System_Driver::filename_list(const char *d, dirent ***list, int (*sort)(struct dirent **, struct dirent **) ) { + int dirlen; + char *dirloc; + + // Assume that locale encoding is no less dense than UTF-8 + dirlen = strlen(d); + dirloc = (char *)malloc(dirlen + 1); + fl_utf8to_mb(d, dirlen, dirloc, dirlen + 1); + +#ifndef HAVE_SCANDIR + // This version is when we define our own scandir + int n = fl_scandir(dirloc, list, 0, sort); +#elif defined(HAVE_SCANDIR_POSIX) + // POSIX (2008) defines the comparison function like this: + int n = scandir(dirloc, list, 0, (int(*)(const dirent **, const dirent **))sort); +#elif defined(__osf__) + // OSF, DU 4.0x + int n = scandir(dirloc, list, 0, (int(*)(dirent **, dirent **))sort); +#elif defined(_AIX) + // AIX is almost standard... + int n = scandir(dirloc, list, 0, (int(*)(void*, void*))sort); +#elif defined(__sgi) + int n = scandir(dirloc, list, 0, sort); +#else + // The vast majority of UNIX systems want the sort function to have this + // prototype, most likely so that it can be passed to qsort without any + // changes: + int n = scandir(dirloc, list, 0, (int(*)(const void*,const void*))sort); +#endif + + free(dirloc); + + // convert every filename to UTF-8, and append a '/' to all + // filenames that are directories + int i; + char *fullname = (char*)malloc(dirlen+FL_PATH_MAX+3); // Add enough extra for two /'s and a nul + // Use memcpy for speed since we already know the length of the string... + memcpy(fullname, d, dirlen+1); + + char *name = fullname + dirlen; + if (name!=fullname && name[-1]!='/') + *name++ = '/'; + + for (i=0; id_name); + newlen = fl_utf8from_mb(NULL, 0, de->d_name, len); + dirent *newde = (dirent*)malloc(de->d_name - (char*)de + newlen + 2); // Add space for a / and a nul + + // Conversion to UTF-8 + memcpy(newde, de, de->d_name - (char*)de); + fl_utf8from_mb(newde->d_name, newlen + 1, de->d_name, len); + + // Check if dir (checks done on "old" name as we need to interact with + // the underlying OS) + if (de->d_name[len-1]!='/' && len<=FL_PATH_MAX) { + // Use memcpy for speed since we already know the length of the string... + memcpy(name, de->d_name, len+1); + if (fl_filename_isdir(fullname)) { + char *dst = newde->d_name + newlen; + *dst++ = '/'; + *dst = 0; + } + } + + free(de); + (*list)[i] = newde; + } + free(fullname); + + return n; +} + +// +// End of "$Id: quartz.H 11017 2016-01-20 21:40:12Z matt $". +// diff --git a/src/fl_open_uri.cxx b/src/fl_open_uri.cxx index 721158dc2..d2a4d9f34 100644 --- a/src/fl_open_uri.cxx +++ b/src/fl_open_uri.cxx @@ -27,7 +27,6 @@ #include "config_lib.h" #include #include -#include #include #include #include "flstring.h" @@ -130,8 +129,9 @@ void fl_decode_uri(char *uri) /** @} */ -#if defined(FL_CFG_GFX_XLIB) || defined(FL_CFG_GFX_QUARTZ) +#if defined(FL_CFG_SYS_POSIX) // code shared by the Mac OS and USE_X11 platforms +# include "drivers/Posix/Fl_Posix_System_Driver.H" # include # include # include @@ -139,7 +139,7 @@ void fl_decode_uri(char *uri) # include // Run the specified program, returning 1 on success and 0 on failure -static int run_program(const char *program, char **argv, char *msg, int msglen) { +int Fl_Posix_System_Driver::run_program(const char *program, char **argv, char *msg, int msglen) { pid_t pid; // Process ID of first child int status; // Exit status from first child sigset_t set, oldset; // Signal masks @@ -163,13 +163,13 @@ static int run_program(const char *program, char **argv, char *msg, int msglen) if (!fork()) { // Second child comes here, redirect stdin/out/err to /dev/null... close(0); - open("/dev/null", O_RDONLY); + ::open("/dev/null", O_RDONLY); close(1); - open("/dev/null", O_WRONLY); + ::open("/dev/null", O_WRONLY); close(2); - open("/dev/null", O_WRONLY); + ::open("/dev/null", O_WRONLY); // Detach from the current process group... setsid(); @@ -210,26 +210,8 @@ static int run_program(const char *program, char **argv, char *msg, int msglen) // Return indicating success... return 1; } -#endif +#endif // FL_CFG_SYS_POSIX -#if defined(FL_CFG_GFX_QUARTZ) - -#include "drivers/Darwin/Fl_Darwin_System_Driver.H" - -int Fl_Darwin_System_Driver::run_program(const char *program, char **argv, char *msg, int msglen) -{ - return ::run_program(program, argv, msg, msglen); -} - -#elif defined(FL_CFG_GFX_XLIB) -#include "drivers/Posix/Fl_Posix_System_Driver.H" - -int Fl_Posix_System_Driver::run_program(const char *program, char **argv, char *msg, int msglen) -{ - return ::run_program(program, argv, msg, msglen); -} - -#endif #ifdef TEST // diff --git a/src/fl_shortcut.cxx b/src/fl_shortcut.cxx index bf8294131..5f8d7cfcb 100644 --- a/src/fl_shortcut.cxx +++ b/src/fl_shortcut.cxx @@ -443,12 +443,12 @@ Fl_System_Driver::Keyname Fl_System_Driver::table[] = { #endif #if defined(FL_CFG_GFX_XLIB) -#include "drivers/Posix/Fl_Posix_System_Driver.H" +#include "drivers/X11/Fl_X11_System_Driver.H" #include Fl_System_Driver::Keyname Fl_System_Driver::table[] = {}; -const char *Fl_Posix_System_Driver::shortcut_add_key_name(unsigned key, char *p, char *buf, const char **eom) +const char *Fl_X11_System_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":