Пример #1
0
int mb_to_wc(int codepage, int flags, const char *mbstr, int mblen,
	     wchar_t *wcstr, int wclen)
{
    if (codepage == DEFAULT_CODEPAGE) {
	int n = 0;
	mbstate_t state;

	memset(&state, 0, sizeof state);

	while (mblen > 0) {
	    size_t i = mbrtowc(wcstr+n, mbstr, (size_t)mblen, &state);
	    if (i == (size_t)-1 || i == (size_t)-2)
		break;
	    n++;
	    mbstr += i;
	    mblen -= i;
	}

	return n;
    } else if (codepage == CS_NONE) {
	int n = 0;

	while (mblen > 0) {
	    wcstr[n] = 0xD800 | (mbstr[0] & 0xFF);
	    n++;
	    mbstr++;
	    mblen--;
	}

	return n;
    } else
	return charset_to_unicode(&mbstr, &mblen, wcstr, wclen, codepage,
				  NULL, NULL, 0);
}
Пример #2
0
static t_unicode keysym_to_unicode(t_unicode ch)
{
	struct char_set *keyb_charset;
	unsigned char buff[1];
	struct char_set_state keyb_state;

	/* 0xef00 - 0xefff is a pass through range to the current
	 * character set.
	 */
	if ((ch < 0xef00) || (ch > 0xefff))
		return ch;

	keyb_charset = trconfig.keyb_config_charset;
	init_charset_state(&keyb_state, keyb_charset);
	buff[0] = ch & 0xFF;
	charset_to_unicode(&keyb_state, &ch, buff, 1);
	cleanup_charset_state(&keyb_state);
	return ch;
}
Пример #3
0
int strwid(char const *s, int charset)
{
    wchar_t buf[256];
    int wid, len = strlen(s);
    charset_state state = CHARSET_INIT_STATE;

    wid = 0;

    while (len > 0) {
	int ret;

	ret = charset_to_unicode(&s, &len, buf, lenof(buf),
				 charset, &state, NULL, 0);

	if (ret > 0)
	    wid += wcswidth(buf, ret);
    }

    return wid;
}
Пример #4
0
static void init_dos_to_unicode_table(void)
{
  struct char_set_state dos_state;
  unsigned short *dest;
  int i;
  t_unicode symbol;
  int result;

  dest = dos_to_unicode_table;

  for (i = 0; i < 0x100; i++) {
    unsigned char ch = i;
    init_charset_state(&dos_state, trconfig.dos_charset);
    result = charset_to_unicode(&dos_state, &symbol, &ch, 1);
    *dest = symbol;
    if (result != 1)
      *dest = '?';
    cleanup_charset_state(&dos_state);
    dest++;
  }
}
Пример #5
0
BOOL strhasupperDOS(char *s)
{
  struct char_set_state dos_state;

  t_unicode symbol;
  size_t len = strlen(s);
  int result = -1;

  init_charset_state(&dos_state, trconfig.dos_charset);

  while (*s) {
    result = charset_to_unicode(&dos_state, &symbol, (unsigned char *)s, len);
    if (result == -1)
      break;
    if (iswupper(symbol))
      break;
    len -= result;
    s += result;
  }
  cleanup_charset_state(&dos_state);
  return(result != -1 && iswupper(symbol));
}
Пример #6
0
static void init_upperlowerDOS_table(void)
{
  struct char_set_state dos_state;
  t_unicode symbol, symbolc;
  int i, result;

  for (i = 0; i < 128; i++) {
    /* force English ASCII handling for 0 -- 127 to avoid problems
       with the Turkish dotless i */
    upperDOS_table[i] = lowerDOS_table[i] = i;
    if (i >= 'a' && i <= 'z')
      upperDOS_table[i] = i - ('a' - 'A');
    else if (i >= 'A' && i <= 'Z')
      lowerDOS_table[i] = i + ('a' - 'A');
  }
  for (i = 128; i < 256; i++) {
    upperDOS_table[i] = lowerDOS_table[i] = i;
    init_charset_state(&dos_state, trconfig.dos_charset);
    result = charset_to_unicode(&dos_state, &symbol, &upperDOS_table[i], 1);
    cleanup_charset_state(&dos_state);
    if (result == 1) {
      symbolc = towupper(symbol);
      init_charset_state(&dos_state, trconfig.dos_charset);
      result = unicode_to_charset(&dos_state, symbolc, &upperDOS_table[i], 1);
      cleanup_charset_state(&dos_state);
      if (result != 1)
	upperDOS_table[i] = i;
      symbolc = towlower(symbol);
      init_charset_state(&dos_state, trconfig.dos_charset);
      result = unicode_to_charset(&dos_state, symbolc, &lowerDOS_table[i], 1);
      cleanup_charset_state(&dos_state);
      if (result != 1)
	lowerDOS_table[i] = i;
    }
  }
}
Пример #7
0
/* This function is borrowed from Wine (LGPL'ed)
   http://source.winehq.org/source/dlls/x11drv/keyboard.c
   with adjustments to match dosemu

   The idea is, if $_layout="auto", to match each keyboard map with
   the X keymap and choose the one that matches best.

   It is used when we can access display, not just for xdosemu,
   but also in xterms. Remote users using terminals will have
   to specify $_layout explicitly though.

   The console map is just another map in this scheme that may
   or may not be the best one.
*/
int X11_DetectLayout (void)
{
  Display *display;
  unsigned match, mismatch, seq, i, alternate;
  int score, keyc, key, pkey, ok = 0;
  KeySym keysym;
  unsigned max_seq[3] = {0, 0};
  int max_score[3] = {INT_MIN, INT_MIN};
  int ismatch = 0;
  int min_keycode, max_keycode;
  t_unicode ckey[2] = {0, 0};
  t_keysym lkey[2] = {0, 0};
  struct keytable_entry *kt;
  struct char_set_state X_charset;

  char *display_name = config.X_display ? config.X_display : getenv("DISPLAY");
  display = XOpenDisplay(display_name);
  if (display == NULL) return 1;

  XDisplayKeycodes(display, &min_keycode, &max_keycode);

#ifndef HAVE_XKB
  int keysyms_per_keycode;
  KeySym *key_mapping;

  /* get data for keycode from X server */
  key_mapping = XGetKeyboardMapping(display, min_keycode,
			    max_keycode + 1 - min_keycode,
			    &keysyms_per_keycode);
#endif

  init_charset_state(&X_charset, lookup_charset("X_keysym"));
  for (kt = keytable_list, alternate = 0; kt->name; ) {
    k_printf("Attempting to match against \"%s\"\n", kt->name);
    match = 0;
    mismatch = 0;
    score = 0;
    seq = 0;
    pkey = -1;
    for (keyc = min_keycode; keyc <= max_keycode; keyc++) {

      for (i = 0; i < 2; i++) {
#ifdef HAVE_XKB
	keysym = XkbKeycodeToKeysym(display, keyc, alternate, i);
#else
	keysym = X11_KeycodeToKeysym(key_mapping, keysyms_per_keycode,
			min_keycode, keyc, alternate, i);
#endif
	charset_to_unicode(&X_charset, &ckey[i],
                (const unsigned char *)&keysym, sizeof(keysym));
      }

      if (ckey[0] != U_VOID && (ckey[0] & 0xf000) != 0xe000) {
        /* search for a match in layout table */
        /* right now, we just find an absolute match for defined positions */
        /* (undefined positions are ignored, so if it's defined as "3#" in */
        /* the table, it's okay that the X server has "3#£", for example) */
        /* however, the score will be higher for longer matches */
        for (key = 0; key < kt->sizemap; key++) {
	  lkey[0] = keysym_to_unicode(kt->key_map[key]);
	  lkey[1] = keysym_to_unicode(kt->shift_map[key]);
          for (ok = 0, i = 0; (ok >= 0) && (i < 2); i++) {
            if (lkey[i] != U_VOID) {
	      if (lkey[i] == ckey[i])
		ok++;
	      else if (ckey[i] != U_VOID)
		ok = -1;
	    }
          }
	  if (debug_level('k') > 5)
	    k_printf("key: % 3d score % 2d for keycode % 3d, %04x %04x, "
		     "got %04x %04x\n",
		     key, ok, keyc, lkey[0], lkey[1], ckey[0], ckey[1]);
          if (ok > 0) {
            score += ok;
            break;
          }
        }
        /* count the matches and mismatches */
        if (ok > 0) {
          match++;
          /* and how much the keycode order matches */
          if (key > pkey) seq++;
          pkey = key;
        } else {
          /* print spaces instead of \0's */
          for (i = 0; i < ARRAY_SIZE(ckey); i++) if (!ckey[i]) ckey[i] = ' ';
          mismatch++;
          score -= 2;
        }
      }
    }
    k_printf("matches=%d, mismatches=%d, seq=%d, score=%d\n",
           match, mismatch, seq, score);
    if (score > max_score[alternate] ||
       (score == max_score[alternate] &&
	((seq > max_seq[alternate]) ||
	 (seq == max_seq[alternate] && kt->keyboard == KEYB_AUTO)))) {
      /* best match so far */
      if (alternate) {
	/* alternate keyboards are optional so a threshold is used */
	if (score > 20) config.altkeytable = kt;
      }
      else
	config.keytable = kt;
      max_score[alternate] = score;
      max_seq[alternate] = seq;
      ismatch = !mismatch;
    }
    alternate = !alternate;
    if (!alternate)
      kt++;
  }
  cleanup_charset_state(&X_charset);

#ifndef HAVE_XKB
  XFree(key_mapping);
#endif

  /* we're done, report results if necessary */
  if (!ismatch)
    k_printf("Using closest match (%s) for scan/virtual codes mapping.\n",
	   config.keytable->name);

  c_printf("CONF: detected layout is \"%s\"\n", config.keytable->name);
  if (config.altkeytable)
    c_printf("CONF: detected alternate layout: %s\n", config.altkeytable->name);
  XCloseDisplay(display);
  return 0;
}
Пример #8
0
/*
 * Return value is true if pterm is to run in direct-to-font mode.
 */
