diff --git a/desktop/meson.build b/desktop/meson.build index e913387d0f..ab59ec23d3 100644 --- a/desktop/meson.build +++ b/desktop/meson.build @@ -5,7 +5,7 @@ desktop_conf.set('GIMP_COMMAND', gimp_command) desktop_conf.set('GIMP_VERSION', gimp_version) desktop_conf.set('GIMP_APP_VERSION', gimp_app_version) desktop_conf.set('GIMP_DESKTOP_NAME', gimp_desktop_name) -desktop_conf.set('MIME_TYPES', ';'.join(MIMEtypes)) +desktop_conf.set('MIME_TYPES', 'image/x-xcf;' + MIMEtypes_dep.get_variable('MIMEtypes')) desktop_conf.set('BUG_REPORT_URL', bug_report_url) desktopfilein = configure_file( diff --git a/meson.build b/meson.build index 9e2b03d0f1..50c72da673 100644 --- a/meson.build +++ b/meson.build @@ -742,44 +742,12 @@ have_doc_shooter= x11_target ################################################################################ # Plugins (optional dependencies) -# The list of MIME types that are supported by plug-ins -MIMEtypes = [ - 'image/bmp', - 'image/g3fax', - 'image/gif', - 'image/svg+xml', - 'image/x-compressed-xcf', - 'image/x-fits', - 'image/x-gimp-gbr', - 'image/x-gimp-gih', - 'image/x-gimp-pat', - 'image/x-pcx', - 'image/x-portable-anymap', - 'image/x-portable-bitmap', - 'image/x-portable-graymap', - 'image/x-portable-pixmap', - 'image/x-psd', - 'image/x-sgi', - 'image/x-sun-raster', - 'image/x-tga', - 'image/x-xbitmap', - 'image/x-xcf', - 'image/x-xwindowdump', -] - - - libtiff_minver = '4.0.0' libtiff = dependency('libtiff-4', version: '>=' + libtiff_minver) -MIMEtypes += 'image/tiff' - libjpeg = dependency('libjpeg') -MIMEtypes += 'image/jpeg' - zlib = dependency('zlib') -MIMEtypes += 'image/x-psp' # Compiler-provided headers can't be found in crossroads environment if not meson.is_cross_build() @@ -793,15 +761,12 @@ liblzma = dependency('liblzma', version: '>='+liblzma_minver) ghostscript = cc.find_library('gs', required: get_option('ghostscript')) -if ghostscript.found() - MIMEtypes += 'application/postscript' -else +if not ghostscript.found() ghostscript = disabler() endif libpng_minver = '1.6.25' libpng = dependency('libpng', version: '>='+libpng_minver) -MIMEtypes += [ 'image/png', 'image/x-icon'] libmng = dependency('libmng', required: get_option('mng')) @@ -821,14 +786,8 @@ endif libaa = cc.find_library('aa', required: get_option('aa')) libxpm = dependency('xpm', required: get_option('xpm')) -if libxpm.found() - MIMEtypes += 'image/x-xpixmap' -endif have_qoi = cc.has_header('qoi.h') -if have_qoi - MIMEtypes += 'image/qoi' -endif libiff = dependency('libiff', required: get_option('ilbm')) libilbm = dependency('libilbm', required: get_option('ilbm')) @@ -837,17 +796,11 @@ if libiff.found() and libilbm.found() else have_ilbm = cc.has_header('libilbm/ilbm.h', required: get_option('ilbm')) endif -if have_ilbm - MIMEtypes += 'image/x-ilbm' -endif openexr_minver = '1.6.1' openexr = dependency('OpenEXR', version: '>='+openexr_minver, required: get_option('openexr') ) -if openexr.found() - MIMEtypes += 'image/x-exr' -endif webp_minver = '0.6.0' webp_libs = [ @@ -860,13 +813,6 @@ foreach lib : webp_libs webp_found = webp_found and lib.found() endforeach -if webp_found - MIMEtypes += [ - 'image/x-webp', - 'image/webp' - ] -endif - libheif_minver = '1.15.1' libheif = dependency('libheif', version: '>='+libheif_minver, required: get_option('heif') @@ -960,17 +906,6 @@ if have_heif if not can_import_heic and not can_import_avif have_heif = false endif - - if have_heif - # Listing support for both HEIC and AVIF if we build with HEIF support, - # because codecs can be added at any time later and we won't be able to edit - # the desktop file once it's installed. See discussion in #9080. - MIMEtypes += [ - 'image/heif', - 'image/heic', - 'image/avif' - ] - endif endif have_vala = add_languages('vala', required: get_option('vala'), native: false) @@ -1014,24 +949,15 @@ cairopdf = dependency('cairo-pdf', version: '>='+cairopdf_minver, required: get_option('cairo-pdf') ) -# PDF import support is a granted feature. -MIMEtypes += 'application/pdf' - wmf_minver = '0.2.8' wmf = dependency('libwmf', version: '>='+wmf_minver, required: get_option('wmf') ) -if wmf.found() - MIMEtypes += 'image/x-wmf' -endif openjpeg_minver = '2.1.0' openjpeg = dependency('libopenjp2', version: '>='+openjpeg_minver, required: get_option('jpeg2000') ) -if openjpeg.found() - MIMEtypes += [ 'image/jp2', 'image/jpeg2000', 'image/jpx', ] -endif jpegxl_minver = '0.7.0' libjxl = dependency('libjxl', @@ -1042,14 +968,8 @@ libjxl_threads = dependency('libjxl_threads', version: '>='+jpegxl_minver, required: get_option('jpeg-xl') ) -if libjxl.found() and libjxl_threads.found() - MIMEtypes += 'image/jxl' -endif xmc = dependency('xcursor', required: get_option('xcursor')) -if xmc.found() - MIMEtypes += 'image/x-xcursor' -endif alsa = dependency('alsa', version: '>=1.0.0', required: get_option('alsa')) @@ -1093,9 +1013,6 @@ endif conf.set('HAVE_DX_DINPUT', directx.found()) cfitsio_dep = dependency('cfitsio', required: get_option('fits')) -if cfitsio_dep.found() - MIMEtypes += 'image/fits' -endif ################################################################################ @@ -1176,8 +1093,6 @@ if not pygobject_found error('PyGObject is required.') endif -MIMEtypes += 'image/openraster' - ## Javascript gjs = find_program('gjs', required: false) @@ -1930,9 +1845,8 @@ subdir('po-python') subdir('po-script-fu') subdir('po-tags') subdir('po-tips') -# Data / Desktop / xml files +# Data / xml files subdir('data') -subdir('desktop') subdir('etc') subdir('menus') subdir('themes') @@ -1957,6 +1871,9 @@ subdir('plug-ins') subdir('app') subdir('app-tools') +# Desktop files +subdir('desktop') + ################################################################################ # Make GIMP runnable without being installed for unit-testing or as a build # tool. diff --git a/plug-ins/generate_mime_ext.py b/plug-ins/generate_mime_ext.py new file mode 100644 index 0000000000..bd1325d9fb --- /dev/null +++ b/plug-ins/generate_mime_ext.py @@ -0,0 +1,54 @@ +#!/usr/bin/env python3 +import sys +import os +import re + +types_associations_list = set() + +#Read file loading plug-ins sourcecode +source_files = sys.argv[3:] +for source_file in source_files: + try: + with open(source_file, 'r', encoding='utf-8') as f: + content = f.read() + except Exception as e: + sys.stderr.write(f"(WARNING): Unable to open file {source_file}: {e}\n") + continue + + #Parse MIME types or extensions declared in the sourcecode + mode = sys.argv[1] + if mode == "--mime": + function_suffix = 'set_mime_types' + elif mode == "--association": + function_suffix = 'set_extensions' + source_file_ext = os.path.splitext(source_file)[1].lower() + if source_file_ext == '.c': + if "LOAD_PROC" not in content and "load_procedure" not in content: + continue + regex = (fr'gimp_file_procedure_{function_suffix}\s*' + fr'\(\s*GIMP_FILE_PROCEDURE\s*\(\s*procedure\s*\)\s*,\s*"([^"]+)"') + elif source_file_ext == '.py': + if "LoadProcedure" not in content: + continue + regex = fr'procedure\.{function_suffix}\s*\(\s*"([^"]+)"\s*\)' + else: + continue + for match in re.findall(regex, content, re.DOTALL): + #(Take care of extensions separated by commas) + for mime_extension in match.split(','): + trimmed = mime_extension.strip() + if trimmed: + types_associations_list.add(trimmed) + +if mode == "--mime": + #Output string with the parsed MIME types + print(";".join(sorted(types_associations_list))) +elif mode == "--association": + #Create list with the parsed extensions + output_file = sys.argv[2] + try: + with open(output_file, 'w', encoding='utf-8') as outf: + outf.writelines(f"{assoc}\n" for assoc in sorted(types_associations_list)) + except Exception as e: + sys.stderr.write(f"(ERROR): When writing output file {output_file}: {e}\n") + sys.exit(1) diff --git a/plug-ins/meson.build b/plug-ins/meson.build index 73174556dc..98f402f546 100644 --- a/plug-ins/meson.build +++ b/plug-ins/meson.build @@ -1,13 +1,11 @@ subdir('common') -if get_option('windows-installer') or get_option('ms-store') - all_plugins_sources = [] - foreach plugin : common_plugins_list - if plugin.get('name').startswith('file-') and plugin.get('name') != 'file-desktop-link' and plugin.get('name') != 'file-lnk' - all_plugins_sources += [ meson.current_source_dir() / 'common' / plugin.get('name') + '.c' ] - endif - endforeach -endif +all_plugins_sources = [] +foreach plugin : common_plugins_list + if plugin.get('name').startswith('file-') and plugin.get('name') != 'file-desktop-link' and plugin.get('name') != 'file-lnk' + all_plugins_sources += [ meson.current_source_dir() / 'common' / plugin.get('name') + '.c' ] + endif +endforeach complex_plugins_list = [ @@ -72,41 +70,47 @@ endif foreach plugin : complex_plugins_list subdir(plugin.get('name')) - if get_option('windows-installer') or get_option('ms-store') - foreach sourcecode : plugin_sourcecode - if plugin.get('name').startswith('file-') - #.ico files are handled in a special way by installer and msix scripts - if plugin.get('name') == 'file-ico' and platform_windows - continue - else - all_plugins_sources += [ meson.current_source_dir() / plugin.get('name') / sourcecode ] - endif + foreach sourcecode : plugin_sourcecode + if plugin.get('name').startswith('file-') + #.ico files are handled in a special way by installer and msix scripts + if plugin.get('name') == 'file-ico' and platform_windows + continue + else + all_plugins_sources += [ meson.current_source_dir() / plugin.get('name') / sourcecode ] endif - endforeach - endif + endif + endforeach endforeach subdir('python') -if get_option('windows-installer') or get_option('ms-store') - foreach plugin : python_plugins - if plugin.get('name').startswith('file-') - all_plugins_sources += [ meson.current_source_dir() / 'python' / plugin.get('name') + '.py' ] - endif - endforeach -endif +foreach plugin : python_plugins + if plugin.get('name').startswith('file-') + all_plugins_sources += [ meson.current_source_dir() / 'python' / plugin.get('name') + '.py' ] + endif +endforeach +#Dynamically created list of supported files with the plugins lists above +MIMEtypes_output = run_command( + python, + meson.current_source_dir() / 'generate_mime_ext.py', + '--mime', + meson.current_build_dir() / 'file_mimetypes.list', + all_plugins_sources +).stdout().strip() +MIMEtypes_dep = declare_dependency(variables : {'MIMEtypes': MIMEtypes_output}) + if get_option('windows-installer') or get_option('ms-store') - #List of file associations dynamically created with the plugins lists above custom_target('file_associations', input : all_plugins_sources, output : 'file_associations.list', command : [ python, - meson.current_source_dir() / 'generate_associations.py', - '@OUTPUT@' + meson.current_source_dir() / 'generate_mime_ext.py', + '--association', + '@OUTPUT@', ] + all_plugins_sources, build_by_default: true )