diff options
| author | ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com> | 2022-03-04 15:40:29 +0100 |
|---|---|---|
| committer | ManoloFLTK <41016272+ManoloFLTK@users.noreply.github.com> | 2022-03-04 15:41:00 +0100 |
| commit | 3718effc431f5622a23c55b254153efdfe4e72c4 (patch) | |
| tree | d8a805870c6a3785022e2f52f0c3715410e29a37 /src/drivers/X11 | |
| parent | a773fdc44bfb818f1830e9e48ba765881e68c942 (diff) | |
Add the Wayland platform to FLTK 1.4
Diffstat (limited to 'src/drivers/X11')
| -rw-r--r-- | src/drivers/X11/Fl_X11_System_Driver.H | 30 | ||||
| -rw-r--r-- | src/drivers/X11/Fl_X11_System_Driver.cxx | 554 |
2 files changed, 3 insertions, 581 deletions
diff --git a/src/drivers/X11/Fl_X11_System_Driver.H b/src/drivers/X11/Fl_X11_System_Driver.H index e39f40706..a5347d74d 100644 --- a/src/drivers/X11/Fl_X11_System_Driver.H +++ b/src/drivers/X11/Fl_X11_System_Driver.H @@ -19,47 +19,23 @@ #define FL_X11_SYSTEM_DRIVER_H #include <config.h> -#include "../Posix/Fl_Posix_System_Driver.H" +#include "../Unix/Fl_Unix_System_Driver.H" -class Fl_X11_System_Driver : public Fl_Posix_System_Driver { +class Fl_X11_System_Driver : public Fl_Unix_System_Driver { public: - Fl_X11_System_Driver() : Fl_Posix_System_Driver() { + Fl_X11_System_Driver() : Fl_Unix_System_Driver() { // X11 system driver does not use a key table key_table = NULL; key_table_size = 0; } 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); - virtual int clocale_snprintf(char *output, size_t output_size, const char *format, va_list args); - virtual int clocale_sscanf(const char *input, 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 **), - char *errmsg=NULL, int errmsg_sz=0); 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, int lname, 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 int utf8locale(); - // this one is in Fl_own_colormap.cxx virtual void own_colormap(); - // this one is in Fl_x.cxx - virtual const char *filename_name(const char *buf); - virtual void add_fd(int fd, int when, Fl_FD_Handler cb, void* = 0); - virtual void add_fd(int fd, Fl_FD_Handler cb, void* = 0); - virtual void remove_fd(int, int when); - virtual void remove_fd(int); - virtual double wait(double time_to_wait); - virtual int ready(); // 2 additional virtual members virtual int poll_or_select(); virtual int poll_or_select_with_delay(double time_to_wait); diff --git a/src/drivers/X11/Fl_X11_System_Driver.cxx b/src/drivers/X11/Fl_X11_System_Driver.cxx index e62fdf8b8..40a98d32e 100644 --- a/src/drivers/X11/Fl_X11_System_Driver.cxx +++ b/src/drivers/X11/Fl_X11_System_Driver.cxx @@ -80,58 +80,6 @@ Fl_System_Driver *Fl_System_Driver::newSystemDriver() return new Fl_X11_System_Driver(); } -#if defined(__linux__) && defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 700 -static locale_t c_locale = NULL; -#endif - - -int Fl_X11_System_Driver::clocale_printf(FILE *output, const char *format, va_list args) { -#if defined(__linux__) && defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 700 - if (!c_locale) - c_locale = newlocale(LC_NUMERIC_MASK, "C", duplocale(LC_GLOBAL_LOCALE)); - locale_t previous_locale = uselocale(c_locale); - int retval = vfprintf(output, format, args); - uselocale(previous_locale); -#else - char *saved_locale = setlocale(LC_NUMERIC, NULL); - setlocale(LC_NUMERIC, "C"); - int retval = vfprintf(output, format, args); - setlocale(LC_NUMERIC, saved_locale); -#endif - return retval; -} - -int Fl_X11_System_Driver::clocale_snprintf(char *output, size_t output_size, const char *format, va_list args) { -#if defined(__linux__) && defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 700 - if (!c_locale) - c_locale = newlocale(LC_NUMERIC_MASK, "C", duplocale(LC_GLOBAL_LOCALE)); - locale_t previous_locale = uselocale(c_locale); - int retval = vsnprintf(output, output_size, format, args); - uselocale(previous_locale); -#else - char *saved_locale = setlocale(LC_NUMERIC, NULL); - setlocale(LC_NUMERIC, "C"); - int retval = vsnprintf(output, output_size, format, args); - setlocale(LC_NUMERIC, saved_locale); -#endif - return retval; -} - -int Fl_X11_System_Driver::clocale_sscanf(const char *input, const char *format, va_list args) { -#if defined(__linux__) && defined(_XOPEN_SOURCE) && _XOPEN_SOURCE >= 700 - if (!c_locale) - c_locale = newlocale(LC_NUMERIC_MASK, "C", duplocale(LC_GLOBAL_LOCALE)); - locale_t previous_locale = uselocale(c_locale); - int retval = vsscanf(input, format, args); - uselocale(previous_locale); -#else - char *saved_locale = setlocale(LC_NUMERIC, NULL); - setlocale(LC_NUMERIC, "C"); - int retval = vsscanf(input, format, args); - setlocale(LC_NUMERIC, saved_locale); -#endif - return retval; -} // Find a program in the path... static char *path_find(const char *program, char *filename, int filesize) { @@ -166,376 +114,6 @@ static char *path_find(const char *program, char *filename, int filesize) { } -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, int lname, 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 (int i = 0, vp = (struct vmount *) list; i < res; ++i) { - name = (char *) vp + vp->vmt_data[VMT_STUB].vmt_off; - strlcpy(filename, name, lname); - // Skip the already added root filesystem - if (strcmp("/", filename) != 0) { - strlcat(filename, "/", lname); - 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 (int i = 0; i < res; ++i) { - strlcpy(filename, list[i].f_mntonname, lname); - // Skip the already added root filesystem - if (strcmp("/", filename) != 0) { - strlcat(filename, "/", lname); - 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 - - // Every Unix has a root filesystem '/'. - // This ensures that the user don't get an empty - // window after requesting filesystem list. - browser->add("/", icon); - num_files ++; - - // - // Open the file that contains a list of mounted filesystems... - // - // Note: this misses automounted filesystems on FreeBSD if absent from /etc/fstab - // - - 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; - if (strcmp("/", filename) == 0) - continue; // "/" was added before - - // Add a trailing slash (except for the root filesystem) - strlcat(filename, "/", lname); - - // printf("Fl_File_Browser::load() - adding \"%s\" to list...\n", filename); - browser->add(filename, icon); - num_files ++; - } - - fclose(mtab); - } -#endif // _AIX || ... - return num_files; -} - -void Fl_X11_System_Driver::newUUID(char *uuidBuffer) -{ - unsigned char b[16]; -#if HAVE_DLSYM && HAVE_DLFCN_H - typedef void (*gener_f_type)(uchar*); - static bool looked_for_uuid_generate = false; - static gener_f_type uuid_generate_f = NULL; - if (!looked_for_uuid_generate) { - looked_for_uuid_generate = true; - uuid_generate_f = (gener_f_type)Fl_Posix_System_Driver::dlopen_or_dlsym("libuuid", "uuid_generate"); - } - if (uuid_generate_f) { - uuid_generate_f(b); - } else -#endif - { - 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]); -} - -/* - Note: `prefs` can be NULL! - */ -char *Fl_X11_System_Driver::preference_rootnode(Fl_Preferences * /*prefs*/, - Fl_Preferences::Root root, - const char *vendor, - const char *application) -{ - static char *filename = 0L; - if (!filename) filename = (char*)::calloc(1, FL_PATH_MAX); - const char *home = ""; - int pref_type = root & Fl_Preferences::ROOT_MASK; - switch (pref_type) { - case Fl_Preferences::USER: - home = getenv("HOME"); - // make sure that $HOME is set to an existing directory - if ((home == NULL) || (home[0] == 0) || (::access(home, F_OK) == -1)) { - struct passwd *pw = getpwuid(getuid()); - if (pw) - home = pw->pw_dir; - } - if ((home == 0L) || (home[0] == 0) || (::access(home, F_OK) == -1)) - return NULL; - strlcpy(filename, home, FL_PATH_MAX); - if (filename[strlen(filename) - 1] != '/') - strlcat(filename, "/", FL_PATH_MAX); - strlcat(filename, ".fltk/", FL_PATH_MAX); - break; - case Fl_Preferences::SYSTEM: - strcpy(filename, "/etc/fltk/"); - break; - default: // MEMORY - filename[0] = '\0'; // empty string - break; - } - - // Make sure that the parameters are not NULL - if ( (vendor==NULL) || (vendor[0]==0) ) - vendor = "unknown"; - if ( (application==NULL) || (application[0]==0) ) - application = "unknown"; - - snprintf(filename + strlen(filename), FL_PATH_MAX - strlen(filename), - "%s/%s.prefs", vendor, application); - - // If this is not the USER path (i.e. SYSTEM or MEMORY), we are done - if ((pref_type) != Fl_Preferences::USER) - return filename; - - // If the legacy file exists, we are also done - if (::access(filename, F_OK)==0) - return filename; - - // This is USER mode, and there is no legacy file. Create an XDG conforming path. - // Check $XDG_CONFIG_HOME, and if it isn't set, default to $HOME/.config - const char *xdg = getenv("XDG_CONFIG_HOME"); - if (xdg==NULL) { - xdg = "~/.config"; - } - filename[0] = 0; - if (strncmp(xdg, "~/", 2)==0) { - strlcpy(filename, home, FL_PATH_MAX); - strlcat(filename, "/", FL_PATH_MAX); - strlcat(filename, xdg+2, FL_PATH_MAX); - } else if (strncmp(xdg, "$HOME/", 6)==0) { - strlcpy(filename, home, FL_PATH_MAX); - strlcat(filename, "/", FL_PATH_MAX); - strlcat(filename, xdg+6, FL_PATH_MAX); - } else if (strncmp(xdg, "${HOME}/", 8)==0) { - strlcpy(filename, home, FL_PATH_MAX); - strlcat(filename, "/", FL_PATH_MAX); - strlcat(filename, xdg+8, FL_PATH_MAX); - } else { - strlcpy(filename, xdg, FL_PATH_MAX); - } - strlcat(filename, "/", FL_PATH_MAX); - strlcat(filename, vendor, FL_PATH_MAX); - strlcat(filename, "/", FL_PATH_MAX); - strlcat(filename, application, FL_PATH_MAX); - strlcat(filename, ".prefs", FL_PATH_MAX); - - return filename; -} - void Fl_X11_System_Driver::display_arg(const char *arg) { Fl::display(arg); } @@ -545,112 +123,6 @@ int Fl_X11_System_Driver::XParseGeometry(const char* string, int* x, int* y, return ::XParseGeometry(string, x, y, width, height); } -// -// Needs some docs -// Returns -1 on error, errmsg will contain OS error if non-NULL. -// -int Fl_X11_System_Driver::filename_list(const char *d, - dirent ***list, - int (*sort)(struct dirent **, struct dirent **), - char *errmsg, int errmsg_sz) { - int dirlen; - char *dirloc; - - if (errmsg && errmsg_sz>0) errmsg[0] = '\0'; - - // 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. Note it updates errmsg on errors. - int n = fl_scandir(dirloc, list, 0, sort, errmsg, errmsg_sz); -#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); - - if (n==-1) { - // Don't write to errmsg if FLTK's fl_scandir() already set it. - // If OS's scandir() was used (HAVE_SCANDIR), we return its error in errmsg here.. -#ifdef HAVE_SCANDIR - if (errmsg) fl_snprintf(errmsg, errmsg_sz, "%s", strerror(errno)); -#endif - return -1; - } - - // 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; i<n; i++) { - int newlen; - dirent *de = (*list)[i]; - int len = strlen(de->d_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; -} - -int Fl_X11_System_Driver::utf8locale() { - static int ret = 2; - if (ret == 2) { - char* s; - ret = 1; /* assume UTF-8 if no locale */ - if (((s = getenv("LC_CTYPE")) && *s) || - ((s = getenv("LC_ALL")) && *s) || - ((s = getenv("LANG")) && *s)) { - ret = (strstr(s,"utf") || strstr(s,"UTF")); - } - } - return ret; -} - #if !defined(FL_DOXYGEN) @@ -700,30 +172,4 @@ void Fl_X11_System_Driver::own_colormap() { #endif // USE_COLORMAP } -int Fl_X11_System_Driver::ready() { - Fl_Timeout::elapse_timeouts(); - if (Fl_Timeout::time_to_wait(1.0) <= 0.0) return 1; - return this->poll_or_select(); -} - -double Fl_X11_System_Driver::wait(double 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); - Fl::flush(); - return ret; - } else { - // do flush first so that user sees the display: - Fl::flush(); - if (Fl::idle) // 'idle' may have been set within flush() - time_to_wait = 0.0; - else { - 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); - } -} - #endif // !defined(FL_DOXYGEN) |