bool init_ucs(struct unicode_data *ucsdata, char *linecharset,
              bool utf8_override, int font_charset, int vtmode)
{
    int i;
    bool ret = false;

    /*
     * In the platform-independent parts of the code, font_codepage
     * is used only for system DBCS support - which we don't
     * support at all. So we set this to something which will never
     * be used.
     */
    ucsdata->font_codepage = -1;

    /*
     * If utf8_override is set and the POSIX locale settings
     * dictate a UTF-8 character set, then just go straight for
     * UTF-8.
     */
    ucsdata->line_codepage = CS_NONE;
    if (utf8_override) {
	const char *s;
	if (((s = getenv("LC_ALL"))   && *s) ||
	    ((s = getenv("LC_CTYPE")) && *s) ||
	    ((s = getenv("LANG"))     && *s)) {
	    if (strstr(s, "UTF-8"))
		ucsdata->line_codepage = CS_UTF8;
	}
    }

    /*
     * Failing that, line_codepage should be decoded from the
     * specification in conf.
     */
    if (ucsdata->line_codepage == CS_NONE)
	ucsdata->line_codepage = decode_codepage(linecharset);

    /*
     * If line_codepage is _still_ CS_NONE, we assume we're using
     * the font's own encoding. This has been passed in to us, so
     * we use that. If it's still CS_NONE after _that_ - i.e. the
     * font we were given had an incomprehensible charset - then we
     * fall back to using the D800 page.
     */
    if (ucsdata->line_codepage == CS_NONE)
	ucsdata->line_codepage = font_charset;

    if (ucsdata->line_codepage == CS_NONE)
	ret = true;

    /*
     * Set up unitab_line, by translating each individual character
     * in the line codepage into Unicode.
     */
    for (i = 0; i < 256; i++) {
	char c[1];
        const char *p;
	wchar_t wc[1];
	int len;
	c[0] = i;
	p = c;
	len = 1;
	if (ucsdata->line_codepage == CS_NONE)
	    ucsdata->unitab_line[i] = 0xD800 | i;
	else if (1 == charset_to_unicode(&p, &len, wc, 1,
					 ucsdata->line_codepage,
					 NULL, L"", 0))
	    ucsdata->unitab_line[i] = wc[0];
	else
	    ucsdata->unitab_line[i] = 0xFFFD;
    }

    /*
     * Set up unitab_xterm. This is the same as unitab_line except
     * in the line-drawing regions, where it follows the Unicode
     * encoding.
     * 
     * (Note that the strange X encoding of line-drawing characters
     * in the bottom 32 glyphs of ISO8859-1 fonts is taken care of
     * by the font encoding, which will spot such a font and act as
     * if it were in a variant encoding of ISO8859-1.)
     */
    for (i = 0; i < 256; i++) {
	static const wchar_t unitab_xterm_std[32] = {
	    0x2666, 0x2592, 0x2409, 0x240c, 0x240d, 0x240a, 0x00b0, 0x00b1,
	    0x2424, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c, 0x23ba,
	    0x23bb, 0x2500, 0x23bc, 0x23bd, 0x251c, 0x2524, 0x2534, 0x252c,
	    0x2502, 0x2264, 0x2265, 0x03c0, 0x2260, 0x00a3, 0x00b7, 0x0020
	};
	static const wchar_t unitab_xterm_poorman[32] =
	    L"*#****o~**+++++-----++++|****L. ";

	const wchar_t *ptr;

	if (vtmode == VT_POORMAN)
	    ptr = unitab_xterm_poorman;
	else
	    ptr = unitab_xterm_std;

	if (i >= 0x5F && i < 0x7F)
	    ucsdata->unitab_xterm[i] = ptr[i & 0x1F];
	else
	    ucsdata->unitab_xterm[i] = ucsdata->unitab_line[i];
    }

    /*
     * Set up unitab_scoacs. The SCO Alternate Character Set is
     * simply CP437.
     */
    for (i = 0; i < 256; i++) {
	char c[1];
        const char *p;
	wchar_t wc[1];
	int len;
	c[0] = i;
	p = c;
	len = 1;
	if (1 == charset_to_unicode(&p, &len, wc, 1, CS_CP437, NULL, L"", 0))
	    ucsdata->unitab_scoacs[i] = wc[0];
	else
	    ucsdata->unitab_scoacs[i] = 0xFFFD;
    }

    /*
     * Find the control characters in the line codepage. For
     * direct-to-font mode using the D800 hack, we assume 00-1F and
     * 7F are controls, but allow 80-9F through. (It's as good a
     * guess as anything; and my bet is that half the weird fonts
     * used in this way will be IBM or MS code pages anyway.)
     */
    for (i = 0; i < 256; i++) {
	int lineval = ucsdata->unitab_line[i];
	if (lineval < ' ' || (lineval >= 0x7F && lineval < 0xA0) ||
	    (lineval >= 0xD800 && lineval < 0xD820) || (lineval == 0xD87F))
	    ucsdata->unitab_ctrl[i] = i;
	else
	    ucsdata->unitab_ctrl[i] = 0xFF;
    }

    return ret;
}