Logo Search packages:      
Sourcecode: yudit version File versions

bool SXInputMethod::createIC ( const SString str,
const SProperties props 
) [private]

Creare an IC. If IC is ascii of none, it will work by all means. If it fails it will fall back to ascii and set name and isAscii. member variables in the class accordingly.

Parameters:
st is the name if ic in the form of x-kinput-ja_JP.eucJP
props is the input mehtod properties.
Returns:
true if we could make it work.

Definition at line 761 of file SXInputMethod.cpp.

References SString::append(), SBinVector< Type >::array(), SX11Impl::display, SHashtable< BType >::get(), SX11Color::getPixelValue(), SString::lower(), SHashtable< BType >::put(), SBinVector< Type >::remove(), SVector< BType >::size(), and SBinVector< Type >::size().

Referenced by start(), and stop().

{
  if (xic!=0 && xim!=0) XDestroyIC (xic);
  if (xim!=0 && xic!=0) XCloseIM (xim);

  inputStyle = "preedit-over-status-over";
  icEncoding = "";
  xic = 0; xim = 0;
   
  SStringVector nv(str, ":");
  SString sname = nv[0];
  name = sname;
  if (sname.size() > 2 && sname[1] == '-') 
  {
    /* 'x-' */
    sname.remove (0);
    sname.remove (0);
  }
  isAscii = (sname == "ascii");
  SProperties ps = props;
  if (sname == "ascii" ||  sname == "none" || sname == "utf-8")
  {
    ps.put ("InputStyle", "none");
    sname = "none";
  }

  SString zname("@im=");
  zname.append (sname);
  zname.append ((char)0);

  SString slocale = SString ((nv.size() > 1) ? SString(nv[1]) : SString(""));
  bool localeOK = false;

#ifdef HAVE_LOCALE
  SString zlocale = slocale;
  zlocale.append ((char)0);
  if (!setlocale (LC_ALL, zlocale.array()))
  {
    setlocale (LC_ALL, "C");
    fprintf (stderr, "Locale %s is not supported by C library.\n", 
        zlocale.array());
  }
  else if (!XSupportsLocale()) 
  {
    fprintf (stderr, "Locale %s is not supported by X.\n", 
         zlocale.array());
  }
  else
  {
    localeOK = true;
    //fprintf (stderr, "set locale %s.\n", zlocale.array());
  }
#else
  fprintf (stderr, "No locale support on this machine.\n");
  isAscii = true;
  name = "x-ascii";
  return false;
#endif
  icEncoding = "";
  SStringVector vl(slocale, ".", true);
  if (vl.size() == 2)
  {
    icEncoding = vl[1];
    icEncoding.lower();
    if (icEncoding == "eucjp")
    {
       icEncoding = "euc-jp";
    }
    else if (icEncoding == "euckr")
    {
       icEncoding = "euc-kr";
    }
    else if (icEncoding == "gb2312")
    {
       icEncoding = "gb-18030";
    }
    else if (icEncoding == "gb18030")
    {
       icEncoding = "gb-18030";
    }
    else if (icEncoding == "gb-2312")
    {
       icEncoding = "gb-18030";
    }
    else if (icEncoding == "big5")
    {
       icEncoding = "big-5";
    }
    else if (icEncoding == "utf8")
    {
       icEncoding = "";
    }
    else if (icEncoding == "iso8859-1")
    {
       icEncoding = "iso-8859-1";
    }
    else if (icEncoding == "iso8859-2")
    {
       icEncoding = "iso-8859-2";
    }
    else if (icEncoding == "iso8859-3")
    {
       icEncoding = "iso-8859-3";
    }
    else if (icEncoding == "iso8859-4")
    {
       icEncoding = "iso-8859-4";
    }
    else if (icEncoding == "iso8859-5")
    {
       icEncoding = "iso-8859-5";
    }
    else if (icEncoding == "iso8859-6")
    {
       icEncoding = "iso-8859-6";
    }
    else if (icEncoding == "iso8859-7")
    {
       icEncoding = "iso-8859-7";
    }
    else if (icEncoding == "iso8859-8")
    {
       icEncoding = "iso-8859-8";
    }
    else if (icEncoding == "iso8859-9")
    {
       icEncoding = "iso-8859-9";
    }
    else if (icEncoding == "iso8859e")
    {
       icEncoding = "iso-8859e";
    }
    else if (icEncoding == "iso8859-15")
    {
       icEncoding = "iso-8859-15";
    }
    else if (icEncoding == "iso8859-16")
    {
       icEncoding = "iso-8859-16";
    }
    else if (icEncoding == "utf-8")
    {
       icEncoding = "";
    }
  }
  
  char * p = localeOK?XSetLocaleModifiers(zname.array()):0;
  if (localeOK && (p==0 || *p == 0))
  {
    fprintf (stderr, "setting modifiers '%s' failed.\n", zname.array());
  }
  xim = (p!=0 && *p) ? XOpenIM(impl->display, 0, 0, 0) : 0;
  bool status = (xim!=0);
  /* hmm. */
  if (!status)
  {
    fprintf (stderr, "openim '%s' failed.\n", zname.array());
    icEncoding = "";
    localeOK = false;
#ifdef HAVE_LOCALE
    setlocale (LC_ALL, "C");
    if (!setlocale (LC_ALL, "C"))
    {
      setlocale (LC_ALL, "C");
      fprintf (stderr, "Locale C is not supported by C library.\n"); 
    }
    else if (!XSupportsLocale()) 
    {
      fprintf (stderr, "Locale C is not supported by X.\n"); 
    }
    else
    {
      localeOK = true;
      //fprintf (stderr, "set locale %s.\n", zlocale.array());
    }
#endif
    isAscii = true;
    name = "x-ascii";
    zname = "@im=none";
    zname.append ((char)0);
    p = localeOK?XSetLocaleModifiers(zname.array()):0;
    xim = (p && *p)?XOpenIM (impl->display, 0, 0, 0):0;
    if (xim == 0)
    {
      fprintf (stderr, "Can not open any xim.\n");
      return false;
    }
    ps.put ("InputStyle", "none");
  }
#ifdef HAVE_SET_IM_VALUES
  //fprintf (stderr, "Setting CB.\n");
  XIMCallback  imCallback;
  imCallback.client_data = (char*)&xim;
  imCallback.callback = (XIMProc) destroyIMCB;
  XSetIMValues (xim, XNDestroyCallback , &imCallback , 0);
#endif
  if (ps.get ("InputStyle") == 0) ps.put ("InputStyle", "none");
  SString s = ps["InputStyle"];

  unsigned long code = XIMPreeditNone | XIMStatusNone;
  if (s=="preedit-root-status-root")
  {
    code = XIMPreeditNothing  | XIMStatusNothing;
  }
  else if (s =="preedit-under-status-under")
  {
    code = XIMPreeditArea  | XIMStatusArea;
  }
  else if (s =="preedit-over-status-under")
  {
    code = XIMPreeditPosition | XIMStatusArea;
  }
  else if (s == "preedit-over-status-over")
  {
    code = XIMPreeditPosition | XIMStatusNothing;
  }
  else if (s == "none")
  {
    //code = XIMPreeditNone | XIMStatusNone;
    /* This one will accept compositions */
    code = XIMPreeditNothing | XIMStatusNothing;
  }
  else
  {
    fprintf (stderr, "InputStyle is bad - %*.*s.\n", SSARGS(s));
    XCloseIM(xim);
    xim = 0;
    return false;
  }
  inputStyle = s;

  XIMStyles* xim_styles;
  if (XGetIMValues(xim, XNQueryInputStyle, &xim_styles, 0)
      || xim_styles==0 || xim_styles->count_styles==0)
  {
      fprintf (stderr, "input method doesn't support any style\n");
      XCloseIM(xim);
      xim = 0;
      return false;
  }
  int i;
  bool hasrootstyle = false;
  bool hasoverthespot = false;
  for (i=0; i<xim_styles->count_styles; i++)
  {
    if (xim_styles->supported_styles[i] == code) break;
    if (xim_styles->supported_styles[i] == 
     (XIMPreeditNothing  | XIMStatusNothing))
    {
       hasrootstyle = true;
    }
    else if (xim_styles->supported_styles[i] == 
     (XIMPreeditPosition  | XIMStatusNothing))
    {
       hasoverthespot = true;
    }
  }
  bool nostyle =  (i == xim_styles->count_styles);
  if (nostyle && hasoverthespot && inputStyle != "None" & inputStyle != "none")
  {
    //fprintf (stderr, "Reverting to preedit-over-status-over.\n");
    inputStyle = "preedit-over-status-over";
    code = XIMPreeditPosition  | XIMStatusNothing;
    nostyle = false;
  }
  if (hasrootstyle && nostyle && inputStyle != "None" && inputStyle != "none")
  {
    //fprintf (stderr, "Reverting to preedit-root-status-root.\n");
    inputStyle = "preedit-root-status-root";
    code = XIMPreeditNothing  | XIMStatusNothing;
    nostyle = false;
  }
  /* Try no precomposition style */
  if (nostyle && inputStyle == "none")
  {
    for (i=0; i<xim_styles->count_styles; i++)
    {
       if (xim_styles->supported_styles[i] 
          == XIMPreeditNone|XIMStatusNone)
       {
          code = XIMPreeditNone|XIMStatusNone;
          inputStyle = "preedit-root-status-root";
          nostyle = false;
          break;
       }
    }
  }
  XFree(xim_styles);
  if (nostyle)
  {
    fprintf (stderr, 
        "Style=%*.*s in %*.*s not found. Style negotiation failed.\n",  
        SSARGS(inputStyle), SSARGS(name));
    XCloseIM(xim);
    xim = 0;
    return false;
  }

  char **missing_charset_list;
  int missing_charset_count;
  char *def_string;

  /* Why? */
  if (fontSet == 0)
  {
    fontSet = XCreateFontSet(impl->display, "*",
              &missing_charset_list,
              &missing_charset_count,
              &def_string);
  }
  /* over the spot */
  if (inputStyle == "preedit-over-status-over")
  {
    XPoint spot = {1, 1};
    /* Why the heck do we need fontset? */
    int screen = DefaultScreen (impl->display);

    XVaNestedList attributes = XVaCreateNestedList (0, 
      XNForeground , BlackPixel (impl->display, screen),
      XNBackground , WhitePixel (impl->display, screen),
      XNSpotLocation, &spot,
      XNFontSet, fontSet,
      0);
    if (attributes==0)
    {
      XCloseIM(xim);
      xim = 0;
      fprintf (stderr, "Can not create XVaNestedList.\n");
      return false;
    }
    xic = XCreateIC(xim, 
       XNInputStyle, code,
       XNClientWindow, (Window) id,
       XNPreeditAttributes, attributes,
       0);
    XFree (attributes);
    //Bool preedit_state = 1;
    //if (xic) XSetICValues (xic, XNPreeditState, preedit_state, 0);
    if (props.get ("InputClientColor"))
    {
      SString col = props["InputClientColor"];
      col.append ((char)0);
      unsigned long bg, fg;
      sscanf (col.array(), "%lu,%lu", &bg, &fg);
      SX11Color xbg = SX11Color(impl, (SS_WORD32)bg);
      SX11Color xfg = SX11Color(impl, (SS_WORD32)fg);
      XVaNestedList atts = XVaCreateNestedList (0, 
       XNForeground, xfg.getPixelValue(),
       XNBackground, xbg.getPixelValue(),
       0);
      if (atts) 
      {
        XSetICValues(xic, XNPreeditAttributes, atts, 0);
        XFree (atts);
      }
    }
  }
  else if (inputStyle == "preedit-under-status-under")
  {
    SString sl = props["InputStatusLocation"];
    sl.append((char)0);
    int statusX, statusY;
    sscanf(sl.array(), "%d,%d", &statusX, &statusY);

    SString ss = props["InputStatusSize"];
    ss.append((char)0);
    int statusWidth, statusHeight;
    sscanf(ss.array(), "%d,%d", &statusWidth, &statusHeight);
    XRectangle statusArea;
    statusArea.width  = statusWidth;
    statusArea.height = statusHeight;
    statusArea.x = statusX;
    statusArea.y = statusY;

    SString col = props["InputStatusColor"];
    col.append ((char)0);
    unsigned long sbg, sfg;
    sscanf (col.array(), "%lu,%lu", &sbg, &sfg);
    SX11Color sxbg = SX11Color(impl, (SS_WORD32)sbg);
    SX11Color sxfg = SX11Color(impl, (SS_WORD32)sfg);

    sl = props["InputClientLocation"];
    sl.append((char)0);
    int clientX, clientY;
    sscanf(sl.array(), "%d,%d", &clientX, &clientY);

    ss = props["InputClientSize"];
    ss.append((char)0);
    int clientWidth, clientHeight;
    sscanf(ss.array(), "%d,%d", &clientWidth, &clientHeight);

    XRectangle clientArea;
    clientArea.width  = clientWidth;
    clientArea.height = clientHeight;
    clientArea.x = clientX;
    clientArea.y = clientY;

    col = props["InputClientColor"];
    col.append ((char)0);
    unsigned long cbg, cfg;
    sscanf (col.array(), "%lu,%lu", &cbg, &cfg);
    SX11Color cxbg = SX11Color(impl, (SS_WORD32)cbg);
    SX11Color cxfg = SX11Color(impl, (SS_WORD32)cfg);

    XVaNestedList sa = XVaCreateNestedList (0, 
      XNForeground , sxfg.getPixelValue(),
      XNBackground , sxbg.getPixelValue(),
      XNFontSet, fontSet,
      XNArea, &statusArea,
      0);

    XVaNestedList ca = XVaCreateNestedList (0, 
      XNForeground , cxfg.getPixelValue(),
      XNBackground , cxbg.getPixelValue(),
      XNFontSet, fontSet,
      XNArea, &clientArea,
      0);

    if (sa==0 || ca==0)
    {
      XCloseIM(xim);
      xim = 0;
      fprintf (stderr, "Can not create XVaNestedList.\n");
      return false;
    }
    SString pw = props["InputWindow"];
    pw.append ((char)0);
    unsigned long w;
    sscanf (pw.array(), "%lu", &w);
    xic = XCreateIC(xim, XNInputStyle, code,
       XNClientWindow, (Window) w,
       XNFocusWindow, (Window) id,
       XNPreeditAttributes, ca,
       XNStatusAttributes, sa,
       0);
    XFree (ca);
    XFree (sa);
  }
  else if (inputStyle == "preedit-over-status-under")
  {
    SString sl = props["InputStatusLocation"];
    sl.append((char)0);
    int statusX, statusY;
    sscanf(sl.array(), "%d,%d", &statusX, &statusY);

    SString ss = props["InputStatusSize"];
    ss.append((char)0);
    int statusWidth, statusHeight;
    sscanf(ss.array(), "%d,%d", &statusWidth, &statusHeight);
    XRectangle statusArea;
    statusArea.width  = statusWidth;
    statusArea.height = statusHeight;
    statusArea.x = statusX;

    SString col = props["InputStatusColor"];
    col.append ((char)0);
    unsigned long sbg, sfg;
    sscanf (col.array(), "%lu,%lu", &sbg, &sfg);
    SX11Color sxbg = SX11Color(impl, (SS_WORD32)sbg);
    SX11Color sxfg = SX11Color(impl, (SS_WORD32)sfg);

    col = props["InputClientColor"];
    col.append ((char)0);
    unsigned long cbg, cfg;
    sscanf (col.array(), "%lu,%lu", &cbg, &cfg);
    SX11Color cxbg = SX11Color(impl, (SS_WORD32)cbg);
    SX11Color cxfg = SX11Color(impl, (SS_WORD32)cfg);

    XVaNestedList sa = XVaCreateNestedList (0, 
      XNForeground , sxfg.getPixelValue(),
      XNBackground , sxbg.getPixelValue(),
      XNFontSet, fontSet,
      XNArea, &statusArea,
      0);

    XPoint spot = {1, 1};
    XVaNestedList ca = XVaCreateNestedList (0, 
      XNForeground , cxfg.getPixelValue(),
      XNBackground , cxbg.getPixelValue(),
      XNSpotLocation, &spot,
      XNFontSet, fontSet,
      0);

    if (sa==0 || ca==0)
    {
      XCloseIM(xim);
      xim = 0;
      fprintf (stderr, "Can not create XVaNestedList.\n");
      return false;
    }
    /* I can do this only in the same window */
    xic = XCreateIC(xim, XNInputStyle, code,
       XNClientWindow, (Window) id,
       XNFocusWindow, (Window) id,
       XNPreeditAttributes, ca,
       XNStatusAttributes, sa,
       0);
    XFree (ca);
    XFree (sa);
  }
  else /* preedit-root-status-root */
  {
    xic = XCreateIC(xim, XNInputStyle, code,
       XNClientWindow, (Window) id,
       XNFocusWindow, (Window) id,
       0);
  }
  if (xic==0) 
  {
    XCloseIM(xim);
    xim = 0;
    fprintf (stderr, "Could not create XIC from XIM\n");
    return false;
  }
  /* is it int and not long? */
  int  xim_ev_mask = 0;

  XGetICValues (xic , XNFilterEvents , &xim_ev_mask , NULL);
  xim_ev_mask |= KeyPressMask|KeyReleaseMask;
  XSetICValues (xic , XNFilterEvents , &xim_ev_mask , NULL);

  //XSetICValues(xic, XNResetState, XIMPreserveState, (char *) 0);
  eventMask |= xim_ev_mask;

  XSelectInput (impl->display, (Window) id, eventMask);
  XSetICFocus (xic);
  /* is it good ? */
  setProperties (props);
  //XSetInputFocus (impl->display, (Window) id, RevertToNone, CurrentTime);
 
  return status;
}


Generated by  Doxygen 1.6.0   Back to index