For those of you who just tuned in, a short recap:
GContentTypeis a string.
- The contents of this string are platform-dependent:
- On *nix it is a
MIME/type, such as
- On Windows it is a file extension, such as
- On MacOS it is a Uniform Type Identifier, such as
- On *nix it is a
- The idea was that these are the things that various platforms use to tie applications to files (i.e. what happens when the user doubleclicks a file, for example).
- The problem is that most applications are written with *nix (or, more specifically, Gnome) in mind, and tend to use
MIME/types. They might also want
GContentTypeon *nix is said to be
MIME/type, but the API is written in such a way that there's a function to get
GContentType, which is implemented as
g_strdup()on *nix, but has other platforms do all kinds of contortions) and use the APIs to get it from
GContentType, which are not trivial to implement.
- Windows native support for
MIME/types is abysmal and is not worth mentioning.
- I'm not sure what the situation with MacOS is, but there were issues in that area too (though they seem to be fixed).
- Luckily, the mechanism that handles
MIME/types on *nix, which is
shared-mime-info, is not specific to *nix. It's just a bunch of xml files, some code to use them efficiently, and a convention as to where applications should install their
mime-infoadditions. This can be made to work on Windows.
- The problem with using it on Windows is that Windows continues to use file extensions for everything, and if Glib uses
MIME/types instead, we'll have incompatibilities and information loss (basically, you might not be able to create a
GContentType-that-is-MIME/typefrom file extension and then convert it back to the same file extension you started with, as the mapping is not straightforward).
- The solution to that was to use a rare feature of
MIME/typespecs (RFC 2045 and 2046). I'm too lazy to read the spec again to figure out whether a technical term for this exists, i'm just calling it extended MIME/types. eM/ts have the form of
MIME/type; foo=bar baz="blue" zool=over, i.e. it allows arbitrary parameters to be appended to the type itself.
- We can use this to append
ext=.footo denote that
GContentType-that-is-MIME/typewas created for a file that has
.fooextension. This information will remain with the
GContentTypefor as long as it lives, and will be available in case it is later used to, for example, find the handler for that type (since on Windows that requires using a file extension, not a
- Additionally it was proposed to generate
*.foofiles for which we've been unable to guess the
application/x-extension-fooare mostly orthogonal, although it seems prudent to avoid redundant cases like
- Theoretically, this can be extended to store MacOS UTI strings, i.e. appending
I implemented all of this, and adjusted the testsuite to make it pass (the new logic is, IMO, more correct than the old one, so the adjustments to the testsuite is less "made the tests fit the code bugs" and more "fixed the code and fixed broken tests").
To market this MR better, i developed it on my Debian machine, meaning that this is not a W32-specific code dump. Most changes will affect the *nix platform, and the testsuite passes there.
I'm open to suggestions for new tests could be added to cover the new functionality, and ideas on which of the APIs should be made public (for all platforms or for some of them).
This code should not break compliant Glib programs. Non-compliant Glib programs are those that exploited the knowledge of implementation details, i.e. interpreted
GContentType strings literally as file extensions or
MIME/types, without going through any APIs. This also includes the programs that used
strcmp() to compare literal values of
GContentTypes instead of using the appropriate APIs.
I didn't test anything on MacOS, and i'm not sure whether it compiles anymore after these changes (hopefully, it does).
This code is made to be as compatible as possible with Windows code in places where it is feasible. For example, it's easy to tell apart file extensions and
MIME/type strings, since the former start with a
. while the latter do not, so Windows part of the code won't try to pass extensions to
This code includes a few changes to improve compatibility with MSVC (the result of a review by fanc some years ago), though i didn't verify that it still compiles with MSVC.