diff options
-rw-r--r-- | CMakeLists.txt | 57 | ||||
-rw-r--r-- | Depends.cmake | 26 | ||||
-rw-r--r-- | README.md | 4 | ||||
-rw-r--r-- | Resources.cmake | 27 | ||||
-rw-r--r-- | res/Fontpack.cmake | 19 | ||||
-rw-r--r-- | res/MacOSXBundleInfo.plist.in | 4 | ||||
-rw-r--r-- | res/about/version.gmi | 12 | ||||
-rwxr-xr-x | res/bincat.sh | 22 | ||||
-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) | bin | 1503504 -> 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) | bin | 418804 -> 418804 bytes | |||
-rw-r--r-- | res/fonts/NotoSansSymbols-Regular.ttf (renamed from res/default.fontpack/NotoSansSymbols-Regular.ttf) | bin | 168520 -> 168520 bytes | |||
-rw-r--r-- | res/fonts/NotoSansSymbols2-Regular.ttf (renamed from res/default.fontpack/NotoSansSymbols2-Regular.ttf) | bin | 583072 -> 583072 bytes | |||
-rw-r--r-- | res/fonts/SmolEmoji-Regular.ttf (renamed from res/default.fontpack/SmolEmoji-Regular.ttf) | bin | 58544 -> 58544 bytes | |||
-rw-r--r-- | res/fonts/SourceSans3-Bold.ttf (renamed from res/default.fontpack/SourceSans3-Bold.ttf) | bin | 298256 -> 298256 bytes | |||
-rw-r--r-- | res/fonts/SourceSans3-ExtraLight.ttf (renamed from res/default.fontpack/SourceSans3-ExtraLight.ttf) | bin | 293932 -> 293932 bytes | |||
-rw-r--r-- | res/fonts/SourceSans3-It.ttf (renamed from res/default.fontpack/SourceSans3-It.ttf) | bin | 214992 -> 214992 bytes | |||
-rw-r--r-- | res/fonts/SourceSans3-Regular.ttf (renamed from res/default.fontpack/SourceSans3-Regular.ttf) | bin | 299252 -> 299252 bytes | |||
-rw-r--r-- | res/fonts/SourceSans3-Semibold.ttf (renamed from res/default.fontpack/SourceSans3-Semibold.ttf) | bin | 298888 -> 298888 bytes | |||
-rw-r--r-- | src/app.c | 17 | ||||
-rw-r--r-- | src/fontpack.c | 16 | ||||
-rw-r--r-- | src/gmrequest.c | 16 | ||||
-rw-r--r-- | src/gmutil.c | 4 | ||||
-rw-r--r-- | src/lang.c | 60 | ||||
-rw-r--r-- | src/macos.m | 22 | ||||
-rw-r--r-- | src/main.c | 3 | ||||
-rw-r--r-- | src/resources.c | 127 | ||||
-rw-r--r-- | src/resources.h | 63 | ||||
-rw-r--r-- | src/ui/root.c | 5 | ||||
-rw-r--r-- | src/ui/text.c | 24 | ||||
-rw-r--r-- | src/ui/window.c | 8 | ||||
-rw-r--r-- | src/updater.c | 86 | ||||
-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 @@ | |||
18 | cmake_minimum_required (VERSION 3.9) | 18 | cmake_minimum_required (VERSION 3.9) |
19 | 19 | ||
20 | project (Lagrange | 20 | project (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") |
30 | endif () | 30 | endif () |
31 | 31 | ||
32 | # Default that depend on environment. | 32 | # Defaults that depend on environment. |
33 | set (DEFAULT_RESIZE_DRAW ON) | 33 | set (DEFAULT_RESIZE_DRAW ON) |
34 | if (HAIKU) | 34 | if (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) | |||
52 | option (ENABLE_POPUP_MENUS "Use popup windows for context menus (if OFF, menus are confined inside main window)" ON) | 52 | option (ENABLE_POPUP_MENUS "Use popup windows for context menus (if OFF, menus are confined inside main window)" ON) |
53 | option (ENABLE_RELATIVE_EMBED "Resources should always be found via relative path" OFF) | 53 | option (ENABLE_RELATIVE_EMBED "Resources should always be found via relative path" OFF) |
54 | option (ENABLE_RESIZE_DRAW "Force window to redraw during resizing" ${DEFAULT_RESIZE_DRAW}) | 54 | option (ENABLE_RESIZE_DRAW "Force window to redraw during resizing" ${DEFAULT_RESIZE_DRAW}) |
55 | option (ENABLE_RESOURCE_EMBED "Embed resources inside the executable" OFF) | 55 | option (ENABLE_SPARKLE "Use Sparkle for automatic updates (macOS)" OFF) |
56 | option (ENABLE_WEBP "Use libwebp to decode .webp images (via pkg-config)" ON) | 56 | option (ENABLE_WEBP "Use libwebp to decode .webp images (via pkg-config)" ON) |
57 | option (ENABLE_WINDOWPOS_FIX "Set position after showing window (workaround for SDL bug)" OFF) | 57 | option (ENABLE_WINDOWPOS_FIX "Set position after showing window (workaround for SDL bug)" OFF) |
58 | option (ENABLE_WINSPARKLE "Use WinSparkle for automatic updates (Windows)" OFF) | ||
58 | option (ENABLE_X11_SWRENDER "Use software rendering (X11)" OFF) | 59 | option (ENABLE_X11_SWRENDER "Use software rendering (X11)" OFF) |
59 | 60 | ||
60 | include (BuildType.cmake) | 61 | include (BuildType.cmake) |
61 | include (res/Embed.cmake) | 62 | include (Resources.cmake) |
62 | include (res/Fontpack.cmake) | ||
63 | include (Depends.cmake) | 63 | include (Depends.cmake) |
64 | 64 | ||
65 | # Package resources. | 65 | # Package resources. |
66 | message (STATUS "Preparing resources...") | 66 | message (STATUS "Preparing resources...") |
67 | make_fontpack (res/default.fontpack) | 67 | set (RESOURCES |
68 | set (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 | ) |
98 | file (GLOB FONTS RELATIVE ${CMAKE_SOURCE_DIR} res/fonts/*) | ||
99 | list (APPEND RESOURCES ${FONTS}) | ||
99 | if ((UNIX AND NOT APPLE) OR MSYS) | 100 | if ((UNIX AND NOT APPLE) OR MSYS) |
100 | list (APPEND EMBED_RESOURCES res/lagrange-64.png) | 101 | list (APPEND RESOURCES res/lagrange-64.png) |
101 | endif () | 102 | endif () |
102 | embed_make (${EMBED_RESOURCES}) | ||
103 | |||
104 | set (EMB_BIN ${CMAKE_CURRENT_BINARY_DIR}/resources.lgr) | 103 | set (EMB_BIN ${CMAKE_CURRENT_BINARY_DIR}/resources.lgr) |
104 | make_resources (${EMB_BIN} ${RESOURCES}) | ||
105 | set_source_files_properties (${EMB_BIN} PROPERTIES MACOSX_PACKAGE_LOCATION Resources) | 105 | set_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 | ) |
227 | if (NOT APPLE) # macos.m has Sparkle updater | ||
228 | list (APPEND SOURCES src/updater.c) | ||
229 | endif () | ||
226 | if (ENABLE_IPC) | 230 | if (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) | |||
406 | endif () | 413 | endif () |
407 | if (MSYS) | 414 | if (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 () | ||
409 | endif () | 419 | endif () |
410 | if (UNIX) | 420 | if (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 () |
434 | elseif (HAIKU) | 442 | elseif (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 () | ||
441 | elseif (UNIX AND NOT APPLE) | 447 | elseif (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) | ||
474 | endif () | 479 | endif () |
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 | ||
147 | add_custom_target (ext-deps DEPENDS ${_dependsToBuild}) | 147 | add_custom_target (ext-deps DEPENDS ${_dependsToBuild}) |
148 | 148 | ||
149 | if (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 () | ||
159 | endif () | ||
160 | |||
161 | if (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}") | ||
173 | endif () | ||
174 | |||
149 | find_package (PkgConfig REQUIRED) | 175 | find_package (PkgConfig REQUIRED) |
150 | pkg_check_modules (SDL2 REQUIRED sdl2) | 176 | pkg_check_modules (SDL2 REQUIRED sdl2) |
151 | pkg_check_modules (MPG123 IMPORTED_TARGET libmpg123) | 177 | pkg_check_modules (MPG123 IMPORTED_TARGET libmpg123) |
@@ -35,10 +35,10 @@ On openSUSE Tumbleweed: | |||
35 | 35 | ||
36 | You need a POSIX-compatible environment to compile Lagrange. | 36 | You need a POSIX-compatible environment to compile Lagrange. |
37 | 37 | ||
38 | The 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). | 38 | The 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 | ||
40 | 1. 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` | 40 | 1. 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` |
41 | 2. 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``` | 41 | 2. 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``` |
42 | 3. 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`. | 42 | 3. 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`. |
43 | 4. Create a build directory. | 43 | 4. Create a build directory. |
44 | 5. In your empty build directory, run CMake: ```cmake {path_of_lagrange_sources} -DCMAKE_BUILD_TYPE=Release``` | 44 | 5. 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 @@ | |||
1 | find_program (ZIP_EXECUTABLE zip DOC "ZIP archiver") | ||
2 | if (NOT ZIP_EXECUTABLE) | ||
3 | message (FATAL_ERROR "Please install 'zip' for packaging resources.") | ||
4 | endif () | ||
5 | |||
6 | function (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}) | ||
27 | endfunction () | ||
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 @@ | |||
1 | find_program (ZIP_EXECUTABLE zip DOC "ZIP archiver") | ||
2 | if (NOT ZIP_EXECUTABLE) | ||
3 | message (FATAL_ERROR "Please install 'zip' to create fontpacks.") | ||
4 | endif () | ||
5 | |||
6 | function (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 | ) | ||
19 | endfunction () | ||
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 | |||
11 | New features: | ||
12 | * macOS: Automatic updates using the Sparkle framework. | ||
13 | * Windows: Automatic updates using the WinSparkle library. | ||
14 | |||
15 | Changes 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 | |||
18 | Fixes: | ||
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 | |||
6 | OUTPUT=-- | ||
7 | SIZES="" | ||
8 | for 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 | ||
21 | done | ||
22 | echo $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] |
21 | name = "Source Sans" | 21 | name = "Source Sans" |
22 | regular = "SourceSans3-Regular.ttf" | 22 | regular = "fonts/SourceSans3-Regular.ttf" |
23 | italic = "SourceSans3-It.ttf" | 23 | italic = "fonts/SourceSans3-It.ttf" |
24 | light = "SourceSans3-ExtraLight.ttf" | 24 | light = "fonts/SourceSans3-ExtraLight.ttf" |
25 | semibold = "SourceSans3-Semibold.ttf" | 25 | semibold = "fonts/SourceSans3-Semibold.ttf" |
26 | bold = "SourceSans3-Bold.ttf" | 26 | bold = "fonts/SourceSans3-Bold.ttf" |
27 | 27 | ||
28 | [iosevka] | 28 | [iosevka] |
29 | name = "Iosevka (compact)" | 29 | name = "Iosevka (compact)" |
30 | monospace = true | 30 | monospace = true |
31 | doc.height = 0.800 | 31 | doc.height = 0.800 |
32 | regular = "IosevkaTerm-Extended.ttf" | 32 | regular = "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" | |||
38 | monospace = true | 38 | monospace = true |
39 | priority = -10 | 39 | priority = -10 |
40 | glyphscale = 0.800 | 40 | glyphscale = 0.800 |
41 | regular = "IosevkaTerm-Extended.ttf" | 41 | regular = "fonts/IosevkaTerm-Extended.ttf" |
42 | 42 | ||
43 | [smolemoji] | 43 | [smolemoji] |
44 | name = "Smol Emoji" | 44 | name = "Smol Emoji" |
45 | override = true # These Emoji/symbols are always preferred. | 45 | override = true # These Emoji/symbols are always preferred. |
46 | auxiliary = true | 46 | auxiliary = true |
47 | priority = 100 | 47 | priority = 100 |
48 | regular = "SmolEmoji-Regular.ttf" | 48 | regular = "fonts/SmolEmoji-Regular.ttf" |
49 | 49 | ||
50 | [notoemoji] | 50 | [notoemoji] |
51 | name = "Noto Emoji" | 51 | name = "Noto Emoji" |
52 | auxiliary = true | 52 | auxiliary = true |
53 | priority = 30 | 53 | priority = 30 |
54 | glyphscale = 1.1 | 54 | glyphscale = 1.1 |
55 | regular = "NotoEmoji-Regular.ttf" | 55 | regular = "fonts/NotoEmoji-Regular.ttf" |
56 | 56 | ||
57 | [notosymbols2] | 57 | [notosymbols2] |
58 | name = "Noto Sans Symbols 2" | 58 | name = "Noto Sans Symbols 2" |
@@ -60,7 +60,7 @@ auxiliary = true | |||
60 | priority = 20 | 60 | priority = 20 |
61 | glyphscale = 1.45 | 61 | glyphscale = 1.45 |
62 | voffset = 0.5 | 62 | voffset = 0.5 |
63 | regular = "NotoSansSymbols2-Regular.ttf" | 63 | regular = "fonts/NotoSansSymbols2-Regular.ttf" |
64 | 64 | ||
65 | [notosymbols] | 65 | [notosymbols] |
66 | name = "Noto Sans Symbols" | 66 | name = "Noto Sans Symbols" |
@@ -68,4 +68,4 @@ auxiliary = true | |||
68 | priority = 10 | 68 | priority = 10 |
69 | glyphscale = 2.0 | 69 | glyphscale = 2.0 |
70 | voffset = 1.2 | 70 | voffset = 1.2 |
71 | regular = "NotoSansSymbols-Regular.ttf" | 71 | regular = "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 | |||
@@ -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 | |||
21 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ | 21 | SOFTWARE, 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 | ||
80 | static void load_FontFile_(iFontFile *d, const iBlock *data) { | 80 | static 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) { | |||
344 | static const iBlock *aboutPageSource_(iRangecc path, iRangecc query) { | 344 | static 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(); |
@@ -21,7 +21,7 @@ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |||
21 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ | 21 | SOFTWARE, 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) | |||
30 | iDeclareType(MsgStr) | 30 | iDeclareType(MsgStr) |
31 | 31 | ||
32 | struct Impl_MsgStr { | 32 | struct 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 | ||
85 | static void load_Lang_(iLang *d, const char *id) { | 85 | static 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 | |||
716 | void 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 */ | ||
729 | void init_Updater(void) {} | ||
730 | #endif | ||
731 | |||
732 | void deinit_Updater(void) {} | ||
733 | void checkNow_Updater(void) {} | ||
@@ -21,6 +21,7 @@ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |||
21 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ | 21 | SOFTWARE, 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 | |||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions are met: | ||
5 | |||
6 | 1. Redistributions of source code must retain the above copyright notice, this | ||
7 | list of conditions and the following disclaimer. | ||
8 | 2. 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 | |||
12 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | ||
13 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
14 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
15 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR | ||
16 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
17 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
18 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
19 | 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 | ||
21 | SOFTWARE, 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 | |||
28 | static iArchive *archive_; | ||
29 | |||
30 | iBlock blobAbout_Resources; | ||
31 | iBlock blobHelp_Resources; | ||
32 | iBlock blobLagrange_Resources; | ||
33 | iBlock blobLicense_Resources; | ||
34 | iBlock blobVersion_Resources; | ||
35 | iBlock blobArghelp_Resources; | ||
36 | iBlock blobCs_Resources; | ||
37 | iBlock blobDe_Resources; | ||
38 | iBlock blobEn_Resources; | ||
39 | iBlock blobEo_Resources; | ||
40 | iBlock blobEs_Resources; | ||
41 | iBlock blobEs_MX_Resources; | ||
42 | iBlock blobFi_Resources; | ||
43 | iBlock blobFr_Resources; | ||
44 | iBlock blobGl_Resources; | ||
45 | iBlock blobHu_Resources; | ||
46 | iBlock blobIa_Resources; | ||
47 | iBlock blobIe_Resources; | ||
48 | iBlock blobIsv_Resources; | ||
49 | iBlock blobPl_Resources; | ||
50 | iBlock blobRu_Resources; | ||
51 | iBlock blobSk_Resources; | ||
52 | iBlock blobSr_Resources; | ||
53 | iBlock blobTok_Resources; | ||
54 | iBlock blobUk_Resources; | ||
55 | iBlock blobZh_Hans_Resources; | ||
56 | iBlock blobZh_Hant_Resources; | ||
57 | iBlock imageShadow_Resources; | ||
58 | iBlock imageLagrange64_Resources; | ||
59 | |||
60 | static 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 | |||
95 | iBool 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 | |||
118 | void deinit_Resources(void) { | ||
119 | iForIndices(i, entries_) { | ||
120 | deinit_Block(entries_[i].data); | ||
121 | } | ||
122 | iRelease(archive_); | ||
123 | } | ||
124 | |||
125 | const 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 | |||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions are met: | ||
5 | |||
6 | 1. Redistributions of source code must retain the above copyright notice, this | ||
7 | list of conditions and the following disclaimer. | ||
8 | 2. 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 | |||
12 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | ||
13 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
14 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
15 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR | ||
16 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
17 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
18 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
19 | 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 | ||
21 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ | ||
22 | |||
23 | #pragma once | ||
24 | |||
25 | #include <the_Foundation/block.h> | ||
26 | |||
27 | iDeclareType(Archive) | ||
28 | |||
29 | iBool init_Resources (const char *path); | ||
30 | void deinit_Resources (void); | ||
31 | |||
32 | const iArchive * archive_Resources (void); | ||
33 | |||
34 | extern iBlock blobAbout_Resources; | ||
35 | extern iBlock blobHelp_Resources; | ||
36 | extern iBlock blobLagrange_Resources; | ||
37 | extern iBlock blobLicense_Resources; | ||
38 | extern iBlock blobVersion_Resources; | ||
39 | extern iBlock blobArghelp_Resources; | ||
40 | extern iBlock blobCs_Resources; | ||
41 | extern iBlock blobDe_Resources; | ||
42 | extern iBlock blobEn_Resources; | ||
43 | extern iBlock blobEo_Resources; | ||
44 | extern iBlock blobEs_Resources; | ||
45 | extern iBlock blobEs_MX_Resources; | ||
46 | extern iBlock blobFi_Resources; | ||
47 | extern iBlock blobFr_Resources; | ||
48 | extern iBlock blobGl_Resources; | ||
49 | extern iBlock blobHu_Resources; | ||
50 | extern iBlock blobIa_Resources; | ||
51 | extern iBlock blobIe_Resources; | ||
52 | extern iBlock blobIsv_Resources; | ||
53 | extern iBlock blobPl_Resources; | ||
54 | extern iBlock blobRu_Resources; | ||
55 | extern iBlock blobSk_Resources; | ||
56 | extern iBlock blobSr_Resources; | ||
57 | extern iBlock blobTok_Resources; | ||
58 | extern iBlock blobUk_Resources; | ||
59 | extern iBlock blobZh_Hans_Resources; | ||
60 | extern iBlock blobZh_Hant_Resources; | ||
61 | extern iBlock imageShadow_Resources; | ||
62 | extern iBlock fontpackDefault_Resources; | ||
63 | extern 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 | |||
3 | Redistribution and use in source and binary forms, with or without | ||
4 | modification, are permitted provided that the following conditions are met: | ||
5 | |||
6 | 1. Redistributions of source code must retain the above copyright notice, this | ||
7 | list of conditions and the following disclaimer. | ||
8 | 2. 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 | |||
12 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | ||
13 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
14 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
15 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR | ||
16 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
17 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
18 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
19 | 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 | ||
21 | SOFTWARE, 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 | |||
29 | static 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 | |||
67 | void 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 | |||
73 | void deinit_Updater(void) { | ||
74 | win_sparkle_cleanup(); | ||
75 | } | ||
76 | |||
77 | void checkNow_Updater(void) { | ||
78 | win_sparkle_check_update_with_ui(); | ||
79 | } | ||
80 | |||
81 | #else | ||
82 | /* dummy as a fallback */ | ||
83 | void init_Updater(void) {} | ||
84 | void deinit_Updater(void) {} | ||
85 | void 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 | ||
3 | Redistribution and use in source and binary forms, with or without | 3 | Redistribution and use in source and binary forms, with or without |
4 | modification, are permitted provided that the following conditions are met: | 4 | modification, 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 |
21 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ | 21 | SOFTWARE, 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> | 25 | void init_Updater (void); |
26 | #include <stdlib.h> | 26 | void deinit_Updater (void); |
27 | 27 | ||
28 | int main(int argc, char *argv[]) { | 28 | void 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 | } | ||