Internationalisation
Martin Tharby Jones <[email protected]> Thu, 27 Feb 2014 20:47:40 +0000
| Newsgroups | gmane.comp.sysutils.lcdproc |
|---|---|
| Message-ID | <[email protected]> |
This is a multi-part message in MIME format.
--------------080905080408080904090902
Content-Type: multipart/alternative;
boundary="------------010606020407020602040109"
--------------010606020407020602040109
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
Hello,
I've attached a patch which provides a first step towards
internationalisation of LCDproc.
I'm a British English speaker with minimal second language skills so I
apologise that I have only addressed those areas that are relevant to
me. My problem was that I have a number of Celtic & Gaelic tracks in my
music collection and the accented characters used in those languages
were not being displayed correctly.
UTF-8 characters greater than 0x7F were displayed as two or more strange
characters:
With the patch and a display that supports ISO-8859-1 most western
European languages can be displayed:
I've also added string support for Unicode on graphic displays:
I've not done title or scroller widgets because I feel graphic displays
should support pixel level scrolling and proportional spaced fonts which
would require more work than I am prepared for (I don't have a graphic
display). Basic string support was coded as proof of concept and as a
test case.
There is obviously more to do but the code in the patch meets my
requirements and I hope will be of use to others.
Further work I have thought of:
* Conversion of menu text
* Use of gettext() and conversion for system screens
* Use of gettext() and conversion for lcdproc screens
Regards
Martin
--------------010606020407020602040109
Content-Type: multipart/related;
boundary="------------060202050607080408030502"
--------------060202050607080408030502
Content-Type: text/html; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=ISO-8859-1">
</head>
<body bgcolor="#FFFFFF" text="#000000">
Hello,<br>
<br>
I've attached a patch which provides a first step towards
internationalisation of LCDproc.<br>
<br>
I'm a British English speaker with minimal second language skills so
I apologise that I have only addressed those areas that are relevant
to me. My problem was that I have a number of Celtic & Gaelic
tracks in my music collection and the accented characters used in
those languages were not being displayed correctly.<br>
<br>
UTF-8 characters greater than 0x7F were displayed as two or more
strange characters:<br>
<br>
<img alt="" src="cid:[email protected]"
height="168" width="488"><br>
<br>
With the patch and a display that supports ISO-8859-1 most western
European languages can be displayed:<br>
<br>
<img alt="" src="cid:[email protected]"
height="168" width="488"><br>
<br>
I've also added string support for Unicode on graphic displays:<br>
<br>
<img alt="" src="cid:[email protected]"
height="168" width="488"><br>
<br>
I've not done title or scroller widgets because I feel graphic
displays should support pixel level scrolling and proportional
spaced fonts which would require more work than I am prepared for (I
don't have a graphic display). Basic string support was coded as
proof of concept and as a test case.<br>
<br>
There is obviously more to do but the code in the patch meets my
requirements and I hope will be of use to others.<br>
<br>
Further work I have thought of:<br>
<ul>
<li>Conversion of menu text</li>
<li>Use of gettext() and conversion for system screens</li>
<li>Use of gettext() and conversion for lcdproc screens<br>
</li>
</ul>
Regards<br>
<br>
Martin<br>
<br>
</body>
</html>
--------------060202050607080408030502
Content-Type: image/png;
name="2014-02-12~16:38:56.png"
Content-Transfer-Encoding: base64
Content-ID: <[email protected]>
Content-Disposition: inline;
filename="2014-02-12~16:38:56.png"
iVBORw0KGgoAAAANSUhEUgAAAegAAACoAQMAAAARse+XAAAABlBMVEUoUShmzGahqbSDAAAB
yElEQVRoge2XDXrDIAiGcwVPwP2Pxwkc8Kmxafqz4kb6PLCMGvQtQoukW/XI9sV0KSTXkyVY
cH+F0x6ZfB92wP3ukW/mYHpR3HSYeuVbrlh6XdxUiUstLEa9kfFvdv7f9KK4xZ98fcSnSu1/
7+48gF4UN/65qGvkfNTeeY2VYHpd3JJzybNdtWX8yZlKwfSiuEVbjTXfktLnNRZO++KGsKX5
IMN4OnsR+jPpNPGNmSYj6yfR6u2C9GfygB5+NNkEy/u+I+k3ZdNColFO3AbUjdpdrJnKQYup
69C+uMkcIaWte8omhrG3Uyp0n/ZY2hu3Xq2d0OgrBCNyXlpjPdt5HO2NG3W0uxwD1W2OxtR1
aI+gxibfvW/uRlvQHpIuRfviboVD9uNPvlamK8/n6om2h+lo2iFbPzVZG6WOebIg53rQWrHV
OnQxHUv74lahXeMnPzcDJlBqN8IXoT8VqzHUD1s51d5GUVptYA2UaZ/C4ljaFzcOEa2uMtVY
xUFDGOgzci9CWLAsmF4TN9501oWa7/5scVwQTDtkO/cKjdeXOw+jHTLVWK31oOFCb+l8QSzt
izvppJNOOumkk0466aSTTjrppJNO+m/oHzPn9c7uBVDPAAAAAElFTkSuQmCC
--------------060202050607080408030502
Content-Type: image/png;
name="2014-02-12~17:50:50.png"
Content-Transfer-Encoding: base64
Content-ID: <[email protected]>
Content-Disposition: inline;
filename="2014-02-12~17:50:50.png"
iVBORw0KGgoAAAANSUhEUgAAAegAAACoAQMAAAARse+XAAAAZ3pUWHRSYXcgcHJvZmlsZSB0
eXBlIGV4aWYAAHjaVcjBDcAgDEPRe6boCCYJJoyDUJG6QcdvBKe+w5dlud9nybV5iNcW7CSS
d+86cgSOAljJ6p7nGvipxuBqLq2xcnIqDHpbMc0aIB8cQxc4NhOZPgAAAAZQTFRFKFEoZsxm
oam0gwAAAVpJREFUaIHtlg0OgzAIhXuFnuDd/3icgNHSdsv8mUozXMazM0r9guCgTWxR+mE6
Z8jYeUQfWA532qIX329vQP1uyzeRMz0pbrxNffItw5eeFzcYlDmTGMuNXJ9582/Tk+IWf/L3
EZ9F3I+jb+5AT4pbf5SLa835qL31GsvO9Ly4JeeS5zq4ZXynp8KZnhS3nGuNNd+S0v0ac6dt
catoOYWtiXvR1zRoLJxSXUbBO7oFfUlrNFaufoM+rlQKCbWcZOnUokK16FIyKu2GtEWpeMja
R3XplGbSLXpgO/W+tEVJt0q1oWIsKgA3z6N93pC2KA1P7eLpm9qmadOzN22R1hjrGX3RrBZA
C+xjhXrRFv0vPRI70nvc4kvb4u6bYoz2edziS9vibn3lOU5YvOnrSnUX/Dr4hMWZtsWNyyn3
pg36YxrxvYMOOuiggw466KCDDjrooIMOOuig59EPUGF7adK5XaAAAAAASUVORK5CYII=
--------------060202050607080408030502
Content-Type: image/png;
name="2014-02-24~17:16:11.png"
Content-Transfer-Encoding: base64
Content-ID: <[email protected]>
Content-Disposition: inline;
filename="2014-02-24~17:16:11.png"
iVBORw0KGgoAAAANSUhEUgAAAegAAACoAQMAAAARse+XAAAABlBMVEUoUShmzGahqbSDAAAB
3UlEQVRoge2YAXKEMAhFvQIn4P7H4wQ0gaDJmnR3TUbsFDqzVczzA5XIduMZ2/4uTQAMgPk4
Hb3Y4UhLysoK8KW/S/TFam08XaUvIr+d/jTFrr1oU/pIJ4TyK2sTDrQRnOlleednLT9dxEQp
CBJtpIE2gDO9LO/8kW5IUGuXxutoozO9Om9sa84DbepHfh+9LO90lHus1Fx6TM4G2t70srxb
a13vd+Tb6TeZ/W679kk9O8q7hN5G7kFfzJhbmmqvnaC20imuR9GXrE/XgQyFH0l/apuMCvry
BLLpkMorJQujvmC6IfjSM7bl8pIOS4hIWmLZWtm05Ro9jl6TN6g29LTLhPQwek3ezFpz7mjz
qNNc6e8SPdFlDNCac6k5sDml+fYR4lH0jAX9D2nrLNzdZSZqHrDqsj157vRlExr1rlj5UWOq
XdVEYUfu9GXbsnAeCeVnLzbpnFhtrcVJ5pS/hy89lTeRCloIaigTFOl+S8dXBCQbnCUgV3o+
73LHXFAwlaq81lGE+0quIveil+bNPe3i1SVS+kHkt9JzeTM2/760zVRlcrHReizHAnCsdKfn
8ubma74ZnjzmZj5Wu9OXbaBN52gabXwIfdmCDjrooIMOOuiggw466KCD9qF/ANZQ9kozh3Rv
AAAAAElFTkSuQmCC
--------------060202050607080408030502--
--------------010606020407020602040109--
--------------080905080408080904090902
Content-Type: text/x-patch;
name="internationalisation.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="internationalisation.patch"
Index: LCDd.conf
===================================================================
RCS file: /cvsroot/lcdproc/lcdproc/LCDd.conf,v
retrieving revision 1.171
diff -u -r1.171 LCDd.conf
--- LCDd.conf 29 Jan 2014 21:48:03 -0000 1.171
+++ LCDd.conf 27 Feb 2014 18:37:05 -0000
@@ -35,6 +35,7 @@
# function properly.
# NOTE: Always place a slash as last character !
DriverPath=server/drivers/
+# DriverPath=/usr/lib/lcdproc/
# Tells the server to load the given drivers. Multiple lines can be given.
# The name of the driver is case sensitive and determines the section
@@ -50,7 +51,36 @@
# mdm166a, ms6931, mtc_s16209x, MtxOrb, mx5000, NoritakeVFD, picolcd,
# pyramid, sdeclcd, sed1330, sed1520, serialPOS, serialVFD, shuttleVFD, sli,
# stv5730, svga, t6963, text, tyan, ula200, vlsys_m428, xosd
-Driver=curses
+#Driver=curses
+#Driver=picolcd
+#Driver=lirc
+Driver=glcd
+
+
+# Configure how LCDd interprets text sent to it prior sending to the display.
+# The locale setting is used in character conversion routines. It may need to
+# be set here if the LCDd deamon is started before the enviroment value has
+# been set. Use the command `locale -a` to list available options.
+Locale=en_GB.utf8
+# System character encoding; input to LCDd, default from locale.
+# The command `iconv --list` will list all coded character sets on your system.
+# The command `locale charmap` will list the one your system is using.
+#SystemCharEncode=UTF-8
+# Display character encoding; the default is the same as the system character
+# encoding which will disable character encoding conversion.
+# This is probably incorrect most modern locales use UTF-8, most displays use
+# an eight bit code with at most 256 glyphs.
+# The glcd driver with the built in font uses:
+#DisplayCharEncode=ISO-8859-1
+# This will work with displays based on the HD44780UA02 and compatable chips
+# although not all characters are mapped correctly. Other parts of the ISO-8859
+# series of standards may be more appropriate for example -5 for Latin/Cyrillic.
+# As a minimal fall-back which just supports ASCII you can use:
+#DisplayCharEncode=ANSI_X3.4-1968
+# To be able to display any glyph provided by a font with the glcd driver & FreeType use:
+#
+DisplayCharEncode=UTF-8
+
# Tells the driver to bind to the given interface. [default: 127.0.0.1]
Bind=127.0.0.1
@@ -116,8 +146,8 @@
ToggleRotateKey=Enter
PrevScreenKey=Left
NextScreenKey=Right
-#ScrollUpKey=Up
-#ScrollDownKey=Down
+ScrollUpKey=Up
+ScrollDownKey=Down
## The menu section. The menu is an internal LCDproc client. ##
@@ -129,11 +159,12 @@
# EnterKey (to select values) and at least one movement keys are required.
# These are the default key assignments:
MenuKey=Escape
+#MenuKey=Minus+Plus
EnterKey=Enter
UpKey=Up
DownKey=Down
-#LeftKey=Left
-#RightKey=Right
+LeftKey=Left
+RightKey=Right
### Driver sections are below this line, in alphabetical order ###
@@ -355,7 +386,7 @@
## glcd generic graphical display driver
[glcd]
# Select what type of connection. See documentation for types.
-ConnectionType=t6963
+ConnectionType=x11
# Width and height of the display in pixel. The supported sizes may depend on
# the ConnectionType. [default: 128x64; legal: 1x1 - 640x480]
@@ -365,6 +396,7 @@
# the driver has been compiled with FreeType and it is enabled. Otherwise the
# default 6x8 cell is used.
#CellSize=12x16
+CellSize=7x9
# If LCDproc has been compiled with FreeType 2 support this option can be used
# to turn if off intentionally. [default: yes; legal: yes, no]
@@ -374,6 +406,7 @@
# and should contain some special Unicode characters like arrows (Andale Mono
# is recommended and can be fetched at http://corefonts.sf.net).
#normal_font=/usr/local/lib/X11/fonts/TTF/andalemo.ttf
+normal_font=/home/martin/Downloads/Fonts/AndaleMono.ttf
# Some fonts miss the Unicode characters used to represent icons. In this case
# the built-in 5x8 font can used if this option is turned off. [default: yes;
@@ -390,7 +423,7 @@
# Set brightness of the backlight if the backlight is switched 'off'. Set this
# to zero to completely turn off the backlight. [default: 100; legal: 0 - 1000]
-#OffBrightness=0
+OffBrightness=200
# Time (ms) from first key report to first repeat. Set to 0 to disable repeated
# key reports. [default: 500; legal: 0 - 3000]
@@ -404,8 +437,10 @@
# By default keys 'A' to 'F' are assigned Up, Down, Left, Right, Enter, Escape.
KeyMap_A=Up
KeyMap_B=Down
-KeyMap_C=Enter
-KeyMap_D=Escape
+KeyMap_C=Left
+KeyMap_D=Right
+KeyMap_E=Enter
+KeyMap_F=Escape
# --- t6963 options ---
@@ -439,7 +474,8 @@
# --- x11 options ---
# PixelSize is size of each dot in pixels + a pixel gap. [default: 3+1]
-#x11_PixelSize=3+1
+x11_PixelSize=3+1
+#x11_PixelSize=2+1
# Colors are in RRGGBB format prefixed with "0x".
# PixelColor: The color of each dot at full contrast. [default: 0x000000]
@@ -452,6 +488,7 @@
# Border: Adds a border (empty space) around the LCD portion of X11 window.
# [default: 20]
#x11_Border=20
+x11_Border=4
# Inverted: inverts the pixels [default: no; legal: yes, no]
#x11_Inverted=no
@@ -803,9 +840,10 @@
# Specify an alternative location of the lircrc file [default: ~/.lircrc]
#lircrc=/etc/lircrc.lcdproc
+lircrc=/etc/lirc/lircrc
# Must be the same as in your lircrc
-#prog=lcdd
+prog=lcdd
@@ -998,11 +1036,11 @@
# Sets the initial state of the backlight upon start-up.
# [default: on; legal: on, off]
-#Backlight=on
+Backlight=on
# Set the initial brightness [default: 1000; legal: 0 - 1000]. Works only
# with the 20x4 device
-Brightness=1000
+Brightness=999
# Set the brightness while the backlight is 'off' [default: 0; legal: 0 - 1000].
# Works only with the 20x4 device.
@@ -1012,7 +1050,7 @@
Contrast=1000
# Link the key lights to the backlight? [default: on; legal: on, off]
-#LinkLights=off
+LinkLights=off
# Light the keys? [default: on; legal: on, off]
Keylights=on
@@ -1030,7 +1068,7 @@
# Host name or IP address of the LIRC instance that is to receive IR codes
# If not set, or set to an empty value, IR support is disabled.
-#LircHost=127.0.0.1
+LircHost=127.0.0.1
# UDP port on which LIRC is listening [default: 8765; legal: 1 - 65535]
LircPort=8765
Index: server/commands/server_commands.c
===================================================================
RCS file: /cvsroot/lcdproc/lcdproc/server/commands/server_commands.c,v
retrieving revision 1.10
diff -u -r1.10 server_commands.c
--- server/commands/server_commands.c 22 Feb 2012 22:25:32 -0000 1.10
+++ server/commands/server_commands.c 27 Feb 2014 18:37:05 -0000
@@ -88,11 +88,16 @@
/* Makes sense to me to set the output immediately;
* however, the outputs are currently set in
* draw_screen(screen *s, int timer)
- * Whatever for? */
+ * Whatever for?
+ * On one driver at least the output controls the
+ * key pad illumination which may depend on which
+ * screen is displayed. It ought to be an attribute
+ * of the screen.
+ */
/* drivers_output(output_state); */
- report(RPT_NOTICE, "output states changed");
+ report(RPT_DEBUG, "output states changed");
return 0;
}
Index: server/commands/widget_commands.c
===================================================================
RCS file: /cvsroot/lcdproc/lcdproc/server/commands/widget_commands.c,v
retrieving revision 1.16
diff -u -r1.16 widget_commands.c
--- server/commands/widget_commands.c 22 Feb 2012 22:25:32 -0000 1.16
+++ server/commands/widget_commands.c 27 Feb 2014 18:37:06 -0000
@@ -34,6 +34,93 @@
#include "widget_commands.h"
+#ifdef INTERNATIONAL_CHAR
+/* TODO: Review international character set conversion.
+ * Initialise character encoding for display */
+#include <iconv.h>
+#include <locale.h>
+#include <langinfo.h>
+#include "shared/configfile.h"
+
+/** Descriptor for character set conversion */
+iconv_t cd;
+
+/**
+ * Initialise widget character encoding conversion.
+ * Parameter strings passed to widget_set_func will probably be encoded using
+ * the system locale (commonly utf-8), displays usually have a simple eight bit
+ * character encoding often a slightly modified superset of ISO-8859-1 or ASCII.
+ *
+ * \retval <0 error
+ * \retval 0 success
+ */
+int
+widget_init(void)
+{
+ /* Local string */
+ char* locale;
+ /* Character encoding locale for system. */
+ char* system_char_encode;
+ /* Character encoding locale for display. */
+ char* display_char_encode;
+ /* Set result to fail to start. */
+ int result = -1;
+
+ /*
+ * Need to set program locale character classification as well as the source
+ * and destination character set for the conversion, a classification that
+ * supports Unicode should give best results.
+ */
+// report(RPT_NOTICE, "%s() initial locale %s", __FUNCTION__, setlocale(LC_ALL, NULL));
+// report(RPT_NOTICE, "%s() initial codeset %s", __FUNCTION__, nl_langinfo(CODESET));
+ report(RPT_NOTICE, "%s() locale set from enviroment %s", __FUNCTION__, setlocale(LC_ALL, ""));
+ locale = strdup(config_get_string("server", "Locale", 0, ""));
+ report(RPT_NOTICE, "%s() setting locale returns %s", __FUNCTION__, setlocale(LC_ALL, locale));
+ system_char_encode = nl_langinfo(CODESET);
+ report(RPT_NOTICE, "%s() program codeset %s", __FUNCTION__, system_char_encode);
+ system_char_encode = strdup(config_get_string("server", "SystemCharEncode", 0, system_char_encode));
+ display_char_encode = strdup(config_get_string("server", "DisplayCharEncode", 0, system_char_encode));
+ if (system_char_encode != NULL && *system_char_encode != '\0'
+ && display_char_encode != NULL && *display_char_encode != '\0')
+ {
+ if (strcmp(system_char_encode, display_char_encode) == 0)
+ {
+ cd = NULL;
+ }
+ else
+ {
+ /* Append "//TRANSLIT" to allow replacement characters for those not in the display set.
+ * TODO: Change this to defining custom characters if supported by the display see
+ * widget_set_text().
+ */
+ display_char_encode = realloc(display_char_encode, strlen(display_char_encode) + strlen("//TRANSLIT") + 1);
+ display_char_encode = strcat(display_char_encode, "//TRANSLIT");
+ cd = iconv_open(display_char_encode, system_char_encode);
+ }
+
+ if (cd == (iconv_t)-1)
+ {
+ report(RPT_WARNING, "%s() failed to open character conversion %s", __FUNCTION__, strerror(errno));
+ }
+ else
+ {
+ report(RPT_NOTICE, "%s() initialised character conversion %s to %s",
+ __FUNCTION__, system_char_encode, display_char_encode);
+ result = 0;
+ }
+ }
+ else
+ {
+ report(RPT_WARNING, "%s() failed to initialise character conversion", __FUNCTION__);
+ }
+ display_uses_utf8 = (strcmp(display_char_encode, "UTF-8") == 0);
+ free(locale);
+ free(system_char_encode);
+ free(display_char_encode);
+ return result;
+}
+#endif
+
/**
* Adds a widget to a screen, but doesn't give it a value
*
@@ -173,6 +260,58 @@
return 0;
}
+#ifdef INTERNATIONAL_CHAR
+/** TODO: Review international character set conversion.
+ * Convert parameter string from locale to display character string
+ * format and allocate storage for it.
+ */
+void widget_set_text(Widget * w, iconv_t cd, char* string)
+{
+ if (cd)
+ {
+ /* Length of parameter string in system encoding */
+ size_t inl = strlen(string);
+ /* Length of string in display encoding, we expect it to be the same
+ * or shorter but we won't know until the conversion has completed. */
+ size_t outl = (inl + 1);
+ char *result = malloc(outl);
+ /* Number of characters replaced (for debug). */
+ size_t count;
+ /* Number of bytes input (for debug). */
+ int incount = inl;
+ /* Input buffer pointer to the string argument */
+ char *inbuf = string;
+ /* Output buffer pointer to the memory allocated */
+ char *outbuf = result;
+ /* Initalise the converter */
+ iconv(cd, NULL, 0, &outbuf, &outl);
+ /* Convert the parameter character set ready to display.
+ * TODO: Change this to defining custom characters if supported by the
+ * display see the //TRANSLIT parameter to iconv_open() in widget_init().
+ */
+ if ((count = iconv(cd, &inbuf, &inl, &outbuf, &outl)) == -1) {
+ report(RPT_WARNING, "%s: Conversion error %s",
+ __FUNCTION__, strerror(errno));
+ }
+ report(RPT_INFO,
+ "%s: Replaced %d characters, bytes in %d/%d out %d ",
+ __FUNCTION__, count, incount - inl, incount, incount + 1 - outl);
+ /* TODO
+ * Is it worth resizing with realloc()? My use case is UTF-8 to ANSI_X3.4
+ * so would only save a few bytes when accented characters are converted.
+ */
+ *outbuf = '\0'; /* add null terminator */
+ w->text = result;
+ report(RPT_INFO, "%s %s", __FUNCTION__, w->text);
+ }
+ else
+ {
+ /* No conversion so just allocate a copy of the parameter. */
+ w->text = strdup(string);
+ }
+}
+#endif
+
/**
* Configures information about a widget, such as its size, shape,
* contents, position, speed, etc.
@@ -248,7 +387,12 @@
w->y = y;
if (w->text != NULL)
free(w->text);
+#ifdef INTERNATIONAL_CHAR
+ /* TODO: Review international character set conversion. */
+ widget_set_text(w, cd, argv[i + 2]);
+#else
w->text = strdup(argv[i + 2]);
+#endif
if (w->text == NULL) {
report(RPT_WARNING, "widget_set_func: Allocation error");
return -1;
@@ -327,7 +471,12 @@
else {
if (w->text != NULL)
free(w->text);
+#ifdef INTERNATIONAL_CHAR
+ /* TODO: Review international character set conversion. */
+ widget_set_text(w, cd, argv[i]);
+#else
w->text = strdup(argv[i]);
+#endif
if (w->text == NULL) {
report(RPT_WARNING, "widget_set_func: Allocation error");
return -1;
@@ -369,7 +518,12 @@
w->speed = speed;
if (w->text != NULL)
free(w->text);
+#ifdef INTERNATIONAL_CHAR
+ /* TODO: Review international character set conversion. */
+ widget_set_text(w, cd, argv[i + 6]);
+#else
w->text = strdup(argv[i + 6]);
+#endif
if (w->text == NULL) {
sock_send_error(c->sock, "Allocation error\n");
return -1;
Index: server/commands/widget_commands.h
===================================================================
RCS file: /cvsroot/lcdproc/lcdproc/server/commands/widget_commands.h,v
retrieving revision 1.5
diff -u -r1.5 widget_commands.h
--- server/commands/widget_commands.h 5 Jan 2011 23:34:37 -0000 1.5
+++ server/commands/widget_commands.h 27 Feb 2014 18:37:06 -0000
@@ -12,6 +12,12 @@
#ifndef COMMANDS_WIDGET_H
#define COMMANDS_WIDGET_H
+#ifdef INTERNATIONAL_CHAR
+/* TODO: Review international character set conversion.
+ * Initialise character encoding locale for display */
+int widget_init(void);
+#endif
+
int widget_add_func(Client *c, int argc, char **argv);
int widget_del_func(Client *c, int argc, char **argv);
int widget_set_func(Client *c, int argc, char **argv);
Index: server/drivers/glcd_drv.c
===================================================================
RCS file: /cvsroot/lcdproc/lcdproc/server/drivers/glcd_drv.c,v
retrieving revision 1.9
diff -u -r1.9 glcd_drv.c
--- server/drivers/glcd_drv.c 4 May 2013 14:31:15 -0000 1.9
+++ server/drivers/glcd_drv.c 27 Feb 2014 18:37:06 -0000
@@ -406,11 +406,34 @@
if ((y < 1) || (y > p->height))
return;
-
- for (i = 0; (string[i] != '\0') && (x <= p->width); i++, x++) {
+ for (i = 0; (string[i] != '\0') && (x <= p->width); i++, x++) {
#ifdef HAVE_FT2
if (p->use_ft2)
+#define USE_WIDE_CHAR
+#ifdef USE_WIDE_CHAR
+/*
+ * TODO: Review international UTF-8 string processing.
+ * Do any other drivers support Unicode?
+ */
+ {
+ wchar_t wc;
+ int consumed;
+
+ consumed = mbtowc(&wc, &string[i], strlen(&string[i]));
+ if (consumed > 0)
+ {
+ glcd_render_char_unicode(drvthis, x, y, wc, 1, 1);
+ i += consumed - 1;
+ }
+ else
+ {
+ report(RPT_DEBUG, "%s failed to convert character '%c'", __FUNCTION__, string[i]);
+ }
+
+ }
+#else /* USE_WIDE_CHAR */
glcd_render_char_unicode(drvthis, x, y, string[i] & 0xFF, 1, 1);
+#endif /* USE_WIDE_CHAR */
else
#endif
glcd_render_char(drvthis, x, y, string[i]);
Index: server/main.c
===================================================================
RCS file: /cvsroot/lcdproc/lcdproc/server/main.c,v
retrieving revision 1.99
diff -u -r1.99 main.c
--- server/main.c 10 Feb 2014 07:19:20 -0000 1.99
+++ server/main.c 27 Feb 2014 18:37:05 -0000
@@ -59,6 +59,11 @@
#include "clients.h"
#include "screen.h"
#include "screenlist.h"
+#ifdef INTERNATIONAL_CHAR
+/* TODO: Review international character set conversion.
+ * Initialise encoding locale for display */
+#include "commands/widget_commands.h"
+#endif
#include "parse.h"
#include "render.h"
#include "serverscreens.h"
@@ -126,6 +131,7 @@
char *drivernames[MAX_DRIVERS];
int num_drivers = 0;
+
/* End of configuration variables */
/* Local variables */
@@ -238,7 +244,15 @@
CHAIN(e, clients_init());
CHAIN(e, input_init());
CHAIN(e, menuscreens_init());
+#ifdef INTERNATIONAL_CHAR
+ /* TODO: Review international character set conversion.
+ * Character encoding locale for display needs initialising
+ * in widget_commands.
+ */
+ CHAIN(e, widget_init());
+#endif
CHAIN(e, server_screen_init());
+
CHAIN_END(e, "Critical error while initializing, abort.");
if (!foreground_mode) {
/* Tell to parent that startup went OK. */
@@ -490,7 +504,6 @@
return 0;
}
-
static void
set_default_settings(void)
{
Index: server/render.c
===================================================================
RCS file: /cvsroot/lcdproc/lcdproc/server/render.c,v
retrieving revision 1.55
diff -u -r1.55 render.c
--- server/render.c 19 Jan 2013 10:25:04 -0000 1.55
+++ server/render.c 27 Feb 2014 18:37:05 -0000
@@ -312,6 +312,9 @@
(w->x > 0) && (w->y > 0) && (w->y > fy) && (w->y <= bottom - top)) {
int length;
char str[BUFSIZE];
+#ifdef INTERNATIONAL_CHAR
+ wchar_t w_str[BUFSIZE];
+#endif
/*
* FIXME: Could be a bug here? w->x is recalculated (On first
@@ -321,8 +324,35 @@
*/
w->x = min(w->x, right - left);
length = min(right - left - w->x + 1, sizeof(str)-1);
+#ifdef INTERNATIONAL_CHAR
+ /*
+ * TODO: Review international string copy.
+ * This is just a proof of concept example, UTF-8 will also need
+ * to be handled in render_title() and render_scroller(). Before
+ * further changes are made we need to decide if there will be
+ * support for pixel scrolling and proportional fonts on graphic
+ * displays.
+ */
+
+ if (display_uses_utf8)
+ {
+ /* Convert to wide character string so that one character uses
+ * one storage unit so that string can be easily set to the
+ * required length.
+ */
+ mbstowcs(w_str, w->text, length);
+ w_str[length] = '\0';
+ wcstombs(str, w_str, sizeof(str));
+ }
+ else
+ {
+ strncpy(str, w->text, length);
+ str[length] = '\0';
+ }
+#else
strncpy(str, w->text, length);
str[length] = '\0';
+#endif
drivers_string(w->x + left, w->y + top, str);
}
return 0;
@@ -408,7 +438,7 @@
length = min(length, sizeof(str)-1);
if ((length <= width) || (delay == 0)) {
- /* copy test starting from the beginning */
+ /* copy text starting from the beginning */
length = min(length, width);
strncpy(str, w->text, length);
str[length] = '\0';
@@ -479,14 +509,15 @@
screen_width = abs(w->right - w->left + 1);
screen_width = min(screen_width, sizeof(str)-1);
- switch (w->length) { /* actually, direction... */
- case 'm': // Marquee
- length = strlen(w->text);
- if (length <= screen_width) {
- /* it fits within the box, just render it */
- drivers_string(w->left, w->top, w->text);
- }
- else {
+ length = strlen(w->text);
+ if (length <= screen_width) {
+ /* it fits within the box, just render it */
+ drivers_string(w->left, w->top, w->text);
+ }
+ else {
+ switch (w->length) { /* actually, direction... */
+ case 'm': // Marquee
+ {
int necessaryTimeUnits = 0;
if (w->speed > 0) {
@@ -518,15 +549,10 @@
str[0] = '\0';
}
drivers_string(w->left, w->top, str);
+ break;
}
- break;
- case 'h':
- length = strlen(w->text) + 1;
- if (length <= screen_width) {
- /* it fits within the box, just render it */
- drivers_string(w->left, w->top, w->text);
- }
- else {
+ case 'h':
+ {
int effLength = length - screen_width;
int necessaryTimeUnits = 0;
@@ -568,18 +594,14 @@
str[0] = '\0';
}
drivers_string(w->left, w->top, str);
+ break;
}
- break;
+
/* FIXME: Vert scrollers don't always seem to scroll */
/* back up after hitting the bottom. They jump back to */
/* the top instead... (nevermind?) */
- case 'v':
- length = strlen(w->text);
- if (length <= screen_width) {
- /* no scrolling required... */
- drivers_string(w->left, w->top, w->text);
- }
- else {
+ case 'v':
+ {
int lines_required = (length / screen_width)
+ (length % screen_width ? 1 : 0);
int available_lines = (w->bottom - w->top + 1);
@@ -634,13 +656,14 @@
for (i = begin; i < begin + available_lines; i++) {
strncpy(str, &((w->text)[i * (screen_width)]), screen_width);
str[screen_width] = '\0';
- /*debug(RPT_DEBUG, "rendering: '%s' of %s", */
- /*str,w->text); */
+ /* debug(RPT_DEBUG, "rendering: '%s' of %s", str,w->text); */
+
drivers_string(w->left, w->top + (i - begin), str);
}
}
+ break;
}
- break;
+ }
}
}
return 0;
Index: server/widget.h
===================================================================
RCS file: /cvsroot/lcdproc/lcdproc/server/widget.h,v
retrieving revision 1.18
diff -u -r1.18 widget.h
--- server/widget.h 22 Feb 2012 22:25:32 -0000 1.18
+++ server/widget.h 27 Feb 2014 18:37:05 -0000
@@ -13,6 +13,18 @@
#ifndef WIDGET_H
#define WIDGET_H
+/* TODO: Review international character set conversion.
+ * International character definition should come from the configuration
+ * if the code is to be kept conditional. I've used conditional code for
+ * ease of testing and review.
+ */
+#define INTERNATIONAL_CHAR
+
+#ifdef INTERNATIONAL_CHAR
+ /** Character encoding for display. */
+ int display_uses_utf8;
+#endif
+
#define INC_TYPES_ONLY 1
#include "screen.h"
#undef INC_TYPES_ONLY
--------------080905080408080904090902
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
_______________________________________________
LCDproc mailing list
[email protected]
http://lists.omnipotent.net/mailman/listinfo/lcdproc
--------------080905080408080904090902--