diff -Nru appstream-generator-0.7.3/contrib/girwrap/APILookupGio.txt appstream-generator-0.7.4/contrib/girwrap/APILookupGio.txt --- appstream-generator-0.7.3/contrib/girwrap/APILookupGio.txt 2018-04-26 16:56:59.000000000 +0000 +++ appstream-generator-0.7.4/contrib/girwrap/APILookupGio.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,557 +0,0 @@ -# -# Copyright (C) Mike Wey -# -# Licensed under the GNU Lesser General Public License Version 3 -# -# This library is free software: you can redistribute it and/or modify -# it under the terms of the GNU Lesser General Public License as published by -# the Free Software Foundation, either version 3 of the license, or -# (at your option) any later version. -# -# This software is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with this library. If not, see . -# - -# must start with wrap -wrap: gio -file: Gio-2.0.gir - -struct: Application -code: start - /** - * The ::command-line signal is emitted on the primary instance when - * a commandline is not handled locally. See g_application_run() and - * the #GApplicationCommandLine documentation for more information. - * - * Params: - * commandLine = a #GApplicationCommandLine representing the - * passed commandline - * - * Return: An integer that is set as the exit status for the calling - * process. See g_application_command_line_set_exit_status(). - */ - gulong addOnCommandLine(int delegate(Scoped!ApplicationCommandLine, Application) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) - { - return Signals.connect(this, "command-line", dlg, connectFlags ^ ConnectFlags.SWAPPED); - } - - /** - * The ::open signal is emitted on the primary instance when there are - * files to open. See g_application_open() for more information. - * - * Params: - * files = an array of #GFiles - * nFiles = the length of @files - * hint = a hint provided by the calling instance - */ - gulong addOnOpen(void delegate(FileIF[], string, Application) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0) - { - return Signals.connect(this, "open", delegate void (GFile* gfiles, int nFiles, string hint, Application app){ - FileIF[] files = new FileIF[nFiles]; - for(int i = 0; i < nFiles; i++) - { - files[i] = ObjectG.getDObject!FileIF((cast(GFile**)gfiles)[i]); - } - dlg(files, hint, app); - }, connectFlags ^ ConnectFlags.SWAPPED); - } -code: end - -struct: BufferedInputStream -noCode: peek_buffer -code: start - /** - * Returns the buffer with the currently available bytes. The returned - * buffer must not be modified and will become invalid when reading from - * the stream or filling the buffer. - * - * Params: - * count = a #gsize to get the number of bytes available in the buffer - * - * Return: read-only buffer - */ - public ubyte[] peekBuffer() - { - size_t count; - - auto p = g_buffered_input_stream_peek_buffer(gBufferedInputStream, &count); - - return (cast(ubyte*)p)[0 .. count]; - } -code: end - -struct: DataInputStream -noCode: read_byte - -struct: DBusActionGroup -import: glib.ConstructionException -code: start - /** - * See_Also: get(). - */ - this(DBusConnection connection, string busName, string objectPath) - { - auto p = g_dbus_action_group_get((connection is null) ? null : connection.getDBusConnectionStruct(), Str.toStringz(busName), Str.toStringz(objectPath)); - - if(p is null) - { - throw new ConstructionException("null returned by g_dbus_action_group_get"); - } - this(cast(GDBusActionGroup*) p, true); - } -code: end - -struct: DBusAnnotationInfo -import: glib.Str -noCode: lookup -code: start - /** - * Looks up the value of an annotation. - * - * The cost of this function is O(n) in number of annotations. - * - * Params: - * annotations = A %NULL-terminated array of annotations or %NULL. - * name = The name of the annotation to look up. - * - * Return: The value or %NULL if not found. Do not free, it is owned by @annotations. - * - * Since: 2.26 - */ - public static string lookup(DBusAnnotationInfo[] annotations, string name) - { - GDBusAnnotationInfo*[] annotationsArray = new GDBusAnnotationInfo*[annotations.length+1]; - for ( int i = 0; i < annotations.length ; i++ ) - { - annotationsArray[i] = annotations[i].getDBusAnnotationInfoStruct(); - } - annotationsArray[$-1] = null; - - return Str.toString(g_dbus_annotation_info_lookup(annotationsArray.ptr, Str.toStringz(name))); - } -code: end - -struct: DBusConnection -alias: new newConnection -noCode: new_finish -noCode: new_for_address_finish -code: start - /** - * Finishes an operation started with g_dbus_connection_new(). - * - * Params: - * res = A GAsyncResult obtained from the GAsyncReadyCallback - * passed to g_dbus_connection_new(). - * address = If true finish an address. - * - * Throws: GException on failure. - * Throws: ConstructionException GTK+ fails to create the object. - * - * Since: 2.26 - */ - public this (AsyncResultIF res, bool address = false) - { - GError* err = null; - GDBusConnection* p; - - if ( address ) - { - p = g_dbus_connection_new_for_address_finish((res is null) ? null : res.getAsyncResultStruct(), &err); - } - else - { - p = g_dbus_connection_new_finish((res is null) ? null : res.getAsyncResultStruct(), &err); - } - - if (err !is null) - { - throw new GException( new ErrorG(err) ); - } - - if(p is null) - { - throw new ConstructionException("null returned by g_dbus_connection_new_finish((res is null) ? null : res.getAsyncResultStruct(), &err)"); - } - this(p, true); - } -code: end - -struct: DBusMenuModel -import: glib.ConstructionException -code: start - /** - * See_Also: get(). - */ - this(DBusConnection connection, string busName, string objectPath) - { - auto p = g_dbus_menu_model_get((connection is null) ? null : connection.getDBusConnectionStruct(), Str.toStringz(busName), Str.toStringz(objectPath)); - - if(p is null) - { - throw new ConstructionException("null returned by g_dbus_menu_model_get"); - } - - this(cast(GDBusMenuModel*) p, true); - } -code: end - -struct: DBusObjectManagerClient -alias: new newObjectManagerClient -noCode: new_finish -noCode: new_for_bus_finish -code: start - /** - * Finishes an operation started with g_dbus_object_manager_client_new(). - * - * Params: - * res = A GAsyncResult obtained from the GAsyncReadyCallback passed to the DBusObjectManager constructor. - * forBus = If true finish an address. - * - * Throws: GException on failure. - * Throws: ConstructionException GTK+ fails to create the object. - * - * Since: 2.30 - */ - public this (AsyncResultIF res, bool forBus = false) - { - GError* err = null; - GDBusObjectManager* p; - - if ( forBus ) - { - p = g_dbus_object_manager_client_new_for_bus_finish((res is null) ? null : res.getAsyncResultStruct(), &err); - } - else - { - p = g_dbus_object_manager_client_new_finish((res is null) ? null : res.getAsyncResultStruct(), &err); - } - - if (err !is null) - { - throw new GException( new ErrorG(err) ); - } - - if(p is null) - { - throw new ConstructionException("null returned by g_dbus_object_manager_client_new_finish((res is null) ? null : res.getAsyncResultStruct(), &err)"); - } - this(cast(GDBusObjectManagerClient*) p, true); - } -code: end - -struct: DBusProxy -alias: new newProxy -noCode: new_finish -noCode: new_for_bus_finish -code: start - /** - * Finishes creating a GDBusProxy. - * - * Params: - * res = A GAsyncResult obtained from the GAsyncReadyCallback - * function passed to g_dbus_proxy_new(). - * forBus = If true finish an address. - * - * Throws: GException on failure. - * Throws: ConstructionException GTK+ fails to create the object. - * - * Since: 2.26 - */ - public this (AsyncResultIF res, bool forBus = false) - { - GError* err = null; - GDBusProxy* p; - - if ( forBus ) - { - p = g_dbus_proxy_new_for_bus_finish((res is null) ? null : res.getAsyncResultStruct(), &err); - } - else - { - p = g_dbus_proxy_new_finish((res is null) ? null : res.getAsyncResultStruct(), &err); - } - - if (err !is null) - { - throw new GException( new ErrorG(err) ); - } - - if(p is null) - { - throw new ConstructionException("null returned by g_dbus_proxy_new_finish((res is null) ? null : res.getAsyncResultStruct(), &err)"); - } - this(p, true); - } -code: end - -version !Windows: start - struct: DesktopAppInfo - noCode: new_from_filename - code: start - /** - * Creates a new #GDesktopAppInfo. - * - * Params: - * filename = the path of a desktop file, in the GLib filename encoding - * - * Return: a new #GDesktopAppInfo or %NULL on error. - * - * Throws: ConstructionException GTK+ fails to create the object. - */ - public static DesktopAppInfo createFromFilename(string filename) - { - auto p = g_desktop_app_info_new_from_filename(Str.toStringz(filename)); - - if(p is null) - { - throw new ConstructionException("null returned by g_desktop_app_info_new_from_filename"); - } - - return new DesktopAppInfo(p, true); - } - code: end -version: end - -struct: FileAttributeInfoList -array: infos n_infos - -struct: InetAddress -noCode: new_any -noCode: new_loopback -code: start - /** - * Creates a InetAddress for the "any" address (unassigned/"don't - * care") for family. - * - * Params: - * family = the address family - * loopback = If true create an InetAddress for the loopback address. - * - * Throws: ConstructionException GTK+ fails to create the object. - * - * Since: 2.22 - */ - public this (GSocketFamily family, bool loopback = false) - { - GInetAddress* p; - - if ( loopback ) - { - p = g_inet_address_new_loopback(family); - } - else - { - p = g_inet_address_new_any(family); - } - - if(p is null) - { - throw new ConstructionException("null returned by g_inet_address_new_any(family)"); - } - this(p, true); - } -code: end - -struct: NoExternal -noCode: true -noExternal: true - -struct: IOModule -move: load NoExternal -move: unload NoExternal -move: query NoExternal - -struct: MenuItem -noCode: new_section -noCode: new_submenu - -struct: OutputStream -out: vprintf error - -struct: PollableUtils -namespace: - -struct: Resource -alias: _register register -alias: _unregister unregister - -struct: SimpleAsyncResult -noCode: new_take_error - -struct: SimpleProxyResolver -array: new ignore_hosts -array: set_ignore_hosts ignore_hosts - -struct: Socket -ref: receive buffer -ref: receive_from buffer -out: receive_message messages -out: receive_message num_messages - -struct: SubprocessLauncher -array: set_environ env - -struct: ThemedIcon -noCode: new - -struct: TlsPassword -out: get_value length -array: get_value Return length -array: set_value value length -array: set_value_full value length - -version !Windows: start - struct: UnixMountEntry - class: UnixMountEntry - - struct: UnixSocketAddress - noCode: new_abstract -version: end - -struct: VolumeMonitor -import: glib.ConstructionException -noCode: get -code: start - /** - * Gets the volume monitor used by gio. - * - * Return: a reference to the #GVolumeMonitor used by gio. Call - * g_object_unref() when done with it. - */ - public this() - { - auto p = g_volume_monitor_get(); - - if(p is null) - { - throw new ConstructionException("g_volume_monitor_get()"); - } - - this(cast(GVolumeMonitor*) p, true); - } -code: end - -struct: - -move: bus_get DBusConnection get -move: bus_get_finish DBusConnection get_finish -move: bus_get_sync DBusConnection get_sync - -move: bus_own_name DBusNames own_name -move: bus_own_name_on_connection DBusNames own_name_on_connection -move: bus_own_name_on_connection_with_closures DBusNames own_name_on_connection_with_closures -move: bus_own_name_with_closures DBusNames own_name_with_closures -move: bus_unown_name DBusNames unown_name -move: bus_unwatch_name DBusNames unwatch_name -move: bus_watch_name DBusNames watch_name -move: bus_watch_name_on_connection DBusNames watch_name_on_connection -move: bus_watch_name_on_connection_with_closures DBusNames watch_name_on_connection_with_closures -move: bus_watch_name_with_closures DBusNames watch_name_with_closures - -move: content_type_can_be_executable ContentType can_be_executable -move: content_type_equals ContentType equals -move: content_type_from_mime_type ContentType from_mime_type -move: content_type_get_description ContentType get_description -move: content_type_get_generic_icon_name ContentType get_generic_icon_name -move: content_type_get_icon ContentType get_icon -move: content_type_get_mime_type ContentType get_mime_type -move: content_type_get_symbolic_icon ContentType get_symbolic_icon -move: content_type_guess ContentType type_guess -move: content_type_guess_for_tree ContentType guess_for_tree -move: content_type_is_a ContentType is_a -move: content_type_is_unknown ContentType is_unknown -move: content_types_get_registered ContentType -version 2.52: move: content_type_is_mime_type ContentType is_mime_type - -move: dbus_error_encode_gerror DBusError encode_gerror -move: dbus_error_get_remote_error DBusError get_remote_error -move: dbus_error_is_remote_error DBusError is_remote_error -move: dbus_error_new_for_dbus_error DBusError new_for_dbus_error -move: dbus_error_quark DBusError quark -move: dbus_error_register_error DBusError register_error -move: dbus_error_register_error_domain DBusError register_error_domain -move: dbus_error_strip_remote_error DBusError strip_remote_error -move: dbus_error_unregister_error DBusError unregister_error - -move: dbus_address_escape_value DBusUtilities address_escape_value -move: dbus_address_get_for_bus_sync DBusUtilities address_get_for_bus_sync -move: dbus_address_get_stream DBusUtilities address_get_stream -move: dbus_address_get_stream_finish DBusUtilities address_get_stream_finish -move: dbus_address_get_stream_sync DBusUtilities address_get_stream_sync -move: dbus_generate_guid DBusUtilities generate_guid -move: dbus_gvalue_to_gvariant DBusUtilities gvalue_to_gvariant -move: dbus_gvariant_to_gvalue DBusUtilities gvariant_to_gvalue -move: dbus_is_address DBusUtilities is_address -move: dbus_is_guid DBusUtilities is_guid -move: dbus_is_interface_name DBusUtilities is_interface_name -move: dbus_is_member_name DBusUtilities is_member_name -move: dbus_is_name DBusUtilities is_name -move: dbus_is_supported_address DBusUtilities is_supported_address -move: dbus_is_unique_name DBusUtilities is_unique_name - -struct: DBusUtilities -out: address_get_stream_finish out_guid -out: address_get_stream_sync out_guid - -move: io_error_from_errno ErrorGIO -move: io_error_quark ErrorGIO - -move: io_modules_load_all_in_directory IOModule load_all_in_directory -move: io_modules_load_all_in_directory_with_scope IOModule load_all_in_directory_with_scope -move: io_modules_scan_all_in_directory IOModule scan_all_in_directory -move: io_modules_scan_all_in_directory_with_scope IOModule scan_all_in_directory_with_scope - -move: io_scheduler_cancel_all_jobs IOSchedulerJob cancel_all_jobs -move: io_scheduler_push_job IOSchedulerJob push_job - -move: pollable_source_new PollableUtils -move: pollable_source_new_full PollableUtils -move: pollable_stream_read PollableUtils -move: pollable_stream_write PollableUtils -move: pollable_stream_write_all PollableUtils - -move: resources_enumerate_children Resource -move: resources_get_info Resource -move: resources_lookup_data Resource -move: resources_open_stream Resource -move: resources_register Resource _register -move: resources_unregister Resource _unregister - -move: keyfile_settings_backend_new SettingsBackend -move: memory_settings_backend_new SettingsBackend -move: null_settings_backend_new SettingsBackend - -move: simple_async_report_error_in_idle SimpleAsyncResult -move: simple_async_report_gerror_in_idle SimpleAsyncResult -move: simple_async_report_take_gerror_in_idle SimpleAsyncResult - -version !Windows: start - move: unix_is_mount_path_system_internal UnixMountEntry is_mount_path_system_internal - move: unix_mount_at UnixMountEntry at - move: unix_mount_compare UnixMountEntry compare - move: unix_mount_free UnixMountEntry free - move: unix_mount_get_device_path UnixMountEntry get_device_path - move: unix_mount_get_fs_type UnixMountEntry get_fs_type - move: unix_mount_get_mount_path UnixMountEntry get_mount_path - move: unix_mount_guess_can_eject UnixMountEntry guess_can_eject - move: unix_mount_guess_icon UnixMountEntry guess_icon - move: unix_mount_guess_name UnixMountEntry guess_name - move: unix_mount_guess_should_display UnixMountEntry guess_should_display - move: unix_mount_guess_symbolic_icon UnixMountEntry guess_symbolic_icon - move: unix_mount_is_readonly UnixMountEntry is_readonly - move: unix_mount_is_system_internal UnixMountEntry is_system_internal - move: unix_mount_points_changed_since UnixMountEntry points_changed_since - move: unix_mount_points_get UnixMountEntry mount_points_get - move: unix_mounts_changed_since UnixMountEntry mounts_changed_since - move: unix_mounts_get UnixMountEntry mounts_get - - version 2.54: start - move: unix_mount_copy UnixMountEntry copy - move: unix_mount_for UnixMountEntry mount_for - version: end -version: end diff -Nru appstream-generator-0.7.3/contrib/girwrap/APILookupGLib.txt appstream-generator-0.7.4/contrib/girwrap/APILookupGLib.txt --- appstream-generator-0.7.3/contrib/girwrap/APILookupGLib.txt 2018-04-26 16:56:59.000000000 +0000 +++ appstream-generator-0.7.4/contrib/girwrap/APILookupGLib.txt 1970-01-01 00:00:00.000000000 +0000 @@ -1,2096 +0,0 @@ -# -# Copyright (C) Mike Wey -# -# Licensed under the GNU Lesser General Public License Version 3 -# -# This library is free software: you can redistribute it and/or modify -# it under the terms of the GNU Lesser General Public License as published by -# the Free Software Foundation, either version 3 of the license, or -# (at your option) any later version. -# -# This software is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Lesser General Public License for more details. -# -# You should have received a copy of the GNU Lesser General Public License -# along with this library. If not, see . -# - -# must start with wrap -wrap: glib -file: GLib-2.0.gir -file: GModule-2.0.gir - -addAliases: start - public alias uint uid_t; - public alias int pid_t; - - version( Windows ) - { - alias int glong; - alias uint gulong; - } - else version( X86_64 ) - { - alias long glong; - alias ulong gulong; - } - else - { - alias int glong; - alias uint gulong; - } - - version (Windows) - { - private import core.stdc.stdio; - - static if( !is(typeof(fdopen(0, null))) ) - { - extern (C) FILE* fdopen(int, char*); - } - } - - struct Scoped(T) - { - T payload; - - alias payload this; - - @disable this(); - @disable this(this); - - ~this() - { - .destroy(payload); - } - } - - auto getScopedGobject(T, Args...)(auto ref Args args) if (is(T == class)) - { - Scoped!(T) result = void; - result.payload = new T(args); - - return result; - } - - /** - * Get the length of a zero terminated array. - */ - size_t getArrayLength(T)(T* arr) - { - size_t len; - - for ( ; arr[len]; len++ ){} - - return len; - } - - unittest - { - assert(getArrayLength("aaaaaaaaa\0".ptr) == 9); - } - - Type* gMalloc(Type)() - { - import glib.c.functions; - return cast(Type*)g_malloc0(Type.sizeof); - } - - alias void* GIConv; -addAliases: end - -addEnums: start - - enum GPriority - { - HIGH = -100, - DEFAULT = 0, - HIGH_IDLE = 100, - DEFAULT_IDLE = 200, - LOW = 300 - } - -addEnums: end - -noConstant: DIR_SEPARATOR -noConstant: DIR_SEPARATOR_S -noConstant: E -noConstant: LN10 -noConstant: LN2 -noConstant: LOG_2_BASE_10 -noConstant: PI -noConstant: PI_2 -noConstant: PI_4 -noConstant: SEARCHPATH_SEPARATOR -noConstant: SEARCHPATH_SEPARATOR_S -noConstant: SQRT2 -noConstant: VERSION_MIN_REQUIRED - -struct: Array -class: ArrayG - -struct: Base64 -move: base64_decode_step Base64 decode_step -move: base64_decode_inplace Base64 decode_inplace -noCode: decode_step -array: decode_inplace Return out_len -code: start - /** - * Incrementally decode a sequence of binary data from its Base-64 stringified - * representation. By calling this function multiple times you can convert - * data in chunks to avoid having to have the full encoded data in memory. - * - * The output buffer must be large enough to fit all the data that will - * be written to it. Since base64 encodes 3 bytes in 4 chars you need - * at least: (@len / 4) * 3 + 3 bytes (+ 3 may be needed in case of non-zero - * state). - * - * Params: - * inn = binary input data - * len = max length of @in data to decode - * output = output buffer - * state = Saved state between steps, initialize to 0 - * save = Saved state between steps, initialize to 0 - * - * Return: The number of bytes of output that was written - * - * Since: 2.12 - */ - public static size_t decodeStep(string inn, ref ubyte[] output, ref int state, ref uint save) - { - auto p = g_base64_decode_step(Str.toStringz(inn), cast(int)inn.length, cast(char*)output.ptr, &state, &save); - - return p; - } -code: end - -struct: BookmarkFile -out: load_from_data_dirs full_path -array: set_groups groups length - -struct: ByteArray -class: ByteArray - -struct: Bytes -noCode: new_take -noCode: new_static - -struct: Checksum -noCode: get_digest -code: start - /** - * Gets the digest from checksum as a raw binary vector and places it - * into buffer. The size of the digest depends on the type of checksum. - * - * Once this function has been called, the Checksum is closed and can - * no longer be updated with update(). - * - * Params: - * buffer = output buffer - * digestLen = an inout parameter. The caller initializes it to the size of buffer. - * After the call it contains the length of the digest. - * - * Since: 2.16 - */ - public void getDigest(ref ubyte[] buffer) - { - size_t digestLen = buffer.length; - - g_checksum_get_digest(gChecksum, buffer.ptr, &digestLen); - - buffer = buffer[0 .. digestLen]; - } -code: end - -struct: ConstructionException -namespace: -code: start - class ConstructionException : Exception - { - this(string message) - { - super(message); - } - - override string toString() - { - return "Construction failure, " ~ msg; - } - } -code: end - -struct: DateTime -structWrap: gpointer DateTime -noCode: new_now_utc -noCode: new_now_local -noCode: new_from_unix_local -noCode: new_from_unix_utc -noCode: new_from_timeval_local -noCode: new_from_timeval_utc -noCode: new_local -noCode: new_utc -noCode: hash -code: start - /** - * Creates a DateTime corresponding to the given Unix time t - * Unix time is the number of seconds that have elapsed since 1970-01-01 - * 00:00:00 UTC, regardless of the local time offset. - * - * This call can fail (ConstructionException) if t represents a time outside - * of the supported range of GDateTime. - * You should release the return value by calling unref() - * when you are done with it - * - * Params: - * t = the Unix time - * utc = If true use utc else use the local timezone. - * - * Throws: ConstructionException GTK+ fails to create the object. - * - * Since: 2.26 - */ - public this (long t, bool utc = true) - { - GDateTime* p; - - if ( utc ) - { - p = g_date_time_new_from_unix_utc(t); - } - else - { - p = g_date_time_new_from_unix_local(t); - } - - if(p is null) - { - throw new ConstructionException("null returned by g_date_time_new_from_unix_local(t)"); - } - this(cast(GDateTime*) p); - } - - /** - * Creates a DateTime corresponding to the given TimeVal tv. - * The time contained in a TimeVal is always stored in the form of - * seconds elapsed since 1970-01-01 00:00:00 UTC, regardless of the - * local time offset. - * - * This call can fail (ConstructionException) if tv represents a time outside - * of the supported range of DateTime. - * You should release the return value by calling unref() - * when you are done with it. - * - * Params: - * tv = a GTimeVal - * utc = If true use utc else use the local timezone. - * - * Throws: ConstructionException GTK+ fails to create the object. - * - * Since: 2.26 - */ - public this (ref GTimeVal tv, bool utc = true) - { - GDateTime* p; - - if ( utc ) - { - p = g_date_time_new_from_timeval_utc(&tv); - } - else - { - p = g_date_time_new_from_timeval_local(&tv); - } - - if(p is null) - { - throw new ConstructionException("null returned by g_date_time_new_from_timeval_local((tv is null) ? null : tv.getTimeValStruct())"); - } - this(cast(GDateTime*) p); - } - - /** */ - override bool opEquals(Object rhs) - { - DateTime date = cast(DateTime)rhs; - - if ( date is null ) - return false; - - return equal(this, date) != 0; - } - - /** */ - override int opCmp(Object rhs) - { - DateTime date = cast(DateTime)rhs; - - if ( date is null ) - return int.min; - - return compare(this, date); - } - - /** */ - override nothrow @trusted hash_t toHash() - { - return hash(); - } - - /** - * Hashes datetime into a guint, suitable for use within GHashTable. - * Since 2.26 - * Params: - * datetime = a GDateTime - * Returns: a guint containing the hash - */ - public nothrow @trusted uint hash() - { - try - { - return g_date_time_hash(gDateTime); - } - catch(Exception e) - { - return 0; - } - } -code: end - -struct: Dir -class: Directory - -struct: Error -class: ErrorG -move: propagate_error Error -move: set_error_literal Error -out: set_error_literal err -out: propagate_error dest - -struct: GException -namespace: -import: glib.ErrorG -import: glib.Str -code: start - class GException : Exception - { - ErrorG error; - - this(ErrorG error) - { - super( Str.toString(error.getErrorGStruct().message) ); - this.error = error; - } - } -code: end - -struct: GLib -namespace: -code: start - static import glib.Version; - deprecated("moves to the glib.Version module") - alias glib.Version.Version Version; -code: end - -struct: HashTable -class: HashTable - -struct: Hmac -noCode: get_digest -move: compute_hmac_for_data Hmac -move: compute_hmac_for_string Hmac -move: compute_hmac_for_bytes Hmac -array: compute_hmac_for_data data length -array: compute_hmac_for_string str length -code: start - /** - * Gets the digest from checksum as a raw binary array and places it - * into buffer. The size of the digest depends on the type of checksum. - * - * Once this function has been called, the Hmac is closed and can - * no longer be updated with update(). - * - * Params: - * buffer = output buffer - * - * Since: 2.30 - */ - public void getDigest(ref ubyte[] buffer) - { - size_t digestLen = buffer.length; - - g_hmac_get_digest(gHmac, buffer.ptr, &digestLen); - - buffer = buffer[0 .. digestLen]; - } -code: end - -struct: IConv -namespace: -noStruct: true -ref: iconv inbuf -out: iconv inbytes_left -array: iconv inbuf inbytes_left -ref: iconv outbuf -out: iconv outbytes_left -array: iconv outbuf outbytes_left - -struct: Idle -class: Idle -cType: -code: start - /** Holds all idle delegates */ - private bool delegate()[] idleListeners; - /** Our idle ID */ - private uint idleID; - /** The priority this class was instantiated with */ - private GPriority priority = GPriority.DEFAULT_IDLE; - - /** - * Creates a new idle cycle. - * Params: - * dlg = the delegate to be executed - * fireNow = When true the delegate will be executed emmidiatly - */ - this(bool delegate() dlg, bool fireNow=false) - { - if ( fireNow && !dlg() ) - return; - - idleListeners ~= dlg; - idleID = g_idle_add_full(priority, cast(GSourceFunc)&idleCallback, cast(void*)this, cast(GDestroyNotify)&destroyIdleNotify); - } - - /** - * Creates a new idle cycle. - * Params: - * dlg = the delegate to be executed - * priority = Priority for the idle function - * fireNow = When true the delegate will be executed emmidiatly - */ - this(bool delegate() dlg, GPriority priority, bool fireNow=false) - { - this.priority = priority; - - if ( fireNow && !dlg() ) - return; - - idleListeners ~= dlg; - idleID = g_idle_add_full(priority, cast(GSourceFunc)&idleCallback, cast(void*)this, cast(GDestroyNotify)&destroyIdleNotify); - } - - /** */ - public void stop() - { - if ( idleID > 0 ) - g_source_remove(idleID); - } - - /** - * Removes the idle from gtk - */ - ~this() - { - stop(); - } - - /** - * Adds a new delegate to this idle cycle - * Params: - * dlg = - * fireNow = - */ - public void addListener(bool delegate() dlg, bool fireNow=false) - { - if ( fireNow && !dlg() ) - return; - - idleListeners ~= dlg; - - if ( idleID == 0 ) - idleID = g_idle_add_full(priority, cast(GSourceFunc)&idleCallback, cast(void*)this, cast(GDestroyNotify)&destroyIdleNotify); - } - - /* - * Executes all delegates on the execution list - * Returns: false if the callback should be removed. - */ - extern(C) static bool idleCallback(Idle idle) - { - bool runAgain = false; - int i = 0; - - while ( i 0 ) --l; - - return line[0..l]; - } - - extern(C) static void childWatchCallback(int pid, int status, Spawn spawn) - { - //writefln("Spawn.childWatchCallback %s %s", pid, status); - spawn.exitStatus = status; - if ( spawn.externalWatch !is null ) - { - spawn.externalWatch(spawn); - } - spawn.close(); - } - - - public bool endOfOutput() - { - if ( standardOutput is null ) return true; - return feof(standardOutput) != 0; - } - - public bool endOfError() - { - if ( standardError is null ) return true; - return feof(standardError) != 0; - } - - string getOutputString() - { - return Str.toString(strOutput); - } - - string getErrorString() - { - return Str.toString(strError); - } - - int getExitStatus() - { - return exitStatus; - } - - /** - * Executes a command synchronasly and - * optionally calls delegates for sysout, syserr and end of job - * - */ - public int commandLineSync( - ChildWatch externalWatch = null, - bool delegate(string) readOutput = null, - bool delegate(string) readError = null ) - { - string commandLine; - foreach ( int count, string arg; argv) - { - if ( count > 0 ) - { - commandLine ~= ' '; - } - commandLine ~= arg; - } - int status = g_spawn_command_line_sync( - Str.toStringz(commandLine), - &strOutput, - &strError, - &exitStatus, - &error); - if ( readOutput != null ) - { - foreach ( string line ; splitLines(Str.toString(strOutput)) ) - { - readOutput(line); - } - } - if ( readError != null ) - { - foreach ( string line ; splitLines(Str.toString(strError)) ) - { - readError(line); - } - } - if ( externalWatch != null ) - { - externalWatch(this); - } - return status; - } -code: end - -struct: Str -import: core.stdc.stdio -import: core.stdc.string -import: gobject.c.types -code: start - /* - * Convert C-style 0 terminated string s to char[] string. - * copied from phobos - */ - public static string toString(const(char)* s, size_t len = 0) pure - { - if ( s is null ) - return cast(string)null; - - if ( len == 0 ) - len = strlen(s); - - return s[0 .. len].idup; - } - - /* - * Convert array of chars s[] to a C-style 0 terminated string. - * copied from phobos - */ - public static char* toStringz(string s) pure - { - if ( s is null ) return null; - char[] copy; - - if (s.length == 0) - { - copy = "\0".dup; - } - else - { - // Need to make a copy - copy = new char[s.length + 1]; - copy[0..s.length] = s[]; - copy[s.length] = 0; - } - - return copy.ptr; - } - - /** */ - public static char** toStringzArray(string[] args) pure - { - if ( args is null ) - { - return null; - } - char** argv = (new char*[args.length]).ptr; - int argc = 0; - foreach (string p; args) - { - argv[argc++] = cast(char*)(p.dup~'\0'); - } - argv[argc] = null; - - return argv; - } - - /** */ - public static char*** toStringzArray(string[][] args) pure - { - if ( args is null ) - { - return null; - } - char**[] argv = new char**[args.length]; - int argc = 0; - foreach( string[] p; args ) - { - argv[argc++] = toStringzArray(p); - } - argv[argc] = null; - - return argv.ptr; - } - - /** */ - public static string[] toStringArray(const(char*)* args) pure - { - if ( args is null ) - { - return null; - } - string[] argv; - - while ( *args !is null ) - { - argv ~= toString(*args); - args++; - } - - return argv; - } - - /** */ - public static string[] toStringArray(const(char*)* args, size_t len) pure - { - string[] argv = new string[len]; - - for ( int i; i < len; i++ ) - { - argv[i] = toString(args[i]); - } - - return argv; - } - - /** */ - public static string[][] toStringArray(char*** args) pure - { - string[][] argv; - - if ( args is null ) - { - return null; - } - - while ( *args !is null ) - { - argv ~= toStringArray(*args); - args++; - } - - return argv; - } - - /** */ - public static void freeString(char* str) - { - g_free(str); - } - - /** */ - public static void freeStringArray(char** str) - { - g_strfreev(str); - } - - /** */ - public static void freeStringArray(char*** str) - { - while ( *str !is null ) - { - g_strfreev(*str); - str++; - } - - g_free(str); - } -code: end - -struct: String -class: StringG - -struct: Thread -noCode: new - -struct: Timeout -class: Timeout -cType: -code: start - /** Holds all idle delegates */ - private bool delegate()[] timeoutListeners; - /** Our timeout ID */ - private uint timeoutID; - - - /** - * Creates a new timeout cycle with the default priority, GPriority.DEFAULT. - * - * Note that timeout functions may be delayed, due to the processing of other - * event sources. Thus they should not be relied on for precise timing. - * After each call to the timeout function, the time of the next timeout is - * recalculated based on the current time and the given interval - * (it does not try to 'catch up' time lost in delays). - * Params: - * interval = the timeout in milieconds - * delegate() = the delegate to be executed - * fireNow = When true the delegate will be executed emmidiatly - */ - this(uint interval, bool delegate() dlg, bool fireNow=false) - { - if ( fireNow && !dlg() ) - return; - - timeoutListeners ~= dlg; - timeoutID = g_timeout_add_full(GPriority.DEFAULT, interval, cast(GSourceFunc)&timeoutCallback, cast(void*)this, cast(GDestroyNotify)&destroyTimeoutNotify); - } - - /** - * Creates a new timeout cycle. - * Params: - * interval = the timeout in milieconds - * delegate() = the delegate to be executed - * priority = Priority for the timeout function - * fireNow = When true the delegate will be executed emmidiatly - */ - this(uint interval, bool delegate() dlg, GPriority priority, bool fireNow=false) - { - if ( fireNow && !dlg() ) - return; - - timeoutListeners ~= dlg; - timeoutID = g_timeout_add_full(priority, interval, cast(GSourceFunc)&timeoutCallback, cast(void*)this, cast(GDestroyNotify)&destroyTimeoutNotify); - } - - /** - * Creates a new timeout cycle with the default priority, GPriority.DEFAULT. - * Params: - * delegate() = the delegate to be executed - * seconds = interval in seconds. - * fireNow = When true the delegate will be executed emmidiatly - */ - this(bool delegate() dlg, uint seconds, bool fireNow=false) - { - if ( fireNow && !dlg() ) - return; - - timeoutListeners ~= dlg; - timeoutID = g_timeout_add_seconds_full(GPriority.DEFAULT, seconds, cast(GSourceFunc)&timeoutCallback, cast(void*)this, cast(GDestroyNotify)&destroyTimeoutNotify); - } - - /** - * Creates a new timeout cycle. - * Params: - * delegate() = the delegate to be executed - * seconds = interval in seconds. - * priority = Priority for the timeout function - * fireNow = When true the delegate will be executed emmidiatly - */ - this(bool delegate() dlg, uint seconds, GPriority priority, bool fireNow=false) - { - if ( fireNow && !dlg() ) - return; - - timeoutListeners ~= dlg; - timeoutID = g_timeout_add_seconds_full(priority, seconds, cast(GSourceFunc)&timeoutCallback, cast(void*)this, cast(GDestroyNotify)&destroyTimeoutNotify); - } - - /** Removes the timeout from gtk */ - public void stop() - { - if ( timeoutID > 0 ) - { - g_source_remove(timeoutID); - } - } - - /** - * Removes the timeout from gtk - */ - ~this() - { - stop(); - } - - /** - * Adds a new delegate to this timeout cycle - * Params: - * dlg = - * fireNow = - */ - public void addListener(bool delegate() dlg, bool fireNow=false) - { - if ( fireNow && !dlg() ) - return; - - timeoutListeners ~= dlg; - } - - /** - * The callback execution from glib - * Params: - * timeout = - * Returns: - */ - extern(C) static bool timeoutCallback(Timeout timeout) - { - bool runAgain = false; - int i = 0; - - while ( i. -# - -# must start with wrap -wrap: gobject -file: GObject-2.0.gir - -noAlias: Type -addEnums: start - - /** - * A value which represents the unique identifier of a registered type. - */ - enum GType : size_t - { - INVALID = 0<<2, - NONE = 1<<2, - INTERFACE = 2<<2, - CHAR = 3<<2, - UCHAR = 4<<2, - BOOLEAN = 5<<2, - INT = 6<<2, - UINT = 7<<2, - LONG = 8<<2, - ULONG = 9<<2, - INT64 = 10<<2, - UINT64 = 11<<2, - ENUM = 12<<2, - FLAGS = 13<<2, - FLOAT = 14<<2, - DOUBLE = 15<<2, - STRING = 16<<2, - POINTER = 17<<2, - BOXED = 18<<2, - PARAM = 19<<2, - OBJECT = 20<<2, - VARIANT = 21<<2, - } -addEnums: end - -struct: CClosure -class: CClosure -import: glib.ConstructionException -import: gobject.ObjectG -noCode: new -noCode: new_swap -noCode: new_object -noCode: new_object_swap -code: start - /** - * Creates a new closure which invokes callbackFunc with userData as - * the last parameter. - * - * Params: - * callbackFunc = the function to invoke - * userData = user data to pass to callbackFunc - * destroyData = destroy notify to be called when userData is no longer used - * swap = if true invoce with usrData as the first parameter - * - * Throws: ConstructionException GTK+ fails to create the object. - */ - public this(GCallback callbackFunc, void* userData, GClosureNotify destroyData, bool swap) - { - GClosure* p; - - if ( swap ) - p = g_cclosure_new_swap(callbackFunc, userData, destroyData); - else - p = g_cclosure_new(callbackFunc, userData, destroyData); - - if(p is null) - { - throw new ConstructionException("null returned by new"); - } - - this(cast(GCClosure*) p); - } - - /** - * A variant of this() which uses object as userData and - * calls ObjectG.watchClosure() on object and the created - * closure. This function is useful when you have a callback closely - * associated with a gobject.ObjectG, and want the callback to no longer run - * after the object is is freed. - * - * Params: - * callbackFunc = the function to invoke - * object = a gobject.ObjectG.ObjectG to pass to callbackFunc - * swap = if true invoce with usrData as the first parameter - * - * Throws: ConstructionException GTK+ fails to create the object. - */ - public this(GCallback callbackFunc, ObjectG object, bool swap) - { - GClosure* p; - - if ( swap ) - p = g_cclosure_new_object_swap(callbackFunc, (object is null) ? null : object.getObjectGStruct()); - else - p = g_cclosure_new_object(callbackFunc, (object is null) ? null : object.getObjectGStruct()); - - if(p is null) - { - throw new ConstructionException("null returned by new_object"); - } - - this(cast(GCClosure*) p); - } -code: end - -struct: DClosure -namespace: -import: glib.Str -import: glib.Variant -import: gobject.c.functions -import: gobject.c.types -import: gobject.Closure -import: gobject.ObjectG -import: gobject.ParamSpec -import: core.memory -import: std.algorithm -import: std.conv -import: std.traits -import: std.typecons -code: start - struct DGClosure(T) - { - GClosure closure; - - static if ( isDelegate!T ) - { - DGClosureWrapDelegate!(T)* wrap; - alias wrap this; - } - else - { - T callback; - } - } - - struct DGClosureWrapDelegate(T) - { - T callback; - } - - /** - * DClosure is a wrapper around the gobject library's GClosure with special handling for marshalling D delegates and function pointers as callbacks. - * - * Closures are central to the concept of asynchronous signal delivery which is widely used throughout GTK+ and GNOME applications. - * A closure is an abstraction, a generic representation of a callback. - */ - class DClosure : Closure - { - /** Get the main Gtk struct */ - public GClosure* getDClosureStruct(bool transferOwnership = false) - { - if (transferOwnership) - ownedRef = false; - return gClosure; - } - - /** - * Sets our main struct and passes it to the parent class. - */ - public this (GClosure* gClosure, bool ownedRef = false) - { - super(gClosure, ownedRef); - } - - /** - * Create a new Closure that will call `callback` when it's invoked. - * - * Params: - * callback = a delegate or function to call when the DClosure is invoked. - * swap = Should the first and last parameter passed to the callback be swapped. - * This is usefull when using the closure for a Signal, where the instance is - * the first parameter, but when using delegates it usually isn't used. - */ - this(T)(T callback, bool swap = false) - if ( isCallable!T ) - { - GClosure* gClosure = g_closure_new_simple(DGClosure!(T).sizeof, null); - g_closure_ref(gClosure); - g_closure_sink(gClosure); - g_closure_set_marshal(gClosure, &d_closure_marshal!T); - if ( swap ) gClosure.derivativeFlag = true; - - auto dClosure = cast(DGClosure!(T)*)gClosure; - - static if ( isDelegate!T ) - { - dClosure.wrap = new DGClosureWrapDelegate!T; - GC.addRoot(dClosure.wrap); - g_closure_add_finalize_notifier(gClosure, null, &d_finalize_nofify); - } - - dClosure.callback = callback; - super(gClosure, true); - } - - extern(C) static void d_finalize_nofify(void* data, GClosure* dClosure) - { - GC.removeRoot((cast(DGClosure!(void delegate())*)dClosure).wrap); - } - - extern(C) static void d_closure_marshal(T)(GClosure* closure, GValue* return_value, uint n_param_values, /*const*/ GValue* param_values, void* invocation_hint, void* marshal_data) - { - DGClosure!(T)* cl = cast(DGClosure!(T)*)closure; - - if ( Parameters!(T).length > n_param_values ) - assert(false, "DClosure doesn't have enough parameters."); - - if ( closure.derivativeFlag ) - { - GValue[] swapped = new GValue[n_param_values]; - swapped[0..n_param_values-1] = param_values[1..n_param_values]; - swapped[n_param_values-1] = param_values[0]; - param_values = swapped.ptr; - } - - mixin(getCallbackCall!T()); - } - - private static string getCallbackCall(T)() - { - if (!__ctfe) assert(false); - - string call; - - alias Params = Parameters!T; - foreach ( param; Params ) - { - static if ( __traits(compiles, TemplateOf!param) && __traits(isSame, TemplateOf!param, glib.c.types.Scoped) ) - call ~= "import "~moduleName!(TemplateArgsOf!(param)[0])~";\n"; - else static if ( is(param == class) || is(param == interface) || is(param == struct) || is(param == enum) ) - call ~= "import "~moduleName!param~";\n"; - else static if ( isPointer!param && ( is(PointerTarget!param == struct) || is(PointerTarget!param == enum)) ) - //The moduleName template gives an forward reference error here. - call ~= "import "~fullyQualifiedName!param.findSplitAfter(".c.types")[0]~";\n"; - } - alias Ret = ReturnType!T; - static if ( is(Ret == class) || is(Ret == interface) || is(Ret == struct) || is(Ret == enum) ) - call ~= "import "~moduleName!Ret~";\n"; - else static if ( isPointer!Ret && ( is(PointerTarget!Ret == struct) || is(PointerTarget!Ret == enum)) ) - call ~= "import "~fullyQualifiedName!Ret.findSplitAfter(".c.types")[0]~";\n"; - - static if ( !is(Ret == void) ) - call ~= "auto ret = "; - call ~= "cl.callback("; - - foreach ( i, param; Params ) - { - if ( i > 0 ) - call ~= ", "; - call ~= getValue!param(i); - } - call ~= ");\n"; - - static if ( is(Ret == bool) ) - call ~= "g_value_set_boolean(return_value, ret);"; - else static if ( is(Ret == byte) ) - call ~= "g_value_set_schar(return_value, ret);"; - else static if ( is(Ret == ubyte) ) - call ~= "g_value_set_uchar(return_value, ret);"; - else static if ( is(Ret == int) ) - call ~= "g_value_set_int(return_value, ret);"; - else static if ( is(Ret == uint) ) - call ~= "g_value_set_uint(return_value, ret);"; - else static if ( is(Ret == long) ) - call ~= "g_value_set_int64(return_value, ret);"; - else static if ( is(Ret == ulong) ) - call ~= "g_value_set_uint64(return_value, ret);"; - else static if ( is(Ret == float) ) - call ~= "g_value_set_float(return_value, ret);"; - else static if ( is(Ret == double) ) - call ~= "g_value_set_double(return_value, ret);"; - else static if ( is(Ret == string) ) - call ~= "g_value_set_string(return_value, Str.toStringz(ret));"; - else static if ( is(Ret == string[]) ) - call ~= "g_value_set_pointer(return_value, Str.toStringzArray(ret));"; - else static if ( is(Ret == enum) ) - call ~= "g_type_is_a(return_value.gType, GType.ENUM) ? g_value_set_enum(return_value, ret) : g_value_set_flags(return_value, ret);"; - else static if ( isPointer!Ret ) - call ~= "g_type_is_a(return_value.gType, GType.POINTER) ? g_value_set_pointer(return_value, ret) : (g_type_is_a(return_value.gType, GType.BOXED) ? g_value_set_boxed(return_value, ret) : g_value_set_object(return_value, ret));"; - else static if ( is(Ret == interface) ) - call ~= "g_value_set_object(return_value, (cast(ObjectG)ret).getObjectGStruct());"; - else static if ( is(Ret == class) ) - { - static if ( is(Ret == Variant) ) - call ~= "g_value_set_variant(return_value, ret.getVariantStruct());"; - else static if ( is(Ret == ParamSpec) ) - call ~= "g_value_set_param(return_value, ret.getParamSpecStruct());"; - else static if ( is(Ret : ObjectG) ) - call ~= "g_value_set_object(return_value, ret.getObjectGStruct());"; - else - call ~= "g_type_is_a(return_value.gType, GType.POINTER) ? g_value_set_pointer(return_value, ret.get"~Ret.stringof~"Struct()) : (g_type_is_a(return_value.gType, GType.BOXED) ? g_value_set_boxed(return_value, ret.get"~Ret.stringof~"Struct()) : g_value_set_object(return_value, ret.get"~Ret.stringof~"Struct()));"; - } - - return call; - } - - private static string getValue(Param)(int index) - { - if (!__ctfe) assert(false); - - static if ( is(Param == bool) ) - return "g_value_get_boolean(¶m_values["~to!string(index)~"]) != 0"; - else static if ( is(Param == byte) ) - return "g_value_get_schar(¶m_values["~to!string(index)~"])"; - else static if ( is(Param == ubyte) ) - return "g_value_get_uchar(¶m_values["~to!string(index)~"])"; - else static if ( is(Param == int) ) - return "g_value_get_int(¶m_values["~to!string(index)~"])"; - else static if ( is(Param == uint) ) - return "g_value_get_uint(¶m_values["~to!string(index)~"])"; - else static if ( is(Param == long) ) - return "g_value_get_int64(¶m_values["~to!string(index)~"])"; - else static if ( is(Param == ulong) ) - return "g_value_get_uint64(¶m_values["~to!string(index)~"])"; - else static if ( is(Param == float) ) - return "g_value_get_float(¶m_values["~to!string(index)~"])"; - else static if ( is(Param == double) ) - return "g_value_get_double(¶m_values["~to!string(index)~"])"; - else static if ( is(Param == string) ) - return "Str.toString(g_value_get_string(¶m_values["~to!string(index)~"]))"; - else static if ( is(Param == string[]) ) - return "Str.toStringArray(cast(const(char*)*)g_value_get_pointer(¶m_values["~to!string(index)~"]))"; - else static if ( is(Param == enum) ) - return "cast("~fullyQualifiedName!Param~")(g_type_is_a(param_values["~to!string(index)~"].gType, GType.ENUM) ? g_value_get_enum(¶m_values["~to!string(index)~"]) : g_value_get_flags(¶m_values["~to!string(index)~"]))"; - else static if ( isPointer!Param ) - return "cast("~fullyQualifiedName!Param~")(g_type_is_a(param_values["~to!string(index)~"].gType, GType.POINTER) ? g_value_get_pointer(¶m_values["~to!string(index)~"]) : (g_type_is_a(param_values["~to!string(index)~"].gType, GType.BOXED) ? g_value_get_boxed(¶m_values["~to!string(index)~"]) : g_value_get_object(¶m_values["~to!string(index)~"])))"; - else static if ( __traits(compiles, TemplateOf!Param) && __traits(isSame, TemplateOf!Param, glib.c.types.Scoped) ) - return "getScopedGobject!("~fullyQualifiedName!(TemplateArgsOf!(Param)[0])~")(cast(typeof("~fullyQualifiedName!(TemplateArgsOf!(Param)[0])~".tupleof[0]))(g_type_is_a(param_values["~to!string(index)~"].gType, GType.POINTER) ? g_value_get_pointer(¶m_values["~to!string(index)~"]) : (g_type_is_a(param_values["~to!string(index)~"].gType, GType.BOXED) ? g_value_get_boxed(¶m_values["~to!string(index)~"]) : g_value_get_object(¶m_values["~to!string(index)~"]))))"; - else static if ( is(Param == interface) ) - return "ObjectG.getDObject!("~fullyQualifiedName!Param~")(cast(GObject*)g_value_get_object(¶m_values["~to!string(index)~"]))"; - else static if ( is(Param == class) ) - { - static if ( is(Param == Variant) ) - return "new Variant(g_value_get_variant(¶m_values["~to!string(index)~"]))"; - else static if ( is(Param== ParamSpec) ) - return "new ParamSpec(g_value_get_param(¶m_values["~to!string(index)~"]))"; - else static if ( is(Param : ObjectG) ) - return "ObjectG.getDObject!("~fullyQualifiedName!Param~")(cast(typeof("~fullyQualifiedName!Param~".tupleof[0]))g_value_get_object(¶m_values["~to!string(index)~"]))"; - else - return "ObjectG.getDObject!("~fullyQualifiedName!Param~")(cast(typeof("~fullyQualifiedName!Param~".tupleof[0]))(g_type_is_a(param_values["~to!string(index)~"].gType, GType.POINTER) ? g_value_get_pointer(¶m_values["~to!string(index)~"]) : (g_type_is_a(param_values["~to!string(index)~"].gType, GType.BOXED) ? g_value_get_boxed(¶m_values["~to!string(index)~"]) : g_value_get_object(¶m_values["~to!string(index)~"]))))"; - } - } - } -code: end - -struct: Object -import: core.memory -import: gobject.Signals -import: std.algorithm -import: std.traits -merge: InitiallyUnowned -noSignal: notify -move: clear_object Object -inout: clear_object object_ptr - -code: start - protected bool isGcRoot; - - /** - * Sets our main struct and passes store it on the gobject. - * Add a gabage collector root to the gtk+ struct so it doesn't get collect - */ - public this (GObject* gObject, bool ownedRef = false) - { - this.gObject = gObject; - if ( gObject !is null ) - { - setDataFull("GObject", cast(void*)this, cast(GDestroyNotify)&destroyNotify); - addToggleRef(cast(GToggleNotify)&toggleNotify, cast(void*)this); - - //If the refCount is larger then 1 toggleNotify isn't called - if (gObject.refCount > 1 && !isGcRoot) - { - GC.addRoot(cast(void*)this); - isGcRoot = true; - } - - //Remove the floating reference if there is one. - if ( isFloating() ) - { - refSink(); - unref(); - } - //If we already owned this reference remove the one added by addToggleRef. - else if ( ownedRef ) - { - unref(); - } - } - } - - extern(C) - { - static void destroyNotify(ObjectG obj) - { - if ( obj.isGcRoot ) - { - GC.removeRoot(cast(void*)obj); - obj.isGcRoot = false; - } - - if ( obj.gObject.refCount > 0 ) - obj.removeToggleRef(cast(GToggleNotify)&toggleNotify, cast(void*)obj); - - obj.gObject = null; - } - - static void toggleNotify(ObjectG obj, GObject* object, int isLastRef) - { - if ( isLastRef && obj.isGcRoot ) - { - GC.removeRoot(cast(void*)obj); - obj.isGcRoot = false; - } - else if ( !obj.isGcRoot ) - { - GC.addRoot(cast(void*)obj); - obj.isGcRoot = true; - } - } - } - - ~this() - { - static if ( isPointer!(typeof(g_object_steal_data)) ) - bool libLoaded = Linker.isLoaded(LIBRARY_GOBJECT); - else - enum libLoaded = true; - - if ( libLoaded && gObject !is null ) - { - // Remove the GDestroyNotify callback, - // for when the D object is destroyed before the C one. - g_object_steal_data(gObject, cast(char*)"GObject"); - - if ( isGcRoot ) - { - GC.removeRoot(cast(void*)this); - isGcRoot = false; - } - - g_object_remove_toggle_ref(gObject, cast(GToggleNotify)&toggleNotify, cast(void*)this); - } - } - - /** */ - T opCast(T)() - { - static if ( is(T : ObjectG) - && !is(T == interface) - && is(typeof(new T(cast(typeof(T.tupleof[0]))gObject, false))) ) - { - //If a regular cast works, return the result. - if ( auto r = cast(T)super ) - return r; - - //Prints a warning if the cast is invalid. - //g_type_check_instance_cast(cast(GTypeInstance*)gObject, T.getType()); - - //Can we cast this type to T. - if ( !g_type_is_a(gObject.gTypeInstance.gClass.gType, T.getType()) ) - return null; - - //Remove the GDestroyNotify callback for the original d object. - g_object_steal_data(gObject, "GObject"); - //Remove the original object as a GC root if needed. - if ( isGcRoot ) - { - GC.removeRoot(cast(void*)this); - isGcRoot = false; - } - //Add a reference for the original D object before we remove the toggle reference. - g_object_ref(gObject); - g_object_remove_toggle_ref(gObject, cast(GToggleNotify)&toggleNotify, cast(void*)this); - - //The new object handles the memory management. - return new T(cast(typeof(T.tupleof[0]))gObject, false); - } - else static if ( is(T == interface) - && hasStaticMember!(T, "getType") - && is(ReturnType!(T.getType) == GType) ) - { - //If a regular cast works, return the result. - if ( auto r = cast(T)super ) - return r; - - //Do we implement interface T. - if ( !g_type_is_a(gObject.gTypeInstance.gClass.gType, T.getType()) ) - return null; - - return getInterfaceInstance!T(gObject); - } - else - return cast(T)super; - } - - /** - * Gets a D Object from the objects table of associations. - * Params: - * obj = GObject containing the associations. - * Returns: the D Object if found, or a newly constructed object if no such Object exists. - */ - public static RT getDObject(T, RT=T, U)(U obj, bool ownedRef = false) - { - if ( obj is null ) - { - return null; - } - - static if ( is(T : ObjectG) && !is(RT == interface) ) - { - auto p = g_object_get_data(cast(GObject*)obj, Str.toStringz("GObject")); - - if ( p !is null ) - return cast(RT)cast(ObjectG)p; - else - return new T(obj, ownedRef); - } - else static if ( is(RT == interface) && hasMember!(RT, "getType") && is(ReturnType!(RT.getType) == GType) ) - { - auto p = g_object_get_data(cast(GObject*)obj, Str.toStringz("GObject")); - - if ( p !is null ) - return cast(RT)cast(ObjectG)p; - else - return getInterfaceInstance!RT(cast(GObject*)obj); - } - else - { - return new T(obj, ownedRef); - } - } - - private static I getInterfaceInstance(I)(GObject* instance) - { - static class Impl: ObjectG, I - { - public this (GObject* gObject, bool ownedRef = false) - { - super(gObject, ownedRef); - } - - /** the main Gtk struct as a void* */ - protected override void* getStruct() - { - return cast(void*)gObject; - } - - // add the interface capabilities - mixin("import "~ moduleName!I[0..$-2] ~"T;import "~ moduleName!I ~"; mixin "~ __traits(identifier, I)[0..$-2] ~"T!("~__traits(identifier, Impl)~");"); - } - - ClassInfo ci = Impl.classinfo; - Impl iface; - void* p; - - //Skip all the setup for the memory management, - //and only add an extra reference for the instance returned. - p = GC.malloc(ci.initializer.length, GC.BlkAttr.FINALIZE, ci); - p[0..ci.initializer.length] = ci.initializer; - iface = cast(Impl)p; - iface.gObject = instance; - iface.addToggleRef(cast(GToggleNotify)&toggleNotify, cast(void*)iface); - - return iface; - } - - /** */ - public void setProperty(T)(string propertyName, T value) - { - setProperty(propertyName, new Value(value)); - } - - deprecated("Use the member function") - public static void unref(ObjectG obj) - { - obj.unref(); - } - - deprecated("Use the member function") - public static ObjectG doref(ObjectG obj) - { - return obj.doref(); - } - - /** - * The notify signal is emitted on an object when one of its - * properties has been changed. Note that getting this signal - * doesn't guarantee that the value of the property has actually - * changed, it may also be emitted when the setter for the property - * is called to reinstate the previous value. - * - * This signal is typically used to obtain change notification for a - * single property. - * - * It is important to note that you must use - * canonical parameter names for the property. - * - * Params: - * dlg = The callback. - * property = Set this if you only want to receive the signal for a specific property. - * connectFlags = The behavior of the signal's connection. - */ - gulong addOnNotify(void delegate(ParamSpec, ObjectG) dlg, string property = "", ConnectFlags connectFlags=cast(ConnectFlags)0) - { - string signalName; - - if ( property == "" ) - signalName = "notify"; - else - signalName = "notify::"~ property; - - return Signals.connect(this, signalName, dlg, connectFlags ^ ConnectFlags.SWAPPED); - } -code: end - -struct: ObjectClass -merge: InitiallyUnownedClass - -struct: ParamSpecBoolean -noCode: true - -struct: ParamSpecBoxed -noCode: true - -struct: ParamSpecChar -noCode: true - -struct: ParamSpecDouble -noCode: true - -struct: ParamSpecEnum -noCode: true - -struct: ParamSpecFlags -noCode: true - -struct: ParamSpecFloat -noCode: true - -struct: ParamSpecGType -noCode: true - -struct: ParamSpecInt -noCode: true - -struct: ParamSpecInt64 -noCode: true - -struct: ParamSpecLong -noCode: true - -struct: ParamSpecObject -noCode: true - -struct: ParamSpecOverride -noCode: true - -struct: ParamSpecParam -noCode: true - -struct: ParamSpecPointer -noCode: true - -struct: ParamSpecString -noCode: true - -struct: ParamSpecUChar -noCode: true - -struct: ParamSpecUInt -noCode: true - -struct: ParamSpecUInt64 -noCode: true - -struct: ParamSpecULong -noCode: true - -struct: ParamSpecUnichar -noCode: true - -struct: ParamSpecValueArray -noCode: true - -struct: ParamSpecVariant -noCode: true - -struct: Signals -import: gobject.DClosure -import: std.traits -code: start - /** - * Connects a callback to a signal for a particular object. - * - * The handler will be called before the default handler of the signal. - * - * Params: - * instance = the instance to connect to. - * detailedSignal = a string of the form "signal-name::detail". - * callback = the callback to connect. - * connectFlags = a combination of ConnectFlags. - * - * Returns: the handler ID, of type gulong (always greater than 0 for successful connections) - */ - public static gulong connect(T)(ObjectG instance, string detailedSignal, T callback, ConnectFlags connectFlags = cast(ConnectFlags)0) - if ( isCallable!T && !is(T == GCallback) ) - { - bool after = (connectFlags & ConnectFlags.AFTER) != false; - bool swap = (connectFlags & ConnectFlags.SWAPPED) != false; - - return Signals.connectClosure(instance, detailedSignal, new DClosure(callback, swap), after); - } - - deprecated public static gulong connectData(void* instanc, string detailedSignal, GCallback cHandler, Object data, GClosureNotify destroyData, GConnectFlags connectFlags) - { - return g_signal_connect_data(instanc, Str.toStringz(detailedSignal), cHandler, cast(void*)data, destroyData, connectFlags); - } - - /** - * Connects a GCallback function to a signal for a particular object. - * - * The handler will be called before the default handler of the signal. - * - * See [memory management of signal handlers][signal-memory-management] for - * details on how to handle the return value and memory management of @data. - * - * Params: - * instance = the instance to connect to. - * detailedSignal = a string of the form "signal-name::detail". - * cHandler = the GCallback to connect. - * data = data to pass to cHandler calls. - * - * Returns: the handler ID, of type gulong (always greater than 0 for successful connections) - */ - public static gulong connect(ObjectG instanc, string detailedSignal, GCallback cHandler, void* data) - { - return g_signal_connect_data((instanc is null) ? null : instanc.getObjectGStruct(), Str.toStringz(detailedSignal), cHandler, data, null, cast(ConnectFlags)0); - } -code: end - -struct: Type -import: gobject.ObjectG -code: start - public static T* getInstanceClass(T)(ObjectG obj) - { - return cast(T*) (cast(GTypeInstance*)obj.getObjectGStruct()).gClass; - } - - /** - * Get the unique name that is assigned to the Objects type. - * Returns: Static type name or NULL. - */ - public static string name(ObjectG obj) - { - GType type = (cast(GTypeInstance*)obj.getObjectGStruct()).gClass.gType; - - return name(type); - } -code: end - -struct: Value -import: gobject.Type -import: std.traits -code: start - /** */ - public this() - { - this(new GValue); - } - - /** */ - this(GOBJECT)(GOBJECT obj) - if ( is(GOBJECT == class) && hasMember!(GOBJECT, "getType") ) - { - this(); - init(GOBJECT.getType()); - - static if ( is(GOBJECT : ObjectG) ) - { - setObject(obj); - } - else - { - if ( Type.isA(gValue.gType, GType.BOXED) ) - setBoxed(obj.tupleof[0]); - else - setPointer(obj.tupleof[0]); - } - } - - - /** */ - this(string value) - { - this(); - init(GType.STRING); - setString(value); - } - - /** */ - this(BOOL)(BOOL value) - if( isBoolean!BOOL ) - { - this(); - init(GType.BOOLEAN); - setBoolean(value); - } - - /** */ - this(INT)(INT value) - if ( isIntegral!INT ) - { - this(); - - static if ( is(OriginalType!INT == int) ) - { - init(GType.INT); - setInt(value); - } - else static if ( is(OriginalType!INT == uint) ) - { - init(GType.UINT); - setUint(value); - } - else static if ( is(OriginalType!INT == long) ) - { - init(GType.INT64); - setInt64(value); - } - else static if ( is(OriginalType!INT == ulong) ) - { - init(GType.UINT64); - setUint64(value); - } - else - { - init(GType.INT); - setInt(value); - } - } - - /** */ - this(FLOAT)(FLOAT value) - if ( isFloatingPoint!FLOAT ) - { - this(); - - static if ( is( FLOAT == float ) ) - { - init(GType.FLOAT); - setFloat(value); - } - else - { - init(GType.DOUBLE); - setDouble(value); - } - } -code: end - -struct: WeakRef -code: start - /** */ - this(void* object) - { - g_weak_ref_init(gWeakRef, object); - } -code: end - -# -# Move functions defined as global into there respective classes -# - -struct: - -move: boxed_copy Boxed copy -move: boxed_free Boxed free -move: boxed_type_register_static Boxed type_register_static -move: pointer_type_register_static Boxed - -move: enum_complete_type_info Enums complete_type_info -move: enum_get_value Enums get_value -move: enum_get_value_by_name Enums get_value_by_name -move: enum_get_value_by_nick Enums get_value_by_nick -move: enum_register_static Enums register_static - -version 2.54: start - move: enum_to_string Enums - move: flags_to_string Enums -version: end - -move: flags_complete_type_info Flags complete_type_info -move: flags_get_first_value Flags get_first_value -move: flags_get_value_by_name Flags get_value_by_name -move: flags_get_value_by_nick Flags get_value_by_nick -move: flags_register_static Flags register_static - -# ParamSpec Constructors? -move: param_spec_boolean Value -move: param_spec_boxed Value -move: param_spec_char Value -move: param_spec_double Value -move: param_spec_enum Value -move: param_spec_flags Value -move: param_spec_float Value -move: param_spec_gtype Value -move: param_spec_int Value -move: param_spec_int64 Value -move: param_spec_long Value -move: param_spec_object Value -move: param_spec_override Value -move: param_spec_param Value -move: param_spec_pointer Value -move: param_spec_string Value -move: param_spec_uchar Value -move: param_spec_uint Value -move: param_spec_uint64 Value -move: param_spec_ulong Value -move: param_spec_unichar Value -move: param_spec_value_array Value -move: param_spec_variant Value - -move: param_type_register_static ParamSpec -move: param_value_convert ParamSpec -move: param_value_defaults ParamSpec -move: param_value_set_default ParamSpec -move: param_value_validate ParamSpec -move: param_values_cmp ParamSpec - -move: signal_accumulator_first_wins Signals accumulator_first_wins -move: signal_accumulator_true_handled Signals accumulator_true_handled -move: signal_add_emission_hook Signals add_emission_hook -move: signal_chain_from_overridden Signals chain_from_overridden -move: signal_chain_from_overridden_handler Signals chain_from_overridden_handler -move: signal_connect_closure Signals connect_closure -move: signal_connect_closure_by_id Signals connect_closure_by_id -move: signal_connect_data Signals connect_data -move: signal_connect_object Signals connect_object -move: signal_emit Signals emit -move: signal_emit_by_name Signals emit_by_name -move: signal_emit_valist Signals emit_valist -move: signal_emitv Signals emitv -move: signal_get_invocation_hint Signals get_invocation_hint -move: signal_handler_block Signals handler_block -move: signal_handler_disconnect Signals handler_disconnect -move: signal_handler_find Signals handler_find -move: signal_handler_is_connected Signals handler_is_connected -move: signal_handler_unblock Signals handler_unblock -move: signal_handlers_block_matched Signals handlers_block_matched -move: signal_handlers_destroy Signals handlers_destroy -move: signal_handlers_disconnect_matched Signals handlers_disconnect_matched -move: signal_handlers_unblock_matched Signals handlers_unblock_matched -move: signal_has_handler_pending Signals has_handler_pending -move: signal_list_ids Signals list_ids -move: signal_lookup Signals lookup -move: signal_name Signals name -move: signal_new Signals new -move: signal_new_class_handler Signals new_class_handler -move: signal_new_valist Signals new_valist -move: signal_newv Signals newv -move: signal_override_class_closure Signals override_class_closure -move: signal_override_class_handler Signals override_class_handler -move: signal_parse_name Signals parse_name -move: signal_query Signals query -move: signal_remove_emission_hook Signals remove_emission_ -move: signal_set_va_marshaller Signals set_va_marshaller -move: signal_stop_emission Signals stop_emission -move: signal_stop_emission_by_name Signals stop_emission_by_name -move: signal_type_cclosure_new Signals type_cclosure_new - -move: source_set_closure Closure -move: source_set_dummy_callback Closure - -move: strdup_value_contents Value - -move: type_add_class_cache_func Type add_class_cache_func -move: type_add_class_private Type add_class_private -move: type_add_instance_private Type add_instance_private -move: type_add_interface_check Type add_interface_check -move: type_add_interface_dynamic Type add_interface_dynamic -move: type_add_interface_static Type add_interface_static -move: type_check_class_cast Type check_class_cast -move: type_check_class_is_a Type check_class_is_a -move: type_check_instance Type check_instance -move: type_check_instance_cast Type check_instance_cast -move: type_check_instance_is_a Type check_instance_is_a -move: type_check_instance_is_fundamentally_a Type check_instance_is_fundamentally_a -move: type_check_is_value_type Type check_is_value_type -move: type_check_value Type check_value -move: type_check_value_holds Type check_value_holds -move: type_children Type children -move: type_create_instance Type create_instance -move: type_default_interface_peek Type default_interface_peek -move: type_default_interface_ref Type default_interface_ref -move: type_default_interface_unref Type default_interface_unref -move: type_depth Type depth -move: type_ensure Type ensure -move: type_free_instance Type free_instance -move: type_from_name Type from_name -move: type_fundamental Type fundamental -move: type_fundamental_next Type fundamental_next -move: type_get_plugin Type get_plugin -move: type_get_qdata Type get_qdata -move: type_get_type_registration_serial Type get_type_registration_serial -move: type_init Type init -move: type_init_with_debug_flags Type init_with_debug_flags -move: type_interfaces Type interfaces -move: type_is_a Type is_a -move: type_name Type name -move: type_name_from_class Type name_from_class -move: type_name_from_instance Type name_from_instance -move: type_next_base Type next_base -move: type_parent Type parent -move: type_qname Type qname -move: type_query Type query -move: type_register_dynamic Type register_dynamic -move: type_register_fundamental Type register_fundamental -move: type_register_static Type register_static -move: type_register_static_simple Type register_static_simple -move: type_remove_class_cache_func Type remove_class_cache_func -move: type_remove_interface_check Type remove_interface_check -move: type_set_qdata Type set_qdata -move: type_test_flags Type test_flags -move: type_get_instance_count Type get_instance_count -#move: type_value_table_peek Type value_table_peek diff -Nru appstream-generator-0.7.3/contrib/girwrap/APILookup.txt appstream-generator-0.7.4/contrib/girwrap/APILookup.txt --- appstream-generator-0.7.3/contrib/girwrap/APILookup.txt 2018-04-26 16:56:59.000000000 +0000 +++ appstream-generator-0.7.4/contrib/girwrap/APILookup.txt 2018-08-04 08:40:54.000000000 +0000 @@ -41,84 +41,6 @@ includeComments: y -# defines the simple token substitution -# TODO allow to create real aliases on the code and simple static token replacement -alias: volatile -alias: G_CONST_RETURN -alias: gint int -alias: guint uint -alias: gboolean bool -alias: gpointer void* -alias: gconstpointer void* -alias: gchar char -alias: guchar char -alias: gshort short -alias: gushort ushort -alias: gint8 byte -alias: guint8 ubyte -alias: gint16 short -alias: guint16 ushort -alias: gint32 int -alias: gint64 long -alias: guint32 uint -alias: guint64 ulong -alias: guintptr size_t -alias: gfloat float -alias: gdouble double -alias: goffset long -alias: gsize size_t -alias: gssize ptrdiff_t -alias: va_list void* -alias: unichar dchar -alias: unichar2 wchar -alias: uchar ubyte -alias: XID uint - -alias: gunichar dchar -alias: gunichar2 wchar - -alias: time_t uint -alias: uid_t uid_t - -alias: alias alias_ -alias: align alig -alias: body bod -alias: continue continu -alias: debug dbg -alias: default defaulx -alias: delete delet -alias: export expor -alias: foreach foreac -alias: function funct -alias: Function Funct -alias: in inn -alias: instance instanc -alias: interface iface -alias: module modul -alias: out output -alias: package p -alias: ref doref -alias: scope scop -alias: string str -alias: switch switc -alias: union unio -alias: version versio - -alias: GLIB_SYSDEF_POLLIN =1 -alias: GLIB_SYSDEF_POLLOUT =4 -alias: GLIB_SYSDEF_POLLPRI =2 -alias: GLIB_SYSDEF_POLLHUP =16 -alias: GLIB_SYSDEF_POLLERR =8 -alias: GLIB_SYSDEF_POLLNVAL =32 - -########################################################### -### predifined: lib -########################################################### - srcDir: . lookup: APILookupAppStream.txt -lookup: APILookupGLib.txt -lookup: APILookupGObject.txt -lookup: APILookupGio.txt -#lookup: APILookupGdkPixbuf.txt diff -Nru appstream-generator-0.7.3/contrib/girwrap/find-d-intf-files.py appstream-generator-0.7.4/contrib/girwrap/find-d-intf-files.py --- appstream-generator-0.7.3/contrib/girwrap/find-d-intf-files.py 2018-04-26 16:56:59.000000000 +0000 +++ appstream-generator-0.7.4/contrib/girwrap/find-d-intf-files.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,18 +0,0 @@ -#!/usr/bin/env python3 - -import os -import sys -import glob - -meson_build_root = os.environ.get('MESON_BUILD_ROOT') -meson_source_root = os.environ.get('MESON_SOURCE_ROOT') - -if not meson_build_root or not meson_source_root: - print('This script should only be run by the Meson build system.') - sys.exit(1) - -files = glob.glob(os.path.join(meson_build_root, 'girepo', '**', '*.d'), recursive=True) - -for fname in sorted(files): - # newer versions of Meson (>= 0.43) don't like absolute paths - print(os.path.relpath(fname, meson_source_root)) diff -Nru appstream-generator-0.7.3/data/asgen-hints.json appstream-generator-0.7.4/data/asgen-hints.json --- appstream-generator-0.7.3/data/asgen-hints.json 2018-04-26 16:56:59.000000000 +0000 +++ appstream-generator-0.7.4/data/asgen-hints.json 2018-08-04 08:40:54.000000000 +0000 @@ -179,8 +179,10 @@ "missing-desktop-file": { "text": ["Found an AppStream metainfo XML file, but the associated .desktop file is missing. This often happens when the .desktop file is renamed, but the", - "<id/> tag of the AppStream metainfo file is not adapted as well, or if the metainfo file is located in a different package than the .desktop file.
", - "Please fix the packaging or work with upstream to resolve this issue."], + "<launchable type=\"desktop-id\"/> tag value of the AppStream metainfo file is not adapted as well, or if the metainfo file is located in a different package than the .desktop file.
", + "Please fix the packaging or work with upstream to resolve this issue.
", + "For older metadata, the desktop-id is inferred from the <id/> tag. If the component metadata has no launchable tag and no", + "icon tag of type stock, check if a .desktop file named after the component-ID is located in the same package."], "severity": "error" }, diff -Nru appstream-generator-0.7.3/data/pangrams/en.txt appstream-generator-0.7.4/data/pangrams/en.txt --- appstream-generator-0.7.3/data/pangrams/en.txt 1970-01-01 00:00:00.000000000 +0000 +++ appstream-generator-0.7.4/data/pangrams/en.txt 2018-08-04 08:40:54.000000000 +0000 @@ -0,0 +1,24 @@ +A quick brown fox jumps over the lazy dog. +Whenever the black fox jumped the squirrel gazed suspiciously. +The five boxing wizards jump quickly. +A large fawn jumped quickly over white zebras in a box. +We quietly gave Bert a handsome prize for his six juicy pink plums. +Crazy Fredrick bought many very exquisite opal jewels. +Five or six big jet planes zoomed quickly past the tower. +My grandfather picks up quartz and valuable onyx jewels. +Sphinx of black quartz, judge my vow. +Two driven jocks help fax my big quiz. +Five quacking zephyrs jolt my wax bed. +Pack my box with five dozen liquor jugs. +Jinxed wizards pluck ivy from the big quilt. +We promptly judged antique ivory buckles for the next prize. +A mad boxer shot a quick, gloved jab to the jaw of his dizzy opponent. +Jaded zombies acted quaintly but kept driving their oxen forward. +The job requires extra pluck and zeal from every young wage earner. +Jived fox nymph grabs quick waltz. +How vexingly quick daft zebras jump! +Amazingly few discotheques provide jukeboxes. +The quick onyx goblin jumps over the lazy dwarf. +Six big devils from Japan quickly forgot how to waltz. +Jack amazed a few girls by dropping the antique onyx vase. +A quick movement of the enemy will jeopardize six gunboats. diff -Nru appstream-generator-0.7.3/debian/changelog appstream-generator-0.7.4/debian/changelog --- appstream-generator-0.7.3/debian/changelog 2018-04-26 17:04:02.000000000 +0000 +++ appstream-generator-0.7.4/debian/changelog 2018-08-04 08:52:48.000000000 +0000 @@ -1,3 +1,11 @@ +appstream-generator (0.7.4-1) unstable; urgency=medium + + * New upstream version: 0.7.4 + * Bump standards version: No changes needed + * Build-depend on GLibD instead of GLib + + -- Matthias Klumpp Sat, 04 Aug 2018 16:52:48 +0800 + appstream-generator (0.7.3-1) unstable; urgency=medium * New upstream version: 0.7.3 diff -Nru appstream-generator-0.7.3/debian/control appstream-generator-0.7.4/debian/control --- appstream-generator-0.7.3/debian/control 2018-04-26 17:04:02.000000000 +0000 +++ appstream-generator-0.7.4/debian/control 2018-08-04 08:52:48.000000000 +0000 @@ -6,7 +6,7 @@ dh-dlang, docbook-xsl, gir-to-d (>= 0.15), - libappstream-dev (>= 0.12.0), + libappstream-dev (>= 0.12.2), libarchive-dev (>= 3.2), libcairo2-dev, libcurl4-gnutls-dev | libcurl4-openssl-dev, @@ -15,7 +15,7 @@ libfreetype6-dev, libgdk-pixbuf2.0-dev, libgirepository1.0-dev, - libglib2.0-dev, + libglibd-2.0-dev, libjs-highlight.js, libjs-jquery-flot, liblmdb-dev, @@ -24,7 +24,7 @@ librsvg2-dev, meson (>= 0.46), xsltproc -Standards-Version: 4.1.4 +Standards-Version: 4.2.0 Homepage: https://github.com/ximion/appstream-generator Vcs-Git: https://salsa.debian.org/pkgutopia-team/appstream-generator.git Vcs-Browser: https://salsa.debian.org/pkgutopia-team/appstream-generator diff -Nru appstream-generator-0.7.3/meson.build appstream-generator-0.7.4/meson.build --- appstream-generator-0.7.3/meson.build 2018-04-26 16:56:59.000000000 +0000 +++ appstream-generator-0.7.4/meson.build 2018-08-04 08:40:54.000000000 +0000 @@ -1,8 +1,8 @@ project('AppStream Generator', 'd', - meson_version : '>=0.44', + meson_version : '>=0.46', subproject_dir : 'contrib/subprojects', license : 'LGPL-3.0+', - version : '0.7.3' + version : '0.7.4' ) asgen_version = meson.project_version() @@ -22,10 +22,8 @@ src_dir = include_directories('src/') dcontainers_dep = dependency('dcontainers', version: '>= 0.8.0', fallback: ['dcontainers', 'dcontainers_dep']) -glib_dep = dependency('glib-2.0') -gobject_dep = dependency('gobject-2.0') -gio_dep = dependency('gio-2.0') -appstream_dep = dependency('appstream', version : '>= 0.12.0') +glibd_dep = dependency('glibd-2.0') +appstream_dep = dependency('appstream', version : '>= 0.12.2') lmdb_dep = dependency('lmdb', version : '>= 0.9') mustache_dep = dependency('mustache-d', required: false) archive_dep = dependency('libarchive', version : '>= 3.2') @@ -51,26 +49,23 @@ gir_wrap_dir = source_root + '/contrib/girwrap/' gir_d_intf_dir = build_root + '/girepo/' -message('Generating D interfaces from GIR...') -girtod_gen = run_command(gir_to_d_prog.path(), +message('Generating AppStream D interfaces from GIR...') +girtod_gen = run_command(gir_to_d_prog, '-i', gir_wrap_dir, - '-o', gir_d_intf_dir) + '-o', gir_d_intf_dir, + '--print-files', 'relative,' + source_root) if girtod_gen.returncode() != 0 - error('Unable to build D intefaces from GIR:\n' + girtod_gen.stderr() + girtod_gen.stdout()) + error('Unable to build D intefaces from GIR:\n' + girtod_gen.stderr()) endif -gir_bind_dir = include_directories('girepo') -# Enlist D GIR interface sources -dgir_glob_script = run_command(source_root + '/contrib/girwrap/find-d-intf-files.py') -if dgir_glob_script.returncode() != 0 - error('Unable to find D GIR interface source code:\n' + dgir_glob_script.stdout() + dgir_glob_script.stderr()) -endif -gir_binding_sources = dgir_glob_script.stdout().strip().split('\n') +gir_bind_dir = include_directories('girepo') +gir_binding_sources = girtod_gen.stdout().strip().split('\n') # static library of bindings automatically generated from GIR girbind_lib = static_library('girbindings', [gir_binding_sources], - include_directories: [gir_bind_dir] + include_directories: [gir_bind_dir], + dependencies: [glibd_dep] ) # diff -Nru appstream-generator-0.7.3/NEWS appstream-generator-0.7.4/NEWS --- appstream-generator-0.7.3/NEWS 2018-04-26 16:56:59.000000000 +0000 +++ appstream-generator-0.7.4/NEWS 2018-08-04 08:40:54.000000000 +0000 @@ -1,3 +1,27 @@ +Version 0.7.4 +~~~~~~~~~~~~~~ +Released: 2018-08-04 + +Notes: + +Features: + * Write CID<->GCID mapping table as additional output data (Matthias Klumpp) + * Don't rebuild GLibD as part of asgen, use the shared library instead (Matthias Klumpp) + * Add hint to add launchable tag if .desktop file is missing (Matthias Klumpp) + * Use posix_spawn codepath for optipng if possible via GLib (Matthias Klumpp) + * Unconditionally add stock-type icon if desktop-file allows for it (Matthias Klumpp) + * Allow font languages to be specified in a languages tag (Matthias Klumpp) + * Improve font language processing with metainfo hints (Matthias Klumpp) + * fonts: Sort selected font styles, prefer regular style for samples (Matthias Klumpp) + * fonts: Use a random pangram for fonts supporting English (Matthias Klumpp) + * fonts: Assume 100% language support for all locale mentioned in font data (Matthias Klumpp) + +Bugfixes: + * Fix build with phobos 2.081 (Antonio Rojas) + * Depend on non-broken Meson version (Matthias Klumpp) + * fonts: Always prefer English for samples if font supports it (Matthias Klumpp) + * Initialize font icon lookup table only if there are fonts (Matthias Klumpp) + Version 0.7.3 ~~~~~~~~~~~~~~ Released: 2018-04-26 diff -Nru appstream-generator-0.7.3/README.md appstream-generator-0.7.4/README.md --- appstream-generator-0.7.3/README.md 2018-04-26 16:56:59.000000000 +0000 +++ appstream-generator-0.7.4/README.md 2018-08-04 08:40:54.000000000 +0000 @@ -17,36 +17,37 @@ * LDC[1] * Meson (>= 0.46) [2] - * glib2 (>= 2.46) - * AppStream [3] - * libarchive (>= 3.2) [4] - * LMDB [5] - * mustache-d [6] - * GirToD [7] - * Containers [8] + * GLibD [3] + * AppStream [4] + * libarchive (>= 3.2) [5] + * LMDB [6] + * mustache-d [7] + * GirToD [8] + * Containers [9] * Cairo * GdkPixbuf 2.0 * RSvg 2.0 * FreeType * Fontconfig * Pango - * Yarn (optional) [9] + * Yarn (optional) [10] [1]: https://github.com/ldc-developers/ldc/releases [2]: http://mesonbuild.com/ -[3]: https://github.com/ximion/appstream -[4]: https://libarchive.org/ -[5]: https://symas.com/lmdb/ -[6]: https://github.com/repeatedly/mustache-d -[7]: https://github.com/gtkd-developers/gir-to-d -[8]: https://github.com/dlang-community/containers -[9]: https://yarnpkg.com/ +[3]: https://github.com/gtkd-developers/GlibD +[4]: https://github.com/ximion/appstream +[5]: https://libarchive.org/ +[6]: https://symas.com/lmdb/ +[7]: https://github.com/repeatedly/mustache-d +[8]: https://github.com/gtkd-developers/gir-to-d +[9]: https://github.com/dlang-community/containers +[10]: https://yarnpkg.com/ On Debian and derivatives of it, all build requirements can be installed using the following command: ```ShellSession sudo apt install meson ldc gir-to-d libappstream-dev libgdk-pixbuf2.0-dev libarchive-dev \ - librsvg2-dev liblmdb-dev libglib2.0-dev libcairo2-dev libcurl4-gnutls-dev \ - libfreetype6-dev libfontconfig1-dev libpango1.0-dev libmustache-d-dev libdcontainers-dev + librsvg2-dev liblmdb-dev libcairo2-dev libcurl4-gnutls-dev libfreetype6-dev libfontconfig1-dev libpango1.0-dev \ + libglibd-2.0-dev libmustache-d-dev libdcontainers-dev ``` ### Build instructions diff -Nru appstream-generator-0.7.3/RELEASE appstream-generator-0.7.4/RELEASE --- appstream-generator-0.7.3/RELEASE 2018-04-26 16:56:59.000000000 +0000 +++ appstream-generator-0.7.4/RELEASE 2018-08-04 08:40:54.000000000 +0000 @@ -2,10 +2,10 @@ 1. Write NEWS entries for AppStream Generator in the same format as usual. -git shortlog v0.7.2.. | grep -i -v trivial | grep -v Merge > NEWS.new +git shortlog v0.7.3.. | grep -i -v trivial | grep -v Merge > NEWS.new -------------------------------------------------------------------------------- -Version 0.7.3 +Version 0.7.4 ~~~~~~~~~~~~~~ Released: 2018-xx-xx @@ -18,8 +18,8 @@ 2. Commit changes in Git: -git commit -a -m "Release version 0.7.3" -git tag -s -f -m "Release 0.7.3" v0.7.3 +git commit -a -m "Release version 0.7.4" +git tag -s -f -m "Release 0.7.4" v0.7.4 git push --tags git push @@ -33,7 +33,7 @@ 5. Send an email to appstream@lists.freedesktop.org ================================================= -AppStream Generator 0.7.3 released! +AppStream Generator 0.7.4 released! Tarballs available here: https://github.com/ximion/appstream-generator/releases diff -Nru appstream-generator-0.7.3/src/asgen/backends/ubuntu/ubupkg.d appstream-generator-0.7.4/src/asgen/backends/ubuntu/ubupkg.d --- appstream-generator-0.7.3/src/asgen/backends/ubuntu/ubupkg.d 2018-04-26 16:56:59.000000000 +0000 +++ appstream-generator-0.7.4/src/asgen/backends/ubuntu/ubupkg.d 2018-08-04 08:40:54.000000000 +0000 @@ -134,7 +134,7 @@ import core.stdc.locale : setlocale, LC_ALL; import core.stdc.string : strdup; - import std.c.stdlib : getenv, setenv, unsetenv; + import core.sys.posix.stdlib : getenv, setenv, unsetenv; import std.string : toStringz; char *[char *] env; diff -Nru appstream-generator-0.7.3/src/asgen/engine.d appstream-generator-0.7.4/src/asgen/engine.d --- appstream-generator-0.7.3/src/asgen/engine.d 2018-04-26 16:56:59.000000000 +0000 +++ appstream-generator-0.7.4/src/asgen/engine.d 2018-08-04 08:40:54.000000000 +0000 @@ -39,7 +39,7 @@ import asgen.result; import asgen.hint; import asgen.reportgenerator; -import asgen.utils : copyDir, stringArrayToByteArray; +import asgen.utils : copyDir, stringArrayToByteArray, getCidFromGlobalID; import asgen.backends.interfaces; import asgen.backends.dummy; @@ -347,6 +347,7 @@ mediaExportDir = dstore.mediaExportPoolDir; // collect metadata, icons and hints for the given packages + string[string] cidGcidMap; bool firstHintEntry = true; logDebug ("Building final metadata and hints files."); foreach (ref pkg; parallel (pkgs, 40)) { @@ -367,6 +368,8 @@ continue; foreach (ref gcid; gcids) { + synchronized (this) cidGcidMap[getCidFromGlobalID (gcid)] = gcid; + // Symlink data from the pool to the suite-specific directories if (useImmutableSuites) { immutable gcidMediaPoolPath = buildPath (dstore.mediaExportPoolDir, gcid); @@ -431,6 +434,7 @@ dataBaseFname = buildPath (dataExportDir, format ("Components-%s.xml", arch)); else dataBaseFname = buildPath (dataExportDir, format ("Components-%s.yml", arch)); + immutable cidIndexFname = buildPath (dataExportDir, format ("CID-Index-%s.json", arch)); immutable hintsBaseFname = buildPath (hintsExportDir, format ("Hints-%s.json", arch)); // write metadata @@ -445,6 +449,12 @@ compressAndSave (mdataFileBytes, dataBaseFname ~ ".gz", ArchiveType.GZIP); compressAndSave (mdataFileBytes, dataBaseFname ~ ".xz", ArchiveType.XZ); + // component ID index + import std.json : JSONValue, toJSON; + auto cidIndexJson = JSONValue (cidGcidMap); + auto cidIndexData = cast(ubyte[]) cidIndexJson.toJSON (true); + compressAndSave (cidIndexData, cidIndexFname ~ ".gz", ArchiveType.GZIP); + // write hints logInfo ("Writing hints for %s/%s [%s]", suite.name, section, arch); diff -Nru appstream-generator-0.7.3/src/asgen/font.d appstream-generator-0.7.4/src/asgen/font.d --- appstream-generator-0.7.3/src/asgen/font.d 2018-04-26 16:56:59.000000000 +0000 +++ appstream-generator-0.7.4/src/asgen/font.d 2018-08-04 08:40:54.000000000 +0000 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 Matthias Klumpp + * Copyright (C) 2016-2018 Matthias Klumpp * * Licensed under the GNU Lesser General Public License Version 3 * @@ -19,12 +19,13 @@ module asgen.font; -import std.string : format, fromStringz, toStringz, toLower, strip; +import std.string : format, fromStringz, toStringz, toLower, strip, splitLines; import std.conv : to; import std.path : buildPath, baseName; import std.array : empty, appender, replace; import std.algorithm : countUntil, remove; static import std.file; +import containers : HashSet; import asgen.bindings.freetype; import asgen.bindings.fontconfig; @@ -38,45 +39,15 @@ // determined on the command-line via: // fc-query --format='FN: %{fullname}\nFS: %{family[0]} %{style[0]}\n' +// global font icon text lookup table, initialized by the constructor or Font and valid (and in memory) +// as long as the generator runs. private static string[string] iconTexts; -// initialize module static data -shared static this () -{ - if (iconTexts.length != 0) - return; - synchronized - iconTexts = ["en": "Aa", - "ar": "أب", - "as": "অআই", - "bn": "অআই", - "be": "Аа", - "bg": "Аа", - "cs": "Aa", - "da": "Aa", - "de": "Aa", - "es": "Aa", - "fr": "Aa", - "gu": "અબક", - "hi": "अआइ", - "he": "אב", - "it": "Aa", - "kn": "ಅಆಇ", - "ml": "ആഇ", - "ne": "अआइ", - "nl": "Aa", - "or": "ଅଆଇ", - "pa": "ਅਆਇ", - "pl": "ĄĘ", - "pt": "Aa", - "ru": "Аа", - "sv": "Åäö", - "ta": "அஆஇ", - "te": "అఆఇ", - "ua": "Аа", - "zh-tw": "漢"]; -} +private static string[] englishPangrams = import("pangrams/en.txt").splitLines (); +/** + * Representation of a single font file. + */ final class Font { @@ -85,7 +56,8 @@ FT_Library library; FT_Face fface; - string[] languages_; + HashSet!string languages_; + string preferredLanguage_; string sampleText_; string sampleIconText_; @@ -98,10 +70,45 @@ this (string fname) { + languages_ = HashSet!string (16); + // NOTE: Freetype is completely non-threadsafe, but we only use it in the constructor. // So mark this section of code as synchronized to never run it in parallel (even having // two Font objects constructed in parallel may lead to errors) synchronized { + // initialize the global font icon lookup table + if (iconTexts.length == 0) { + iconTexts = ["en": "Aa", + "ar": "أب", + "as": "অআই", + "bn": "অআই", + "be": "Аа", + "bg": "Аа", + "cs": "Aa", + "da": "Aa", + "de": "Aa", + "es": "Aa", + "fr": "Aa", + "gu": "અબક", + "hi": "अआइ", + "he": "אב", + "it": "Aa", + "kn": "ಅಆಇ", + "ml": "ആഇ", + "ne": "अआइ", + "nl": "Aa", + "or": "ଅଆଇ", + "pa": "ਅਆਇ", + "pl": "ĄĘ", + "pt": "Aa", + "ru": "Аа", + "sv": "Åäö", + "ta": "அஆஇ", + "te": "అఆఇ", + "ua": "Аа", + "zh-tw": "漢"]; + } + initFreeType (); FT_Error err; @@ -109,8 +116,8 @@ if (err != 0) throw new Exception ("Unable to load font face from file. Error code: %s".format (err)); - loadFontConfigData (fname); - fileBaseName = fname.baseName; + loadFontConfigData (fname); + fileBaseName = fname.baseName; } } @@ -172,7 +179,7 @@ scope (exit) FcPatternDestroy (fpattern); // load information about the font - auto res = appender!(string[]); + languages_ = HashSet!string (16); auto anyLangAdded = false; auto match = true; @@ -192,7 +199,7 @@ char *tmp; FcStrListFirst (list); while ((tmp = FcStrListNext (list)) !is null) { - res ~= to!string (tmp.fromStringz); + languages_.put (to!string (tmp.fromStringz)); anyLangAdded = true; } } @@ -210,17 +217,13 @@ // assume 'en' is available if (!anyLangAdded) - res ~= "en"; - languages_ = res.data; + languages_.put ("en"); // prefer the English language if possible // this is a hack since some people don't set their // tag properly. - immutable enIndex = languages_.countUntil ("en"); - if (anyLangAdded && enIndex > 0) { - languages_ = languages_.remove (enIndex); - languages_ = "en" ~ languages_; - } + if (anyLangAdded && languages_.contains ("en")) + preferredLanguage = "en"; } @property @@ -275,10 +278,55 @@ return fface; } + auto getLanguageList () + { + import std.algorithm : sort; + import std.array : array; + + return array (languages_[]).sort; + } + + @property + void preferredLanguage (string lang) + { + preferredLanguage_ = lang; + } + @property - const(string[]) languages () const + string preferredLanguage () { - return languages_; + return preferredLanguage_; + } + + void addLanguage (string lang) + { + languages_.put (lang); + } + + private string randomEnglishPangram (const string tmpId) + { + import std.digest.crc : crc32Of; + import std.conv : to; + import std.bitmanip : peek; + import std.range : take; + + import std.stdio : writeln; + + // we do want deterministic results here, so base the "random" + // pangram on the font family / font base name + immutable ubyte[4] hash = crc32Of (tmpId); + immutable pangramIdx = hash.to!(ubyte[]).peek!uint % englishPangrams.length; + + return englishPangrams[pangramIdx]; + } + + private string randomEnglishPangram () + { + auto tmpFontId = this.family; + if (tmpFontId.empty) + tmpFontId = this.fileBaseName; + + return randomEnglishPangram (tmpFontId); } private void findSampleTexts () @@ -309,21 +357,34 @@ return g[0]; } + // always prefer English (even if not alphabetically first) + if (languages_.contains ("en")) + preferredLanguage = "en"; + + // ensure we try the preferred language first + auto tmpLangList = array(getLanguageList ()); + if (!preferredLanguage.empty) + tmpLangList = [this.preferredLanguage] ~ tmpLangList; + // determine our sample texts - foreach (ref lang; this.languages) { + foreach (ref lang; tmpLangList) { auto plang = pango_language_from_string (lang.toStringz); - auto text = pango_language_get_sample_string (plang).fromStringz; + string text; + if (lang == "en") + text = randomEnglishPangram (); + else + text = pango_language_get_sample_string (plang).fromStringz.to!string; - if (text is null) - continue; + if (text.empty) + continue; - sampleText_ = text.dup; - auto itP = lang in iconTexts; + sampleText_ = text; + const itP = lang in iconTexts; if (itP !is null) { sampleIconText_ = *itP; break; } - } + } // set some default values if we have been unable to find any texts setFallbackSampleTextIfRequired (); @@ -407,6 +468,7 @@ { import std.stdio : writeln, File; import std.path : buildPath; + import std.array : array; import asgen.utils : getTestSamplesDir; writeln ("TEST: ", "Font"); @@ -430,14 +492,24 @@ assert (font.style == "Regular"); assert (font.charset == FT_ENCODING_UNICODE); - writeln (font.languages); - assert (font.languages == ["en", "aa", "ab", "af", "ak", "an", "ast", "av", "ay", "az-az", "ba", "be", "ber-dz", "bg", "bi", "bin", "bm", "br", "bs", - "bua", "ca", "ce", "ch", "chm", "co", "crh", "cs", "csb", "cu", "cv", "cy", "da", "de", "ee", "el", "eo", "es", "et", "eu", - "fat", "ff", "fi", "fil", "fj", "fo", "fr", "fur", "fy", "ga", "gd", "gl", "gn", "gv", "ha", "haw", "ho", "hr", "hsb", "ht", - "hu", "hz", "ia", "id", "ie", "ig", "ik", "io", "is", "it", "jv", "kaa", "kab", "ki", "kj", "kk", "kl", "kr", "ku-am", "ku-tr", - "kum", "kv", "kw", "kwm", "ky", "la", "lb", "lez", "lg", "li", "ln", "lt", "lv", "mg", "mh", "mi", "mk", "mn-mn", "mo", "ms", "mt", - "na", "nb", "nds", "ng", "nl", "nn", "no", "nr", "nso", "nv", "ny", "oc", "om", "os", "pap-an", "pap-aw", "pl", "pt", "qu", "quz", - "rm", "rn", "ro", "ru", "rw", "sah", "sc", "sco", "se", "sel", "sg", "sh", "shs", "sk", "sl", "sm", "sma", "smj", "smn", "sms", "sn", - "so", "sq", "sr", "ss", "st", "su", "sv", "sw", "tg", "tk", "tl", "tn", "to", "tr", "ts", "tt", "tw", "ty", "tyv", "uk", "uz", "ve", - "vi", "vo", "vot", "wa", "wen", "wo", "xh", "yap", "yo", "za", "zu"]); + const langList = array (font.getLanguageList ()); + writeln (langList); + assert (langList == ["aa", "ab", "af", "ak", "an", "ast", "av", "ay", "az-az", "ba", "be", "ber-dz", "bg", "bi", "bin", + "bm", "br", "bs", "bua", "ca", "ce", "ch", "chm", "co", "crh", "cs", "csb", "cu", "cv", "cy", "da", + "de", "ee", "el", "en", "eo", "es", "et", "eu", "fat", "ff", "fi", "fil", "fj", "fo", "fr", "fur", + "fy", "ga", "gd", "gl", "gn", "gv", "ha", "haw", "ho", "hr", "hsb", "ht", "hu", "hz", "ia", "id", + "ie", "ig", "ik", "io", "is", "it", "jv", "kaa", "kab", "ki", "kj", "kk", "kl", "kr", "ku-am", + "ku-tr", "kum", "kv", "kw", "kwm", "ky", "la", "lb", "lez", "lg", "li", "ln", "lt","lv", "mg", "mh", + "mi", "mk", "mn-mn", "mo", "ms", "mt", "na", "nb", "nds", "ng", "nl", "nn", "no", "nr", "nso", "nv", + "ny", "oc", "om", "os", "pap-an", "pap-aw", "pl", "pt", "qu", "quz", "rm", "rn", "ro", "ru", "rw", + "sah", "sc", "sco", "se", "sel", "sg", "sh", "shs", "sk", "sl", "sm","sma", "smj", "smn", "sms", "sn", + "so", "sq", "sr", "ss", "st", "su", "sv", "sw", "tg", "tk", "tl", "tn", "to", "tr", "ts", "tt", "tw", + "ty", "tyv", "uk", "uz", "ve", "vi", "vo", "vot", "wa", "wen", "wo", "xh", "yap", "yo", "za", "zu"]); + + + // uses "Noto Sans" + assert (font.randomEnglishPangram () == "A large fawn jumped quickly over white zebras in a box."); + + assert (font.randomEnglishPangram ("aaaaa") == "Jack amazed a few girls by dropping the antique onyx vase."); + assert (font.randomEnglishPangram ("abcdefg") == "Two driven jocks help fax my big quiz."); } diff -Nru appstream-generator-0.7.3/src/asgen/handlers/fonthandler.d appstream-generator-0.7.4/src/asgen/handlers/fonthandler.d --- appstream-generator-0.7.3/src/asgen/handlers/fonthandler.d 2018-04-26 16:56:59.000000000 +0000 +++ appstream-generator-0.7.4/src/asgen/handlers/fonthandler.d 2018-08-04 08:40:54.000000000 +0000 @@ -115,9 +115,32 @@ // we found n this package. auto selectedFonts = appender!(Font[]); if (fontHints.data.length == 0) { + import std.algorithm : canFind, sort; + import std.array : array; + selectedFonts.reserve (allFonts.length); - foreach (ref font; allFonts.byValue) - selectedFonts ~= font; + + // prepend fonts that contain "regular" so we prefer the regular + // font face for rendering samples over the other styles + // also ensure that the font style list is sorted for more + // deterministic results + auto regularFound = false; + foreach (ref font; allFonts.byValue.array.sort!"a.fullName < b.fullName") { + immutable fontStyleId = font.style.toLower; + if (!regularFound && fontStyleId.canFind ("regular")) { + auto tmp = selectedFonts.data.dup; + selectedFonts.clear (); + selectedFonts ~= font; + selectedFonts ~= tmp; + + // if we found a font which has a style that equals "regular", + // we can stop searching for the preferred font + if (fontStyleId == "regular") + regularFound = true; + } else { + selectedFonts ~= font; + } + } } else { // find fonts based on the hints we have // the hint as well as the dictionary keys are all lowercased, so we @@ -138,6 +161,27 @@ return; } + // language information of fonts is often wrong. In case there was a metainfo file + // with languages explicitly set, we take the first language and prefer that over the others. + auto cptLanguages = cpt.getLanguages (); + if (cptLanguages !is null) { + auto firstLang = (cast(char*) cptLanguages.first.data).fromStringz; + + foreach (ref font; selectedFonts.data) + font.preferredLanguage = firstLang.to!string; + + // add languages mentioned in the metainfo file to list of supported languages + // of the respective font + auto item = cptLanguages.first.next; + while (item !is null) { + + foreach (ref font; selectedFonts.data) + font.addLanguage (to!string ((cast(char*) item.data).fromStringz)); + + item = item.next; + } + } + logDebug ("Rendering font data for %s", gcid); // process font files @@ -146,8 +190,10 @@ logDebug ("Processing font '%s'", font.id); // add language information - foreach (ref lang; font.languages) { - cpt.addLanguage (lang, 80); + foreach (ref lang; font.getLanguageList ()) { + // we have no idea how well the font supports the language's script, + // but since it adverties support in its metadata, we just assume 100% here + cpt.addLanguage (lang, 100); } // render an icon for our font diff -Nru appstream-generator-0.7.3/src/asgen/handlers/iconhandler.d appstream-generator-0.7.4/src/asgen/handlers/iconhandler.d --- appstream-generator-0.7.3/src/asgen/handlers/iconhandler.d 2018-04-26 16:56:59.000000000 +0000 +++ appstream-generator-0.7.4/src/asgen/handlers/iconhandler.d 2018-08-04 08:40:54.000000000 +0000 @@ -803,23 +803,26 @@ // search for the right icon iside the current package auto success = findAndStoreXdgIcon (gres.pkg); - if ((!success) && (!gres.isIgnored (cpt))) { + if (!success && !gres.isIgnored (cpt)) { // search in all packages success = findAndStoreXdgIcon (); - if (success) { + } + + if (success) { // we found a valid stock icon, so set that additionally to the cached one auto icon = new Icon (); icon.setKind (IconKind.STOCK); icon.setName (iconName); cpt.addIcon (icon); - } else if ((lastIconName !is null) && (!iconAllowed (lastIconName))) { + } else { + if ((lastIconName !is null) && (!iconAllowed (lastIconName))) { gres.addHint (cpt.getId (), "icon-format-unsupported", ["icon_fname": baseName (lastIconName)]); + return false; + } + if (lastIconName is null) { + gres.addHint (cpt.getId (), "icon-not-found", ["icon_fname": iconName]); + return false; } - } - - if ((!success) && (lastIconName is null)) { - gres.addHint (cpt.getId (), "icon-not-found", ["icon_fname": iconName]); - return false; } } diff -Nru appstream-generator-0.7.3/src/asgen/image.d appstream-generator-0.7.4/src/asgen/image.d --- appstream-generator-0.7.3/src/asgen/image.d 2018-04-26 16:56:59.000000000 +0000 +++ appstream-generator-0.7.4/src/asgen/image.d 2018-08-04 08:40:54.000000000 +0000 @@ -54,16 +54,40 @@ private void optimizePNG (string fname) { - import std.process; + import glib.Spawn : Spawn; auto conf = asgen.config.Config.get (); if (!conf.featureEnabled (GeneratorFeature.OPTIPNG)) return; - // NOTE: Maybe add an option to run optipng with stronger optimization? (>= -o4) - auto optipng = execute (["optipng", fname ]); - if (optipng.status != 0) - logWarning ("Optipng on '%s' failed with error code %s: %s", fname, optipng.status, optipng.output); + int exitStatus; + string opngStdout; + string opngStderr; + try { + // NOTE: Maybe add an option to run optipng with stronger optimization? (>= -o4) + Spawn.sync (null, // working directory + ["/usr/bin/optipng", fname ], // argv + [], // envp + SpawnFlags.LEAVE_DESCRIPTORS_OPEN, + null, // child setup + null, // user data + opngStdout, // out stdout + opngStderr, // out stderr + exitStatus); + } catch (Exception e) { + logError ("Failed to spawn optipng: %s", e.to!string); + return; + } + + if (exitStatus != 0) { + if (!opngStdout.empty) { + if (opngStderr.empty) + opngStderr = opngStdout; + else + opngStderr = opngStderr ~ "\n" ~ opngStdout; + } + logWarning ("Optipng on '%s' failed with error code %s: %s", fname, exitStatus, opngStderr); + } } /** diff -Nru appstream-generator-0.7.3/src/asgen/meson.build appstream-generator-0.7.4/src/asgen/meson.build --- appstream-generator-0.7.3/src/asgen/meson.build 2018-04-26 16:56:59.000000000 +0000 +++ appstream-generator-0.7.4/src/asgen/meson.build 2018-08-04 08:40:54.000000000 +0000 @@ -7,6 +7,8 @@ configuration: conf_data ) +data_import_dirs = include_directories('../../data') + # # Sources # @@ -80,9 +82,7 @@ include_directories: [src_dir, gir_bind_dir], dependencies: [dcontainers_dep, - glib_dep, - gobject_dep, - gio_dep, + glibd_dep, appstream_dep, lmdb_dep, archive_dep, @@ -95,6 +95,7 @@ fontconfig_dep, pango_dep], link_with: [girbind_lib], + d_import_dirs: [data_import_dirs], install: true ) @@ -104,9 +105,7 @@ include_directories: [src_dir, gir_bind_dir], dependencies: [dcontainers_dep, - glib_dep, - gobject_dep, - gio_dep, + glibd_dep, appstream_dep, lmdb_dep, archive_dep, @@ -119,6 +118,7 @@ fontconfig_dep, pango_dep], link_with: [girbind_lib], + d_import_dirs: [data_import_dirs], d_unittest: true ) test('asgen_tests', asgen_test_exe) diff -Nru appstream-generator-0.7.3/tests/ci/Dockerfile appstream-generator-0.7.4/tests/ci/Dockerfile --- appstream-generator-0.7.3/tests/ci/Dockerfile 2018-04-26 16:56:59.000000000 +0000 +++ appstream-generator-0.7.4/tests/ci/Dockerfile 2018-08-04 08:40:54.000000000 +0000 @@ -19,11 +19,13 @@ libglib2.0-dev \ libstemmer-dev \ libxml2-dev \ - libyaml-dev + libyaml-dev \ + gperf # install dependencies only for appstream-generator RUN apt-get install -yq --no-install-recommends \ gir-to-d \ + libglibd-2.0-dev \ libmustache-d-dev \ libcurl4-gnutls-dev \ liblmdb-dev \ diff -Nru appstream-generator-0.7.3/tests/ci/run-dscanner.py appstream-generator-0.7.4/tests/ci/run-dscanner.py --- appstream-generator-0.7.3/tests/ci/run-dscanner.py 2018-04-26 16:56:59.000000000 +0000 +++ appstream-generator-0.7.4/tests/ci/run-dscanner.py 2018-08-04 08:40:54.000000000 +0000 @@ -31,7 +31,8 @@ extra_inc = ['containers', 'stdx-allocator', - 'mustache-d'] + 'mustache-d', + 'glibd-2'] for d in extra_inc: for inc_root in ['/usr/include/d/', '/usr/local/include/d/']: