summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt57
-rw-r--r--Depends.cmake26
-rw-r--r--README.md4
-rw-r--r--Resources.cmake27
-rw-r--r--res/Fontpack.cmake19
-rw-r--r--res/MacOSXBundleInfo.plist.in4
-rw-r--r--res/about/version.gmi12
-rwxr-xr-xres/bincat.sh22
-rw-r--r--res/fontpack.ini (renamed from res/default.fontpack/fontpack.ini)22
-rw-r--r--res/fonts/IosevkaTerm-Extended.ttf (renamed from res/default.fontpack/IosevkaTerm-Extended.ttf)bin1503504 -> 1503504 bytes
-rw-r--r--res/fonts/LICENSE_OFL.txt (renamed from res/default.fontpack/LICENSE_OFL.txt)0
-rw-r--r--res/fonts/LICENSE_SmolEmoji.txt (renamed from res/default.fontpack/LICENSE_SmolEmoji.txt)0
-rw-r--r--res/fonts/NotoEmoji-Regular.ttf (renamed from res/default.fontpack/NotoEmoji-Regular.ttf)bin418804 -> 418804 bytes
-rw-r--r--res/fonts/NotoSansSymbols-Regular.ttf (renamed from res/default.fontpack/NotoSansSymbols-Regular.ttf)bin168520 -> 168520 bytes
-rw-r--r--res/fonts/NotoSansSymbols2-Regular.ttf (renamed from res/default.fontpack/NotoSansSymbols2-Regular.ttf)bin583072 -> 583072 bytes
-rw-r--r--res/fonts/SmolEmoji-Regular.ttf (renamed from res/default.fontpack/SmolEmoji-Regular.ttf)bin58544 -> 58544 bytes
-rw-r--r--res/fonts/SourceSans3-Bold.ttf (renamed from res/default.fontpack/SourceSans3-Bold.ttf)bin298256 -> 298256 bytes
-rw-r--r--res/fonts/SourceSans3-ExtraLight.ttf (renamed from res/default.fontpack/SourceSans3-ExtraLight.ttf)bin293932 -> 293932 bytes
-rw-r--r--res/fonts/SourceSans3-It.ttf (renamed from res/default.fontpack/SourceSans3-It.ttf)bin214992 -> 214992 bytes
-rw-r--r--res/fonts/SourceSans3-Regular.ttf (renamed from res/default.fontpack/SourceSans3-Regular.ttf)bin299252 -> 299252 bytes
-rw-r--r--res/fonts/SourceSans3-Semibold.ttf (renamed from res/default.fontpack/SourceSans3-Semibold.ttf)bin298888 -> 298888 bytes
-rw-r--r--src/app.c17
-rw-r--r--src/fontpack.c16
-rw-r--r--src/gmrequest.c16
-rw-r--r--src/gmutil.c4
-rw-r--r--src/lang.c60
-rw-r--r--src/macos.m22
-rw-r--r--src/main.c3
-rw-r--r--src/resources.c127
-rw-r--r--src/resources.h63
-rw-r--r--src/ui/root.c5
-rw-r--r--src/ui/text.c24
-rw-r--r--src/ui/window.c8
-rw-r--r--src/updater.c86
-rw-r--r--src/updater.h (renamed from res/bincat.c)30
35 files changed, 501 insertions, 173 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 314505c5..69b7c5c8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -18,7 +18,7 @@
18cmake_minimum_required (VERSION 3.9) 18cmake_minimum_required (VERSION 3.9)
19 19
20project (Lagrange 20project (Lagrange
21 VERSION 1.8.3 21 VERSION 1.9.0
22 DESCRIPTION "A Beautiful Gemini Client" 22 DESCRIPTION "A Beautiful Gemini Client"
23 LANGUAGES C 23 LANGUAGES C
24) 24)
@@ -29,7 +29,7 @@ if (IOS)
29 set (IOS_BUILD_DATE "2021-10-23") 29 set (IOS_BUILD_DATE "2021-10-23")
30endif () 30endif ()
31 31
32# Default that depend on environment. 32# Defaults that depend on environment.
33set (DEFAULT_RESIZE_DRAW ON) 33set (DEFAULT_RESIZE_DRAW ON)
34if (HAIKU) 34if (HAIKU)
35 set (DEFAULT_RESIZE_DRAW OFF) 35 set (DEFAULT_RESIZE_DRAW OFF)
@@ -52,20 +52,19 @@ option (ENABLE_MPG123 "Use mpg123 for decoding MPEG audio" ON)
52option (ENABLE_POPUP_MENUS "Use popup windows for context menus (if OFF, menus are confined inside main window)" ON) 52option (ENABLE_POPUP_MENUS "Use popup windows for context menus (if OFF, menus are confined inside main window)" ON)
53option (ENABLE_RELATIVE_EMBED "Resources should always be found via relative path" OFF) 53option (ENABLE_RELATIVE_EMBED "Resources should always be found via relative path" OFF)
54option (ENABLE_RESIZE_DRAW "Force window to redraw during resizing" ${DEFAULT_RESIZE_DRAW}) 54option (ENABLE_RESIZE_DRAW "Force window to redraw during resizing" ${DEFAULT_RESIZE_DRAW})
55option (ENABLE_RESOURCE_EMBED "Embed resources inside the executable" OFF) 55option (ENABLE_SPARKLE "Use Sparkle for automatic updates (macOS)" OFF)
56option (ENABLE_WEBP "Use libwebp to decode .webp images (via pkg-config)" ON) 56option (ENABLE_WEBP "Use libwebp to decode .webp images (via pkg-config)" ON)
57option (ENABLE_WINDOWPOS_FIX "Set position after showing window (workaround for SDL bug)" OFF) 57option (ENABLE_WINDOWPOS_FIX "Set position after showing window (workaround for SDL bug)" OFF)
58option (ENABLE_WINSPARKLE "Use WinSparkle for automatic updates (Windows)" OFF)
58option (ENABLE_X11_SWRENDER "Use software rendering (X11)" OFF) 59option (ENABLE_X11_SWRENDER "Use software rendering (X11)" OFF)
59 60
60include (BuildType.cmake) 61include (BuildType.cmake)
61include (res/Embed.cmake) 62include (Resources.cmake)
62include (res/Fontpack.cmake)
63include (Depends.cmake) 63include (Depends.cmake)
64 64
65# Package resources. 65# Package resources.
66message (STATUS "Preparing resources...") 66message (STATUS "Preparing resources...")
67make_fontpack (res/default.fontpack) 67set (RESOURCES
68set (EMBED_RESOURCES
69 res/about/about.gmi 68 res/about/about.gmi
70 res/about/help.gmi 69 res/about/help.gmi
71 res/about/lagrange.gmi 70 res/about/lagrange.gmi
@@ -94,14 +93,15 @@ set (EMBED_RESOURCES
94 res/lang/zh_Hans.bin 93 res/lang/zh_Hans.bin
95 res/lang/zh_Hant.bin 94 res/lang/zh_Hant.bin
96 res/shadow.png 95 res/shadow.png
97 ${CMAKE_BINARY_DIR}/default.fontpack 96 res/fontpack.ini
98) 97)
98file (GLOB FONTS RELATIVE ${CMAKE_SOURCE_DIR} res/fonts/*)
99list (APPEND RESOURCES ${FONTS})
99if ((UNIX AND NOT APPLE) OR MSYS) 100if ((UNIX AND NOT APPLE) OR MSYS)
100 list (APPEND EMBED_RESOURCES res/lagrange-64.png) 101 list (APPEND RESOURCES res/lagrange-64.png)
101endif () 102endif ()
102embed_make (${EMBED_RESOURCES})
103
104set (EMB_BIN ${CMAKE_CURRENT_BINARY_DIR}/resources.lgr) 103set (EMB_BIN ${CMAKE_CURRENT_BINARY_DIR}/resources.lgr)
104make_resources (${EMB_BIN} ${RESOURCES})
105set_source_files_properties (${EMB_BIN} PROPERTIES MACOSX_PACKAGE_LOCATION Resources) 105set_source_files_properties (${EMB_BIN} PROPERTIES MACOSX_PACKAGE_LOCATION Resources)
106 106
107# Source files. 107# Source files.
@@ -144,11 +144,14 @@ set (SOURCES
144 src/periodic.h 144 src/periodic.h
145 src/prefs.c 145 src/prefs.c
146 src/prefs.h 146 src/prefs.h
147 src/resources.c
148 src/resources.h
147 src/sitespec.c 149 src/sitespec.c
148 src/sitespec.h 150 src/sitespec.h
149 src/stb_image.h 151 src/stb_image.h
150 src/stb_image_resize.h 152 src/stb_image_resize.h
151 src/stb_truetype.h 153 src/stb_truetype.h
154 src/updater.h
152 src/visited.c 155 src/visited.c
153 src/visited.h 156 src/visited.h
154 # Audio playback: 157 # Audio playback:
@@ -219,10 +222,11 @@ set (SOURCES
219 res/about/lagrange.gmi 222 res/about/lagrange.gmi
220 res/about/license.gmi 223 res/about/license.gmi
221 res/about/version.gmi 224 res/about/version.gmi
222 ${CMAKE_CURRENT_BINARY_DIR}/embedded.c 225 ${EMB_BIN}
223 ${CMAKE_CURRENT_BINARY_DIR}/embedded.h
224 ${CMAKE_CURRENT_BINARY_DIR}/resources.lgr
225) 226)
227if (NOT APPLE) # macos.m has Sparkle updater
228 list (APPEND SOURCES src/updater.c)
229endif ()
226if (ENABLE_IPC) 230if (ENABLE_IPC)
227 list (APPEND SOURCES 231 list (APPEND SOURCES
228 src/ipc.c 232 src/ipc.c
@@ -363,6 +367,9 @@ if (APPLE)
363 else () 367 else ()
364 target_link_libraries (app PUBLIC "-framework AppKit") 368 target_link_libraries (app PUBLIC "-framework AppKit")
365 endif () 369 endif ()
370 if (ENABLE_SPARKLE)
371 target_link_libraries (app PUBLIC sparkle)
372 endif ()
366 if (CMAKE_OSX_DEPLOYMENT_TARGET AND NOT IOS) 373 if (CMAKE_OSX_DEPLOYMENT_TARGET AND NOT IOS)
367 target_compile_options (app PUBLIC -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}) 374 target_compile_options (app PUBLIC -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET})
368 target_link_options (app PUBLIC -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET}) 375 target_link_options (app PUBLIC -mmacosx-version-min=${CMAKE_OSX_DEPLOYMENT_TARGET})
@@ -406,6 +413,9 @@ if (APPLE)
406endif () 413endif ()
407if (MSYS) 414if (MSYS)
408 target_link_libraries (app PUBLIC d2d1 uuid dwmapi) # querying DPI 415 target_link_libraries (app PUBLIC d2d1 uuid dwmapi) # querying DPI
416 if (ENABLE_WINSPARKLE)
417 target_link_libraries (app PUBLIC winsparkle)
418 endif ()
409endif () 419endif ()
410if (UNIX) 420if (UNIX)
411 target_link_libraries (app PUBLIC m) 421 target_link_libraries (app PUBLIC m)
@@ -420,9 +430,7 @@ if (MSYS)
420 if (TARGET PkgConfig::MPG123) 430 if (TARGET PkgConfig::MPG123)
421 install (PROGRAMS ${MPG123_LIBDIR}/../bin/msys-mpg123-0.dll DESTINATION .) 431 install (PROGRAMS ${MPG123_LIBDIR}/../bin/msys-mpg123-0.dll DESTINATION .)
422 endif () 432 endif ()
423 if (NOT ENABLE_RESOURCE_EMBED) 433 install (FILES ${EMB_BIN} DESTINATION .)
424 install (FILES ${EMB_BIN} DESTINATION .)
425 endif ()
426 install (PROGRAMS 434 install (PROGRAMS
427 ${SDL2_LIBDIR}/SDL2.dll 435 ${SDL2_LIBDIR}/SDL2.dll
428 res/urlopen.bat 436 res/urlopen.bat
@@ -433,11 +441,9 @@ if (MSYS)
433 endif () 441 endif ()
434elseif (HAIKU) 442elseif (HAIKU)
435 install (TARGETS app DESTINATION .) 443 install (TARGETS app DESTINATION .)
436 if (NOT ENABLE_RESOURCE_EMBED) 444 target_compile_definitions (app PUBLIC
437 target_compile_definitions (app PUBLIC 445 LAGRANGE_EMB_BIN="${CMAKE_INSTALL_PREFIX}/resources.lgr")
438 LAGRANGE_EMB_BIN="${CMAKE_INSTALL_PREFIX}/resources.lgr") 446 install (FILES ${EMB_BIN} DESTINATION .)
439 install (FILES ${EMB_BIN} DESTINATION .)
440 endif ()
441elseif (UNIX AND NOT APPLE) 447elseif (UNIX AND NOT APPLE)
442 include (GNUInstallDirs) 448 include (GNUInstallDirs)
443 set_target_properties (app PROPERTIES 449 set_target_properties (app PROPERTIES
@@ -464,11 +470,10 @@ MimeType=x-scheme-handler/gemini;x-scheme-handler/gopher;
464 install (FILES res/fi.skyjake.Lagrange.appdata.xml 470 install (FILES res/fi.skyjake.Lagrange.appdata.xml
465 DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/metainfo 471 DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/metainfo
466 ) 472 )
467 if (NOT ENABLE_RESOURCE_EMBED) 473 if (NOT ENABLE_RELATIVE_EMBED)
468 if (NOT ENABLE_RELATIVE_EMBED) 474 target_compile_definitions (app PUBLIC
469 target_compile_definitions (app PUBLIC
470 LAGRANGE_EMB_BIN="${CMAKE_INSTALL_FULL_DATADIR}/lagrange/resources.lgr") 475 LAGRANGE_EMB_BIN="${CMAKE_INSTALL_FULL_DATADIR}/lagrange/resources.lgr")
471 endif () 476 endif ()
472 install (FILES ${EMB_BIN} DESTINATION ${CMAKE_INSTALL_DATADIR}/lagrange)
473 endif () 477 endif ()
478 install (FILES ${EMB_BIN} DESTINATION ${CMAKE_INSTALL_DATADIR}/lagrange)
474endif () 479endif ()
diff --git a/Depends.cmake b/Depends.cmake
index aaa2e8ea..0ea313f3 100644
--- a/Depends.cmake
+++ b/Depends.cmake
@@ -146,6 +146,32 @@ endif ()
146 146
147add_custom_target (ext-deps DEPENDS ${_dependsToBuild}) 147add_custom_target (ext-deps DEPENDS ${_dependsToBuild})
148 148
149if (ENABLE_SPARKLE)
150 # macOS only.
151 add_library (sparkle INTERFACE)
152 set (SPARKLE_FRAMEWORK ${SPARKLE_DIR}/Sparkle.framework)
153 target_link_libraries (sparkle INTERFACE ${SPARKLE_FRAMEWORK})
154 target_compile_definitions (sparkle INTERFACE LAGRANGE_ENABLE_SPARKLE=1)
155 message (STATUS "Using Sparkle: ${SPARKLE_FRAMEWORK}")
156 if (NOT SPARKLE_ARCH)
157 message (FATAL_ERROR "Set SPARKLE_ARCH to a CPU architecture ID (e.g., arm64)")
158 endif ()
159endif ()
160
161if (ENABLE_WINSPARKLE)
162 # Windows only.
163 add_library (winsparkle INTERFACE)
164 target_include_directories (winsparkle INTERFACE ${WINSPARKLE_DIR}/include)
165 set (WINSPARKLE_DLL ${WINSPARKLE_DIR}/x64/Release/WinSparkle.dll)
166 target_link_libraries (winsparkle INTERFACE ${WINSPARKLE_DLL})
167 target_compile_definitions (winsparkle INTERFACE LAGRANGE_ENABLE_WINSPARKLE=1)
168 install (
169 PROGRAMS ${WINSPARKLE_DLL}
170 DESTINATION .
171 )
172 message (STATUS "Using WinSparkle: ${WINSPARKLE_DLL}")
173endif ()
174
149find_package (PkgConfig REQUIRED) 175find_package (PkgConfig REQUIRED)
150pkg_check_modules (SDL2 REQUIRED sdl2) 176pkg_check_modules (SDL2 REQUIRED sdl2)
151pkg_check_modules (MPG123 IMPORTED_TARGET libmpg123) 177pkg_check_modules (MPG123 IMPORTED_TARGET libmpg123)
diff --git a/README.md b/README.md
index 5e66ea3c..9e68bf26 100644
--- a/README.md
+++ b/README.md
@@ -35,10 +35,10 @@ On openSUSE Tumbleweed:
35 35
36You need a POSIX-compatible environment to compile Lagrange. 36You need a POSIX-compatible environment to compile Lagrange.
37 37
38The required tools are a C11 compiler (e.g., Clang or GCC), CMake and `pkg-config`. Additional tools are required for the optional compilation of HarfBuzz and GNU FriBidi (see next section for details). 38The required tools are a C11 compiler (e.g., Clang or GCC), CMake, `pkg-config`, and `zip`. Additional tools are required for the optional compilation of HarfBuzz and GNU FriBidi (see next section for details).
39 39
401. Download and extract a source tarball from [Releases][rel]. Please note that the GitHub/Gitea-generated tarballs do not contain HarfBuzz, GNU FriBidi, or [the_Foundation](https://git.skyjake.fi/skyjake/the_Foundation) submodules; check which tarball you are getting. Alternatively, you may also clone the repository and its submodules: `git clone --recursive --branch release https://git.skyjake.fi/gemini/lagrange` 401. Download and extract a source tarball from [Releases][rel]. Please note that the GitHub/Gitea-generated tarballs do not contain HarfBuzz, GNU FriBidi, or [the_Foundation](https://git.skyjake.fi/skyjake/the_Foundation) submodules; check which tarball you are getting. Alternatively, you may also clone the repository and its submodules: `git clone --recursive --branch release https://git.skyjake.fi/gemini/lagrange`
412. Check that you have the recommended build tools and dependencies installed: CMake, SDL 2, OpenSSL 1.1.1, libpcre, libunistring, GNU FriBidi, and zlib. For example, on macOS this would do the trick (using Homebrew): ```brew install cmake sdl2 openssl@1.1 pcre libunistring fribidi``` Or on Ubuntu: ```sudo apt install cmake libsdl2-dev libssl-dev libpcre3-dev zlib1g-dev libunistring-dev libfribidi-dev``` 412. Check that you have the recommended build tools and dependencies installed: SDL 2, OpenSSL 1.1.1, libpcre, libunistring, GNU FriBidi, and zlib. For example, on macOS this would do the trick (using Homebrew): ```brew install cmake sdl2 openssl@1.1 pcre libunistring fribidi``` Or on Ubuntu: ```sudo apt install cmake zip libsdl2-dev libssl-dev libpcre3-dev zlib1g-dev libunistring-dev libfribidi-dev```
423. Optionally, install the mpg123 decoder library for MPEG audio support. For example, the macOS Homebrew package is `mpg123` and on Ubuntu it is `libmpg123-dev`. 423. Optionally, install the mpg123 decoder library for MPEG audio support. For example, the macOS Homebrew package is `mpg123` and on Ubuntu it is `libmpg123-dev`.
434. Create a build directory. 434. Create a build directory.
445. In your empty build directory, run CMake: ```cmake {path_of_lagrange_sources} -DCMAKE_BUILD_TYPE=Release``` 445. In your empty build directory, run CMake: ```cmake {path_of_lagrange_sources} -DCMAKE_BUILD_TYPE=Release```
diff --git a/Resources.cmake b/Resources.cmake
new file mode 100644
index 00000000..fc5d20c6
--- /dev/null
+++ b/Resources.cmake
@@ -0,0 +1,27 @@
1find_program (ZIP_EXECUTABLE zip DOC "ZIP archiver")
2if (NOT ZIP_EXECUTABLE)
3 message (FATAL_ERROR "Please install 'zip' for packaging resources.")
4endif ()
5
6function (make_resources dst)
7 list (REMOVE_AT ARGV 0)
8 set (files)
9 foreach (arg ${ARGV})
10 get_filename_component (name ${arg} NAME)
11 if (NOT "${name}" MATCHES "^\\..*")
12 string (SUBSTRING ${arg} 4 -1 rel)
13 list (APPEND files ${rel})
14 endif ()
15 endforeach (arg)
16 file (REMOVE ${dst})
17 get_filename_component (dstName ${dst} NAME)
18 message (STATUS " ${dstName}")
19 set (versionTempPath ${CMAKE_SOURCE_DIR}/res/VERSION)
20 file (WRITE ${versionTempPath} ${PROJECT_VERSION})
21 execute_process (
22 COMMAND ${ZIP_EXECUTABLE} -1 ${dst} VERSION ${files}
23 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/res
24 OUTPUT_QUIET
25 )
26 file (REMOVE ${versionTempPath})
27endfunction ()
diff --git a/res/Fontpack.cmake b/res/Fontpack.cmake
deleted file mode 100644
index 26d6df1e..00000000
--- a/res/Fontpack.cmake
+++ /dev/null
@@ -1,19 +0,0 @@
1find_program (ZIP_EXECUTABLE zip DOC "ZIP archiver")
2if (NOT ZIP_EXECUTABLE)
3 message (FATAL_ERROR "Please install 'zip' to create fontpacks.")
4endif ()
5
6function (make_fontpack src)
7 get_filename_component (dst ${src} NAME)
8 set (fn ${CMAKE_BINARY_DIR}/${dst})
9 execute_process (COMMAND ${CMAKE_COMMAND} -E remove ${fn})
10 file (GLOB files RELATIVE ${CMAKE_SOURCE_DIR}/${src}
11 ${CMAKE_SOURCE_DIR}/${src}/*
12 )
13 message (STATUS " ${src}")
14 execute_process (
15 COMMAND ${ZIP_EXECUTABLE} -0 ${fn} ${files}
16 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}/${src}
17 OUTPUT_QUIET
18 )
19endfunction ()
diff --git a/res/MacOSXBundleInfo.plist.in b/res/MacOSXBundleInfo.plist.in
index a17831ad..08907283 100644
--- a/res/MacOSXBundleInfo.plist.in
+++ b/res/MacOSXBundleInfo.plist.in
@@ -104,5 +104,9 @@
104 </array> 104 </array>
105 </dict> 105 </dict>
106 </array> 106 </array>
107 <key>SUFeedURL</key>
108 <string>https://etc.skyjake.fi/lagrange/appcast-${SPARKLE_ARCH}.xml</string>
109 <key>SUPublicEDKey</key>
110 <string>NK3VR3l8lypjm05VS4+Ry8A95rhmRzX+ftgQpzqYAy4=</string>
107</dict> 111</dict>
108</plist> 112</plist>
diff --git a/res/about/version.gmi b/res/about/version.gmi
index b5750c8c..a5e0d01f 100644
--- a/res/about/version.gmi
+++ b/res/about/version.gmi
@@ -6,6 +6,17 @@
6``` 6```
7# Release notes 7# Release notes
8 8
9# 1.9
10
11New features:
12* macOS: Automatic updates using the Sparkle framework.
13* Windows: Automatic updates using the WinSparkle library.
14
15Changes and enhancements:
16* The resource bundle (resources.lgr) is now a regular ZIP archive. This allows it to do double duty as a fontpack containing the built-in fonts. The archive contains a version number to avoid use of obsolete resources.
17
18Fixes:
19
9## 1.8.3 20## 1.8.3
10* Fixed clicking on UI elements that are over the page top banner. The banner would always get clicked instead. 21* Fixed clicking on UI elements that are over the page top banner. The banner would always get clicked instead.
11* Titan upload identity is remembered as a site-specific setting. It is no longer affected by selections in the Identities sidebar. 22* Titan upload identity is remembered as a site-specific setting. It is no longer affected by selections in the Identities sidebar.
@@ -43,7 +54,6 @@ New features:
43* Added warning message about missing font glyphs. 54* Added warning message about missing font glyphs.
44* Added warning message about terminal emulation. Lagrange supports a small subset of ANSI escape sequences, so page appearance may be incorrect when these are used in content. 55* Added warning message about terminal emulation. Lagrange supports a small subset of ANSI escape sequences, so page appearance may be incorrect when these are used in content.
45* Added tab close buttons. 56* Added tab close buttons.
46* Added style option to show links as bold regardless of visited status.
47* Added a feed subscription option to exclude web links (HTTP/HTTPS), since those are not viewable in the app by default. 57* Added a feed subscription option to exclude web links (HTTP/HTTPS), since those are not viewable in the app by default.
48* Added an automatic conversion of Markdown to Gemtext when viewing local files. (Not all Markdown features are supported.) 58* Added an automatic conversion of Markdown to Gemtext when viewing local files. (Not all Markdown features are supported.)
49* Added UI language for Ukrainian (uk). 59* Added UI language for Ukrainian (uk).
diff --git a/res/bincat.sh b/res/bincat.sh
deleted file mode 100755
index eb46655b..00000000
--- a/res/bincat.sh
+++ /dev/null
@@ -1,22 +0,0 @@
1#!/bin/bash
2# Binary Resource Concatenator
3# Copyright: 2021 Jaakko Keränen <jaakko.keranen@iki.fi>
4# License: BSD 2-Clause
5
6OUTPUT=--
7SIZES=""
8for fn in $*; do
9 if [ "$OUTPUT" = "--" ]; then
10 OUTPUT=$fn
11 rm -f ${OUTPUT}
12 else
13 vals=(`/bin/ls -l $fn`)
14 if [ "$SIZES" = "" ]; then
15 SIZES=${vals[4]}
16 else
17 SIZES=$SIZES\;${vals[4]}
18 fi
19 cat ${fn} >> ${OUTPUT}
20 fi
21done
22echo $SIZES
diff --git a/res/default.fontpack/fontpack.ini b/res/fontpack.ini
index 68316ef6..920a4ad2 100644
--- a/res/default.fontpack/fontpack.ini
+++ b/res/fontpack.ini
@@ -19,17 +19,17 @@
19 19
20[default] 20[default]
21name = "Source Sans" 21name = "Source Sans"
22regular = "SourceSans3-Regular.ttf" 22regular = "fonts/SourceSans3-Regular.ttf"
23italic = "SourceSans3-It.ttf" 23italic = "fonts/SourceSans3-It.ttf"
24light = "SourceSans3-ExtraLight.ttf" 24light = "fonts/SourceSans3-ExtraLight.ttf"
25semibold = "SourceSans3-Semibold.ttf" 25semibold = "fonts/SourceSans3-Semibold.ttf"
26bold = "SourceSans3-Bold.ttf" 26bold = "fonts/SourceSans3-Bold.ttf"
27 27
28[iosevka] 28[iosevka]
29name = "Iosevka (compact)" 29name = "Iosevka (compact)"
30monospace = true 30monospace = true
31doc.height = 0.800 31doc.height = 0.800
32regular = "IosevkaTerm-Extended.ttf" 32regular = "fonts/IosevkaTerm-Extended.ttf"
33 33
34[iosevka-body] 34[iosevka-body]
35# Variant of Iosevka with expanded line spacing for better readability. 35# Variant of Iosevka with expanded line spacing for better readability.
@@ -38,21 +38,21 @@ name = "Iosevka"
38monospace = true 38monospace = true
39priority = -10 39priority = -10
40glyphscale = 0.800 40glyphscale = 0.800
41regular = "IosevkaTerm-Extended.ttf" 41regular = "fonts/IosevkaTerm-Extended.ttf"
42 42
43[smolemoji] 43[smolemoji]
44name = "Smol Emoji" 44name = "Smol Emoji"
45override = true # These Emoji/symbols are always preferred. 45override = true # These Emoji/symbols are always preferred.
46auxiliary = true 46auxiliary = true
47priority = 100 47priority = 100
48regular = "SmolEmoji-Regular.ttf" 48regular = "fonts/SmolEmoji-Regular.ttf"
49 49
50[notoemoji] 50[notoemoji]
51name = "Noto Emoji" 51name = "Noto Emoji"
52auxiliary = true 52auxiliary = true
53priority = 30 53priority = 30
54glyphscale = 1.1 54glyphscale = 1.1
55regular = "NotoEmoji-Regular.ttf" 55regular = "fonts/NotoEmoji-Regular.ttf"
56 56
57[notosymbols2] 57[notosymbols2]
58name = "Noto Sans Symbols 2" 58name = "Noto Sans Symbols 2"
@@ -60,7 +60,7 @@ auxiliary = true
60priority = 20 60priority = 20
61glyphscale = 1.45 61glyphscale = 1.45
62voffset = 0.5 62voffset = 0.5
63regular = "NotoSansSymbols2-Regular.ttf" 63regular = "fonts/NotoSansSymbols2-Regular.ttf"
64 64
65[notosymbols] 65[notosymbols]
66name = "Noto Sans Symbols" 66name = "Noto Sans Symbols"
@@ -68,4 +68,4 @@ auxiliary = true
68priority = 10 68priority = 10
69glyphscale = 2.0 69glyphscale = 2.0
70voffset = 1.2 70voffset = 1.2
71regular = "NotoSansSymbols-Regular.ttf" 71regular = "fonts/NotoSansSymbols-Regular.ttf"
diff --git a/res/default.fontpack/IosevkaTerm-Extended.ttf b/res/fonts/IosevkaTerm-Extended.ttf
index 16989a85..16989a85 100644
--- a/res/default.fontpack/IosevkaTerm-Extended.ttf
+++ b/res/fonts/IosevkaTerm-Extended.ttf
Binary files differ
diff --git a/res/default.fontpack/LICENSE_OFL.txt b/res/fonts/LICENSE_OFL.txt
index d952d62c..d952d62c 100644
--- a/res/default.fontpack/LICENSE_OFL.txt
+++ b/res/fonts/LICENSE_OFL.txt
diff --git a/res/default.fontpack/LICENSE_SmolEmoji.txt b/res/fonts/LICENSE_SmolEmoji.txt
index 3513b65a..3513b65a 100644
--- a/res/default.fontpack/LICENSE_SmolEmoji.txt
+++ b/res/fonts/LICENSE_SmolEmoji.txt
diff --git a/res/default.fontpack/NotoEmoji-Regular.ttf b/res/fonts/NotoEmoji-Regular.ttf
index 19b7badf..19b7badf 100644
--- a/res/default.fontpack/NotoEmoji-Regular.ttf
+++ b/res/fonts/NotoEmoji-Regular.ttf
Binary files differ
diff --git a/res/default.fontpack/NotoSansSymbols-Regular.ttf b/res/fonts/NotoSansSymbols-Regular.ttf
index 68847551..68847551 100644
--- a/res/default.fontpack/NotoSansSymbols-Regular.ttf
+++ b/res/fonts/NotoSansSymbols-Regular.ttf
Binary files differ
diff --git a/res/default.fontpack/NotoSansSymbols2-Regular.ttf b/res/fonts/NotoSansSymbols2-Regular.ttf
index 79706435..79706435 100644
--- a/res/default.fontpack/NotoSansSymbols2-Regular.ttf
+++ b/res/fonts/NotoSansSymbols2-Regular.ttf
Binary files differ
diff --git a/res/default.fontpack/SmolEmoji-Regular.ttf b/res/fonts/SmolEmoji-Regular.ttf
index 3ab9484b..3ab9484b 100644
--- a/res/default.fontpack/SmolEmoji-Regular.ttf
+++ b/res/fonts/SmolEmoji-Regular.ttf
Binary files differ
diff --git a/res/default.fontpack/SourceSans3-Bold.ttf b/res/fonts/SourceSans3-Bold.ttf
index 486ede63..486ede63 100644
--- a/res/default.fontpack/SourceSans3-Bold.ttf
+++ b/res/fonts/SourceSans3-Bold.ttf
Binary files differ
diff --git a/res/default.fontpack/SourceSans3-ExtraLight.ttf b/res/fonts/SourceSans3-ExtraLight.ttf
index 53e1541c..53e1541c 100644
--- a/res/default.fontpack/SourceSans3-ExtraLight.ttf
+++ b/res/fonts/SourceSans3-ExtraLight.ttf
Binary files differ
diff --git a/res/default.fontpack/SourceSans3-It.ttf b/res/fonts/SourceSans3-It.ttf
index 9823601c..9823601c 100644
--- a/res/default.fontpack/SourceSans3-It.ttf
+++ b/res/fonts/SourceSans3-It.ttf
Binary files differ
diff --git a/res/default.fontpack/SourceSans3-Regular.ttf b/res/fonts/SourceSans3-Regular.ttf
index f6d31e8c..f6d31e8c 100644
--- a/res/default.fontpack/SourceSans3-Regular.ttf
+++ b/res/fonts/SourceSans3-Regular.ttf
Binary files differ
diff --git a/res/default.fontpack/SourceSans3-Semibold.ttf b/res/fonts/SourceSans3-Semibold.ttf
index d4774aab..d4774aab 100644
--- a/res/default.fontpack/SourceSans3-Semibold.ttf
+++ b/res/fonts/SourceSans3-Semibold.ttf
Binary files differ
diff --git a/src/app.c b/src/app.c
index 148bba52..abcf95da 100644
--- a/src/app.c
+++ b/src/app.c
@@ -23,7 +23,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
23#include "app.h" 23#include "app.h"
24#include "bookmarks.h" 24#include "bookmarks.h"
25#include "defs.h" 25#include "defs.h"
26#include "embedded.h" 26#include "resources.h"
27#include "feeds.h" 27#include "feeds.h"
28#include "mimehooks.h" 28#include "mimehooks.h"
29#include "gmcerts.h" 29#include "gmcerts.h"
@@ -33,6 +33,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
33#include "ipc.h" 33#include "ipc.h"
34#include "periodic.h" 34#include "periodic.h"
35#include "sitespec.h" 35#include "sitespec.h"
36#include "updater.h"
36#include "ui/certimportwidget.h" 37#include "ui/certimportwidget.h"
37#include "ui/color.h" 38#include "ui/color.h"
38#include "ui/command.h" 39#include "ui/command.h"
@@ -711,19 +712,17 @@ static void init_App_(iApp *d, int argc, char **argv) {
711 } 712 }
712 SDL_free(exec); 713 SDL_free(exec);
713 } 714 }
714#if defined (iHaveLoadEmbed)
715 /* Load the resources from a file. Check the executable directory first, then a 715 /* Load the resources from a file. Check the executable directory first, then a
716 system-wide location, and as a final fallback, the current working directory. */ { 716 system-wide location, and as a final fallback, the current working directory. */ {
717 if (!load_Embed(concatPath_CStr(cstr_String(execPath_App()), EMB_BIN2))) { 717 if (!init_Resources(concatPath_CStr(cstr_String(execPath_App()), EMB_BIN2))) {
718 if (!load_Embed(concatPath_CStr(cstr_String(execPath_App()), EMB_BIN))) { 718 if (!init_Resources(concatPath_CStr(cstr_String(execPath_App()), EMB_BIN))) {
719 if (!load_Embed("resources.lgr")) { 719 if (!init_Resources("resources.lgr")) {
720 fprintf(stderr, "failed to load resources: %s\n", strerror(errno)); 720 fprintf(stderr, "failed to load resources: %s\n", strerror(errno));
721 exit(-1); 721 exit(-1);
722 } 722 }
723 } 723 }
724 } 724 }
725 } 725 }
726#endif
727 init_Lang(); 726 init_Lang();
728 /* Configure the valid command line options. */ { 727 /* Configure the valid command line options. */ {
729 defineValues_CommandLine(&d->args, "close-tab", 0); 728 defineValues_CommandLine(&d->args, "close-tab", 0);
@@ -742,7 +741,7 @@ static void init_App_(iApp *d, int argc, char **argv) {
742 iStringList *openCmds = new_StringList(); 741 iStringList *openCmds = new_StringList();
743 /* Handle command line options. */ { 742 /* Handle command line options. */ {
744 if (contains_CommandLine(&d->args, "help")) { 743 if (contains_CommandLine(&d->args, "help")) {
745 puts(cstr_Block(&blobArghelp_Embedded)); 744 puts(cstr_Block(&blobArghelp_Resources));
746 terminate_App_(0); 745 terminate_App_(0);
747 } 746 }
748 if (contains_CommandLine(&d->args, "version;V")) { 747 if (contains_CommandLine(&d->args, "version;V")) {
@@ -3127,6 +3126,10 @@ iBool handleCommand_App(const char *cmd) {
3127 } 3126 }
3128 return iFalse; 3127 return iFalse;
3129 } 3128 }
3129 else if (equal_Command(cmd, "updater.check")) {
3130 checkNow_Updater();
3131 return iTrue;
3132 }
3130 else if (equal_Command(cmd, "fontpack.enable")) { 3133 else if (equal_Command(cmd, "fontpack.enable")) {
3131 const iString *packId = collect_String(suffix_Command(cmd, "id")); 3134 const iString *packId = collect_String(suffix_Command(cmd, "id"));
3132 enablePack_Fonts(packId, arg_Command(cmd)); 3135 enablePack_Fonts(packId, arg_Command(cmd));
diff --git a/src/fontpack.c b/src/fontpack.c
index bbf1833e..79f35526 100644
--- a/src/fontpack.c
+++ b/src/fontpack.c
@@ -21,7 +21,7 @@ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 21SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
22 22
23#include "fontpack.h" 23#include "fontpack.h"
24#include "embedded.h" 24#include "resources.h"
25#include "ui/window.h" 25#include "ui/window.h"
26#include "app.h" 26#include "app.h"
27 27
@@ -79,6 +79,15 @@ void init_FontFile(iFontFile *d) {
79 79
80static void load_FontFile_(iFontFile *d, const iBlock *data) { 80static void load_FontFile_(iFontFile *d, const iBlock *data) {
81 set_Block(&d->sourceData, data); 81 set_Block(&d->sourceData, data);
82#if 0
83 /* Count the number of available fonts. */
84 for (int i = 0; ; i++) {
85 if (stbtt_GetFontOffsetForIndex(constData_Block(&d->sourceData), i) < 0) {
86 printf("%s: contains %d fonts\n", cstr_String(&d->id), i);
87 break;
88 }
89 }
90#endif
82 const size_t offset = stbtt_GetFontOffsetForIndex(constData_Block(&d->sourceData), 91 const size_t offset = stbtt_GetFontOffsetForIndex(constData_Block(&d->sourceData),
83 d->colIndex); 92 d->colIndex);
84 stbtt_InitFont(&d->stbInfo, constData_Block(data), offset); 93 stbtt_InitFont(&d->stbInfo, constData_Block(data), offset);
@@ -581,11 +590,8 @@ void init_Fonts(const char *userDir) {
581 /* Load the required fonts. */ { 590 /* Load the required fonts. */ {
582 iFontPack *pack = new_FontPack(); 591 iFontPack *pack = new_FontPack();
583 setCStr_String(&pack->id, "default"); 592 setCStr_String(&pack->id, "default");
584 iArchive *arch = new_Archive();
585 setReadOnly_FontPack(pack, iTrue); 593 setReadOnly_FontPack(pack, iTrue);
586 openData_Archive(arch, &fontpackDefault_Embedded); 594 loadArchive_FontPack(pack, archive_Resources()); /* should never fail if we've made it this far */
587 loadArchive_FontPack(pack, arch); /* should never fail if we've made it this far */
588 iRelease(arch);
589 pushBack_PtrArray(&d->packs, pack); 595 pushBack_PtrArray(&d->packs, pack);
590 } 596 }
591 /* Find and load .fontpack files in known locations. */ { 597 /* Find and load .fontpack files in known locations. */ {
diff --git a/src/gmrequest.c b/src/gmrequest.c
index 03a6d999..23845475 100644
--- a/src/gmrequest.c
+++ b/src/gmrequest.c
@@ -29,7 +29,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
29#include "feeds.h" 29#include "feeds.h"
30#include "bookmarks.h" 30#include "bookmarks.h"
31#include "ui/text.h" 31#include "ui/text.h"
32#include "embedded.h" 32#include "resources.h"
33#include "defs.h" 33#include "defs.h"
34 34
35#include <the_Foundation/archive.h> 35#include <the_Foundation/archive.h>
@@ -344,19 +344,19 @@ static void requestFinished_GmRequest_(iGmRequest *d, iTlsRequest *req) {
344static const iBlock *aboutPageSource_(iRangecc path, iRangecc query) { 344static const iBlock *aboutPageSource_(iRangecc path, iRangecc query) {
345 const iBlock *src = NULL; 345 const iBlock *src = NULL;
346 if (equalCase_Rangecc(path, "about")) { 346 if (equalCase_Rangecc(path, "about")) {
347 return &blobAbout_Embedded; 347 return &blobAbout_Resources;
348 } 348 }
349 if (equalCase_Rangecc(path, "lagrange")) { 349 if (equalCase_Rangecc(path, "lagrange")) {
350 return &blobLagrange_Embedded; 350 return &blobLagrange_Resources;
351 } 351 }
352 if (equalCase_Rangecc(path, "help")) { 352 if (equalCase_Rangecc(path, "help")) {
353 return &blobHelp_Embedded; 353 return &blobHelp_Resources;
354 } 354 }
355 if (equalCase_Rangecc(path, "license")) { 355 if (equalCase_Rangecc(path, "license")) {
356 return &blobLicense_Embedded; 356 return &blobLicense_Resources;
357 } 357 }
358 if (equalCase_Rangecc(path, "version")) { 358 if (equalCase_Rangecc(path, "version")) {
359 return &blobVersion_Embedded; 359 return &blobVersion_Resources;
360 } 360 }
361 if (equalCase_Rangecc(path, "debug")) { 361 if (equalCase_Rangecc(path, "debug")) {
362 return utf8_String(debugInfo_App()); 362 return utf8_String(debugInfo_App());
@@ -396,7 +396,7 @@ static const iBlock *replaceVariables_(const iBlock *block) {
396#if 0 396#if 0
397 else if (startsWith_Rangecc(name, "BT:")) { /* block text */ 397 else if (startsWith_Rangecc(name, "BT:")) { /* block text */
398 repl = range_String(collect_String(renderBlockChars_Text( 398 repl = range_String(collect_String(renderBlockChars_Text(
399 &fontFiraSansRegular_Embedded, 399 &fontFiraSansRegular_Resources,
400 11, /* should be larger if shaded */ 400 11, /* should be larger if shaded */
401 quadrants_TextBlockMode, 401 quadrants_TextBlockMode,
402 &(iString){ iBlockLiteral( 402 &(iString){ iBlockLiteral(
@@ -404,7 +404,7 @@ static const iBlock *replaceVariables_(const iBlock *block) {
404 } 404 }
405 else if (startsWith_Rangecc(name, "ST:")) { /* shaded text */ 405 else if (startsWith_Rangecc(name, "ST:")) { /* shaded text */
406 repl = range_String(collect_String(renderBlockChars_Text( 406 repl = range_String(collect_String(renderBlockChars_Text(
407 &fontSmolEmojiRegular_Embedded, 407 &fontSmolEmojiRegular_Resources,
408 20, 408 20,
409 shading_TextBlockMode, 409 shading_TextBlockMode,
410 &(iString){ iBlockLiteral( 410 &(iString){ iBlockLiteral(
diff --git a/src/gmutil.c b/src/gmutil.c
index e0792d69..70a3608e 100644
--- a/src/gmutil.c
+++ b/src/gmutil.c
@@ -301,6 +301,10 @@ void urlEncodePath_String(iString *d) {
301 return; 301 return;
302 } 302 }
303 if (isEmpty_Range(&url.path)) { 303 if (isEmpty_Range(&url.path)) {
304 if (equalCase_Rangecc(url.scheme, "gemini") && url.path.start) {
305 /* Normalize to "/" as per specification (November 2021 update). */
306 insertData_Block(&d->chars, url.path.start - constBegin_String(d), "/", 1);
307 }
304 return; 308 return;
305 } 309 }
306 iString *encoded = new_String(); 310 iString *encoded = new_String();
diff --git a/src/lang.c b/src/lang.c
index 7b00f172..0bafb42b 100644
--- a/src/lang.c
+++ b/src/lang.c
@@ -21,7 +21,7 @@ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 21SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
22 22
23#include "lang.h" 23#include "lang.h"
24#include "embedded.h" 24#include "resources.h"
25 25
26#include <the_Foundation/sortedarray.h> 26#include <the_Foundation/sortedarray.h>
27#include <the_Foundation/string.h> 27#include <the_Foundation/string.h>
@@ -30,7 +30,7 @@ iDeclareType(Lang)
30iDeclareType(MsgStr) 30iDeclareType(MsgStr)
31 31
32struct Impl_MsgStr { 32struct Impl_MsgStr {
33 iRangecc id; /* these point to null-terminated strings in embedded data */ 33 iRangecc id; /* these point to null-terminated strings in resources */
34 iRangecc str; 34 iRangecc str;
35}; 35};
36 36
@@ -83,44 +83,44 @@ static void clear_Lang_(iLang *d) {
83} 83}
84 84
85static void load_Lang_(iLang *d, const char *id) { 85static void load_Lang_(iLang *d, const char *id) {
86 /* Load compiled language strings from an embedded blob. */ 86 /* Load compiled language strings from a resource blob. */
87 /* TODO: How about an array for these? (id, blob, pluralType) */ 87 /* TODO: How about an array for these? (id, blob, pluralType) */
88 iUnused(id); 88 iUnused(id);
89 const iBlock *data = equal_CStr(id, "fi") ? &blobFi_Embedded 89 const iBlock *data = equal_CStr(id, "fi") ? &blobFi_Resources
90 : equal_CStr(id, "fr") ? &blobFr_Embedded 90 : equal_CStr(id, "fr") ? &blobFr_Resources
91 : equal_CStr(id, "cs") ? &blobCs_Embedded 91 : equal_CStr(id, "cs") ? &blobCs_Resources
92 : equal_CStr(id, "ru") ? &blobRu_Embedded 92 : equal_CStr(id, "ru") ? &blobRu_Resources
93 : equal_CStr(id, "eo") ? &blobEo_Embedded 93 : equal_CStr(id, "eo") ? &blobEo_Resources
94 : equal_CStr(id, "es") ? &blobEs_Embedded 94 : equal_CStr(id, "es") ? &blobEs_Resources
95 : equal_CStr(id, "es_MX") ? &blobEs_MX_Embedded 95 : equal_CStr(id, "es_MX") ? &blobEs_MX_Resources
96 : equal_CStr(id, "de") ? &blobDe_Embedded 96 : equal_CStr(id, "de") ? &blobDe_Resources
97 : equal_CStr(id, "gl") ? &blobGl_Embedded 97 : equal_CStr(id, "gl") ? &blobGl_Resources
98 : equal_CStr(id, "hu") ? &blobHu_Embedded 98 : equal_CStr(id, "hu") ? &blobHu_Resources
99 : equal_CStr(id, "ia") ? &blobIa_Embedded 99 : equal_CStr(id, "ia") ? &blobIa_Resources
100 : equal_CStr(id, "ie") ? &blobIe_Embedded 100 : equal_CStr(id, "ie") ? &blobIe_Resources
101 : equal_CStr(id, "isv") ? &blobIsv_Embedded 101 : equal_CStr(id, "isv") ? &blobIsv_Resources
102 : equal_CStr(id, "pl") ? &blobPl_Embedded 102 : equal_CStr(id, "pl") ? &blobPl_Resources
103 : equal_CStr(id, "sk") ? &blobSk_Embedded 103 : equal_CStr(id, "sk") ? &blobSk_Resources
104 : equal_CStr(id, "sr") ? &blobSr_Embedded 104 : equal_CStr(id, "sr") ? &blobSr_Resources
105 : equal_CStr(id, "tok") ? &blobTok_Embedded 105 : equal_CStr(id, "tok") ? &blobTok_Resources
106 : equal_CStr(id, "uk") ? &blobUk_Embedded 106 : equal_CStr(id, "uk") ? &blobUk_Resources
107 : equal_CStr(id, "zh_Hans") ? &blobZh_Hans_Embedded 107 : equal_CStr(id, "zh_Hans") ? &blobZh_Hans_Resources
108 : equal_CStr(id, "zh_Hant") ? &blobZh_Hant_Embedded 108 : equal_CStr(id, "zh_Hant") ? &blobZh_Hant_Resources
109 : &blobEn_Embedded; 109 : &blobEn_Resources;
110 if (data == &blobRu_Embedded || data == &blobSr_Embedded || data == &blobUk_Embedded) { 110 if (data == &blobRu_Resources || data == &blobSr_Resources || data == &blobUk_Resources) {
111 d->pluralType = slavic_PluralType; 111 d->pluralType = slavic_PluralType;
112 } 112 }
113 else if (data == &blobIsv_Embedded) { 113 else if (data == &blobIsv_Resources) {
114 d->pluralType = oneTwoMany_PluralType; 114 d->pluralType = oneTwoMany_PluralType;
115 } 115 }
116 else if (data == &blobCs_Embedded || data == &blobSk_Embedded) { 116 else if (data == &blobCs_Resources || data == &blobSk_Resources) {
117 d->pluralType = oneFewMany_PluralType; 117 d->pluralType = oneFewMany_PluralType;
118 } 118 }
119 else if (data == &blobPl_Embedded) { 119 else if (data == &blobPl_Resources) {
120 d->pluralType = polish_PluralType; 120 d->pluralType = polish_PluralType;
121 } 121 }
122 else if (data == &blobZh_Hans_Embedded || data == &blobZh_Hant_Embedded || 122 else if (data == &blobZh_Hans_Resources || data == &blobZh_Hant_Resources ||
123 data == &blobTok_Embedded) { 123 data == &blobTok_Resources) {
124 d->pluralType = none_PluralType; 124 d->pluralType = none_PluralType;
125 } 125 }
126 else { 126 else {
diff --git a/src/macos.m b/src/macos.m
index 35594b7b..cfbca488 100644
--- a/src/macos.m
+++ b/src/macos.m
@@ -709,3 +709,25 @@ iColor systemAccent_Color(void) {
709#endif 709#endif
710 return (iColor){ 255, 255, 255, 255 }; 710 return (iColor){ 255, 255, 255, 255 };
711} 711}
712
713#if defined (LAGRANGE_ENABLE_SPARKLE)
714#import <Sparkle/Sparkle.h>
715
716void init_Updater(void) {
717 SUUpdater *updater = [SUUpdater sharedUpdater];
718 /* Add it to the menu. */
719 NSMenu *appMenu = [[[NSApp mainMenu] itemAtIndex:0] submenu];
720 NSMenuItem *item = [appMenu insertItemWithTitle:@"Check for Updates…"
721 action:@selector(checkForUpdates:)
722 keyEquivalent:@""
723 atIndex:3];
724 item.target = updater;
725}
726
727#else
728/* dummy as a fallback */
729void init_Updater(void) {}
730#endif
731
732void deinit_Updater(void) {}
733void checkNow_Updater(void) {}
diff --git a/src/main.c b/src/main.c
index f7ac6522..6e5e99e9 100644
--- a/src/main.c
+++ b/src/main.c
@@ -21,6 +21,7 @@ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 21SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
22 22
23#include "app.h" 23#include "app.h"
24#include "updater.h"
24 25
25#if defined (iPlatformAppleDesktop) 26#if defined (iPlatformAppleDesktop)
26# include "macos.h" 27# include "macos.h"
@@ -82,11 +83,13 @@ int main(int argc, char **argv) {
82 if (SDL_Init(SDL_INIT_AUDIO)) { 83 if (SDL_Init(SDL_INIT_AUDIO)) {
83 fprintf(stderr, "[SDL] audio init failed: %s\n", SDL_GetError()); 84 fprintf(stderr, "[SDL] audio init failed: %s\n", SDL_GetError());
84 } 85 }
86 init_Updater();
85 run_App(argc, argv); 87 run_App(argc, argv);
86 SDL_Quit(); 88 SDL_Quit();
87#if defined (LAGRANGE_ENABLE_MPG123) 89#if defined (LAGRANGE_ENABLE_MPG123)
88 mpg123_exit(); 90 mpg123_exit();
89#endif 91#endif
92 deinit_Updater();
90 deinit_Foundation(); 93 deinit_Foundation();
91 return 0; 94 return 0;
92} 95}
diff --git a/src/resources.c b/src/resources.c
new file mode 100644
index 00000000..24fbe214
--- /dev/null
+++ b/src/resources.c
@@ -0,0 +1,127 @@
1/* Copyright 2021 Jaakko Keränen <jaakko.keranen@iki.fi>
2
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions are met:
5
61. Redistributions of source code must retain the above copyright notice, this
7 list of conditions and the following disclaimer.
82. Redistributions in binary form must reproduce the above copyright notice,
9 this list of conditions and the following disclaimer in the documentation
10 and/or other materials provided with the distribution.
11
12THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
13ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
14WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
15DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
16ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
17(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
18LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
19ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
20(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
22
23#include "resources.h"
24
25#include <the_Foundation/archive.h>
26#include <the_Foundation/version.h>
27
28static iArchive *archive_;
29
30iBlock blobAbout_Resources;
31iBlock blobHelp_Resources;
32iBlock blobLagrange_Resources;
33iBlock blobLicense_Resources;
34iBlock blobVersion_Resources;
35iBlock blobArghelp_Resources;
36iBlock blobCs_Resources;
37iBlock blobDe_Resources;
38iBlock blobEn_Resources;
39iBlock blobEo_Resources;
40iBlock blobEs_Resources;
41iBlock blobEs_MX_Resources;
42iBlock blobFi_Resources;
43iBlock blobFr_Resources;
44iBlock blobGl_Resources;
45iBlock blobHu_Resources;
46iBlock blobIa_Resources;
47iBlock blobIe_Resources;
48iBlock blobIsv_Resources;
49iBlock blobPl_Resources;
50iBlock blobRu_Resources;
51iBlock blobSk_Resources;
52iBlock blobSr_Resources;
53iBlock blobTok_Resources;
54iBlock blobUk_Resources;
55iBlock blobZh_Hans_Resources;
56iBlock blobZh_Hant_Resources;
57iBlock imageShadow_Resources;
58iBlock imageLagrange64_Resources;
59
60static struct {
61 iBlock *data;
62 const char *archivePath;
63} entries_[] = {
64 { &blobAbout_Resources, "about/about.gmi" },
65 { &blobHelp_Resources, "about/help.gmi" },
66 { &blobLagrange_Resources, "about/lagrange.gmi" },
67 { &blobLicense_Resources, "about/license.gmi" },
68 { &blobVersion_Resources, "about/version.gmi" },
69 { &blobArghelp_Resources, "arg-help.txt" },
70 { &blobCs_Resources, "lang/cs.bin" },
71 { &blobDe_Resources, "lang/de.bin" },
72 { &blobEn_Resources, "lang/en.bin" },
73 { &blobEo_Resources, "lang/eo.bin" },
74 { &blobEs_Resources, "lang/es.bin" },
75 { &blobEs_MX_Resources, "lang/es_MX.bin" },
76 { &blobFi_Resources, "lang/fi.bin" },
77 { &blobFr_Resources, "lang/fr.bin" },
78 { &blobGl_Resources, "lang/gl.bin" },
79 { &blobHu_Resources, "lang/hu.bin" },
80 { &blobIa_Resources, "lang/ia.bin" },
81 { &blobIe_Resources, "lang/ie.bin" },
82 { &blobIsv_Resources, "lang/isv.bin" },
83 { &blobPl_Resources, "lang/pl.bin" },
84 { &blobRu_Resources, "lang/ru.bin" },
85 { &blobSk_Resources, "lang/sk.bin" },
86 { &blobSr_Resources, "lang/sr.bin" },
87 { &blobTok_Resources, "lang/tok.bin" },
88 { &blobUk_Resources, "lang/uk.bin" },
89 { &blobZh_Hans_Resources, "lang/zh_Hans.bin" },
90 { &blobZh_Hant_Resources, "lang/zh_Hant.bin" },
91 { &imageShadow_Resources, "shadow.png" },
92 { &imageLagrange64_Resources, "lagrange-64.png" },
93};
94
95iBool init_Resources(const char *path) {
96 archive_ = new_Archive();
97 if (openFile_Archive(archive_, collectNewCStr_String(path))) {
98 iVersion appVer;
99 init_Version(&appVer, range_CStr(LAGRANGE_APP_VERSION));
100 iVersion resVer;
101 init_Version(&resVer, range_Block(dataCStr_Archive(archive_, "VERSION")));
102 if (!cmp_Version(&resVer, &appVer)) {
103 iForIndices(i, entries_) {
104 const iBlock *data = dataCStr_Archive(archive_, entries_[i].archivePath);
105 if (data) {
106 initCopy_Block(entries_[i].data, data);
107 }
108 }
109 return iTrue;
110 }
111 fprintf(stderr, "[Resources] %s: version mismatch (%s != " LAGRANGE_APP_VERSION ")\n",
112 path, cstr_Block(dataCStr_Archive(archive_, "VERSION")));
113 }
114 iRelease(archive_);
115 return iFalse;
116}
117
118void deinit_Resources(void) {
119 iForIndices(i, entries_) {
120 deinit_Block(entries_[i].data);
121 }
122 iRelease(archive_);
123}
124
125const iArchive *archive_Resources(void) {
126 return archive_;
127}
diff --git a/src/resources.h b/src/resources.h
new file mode 100644
index 00000000..df5cac36
--- /dev/null
+++ b/src/resources.h
@@ -0,0 +1,63 @@
1/* Copyright 2021 Jaakko Keränen <jaakko.keranen@iki.fi>
2
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions are met:
5
61. Redistributions of source code must retain the above copyright notice, this
7 list of conditions and the following disclaimer.
82. Redistributions in binary form must reproduce the above copyright notice,
9 this list of conditions and the following disclaimer in the documentation
10 and/or other materials provided with the distribution.
11
12THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
13ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
14WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
15DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
16ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
17(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
18LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
19ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
20(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
22
23#pragma once
24
25#include <the_Foundation/block.h>
26
27iDeclareType(Archive)
28
29iBool init_Resources (const char *path);
30void deinit_Resources (void);
31
32const iArchive * archive_Resources (void);
33
34extern iBlock blobAbout_Resources;
35extern iBlock blobHelp_Resources;
36extern iBlock blobLagrange_Resources;
37extern iBlock blobLicense_Resources;
38extern iBlock blobVersion_Resources;
39extern iBlock blobArghelp_Resources;
40extern iBlock blobCs_Resources;
41extern iBlock blobDe_Resources;
42extern iBlock blobEn_Resources;
43extern iBlock blobEo_Resources;
44extern iBlock blobEs_Resources;
45extern iBlock blobEs_MX_Resources;
46extern iBlock blobFi_Resources;
47extern iBlock blobFr_Resources;
48extern iBlock blobGl_Resources;
49extern iBlock blobHu_Resources;
50extern iBlock blobIa_Resources;
51extern iBlock blobIe_Resources;
52extern iBlock blobIsv_Resources;
53extern iBlock blobPl_Resources;
54extern iBlock blobRu_Resources;
55extern iBlock blobSk_Resources;
56extern iBlock blobSr_Resources;
57extern iBlock blobTok_Resources;
58extern iBlock blobUk_Resources;
59extern iBlock blobZh_Hans_Resources;
60extern iBlock blobZh_Hant_Resources;
61extern iBlock imageShadow_Resources;
62extern iBlock fontpackDefault_Resources;
63extern iBlock imageLagrange64_Resources;
diff --git a/src/ui/root.c b/src/ui/root.c
index 95126654..4849d0c7 100644
--- a/src/ui/root.c
+++ b/src/ui/root.c
@@ -27,7 +27,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
27#include "command.h" 27#include "command.h"
28#include "defs.h" 28#include "defs.h"
29#include "documentwidget.h" 29#include "documentwidget.h"
30#include "embedded.h" 30#include "resources.h"
31#include "inputwidget.h" 31#include "inputwidget.h"
32#include "keys.h" 32#include "keys.h"
33#include "labelwidget.h" 33#include "labelwidget.h"
@@ -78,6 +78,9 @@ static const iMenuItem navMenuItems_[] = {
78 { gear_Icon " ${menu.preferences}", SDLK_COMMA, KMOD_PRIMARY, "preferences" }, 78 { gear_Icon " ${menu.preferences}", SDLK_COMMA, KMOD_PRIMARY, "preferences" },
79 { "${menu.help}", SDLK_F1, 0, "!open url:about:help" }, 79 { "${menu.help}", SDLK_F1, 0, "!open url:about:help" },
80 { "${menu.releasenotes}", 0, 0, "!open url:about:version" }, 80 { "${menu.releasenotes}", 0, 0, "!open url:about:version" },
81 #if defined (LAGRANGE_ENABLE_WINSPARKLE)
82 { "${menu.update}", 0, 0, "updater.check" },
83 #endif
81 { "---" }, 84 { "---" },
82 { "${menu.quit}", 'q', KMOD_PRIMARY, "quit" } 85 { "${menu.quit}", 'q', KMOD_PRIMARY, "quit" }
83}; 86};
diff --git a/src/ui/text.c b/src/ui/text.c
index abe8640c..91633f27 100644
--- a/src/ui/text.c
+++ b/src/ui/text.c
@@ -23,7 +23,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
23#include "text.h" 23#include "text.h"
24#include "color.h" 24#include "color.h"
25#include "metrics.h" 25#include "metrics.h"
26#include "embedded.h" 26#include "resources.h"
27#include "window.h" 27#include "window.h"
28#include "paint.h" 28#include "paint.h"
29#include "app.h" 29#include "app.h"
@@ -180,21 +180,21 @@ static void init_Font(iFont *d, const iFontSpec *fontSpec, const iFontFile *font
180 d->data = NULL; 180 d->data = NULL;
181 d->family = undefined_TextFont; 181 d->family = undefined_TextFont;
182 /* Note: We only use `family` currently for applying a kerning fix to Nunito. */ 182 /* Note: We only use `family` currently for applying a kerning fix to Nunito. */
183 if (data == &fontNunitoRegular_Embedded || 183 if (data == &fontNunitoRegular_Resources ||
184 data == &fontNunitoBold_Embedded || 184 data == &fontNunitoBold_Resources ||
185 data == &fontNunitoExtraBold_Embedded || 185 data == &fontNunitoExtraBold_Resources ||
186 //data == &fontNunitoLightItalic_Embedded || 186 //data == &fontNunitoLightItalic_Resources ||
187 data == &fontNunitoExtraLight_Embedded) { 187 data == &fontNunitoExtraLight_Resources) {
188 d->family = nunito_TextFont; 188 d->family = nunito_TextFont;
189 } 189 }
190 else if (//data == &fontScheherazadeNewRegular_Embedded) { 190 else if (//data == &fontScheherazadeNewRegular_Resources) {
191 data == &fontNotoSansArabicUIRegular_Embedded) { 191 data == &fontNotoSansArabicUIRegular_Resources) {
192 d->family = arabic_TextFont; 192 d->family = arabic_TextFont;
193 } 193 }
194 else if (data == &fontNotoSansSymbolsRegular_Embedded || 194 else if (data == &fontNotoSansSymbolsRegular_Resources ||
195 data == &fontNotoSansSymbols2Regular_Embedded || 195 data == &fontNotoSansSymbols2Regular_Resources ||
196 data == &fontNotoEmojiRegular_Embedded || 196 data == &fontNotoEmojiRegular_Resources ||
197 data == &fontSmolEmojiRegular_Embedded) { 197 data == &fontSmolEmojiRegular_Resources) {
198 d->family = emojiAndSymbols_TextFont; 198 d->family = emojiAndSymbols_TextFont;
199 } 199 }
200#endif 200#endif
diff --git a/src/ui/window.c b/src/ui/window.c
index fa364cff..2f6fe430 100644
--- a/src/ui/window.c
+++ b/src/ui/window.c
@@ -26,7 +26,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
26#include "bookmarks.h" 26#include "bookmarks.h"
27#include "command.h" 27#include "command.h"
28#include "defs.h" 28#include "defs.h"
29#include "embedded.h" 29#include "resources.h"
30#include "keys.h" 30#include "keys.h"
31#include "labelwidget.h" 31#include "labelwidget.h"
32#include "documentwidget.h" 32#include "documentwidget.h"
@@ -583,7 +583,7 @@ void init_MainWindow(iMainWindow *d, iRect rect) {
583#if defined (iPlatformLinux) 583#if defined (iPlatformLinux)
584 SDL_SetWindowMinimumSize(d->base.win, minSize.x * d->base.pixelRatio, minSize.y * d->base.pixelRatio); 584 SDL_SetWindowMinimumSize(d->base.win, minSize.x * d->base.pixelRatio, minSize.y * d->base.pixelRatio);
585 /* Load the window icon. */ { 585 /* Load the window icon. */ {
586 SDL_Surface *surf = loadImage_(&imageLagrange64_Embedded, 0); 586 SDL_Surface *surf = loadImage_(&imageLagrange64_Resources, 0);
587 SDL_SetWindowIcon(d->base.win, surf); 587 SDL_SetWindowIcon(d->base.win, surf);
588 free(surf->pixels); 588 free(surf->pixels);
589 SDL_FreeSurface(surf); 589 SDL_FreeSurface(surf);
@@ -597,7 +597,7 @@ void init_MainWindow(iMainWindow *d, iRect rect) {
597 setupUserInterface_MainWindow(d); 597 setupUserInterface_MainWindow(d);
598 postCommand_App("~bindings.changed"); /* update from bindings */ 598 postCommand_App("~bindings.changed"); /* update from bindings */
599 /* Load the border shadow texture. */ { 599 /* Load the border shadow texture. */ {
600 SDL_Surface *surf = loadImage_(&imageShadow_Embedded, 0); 600 SDL_Surface *surf = loadImage_(&imageShadow_Resources, 0);
601 d->base.borderShadow = SDL_CreateTextureFromSurface(d->base.render, surf); 601 d->base.borderShadow = SDL_CreateTextureFromSurface(d->base.render, surf);
602 SDL_SetTextureBlendMode(d->base.borderShadow, SDL_BLENDMODE_BLEND); 602 SDL_SetTextureBlendMode(d->base.borderShadow, SDL_BLENDMODE_BLEND);
603 free(surf->pixels); 603 free(surf->pixels);
@@ -607,7 +607,7 @@ void init_MainWindow(iMainWindow *d, iRect rect) {
607#if defined (LAGRANGE_ENABLE_CUSTOM_FRAME) 607#if defined (LAGRANGE_ENABLE_CUSTOM_FRAME)
608 /* Load the app icon for drawing in the title bar. */ 608 /* Load the app icon for drawing in the title bar. */
609 if (prefs_App()->customFrame) { 609 if (prefs_App()->customFrame) {
610 SDL_Surface *surf = loadImage_(&imageLagrange64_Embedded, appIconSize_Root()); 610 SDL_Surface *surf = loadImage_(&imageLagrange64_Resources, appIconSize_Root());
611 SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0"); 611 SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "0");
612 d->appIcon = SDL_CreateTextureFromSurface(d->base.render, surf); 612 d->appIcon = SDL_CreateTextureFromSurface(d->base.render, surf);
613 free(surf->pixels); 613 free(surf->pixels);
diff --git a/src/updater.c b/src/updater.c
new file mode 100644
index 00000000..706de31d
--- /dev/null
+++ b/src/updater.c
@@ -0,0 +1,86 @@
1/* Copyright 2021 Jaakko Keränen <jaakko.keranen@iki.fi>
2
3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions are met:
5
61. Redistributions of source code must retain the above copyright notice, this
7 list of conditions and the following disclaimer.
82. Redistributions in binary form must reproduce the above copyright notice,
9 this list of conditions and the following disclaimer in the documentation
10 and/or other materials provided with the distribution.
11
12THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
13ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
14WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
15DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
16ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
17(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
18LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
19ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
20(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
22
23#include "updater.h"
24
25#if defined (LAGRANGE_ENABLE_WINSPARKLE)
26#include <time.h>
27#include <winsparkle.h>
28
29static const char *signaturePublicKeyPem_ =
30 "-----BEGIN PUBLIC KEY-----\n"
31 "MIIGRjCCBDkGByqGSM44BAEwggQsAoICAQC0jSisyaT6q6qqjmlWFfFDOs66EfC7\n"
32 "78ATFlhl63otIed7oeyg2Q0BFB2bdGMpJbivu/jFjaZglz7YpKLhLHiUb3Fn10lz\n"
33 "V3WwaXXmbdwSuYH1zceIptho6crWgkZcSwGer+/I3twDxIe0XhGEG7quh7ukJsh/\n"
34 "hh9LgeIgNsVDdKRyJEs24ZQD44rQwb3hY19JCEzdd/S4FZwLbNeXwrPBPdzUO7JT\n"
35 "KmhMJJbQbhb1iNyqClCl5VQM0w5cI3L+k3fcBcUgsEh2kJHsH8ezATDH8Ltmvkmz\n"
36 "L8bhVLLHlGl0jvHfKHjINz9p/Ur+ifcFmwCWTmd61ZhEKcBpK0jEkE5ZwXzIZ3pJ\n"
37 "AAen0Nr0Y6x7rK5AU630wkQbD7M6W5QOys+9FPuIGW/q0nk80TKFR4ElVc0CVF0t\n"
38 "nOGa6lu6uaIkgKN+ePXUwSUFvYNOC/3ILURq9JnAPPGXwgIsOUTPtzPcBOfH24sy\n"
39 "HhImEaAZPdsx2eTiJv2zFwF0k5H/kPHQgyr+5dPaYSt+9yeObF4zQ7S/raqCRE/d\n"
40 "eT29MkwkGugXnljbSi0cjn1MCw9wQqLLwcea6KRWASzPmMMT8Ratrm1QWNvmPOaK\n"
41 "nijP+EVMPztnU4G3BAei7lnw8G3us+z0GzZ6RBR7siR4RIi4C7bngXygOYI7ekPT\n"
42 "WZui90VHORz3mQIhAJ7rakeaAPmDryZAHO9Ff2OmRibCO6WRrk16Z1m5lYU7AoIC\n"
43 "AEh0FdkF6OWNK1F44o9CKvE+vOr9SXu/gJ9JLm30Cfq/LPQ3lgOl13hYzAje/F8p\n"
44 "OATT0N0zkm3FmI7Kbw3ovUQ/Lot+UCvuv9ViIG98GZUldTyytKx3tRyuuRmXK3lS\n"
45 "7ugvt+XXo5sA9a3t6TJWMFJJCBRO+uizUs0m4uxb+rWnWv+AAUKDL/etbHxxKzo+\n"
46 "dIYRLgIaJtValVSkkik27Tw20+KEWKyy0H7EinIxn2iFVQ41j2jDwji931HJR5zI\n"
47 "fX0JG5nqcyfNj4m6o36n0yshAs13dJqyZiB4Y6pWb8TJf9GgnceBTWCIXH2nlL/C\n"
48 "UloCoVLfOTZ1hT4p1Wbou+5zlxwBS8/nZaiXecWm9srKDIwSB6zYLK9b2Eord197\n"
49 "34R0LKW9PsyHxnJvkip0oN4Fp9CltuN9VFbkc1k1nEiZh+etnh+m4eWnC5tzBGRx\n"
50 "Hh4GvKkVV43cIdIle4ht0Gt/6ex3bFAVmMmV4Z8767CnXJ9HPlksqQYRyLoolrJ0\n"
51 "X6GQ+8jZFaY36f+ViejbS7pHUl8s3OESfCAYwbipjSQZyPz+kfLjueEp0Klh7BHa\n"
52 "uRHHfM2FsxSkk+DO9fMUGNluC+5qvneccd7NvFfuPPgcD3OU9WBqKUfuKyXpkSMx\n"
53 "W1Oo5SqXi1sHirs3r6GFXqtW2LR+PD9Ve78L3Yd5rv9mA4ICBQACggIAPsdNd6rA\n"
54 "IlX1YI3OXyY+CVPJYBoAySWNa5H8JHEYC8ui4OB8gyge3S6utoF6m9lgU3evjqXy\n"
55 "dRYI/st6Eb5NESFrKPn1eH4r+2kU/34hshEA0yGjNGWzoXnhDCusGWGiZwq+Rr3v\n"
56 "Q5vI8T8lsnYuplCPGnoWJzq1niCPobVydog1lmZ396ARErGrPZxzM7ab8EY2BNSj\n"
57 "pcA1wYwuGGJIvCRLDxqaUlTbIdTP/QzIKQAHoFCtJetOmS5ovCyz9Zr+4fC/SFtq\n"
58 "G1BjTodIhQFrreGMwl3VtIOnrCUI430BxEPMsDWgZzgx5JgMwmgIVFul47MoulVE\n"
59 "gcz6sNKVuRXYhRTq8V6hZOamOT1VqZQb+dqQqDZ5p265VOgz71z1CgTF9FnRV04z\n"
60 "qhlWHHnxMEaQYZWlvw8zlXRNBqjHQyOHhOE9nsrNpTsFqnImBpO0s9UJxTRWNnf/\n"
61 "hLrzuOBQoDlOcE4yBR1mRymJQ9xHFzEI4yxP9Vg7RTEkMhhk1vlqPWvuIyv4gCCm\n"
62 "7btKMnYNL99cMAjhgyDyh7mAOfOWv5rAgzDIMViRO+U7EZ+ZRR+ovnuWMMn1OZAA\n"
63 "aXDKDVffI0NSO+Aw3EDAL4LfZsOBkDS2N/2ESR+EoBtYqoI7YJ3iu1iEHp8WxCyA\n"
64 "4YdR7KTyioKNHjvC5EG2bvHtYfw6ng6zSOY=\n"
65 "-----END PUBLIC KEY-----";
66
67void init_Updater(void) {
68 win_sparkle_set_appcast_url("https://etc.skyjake.fi/lagrange/appcast-windows.xml");
69 win_sparkle_set_dsa_pub_pem(signaturePublicKeyPem_);
70 win_sparkle_init();
71}
72
73void deinit_Updater(void) {
74 win_sparkle_cleanup();
75}
76
77void checkNow_Updater(void) {
78 win_sparkle_check_update_with_ui();
79}
80
81#else
82/* dummy as a fallback */
83void init_Updater(void) {}
84void deinit_Updater(void) {}
85void checkNow_Updater(void) {}
86#endif
diff --git a/res/bincat.c b/src/updater.h
index 8fc9d831..00cb8b7f 100644
--- a/res/bincat.c
+++ b/src/updater.h
@@ -1,4 +1,4 @@
1/* Copyright 2020 Jaakko Keränen <jaakko.keranen@iki.fi> 1/* Copyright 2021 Jaakko Keränen <jaakko.keranen@iki.fi>
2 2
3Redistribution and use in source and binary forms, with or without 3Redistribution and use in source and binary forms, with or without
4modification, are permitted provided that the following conditions are met: 4modification, are permitted provided that the following conditions are met:
@@ -20,29 +20,9 @@ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
20(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 20(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
21SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ 21SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
22 22
23/* bincat.c: Tiny tool for concatenating binary files */ 23#pragma once
24 24
25#include <stdio.h> 25void init_Updater (void);
26#include <stdlib.h> 26void deinit_Updater (void);
27 27
28int main(int argc, char *argv[]) { 28void checkNow_Updater (void);
29 const size_t bufSize = 1024 * 256;
30 char *buf = malloc(bufSize);
31 FILE *out = fopen(argv[1], "wb");
32 int i;
33 for (i = 2; i < argc; ++i) {
34 FILE *f = fopen(argv[i], "rb");
35 size_t fileSize = 0;
36 for (;;) {
37 size_t num = fread(buf, 1, bufSize, f);
38 if (num <= 0) break;
39 fileSize += num;
40 fwrite(buf, 1, num, out);
41 }
42 fclose(f);
43 printf("%zu;", fileSize);
44 }
45 fclose(out);
46 free(buf);
47 return 0;
48}