diff --git a/macos/Info.plist b/macos/Info.plist new file mode 100644 index 0000000..698aa49 --- /dev/null +++ b/macos/Info.plist @@ -0,0 +1,20 @@ + + + + + CFBundleExecutable + launcher.sh + CFBundleName + pw3270 + CFBundleDisplayName + pw3270 + CFBundleIconFile + pw3270.icns + CFBundleIdentifier + br.com.bb.pw3270 + NSHighResolutionCapable + + LSMinimumSystemVersion + 10.13.6 + + diff --git a/macos/bundle b/macos/bundle new file mode 100755 index 0000000..918937c --- /dev/null +++ b/macos/bundle @@ -0,0 +1,210 @@ +#!/usr/bin/env bash +#@author André Breves +set -Eeuo pipefail + +check_dependencies() { + local unavailable=() + for dependency in "${@:-$(&2 "Lib ${lib} not found" + exit 1 + fi + done +} + +bundle_cp() { + local system_libs='^(/System/.*|/usr/lib/.*)$' + + for source in "${@:-$(&2 "File \"${source}\" not found" + exit 1 + fi + + local id="" + local target="" + local file_type + file_type="$(file -b "${source}")" + case "${file_type}" in + *executable*) + target="$(greadlink -m "${exe_path}/$(basename "${source}")")";; + *) + id="@rpath/$(basename "${source}")" + target="$(greadlink -m "${lib_path}/$(basename "${source}")")";; + esac + + if [[ "${id}" != "" ]]; then echo "${id}"; fi + + if [[ -f "${target}" ]]; then continue; fi + + mkdir -p "$(dirname "${target}")" + cp "${source}" "${target}" + chmod u+w "${target}" + + if [[ "${id}" != "" ]]; then install_name_tool -id "${id}" "${target}"; fi + install_name_tool -add_rpath "@executable_path/../Frameworks" "${target}" + + for old_install_name in $(otool -L "${target}" | grep '^\t' | cut -c 2- | sed -n "s/\(.*\) (.*)/\1/p"); do + if [[ "${old_install_name}" == "${id}" ]]; then continue; fi + local lib="$(find_lib "${old_install_name}")" + local new_install_name="$(bundle_cp "${lib}")" + if [[ "${new_install_name}" != "" ]]; then + install_name_tool -change "${old_install_name}" "${new_install_name}" "${target}" + fi + done + echo >&2 "${target}" + done +} + +bundle_cache() { + local awaiting_file=1; + while IFS= read -r line; do + if (( awaiting_file )); then + if [[ ! "${line}" =~ ^"#" && "${line}" != "" ]]; then + line="${line##\ }" + line="${line#\"}" + line="${line%%\ }" + line="${line%\"}" + line="\"$(bundle_cp "${line}")\"" + awaiting_file=0 + fi + else + if [[ "${line}" == "" ]]; then + awaiting_file=1 + fi + fi + printf '%s\n' "${line}" + done +} + +# Check dependencies +check_dependencies otool grep cut sed greadlink qlmanage sips iconutil + +# Creates temporary directory +echo "Creating temporary directory" +tmp="$(mktemp -d)" +trap 'echo "Removing temporary directory \"${tmp}\""; rm -rf "${tmp}"' EXIT + +bundle="pw3270.app" +bundle_path="${bundle}/Contents" +exe_path="${bundle_path}/MacOS" +lib_path="${bundle_path}/Frameworks" +res_path="${bundle_path}/Resources" + +rm -fr "${bundle}" + +mkdir -p "${bundle_path}" +cp "Info.plist" "${bundle_path}" + +mkdir -p "${res_path}" +cp -r "../ui" "${res_path}" +cp -r "$(brew --prefix)/share/pw3270/remap" "${res_path}" +cp "$(brew --prefix)/share/pw3270/colors.conf" "${res_path}" + +# Bundle GLib schemas +echo "Bundling GLib schemas" +mkdir -p "${tmp}/schemas" +cp "../schemas/linux/"*".xml" "${tmp}/schemas" +cp "$(pkg-config gtk+-3.0 --variable=prefix)/share/glib-2.0/schemas/org.gtk.Settings."*".gschema.xml" "${tmp}/schemas" +glib-compile-schemas --targetdir="${res_path}" "${tmp}/schemas" + +# Create the GTK settings file +# https://developer.gnome.org/gtk3/stable/GtkSettings.html +mkdir -p "${res_path}/gtk-3.0" +cat > "${res_path}/gtk-3.0/settings.ini" << EOF +[Settings] +gtk-theme-name=Adwaita +gtk-print-preview-command="open -b com.apple.Preview %f" +EOF + +# Make icon bundle +echo "Creating app icon bundle" +iconset="${tmp}/pw3270.iconset" +rm -fr "${iconset}" +mkdir -p "${iconset}" +icon_sizes=("16" "32" "64" "128" "256" "512" "1024") +for ((i=1; i < ${#icon_sizes[*]}; i++)); do + size=${icon_sizes[$((i - 1))]} + convert -density "${size}" -resize "${size}x" -background transparent "../branding/pw3270.svg" "${iconset}/icon_${size}x${size}.png" + + size2x=${icon_sizes[${i}]} + convert -density "${size2x}" -resize "${size2x}x" -background transparent "../branding/pw3270.svg" "${iconset}/icon_${size}x${size}@2x.png" +done +iconutil -c icns -o "${res_path}/pw3270.icns" "${iconset}" + + +# Copy icons +mkdir -p "${res_path}/icons" +cp -r "$(brew --prefix adwaita-icon-theme)/share/icons/" "${res_path}/icons" +cp -r "$(brew --prefix hicolor-icon-theme)/share/icons/" "${res_path}/icons" +mogrify -format png -path "${res_path}" -background transparent "../branding/*.svg" + +# Copy themes +mkdir -p "${res_path}/themes" +cp -a "$(brew --prefix gtk+3)/share/themes/Mac" "${res_path}/themes" + +# Copy mime database +mkdir -p "${res_path}/mime" +cp "$(pkg-config shared-mime-info --variable=prefix)/share/mime/mime.cache" "${res_path}/mime" + +# Copy executables +mkdir -p "${exe_path}" +bundle_cp "../.bin/Release/pw3270" +cp "launcher.sh" "${exe_path}" + +# Bundle GdkPixbuf Image Loader Modules +gdk-pixbuf-query-loaders | bundle_cache > "${res_path}/gdk-loaders.cache" + +# Bundle GTK+ Input Method Modules +gtk_prefix="$(pkg-config gtk+-3.0 --variable prefix)" +gtk-query-immodules-3.0 | bundle_cache \ + | sed "s|${gtk_prefix}/share/locale|@executable_path/../Resources/locale|g" \ + > "${res_path}/gtk.immodules" + +# Bundle print backends +mkdir -p "${lib_path}/printbackends" +for backend in "$(pkg-config gtk+-3.0 --variable=prefix)/lib/gtk-3.0/$(pkg-config gtk+-3.0 --variable=gtk_binary_version)/printbackends/"*.so; do + bundle_cp "${backend}" + # TODO: update bundle_cp to inform destiny dir + mv "${lib_path}/$(basename "${backend}")" "${lib_path}/printbackends" +done + +# TODO: gerar o Info.plist com a versão do macOS $(sw_vers -productVersion) + +# Bundle locale +mkdir -p "${res_path}/locale" +cp -r "../.bin/locale/" "${res_path}/locale" +cp "$(brew --prefix)/share/locale/pt_BR/LC_MESSAGES/lib3270.mo" "${res_path}/locale/pt_BR/LC_MESSAGES" +cp "$(brew --prefix)/share/locale/pt_BR/LC_MESSAGES/libv3270.mo" "${res_path}/locale/pt_BR/LC_MESSAGES" diff --git a/macos/launcher.sh b/macos/launcher.sh new file mode 100755 index 0000000..4901273 --- /dev/null +++ b/macos/launcher.sh @@ -0,0 +1,65 @@ +#!/usr/bin/env sh +#@author André Breves +set -euo + +cd "${0%/*}" +executable_path="${PWD}" +cd .. +contents_path="${PWD}" +cd Resources +resource_path="${PWD}" + +info_plist="${contents_path}/Info.plist" +bundle_identifier=$(plutil -extract "CFBundleIdentifier" xml1 -o - "${info_plist}" | sed -n "s/.*\(.*\)<\/string>.*/\1/p") + +# XDG Base Directory Specification +# https://specifications.freedesktop.org/basedir-spec/latest/ar01s03.html + +# Defines the base directory relative to which user specific configuration files should be stored +export XDG_CONFIG_HOME="${HOME}/Library/Application Support/${bundle_identifier}" + +# Defines the base directory relative to which user specific data files should be stored +export XDG_DATA_HOME="${HOME}/Library/Application Support/${bundle_identifier}" + +# Defines the preference-ordered set of base directories to search for data files in addition to the $XDG_DATA_HOME base directory +export XDG_DATA_DIRS="${resource_path}" + +# Defines the preference-ordered set of base directories to search for configuration files in addition to the $XDG_CONFIG_HOME base directory +export XDG_CONFIG_DIRS="${resource_path}" + +# Defines the base directory relative to which user specific non-essential data files should be stored +export XDG_CACHE_HOME="${HOME}/Library/Caches/${bundle_identifier}" + + +# Running GTK+ Applications +# https://developer.gnome.org/gtk3/stable/gtk-running.html + +# If set, makes GTK+ use $GTK_DATA_PREFIX instead of the prefix configured when GTK+ was compiled +export GTK_DATA_PREFIX="${resource_path}" + +# Specifies the file listing the Input Method modules to load +export GTK_IM_MODULE_FILE="${resource_path}/gtk.immodules" + +# Specifies the file listing the GdkPixbuf loader modules to load +export GDK_PIXBUF_MODULE_FILE="${resource_path}/gdk-loaders.cache" + +# Specifies a list of directories to search when GTK+ is looking for dynamically loaded objects such as the modules +# specified by GTK_MODULES, theme engines, input method modules, file system backends and print backends. +export GTK_PATH="${contents_path}/Frameworks" + +# Running GIO applications +# https://developer.gnome.org/gio/stable/running-gio-apps.html + +# This variable can be set to the names of directories to consider when looking for compiled schemas for GSettings +export GSETTINGS_SCHEMA_DIR="${resource_path}" + +# export LANG="pt_BR" +# export LC_MESSAGES="pt_BR" +# export LC_ALL="pt_BR" + +mkdir -p "${XDG_CONFIG_HOME}" +mkdir -p "${XDG_DATA_HOME}" +mkdir -p "${XDG_CACHE_HOME}" + +cd "${resource_path}" +exec "${executable_path}/pw3270" -- libgit2 0.21.2