make framebuffer use the language environment for the UI resources

This commit is contained in:
Vincent Sanders 2019-02-17 00:08:28 +00:00
parent cfb6c461fc
commit 54371c28f0
18 changed files with 181 additions and 32 deletions

3
.gitignore vendored
View File

@ -7,8 +7,7 @@ frontends/riscos/appdir/Resources/fr/Templates,fec
frontends/riscos/appdir/Resources/de/Templates,fec frontends/riscos/appdir/Resources/de/Templates,fec
frontends/riscos/appdir/Resources/nl/Templates,fec frontends/riscos/appdir/Resources/nl/Templates,fec
resources/*/Messages resources/*/Messages
frontends/gtk/res/*/Messages frontends/*/res/*/Messages
frontends/windows/res/*/Messages
codedocs codedocs
nsgtk nsgtk
nsgtk3 nsgtk3

View File

@ -1,5 +1,10 @@
#
# Makefile for NetSurf Framebuffer frontend
#
# This file is part of NetSurf
#
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# Framebuffer target setup # Framebuffer flag setup (using pkg-config)
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
CFLAGS += -std=c99 -g \ CFLAGS += -std=c99 -g \
@ -50,6 +55,14 @@ LDFLAGS += -Wl,--whole-archive
$(eval $(call pkg_config_find_and_add,libnsfb,libnsfb)) $(eval $(call pkg_config_find_and_add,libnsfb,libnsfb))
LDFLAGS += -Wl,--no-whole-archive LDFLAGS += -Wl,--no-whole-archive
# ---------------------------------------------------------------------------
# Target setup
# ---------------------------------------------------------------------------
# The filter and target for split messages
MESSAGES_FILTER=fb
MESSAGES_TARGET=$(FRONTEND_RESOURCES_DIR)
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
# HOST specific feature flags # HOST specific feature flags
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------

View File

