Rewrite Fl_File_Browser.cxx under the driver model.
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.3-porting@11570 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
This commit is contained in:
parent
9ca66c6f3d
commit
927774af85
@ -26,9 +26,12 @@
|
||||
|
||||
#include <FL/Fl_Export.H>
|
||||
#include <FL/platform_types.h>
|
||||
#include <FL/filename.H>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
class Fl_File_Icon;
|
||||
class Fl_File_Browser;
|
||||
|
||||
/**
|
||||
\brief A base class for platform-specific system operations.
|
||||
@ -128,6 +131,10 @@ public:
|
||||
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()
|
||||
virtual int file_browser_load_filesystem(Fl_File_Browser *browser, char *filename, Fl_File_Icon *icon) {return 0;}
|
||||
// the default implementation of file_browser_load_directory() should be enough
|
||||
virtual int file_browser_load_directory(const char *directory, char *filename, dirent ***pfiles, Fl_File_Sort_F *sort);
|
||||
};
|
||||
|
||||
#endif // FL_SYSTEM_DRIVER_H
|
||||
|
@ -4,6 +4,7 @@
|
||||
// Fl_File_Browser routines.
|
||||
//
|
||||
// Copyright 1999-2010 by Michael Sweet.
|
||||
// Copyright 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
|
||||
@ -26,12 +27,6 @@
|
||||
// Fl_File_Browser::filter() - Set the filename filter.
|
||||
//
|
||||
|
||||
#if defined(WIN32) || defined(__APPLE__) // PORTME: Fl_Screen_Driver - platform file browser
|
||||
#elif defined(FL_PORTING)
|
||||
# pragma message "FL_PORTING: implement the internals of your file browser here"
|
||||
#else
|
||||
#endif
|
||||
|
||||
//
|
||||
// Include necessary header files...
|
||||
//
|
||||
@ -46,57 +41,6 @@
|
||||
#include <stdlib.h>
|
||||
#include "flstring.h"
|
||||
|
||||
#ifdef __CYGWIN__
|
||||
# include <mntent.h>
|
||||
#elif defined(WIN32)
|
||||
# include <windows.h>
|
||||
# include <direct.h>
|
||||
// Apparently Borland C++ defines DIRECTORY in <direct.h>, which
|
||||
// interfers with the Fl_File_Icon enumeration of the same name.
|
||||
# ifdef DIRECTORY
|
||||
# undef DIRECTORY
|
||||
# endif // DIRECTORY
|
||||
#endif // __CYGWIN__
|
||||
|
||||
#ifdef __EMX__
|
||||
# define INCL_DOS
|
||||
# define INCL_DOSMISC
|
||||
# include <os2.h>
|
||||
#endif // __EMX__
|
||||
|
||||
#if defined(__APPLE__) // PORTME: Fl_Screen_Driver - platform file browser
|
||||
# include <sys/param.h>
|
||||
# include <sys/ucred.h>
|
||||
# include <sys/mount.h>
|
||||
#endif // __APPLE__ // PORTME: Fl_Screen_Driver - platform file browser
|
||||
|
||||
#if defined(_AIX)
|
||||
extern "C" {
|
||||
# include <sys/types.h>
|
||||
# include <sys/vmount.h>
|
||||
# include <sys/mntctl.h>
|
||||
// Older AIX versions don't expose this prototype
|
||||
int
|
||||
mntctl(int, int, char *);
|
||||
}
|
||||
#endif // _AIX
|
||||
|
||||
#if defined(__NetBSD__)
|
||||
extern "C" {
|
||||
# include <sys/param.h> // For '__NetBSD_Version__' definition
|
||||
# if defined(__NetBSD_Version__) && (__NetBSD_Version__ >= 300000000)
|
||||
# include <sys/types.h>
|
||||
# include <sys/statvfs.h>
|
||||
# if defined(HAVE_PTHREAD) && defined(HAVE_PTHREAD_H)
|
||||
# include <pthread.h>
|
||||
# endif // HAVE_PTHREAD && HAVE_PTHREAD_H
|
||||
# ifdef HAVE_PTHREAD
|
||||
static pthread_mutex_t getvfsstat_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
# endif // HAVE_PTHREAD/
|
||||
# endif // __NetBSD_Version__
|
||||
}
|
||||
#endif // __NetBSD__
|
||||
|
||||
//
|
||||
// FL_BLINE definition from "Fl_Browser.cxx"...
|
||||
//
|
||||
@ -461,237 +405,17 @@ Fl_File_Browser::load(const char *directory,// I - Directory to load
|
||||
// No directory specified; for UNIX list all mount points. For DOS
|
||||
// list all valid drive letters...
|
||||
//
|
||||
|
||||
num_files = 0;
|
||||
if ((icon = Fl_File_Icon::find("any", Fl_File_Icon::DEVICE)) == NULL)
|
||||
icon = Fl_File_Icon::find("any", Fl_File_Icon::DIRECTORY);
|
||||
|
||||
#ifdef WIN32
|
||||
# ifdef __CYGWIN__
|
||||
//
|
||||
// Cygwin provides an implementation of setmntent() to get the list
|
||||
// of available drives...
|
||||
//
|
||||
FILE *m = setmntent("/-not-used-", "r");
|
||||
struct mntent *p;
|
||||
|
||||
while ((p = getmntent (m)) != NULL) {
|
||||
add(p->mnt_dir, icon);
|
||||
num_files ++;
|
||||
}
|
||||
|
||||
endmntent(m);
|
||||
# else
|
||||
//
|
||||
// Normal WIN32 code uses drive bits...
|
||||
//
|
||||
DWORD drives; // Drive available bits
|
||||
|
||||
drives = GetLogicalDrives();
|
||||
for (i = 'A'; i <= 'Z'; i ++, drives >>= 1)
|
||||
if (drives & 1)
|
||||
{
|
||||
sprintf(filename, "%c:/", i);
|
||||
|
||||
if (i < 'C') // see also: GetDriveType and GetVolumeInformation in WIN32
|
||||
add(filename, icon);
|
||||
else
|
||||
add(filename, icon);
|
||||
|
||||
num_files ++;
|
||||
}
|
||||
# endif // __CYGWIN__
|
||||
#elif defined(__EMX__)
|
||||
//
|
||||
// OS/2 code uses drive bits...
|
||||
//
|
||||
ULONG curdrive; // Current drive
|
||||
ULONG drives; // Drive available bits
|
||||
int start = 3; // 'C' (MRS - dunno if this is correct!)
|
||||
|
||||
|
||||
DosQueryCurrentDisk(&curdrive, &drives);
|
||||
drives >>= start - 1;
|
||||
for (i = 'A'; i <= 'Z'; i ++, drives >>= 1)
|
||||
if (drives & 1)
|
||||
{
|
||||
sprintf(filename, "%c:/", i);
|
||||
add(filename, icon);
|
||||
|
||||
num_files ++;
|
||||
}
|
||||
#elif defined(__APPLE__) // PORTME: Fl_Screen_Driver - platform file browser
|
||||
// MacOS X and Darwin use getfsstat() system call...
|
||||
int numfs; // Number of file systems
|
||||
struct statfs *fs; // Buffer for file system info
|
||||
|
||||
|
||||
// We always have the root filesystem.
|
||||
add("/", icon);
|
||||
|
||||
// Get the mounted filesystems...
|
||||
numfs = getfsstat(NULL, 0, MNT_NOWAIT);
|
||||
if (numfs > 0) {
|
||||
// We have file systems, get them...
|
||||
fs = new struct statfs[numfs];
|
||||
getfsstat(fs, sizeof(struct statfs) * numfs, MNT_NOWAIT);
|
||||
|
||||
// Add filesystems to the list...
|
||||
for (i = 0; i < numfs; i ++) {
|
||||
// Ignore "/", "/dev", and "/.vol"...
|
||||
if (fs[i].f_mntonname[1] && strcmp(fs[i].f_mntonname, "/dev") &&
|
||||
strcmp(fs[i].f_mntonname, "/.vol")) {
|
||||
snprintf(filename, sizeof(filename), "%s/", fs[i].f_mntonname);
|
||||
add(filename, icon);
|
||||
}
|
||||
num_files ++;
|
||||
}
|
||||
|
||||
// Free the memory used for the file system info array...
|
||||
delete[] fs;
|
||||
}
|
||||
#elif defined(_AIX)
|
||||
// AIX don't write the mounted filesystems to a file like '/etc/mnttab'.
|
||||
// But reading the list of mounted filesystems from the kernel is possible:
|
||||
// http://publib.boulder.ibm.com/infocenter/pseries/v5r3/topic/com.ibm.aix.basetechref/doc/basetrf1/mntctl.htm
|
||||
int res = -1, len;
|
||||
char *list = NULL, *name;
|
||||
struct vmount *vp;
|
||||
|
||||
// We always have the root filesystem
|
||||
add("/", icon);
|
||||
// Get the required buffer size for the vmount structures
|
||||
res = mntctl(MCTL_QUERY, sizeof(len), (char *) &len);
|
||||
if (!res) {
|
||||
// Allocate buffer ...
|
||||
list = (char *) malloc((size_t) len);
|
||||
if (NULL == list) {
|
||||
res = -1;
|
||||
} else {
|
||||
// ... and read vmount structures from kernel
|
||||
res = mntctl(MCTL_QUERY, len, list);
|
||||
if (0 >= res) {
|
||||
res = -1;
|
||||
} else {
|
||||
for (i = 0, vp = (struct vmount *) list; i < res; ++i) {
|
||||
name = (char *) vp + vp->vmt_data[VMT_STUB].vmt_off;
|
||||
strlcpy(filename, name, sizeof(filename));
|
||||
// Skip the already added root filesystem
|
||||
if (strcmp("/", filename) != 0) {
|
||||
strlcat(filename, "/", sizeof(filename));
|
||||
add(filename, icon);
|
||||
}
|
||||
vp = (struct vmount *) ((char *) vp + vp->vmt_length);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Note: Executing 'free(NULL)' is allowed and simply do nothing
|
||||
free((void *) list);
|
||||
#elif defined(__NetBSD__) && defined(__NetBSD_Version__) \
|
||||
&& (__NetBSD_Version__ >= 300000000)
|
||||
// NetBSD don't write the mounted filesystems to a file like '/etc/mnttab'.
|
||||
// Since NetBSD 3.0 the system call getvfsstat(2) has replaced getfsstat(2)
|
||||
// that is used by getmntinfo(3):
|
||||
// http://www.daemon-systems.org/man/getmntinfo.3.html
|
||||
int res = -1;
|
||||
struct statvfs *list;
|
||||
|
||||
// We always have the root filesystem
|
||||
add("/", icon);
|
||||
# ifdef HAVE_PTHREAD
|
||||
// Lock mutex for thread safety
|
||||
if (!pthread_mutex_lock(&getvfsstat_mutex)) {
|
||||
# endif // HAVE_PTHREAD
|
||||
// Get list of statvfs structures
|
||||
res = getmntinfo(&list, ST_WAIT);
|
||||
if(0 < res) {
|
||||
for (i = 0; i < res; ++i) {
|
||||
strlcpy(filename, list[i].f_mntonname, sizeof(filename));
|
||||
// Skip the already added root filesystem
|
||||
if (strcmp("/", filename) != 0) {
|
||||
strlcat(filename, "/", sizeof(filename));
|
||||
add(filename, icon);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
res = -1;
|
||||
}
|
||||
# ifdef HAVE_PTHREAD
|
||||
pthread_mutex_unlock(&getvfsstat_mutex);
|
||||
}
|
||||
# endif // HAVE_PTHREAD
|
||||
#else
|
||||
//
|
||||
// UNIX code uses /etc/fstab or similar...
|
||||
//
|
||||
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);
|
||||
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.
|
||||
add("/", icon);
|
||||
}
|
||||
#endif // WIN32 || __EMX__ || __APPLE__ || _AIX || ... // PORTME: Fl_Screen_Driver - platform file browser
|
||||
num_files = Fl::system_driver()->file_browser_load_filesystem(this, filename, icon);
|
||||
}
|
||||
else
|
||||
{
|
||||
dirent **files; // Files in in directory
|
||||
|
||||
|
||||
//
|
||||
// Build the file list...
|
||||
//
|
||||
|
||||
#if (defined(WIN32) && !defined(__CYGWIN__)) || defined(__EMX__)
|
||||
strlcpy(filename, directory_, sizeof(filename));
|
||||
i = (int) (strlen(filename) - 1);
|
||||
|
||||
if (i == 2 && filename[1] == ':' &&
|
||||
(filename[2] == '/' || filename[2] == '\\'))
|
||||
filename[2] = '/';
|
||||
else if (filename[i] != '/' && filename[i] != '\\')
|
||||
strlcat(filename, "/", sizeof(filename));
|
||||
|
||||
num_files = fl_filename_list(filename, &files, sort);
|
||||
#else
|
||||
num_files = fl_filename_list(directory_, &files, sort);
|
||||
#endif /* WIN32 || __EMX__ */
|
||||
|
||||
num_files = Fl::system_driver()->file_browser_load_directory(directory_, filename, &files, sort);
|
||||
if (num_files <= 0)
|
||||
return (0);
|
||||
|
||||
|
@ -417,6 +417,12 @@ int Fl_System_Driver::filename_expand(char *to,int tolen, const char *from) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
int Fl_System_Driver::file_browser_load_directory(const char *directory, char *filename, dirent ***pfiles,
|
||||
Fl_File_Sort_F *sort)
|
||||
{
|
||||
return filename_list(directory, pfiles, sort);
|
||||
}
|
||||
|
||||
//
|
||||
// End of "$Id$".
|
||||
//
|
||||
|
@ -75,6 +75,7 @@ public:
|
||||
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);
|
||||
};
|
||||
|
||||
#endif // FL_DARWIN_SYSTEM_DRIVER_H
|
||||
|
@ -20,7 +20,9 @@
|
||||
#include "../../config_lib.h"
|
||||
#include "Fl_Darwin_System_Driver.H"
|
||||
#include <FL/Fl.H>
|
||||
#include <FL/Fl_File_Browser.H>
|
||||
#include <FL/filename.H>
|
||||
#include <FL/Fl_File_Icon.H>
|
||||
#include <string.h>
|
||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
|
||||
#include <xlocale.h>
|
||||
@ -29,6 +31,9 @@
|
||||
#include <stdio.h>
|
||||
#include <dlfcn.h>
|
||||
#include <pwd.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/ucred.h>
|
||||
#include <sys/mount.h>
|
||||
|
||||
extern int fl_mac_os_version; // the version number of the running Mac OS X
|
||||
|
||||
@ -153,6 +158,40 @@ int Fl_Darwin_System_Driver::open_uri(const char *uri, char *msg, int msglen)
|
||||
return run_program("/usr/bin/open", argv, msg, msglen) != 0;
|
||||
}
|
||||
|
||||
int Fl_Darwin_System_Driver::file_browser_load_filesystem(Fl_File_Browser *browser, char *filename, Fl_File_Icon *icon)
|
||||
{
|
||||
// MacOS X and Darwin use getfsstat() system call...
|
||||
int numfs; // Number of file systems
|
||||
struct statfs *fs; // Buffer for file system info
|
||||
int num_files = 0;
|
||||
|
||||
// We always have the root filesystem.
|
||||
browser->add("/", icon);
|
||||
|
||||
// Get the mounted filesystems...
|
||||
numfs = getfsstat(NULL, 0, MNT_NOWAIT);
|
||||
if (numfs > 0) {
|
||||
// We have file systems, get them...
|
||||
fs = new struct statfs[numfs];
|
||||
getfsstat(fs, sizeof(struct statfs) * numfs, MNT_NOWAIT);
|
||||
|
||||
// Add filesystems to the list...
|
||||
for (int i = 0; i < numfs; i ++) {
|
||||
// Ignore "/", "/dev", and "/.vol"...
|
||||
if (fs[i].f_mntonname[1] && strcmp(fs[i].f_mntonname, "/dev") &&
|
||||
strcmp(fs[i].f_mntonname, "/.vol")) {
|
||||
snprintf(filename, sizeof(filename), "%s/", fs[i].f_mntonname);
|
||||
browser->add(filename, icon);
|
||||
}
|
||||
num_files ++;
|
||||
}
|
||||
|
||||
// Free the memory used for the file system info array...
|
||||
delete[] fs;
|
||||
}
|
||||
return num_files;
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// End of "$Id$".
|
||||
|
@ -75,6 +75,7 @@ public:
|
||||
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);
|
||||
};
|
||||
|
||||
#endif // FL_POSIX_SYSTEM_DRIVER_H
|
||||
|
@ -19,6 +19,8 @@
|
||||
#include <config.h>
|
||||
#include "Fl_Posix_System_Driver.H"
|
||||
#include "../../flstring.h"
|
||||
#include <FL/Fl_File_Browser.H>
|
||||
#include <FL/Fl_File_Icon.H>
|
||||
#include <FL/filename.H>
|
||||
#include <FL/Fl.H>
|
||||
#include <X11/Xlib.h>
|
||||
@ -28,7 +30,33 @@
|
||||
#include <pwd.h>
|
||||
#include <unistd.h>
|
||||
|
||||
// Pointers you can use to change FLTK to a foreign language.
|
||||
#if defined(_AIX)
|
||||
extern "C" {
|
||||
# include <sys/types.h>
|
||||
# include <sys/vmount.h>
|
||||
# include <sys/mntctl.h>
|
||||
// Older AIX versions don't expose this prototype
|
||||
int mntctl(int, int, char *);
|
||||
}
|
||||
#endif // _AIX
|
||||
|
||||
#if defined(__NetBSD__)
|
||||
extern "C" {
|
||||
# include <sys/param.h> // For '__NetBSD_Version__' definition
|
||||
# if defined(__NetBSD_Version__) && (__NetBSD_Version__ >= 300000000)
|
||||
# include <sys/types.h>
|
||||
# include <sys/statvfs.h>
|
||||
# if defined(HAVE_PTHREAD) && defined(HAVE_PTHREAD_H)
|
||||
# include <pthread.h>
|
||||
# endif // HAVE_PTHREAD && HAVE_PTHREAD_H
|
||||
# ifdef HAVE_PTHREAD
|
||||
static pthread_mutex_t getvfsstat_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
# endif // HAVE_PTHREAD/
|
||||
# endif // __NetBSD_Version__
|
||||
}
|
||||
#endif // __NetBSD__
|
||||
|
||||
// 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";
|
||||
@ -284,6 +312,130 @@ int Fl_Posix_System_Driver::open_uri(const char *uri, char *msg, int 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;
|
||||
}
|
||||
|
||||
//
|
||||
// End of "$Id$".
|
||||
//
|
||||
|
@ -77,6 +77,8 @@ public:
|
||||
virtual const char *filename_ext(const char *buf);
|
||||
virtual int open_uri(const char *uri, char *msg, int msglen);
|
||||
virtual int use_recent_tooltip_fix() {return 1;}
|
||||
virtual int file_browser_load_filesystem(Fl_File_Browser *browser, char *filename, Fl_File_Icon *icon);
|
||||
virtual int file_browser_load_directory(const char *directory, char *filename, dirent ***pfiles, Fl_File_Sort_F *sort);
|
||||
};
|
||||
|
||||
#endif // FL_WINAPI_SYSTEM_DRIVER_H
|
||||
|
@ -22,6 +22,8 @@
|
||||
#include <FL/Fl.H>
|
||||
#include <FL/fl_utf8.h>
|
||||
#include <FL/filename.H>
|
||||
#include <FL/Fl_File_Browser.H>
|
||||
#include <FL/Fl_File_Icon.H>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <windows.h>
|
||||
@ -30,6 +32,15 @@
|
||||
#include <process.h>
|
||||
#include <locale.h>
|
||||
#include "../../flstring.h"
|
||||
#include <direct.h>
|
||||
// Apparently Borland C++ defines DIRECTORY in <direct.h>, which
|
||||
// interfers with the Fl_File_Icon enumeration of the same name.
|
||||
# ifdef DIRECTORY
|
||||
# undef DIRECTORY
|
||||
# endif // DIRECTORY
|
||||
#ifdef __CYGWIN__
|
||||
# include <mntent.h>
|
||||
#endif
|
||||
|
||||
inline int isdirsep(char c) { return c == '/' || c == '\\'; }
|
||||
|
||||
@ -665,6 +676,54 @@ int Fl_WinAPI_System_Driver::open_uri(const char *uri, char *msg, int msglen)
|
||||
return (int)(ShellExecute(HWND_DESKTOP, "open", uri, NULL, NULL, SW_SHOW) > (void *)32);
|
||||
}
|
||||
|
||||
int Fl_WinAPI_System_Driver::file_browser_load_filesystem(Fl_File_Browser *browser, char *filename, Fl_File_Icon *icon)
|
||||
{
|
||||
int num_files = 0;
|
||||
# ifdef __CYGWIN__
|
||||
//
|
||||
// Cygwin provides an implementation of setmntent() to get the list
|
||||
// of available drives...
|
||||
//
|
||||
FILE *m = setmntent("/-not-used-", "r");
|
||||
struct mntent *p;
|
||||
while ((p = getmntent (m)) != NULL) {
|
||||
browser->add(p->mnt_dir, icon);
|
||||
num_files ++;
|
||||
}
|
||||
endmntent(m);
|
||||
# else
|
||||
//
|
||||
// Normal WIN32 code uses drive bits...
|
||||
//
|
||||
DWORD drives; // Drive available bits
|
||||
drives = GetLogicalDrives();
|
||||
for (int i = 'A'; i <= 'Z'; i ++, drives >>= 1)
|
||||
if (drives & 1)
|
||||
{
|
||||
sprintf(filename, "%c:/", i);
|
||||
if (i < 'C') // see also: GetDriveType and GetVolumeInformation in WIN32
|
||||
browser->add(filename, icon);
|
||||
else
|
||||
browser->add(filename, icon);
|
||||
num_files ++;
|
||||
}
|
||||
# endif // __CYGWIN__
|
||||
return num_files;
|
||||
}
|
||||
|
||||
int Fl_WinAPI_System_Driver::file_browser_load_directory(const char *directory, char *filename, dirent ***pfiles,
|
||||
Fl_File_Sort_F *sort)
|
||||
{
|
||||
strlcpy(filename, directory, sizeof(filename));
|
||||
int i = (int) (strlen(filename) - 1);
|
||||
if (i == 2 && filename[1] == ':' &&
|
||||
(filename[2] == '/' || filename[2] == '\\'))
|
||||
filename[2] = '/';
|
||||
else if (filename[i] != '/' && filename[i] != '\\')
|
||||
strlcat(filename, "/", sizeof(filename));
|
||||
return filename_list(filename, pfiles, sort);
|
||||
}
|
||||
|
||||
//
|
||||
// End of "$Id$".
|
||||
//
|
||||
|
Loading…
x
Reference in New Issue
Block a user