From 51d823832538d495f382299ec668e7afa1cc12f8 Mon Sep 17 00:00:00 2001 From: Jaakko Keränen Date: Sat, 2 Jan 2021 11:35:53 +0200 Subject: Add support for Finger protocol A patch courtesy of John Cowan. IssueID #106 --- src/gmdocument.c | 22 ++++++++++++---------- src/gmdocument.h | 2 +- src/gmrequest.c | 9 +++++---- src/gopher.c | 17 +++++++++++------ src/ui/documentwidget.c | 1 + 5 files changed, 30 insertions(+), 21 deletions(-) (limited to 'src') diff --git a/src/gmdocument.c b/src/gmdocument.c index 1f8ecb75..8d2e3f1f 100644 --- a/src/gmdocument.c +++ b/src/gmdocument.c @@ -177,8 +177,9 @@ static iRangecc addLink_GmDocument_(iGmDocument *d, iRangecc line, iGmLinkId *li else if (startsWithCase_Rangecc(parts.scheme, "http")) { link->flags |= http_GmLinkFlag; } - else if (equalCase_Rangecc(parts.scheme, "gopher")) { - link->flags |= gopher_GmLinkFlag; + else if (equalCase_Rangecc(parts.scheme, "gopher") || + equalCase_Rangecc(parts.scheme, "finger")) { + link->flags |= gopher_finger_GmLinkFlag; if (startsWith_Rangecc(parts.path, "/7")) { link->flags |= query_GmLinkFlag; } @@ -187,7 +188,6 @@ static iRangecc addLink_GmDocument_(iGmDocument *d, iRangecc line, iGmLinkId *li link->flags |= file_GmLinkFlag; } else if (equalCase_Rangecc(parts.scheme, "data")) { - link->flags |= data_GmLinkFlag; } else if (equalCase_Rangecc(parts.scheme, "about")) { link->flags |= about_GmLinkFlag; @@ -245,7 +245,8 @@ static iBool isForcedMonospace_GmDocument_(const iGmDocument *d) { if (equalCase_Rangecc(scheme, "gemini")) { return prefs_App()->monospaceGemini; } - if (equalCase_Rangecc(scheme, "gopher")) { + if (equalCase_Rangecc(scheme, "gopher") || + equalCase_Rangecc(scheme, "finger")) { return prefs_App()->monospaceGopher; } return iFalse; @@ -1373,24 +1374,24 @@ enum iColorId linkColor_GmDocument(const iGmDocument *d, iGmLinkId linkId, enum if (link->flags & visited_GmLinkFlag) { return link->flags & www_GmLinkFlag ? tmHypertextLinkIconVisited_ColorId - : link->flags & gopher_GmLinkFlag ? tmGopherLinkIconVisited_ColorId + : link->flags & gopher_finger_GmLinkFlag ? tmGopherLinkIconVisited_ColorId : tmLinkIconVisited_ColorId; } return link->flags & www_GmLinkFlag ? tmHypertextLinkIcon_ColorId - : link->flags & gopher_GmLinkFlag ? tmGopherLinkIcon_ColorId + : link->flags & gopher_finger_GmLinkFlag ? tmGopherLinkIcon_ColorId : tmLinkIcon_ColorId; } if (part == text_GmLinkPart) { return link->flags & www_GmLinkFlag ? tmHypertextLinkText_ColorId - : link->flags & gopher_GmLinkFlag ? tmGopherLinkText_ColorId + : link->flags & gopher_finger_GmLinkFlag ? tmGopherLinkText_ColorId : tmLinkText_ColorId; } if (part == textHover_GmLinkPart) { return link->flags & www_GmLinkFlag ? tmHypertextLinkTextHover_ColorId - : link->flags & gopher_GmLinkFlag ? tmGopherLinkTextHover_ColorId + : link->flags & gopher_finger_GmLinkFlag ? tmGopherLinkTextHover_ColorId : tmLinkTextHover_ColorId; } if (part == domain_GmLinkPart) { @@ -1399,13 +1400,13 @@ enum iColorId linkColor_GmDocument(const iGmDocument *d, iGmLinkId linkId, enum } return link->flags & www_GmLinkFlag ? tmHypertextLinkDomain_ColorId - : link->flags & gopher_GmLinkFlag ? tmGopherLinkDomain_ColorId + : link->flags & gopher_finger_GmLinkFlag ? tmGopherLinkDomain_ColorId : tmLinkDomain_ColorId; } if (part == visited_GmLinkPart) { return link->flags & www_GmLinkFlag ? tmHypertextLinkLastVisitDate_ColorId - : link->flags & gopher_GmLinkFlag ? tmGopherLinkLastVisitDate_ColorId + : link->flags & gopher_finger_GmLinkFlag ? tmGopherLinkLastVisitDate_ColorId : tmLinkLastVisitDate_ColorId; } } @@ -1416,6 +1417,7 @@ iBool isMediaLink_GmDocument(const iGmDocument *d, iGmLinkId linkId) { const iString *dstUrl = absoluteUrl_String(&d->url, linkUrl_GmDocument(d, linkId)); const iRangecc scheme = urlScheme_String(dstUrl); if (equalCase_Rangecc(scheme, "gemini") || equalCase_Rangecc(scheme, "gopher") || + equalCase_Rangecc(scheme, "finger") || equalCase_Rangecc(scheme, "file") || willUseProxy_App(scheme)) { return (linkFlags_GmDocument(d, linkId) & (imageFileExtension_GmLinkFlag | audioFileExtension_GmLinkFlag)) != 0; diff --git a/src/gmdocument.h b/src/gmdocument.h index b1121d85..7d962511 100644 --- a/src/gmdocument.h +++ b/src/gmdocument.h @@ -53,7 +53,7 @@ typedef uint16_t iGmLinkId; enum iGmLinkFlags { gemini_GmLinkFlag = iBit(1), - gopher_GmLinkFlag = iBit(2), + gopher_finger_GmLinkFlag = iBit(2), http_GmLinkFlag = iBit(3), file_GmLinkFlag = iBit(4), data_GmLinkFlag = iBit(5), diff --git a/src/gmrequest.c b/src/gmrequest.c index 5b005fbb..a1cf1a8e 100644 --- a/src/gmrequest.c +++ b/src/gmrequest.c @@ -434,9 +434,6 @@ static void gopherError_GmRequest_(iGmRequest *d, iSocket *socket, int error, co } static void beginGopherConnection_GmRequest_(iGmRequest *d, const iString *host, uint16_t port) { - if (port == 0) { - port = 70; /* default port */ - } clear_Block(&d->gopher.source); iGmResponse *resp = d->resp; d->gopher.meta = &resp->meta; @@ -642,7 +639,11 @@ void submit_GmRequest(iGmRequest *d) { } } else if (equalCase_Rangecc(url.scheme, "gopher")) { - beginGopherConnection_GmRequest_(d, host, port); + beginGopherConnection_GmRequest_(d, host, port ? port : 70); + return; + } + else if (equalCase_Rangecc(url.scheme, "finger")) { + beginGopherConnection_GmRequest_(d, host, port ? port : 79); return; } else if (!equalCase_Rangecc(url.scheme, "gemini")) { diff --git a/src/gopher.c b/src/gopher.c index dfdcf672..229ff9f4 100644 --- a/src/gopher.c +++ b/src/gopher.c @@ -149,16 +149,21 @@ void deinit_Gopher(iGopher *d) { void open_Gopher(iGopher *d, const iString *url) { iUrl parts; init_Url(&parts, url); - /* Determine Gopher item type. */ - d->type = '1'; if (!isEmpty_Range(&parts.path)) { if (*parts.path.start == '/') { parts.path.start++; } - if (parts.path.start < parts.path.end) { - d->type = *parts.path.start; - parts.path.start++; - } + } + /* Determine Gopher item type (finger is type 0). */ + if (equalCase_Rangecc(parts.scheme, "finger")) { + d->type = '0'; + } + else if (parts.path.start < parts.path.end) { + d->type = *parts.path.start; + parts.path.start++; + } + else { + d->type = '1'; } if (d->type == '7' && isEmpty_Range(&parts.query)) { /* Ask for the query parameters first. */ diff --git a/src/ui/documentwidget.c b/src/ui/documentwidget.c index bc9dbc8d..da66c65d 100644 --- a/src/ui/documentwidget.c +++ b/src/ui/documentwidget.c @@ -2292,6 +2292,7 @@ static iBool processEvent_DocumentWidget_(iDocumentWidget *d, const SDL_Event *e const iRangecc scheme = urlScheme_String(linkUrl); const iBool isGemini = equalCase_Rangecc(scheme, "gemini"); if (willUseProxy_App(scheme) || isGemini || + equalCase_Rangecc(scheme, "finger") || equalCase_Rangecc(scheme, "gopher")) { /* Regular links that we can open. */ pushBackN_Array( -- cgit v1.2.3 From fe4302d8cbd04d64cab96d7781285a9cf602d591 Mon Sep 17 00:00:00 2001 From: Jaakko Keränen Date: Sat, 2 Jan 2021 14:18:41 +0200 Subject: GmDocument: New link icon for Finger links Added a new link flag to identify Finger links so they can use their own icon. --- src/gmdocument.c | 59 ++++++++++++++++++++++++++++---------------------------- src/gmdocument.h | 13 +++++++------ 2 files changed, 36 insertions(+), 36 deletions(-) (limited to 'src') diff --git a/src/gmdocument.c b/src/gmdocument.c index 8d2e3f1f..6f038524 100644 --- a/src/gmdocument.c +++ b/src/gmdocument.c @@ -177,13 +177,15 @@ static iRangecc addLink_GmDocument_(iGmDocument *d, iRangecc line, iGmLinkId *li else if (startsWithCase_Rangecc(parts.scheme, "http")) { link->flags |= http_GmLinkFlag; } - else if (equalCase_Rangecc(parts.scheme, "gopher") || - equalCase_Rangecc(parts.scheme, "finger")) { - link->flags |= gopher_finger_GmLinkFlag; + else if (equalCase_Rangecc(parts.scheme, "gopher")) { + link->flags |= gopher_GmLinkFlag; if (startsWith_Rangecc(parts.path, "/7")) { link->flags |= query_GmLinkFlag; } } + else if (equalCase_Rangecc(parts.scheme, "finger")) { + link->flags |= finger_GmLinkFlag; + } else if (equalCase_Rangecc(parts.scheme, "file")) { link->flags |= file_GmLinkFlag; } @@ -291,6 +293,7 @@ static void doLayout_GmDocument_(iGmDocument *d) { static const char *globe = "\U0001f310"; static const char *quote = "\u201c"; static const char *magnifyingGlass = "\U0001f50d"; + static const char *pointingFinger = "\U0001f449"; const float midRunSkip = 0; /*0.120f;*/ /* extra space between wrapped text/quote lines */ const iPrefs *prefs = prefs_App(); clear_Array(&d->layout); @@ -307,7 +310,7 @@ static void doLayout_GmDocument_(iGmDocument *d) { iBool isFirstText = prefs->bigFirstParagraph; iBool addQuoteIcon = prefs->quoteIcon; iBool isPreformat = iFalse; - iRangecc preAltText = iNullRange; + iRangecc preAltText = iNullRange; /* TODO: alt text is being ignored */ int preFont = preformatted_FontId; uint16_t preId = 0; iBool enableIndents = iFalse; @@ -474,6 +477,7 @@ static void doLayout_GmDocument_(iGmDocument *d) { const iGmLink *link = constAt_PtrArray(&d->links, run.linkId - 1); icon.text = range_CStr(link->flags & query_GmLinkFlag ? magnifyingGlass : link->flags & file_GmLinkFlag ? folder + : link->flags & finger_GmLinkFlag ? pointingFinger : link->flags & mailto_GmLinkFlag ? envelope : link->flags & remote_GmLinkFlag ? globe : arrow); @@ -1111,7 +1115,7 @@ static void normalize_GmDocument(iGmDocument *d) { iRangecc src = range_String(&d->source); iRangecc line = iNullRange; iBool isPreformat = iFalse; - if (d->format == plainText_GmDocumentFormat) { // || isGopher_GmDocument_(d)) { + if (d->format == plainText_GmDocumentFormat) { isPreformat = iTrue; /* Cannot be turned off. */ } const int preTabWidth = 4; /* TODO: user-configurable parameter */ @@ -1364,7 +1368,8 @@ iMediaId linkAudio_GmDocument(const iGmDocument *d, iGmLinkId linkId) { enum iColorId linkColor_GmDocument(const iGmDocument *d, iGmLinkId linkId, enum iGmLinkPart part) { const iGmLink *link = link_GmDocument_(d, linkId); - const int www_GmLinkFlag = http_GmLinkFlag | mailto_GmLinkFlag; + const int www_GmLinkFlag = http_GmLinkFlag | mailto_GmLinkFlag; + const int gopherOrFinger_GmLinkFlag = gopher_GmLinkFlag | finger_GmLinkFlag; if (link) { const iBool isUnsupported = (link->flags & supportedProtocol_GmLinkFlag) == 0; if (part == icon_GmLinkPart) { @@ -1372,42 +1377,36 @@ enum iColorId linkColor_GmDocument(const iGmDocument *d, iGmLinkId linkId, enum return tmBadLink_ColorId; } if (link->flags & visited_GmLinkFlag) { - return link->flags & www_GmLinkFlag - ? tmHypertextLinkIconVisited_ColorId - : link->flags & gopher_finger_GmLinkFlag ? tmGopherLinkIconVisited_ColorId - : tmLinkIconVisited_ColorId; + return link->flags & www_GmLinkFlag ? tmHypertextLinkIconVisited_ColorId + : link->flags & gopherOrFinger_GmLinkFlag ? tmGopherLinkIconVisited_ColorId + : tmLinkIconVisited_ColorId; } - return link->flags & www_GmLinkFlag - ? tmHypertextLinkIcon_ColorId - : link->flags & gopher_finger_GmLinkFlag ? tmGopherLinkIcon_ColorId - : tmLinkIcon_ColorId; + return link->flags & www_GmLinkFlag ? tmHypertextLinkIcon_ColorId + : link->flags & gopherOrFinger_GmLinkFlag ? tmGopherLinkIcon_ColorId + : tmLinkIcon_ColorId; } if (part == text_GmLinkPart) { - return link->flags & www_GmLinkFlag - ? tmHypertextLinkText_ColorId - : link->flags & gopher_finger_GmLinkFlag ? tmGopherLinkText_ColorId - : tmLinkText_ColorId; + return link->flags & www_GmLinkFlag ? tmHypertextLinkText_ColorId + : link->flags & gopherOrFinger_GmLinkFlag ? tmGopherLinkText_ColorId + : tmLinkText_ColorId; } if (part == textHover_GmLinkPart) { - return link->flags & www_GmLinkFlag - ? tmHypertextLinkTextHover_ColorId - : link->flags & gopher_finger_GmLinkFlag ? tmGopherLinkTextHover_ColorId - : tmLinkTextHover_ColorId; + return link->flags & www_GmLinkFlag ? tmHypertextLinkTextHover_ColorId + : link->flags & gopherOrFinger_GmLinkFlag ? tmGopherLinkTextHover_ColorId + : tmLinkTextHover_ColorId; } if (part == domain_GmLinkPart) { if (isUnsupported) { return tmBadLink_ColorId; } - return link->flags & www_GmLinkFlag - ? tmHypertextLinkDomain_ColorId - : link->flags & gopher_finger_GmLinkFlag ? tmGopherLinkDomain_ColorId - : tmLinkDomain_ColorId; + return link->flags & www_GmLinkFlag ? tmHypertextLinkDomain_ColorId + : link->flags & gopherOrFinger_GmLinkFlag ? tmGopherLinkDomain_ColorId + : tmLinkDomain_ColorId; } if (part == visited_GmLinkPart) { - return link->flags & www_GmLinkFlag - ? tmHypertextLinkLastVisitDate_ColorId - : link->flags & gopher_finger_GmLinkFlag ? tmGopherLinkLastVisitDate_ColorId - : tmLinkLastVisitDate_ColorId; + return link->flags & www_GmLinkFlag ? tmHypertextLinkLastVisitDate_ColorId + : link->flags & gopherOrFinger_GmLinkFlag ? tmGopherLinkLastVisitDate_ColorId + : tmLinkLastVisitDate_ColorId; } } return tmLinkText_ColorId; diff --git a/src/gmdocument.h b/src/gmdocument.h index 7d962511..e2c7e10c 100644 --- a/src/gmdocument.h +++ b/src/gmdocument.h @@ -53,12 +53,13 @@ typedef uint16_t iGmLinkId; enum iGmLinkFlags { gemini_GmLinkFlag = iBit(1), - gopher_finger_GmLinkFlag = iBit(2), - http_GmLinkFlag = iBit(3), - file_GmLinkFlag = iBit(4), - data_GmLinkFlag = iBit(5), - about_GmLinkFlag = iBit(6), - mailto_GmLinkFlag = iBit(7), + gopher_GmLinkFlag = iBit(2), + finger_GmLinkFlag = iBit(3), + http_GmLinkFlag = iBit(4), + file_GmLinkFlag = iBit(5), + data_GmLinkFlag = iBit(6), + about_GmLinkFlag = iBit(7), + mailto_GmLinkFlag = iBit(8), supportedProtocol_GmLinkFlag = 0xff, remote_GmLinkFlag = iBit(9), humanReadable_GmLinkFlag = iBit(10), /* link has a human-readable description */ -- cgit v1.2.3