summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/app.c39
-rw-r--r--src/main.c4
-rw-r--r--src/resources.c20
-rw-r--r--src/ui/documentwidget.c4
-rw-r--r--src/ui/text.c4
-rw-r--r--src/ui/text_simple.c7
-rw-r--r--src/ui/touch.c4
-rw-r--r--src/ui/window.c10
8 files changed, 75 insertions, 17 deletions
diff --git a/src/app.c b/src/app.c
index a2de03ca..bfac84d9 100644
--- a/src/app.c
+++ b/src/app.c
@@ -92,7 +92,10 @@ static const char *defaultDataDir_App_ = "~/Library/Application Support";
92#define EMB_BIN "../resources.lgr" 92#define EMB_BIN "../resources.lgr"
93static const char *defaultDataDir_App_ = "~/AppData/Roaming/fi.skyjake.Lagrange"; 93static const char *defaultDataDir_App_ = "~/AppData/Roaming/fi.skyjake.Lagrange";
94#endif 94#endif
95#if defined (iPlatformLinux) || defined (iPlatformOther) 95#if defined (iPlatformAndroidMobile)
96#define EMB_BIN "resources.lgr" /* loaded from assets with SDL_rwops */
97static const char *defaultDataDir_App_ = NULL; /* will ask SDL */
98#elif defined (iPlatformLinux) || defined (iPlatformOther)
96#define EMB_BIN "../../share/lagrange/resources.lgr" 99#define EMB_BIN "../../share/lagrange/resources.lgr"
97#define EMB_BIN2 "../../../share/lagrange/resources.lgr" 100#define EMB_BIN2 "../../../share/lagrange/resources.lgr"
98static const char *defaultDataDir_App_ = "~/.config/lagrange"; 101static const char *defaultDataDir_App_ = "~/.config/lagrange";
@@ -137,6 +140,9 @@ struct Impl_App {
137 int autoReloadTimer; 140 int autoReloadTimer;
138 iPeriodic periodic; 141 iPeriodic periodic;
139 int warmupFrames; /* forced refresh just after resuming from background; FIXME: shouldn't be needed */ 142 int warmupFrames; /* forced refresh just after resuming from background; FIXME: shouldn't be needed */
143#if defined (iPlatformAndroidMobile)
144 float displayDensity;
145#endif
140 /* Preferences: */ 146 /* Preferences: */
141 iBool commandEcho; /* --echo */ 147 iBool commandEcho; /* --echo */
142 iBool forceSoftwareRender; /* --sw */ 148 iBool forceSoftwareRender; /* --sw */
@@ -300,7 +306,10 @@ static const char *dataDir_App_(void) {
300 return userDir; 306 return userDir;
301 } 307 }
302#endif 308#endif
303 return defaultDataDir_App_; 309 if (defaultDataDir_App_) {
310 return defaultDataDir_App_;
311 }
312 return SDL_GetPrefPath("Jaakko Keränen", "fi.skyjake.lagrange");
304} 313}
305 314
306static const char *downloadDir_App_(void) { 315static const char *downloadDir_App_(void) {
@@ -698,7 +707,7 @@ static iBool hasCommandLineOpenableScheme_(const iRangecc uri) {
698} 707}
699 708
700static void init_App_(iApp *d, int argc, char **argv) { 709static void init_App_(iApp *d, int argc, char **argv) {
701#if defined (iPlatformLinux) 710#if defined (iPlatformLinux) && !defined (iPlatformAndroid)
702 d->isRunningUnderWindowSystem = !iCmpStr(SDL_GetCurrentVideoDriver(), "x11") || 711 d->isRunningUnderWindowSystem = !iCmpStr(SDL_GetCurrentVideoDriver(), "x11") ||
703 !iCmpStr(SDL_GetCurrentVideoDriver(), "wayland"); 712 !iCmpStr(SDL_GetCurrentVideoDriver(), "wayland");
704#else 713#else
@@ -745,6 +754,8 @@ static void init_App_(iApp *d, int argc, char **argv) {
745 } 754 }
746 } 755 }
747 init_Lang(); 756 init_Lang();
757 iStringList *openCmds = new_StringList();
758#if !defined (iPlatformAndroidMobile)
748 /* Configure the valid command line options. */ { 759 /* Configure the valid command line options. */ {
749 defineValues_CommandLine(&d->args, "close-tab", 0); 760 defineValues_CommandLine(&d->args, "close-tab", 0);
750 defineValues_CommandLine(&d->args, "echo;E", 0); 761 defineValues_CommandLine(&d->args, "echo;E", 0);
@@ -759,7 +770,6 @@ static void init_App_(iApp *d, int argc, char **argv) {
759 defineValues_CommandLine(&d->args, "sw", 0); 770 defineValues_CommandLine(&d->args, "sw", 0);
760 defineValues_CommandLine(&d->args, "version;V", 0); 771 defineValues_CommandLine(&d->args, "version;V", 0);
761 } 772 }
762 iStringList *openCmds = new_StringList();
763 /* Handle command line options. */ { 773 /* Handle command line options. */ {
764 if (contains_CommandLine(&d->args, "help")) { 774 if (contains_CommandLine(&d->args, "help")) {
765 puts(cstr_Block(&blobArghelp_Resources)); 775 puts(cstr_Block(&blobArghelp_Resources));
@@ -808,6 +818,7 @@ static void init_App_(iApp *d, int argc, char **argv) {
808 } 818 }
809 } 819 }
810 } 820 }
821#endif
811#if defined (LAGRANGE_ENABLE_IPC) 822#if defined (LAGRANGE_ENABLE_IPC)
812 /* Only one instance is allowed to run at a time; the runtime files (bookmarks, etc.) 823 /* Only one instance is allowed to run at a time; the runtime files (bookmarks, etc.)
813 are not shareable. */ { 824 are not shareable. */ {
@@ -842,7 +853,7 @@ static void init_App_(iApp *d, int argc, char **argv) {
842 /* Must scale by UI scaling factor. */ 853 /* Must scale by UI scaling factor. */
843 mulfv_I2(&d->initialWindowRect.size, desktopDPI_Win32()); 854 mulfv_I2(&d->initialWindowRect.size, desktopDPI_Win32());
844#endif 855#endif
845#if defined (iPlatformLinux) 856#if defined (iPlatformLinux) && !defined (iPlatformAndroid)
846 /* Scale by the primary (?) monitor DPI. */ 857 /* Scale by the primary (?) monitor DPI. */
847 if (isRunningUnderWindowSystem_App()) { 858 if (isRunningUnderWindowSystem_App()) {
848 float vdpi; 859 float vdpi;
@@ -1301,6 +1312,15 @@ void processEvents_App(enum iAppEventMode eventMode) {
1301 } 1312 }
1302 ev.key.keysym.mod = mapMods_Keys(ev.key.keysym.mod & ~KMOD_CAPS); 1313 ev.key.keysym.mod = mapMods_Keys(ev.key.keysym.mod & ~KMOD_CAPS);
1303 } 1314 }
1315#if defined (iPlatformAndroidMobile)
1316 /* Ignore all mouse events; just use touch. */
1317 if (ev.type == SDL_MOUSEBUTTONDOWN ||
1318 ev.type == SDL_MOUSEBUTTONUP ||
1319 ev.type == SDL_MOUSEMOTION ||
1320 ev.type == SDL_MOUSEWHEEL) {
1321 continue;
1322 }
1323#endif
1304 /* Scroll events may be per-pixel or mouse wheel steps. */ 1324 /* Scroll events may be per-pixel or mouse wheel steps. */
1305 if (ev.type == SDL_MOUSEWHEEL) { 1325 if (ev.type == SDL_MOUSEWHEEL) {
1306#if defined (iPlatformAppleDesktop) 1326#if defined (iPlatformAppleDesktop)
@@ -1759,6 +1779,8 @@ enum iAppDeviceType deviceType_App(void) {
1759 return tablet_AppDeviceType; 1779 return tablet_AppDeviceType;
1760#elif defined (iPlatformAppleMobile) 1780#elif defined (iPlatformAppleMobile)
1761 return isPhone_iOS() ? phone_AppDeviceType : tablet_AppDeviceType; 1781 return isPhone_iOS() ? phone_AppDeviceType : tablet_AppDeviceType;
1782#elif defined (iPlatformAndroidMobile)
1783 return phone_AppDeviceType; /* TODO: Java side could tell us via cmdline if this is a tablet. */
1762#else 1784#else
1763 return desktop_AppDeviceType; 1785 return desktop_AppDeviceType;
1764#endif 1786#endif
@@ -3350,3 +3372,10 @@ void closePopups_App(void) {
3350 } 3372 }
3351 } 3373 }
3352} 3374}
3375
3376#if defined (iPlatformAndroidMobile)
3377float displayDensity_Android(void) {
3378 iApp *d = &app_;
3379 return toFloat_String(at_CommandLine(&d->args, 1));
3380}
3381#endif
diff --git a/src/main.c b/src/main.c
index 6e5e99e9..ad69c6df 100644
--- a/src/main.c
+++ b/src/main.c
@@ -67,9 +67,11 @@ int main(int argc, char **argv) {
67 "ECDHE-RSA-AES128-GCM-SHA256:" 67 "ECDHE-RSA-AES128-GCM-SHA256:"
68 "DHE-RSA-AES256-GCM-SHA384"); 68 "DHE-RSA-AES256-GCM-SHA384");
69 SDL_SetHint(SDL_HINT_VIDEO_ALLOW_SCREENSAVER, "1"); 69 SDL_SetHint(SDL_HINT_VIDEO_ALLOW_SCREENSAVER, "1");
70 SDL_SetHint(SDL_HINT_MAC_BACKGROUND_APP, "1");
70 SDL_SetHint(SDL_HINT_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK, "1"); 71 SDL_SetHint(SDL_HINT_MAC_CTRL_CLICK_EMULATE_RIGHT_CLICK, "1");
72#if SDL_VERSION_ATLEAST(2, 0, 8)
71 SDL_SetHint(SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR, "0"); 73 SDL_SetHint(SDL_HINT_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR, "0");
72 SDL_SetHint(SDL_HINT_MAC_BACKGROUND_APP, "1"); 74#endif
73#if 0 75#if 0
74 SDL_SetHint(SDL_HINT_MOUSE_TOUCH_EVENTS, "1"); /* debugging! */ 76 SDL_SetHint(SDL_HINT_MOUSE_TOUCH_EVENTS, "1"); /* debugging! */
75#endif 77#endif
diff --git a/src/resources.c b/src/resources.c
index c60a2916..5c7e41ea 100644
--- a/src/resources.c
+++ b/src/resources.c
@@ -25,6 +25,8 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
25#include <the_Foundation/archive.h> 25#include <the_Foundation/archive.h>
26#include <the_Foundation/version.h> 26#include <the_Foundation/version.h>
27 27
28#include <SDL_rwops.h>
29
28static iArchive *archive_; 30static iArchive *archive_;
29 31
30iBlock blobAbout_Resources; 32iBlock blobAbout_Resources;
@@ -96,7 +98,23 @@ static struct {
96 98
97iBool init_Resources(const char *path) { 99iBool init_Resources(const char *path) {
98 archive_ = new_Archive(); 100 archive_ = new_Archive();
99 if (openFile_Archive(archive_, collectNewCStr_String(path))) { 101 iBool ok = iFalse;
102#if defined (iPlatformAndroidMobile)
103 /* Resources are bundled as assets so they cannot be loaded as a regular file.
104 Fortunately, SDL implements a file wrapper. */
105 SDL_RWops *io = SDL_RWFromFile(path, "rb");
106 if (io) {
107 iBlock buf;
108 init_Block(&buf, (size_t) SDL_RWsize(io));
109 SDL_RWread(io, data_Block(&buf), size_Block(&buf), 1);
110 SDL_RWclose(io);
111 ok = openData_Archive(archive_, &buf);
112 deinit_Block(&buf);
113 }
114#else
115 ok = openFile_Archive(archive_, collectNewCStr_String(path));
116#endif
117 if (ok) {
100 iVersion appVer; 118 iVersion appVer;
101 init_Version(&appVer, range_CStr(LAGRANGE_APP_VERSION)); 119 init_Version(&appVer, range_CStr(LAGRANGE_APP_VERSION));
102 iVersion resVer; 120 iVersion resVer;
diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c
index 746e03e0..46af5fcd 100644
--- a/src/ui/documentwidget.c
+++ b/src/ui/documentwidget.c
@@ -1224,10 +1224,6 @@ static void showErrorPage_DocumentWidget_(iDocumentWidget *d, enum iGmStatusCode
1224 case tooManyRedirects_GmStatusCode: 1224 case tooManyRedirects_GmStatusCode:
1225 appendFormat_String(src, "=> %s\n", cstr_String(meta)); 1225 appendFormat_String(src, "=> %s\n", cstr_String(meta));
1226 break; 1226 break;
1227 case tlsFailure_GmStatusCode:
1228// useBanner = iFalse; /* valid data wasn't received from host */
1229// appendFormat_String(src, ">%s\n", cstr_String(meta));
1230 break;
1231 case tlsServerCertificateExpired_GmStatusCode: 1227 case tlsServerCertificateExpired_GmStatusCode:
1232 makeFooterButtons_DocumentWidget_( 1228 makeFooterButtons_DocumentWidget_(
1233 d, 1229 d,
diff --git a/src/ui/text.c b/src/ui/text.c
index 977cac9c..4a4b3776 100644
--- a/src/ui/text.c
+++ b/src/ui/text.c
@@ -1871,7 +1871,7 @@ iInt2 tryAdvance_Text(int fontId, iRangecc text, int width, const char **endPos)
1871} 1871}
1872 1872
1873iInt2 tryAdvanceNoWrap_Text(int fontId, iRangecc text, int width, const char **endPos) { 1873iInt2 tryAdvanceNoWrap_Text(int fontId, iRangecc text, int width, const char **endPos) {
1874 if (width <= 1) { 1874 if (width && width <= 1) {
1875 *endPos = text.start; 1875 *endPos = text.start;
1876 return zero_I2(); 1876 return zero_I2();
1877 } 1877 }
@@ -2070,7 +2070,7 @@ iTextMetrics draw_WrapText(iWrapText *d, int fontId, iInt2 pos, int color) {
2070 const int width = d->mode == word_WrapTextMode 2070 const int width = d->mode == word_WrapTextMode
2071 ? tryAdvance_Text(fontId, text, d->maxWidth, &endPos).x 2071 ? tryAdvance_Text(fontId, text, d->maxWidth, &endPos).x
2072 : tryAdvanceNoWrap_Text(fontId, text, d->maxWidth, &endPos).x; 2072 : tryAdvanceNoWrap_Text(fontId, text, d->maxWidth, &endPos).x;
2073 notify_WrapText_(d, endPos, (iTextAttrib){ .colorId = color }, 0, width); 2073 notify_WrapText_(d, endPos, (iTextAttrib){ .fgColorId = color }, 0, width);
2074 drawRange_Text(fontId, pos, color, (iRangecc){ text.start, endPos }); 2074 drawRange_Text(fontId, pos, color, (iRangecc){ text.start, endPos });
2075 text.start = endPos; 2075 text.start = endPos;
2076 pos.y += lineHeight_Text(fontId); 2076 pos.y += lineHeight_Text(fontId);
diff --git a/src/ui/text_simple.c b/src/ui/text_simple.c
index 81fb94a5..8560c138 100644
--- a/src/ui/text_simple.c
+++ b/src/ui/text_simple.c
@@ -61,7 +61,7 @@ static iRect runSimple_Font_(iFont *d, const iRunArgs *args) {
61 and other non-complex LTR scripts. Composed glyphs are not supported (must rely on text 61 and other non-complex LTR scripts. Composed glyphs are not supported (must rely on text
62 being in a pre-composed form). This algorithm is used if HarfBuzz is not available. */ 62 being in a pre-composed form). This algorithm is used if HarfBuzz is not available. */
63 const iInt2 orig = args->pos; 63 const iInt2 orig = args->pos;
64 iTextAttrib attrib = { .colorId = args->color }; 64 iTextAttrib attrib = { .fgColorId = args->color };
65 iRect bounds = { orig, init_I2(0, d->height) }; 65 iRect bounds = { orig, init_I2(0, d->height) };
66 float xpos = orig.x; 66 float xpos = orig.x;
67 float xposMax = xpos; 67 float xposMax = xpos;
@@ -118,8 +118,9 @@ static iRect runSimple_Font_(iFont *d, const iRunArgs *args) {
118 if (match_RegExp(activeText_->ansiEscape, chPos, args->text.end - chPos, &m)) { 118 if (match_RegExp(activeText_->ansiEscape, chPos, args->text.end - chPos, &m)) {
119 if (mode & draw_RunMode && ~mode & permanentColorFlag_RunMode) { 119 if (mode & draw_RunMode && ~mode & permanentColorFlag_RunMode) {
120 /* Change the color. */ 120 /* Change the color. */
121 const iColor clr = 121 iColor clr;
122 ansiForeground_Color(capturedRange_RegExpMatch(&m, 1), tmParagraph_ColorId); 122 ansiColors_Color(capturedRange_RegExpMatch(&m, 1), tmParagraph_ColorId,
123 none_ColorId, &clr, NULL);
123 SDL_SetTextureColorMod(activeText_->cache, clr.r, clr.g, clr.b); 124 SDL_SetTextureColorMod(activeText_->cache, clr.r, clr.g, clr.b);
124 if (args->mode & fillBackground_RunMode) { 125 if (args->mode & fillBackground_RunMode) {
125 SDL_SetRenderDrawColor(activeText_->render, clr.r, clr.g, clr.b, 0); 126 SDL_SetRenderDrawColor(activeText_->render, clr.r, clr.g, clr.b, 0);
diff --git a/src/ui/touch.c b/src/ui/touch.c
index 195d1dff..d6846572 100644
--- a/src/ui/touch.c
+++ b/src/ui/touch.c
@@ -42,7 +42,11 @@ iDeclareType(TouchState)
42 42
43static const uint32_t longPressSpanMs_ = 500; 43static const uint32_t longPressSpanMs_ = 500;
44static const uint32_t shortPressSpanMs_ = 250; 44static const uint32_t shortPressSpanMs_ = 250;
45#if defined (iPlatformAndroidMobile)
46static const int tapRadiusPt_ = 30; /* inaccurate sensors? */
47#else
45static const int tapRadiusPt_ = 10; 48static const int tapRadiusPt_ = 10;
49#endif
46 50
47enum iTouchEdge { 51enum iTouchEdge {
48 none_TouchEdge, 52 none_TouchEdge,
diff --git a/src/ui/window.c b/src/ui/window.c
index 0bbe588c..9f12cabf 100644
--- a/src/ui/window.c
+++ b/src/ui/window.c
@@ -263,6 +263,10 @@ static float pixelRatio_Window_(const iWindow *d) {
263# define baseDPI_Window 96.0f 263# define baseDPI_Window 96.0f
264#endif 264#endif
265 265
266#if defined (iPlatformAndroidMobile)
267float displayDensity_Android(void);
268#endif
269
266static float displayScale_Window_(const iWindow *d) { 270static float displayScale_Window_(const iWindow *d) {
267 /* The environment variable LAGRANGE_OVERRIDE_DPI can be used to override the automatic 271 /* The environment variable LAGRANGE_OVERRIDE_DPI can be used to override the automatic
268 display DPI detection. If not set, or is an empty string, ignore it. 272 display DPI detection. If not set, or is an empty string, ignore it.
@@ -289,6 +293,8 @@ static float displayScale_Window_(const iWindow *d) {
289#elif defined (iPlatformMsys) 293#elif defined (iPlatformMsys)
290 iUnused(d); 294 iUnused(d);
291 return desktopDPI_Win32(); 295 return desktopDPI_Win32();
296#elif defined (iPlatformAndroidMobile)
297 return displayDensity_Android();
292#else 298#else
293 if (isRunningUnderWindowSystem_App()) { 299 if (isRunningUnderWindowSystem_App()) {
294 float vdpi = 0.0f; 300 float vdpi = 0.0f;
@@ -457,7 +463,7 @@ void init_Window(iWindow *d, enum iWindowType type, iRect rect, uint32_t flags)
457 d->mouseGrab = NULL; 463 d->mouseGrab = NULL;
458 d->focus = NULL; 464 d->focus = NULL;
459 d->pendingCursor = NULL; 465 d->pendingCursor = NULL;
460 d->isExposed = iFalse; 466 d->isExposed = (deviceType_App() != desktop_AppDeviceType);
461 d->isMinimized = iFalse; 467 d->isMinimized = iFalse;
462 d->isInvalidated = iFalse; /* set when posting event, to avoid repeated events */ 468 d->isInvalidated = iFalse; /* set when posting event, to avoid repeated events */
463 d->isMouseInside = iTrue; 469 d->isMouseInside = iTrue;
@@ -541,6 +547,8 @@ void init_MainWindow(iMainWindow *d, iRect rect) {
541 SDL_SetHint(SDL_HINT_RENDER_DRIVER, "metal"); 547 SDL_SetHint(SDL_HINT_RENDER_DRIVER, "metal");
542 flags |= SDL_WINDOW_METAL; 548 flags |= SDL_WINDOW_METAL;
543 d->base.isExposed = iTrue; 549 d->base.isExposed = iTrue;
550#elif defined (iPlatformAndroidMobile)
551 d->base.isExposed = iTrue;
544#else 552#else
545 if (!forceSoftwareRender_App()) { 553 if (!forceSoftwareRender_App()) {
546 flags |= SDL_WINDOW_OPENGL; 554 flags |= SDL_WINDOW_OPENGL;