@ -17,29 +17,128 @@
*/ */
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "utils/filepath.h" #include "utils/filepath.h"
#include "utils/log.h"
#include "framebuffer/findfile.h" #include "framebuffer/findfile.h"
char **respaths; /** resource search path vector */ char **respaths; /** resource search path vector */
/** Create an array of valid paths to search for resources. #define MAX_LANGV_SIZE 32
/**
* goes through the environment in appropriate order to find configured language
*
* \return language to use or "C" if nothing appropriate is set
*/
static const char *get_language_env(void)
{
const char *envstr;
envstr = getenv("LANGUAGE");
if ((envstr != NULL) && (envstr[0] != 0)) {
return envstr;
}
envstr = getenv("LC_ALL");
if ((envstr != NULL) && (envstr[0] != 0)) {
return envstr;
}
envstr = getenv("LC_MESSAGES");
if ((envstr != NULL) && (envstr[0] != 0)) {
return envstr;
}
envstr = getenv("LANG");
if ((envstr != NULL) && (envstr[0] != 0)) {
return envstr;
}
return "C";
}
/**
* build a string vector of language names
*/
static char **get_language_names(void)
{
char **langv; /* output string vector of languages */
int langc; /* count of languages in vector */
const char *envlang; /* colon separated list of languages from environment */
int lstart = 0; /* offset to start of current language */
int lunder = 0; /* offset to underscore in current language */
int lend = 0; /* offset to end of current language */
char *nlang;
langv = calloc(MAX_LANGV_SIZE + 2, sizeof(char *));
if (langv == NULL) {
return NULL;
}
envlang = get_language_env();
for (langc = 0; langc < MAX_LANGV_SIZE; langc++) {
/* work through envlang splitting on : */
while ((envlang[lend] != 0) &&
(envlang[lend] != ':') &&
(envlang[lend] != '.')) {
if (envlang[lend] == '_') {
lunder = lend;
}
lend++;
}
/* place language in string vector */
nlang = malloc(lend - lstart + 1);
memcpy(nlang, envlang + lstart, lend - lstart);
nlang[lend - lstart] = 0;
langv[langc] = nlang;
/* add language without specialisation to vector */
if (lunder != lstart) {
nlang = malloc(lunder - lstart + 1);
memcpy(nlang, envlang + lstart, lunder - lstart);
nlang[lunder - lstart] = 0;
langv[++langc] = nlang;
}
/* if we stopped at the dot, move to the colon delimiter */
while ((envlang[lend] != 0) &&
(envlang[lend] != ':')) {
lend++;
}
if (envlang[lend] == 0) {
/* reached end of environment language list */
break;
}
lend++;
lstart = lunder = lend;
}
return langv;
}
/**
* Create an array of valid paths to search for resources.
* *
* The idea is that all the complex path computation to find resources * The idea is that all the complex path computation to find resources
* is performed here, once, rather than every time a resource is * is performed here, once, rather than every time a resource is
* searched for. * searched for.
*/ */
char ** char **
fb_init_resource(const char *resource_path) fb_init_resource_path(const char *resource_path)
{ {
char **pathv; /* resource path string vector */ char **pathv; /* resource path string vector */
char **respath; /* resource paths vector */ char **respath; /* resource paths vector */
const char *lang = NULL; char **langv;
pathv = filepath_path_to_strvec(resource_path); pathv = filepath_path_to_strvec(resource_path);
respath = filepath_generate(pathv, &lang); langv = get_language_names();
respath = filepath_generate(pathv, (const char * const *)langv);
filepath_free_strvec(pathv); filepath_free_strvec(pathv);

View File

@ -27,6 +27,6 @@ extern char **respaths;
* is performed here, once, rather than every time a resource is * is performed here, once, rather than every time a resource is
* searched for. * searched for.
*/ */
char **fb_init_resource(const char *resource_path); char **fb_init_resource_path(const char *resource_path);
#endif /* NETSURF_FB_FINDFILE_H */ #endif /* NETSURF_FB_FINDFILE_H */

View File

@ -2104,7 +2104,8 @@ static struct gui_misc_table framebuffer_misc_table = {
.quit = gui_quit, .quit = gui_quit,
}; };
/** Entry point from OS. /**
* Entry point from OS.
* *
* /param argc The number of arguments in the string vector. * /param argc The number of arguments in the string vector.
* /param argv The argument string vector. * /param argv The argument string vector.
@ -2134,7 +2135,7 @@ main(int argc, char** argv)
die("NetSurf operation table failed registration"); die("NetSurf operation table failed registration");
} }
respaths = fb_init_resource(NETSURF_FB_RESPATH":"NETSURF_FB_FONTPATH); respaths = fb_init_resource_path(NETSURF_FB_RESPATH":"NETSURF_FB_FONTPATH);
/* initialise logging. Not fatal if it fails but not much we /* initialise logging. Not fatal if it fails but not much we
* can do about it either. * can do about it either.

View File

@ -1 +1 @@
../../../resources/en/Messages en/Messages

View File

@ -0,0 +1 @@
../../../../resources/de/welcome.html

View File

@ -0,0 +1 @@
../../../../resources/en/credits.html

View File

@ -0,0 +1 @@
../../../../resources/en/licence.html

View File

@ -0,0 +1 @@
../../../../resources/en/maps.html

View File

@ -0,0 +1 @@
../../../../resources/en/welcome.html

View File

@ -0,0 +1 @@
../../../../resources/it/credits.html

View File

@ -0,0 +1 @@
../../../../resources/it/licence.html

View File

@ -0,0 +1 @@
../../../../resources/ja/welcome.html

View File

@ -0,0 +1 @@
../../../../resources/nl/credits.html

View File

@ -0,0 +1 @@
../../../../resources/nl/licence.html

View File

@ -0,0 +1 @@
../../../../resources/nl/welcome.html

View File

@ -16,10 +16,12 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
/** \file /**
* \file
* Provides utility functions for finding readable files. * Provides utility functions for finding readable files.
* *
* These functions are intended to make finding resource files more straightforward. * These functions are intended to make finding resource files more
* straightforward.
*/ */
#include <sys/types.h> #include <sys/types.h>
@ -75,6 +77,7 @@ char *filepath_vsfindfile(char *str, const char *format, va_list ap)
return realpathname; return realpathname;
} }
/* exported interface documented in filepath.h */ /* exported interface documented in filepath.h */
char *filepath_sfindfile(char *str, const char *format, ...) char *filepath_sfindfile(char *str, const char *format, ...)
{ {
@ -88,6 +91,7 @@ char *filepath_sfindfile(char *str, const char *format, ...)
return ret; return ret;
} }
/* exported interface documented in filepath.h */ /* exported interface documented in filepath.h */
char *filepath_findfile(const char *format, ...) char *filepath_findfile(const char *format, ...)
{ {
@ -120,6 +124,7 @@ char *filepath_sfind(char **respathv, char *filepath, const char *filename)
return NULL; return NULL;
} }
/* exported interface documented in filepath.h */ /* exported interface documented in filepath.h */
char *filepath_find(char **respathv, const char *filename) char *filepath_find(char **respathv, const char *filename)
{ {
@ -141,6 +146,7 @@ char *filepath_find(char **respathv, const char *filename)
return ret; return ret;
} }
/* exported interface documented in filepath.h */ /* exported interface documented in filepath.h */
char * char *
filepath_sfinddef(char **respathv, filepath_sfinddef(char **respathv,
@ -182,7 +188,8 @@ filepath_generate(char * const *pathv, const char * const *langv)
int langc = 0; int langc = 0;
int respathc = 0; int respathc = 0;
struct stat dstat; struct stat dstat;
char tmppath[PATH_MAX]; char *tmppath;
int tmppathlen;
respath = calloc(MAX_RESPATH, sizeof(char *)); respath = calloc(MAX_RESPATH, sizeof(char *));
@ -193,12 +200,29 @@ filepath_generate(char * const *pathv, const char * const *langv)
/* path element exists and is a directory */ /* path element exists and is a directory */
langc = 0; langc = 0;
while (langv[langc] != NULL) { while (langv[langc] != NULL) {
snprintf(tmppath, sizeof tmppath, "%s/%s", pathv[pathc],langv[langc]); tmppathlen = snprintf(NULL,
0,
"%s/%s",
pathv[pathc],
langv[langc]);
tmppath = malloc(tmppathlen + 1);
if (tmppath == NULL) {
break;
}
snprintf(tmppath,
tmppathlen + 1,
"%s/%s",
pathv[pathc],
langv[langc]);
if ((stat(tmppath, &dstat) == 0) && if ((stat(tmppath, &dstat) == 0) &&
S_ISDIR(dstat.st_mode)) { S_ISDIR(dstat.st_mode)) {
/* path element exists and is a directory */ /* path element exists and is a directory */
respath[respathc++] = strdup(tmppath); respath[respathc++] = tmppath;
} else {
free(tmppath);
} }
langc++; langc++;
} }
respath[respathc++] = strdup(pathv[pathc]); respath[respathc++] = strdup(pathv[pathc]);
@ -208,6 +232,7 @@ filepath_generate(char * const *pathv, const char * const *langv)
return respath; return respath;
} }
/** /**
* expand ${} in a string into environment variables. * expand ${} in a string into environment variables.
* *
@ -282,6 +307,7 @@ expand_path(const char *path, int pathlen)
return exp; return exp;
} }
/* exported interface documented in filepath.h */ /* exported interface documented in filepath.h */
char ** char **
filepath_path_to_strvec(const char *path) filepath_path_to_strvec(const char *path)
@ -325,6 +351,7 @@ filepath_path_to_strvec(const char *path)
return strvec; return strvec;
} }
/* exported interface documented in filepath.h */ /* exported interface documented in filepath.h */
void filepath_free_strvec(char **pathv) void filepath_free_strvec(char **pathv)
{ {
@ -335,4 +362,3 @@ void filepath_free_strvec(char **pathv)
} }
free(pathv); free(pathv);
} }