Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

ncurses i utf8

127 views
Skip to first unread message

Krzysztof Garus

unread,
Nov 4, 2004, 2:05:30 AM11/4/04
to
witam,

zabieram się do nauki ncurses, bo chcę napisać program z takim interfejsem.
Wszystkie stringi w programie mają być kodowane w UTF-8. Czy
niemożliwe/trudne/łatwe jest aby użytkownikowi zawsze wyświetlało się to
dobrze?

bajcik
--
Krzysztof Garus
Stronka: http://kolos.math.uni.lodz.pl/~bajcik/
Serwis: http://gielda.linux.pl/ #GG 2065861

Krzysztof Garus

unread,
Nov 4, 2004, 2:13:00 AM11/4/04
to
Świadek Krzysztof Garus zeznał:

> witam,
>
> zabieram się do nauki ncurses, bo chcę napisać program z takim interfejsem.
> Wszystkie stringi w programie mają być kodowane w UTF-8. Czy
> niemożliwe/trudne/łatwe jest aby użytkownikowi zawsze wyświetlało się to
> dobrze?

dodam że znalazłem fajny tekst związany z tym zagadnieniem:
http://groups.google.com/groups?hl=pl&lr=&selm=slrn8inpn5.fk.radecki%40localhost.localdomain

Ale pytanie o to jak zadbać o poprawność obsługi od strony programisty jest
aktualne.

bajcik

Marcin 'Qrczak' Kowalczyk

unread,
Nov 4, 2004, 3:49:52 AM11/4/04
to
Krzysztof Garus <baj...@kolos.math.uni.lodz.pl> writes:

> zabieram się do nauki ncurses, bo chcę napisać program z takim
> interfejsem. Wszystkie stringi w programie mają być kodowane w
> UTF-8. Czy niemożliwe/trudne/łatwe jest aby użytkownikowi zawsze
> wyświetlało się to dobrze?

Są dwa warianty części API curses: wąski, używający typów chtype,
char * (np. addch, addstr, getch) i szeroki, z cchar_t, wchar_t *
(np. add_wch, add_wstr, get_wch).

ncurses z jednego źródła produkuje dwie biblioteki, używające
wewnętrznie wąskich i szerokich znaków (libcurses i libcursesw).

API z wąskimi znakami nadaje się tylko do kodowań, w których jeden
znak zajmuje jeden bajt. Biblioteka z wąskimi znakami obsługuje tylko
wąskie API.

API z szerokimi znakami nadaje się do dowolnych kodowań obsługiwanych
przez system, przy czym programista musi podawać ciągi wchar_t (jeden
cchar_t może zawierać kilka wchar_t, jeśli to jest znak z osobno
kodowanymi akcentami - API to przewiduje, ale nie wiem, jak działa
obecna implementacja). Biblioteka z szerokimi znakami obsługuje oba
API. Wewnętrznie konwertuje wszystko do wchar_t, a przy wyświetlaniu
konwertuje z powrotem.

Jeśli używamy libcursesw, to sensowniej jest używać tylko szerokiego
API. Jest pewne, że addch/getch nie ma sensu w UTF-8 i że addstr nie
zadziała w UTF-8 z libcurses. Nie wiem, jak się zachowa addstr w UTF-8
z libcursesw (i inne operacje na całych napisach), ale zgaduję, że źle.
Szerokie API to jedyny sposób na pełnoekranowe wyświetlanie się na
terminalach UTF-8. Teraz chyba większość X-owych terminali obsługuje
UTF-8 (np. GNOME Terminal).

Niestety szerokiego API z ncurses mało kto jeszcze używa (choć od
dawna jest wyspecyfikowane przez X/Open, więc zgaduję, że jakieś inne
implementacje curses niż ncurses na komercyjnych Uniksach to mogły
obsługiwać) i dopiero na początku października zostały w nim
poprawione grube błędy (add_wch ignorowało atrybuty znaku, get_wch źle
przekodowywało znak jeśli kodowanie było inne niż ISO-8859-1 i UTF-8).

Teraz już działa, przynajmniej to, co testowałem (napisałem Tetrisa).
Użycie szerokiego API z libcursesw działa na terminalach
w jednobajtowych kodowaniach i UTF-8. Kodowanie musi być zadeklarowane
z locale, żeby się poprawnie wyświetlało, natomiast samo API pracuje
na wchar_t, które pod Linuxem jest Unikodem (4 bajty na znak).
To jest wygodne zwłaszcza z poziomu języków, które wewnętrznie pracują
na Unikodzie.

