#include "newt.h"
#include "newt_pr.h"
-#if defined(HAVE_FRIBIDI_FRIBIDI_H) && defined(HAVE_DLFCN_H)
-#include <fribidi/fribidi.h>
-#include <dlfcn.h>
-
-/* No sense in enabling shaping if we don't have BIDI support. */
-typedef struct
-{
- int is_shaped;
- wchar_t isolated;
- wchar_t initial;
- wchar_t medial;
- wchar_t final;
-}
-arabic_char_node;
-
-#define ARABIC_BASE 0x621
-#define ARABIC_END 0x64A
-
-static const arabic_char_node arabic_shaping_table[] = {
-/* 0x621 */ { TRUE , 0xFE80, 0x0000, 0x0000, 0x0000},
-/* 0x622 */ { TRUE , 0xFE81, 0x0000, 0x0000, 0xFE82},
-/* 0x623 */ { TRUE , 0xFE83, 0x0000, 0x0000, 0xFE84},
-/* 0x624 */ { TRUE , 0xFE85, 0x0000, 0x0000, 0xFE86},
-/* 0x625 */ { TRUE , 0xFE87, 0x0000, 0x0000, 0xFE88},
-/* 0x626 */ { TRUE , 0xFE89, 0xFE8B, 0xFE8C, 0xFE8A},
-/* 0x627 */ { TRUE , 0xFE8D, 0x0000, 0x0000, 0xFE8E},
-/* 0x628 */ { TRUE , 0xFE8F, 0xFE91, 0xFE92, 0xFE90},
-/* 0x629 */ { TRUE , 0xFE93, 0x0000, 0x0000, 0xFE94},
-/* 0x62A */ { TRUE , 0xFE95, 0xFE97, 0xFE98, 0xFE96},
-/* 0x62B */ { TRUE , 0xFE99, 0xFE9B, 0xFE9C, 0xFE9A},
-/* 0x62C */ { TRUE , 0xFE9D, 0xFE9F, 0xFEA0, 0xFE9E},
-/* 0x62D */ { TRUE , 0xFEA1, 0xFEA3, 0xFEA4, 0xFEA2},
-/* 0x62E */ { TRUE , 0xFEA5, 0xFEA7, 0xFEA8, 0xFEA6},
-/* 0x62F */ { TRUE , 0xFEA9, 0x0000, 0x0000, 0xFEAA},
-/* 0x630 */ { TRUE , 0xFEAB, 0x0000, 0x0000, 0xFEAC},
-/* 0x631 */ { TRUE , 0xFEAD, 0x0000, 0x0000, 0xFEAE},
-/* 0x632 */ { TRUE , 0xFEAF, 0x0000, 0x0000, 0xFEB0},
-/* 0x633 */ { TRUE , 0xFEB1, 0xFEB3, 0xFEB4, 0xFEB2},
-/* 0x634 */ { TRUE , 0xFEB5, 0xFEB7, 0xFEB8, 0xFEB6},
-/* 0x635 */ { TRUE , 0xFEB9, 0xFEBB, 0xFEBC, 0xFEBA},
-/* 0x636 */ { TRUE , 0xFEBD, 0xFEBF, 0xFEC0, 0xFEBE},
-/* 0x637 */ { TRUE , 0xFEC1, 0xFEC3, 0xFEC4, 0xFEC2},
-/* 0x638 */ { TRUE , 0xFEC5, 0xFEC7, 0xFEC8, 0xFEC6},
-/* 0x639 */ { TRUE , 0xFEC9, 0xFECB, 0xFECC, 0xFECA},
-/* 0x63A */ { TRUE , 0xFECD, 0xFECF, 0xFED0, 0xFECE},
-/* 0x63B */ { FALSE, 0x0000, 0x0000, 0x0000, 0x0000},
-/* 0x63C */ { FALSE, 0x0000, 0x0000, 0x0000, 0x0000},
-/* 0x63D */ { FALSE, 0x0000, 0x0000, 0x0000, 0x0000},
-/* 0x63E */ { FALSE, 0x0000, 0x0000, 0x0000, 0x0000},
-/* 0x63F */ { FALSE, 0x0000, 0x0000, 0x0000, 0x0000},
-/* 0x640 */ { TRUE , 0x0640, 0x0640, 0x0640, 0x0640},
-/* 0x641 */ { TRUE , 0xFED1, 0xFED3, 0xFED4, 0xFED2},
-/* 0x642 */ { TRUE , 0xFED5, 0xFED7, 0xFED8, 0xFED6},
-/* 0x643 */ { TRUE , 0xFED9, 0xFEDB, 0xFEDC, 0xFEDA},
-/* 0x644 */ { TRUE , 0xFEDD, 0xFEDF, 0xFEE0, 0xFEDE},
-/* 0x645 */ { TRUE , 0xFEE1, 0xFEE3, 0xFEE4, 0xFEE2},
-/* 0x646 */ { TRUE , 0xFEE5, 0xFEE7, 0xFEE8, 0xFEE6},
-/* 0x647 */ { TRUE , 0xFEE9, 0xFEEB, 0xFEEC, 0xFEEA},
-/* 0x648 */ { TRUE , 0xFEED, 0x0000, 0x0000, 0xFEEE},
-/* 0x649 */ { TRUE , 0xFEEF, 0x0000, 0x0000, 0xFEF0},
-/* 0x64A */ { TRUE , 0xFEF1, 0xFEF3, 0xFEF4, 0xFEF2}
-};
-
-typedef struct {
- wchar_t c;
- arabic_char_node ar_node;
-}
-extra_char_node;
-
-#define EXTRA_BASE 0x67E
-#define EXTRA_END 0x6CC
-static const extra_char_node extra_shaping_table[] = {
- {0x067E, {TRUE, 0xFB56, 0xFB58, 0xFB59, 0xFB57}},
- {0x0686, {TRUE, 0xFB7A, 0xFB7C, 0xFB7D, 0xFB7B}},
- {0x0698, {TRUE, 0xFB8A, 0x0000, 0x0000, 0xFB8B}},
- {0x06A9, {TRUE, 0xFB8E, 0xFB90, 0xFB91, 0xFB8F}},
- {0x06AF, {TRUE, 0xFB92, 0xFB94, 0xFB95, 0xFB93}},
- {0x06CC, {TRUE, 0xFBFC, 0xFBFE, 0xFBFF, 0xFBFD}},
- {0x0000, {FALSE, 0x0000, 0x0000, 0x0000, 0x0000}},
-};
-
-static const arabic_char_node *get_char_node(wchar_t w)
-{
- if (w >= ARABIC_BASE && w <= ARABIC_END)
- return &arabic_shaping_table[w - ARABIC_BASE];
- else if (w >= EXTRA_BASE && w <= EXTRA_END) {
- const extra_char_node *node = extra_shaping_table;
-
- while (node->c) {
- if (node->c == w)
- return &node->ar_node;
- node++;
- }
- return NULL;
- }
- return NULL;
-}
-
-static int do_shaping(wchar_t *buf, int len) {
- int i,j;
-
- wchar_t *newbuf;
-
- if (len < 1)
- return 0;
-
- newbuf = (wchar_t *)malloc(sizeof(wchar_t)*len);
-
- for (i = 0, j = 0; i < len; i++, j++) {
- int have_previous = FALSE, have_next = FALSE;
- const arabic_char_node *node, *node1;
- int prev, next;
-
- if (buf[i] == L'\0')
- break;
-
- /* If it is non-joiner, ignore it */
- if (buf[i] == 0x200C) {
- j--;
- continue;
- }
-
- newbuf[j] = buf[i];
-
- /* If it's not in our range, skip it. */
- node = get_char_node(buf[i]);
- if (!node)
- {
- continue;
- }
-
- /* The character wasn't included in the unicode shaping table. */
- if (!node->is_shaped)
- {
- continue;
- }
-
- for (prev = i - 1; prev >= 0; prev--)
- if (wcwidth(buf[prev]) || buf[prev] == 0x200C)
- break;
-
- if (prev >= 0 && (node1 = get_char_node(buf[prev]))
- && ( node1->initial || node1->medial))
- {
- have_previous = TRUE;
- }
-
- for (next = i + 1; next < len; next++)
- if (wcwidth(buf[next]) || buf[next] == 0x200C)
- break;
-
- if (next < len && (node1 = get_char_node(buf[next]))
- && (node1->medial || node1->final))
- {
- have_next = TRUE;
- }
-
- /*
- * FIXME: do not make ligature if there are combining
- * characters between two parts.
- */
- if (buf[i] == 0x644 && have_next && next == i + 1)
- {
- switch (buf[next])
- {
- case 0x622:
- newbuf[j] = 0xFEF5 + (have_previous ? 1 : 0);
- i++;
- continue;
- case 0x623:
- newbuf[j] = 0xFEF7 + (have_previous ? 1 : 0);
- i++;
- continue;
- case 0x625:
- newbuf[j] = 0xFEF9 + (have_previous ? 1 : 0);
- i++;
- continue;
- case 0x627:
- newbuf[j] = 0xFEFB + (have_previous ? 1 : 0);
- i++;
- continue;
- default:
- break;
- }
- }
-
- /** Medial **/
- if (have_previous && have_next && node->medial)
- {
- newbuf[j] = node->medial;
- }
-
- /** Final **/
- else if (have_previous && node->final)
- {
- newbuf[j] = node->final;
- }
-
- /** Initial **/
- else if (have_next && node->initial)
- {
- newbuf[j] = node->initial;
- }
-
- /** Isolated **/
- else if (node->isolated)
- {
- newbuf[j] = node->isolated;
- }
- }
- for (i = 0; i < len && i < j; i++) {
- buf[i] = newbuf[i];
- }
- while (i < len) {
- buf[i++] = L'\0';
- }
-
- free(newbuf);
- return 0;
-}
-
-/* Converts bidi wchar text {in} to visual wchar text which is displayable
- * in text mode. Uses {base_dir} as default base direction.
- * Returns malloc'ed converted text or NULL in case of error or if {need_out} is
- * not set. Modifies {base_dir} to reflect actual direction.
- */
-static wchar_t* wchar_to_textmod_visual(wchar_t *in,unsigned int len,FriBidiCharType *base_dir, int need_out)
-{
- FriBidiChar *out = NULL;
- static void *handle = NULL;
-
- fribidi_boolean (*func_ptr) (FriBidiChar *, FriBidiStrIndex,
- FriBidiCharType *, FriBidiChar *,
- FriBidiStrIndex *, FriBidiStrIndex *,
- FriBidiLevel *);
-
- if (!handle)
- handle = dlopen("/usr/lib/libfribidi.so.0", RTLD_LAZY | RTLD_GLOBAL);
- if (!handle)
- handle = dlopen("/lib/libfribidi.so.0", RTLD_LAZY | RTLD_GLOBAL);
- if (!handle)
- return NULL;
-
- func_ptr = dlsym(handle, "fribidi_log2vis");
- if (!func_ptr) {
- dlclose(handle);
- handle = NULL;
- return NULL;
- }
-
- if (need_out) {
- out = (FriBidiChar *)malloc(sizeof(FriBidiChar)*(len+1));
- if(!out)
- {
- dlclose(handle);
- handle = NULL;
- return (wchar_t *) out;
- }
-
- do_shaping(in, len);
- len = wcsnlen(in, len);
- }
- (*func_ptr)(in, len, base_dir, out, NULL, NULL, NULL);
-
- return (wchar_t *) out;
-}
-
-/*
- * Converts text given in {str} from logical order to visual order.
- * Uses {dir} as base direction ('N', 'R', 'L').
- * Returns malloc'ed converted string. Modifies {dir} to reflect actual
- * direction.
- */
-static char *_newt_log2vis(const char *str, char *dir)
-{
- wchar_t *wcs;
- char *rstr = NULL;
- int len = strlen(str);
- int ret;
- FriBidiCharType basedir;
-
- switch (*dir)
- {
- case 'R': basedir = FRIBIDI_TYPE_R;
- break;
- case 'L': basedir = FRIBIDI_TYPE_L;
- break;
- default: basedir = FRIBIDI_TYPE_ON;
- break;
- }
-
- if (len) {
- wchar_t *owcs;
- int newlen;
-
- wcs = malloc(sizeof(*wcs) * (len + 1));
- if (!wcs)
- return NULL;
- ret = mbstowcs(wcs, str, len + 1);
- if (ret < 0) {
- free(wcs);
- return NULL;
- }
- owcs = wchar_to_textmod_visual(wcs, ret, &basedir, 1);
- if (FRIBIDI_DIR_TO_LEVEL(basedir))
- *dir = 'R';
- else
- *dir = 'L';
-
- free(wcs);
- if (!owcs)
- return NULL;
-
- newlen = wcstombs(NULL, owcs, 0);
- if (newlen < 0) {
- free(owcs);
- return NULL;
- }
- rstr = malloc(newlen + 1);
- if (!rstr) {
- free(owcs);
- return NULL;
- }
- ret = wcstombs(rstr, owcs, newlen + 1);
- free(owcs);
- if (ret < 0) {
- free(rstr);
- return NULL;
- }
- }
- return rstr;
-}
-
-/* Returns base direction of text given in {str}.
- */
-char get_text_direction(const char *str)
-{
- int len = strlen(str);
- char dir = 'N';
- wchar_t *wcs;
- int ret;
-
- FriBidiCharType basedir = FRIBIDI_TYPE_ON;
-
- if (len) {
- wcs = malloc(sizeof(*wcs) * (len + 1));
- if (!wcs)
- return dir;
- ret = mbstowcs(wcs, str, len + 1);
- if (ret < 0) {
- free(wcs);
- return dir;
- }
- wchar_to_textmod_visual(wcs, ret, &basedir, 1);
- free(wcs);
- if (FRIBIDI_DIR_TO_LEVEL(basedir))
- dir = 'R';
- else
- dir = 'L';
- }
- return dir;
-}
-
-/* If width of string {str} is less then {width} adds
- * final spaces to make it {width} position wide.
- * Returns malloc'ed padded string or NULL in case of errors
- * or if string does not need padding.
- */
-static char *pad_line(const char *str, int width)
-{
- int len = strlen(str);
- int w = _newt_wstrlen(str, len);
-
- if (w < width) {
- char *newstr = malloc(len + 1 + (width - w));
- if (!newstr)
- return NULL;
- memcpy(newstr, str, len);
- memset(newstr + len, ' ', width - w);
- newstr[len+width-w] = '\0';
- return newstr;
- }
- return NULL;
-}
-
-/*
- * Writes string {str}. Uses {dir} as default direction.
- * Returns direction of the string in {dir}.
- */
-void write_string_int(const char *str, char *dir)
-{
- char dummy;
- char *tmpstr;
-
- if (!dir) {
- dummy = 'N';
- dir = &dummy;
- }
-
- tmpstr = _newt_log2vis(str, dir);
- if (tmpstr)
- str = tmpstr;
- SLsmg_write_string(str);
- if (tmpstr)
- free(tmpstr);
-}
-
-/* Writes at most {n} positions of the string {str}.
- * Adds final (logical) spaces if string width is less than {n}.
- * Uses {dir} as default direction.
- * Returns direction of the string in {dir}
- */
-void write_nstring_int(const char *str, int n, char *dir)
-{
- char dummy;
- char *tmpstr, *tmpstr1;
-
- if (!dir) {
- dummy = 'N';
- dir = &dummy;
- }
-
- tmpstr1 = pad_line(str, n);
- if (tmpstr1)
- str = tmpstr1;
- tmpstr = _newt_log2vis(str, dir);
- if (tmpstr) {
- free(tmpstr1);
- str = tmpstr;
- }
- SLsmg_write_nstring(str, n);
- if (tmpstr)
- free(tmpstr);
- else
- free(tmpstr1);
-}
-#else
-void write_string_int(const char *str, char *dir)
-{
- SLsmg_write_string(str);
-}
-
-void write_nstring_int(const char *str, int w, char *dir)
-{
- SLsmg_write_nstring(str, w);
-}
-
-char get_text_direction(const char *str)
-{
- return 'L';
-}
-#endif
-
struct Window {
int height, width, top, left;
SLsmg_Char_Type * buffer;
SLtt_get_terminfo();
SLtt_get_screen_size();
- // there is no such function in slang?!
- // SLutf8_enable(-1); /* init. utf8 according to locale */
MonoValue = getenv(MonoEnv);
if ( MonoValue == NULL ) {
SLsmg_set_char_set(0);
SLsmg_write_char(' ');
SLsmg_set_color(NEWT_COLORSET_TITLE);
- write_string_int((char *)currentWindow->title, NULL);
+ SLsmg_write_string((char *)currentWindow->title);
SLsmg_set_color(NEWT_COLORSET_BORDER);
SLsmg_write_char(' ');
SLsmg_set_char_set(1);
buf[SLtt_Screen_Cols] = '\0';
}
SLsmg_gotorc(SLtt_Screen_Rows - 1, 0);
- write_string_int(buf, NULL);
+ SLsmg_write_string(buf);
}
void newtPushHelpLine(const char * text) {
}
SLsmg_gotorc(row, col);
- write_string_int((char *)text, NULL);
+ SLsmg_write_string((char *)text);
}
int newtSetFlags(int oldFlags, int newFlags, enum newtFlagsSense sense) {