diff options
author | Adam Borowski <kilobyte@angband.pl> | 2011-04-01 01:00:14 +0200 |
---|---|---|
committer | Adam Borowski <kilobyte@angband.pl> | 2011-04-01 01:00:14 +0200 |
commit | 452ff385766f7f82e4ff92f319dd3a284795fd2e (patch) | |
tree | 35f3bfd02c4d16d05cda2126aaf82dd945690686 /crawl-ref/source/libunix.cc | |
parent | 778a975c1cf474d6c585d2177956daff30cffc24 (diff) | |
parent | 5485922b1f7b6c4e369d0b885ccfbff0e6e0d850 (diff) | |
download | crawl-ref-452ff385766f7f82e4ff92f319dd3a284795fd2e.tar.gz crawl-ref-452ff385766f7f82e4ff92f319dd3a284795fd2e.zip |
Merge branch 'unicode'.
There are some issues left, like incorrect wrapping in some cases, but
we can fix them later.
Diffstat (limited to 'crawl-ref/source/libunix.cc')
-rw-r--r-- | crawl-ref/source/libunix.cc | 266 |
1 files changed, 66 insertions, 200 deletions
diff --git a/crawl-ref/source/libunix.cc b/crawl-ref/source/libunix.cc index 68268e56f0..ca77dfc4ff 100644 --- a/crawl-ref/source/libunix.cc +++ b/crawl-ref/source/libunix.cc @@ -35,6 +35,7 @@ #include "files.h" #include "state.h" #include "stuff.h" +#include "unicode.h" #include "view.h" #include "viewgeom.h" @@ -43,12 +44,9 @@ #include <sys/resource.h> #endif -#ifdef UNICODE_GLYPHS #include <wchar.h> #include <locale.h> #include <langinfo.h> -#endif - #include <termios.h> static struct termios def_term; @@ -84,7 +82,6 @@ static int Current_Colour = COLOR_PAIR(BG_COL * 8 + FG_COL); static int curs_fg_attr(int col); static int curs_bg_attr(int col); -static int waddstr_with_altcharset(WINDOW* w, const char* s); static bool cursor_is_enabled = true; @@ -163,27 +160,6 @@ static void setup_colour_pairs(void) init_pair(63, COLOR_BLACK, Options.background_colour); } -#ifdef UNICODE_GLYPHS -static std::string unix_glyph2string(unsigned gly) -{ - char buf[50]; // Overkill, I know. - wchar_t wcbuf[2]; - wcbuf[0] = gly; - wcbuf[1] = 0; - if (wcstombs(buf, wcbuf, sizeof buf) != (size_t) -1) - return (buf); - - return std::string(1, gly); -} - -static int unix_multibyte_strlen(const std::string &s) -{ - const char *cs = s.c_str(); - size_t len = mbsrtowcs(NULL, &cs, 0, NULL); - return (len == (size_t) -1? s.length() : len); -} -#endif - static void unix_handle_terminal_resize(); static void termio_init() @@ -204,19 +180,6 @@ static void termio_init() tcsetattr(0, TCSAFLUSH, &game_term); - crawl_state.unicode_ok = false; -#ifdef UNICODE_GLYPHS - if (setlocale(LC_ALL, "") - && !strcmp(nl_langinfo(CODESET), "UTF-8")) - { - crawl_state.unicode_ok = true; - crawl_state.glyph2strfn = unix_glyph2string; - crawl_state.multibyte_strlen = unix_multibyte_strlen; - } - else - setlocale(LC_ALL, "C"); -#endif - crawl_state.terminal_resize_handler = unix_handle_terminal_resize; } @@ -266,34 +229,41 @@ static int proc_mouse_event(int c, const MEVENT *me) } #endif -static int raw_m_getch() +int getchk() { - const int c = getch(); - switch (c) - { -#ifdef NCURSES_MOUSE_VERSION - case KEY_MOUSE: + wint_t c; + switch (get_wch(&c)) { - MEVENT me; - getmouse(&me); - return (proc_mouse_event(c, &me)); - } -#endif - default: + case ERR: // getch() returns -1 on EOF, convert that into an Escape. Evil hack, // but the alternative is to explicitly check for -1 everywhere where // we might otherwise spin in a tight keyboard input loop. - return (c == -1? ESCAPE : c); + return ESCAPE; + case OK: + // a normal (printable) key + return c; } + + return -c; } int m_getch() { int c; do - c = raw_m_getch(); - while ((c == CK_MOUSE_MOVE || c == CK_MOUSE_CLICK) - && !crawl_state.mouse_enabled); + { + c = getchk(); + +#ifdef NCURSES_MOUSE_VERSION + if (c == -KEY_MOUSE) + { + MEVENT me; + getmouse(&me); + c = proc_mouse_event(c, &me); + } +#endif + } while ((c == CK_MOUSE_MOVE || c == CK_MOUSE_CLICK) + && !crawl_state.mouse_enabled); return (c); } @@ -305,17 +275,17 @@ int getch_ck() { // [dshaligram] MacOS ncurses returns 127 for backspace. case 127: - case KEY_BACKSPACE: return CK_BKSP; - case KEY_DC: return CK_DELETE; - case KEY_HOME: return CK_HOME; - case KEY_PPAGE: return CK_PGUP; - case KEY_END: return CK_END; - case KEY_NPAGE: return CK_PGDN; - case KEY_UP: return CK_UP; - case KEY_DOWN: return CK_DOWN; - case KEY_LEFT: return CK_LEFT; - case KEY_RIGHT: return CK_RIGHT; - default: return c; + case -KEY_BACKSPACE: return CK_BKSP; + case -KEY_DC: return CK_DELETE; + case -KEY_HOME: return CK_HOME; + case -KEY_PPAGE: return CK_PGUP; + case -KEY_END: return CK_END; + case -KEY_NPAGE: return CK_PGDN; + case -KEY_UP: return CK_UP; + case -KEY_DOWN: return CK_DOWN; + case -KEY_LEFT: return CK_LEFT; + case -KEY_RIGHT: return CK_RIGHT; + default: return c; } } @@ -442,26 +412,26 @@ static void unixcurses_defkeys(void) int unixcurses_get_vi_key(int keyin) { - switch (keyin) + switch (-keyin) { - // 1001..1009: passed without change - case 1031: return 1007; - case 1034: return 1001; - case 1040: return 1005; - - case KEY_HOME: return 1007; - case KEY_END: return 1001; - case KEY_DOWN: return 1002; - case KEY_UP: return 1008; - case KEY_LEFT: return 1004; - case KEY_RIGHT: return 1006; - case KEY_NPAGE: return 1003; - case KEY_PPAGE: return 1009; - case KEY_A1: return 1007; - case KEY_A3: return 1009; - case KEY_B2: return 1005; - case KEY_C1: return 1001; - case KEY_C3: return 1003; + // -1001..-1009: passed without change + case 1031: return -1007; + case 1034: return -1001; + case 1040: return -1005; + + case KEY_HOME: return -1007; + case KEY_END: return -1001; + case KEY_DOWN: return -1002; + case KEY_UP: return -1008; + case KEY_LEFT: return -1004; + case KEY_RIGHT: return -1006; + case KEY_NPAGE: return -1003; + case KEY_PPAGE: return -1009; + case KEY_A1: return -1007; + case KEY_A3: return -1009; + case KEY_B2: return -1005; + case KEY_C1: return -1001; + case KEY_C3: return -1003; case KEY_SHOME: return 'Y'; case KEY_SEND: return 'B'; case KEY_SLEFT: return 'H'; @@ -613,9 +583,8 @@ extern "C" char *itoa(int value, char *strptr, int radix) return strptr; } -int cprintf(const char *format,...) +void cprintf(const char *format, ...) { - int i; char buffer[2048]; // One full screen if no control seq... va_list argp; @@ -623,100 +592,27 @@ int cprintf(const char *format,...) va_start(argp, format); vsnprintf(buffer, sizeof(buffer), format, argp); va_end(argp); - i = waddstr_with_altcharset(stdscr, buffer); - return (i); -} -// Wrapper around curses waddstr(); handles switching to the alt charset -// when necessary, and performing the funny DEC translation. -// Returns a curses success value. -static int waddstr_with_altcharset(WINDOW* w, const char* str) -{ - int ret = OK; - if (Options.char_set == CSET_ASCII || Options.char_set == CSET_UNICODE) + ucs_t c; + char *bp = buffer; + while(int s = utf8towc(&c, bp)) { - // In ascii, we don't expect any high-bit chars. - // In Unicode, str is UTF-8 and we shouldn't touch anything. - ret = waddstr(w, str); + bp += s; + putwch(c); } - else - { - // Otherwise, high bit indicates alternate charset. - // DEC line-drawing chars don't have the high bit, so - // we map them into 0xE0 and above. - const bool bDEC = (Options.char_set == CSET_DEC); - const char* begin = str; - - while (true) - { - const char* end = begin; - // Output a range of normal characters (the common case) - while (*end && (unsigned char)*end <= 127) ++end; - if (end-begin) ret = waddnstr(w, begin, end-begin); - - // Then a single high-bit character - chtype c = (unsigned char)*end; - if (c == 0) - break; - else if (bDEC && c >= 0xE0) - ret = waddch(w, (c & 0x7F) | A_ALTCHARSET); - else // if (*end > 127) - ret = waddch(w, c | A_ALTCHARSET); - begin = end+1; - } - } - return ret; } -int putch(unsigned char chr) +int putwch(ucs_t chr) { - if (chr == 0) - chr = ' '; - - return (addch(chr)); -} - -int putwch(unsigned chr) -{ -#ifdef UNICODE_GLYPHS - if (chr <= 127 || Options.char_set != CSET_UNICODE) - return (putch(chr)); - wchar_t c = chr; + // TODO: recognize unsupported characters and try to transliterate return (addnwstr(&c, 1)); -#else - return (putch(static_cast<unsigned char>(chr))); -#endif } -int window(int x1, int y1, int x2, int y2) +void put_colour_ch(int colour, ucs_t ch) { - x1 = y1 = x2 = y2 = 0; /* Do something to them.. makes gcc happy :) */ - return OK; -} - -void put_colour_ch(int colour, unsigned ch) -{ - if (Options.char_set == CSET_ASCII || Options.char_set == CSET_UNICODE) - { - // Unicode can't or-in curses attributes; but it also doesn't have - // to fool around with altcharset - textattr(colour); - putwch(ch); - } - else - { - const unsigned oldch = ch; - if (oldch & 0x80) ch |= A_ALTCHARSET; - // Shift the DEC line drawing set - if (oldch >= 0xE0 && Options.char_set == CSET_DEC) - ch ^= 0x80; - textattr(colour); - - // putch truncates ch to a byte, so don't use it. - if ((ch & 0x7f) == 0) ch |= ' '; - addch(ch); - } + textattr(colour); + putwch(ch); } void puttext(int x1, int y1, const crawl_view_buffer &vbuf) @@ -937,7 +833,6 @@ int gotoxy_sys(int x, int y) return (move(y - 1, x - 1)); } -#ifdef UNICODE_GLYPHS typedef cchar_t char_info; inline bool operator == (const cchar_t &a, const cchar_t &b) { @@ -974,37 +869,8 @@ static void flip_colour(cchar_t &ch) } const int newpair = (fg * 8 + bg); - ch.attr = COLOR_PAIR(newpair) | (ch.attr & A_ALTCHARSET); + ch.attr = COLOR_PAIR(newpair); } -#else // ! UNICODE_GLYPHS -typedef unsigned long char_info; -#define character_at(y,x) mvinch(y,x) -#define valid_char(x) (x) -#define write_char_at(y,x,c) mvaddch(y, x, c) - -#define char_info_character(c) ((c) & A_CHARTEXT) -#define char_info_colour(c) ((c) & A_COLOR) -#define char_info_attributes(c) ((c) & A_ATTRIBUTES) - -static void flip_colour(char_info &ch) -{ - const unsigned colour = char_info_colour(ch); - const int pair = PAIR_NUMBER(colour); - - int fg = pair & 7; - int bg = (pair >> 3) & 7; - - if (pair == 63) - { - fg = COLOR_WHITE; - bg = COLOR_BLACK; - } - - const int newpair = (fg * 8 + bg); - ch = (char_info_character(ch) | COLOR_PAIR(newpair) | - (char_info_attributes(ch) & A_ALTCHARSET)); -} -#endif static char_info oldch, oldmangledch; static int faked_x = -1, faked_y; |