Obecny maintainer ncurses, Thomas E. Dickey, szybko odpowiada na mejle
na liście ncurses.

--
__("< Marcin Kowalczyk
\__/ qrc...@knm.org.pl
^^ http://qrnik.knm.org.pl/~qrczak/

Krzysztof Garus

unread,
Nov 8, 2004, 2:13:56 AM11/8/04
to
Świadek Marcin 'Qrczak' Kowalczyk zeznał:

> Krzysztof Garus <baj...@kolos.math.uni.lodz.pl> writes:
>
>> zabieram się do nauki ncurses, bo chcę napisać program z takim
>> interfejsem. Wszystkie stringi w programie mają być kodowane w
>> UTF-8. Czy niemożliwe/trudne/łatwe jest aby użytkownikowi zawsze
>> wyświetlało się to dobrze?

> Jeśli używamy libcursesw, to sensowniej jest używać tylko szerokiego


> API. Jest pewne, że addch/getch nie ma sensu w UTF-8 i że addstr nie
> zadziała w UTF-8 z libcurses. Nie wiem, jak się zachowa addstr w UTF-8
> z libcursesw (i inne operacje na całych napisach), ale zgaduję, że źle.
> Szerokie API to jedyny sposób na pełnoekranowe wyświetlanie się na
> terminalach UTF-8. Teraz chyba większość X-owych terminali obsługuje
> UTF-8 (np. GNOME Terminal).

Dzięki za wyjaśnienia. Tak sie zastanawiam: czy nie prościej byłoby uzywać
"zwykłej" libcurses i iconv'ować z/do UTF-8?

Marcin 'Qrczak' Kowalczyk

unread,
Nov 8, 2004, 2:36:39 AM11/8/04
to
Krzysztof Garus <baj...@kolos.math.uni.lodz.pl> writes:

> Dzięki za wyjaśnienia. Tak sie zastanawiam: czy nie prościej byłoby uzywać
> "zwykłej" libcurses i iconv'ować z/do UTF-8?

To nie będzie działać w trybie UTF-8. libcurses przechowuje tylko
1 bajt na znak, nie będzie poprawnie odświeżać ekranu.

Co prawda lynx tak robił, ale w pokręcony i kruchy sposób. Ustawiał
szerokość ekranu na sztucznie dużo i pilnował, żeby ncurses odświeżał
za każdym razem całe linie (jeśli curses ma odświeżyć kawałek linii
zaczynając od jej połowy, to w złym miejscu umieści kursor).

Krzysztof Garus

unread,
Nov 8, 2004, 3:58:26 AM11/8/04
to
Świadek Marcin 'Qrczak' Kowalczyk zeznał:
> Krzysztof Garus <baj...@kolos.math.uni.lodz.pl> writes:
>
>> Dzięki za wyjaśnienia. Tak sie zastanawiam: czy nie prościej byłoby uzywać
>> "zwykłej" libcurses i iconv'ować z/do UTF-8?
>
> To nie będzie działać w trybie UTF-8. libcurses przechowuje tylko
> 1 bajt na znak, nie będzie poprawnie odświeżać ekranu.
>
> Co prawda lynx tak robił, ale w pokręcony i kruchy sposób. Ustawiał
> szerokość ekranu na sztucznie dużo i pilnował, żeby ncurses odświeżał
> za każdym razem całe linie (jeśli curses ma odświeżyć kawałek linii
> zaczynając od jej połowy, to w złym miejscu umieści kursor).

co innego miałem na myśli: przed użyciem każdej z funkcji skonwertować napis w
utf-8 na lokalny (wskazany w konfiguracji przez użytkownika) i dalej po
staremu. libcurses nie będzie wiedziało o jakichśtam utf-8 wcześniej.

Oczywiście wszystkie znaczki nie będące w docelowym kodowaniu byłyby ucięte.

Marcin 'Qrczak' Kowalczyk

unread,
Nov 8, 2004, 5:46:01 AM11/8/04
to
Krzysztof Garus <baj...@kolos.math.uni.lodz.pl> writes:

> co innego miałem na myśli: przed użyciem każdej z funkcji skonwertować
> napis w utf-8 na lokalny (wskazany w konfiguracji przez użytkownika)
> i dalej po staremu. libcurses nie będzie wiedziało o jakichśtam
> utf-8 wcześniej.

Jeśli lokalnym jest UTF-8, to program nie będzie się poprawnie wyświetlać,
a mógłby.

0 new messages