//
// Copyright (C) 1999-2004 Toshikaz Hirabayashi
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// TOSHIKAZ HIRABAYASHI BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
// OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
// Except as contained in this notice, the name of Toshikaz Hirabayashi shall
// not be used in advertising or otherwise to promote the sale, use or other
// dealings in this Software without prior written authorization from
// Toshikaz Hirabayashi.

#include <WScom.h>
#include <WSkeysym.h>
#include <WSDkeyboard.h>
#include <WSCvifield.h>
#include <WSCclassInformation.h>
#include <WSDdev.h>
#include <WSCdevice.h>
#include <WSCimageSet.h>
#include <WSDtimer.h>
#include <WSCfontSet.h>
#include <WSCblink.h>
#include <WSDmouse.h>
#include <WSDappDev.h>
#include <WSCbaseList.h>

WSMFguiClassInitialize(WSCvifield,WSCvlabel);
WSMFversion(WSCvifield,WSCvlabel);

//#define TDBG
WSMFpropertyValueChange(WSCvifield,WSNbackColor,short,WS_DF_WORKBACKCOLOR);

WSCvifield::WSCvifield(WSCbase* base,char* objname):
                WSCvlabel(base,objname){

  _register_focus_move();
  _cbase = 0;
  _cursor_fore = 1;
  _upname = WSGFstrdup("");
  _dwname = WSGFstrdup("");
  _lname = WSGFstrdup("");
  _rname = WSGFstrdup("");
  _rtname = WSGFstrdup("");
  _tbname = WSGFstrdup("");
  _btbname = WSGFstrdup("");
  _data_source_name = WSGFstrdup("");
  _data_source_type = WS_DATA_SOURCE_NONE;
  _enable_focus_move = False;
  _cursor_adjust = True;
  _skip_mode = False;
  _multi_lines = 0;
//  _columns = 0;
  _cur_pos = 0;
  _cur_pos_bk = -1;
  _kanji_in = True;
  _icursor = True;
  _fspace = False;
  _mouse_pressed = False;
  _enable_max = True;
  _mx = 0;
  _my = 0;
  _no_hatch = 0;
  _no_mcur_adjust = 0;
  _select_pos1 = 0;
  _select_pos2 = 0;
  _disp_cur_x = 0;
  _disp_cur_y = 0;
  _lines = -1;
  _deleting = 0;
  _return_key_focus = 0;
  _back_color = WS_DF_WORKBACKCOLOR;
  _ucs2 = new WSCushort[1];
  _ucs2[0] =0;
  _key_input_disable = 0;
  _fep_set_focus = 0;
  _display_only = 0;
  _need_ds_update = False;

  
  WSMFpropertyCreateStart
    WSMFparentCheckVerSrc(WSCvifield);

//    WSMFpropertyCreate(WSNcolumns,         WSCushort, _columns,WSScolumns );
    WSMFpropertyCreate(WSNcursorPos,  short, _cur_pos, WSScursorPos );
    WSMFpropertyCreate(WSNkanjiIn,  WSCbool, _kanji_in, WSSkanjiIn );
      WSMFpropertySetSelection(WSRbool1,WSRbool1D);
      WSMFpropertyVisible(False);
    WSMFpropertyCreate(WSNinterCur, WSCbool, _icursor,WSSinterCur);
      WSMFpropertySetSelection(WSRbool1,WSRbool1D);
    WSMFpropertyCreate(WSNupward, char*, _upname,WSSupward);
    WSMFpropertyCreate(WSNdownward,char*, _dwname,WSSdownward);
    WSMFpropertyCreate(WSNleftward,char*,_lname,WSSleftward);
    WSMFpropertyCreate(WSNrightward, char*,_rname,WSSrightward);
    WSMFpropertyCreate(WSNreturn,char*,_rtname,WSSreturn);
    WSMFpropertyCreate(WSNtab,char*,_tbname,WSStab);
    WSMFpropertyCreate(WSNbacktab,char*,_btbname,WSSbacktab);
    WSMFpropertyCreate(WSNenableFocusMove, WSCbool,_enable_focus_move,WSSenableFocusMove);
    WSMFpropertySetSelection(WSRbool1,WSRbool1D);

    WSMFpropertyCreate(WSNfillSpace, WSCbool, _fspace,WSSfillSpace);
      WSMFpropertySetSelection(WSRbool1,WSRbool1D);
    WSMFpropertyCreate(WSNcursorAdjust,WSCbool,_cursor_adjust,WSScursorAdjust);
      WSMFpropertySetSelection(WSRbool1,WSRbool1D);
    WSMFpropertyCreate(WSNifieldSkipMode,WSCbool,_skip_mode,WSSifieldSkipMode );
      WSMFpropertySetSelection(WSRbool1,WSRbool1D);
    WSMFpropertyCreate(WSNnoHatch,WSCbool,_no_hatch,WSSnoHatch );
      WSMFpropertySetSelection(WSRbool1,WSRbool1D);
    WSMFpropertyCreate(WSNreturnKeyFocus,WSCbool,_return_key_focus,WSSreturnKeyFocus );
      WSMFpropertySetSelection(WSRbool1,WSRbool1D);
    WSMFpropertyCreate(WSNdataSource, WSCuchar, _data_source_type,WSSdataSource );
      WSMFpropertySetSelection(WSRdataSource,WSRdataSourceD);
    WSMFpropertyCreate(WSNdataSourceName, char*, _data_source_name,WSSdataSourceName );
    WSMFpropertyCreate(WSNdisplayOnly,WSCbool,_display_only,WSSdisplayOnly );
      WSMFpropertySetSelection(WSRbool3,WSRbool3D);



    WSMFpropertyDelete(WSNemboss);
    WSMFpropertyDelete(WSNorientation);
    WSMFpropertyDelete(WSNalignmentH);
    WSMFpropertyDelete(WSNalignmentV);

    WSMFpropertyValueChangeDef(WSCvifield,WSNbackColor,short);


    WSMFaddTrigger(WSEV_ACTIVATE    );
    WSMFaddTrigger(WSEV_KEY_PRESS   );
    WSMFaddTrigger(WSEV_KEY_RELEASE );
    WSMFaddTrigger(WSEV_KEY_HOOK    );
    WSMFaddTrigger(WSEV_FOCUS_CH    );
    WSMFaddTrigger(WSEV_VALUE_CH    );
  WSMFpropertyCreateEnd

}

//WSMFproperty( WSCvifield, WSNcolumns,   WSCushort, _columns,   0  );
WSMFproperty( WSCvifield, WSNcursorPos,  short,          _cur_pos,0      );
WSMFproperty( WSCvifield, WSNkanjiIn,  WSCbool,    _kanji_in,  True   );
WSMFproperty( WSCvifield, WSNinterCur, WSCbool,    _icursor, True  );
WSMFproperty( WSCvifield, WSNenableFocusMove, WSCbool,    _enable_focus_move, False );
WSMFproperty( WSCvifield, WSNupward,    char*,   _upname, WSGFstrdup(""));
WSMFproperty( WSCvifield, WSNdownward, char*,   _dwname, WSGFstrdup(""));
WSMFproperty( WSCvifield, WSNleftward,   char*,   _lname, WSGFstrdup(""));
WSMFproperty( WSCvifield, WSNrightward,  char*,   _rname, WSGFstrdup(""));
WSMFproperty( WSCvifield, WSNreturn, char*,   _rtname, WSGFstrdup(""));
WSMFproperty( WSCvifield, WSNtab, char*,   _tbname, WSGFstrdup(""));
WSMFproperty( WSCvifield, WSNbacktab, char*,   _btbname, WSGFstrdup(""));
WSMFproperty( WSCvifield, WSNfillSpace,   WSCbool,    _fspace,    False );
WSMFproperty( WSCvifield, WSNcursorAdjust,WSCbool,    _cursor_adjust, True );
//WSMFproperty( WSCvifield, WSNmultiLine,  WSCbool,    _multi_lines,   False );
WSMFproperty( WSCvifield, WSNifieldSkipMode, WSCbool,  _skip_mode,     False );
WSMFproperty( WSCvifield, WSNnoHatch, WSCbool,  _no_hatch,     False );
WSMFproperty( WSCvifield, WSNreturnKeyFocus, WSCbool, _return_key_focus, False);
WSMFproperty( WSCvifield, WSNdataSource,  WSCuchar, _data_source_type,WS_DATA_SOURCE_NONE);
WSMFproperty( WSCvifield, WSNdataSourceName,  char*, _data_source_name,WSGFstrdup(""));

WSMFproperty( WSCvifield, WSNdisplayOnly, WSCbool,  _display_only,     False );

void WSCvifield::setWorkWSNupward(char*){}
void WSCvifield::getWorkWSNupward(char**){}
void WSCvifield::setWorkWSNdownward(char*){}
void WSCvifield::getWorkWSNdownward(char**){}
void WSCvifield::setWorkWSNleftward(char*){}
void WSCvifield::getWorkWSNleftward(char**){}
void WSCvifield::setWorkWSNrightward(char*){}
void WSCvifield::getWorkWSNrightward(char**){}
void WSCvifield::setWorkWSNreturn(char*){}
void WSCvifield::getWorkWSNreturn(char**){}
void WSCvifield::setWorkWSNtab(char*){}
void WSCvifield::getWorkWSNtab(char**){}
void WSCvifield::setWorkWSNbacktab(char*){}
void WSCvifield::getWorkWSNbacktab(char**){}
void WSCvifield::setWorkWSNlabelString(char*){
  
  if (_label_string[0] == 0){
    if (_fspace != False){
      long len = _max_length;
      if (_enable_max != False){
        delete _label_string;
        _label_string = new char[len+1];
        memset(_label_string,' ',len);
        _label_string[len]=0;
      }
    }
    WSCushort* str = WSGFgetUCS2(_label_string,WS_EN_DEFAULT);
    _set_text(str);
    setCurPos(0);
    return;
  }

  WSCushort* ustr = WSGFgetUCS2(_label_string,WS_EN_DEFAULT);
  if (_enable_max != False && WSGFstrlenUCS2(ustr) > _max_length-1){
    ustr[_max_length] = 0;
  }
  _set_text( ustr );
  _fill_space();
  setCurPos(0);
}
void WSCvifield::getWorkWSNlabelString(char** data){
  if (_label_string == NULL){
    if (_ucs2 != NULL){
      _label_string = WSGFgetString(_ucs2,WS_EN_DEFAULT);
      *data = _label_string;
    }else{
      *data = "";
    }
  }else{
    *data = _label_string;
  }
  if (getPropertyEditMode() != False &&
      _data_source_type != WS_DATA_SOURCE_NONE){
    *data = "";
  }
}

//void WSCvifield::setWorkWSNcolumns(WSCushort){}
//void WSCvifield::getWorkWSNcolumns(WSCushort*){}
void WSCvifield::setWorkWSNcursorPos(short data){
  if (_initialized == False){
    if (data != 0){
      setCurPos(data);
	}
    return;
  }
  setCurPos(data);
}

void WSCvifield::getWorkWSNcursorPos(short*){}
void WSCvifield::setWorkWSNmaxLength(WSCushort data){
  if (getInitialized() == False && data == WS_VLABEL_MAXLEN_DEFAULT){
    return;
  }
  if (data == 0){
    _enable_max = False;
  }
  WSCvlabel::setWorkWSNmaxLength(data);
  if (data == 0){
    return;
  }
  if (_enable_max != False){
    _update_text();
  }
}

void WSCvifield::setWorkWSNkanjiIn(WSCbool data){
  if (_initialized == False){
    return;
  }
  WSDdev* dev = getowndev();
  if (dev == NULL){
    return;
  }
  if (getFocus() != False){
      WSGIappKeyboard()->setFocusInputWorkProc(_key_handler,NULL,this);
      if (data == False){
        WSGIappKeyboard()->setEnableFep(dev,False);
      }else{
        WSGIappKeyboard()->setEnableFep(dev,True);
      }
  }
}

void WSCvifield::getWorkWSNkanjiIn(WSCbool*){}
void WSCvifield::setWorkWSNinterCur(WSCbool fl){
  if (getInitialized() != False && fl != False){
    WSCstring str(getProperty(WSNlabelString));
    str.delTailSpace();
    setPropertyV(WSNlabelString,str.getString());
  }
}

void WSCvifield::getWorkWSNinterCur(WSCbool*){}
void WSCvifield::setWorkWSNenableFocusMove(WSCbool){}
void WSCvifield::getWorkWSNenableFocusMove(WSCbool*){}
void WSCvifield::setWorkWSNdisplayOnly(WSCbool){}
void WSCvifield::getWorkWSNdisplayOnly(WSCbool*){}

void WSCvifield::setWorkWSNfillSpace(WSCbool fl){
  if (getInitialized() != False && fl == False){
    WSGFdelTailSpaceUCS2(_ucs2);
  }
}

void WSCvifield::getWorkWSNfillSpace(WSCbool*){}
void WSCvifield::setWorkWSNcursorAdjust(WSCbool){}
void WSCvifield::getWorkWSNcursorAdjust(WSCbool*){}
void WSCvifield::setWorkWSNifieldSkipMode(WSCbool){}
void WSCvifield::getWorkWSNifieldSkipMode(WSCbool*){}
void WSCvifield::setWorkWSNnoHatch(WSCbool){}
void WSCvifield::getWorkWSNnoHatch(WSCbool*){}
void WSCvifield::setWorkWSNreturnKeyFocus(WSCbool){}
void WSCvifield::getWorkWSNreturnKeyFocus(WSCbool*){}

void WSCvifield::_set_ds_instance(){
  WSCbase* serv = WSGIappObjectList()->searchInstance("WSCbase", _data_source_name);
  if (serv != NULL){
    setDataSourceServer(serv);
    serv->addDataSourceClient(this);
    WSCstring val;
    val = serv->getProperty(serv->getDefaultProperty());
    setProperty(WSNlabelString,val);
  }else{
    _need_ds_update = True;
  }
}

void WSCvifield::setWorkWSNdataSource(WSCuchar){
  if (_data_source_name != NULL && _data_source_name[0] != 0){
    if (_data_source_type == WS_DATA_SOURCE_FILE){
      WSCstring* str = WSGFreadTextFile(_data_source_name);
      if (str != NULL){
        setProperty(WSNlabelString,str->getString());
        delete str;
      }
    }else
    if (_data_source_type == WS_DATA_SOURCE_INSTANCE){
      _set_ds_instance();
    }
    if (_data_source_type != WS_DATA_SOURCE_INSTANCE){
      WSCbase* ds = getDataSourceServer();
      if (ds != NULL){
        ds->delDataSourceClient(this);
        setDataSourceServer(NULL);
      }
    }
  }
}
void WSCvifield::getWorkWSNdataSource(WSCuchar*){}
void WSCvifield::setWorkWSNdataSourceName(char* sname){
  if (_data_source_type == WS_DATA_SOURCE_INSTANCE){
    _set_ds_instance();
  }else
  if (_data_source_type == WS_DATA_SOURCE_FILE){
    WSCstring* str = WSGFreadTextFile(sname);
    if (str != NULL){
      setProperty(WSNlabelString,str->getString());
      delete str;
    }
  }
}
void WSCvifield::getWorkWSNdataSourceName(char**){}


WSCvifield::~WSCvifield(){
  if (getFocus() != False){
    WSGIappTimer()->delTimerProc( _cur_timer_id );
    WSGIappKeyboard()->resetFocusInputWorkProc();
  }
  if (this == WSGIappDev()->getSelectionOwner()){
    _deleting = True;
    WSGIappDev()->setSelectionOwner(NULL);
  }
  _cur_timer_id = 0;

  if (getowndev() != NULL){
    WSGIappKeyboard()->resetFep(getowndev());
  }
 
  setFocus(False);
  if (_upname != NULL){
    delete _upname;
    _upname = NULL;
  }
  if (_dwname != NULL){
    delete _dwname;
    _dwname = NULL;
  }
  if (_lname != NULL){
    delete _lname;
    _lname = NULL;
  }
  if (_rname != NULL){
    delete _rname;
    _rname = NULL;
  }
  if (_rtname != NULL){
    delete _rtname;
    _rtname = NULL;
  }
  if (_tbname != NULL){
    delete _tbname;
    _tbname = NULL;
  }
  if (_btbname != NULL){
    delete _btbname;
    _btbname = NULL;
  }

  if (_ucs2 != NULL){
    delete _ucs2;
    _ucs2 = NULL;
  }
  if (_data_source_name != NULL){
    delete _data_source_name;
    _data_source_name = NULL;
  }
}
long WSCvifield::_cur_timer_id = 0;

void WSCvifield::_cursor_blink_handler(WSCuchar,void* ptr){
  WSCvifield* ifd = (WSCvifield*)ptr;
  WSGIappKeyboard()->setFocusInputWorkProc(_key_handler,NULL,ifd);
  ifd->setAbsoluteDraw(True);
  ifd->onCursorBlink();
}

void WSCvifield::onCursorBlink(){
  setCursorFore( !getCursorFore() );
  setAbsoluteDraw(True);
  WSCbool fl;
  getPropertyV(WSNblinkRefreshing,&fl);
  if (fl == False){
    draw();
  }else{
    redraw();
  }
  if (_show_grip_hand != False){
    drawGriphand();
  }
  return;
}

WSCbool WSCvifield::getCursorFore(){
  return _cursor_fore;
}

void WSCvifield::setCursorFore(WSCbool fl){
//printf("WSCvifield::setCursorFore fl=%d\n",fl);
  if (fl != False){
    _cursor_fore = True;
  }else{
    _cursor_fore = False;
  }
}

long WSCvifield::_device_initialize(){
  WSDdev* dev = getowndev();
  if (dev == NULL){
    return WS_ERR;
  }
  dev->setEnableEventBit(WSEV_MOUSE_PRESS_BIT | WSEV_MOUSE_RELEASE_BIT |
                         WSEV_MOUSE_MOVE_BIT );
  WSCvlabel::_device_initialize();
  return WS_NO_ERR;
}

void WSCvifield::_fill_space(){
  if (_enable_max == False){
    return;
  }
  if (_fspace == False && _icursor != False){
    return;
  }
  if (WSGFstrlenUCS2(_ucs2) >= _max_length ){
    return;
  }

  long len = _max_length;
  long len2 = WSGFstrlenUCS2(_ucs2);
  WSCushort* tmp = new WSCushort[len+1];
  memcpy(tmp,_ucs2,sizeof(WSCushort)*len2);
  long i;
  for(i=len2; i<len; i++){
    tmp[i] = (WSCushort)' ';
  } 
  _set_text(tmp);
  return;
}

long WSCvifield::draw(){
#ifdef TDBG
  printf("WSCvifield::draw start %d\n",WSGFclocktime());
#endif
dbprintf("WSCvifield::draw %s:%d  %s begin..\n",__FILE__,__LINE__,getInstanceName());
  if (getVisible() == False){
dbprintf("WSCvifield::draw %s:%d  %s vis=False\n",__FILE__,__LINE__,getInstanceName());
    return WS_NO_ERR;
  }
//printf("WSCvifield::draw start:");
//WSGFtimetrace();

  WSDdev* dev = getowndev();
  if (dev == NULL){
dbprintf("WSCvifield::draw %s:%d  %s dev=NULL\n",__FILE__,__LINE__,getInstanceName());
    return WS_ERR;
  }
  if (_ucs2 == NULL){
    _ucs2 = new WSCushort[1];
    _ucs2[0] =0;
  }
  char shadow_type = _shadow_type;
  if (getFocus() != False){
    if (_use_pix == False){
        char fl = True;
        dev->setValue(WSDEV_USE_PIXMAP,&fl);
    }
  }
  if (shadow_type == WS_SHADOW_TRANS){
    if (getFocus() != False){
      shadow_type = WS_SHADOW_IN;
    }else if (_use_pix != False){
      //USE_PIXMAP = True にされているのを False にする。
      char fl = False;
      dev->setValue(WSDEV_USE_PIXMAP,&fl);
    }
  }

#ifdef TDBG
  printf("WSCvifield::draw here-1 %d\n",WSGFclocktime());
#endif

  short x = _x;
  short y = _y;
  WSCushort w = _w;
  WSCushort h = _h;

  WSCbool absolute = getAbsoluteDraw();
  if (absolute != False){
  }else if (dev->isExposed(x,y,w,h) == False ){
dbprintf("WSCvifield::draw %s:%d  %s not exposed\n",__FILE__,__LINE__,getInstanceName());
    return WS_NO_ERR;
  }

  WSCushort st = _shadow_thick;
  long blinking   = _bl_fl;
  long blinkfore  = WSGIappBlink()->getBlinkFore(_blink_rate);
  long shadowtype = _shadow_type;
  long twinblink  = _tw_fl;
  long blinktype  = _bl_type;
  short fgno         = _fore_color;
  short bgno         = _back_color;
  short blinkcolorno = _blink_color;
  short backblinkno  = _bg_blink_color;
  short tsno  = _ts_color;
  short bsno  = _bs_color;
  long  draw_cur =  getFocus() != False && getSensitive() != False && _cursor_fore != False ;
  WSCbool bldraw = (blinking  != False && blinkfore != False );

  if (shadowtype == WS_SHADOW_NONE &&
        bldraw && twinblink == False){
    return WS_NO_ERR;
  }
  _adjust_cbase();

  long err = dev->beginDraw(x,y,w,h,absolute);
  if (err != WS_NO_ERR){
dbprintf("WSCvifield::draw %s:%d %s device is not ready\n",__FILE__,__LINE__,getInstanceName());
    return WS_NO_ERR;
  }
  WSCbase::update();
  setAbsoluteDraw(False);
//  WSCushort* str = &_ucs2[_cbase];
  long ulen = WSGFstrlenUCS2(&_ucs2[_cbase]);
  WSCushort* str = new WSCushort[ulen+1];
  long i;
  for(i=0; i<ulen; i++){
    if (_ucs2[_cbase + i] == '\t'){
      str[i] = ' ';
    }else{
      str[i] = _ucs2[_cbase + i];
    }
  }
  str[ulen] = 0;
 
#ifdef TDBG
  printf("WSCvifield::draw here0 %d\n",WSGFclocktime());
#endif

  if (shadowtype != WS_SHADOW_TRANS) {
    if (_rv_fl != False) {
      if (bldraw && blinktype != WS_FORE){
        dev->setForeColor(blinkcolorno);
      }else{
        dev->setForeColor(fgno);
      }
    }else{
      if (bldraw && blinktype != WS_FORE){
        dev->setForeColor(backblinkno);
      }else{
        dev->setForeColor(bgno);
      }
    }
    if (_grad_no == 0){
      dev->drawFillRect(0, 0, w, h);
    }else{
      dev->drawGradation(_grad_no,tsno,bgno,bsno,0, 0, w, h,_grad_margin);
    }
  }

  short ix = st+ _margin_left;
  short iy = st+ _margin_top;
  WSCushort iw = w - st*2;
  WSCushort ih = h - st*2;
  WSCushort h_m = _margin_left + _margin_right;
  WSCushort v_m = _margin_top + _margin_bottom;

  if (iw < h_m) {
    iw = 1;
  }else{
    iw = iw - h_m;
  }
  if (ih < v_m) {
    ih = 1;
  }else{
    ih = ih - v_m;
  }

  WSDimage* image;
  if (bldraw  && blinktype != WS_BACK ){
    if (_blink_pixmap != -1 && twinblink != False){
      image = WSGIappImageSet()->getImage(_blink_pixmap);
      dev->drawImage(ix, iy, iw, ih, image, WS_CENTER);
    }
  }else{
    if (_label_pixmap != -1){
      image = WSGIappImageSet()->getImage(_label_pixmap);
      dev->drawImage(ix, iy, iw, ih, image, WS_CENTER);
    }
  }
 

  if (shadowtype != WS_SHADOW_TRANS) {
    if (st > 0){
//DEVELOP need change to fast
      WSGFdrawShadow(dev, shadowtype, st, tsno, tsno, bsno, bgno,0, 0, w, h);
dbprintf("WSCvifield::draw %s:%d %s draw shadow..\n",__FILE__,__LINE__,getInstanceName());
    }
  }

  if (_rv_fl != False) {
      if (bldraw && blinktype != WS_BACK && twinblink != False){
        dev->setForeColor(backblinkno);
      }else{
        dev->setForeColor(bgno);
      }
  }else{
      if (bldraw && blinktype != WS_BACK && twinblink != False){
        dev->setForeColor(blinkcolorno);
      }else{
        dev->setForeColor(fgno);
      }
  }

  WSCushort margin_left   = _margin_left;
  WSCushort margin_right  = _margin_right;
  WSCushort margin_top    = _margin_top;
  WSCushort margin_bottom = _margin_bottom;
  short sx = _shadow_thick + margin_left;
  short sy = _shadow_thick + margin_top;
//  short mdx = margin_left;
//  short mdy = margin_top;
  short mdx = _shadow_thick + margin_left;
  short mdy = _shadow_thick + margin_top;
  short sw = 0;
  short sh = 0;
  if ( w > _shadow_thick*2 + margin_left + margin_right){
    sw = w -_shadow_thick*2 - margin_left - margin_right;
  }

  if ( h > _shadow_thick*2 + margin_top + margin_bottom){
    sh = h -_shadow_thick*2 - margin_top - margin_bottom;
  }

  char alignment = WS_LEFT;
  if (_multi_lines != False){
    alignment = WS_LEFT_TOP;
  }

  if (getSensitive() == False ||
      (getPropertyEditMode() != False && (long)getUserData(WS_DET) == 0)){
    dev->setHatchPattern(8);
  }

#ifdef TDBG
  printf("WSCvifield::draw here1 %d\n",WSGFclocktime());
#endif

  if (!(bldraw  && blinktype != WS_BACK && twinblink == False)){
    long spos1 = 0;
    long spos2 = 0;
    if (_select_pos1 != _select_pos2){
      spos2 = _select_pos2 - _cbase;
      spos1 = _select_pos1 - _cbase;
    }

    dev->setBackColor(bgno);
    if (_rv_fl != False) {
      if (bldraw && blinktype != WS_FORE){
        if (draw_cur != False){
          dev->setBackColor(blinkcolorno);
        }
      }else{
        if (draw_cur != False){
          dev->setBackColor(fgno);
        }
      }
    }else{
      if (bldraw && blinktype != WS_FORE){
        if (draw_cur != False){
          dev->setBackColor(backblinkno);
        }
      }else{
        if (draw_cur != False){
          dev->setBackColor(bgno);
        }
      }
    }
    if ( draw_cur != False){
      long cpos = _cur_pos - _cbase;
#ifdef TDBG
  printf("WSCvifield::draw here1.5 %d\n",WSGFclocktime());
#endif
//printf("WSCvifield::draw drawUString xy=%d,%d cpos=%d _cursor_fore=%d\n",sx,sy,cpos,_cursor_fore);
      if (_multi_lines == False){
        if (_key_input_disable == False){
          dev->drawUString(sx,sy,sw,sh,
            str, _font, alignment, cpos,_icursor, spos1,spos2);
        }else{
          dev->drawUString(sx,sy,sw,sh,
            str, _font, alignment, -1,_icursor, spos1,spos2);
        }
dbprintf("WSCvifield::draw %s:%d %s draw string..\n",__FILE__,__LINE__,getInstanceName());
      }else{
        long x1 = sx,y1=sy;
        long xx = 0,yy=0;
        if (_no_mcur_adjust == 0){
          _get_disp_cur_pos(&xx,&yy);
//printf("draw: dispcurpos x,y=%d,%d\n",xx,yy);
          if (xx > mdx +sw + _mx - WS_MLINE_MARGIN){
            _mx += xx - (mdx + sw + _mx - WS_MLINE_MARGIN);
          }else
          if (xx < mdx + _mx ){    
            _mx -= (mdx+ _mx) -xx;
          }
          if (_mx < 0){
            _mx = 0;
          }
        }
//printf("draw: dispcurpos sx,_mx=%d,%d\n",sx,_mx);
        x1 =  sx - _mx;

        WSDfont* font = WSGIappFontSet()->getFont(_font);
        long fh = font->getFontHeight();
#ifdef TDBG
  printf("WSCvifield::draw here2 %d\n",WSGFclocktime());
#endif

        if (_no_mcur_adjust == 0){
//printf("WSCvifield::draw here2 yy=%d _my=%d fh=%d sh=%d mdy=%d ",yy,_my,fh,sh,mdy);
          if (yy > mdy + sh + _my - fh - WS_MLINE_MARGIN){
            _my += yy - (mdy + sh + _my - fh- WS_MLINE_MARGIN);
          }else
          if (yy < mdy + _my ){    
            _my -= (mdy+ _my) -yy;
          }
          if (_my < 0){
            _my = 0;
          }
//printf(" _my=%d\n",_my);
        }
        y1 =  sy - _my;
//printf("fh=%d sy=%d _my=%d\n",fh,sy,_my);
        WSCushort sw2 = sx + sw - x1;
        WSCushort sh2 = sy + sh - y1;
//printf("WSCvifield::draw drawUString xy2=%d,%d\n",x1,y1);
        if (_key_input_disable == False){
          dev->drawUString(x1,y1,sw2,sh2,
              str, _font, alignment, cpos,_icursor, spos1,spos2);
        }else{
          dev->drawUString(x1,y1,sw2,sh2,
              str, _font, alignment, -1,_icursor, spos1,spos2);
        }
dbprintf("WSCvifield::draw %s:%d %s draw string..\n",__FILE__,__LINE__,getInstanceName());
#ifdef TDBG
  printf("WSCvifield::draw here3 %d\n",WSGFclocktime());
#endif
      }
#if 0
      if (_kanji_in != False){
        _fep_cursor_adjust(WSGIappKeyboard());
      }
#endif
    }else{
      if (_multi_lines == False){
//printf("WSCvifield::draw drawUString xy3=%d,%d\n",sx,sy);
        dev->drawUString(sx,sy,sw,sh,
              str, _font, alignment, -1,False, spos1,spos2);
      }else{
        long x1 = sx,y1=sy;
        long xx = 0,yy=0;
        if (_no_mcur_adjust == 0){
          _get_disp_cur_pos(&xx,&yy);
          if ( mdx +sw + _mx - WS_MLINE_MARGIN < xx ){
            _mx += xx - (mdx + sw + _mx - WS_MLINE_MARGIN);
          }else
          if (xx < mdx + _mx ){    
            _mx -= (mdx+ _mx) -xx;
          }
          if (_mx < 0){
            _mx = 0;
          }
        }
        x1 =  sx - _mx;

        WSDfont* font = WSGIappFontSet()->getFont(_font);
        long fh = font->getFontHeight();
#ifdef TDBG
  printf("WSCvifield::draw here2 %d\n",WSGFclocktime());
#endif
        if (_no_mcur_adjust == 0){
//printf("WSCvifield::draw here3 yy=%d _my=%d fh=%d sh=%d mdy=%d ",yy,_my,fh,sh,mdy);
          if (yy > mdy + sh + _my - fh - WS_MLINE_MARGIN){
            _my += yy - (mdy + sh + _my - fh - WS_MLINE_MARGIN);
          }else
          if (yy < mdy + _my ){    
            _my -= (mdy+ _my) -yy;
          }
          if (_my < 0){
            _my = 0;
          }
//printf(" _my=%d\n",_my);
        }
        y1 =  sy - _my;
        WSCushort sw2 = sx + sw - x1;
        WSCushort sh2 = sy + sh - y1;
//printf("WSCvifield::draw drawUString xy4=%d,%d\n",x1,y1);
        dev->drawUString(x1,y1,sw2,sh2, str, _font, alignment, -1,False,
               spos1,spos2);
#ifdef TDBG
  printf("WSCvifield::draw here3 %d\n",WSGFclocktime());
#endif 

      }
dbprintf("WSCvifield::draw %s:%d %s draw string..\n",__FILE__,__LINE__,getInstanceName());
#if 0
      if (_kanji_in != False){
        _fep_cursor_adjust(WSGIappKeyboard());
      }
#endif
    }
  }

  if (str != NULL){
    delete str;
  }

dbprintf("WSCvifield::draw %s:%d  %s end..\n",__FILE__,__LINE__,getInstanceName());
  dev->endDraw();
#ifdef TDBG
  printf("WSCvifield::draw done %d\n",WSGFclocktime());
#endif 
  return WS_NO_ERR;
}
long WSCvifield::_cursor_move(char direction){
  if (_ucs2 == NULL){
    _cur_pos = 0;
    return WS_NO_ERR;
  }
  if (direction == WS_LEFT){
    if (_enable_focus_move != False  && _cur_pos == 0){
      return WS_ERR;
    }
    if (_cur_pos >0){
      _cur_pos--;
    }
    return WS_NO_ERR;
  }else if (direction == WS_RIGHT){
    if (_enable_max != False && _enable_focus_move != False &&
        _cur_pos ==  _max_length - !_icursor){
      return WS_ERR;
    }

    if ( _enable_max == False || _cur_pos <  _max_length - !_icursor){
      _cur_pos++;
    }
    long len =  WSGFstrlenUCS2(_ucs2);
    if (_cur_pos > len){
      _cur_pos = len;
    }
    return WS_NO_ERR;
  }else if (direction == WS_UP){
#ifdef TDBG
  printf("WSCvifield::_cursor_move start %d\n",WSGFclocktime());
#endif 
    long xpos,ypos;
//    WSCushort* text = _get_disp_string();
    WSCushort* text = &_ucs2[_cbase];
    if (_multi_lines == False){
      text = _ucs2;
    }
    WSGFcalcStringXYPos(text,_cur_pos,&xpos,&ypos);
    if (_enable_focus_move != False && ypos ==  0){
      return WS_ERR;
    }

    if (ypos > 0){
      ypos--;
    }
//long _must_adjust_x_;
//printf("WSCvifield::_cursor_move up ypos=%d cpos=%d\n",ypos,_cur_pos);
    WSGFcalcStringXYPosToPos(text,xpos,ypos,&_cur_pos);
//printf("WSCvifield::_cursor_move up2 ypos=%d cpos=%d\n",ypos,_cur_pos);
    if (_enable_max != False && _cur_pos >= _max_length - !_icursor){
      _cur_pos = _max_length - !_icursor;
    }

#ifdef TDBG
  printf("WSCvifield::_cursor_move done %d\n",WSGFclocktime());
#endif
    return WS_NO_ERR;
  }else if (direction == WS_DOWN){
#ifdef TDBG
  printf("WSCvifield::_cursor_move start %d\n",WSGFclocktime());
#endif
    long xpos,ypos;
//    WSCushort* text = _get_disp_string();
    WSCushort* text = &_ucs2[_cbase];
    if (_multi_lines == False){
      text = _ucs2;
    }
//long _must_adjust_x_2;
    WSGFcalcStringXYPos(text,_cur_pos,&xpos,&ypos);
#ifdef TDBG
  printf("WSCvifield::_cursor_move here2 %d\n",WSGFclocktime());
#endif
    if (_lines == -1 ){
      _lines = WSGFgetLinesUCS2(_ucs2);
//printf("WSCvifield::_cursor_move here lines=%d _cbase=%d\n",_lines,_cbase);
    }
#ifdef TDBG
  printf("WSCvifield::_cursor_move here3 %d\n",WSGFclocktime());
#endif
    if (_enable_focus_move != False && ypos >  _lines-2 ){
      return WS_ERR;
    }
    if (ypos < _lines -1){
      ypos++;
    }
//printf("_cursor_move down x,y=%d,%d pos=%d lines=%d\n",xpos,ypos,_cur_pos,_lines);
    WSGFcalcStringXYPosToPos(text,xpos,ypos,&_cur_pos);
//printf("_cursor_move down2 x,y=%d,%d pos=%d \n",xpos,ypos,_cur_pos);
fflush(stdout);
    if ( _enable_max != False && _cur_pos >=  _max_length - !_icursor){
      _cur_pos = _max_length - !_icursor;
    }
#ifdef TDBG
  printf("WSCvifield::_cursor_move done %d\n",WSGFclocktime());
#endif
    return WS_NO_ERR;
  }
  return WS_ERR;
}

void WSCvifield::_get_disp_cur_pos(long* cx,long* cy){
  *cx =0;
  *cy =0;
  if (_cur_pos == _cur_pos_bk){
    *cx = _disp_cur_x;
    *cy = _disp_cur_y;
//printf("WSCvifield::_get_disp_cur_pos %d %d\n",_disp_cur_x,_disp_cur_y);
    return;
  }

#ifdef TDBG
  printf("WSCvifield::_get_disp_cur_pos start %d\n",WSGFclocktime());
#endif

  _cur_pos_bk = _cur_pos;

//  WSCushort* rawstr = _get_disp_string();
  WSCushort* rawstr = &_ucs2[_cbase];
  if (_multi_lines == False){
    rawstr = _ucs2;
  } 

  if ( _fspace == False){
    long col = WSGFstrlenUCS2(rawstr);
    if (_cur_pos > col - !_icursor){
       _cur_pos = col - !_icursor;
    } 
    if (_cur_pos < 0){
       _cur_pos = 0;
    }
  }

  _adjust_cbase();

  char alignment =  WS_LEFT;
  WSCushort* str;
  if (_multi_lines == False){
    str = rawstr;
  }else{
    alignment = WS_LEFT_TOP;
    str = rawstr;
  }
  WSCushort margin_left = _margin_left;
  WSCushort margin_right = _margin_right;
  WSCushort margin_top = _margin_top;
  WSCushort margin_bottom = _margin_bottom;
  WSCushort dw = _w;
  WSCushort dh = _h;
 
  long cursor_pos = _cur_pos - _cbase;
  WSCrect area;
  area.setRect(_shadow_thick+ margin_left,
        _shadow_thick + margin_top,
        dw -_shadow_thick*2 - margin_left - margin_right,
        dh -_shadow_thick*2 - margin_top -  margin_bottom);
  WSDfont* font = WSGIappFontSet()->getFont(_font);
  if (font != NULL){
    WSGFcalcStringPosAddr(str,&area,alignment,font,cursor_pos,
        &_disp_cur_x,&_disp_cur_y);

  }
  *cx = _disp_cur_x;
  *cy = _disp_cur_y;

#ifdef TDBG
  printf("WSCvifield::_get_disp_cur_pos done %d\n",WSGFclocktime());
#endif

//printf("WSCvifield::_get_disp_cur_pos4 %d %d\n",_disp_cur_x,_disp_cur_y);
}
void WSCvifield::_set_cur_pos(long absolute_pos){
  _cur_pos = absolute_pos + _cbase;
}
WSCbool WSCvifield::_special_key_handler(void* ptr,WSDkeyboard* keyboard,WSCbool fl){
  WSCvifield* obj = (WSCvifield*)ptr;
  if (obj->getVisible() == False){
    return True;
  }
  if (obj->getSensitive() == False){
    return True;
  }
  if (keyboard->getKey() == WSK_Return){
    obj->_on_key_input(keyboard,fl);
    if (fl != False){
      obj->onKey(keyboard,True);
      obj->execProcedure(WSEV_KEY_PRESS);
    }else{
      obj->onKey(keyboard,False);
      obj->execProcedure(WSEV_KEY_RELEASE);
    }
    return False;
  }
  return True;
}
void WSCvifield::_key_handler(void* ptr,WSDkeyboard* keyboard,WSCbool fl){
  WSCvifield* obj = (WSCvifield*)ptr;
  if (obj->getVisible() == False){
    return;
  }
  if (obj->getSensitive() == False){
    return;
  }
  if (keyboard->withAlt() != False){
    return;
  }
  obj->_on_key_input(keyboard,fl);
  if (fl != False){
    obj->onKey(keyboard,True);
    obj->execProcedure(WSEV_KEY_PRESS);
  }else{
    obj->onKey(keyboard,False);
    obj->execProcedure(WSEV_KEY_RELEASE);
  }
}

void WSCvifield::onKeyHook(WSDkeyboard* ){}
void WSCvifield::onKeyInput(WSDkeyboard* keyb,WSCbool fl){
  _on_key_input(keyb,fl);
}
void WSCvifield::onKey(WSDkeyboard* keyb,WSCbool fl){
  if( fl != False && keyb->getKey() == WSK_Return){
//    execEventProc(WSEV_ACTIVATE,NULL);
    onActivate();
  }
}
void WSCvifield::onActivate(){
  execProcedure(WSEV_ACTIVATE);
}

long WSCvifield::_get_absolute_pos(long x,long y){
  WSCushort dw = _w;
  WSCushort dh = _h;

  WSCushort margin_left = _margin_left;
  WSCushort margin_right = _margin_right;
  WSCushort margin_top = _margin_top;
  WSCushort margin_bottom = _margin_bottom;

  char alignment =  WS_LEFT;
  long px = x;
  long py = y;
  if (_multi_lines != False){
    alignment = WS_LEFT_TOP;
    px += _mx;
    py += _my;
  }
  WSCrect area;
  area.setRect(_shadow_thick+ margin_left,
           _shadow_thick + margin_top,
           dw -_shadow_thick*2 - margin_left - margin_right,
           dh -_shadow_thick*2 - margin_top -  margin_bottom);
  WSDfont* font = WSGIappFontSet()->getFont(_font);

  long absolute_pos = 0;
//  WSCushort* str = _get_disp_string();
  WSCushort* str = &_ucs2[_cbase];
  WSGFcalcStringPosFromAddr(str,&area,alignment,font,px,py,&absolute_pos,_icursor);
  return absolute_pos;
}
void WSCvifield::_set_select_pos1(long pos){
  _select_pos1 = pos + _cbase;
}
void WSCvifield::_set_select_pos2(long pos){
  _select_pos2 = pos + _cbase;
#ifndef SUN
#ifndef MSW
  long pos1 = _select_pos1;
  long pos2 = _select_pos2;
  if (pos1 > pos2){
    pos2 = _select_pos1;
    pos1 = _select_pos2;
  }
  if (pos1 != pos2){
    if (_label_string == NULL){
      _label_string = WSGFgetString(_ucs2,WS_EN_UTF8);
    }
    WSCstring str(_label_string,WS_EN_UTF8);
    str.cutString(pos2);
    str.deleteChars(0,pos1);
    WSGIappDev()->setSelectionOwner(this);
    WSGIappKeyboard()->setSelectedString(str);

//printf("WSCvifield::_set_select_pos select=#%s#\n",(char*)str);
  }
#endif
#endif
}
void WSCvifield::onMousePress(WSCpoint* point){
  WSCvlabel::onMousePress(point);
  if (getSensitive() != False){
    _mouse_pressed = True;
#ifndef SUN
#ifndef MSW
    if (WSGIappMouse()->getMouseStatus() & WS_MOUSE_BTN2){
      char* istr =  WSGIappKeyboard()->getSelectedString(WS_EN_UTF8);
      WSCushort* istr2 = WSGFgetUCS2(istr,WS_EN_UTF8);
      _replace_string(istr2);
    }else
#endif
#endif
    if (_cursor_adjust != False){
      long absolute_pos = _get_absolute_pos(point->x,point->y);
#if 0
      WSCbool on_kanji;
      WSCushort* str = _get_disp_string();
      str->columnToEucByte(absolute_pos,&on_kanji);
      if (on_kanji != False){
         if (absolute_pos > 0){
            absolute_pos--;
         }
      }
#endif
      _set_cur_pos(absolute_pos);
      _reset_select_string();
    }
    if (_kanji_in == False){
      WSGIappKeyboard()->resetFep(getowndev());
    }else{
      _fep_cursor_adjust(WSGIappKeyboard());
    }
    setFocus(True);
    setAbsoluteDraw(True);
    WSCbool fl;
    getPropertyV(WSNblinkRefreshing,&fl);
    if (fl == False){
      draw();
    }else{
      redraw();
    }
  }
}
void WSCvifield::onMouseMove(WSCpoint* point){
  WSCvlabel::onMouseMove(point);
  if (WSGIappMouse()->getMouseStatus() & WS_MOUSE_BTN1){
//printf("WSCvifield::onMouseMove ...\n");
    if ( _mouse_pressed != True){
      return;
    }
    if (getSensitive() != False){
      if (_cursor_adjust != False){
        long absolute_pos = _get_absolute_pos(point->x,point->y);
       
#if 0
        WSCbool on_kanji;
        WSCstring* str = _get_disp_string();
        str->columnToEucByte(absolute_pos,&on_kanji);
        if (on_kanji != False){
           if (absolute_pos > 0){
              absolute_pos--;
           }
        }
#endif
        _set_cur_pos(absolute_pos);
        _set_select_pos2(absolute_pos);

        setAbsoluteDraw(True);
        WSCbool fl;
        getPropertyV(WSNblinkRefreshing,&fl);
        if (fl == False){
          draw();
        }else{
          redraw();
        }
      }
    }
  }
}
void WSCvifield::onMouseRelease(WSCpoint* point){
//printf("WSCvifield::onMouseRelease ...\n");
  WSCvlabel::onMouseRelease(point);
  if (getSensitive() != False){
    _mouse_pressed = False;
#if 0
    if (WSGIappMouse()->getStatus() & WS_MOUSE_BTN1){
      if (_cursor_adjust != False){
        long absolute_pos = _get_absolute_pos(point->x,point->y);
     
        WSCbool on_kanji;
        WSCstring* str = _get_disp_string();
        str->columnToEucByte(absolute_pos,&on_kanji);
        if (on_kanji != False){
           if (absolute_pos > 0){
              absolute_pos--;
           }
        }
        _set_cur_pos(absolute_pos);
        _set_select_pos2(absolute_pos);
      }
      setAbsoluteDraw(True);
      WSCbool fl;
      getPropertyV(WSNblinkRefreshing,&fl);
      if (fl == False){
        draw();
      }else{
        redraw();
      }
    }
#endif
  }
}
void WSCvifield::_reset_select_string(){
  _select_pos1 = _cur_pos;
  _select_pos2 = _cur_pos;
}
void WSCvifield::_delete_select_string(){
  if (_select_pos1 == _select_pos2){
    return;
  }
  long pos1 = _select_pos1;
  long pos2 = _select_pos2;
  if (pos1 > pos2){
    pos2 = _select_pos1;
    pos1 = _select_pos2;
  }
  WSGFdelStringUCS2(_ucs2,pos1,pos2-pos1);
  if (_select_pos1 < _select_pos2){
    _select_pos2 = _select_pos1;
    _cur_pos = _select_pos1;
  }else{
    _select_pos1 = _select_pos2;
    _cur_pos = _select_pos2;
  }
  _text_changed = True;
}
void WSCvifield::_adjust_max_len(){
  if (_enable_max != False){
    long len = WSGFstrlenUCS2(_ucs2);
    if (len >_max_length){
      _ucs2[_max_length] = 0;
    }
  }
}
void WSCvifield::_on_key_input(WSDkeyboard* keyboard,WSCbool fl){
#ifdef TDBG
  printf("WSCvifield::_on_key_input %d\n",WSGFclocktime());
#endif
  if (getSensitive() == False){
    return;
  }
  if (fl == False){
    return;
  }
  onKeyHook(keyboard);
  execProcedure(WSEV_KEY_HOOK);
  WSCulong key =  keyboard->getKey();
//  WSCstring str( _label_string );
  if (_display_only != False){
    WSCbool reject = True;
    if (WSGIappKeyboard()->isCursorKey() != False){
      reject = False;
    }
    if ((key == WSK_C || key == WSK_c) &&
        WSGIappKeyboard()->withCntl() != False){
      reject = False;
    }else
    if (key == WSK_Insert &&
        (WSGIappKeyboard()->withCntl() != False ||
         WSGIappKeyboard()->withShift() != False )){
      reject = False;
    }

    if (reject != False){
      return;
    }
  }

  _no_mcur_adjust = 0;
  if (key == WSK_Return && _return_key_ok() == False){
     if (_enable_focus_move != False){
       WSCbase* target = getFocusMoveInstance(WS_RET);
       if (target != NULL && target != (WSCbase*)this && target->existProperty(WSNcursorPos) != False){
         target->setPropertyV(WSNcursorPos,(short)0);
       }
       if (target != NULL ){
         target->setFocus();
         target->draw();
       }
     }
     return;
  }

  WSCbool refresh;
  getPropertyV(WSNblinkRefreshing,&refresh);

  if ( keyboard->isCursorKey() != False ||
       key == WSK_Tab ||
       key == WSK_BackSpace ||
       key == WSK_Home ||
       key == WSK_End ||
       (key == WSK_Insert && keyboard->isTtyFunction() != False 
                          && keyboard->withShift() == False
                          && keyboard->withShift() == False) ||
       (key == WSK_Delete && keyboard->isTtyFunction() != False) ){

    WSCbase* target;
    WSCushort* newstr = NULL;
    switch(key){
      case WSK_BackSpace:
        if (_key_input_disable != False){
          break;
        }
        if (_cur_pos >= 0){
          if (_cur_pos == _select_pos2 && _select_pos1 < _select_pos2){
            _cur_pos = _select_pos1;
            _delete_select_string();
          }else
          if (_cur_pos == _select_pos2 && _select_pos1 > _select_pos2){
            _select_pos2 = _select_pos1;
            _select_pos1 = _cur_pos;
            _delete_select_string();
          }else
          if (_cur_pos == _select_pos1 && _select_pos1 > _select_pos2){
            _cur_pos = _select_pos2;
            _select_pos2 = _select_pos1;
            _select_pos1 = _cur_pos;
            _delete_select_string();
          }else{
            _reset_select_string();
            if (_cur_pos > 0){
              _cur_pos--;
              WSGFdelStringUCS2(_ucs2,_cur_pos,1);
              _text_changed = True;
            }
          }
          _update_text();
          _fep_cursor_adjust(keyboard);
        }else{

        }
        break;
      case WSK_Delete:
        if (_key_input_disable != False){
          break;
        }
        if (_select_pos1 == _select_pos2){
          WSGFdelStringUCS2(_ucs2,_cur_pos,1);
          _text_changed = True;
        }else{
          _delete_select_string();
        }
        _update_text();
        _fep_cursor_adjust(keyboard);
        break;
      case WSK_Left:
        if (_cursor_move(WS_LEFT) != WS_NO_ERR){
          if (_enable_focus_move != False){
            target = getFocusMoveInstance(WS_LEFT);
            if (target != NULL && target != (WSCbase*)this &&
              target->cast("WSCvifield") != NULL){
              target->setPropertyV(WSNcursorPos,(short)-1);
            }
            if (target != NULL ){
              target->setFocus();
              target->draw();
            }
          }
        }else{
          if (keyboard->withShift() == False){
            _select_pos1 = _cur_pos;
            _select_pos2 = _cur_pos;
          }else{
            _set_select_pos2(_cur_pos - _cbase);
            setAbsoluteDraw(True);
            WSCbool fl;
            getPropertyV(WSNblinkRefreshing,&fl);
            if (fl == False){
              draw();
            }else{
              redraw();
            }
          }
          _fep_cursor_adjust(keyboard);
          if (_multi_lines != False){
            return;
          }
        }
        break;
      case WSK_Right:
        if (_cursor_move(WS_RIGHT) != WS_NO_ERR){
          if (_enable_focus_move != False){
            target = getFocusMoveInstance(WS_RIGHT);
            if ( target != NULL && target != (WSCbase*)this &&
              target->cast("WSCvifield") != NULL){
              target->setPropertyV(WSNcursorPos,(short)0);
            }
            if (target != NULL ){
              target->setFocus();
              target->draw();
            }
          }
        }else{
          if (keyboard->withShift() == False){
            _select_pos1 = _cur_pos;
            _select_pos2 = _cur_pos;
          }else{
            _set_select_pos2(_cur_pos - _cbase);
            setAbsoluteDraw(True);
            WSCbool fl;
            getPropertyV(WSNblinkRefreshing,&fl);
            if (fl == False){
              draw();
            }else{
              redraw();
            }
          }
          _fep_cursor_adjust(keyboard);
          if (_multi_lines != False){
            return;
          }
        }
        break;
      case WSK_Up:
        if (_cursor_move(WS_UP) != WS_NO_ERR){
          if (_enable_focus_move != False){
            target = getFocusMoveInstance(WS_UP);
            if (target != NULL && target != (WSCbase*)this &&
              target->cast("WSCvifield") != NULL){
              target->setPropertyV(WSNcursorPos,(short)0);
            }
            if (target != NULL ){
              target->setFocus();
              target->draw();
            }
          }
        }else{
          if (keyboard->withShift() == False){
            _select_pos1 = _cur_pos;
            _select_pos2 = _cur_pos;
          }else{
            _set_select_pos2(_cur_pos - _cbase);
            setAbsoluteDraw(True);
            WSCbool fl;
            getPropertyV(WSNblinkRefreshing,&fl);
            if (fl == False){
              draw();
            }else{
              redraw();
            }
          }
          _fep_cursor_adjust(keyboard);
          if (_multi_lines != False){
            return;
          }
        }
        break;
      case WSK_Down:
        if (_cursor_move(WS_DOWN) != WS_NO_ERR){
          if (_enable_focus_move != False){
            target = getFocusMoveInstance(WS_DOWN);
            if (target != (WSCbase*)this && target != NULL &&
              target->cast("WSCvifield") != NULL){
              target->setPropertyV(WSNcursorPos,(short)0);
            }
            if (target != NULL ){
              target->setFocus();
              target->draw();
            }
          }
        }else{
          if (keyboard->withShift() == False){
            _select_pos1 = _cur_pos;
            _select_pos2 = _cur_pos;
          }else{
            _set_select_pos2(_cur_pos - _cbase);
            setAbsoluteDraw(True);
            WSCbool fl;
            getPropertyV(WSNblinkRefreshing,&fl);
            if (fl == False){
              draw();
            }else{
              redraw();
            }
          }
          _fep_cursor_adjust(keyboard);
          if (_multi_lines != False){
            return;
          }
        }
        break;
      case WSK_Home:
        if (keyboard->withCntl() != False){
          _cur_pos = 0;
        }else{
          long len = WSGFstrlenUCS2(_ucs2);
          if (len+1 > _cur_pos){
            long i;
            if (_ucs2[_cur_pos] == '\n' && _cur_pos > 0){
              _cur_pos--;
            }
            for(i = _cur_pos; i > -1; i--){
              if (_ucs2[i] == '\n'){
                _cur_pos = i+1;
                break;
              } 
              if (i==0){
                _cur_pos = 0;
              }
            }
          }
        }
        _select_pos1 = _cur_pos;
        _select_pos2 = _cur_pos;
        _fep_cursor_adjust(keyboard);
        if (_multi_lines != False){
          return;
        }
        {
          WSCbool fl;
          getPropertyV(WSNblinkRefreshing,&fl);
          if (fl == False){
            draw();
          }else{
            redraw();
          }
        }
        break;
      case WSK_End:
        if (keyboard->withCntl() != False){
          long len = WSGFstrlenUCS2(_ucs2);
          if (_icursor == False){
            _cur_pos = len -1;
          }else{
            _cur_pos = len;
          }
          if (_cur_pos < 0){
            _cur_pos = 0;
          }
        }else{
          long len = WSGFstrlenUCS2(_ucs2);
          if (len > _cur_pos){
            long i;
            for(i = _cur_pos; i < len; i++){
              if (_ucs2[i] == '\n'){
                _cur_pos = i;
                break;
              } 
              if (i == len -1){
                if (_icursor == False){
                  _cur_pos = len;
                }else{
                  _cur_pos = len+1;
                }
              }
            }
          }
        }
        _select_pos1 = _cur_pos;
        _select_pos2 = _cur_pos;
        _fep_cursor_adjust(keyboard);
        if (_multi_lines != False){
          return;
        }
        {
          WSCbool fl;
          getPropertyV(WSNblinkRefreshing,&fl);
          if (fl == False){
            draw();
          }else{
            redraw();
          }
        }
        break;
      case WSK_Insert:
        if ( (keyboard->withCntl() != False) ||
             (keyboard->withShift() != False)){
          break;
        }
        if (_key_input_disable != False){
          break;
        }
        WSCushort tmp[2];
        tmp[0] = (WSCushort)' ';
        tmp[1] = 0;
        newstr = WSGFinsertStringUCS2(_ucs2,_cur_pos,tmp);
        _set_text(newstr);
        _fep_cursor_adjust(keyboard);
        break;
      case WSK_Tab:
        _reset_select_string();
        if (keyboard->withShift() != False){
          if (_enable_focus_move != False){
            target = getFocusMoveInstance(WS_STAB);
            if (target != NULL && target != (WSCbase*)this &&
              target->cast("WSCvifield") != NULL){
              target->setPropertyV(WSNcursorPos,(short)0);
            }
            if (target != NULL ){
              target->setFocus();
              target->draw();
            }
          }
        }else{
          if (_enable_focus_move != False){
            target = getFocusMoveInstance(WS_TAB);
            if ( target != NULL && target != (WSCbase*)this &&
              target->cast("WSCvifield") != NULL){
              target->setPropertyV(WSNcursorPos,(short)0);
            }
            if (target != NULL ){
              target->setFocus();
              target->draw();
            }
          }
        }
        break;
    }
  }else{
    WSCstring* istr1 = keyboard->getTextString();
//printf("keyboard->getTextString()=%s\n",istr1->getString());
    WSCushort* istr = WSGFgetUCS2(istr1->getString(WS_EN_UTF8),WS_EN_UTF8);
    WSCushort tmp[2];
    tmp[0] = '\n';
    tmp[1] = 0;
    if (key == WSK_Return ){
      istr = WSGFstrdupUCS2(tmp);
    }else{
      WSGFdelLineFeedUCS2(istr);
    }
    if (((key == WSK_C || key == WSK_c) && keyboard->withCntl() != False) ||
         (key == WSK_Insert && keyboard->isTtyFunction() != False
                            && keyboard->withCntl() != False)){
      long pos1 = _select_pos1;
      long pos2 = _select_pos2;
      if (pos1 > pos2){
        pos2 = _select_pos1;
        pos1 = _select_pos2;
      }
      if (pos1 != pos2){
        WSCushort* sstr = new WSCushort[pos2-pos1+1];
        memcpy(sstr,&_ucs2[pos1],sizeof(WSCushort)*(pos2-pos1+1));
        sstr[pos2-pos1]=0;
        WSGIappDev()->setSelectionOwner(this);
        char* sstr2 = WSGFgetString(sstr,WS_EN_UTF8); 
        WSGIappKeyboard()->setSelectedString(sstr2,WS_EN_UTF8);
        delete sstr;
        delete sstr2;
      }
    }else
    if (((key == WSK_V || key == WSK_v) && keyboard->withCntl() != False) || 
         (key == WSK_Insert && keyboard->isTtyFunction() != False
                            && keyboard->withShift() != False)){
      char* istr0 = WSGIappKeyboard()->getSelectedString(WS_EN_UTF8);
//printf("paste=#%s#\n",istr0);
      WSCushort* istr2 = WSGFgetUCS2(istr0,WS_EN_UTF8);
      _replace_string(istr2);
      _fep_cursor_adjust(keyboard);
      _update_text();
      delete istr2;
    }else{
      if (_key_input_disable == False && istr[0] != 0){
        _replace_string(istr);
        _fep_cursor_adjust(keyboard);
        _update_text();
      }
    }
    delete istr; 
  }

  setCursorFore(True);
  setAbsoluteDraw(True);
  if (refresh == False){
    draw();
  }else{
    redraw();
  }
#ifdef TDBG
  printf("WSCvifield::_on_key_input done. %d\n",WSGFclocktime());
#endif
}
void WSCvifield::replaceSelectedString(char* istr,long encode){
  WSCushort* istr2 = WSGFgetUCS2(istr,encode);
  _replace_string(istr2); 
  delete istr2;
}
void WSCvifield::deleteSelectedString(){
  _delete_select_string();
  _update_text();
}
WSCstring WSCvifield::getSelectedString(){
  WSCstring tmp;
  if (_select_pos1 == _select_pos2){
    return tmp;
  }
  long pos1 = _select_pos1;
  long pos2 = _select_pos2;
  if (pos1 > pos2){
    pos2 = _select_pos1;
    pos1 = _select_pos2;
  }
  WSCushort* str = WSGFstrdupUCS2(_ucs2);
  str[pos2] = 0;
  WSGFdelStringUCS2(str,0,pos1);
  char* str2 = WSGFgetString(str,WS_EN_UTF8);
  tmp.setString(str2,WS_EN_UTF8);
  delete str;
  delete str2;
  return tmp;
}
void WSCvifield::_replace_string(WSCushort* istr){
  if (_ucs2 == NULL){
    _ucs2 = WSGFstrdupUCS2(istr);
    _text_changed = True;
    _update_text();
    _cur_pos = WSGFstrlenUCS2(istr);
  }else
  if (_ucs2[0] == 0){
    delete _ucs2;
    _ucs2 = WSGFstrdupUCS2(istr);
    _text_changed = True;
    _update_text();
    _cur_pos = WSGFstrlenUCS2(istr);
  }else{
    _delete_select_string();
    if (_icursor == False){
      WSGFdelStringUCS2(_ucs2,_cur_pos,1);
    }
    WSCushort* newstr = WSGFinsertStringUCS2(_ucs2,_cur_pos,istr);
    _set_text(newstr);
    _cur_pos += WSGFstrlenUCS2(istr);
  }
  if (_enable_max != False && _cur_pos >= _max_length - !_icursor){
    _cur_pos = _max_length - !_icursor;
    if (_skip_mode != False){
      if (_cursor_move(WS_RIGHT) != WS_NO_ERR){
        if (_enable_focus_move != False){
          WSCbase* target = getFocusMoveInstance(WS_RIGHT);
          if ( target != NULL && target != (WSCbase*)this &&
               target->cast("WSCvifield") != NULL){
            target->setPropertyV(WSNcursorPos,(short)0);
          }
          if (target != NULL ){
            target->setFocus();
            target->draw();
          }
        }
      }
    }
  }
}
void WSCvifield::_get_cur_pos(long* cx,long* cy,long* cpos){
#ifdef TDBG
  printf("WSCvifield::_get_cur_pos  start  -------    %d\n",WSGFclocktime());
#endif
  if (_multi_lines == False){
    *cx = _cur_pos;
    *cy = 0;
    *cpos = _cur_pos;
  }else{
    long pos = _cur_pos;
    WSCstring str( _label_string );

    long lnum = str.getWords("\n");
    long i;
    long line = 0;
    long curpos = 0;
    for(i=0; i< lnum; i++){
      long lpos = str.getWordCharPos(i,"\n");
    
      if (pos < lpos){
        line = i;
        if (i != 0){
          curpos =  pos - str.getWordCharPos(i-1,"\n");
        }else{
          curpos = pos - lpos;
        }
        break;
      }
    }
    *cx = curpos;
    *cy = line;
  }
#ifdef TDBG
  printf("WSCvifield::_get_cur_pos  done.  -------    %d\n",WSGFclocktime());
#endif
}
WSCbool WSCvifield::_return_key_ok(){
  if (_multi_lines != False){
    return True;
  }else{
    return False;
  }
}
void WSCvifield::_adjust_cbase(){
  if (_ucs2 == NULL){
    _cbase = 0;
    return;
  }
  if (_multi_lines == False){
    if ((long)((long)_cur_pos - (long)_cbase) < 0 ){
       _cbase = _cur_pos;
       return;
    }
    if (_w > _shadow_thick *2 + _margin_left + _margin_right){
      long width = _w -( _shadow_thick *2 + _margin_left + _margin_right);
      WSDfont* font = WSGIappFontSet()->getFont(_font);
      WSCushort* tmp = WSGFstrdupUCS2(_ucs2);
      long len = WSGFstrlenUCS2(_ucs2);
      tmp[_cur_pos] = 0;
      while(1){
        long strw = font->getStringWidthUCS2(&tmp[_cbase]);
        if (strw > width){
          _cbase++;
        }else{
          break;
        }
        if (_cbase >= len){
          _cbase = len;
          break;
        }
      }
      delete tmp;
    }
  }
}
#if 0
WSCushosrt* WSCvifield::_get_disp_string(){
  if (_multi_lines == False){
    WSCbushort* ret = WSGFstrdupUCS2(_ucs2);
    if (_cbase != 0){
      WSGFdelStringUCS2(_ucs2,0,_cbase);
    }
    WSCushort columns = _columns;
    if (columns == 0){
      if (_w > _shadow_thick *2 + _margin_left + _margin_right){
        WSDfont* font = WSGIappFontSet()->getFont(_font);
        WSCstring tmp("H");
        columns = (_w - _shadow_thick *2 - _margin_left - _margin_right)/
              font->getStringWidth(&tmp);
      }
      if (columns < 1){
        columns = 1;
      }
    }
    _str_work.cut_string(columns);
  }else{
    _str_work.setString( _label_string );
  }
  return &_str_work; 
}
#endif
void WSCvifield::_fep_cursor_adjust(WSDkeyboard* keyboard){
#ifdef TDBG
  printf("WSCvifield::_fep_cursor_adjust start %d\n",WSGFclocktime());
#endif
  long ox,oy;
  if (getowndev() != NULL){
    if (_multi_lines == False){
      _get_disp_cur_pos(&ox,&oy);
      keyboard->setFepPos(getowndev(),ox + _x,oy + _y,_font,_fore_color,
                          _back_color);
    }else{
      _get_disp_cur_pos(&ox,&oy);
      keyboard->setFepPos(getowndev(),_shadow_thick + ox + _x - _mx,
                          _shadow_thick + oy + _y - _my,_font,
                          _fore_color,_back_color);
    }
  }
#ifdef TDBG
  printf("WSCvifield::_fep_cursor_adjust done %d\n",WSGFclocktime());
#endif
}

void WSCvifield::onFocusChange(WSCbool fl){
  if (getSensitive() == False && fl != False){
    return;
  }
  if (fl == False && _use_pix == False && _dev != NULL){
    char fl = False;
    _dev->setValue(WSDEV_USE_PIXMAP,&fl);
  }
  if (fl != False){
    WSGIappKeyboard()->setFocusInputWorkProc(_key_handler,NULL,this);
    if (_return_key_focus != False){
      WSGIappKeyboard()->setSpecialInputWorkProc(_special_key_handler,this);
      setSpecialFocus(True);
    }
    if (_kanji_in == False){
      WSGIappKeyboard()->setEnableFep(getowndev(),False);
    }else{
      WSGIappKeyboard()->setEnableFep(getowndev(),True);
    }
    if (_cur_timer_id != 0){
WSMFtrace("WSCvifiled::onFocusChange(%d)   _cur_timer_id ERROR!!!!\n",fl);
    }else{
      _cur_timer_id = WSGIappTimer()->addTimerProc(_cursor_blink_handler,WS500MS,this);
      setCursorFore(True);
    }
    _fep_cursor_adjust(WSGIappKeyboard());

    if (_kanji_in != False && _fep_set_focus != False){
      _fep_set_focus = False;
      long ox,oy;
      if (_multi_lines == False){
        _get_disp_cur_pos(&ox,&oy);
        WSGIappKeyboard()->startKanji(getowndev(),ox + _x,oy + _y,_font,_fore_color,
                          _back_color);
      }else{
        _get_disp_cur_pos(&ox,&oy);
        WSGIappKeyboard()->startKanji(getowndev(),_shadow_thick + ox + _x - _mx,
                          _shadow_thick + oy + _y - _my,_font,
                          _fore_color,_back_color);
      }
    }

  }else{
    WSGIappKeyboard()->resetFocusInputWorkProc();
    WSGIappTimer()->delTimerProc( _cur_timer_id );
    _cur_timer_id = 0;
    setCursorFore(False);
    if (_return_key_focus != False){
      setSpecialFocus(False);
      WSGIappKeyboard()->resetSpecialInputWorkProc();
    }
  }
  setAbsoluteDraw(True);
  draw();

  if (fl == False && getowndev() != NULL){
    WSGIappKeyboard()->resetFep(getowndev());
  }
}
void WSCvifield::onSpecialFocusChange(WSCbool fl){
  if (fl == False){
    WSGIappKeyboard()->resetSpecialInputWorkProc();
  }else{
    WSGIappKeyboard()->setSpecialInputWorkProc(_special_key_handler,this);
  }
  WSCvlabel::onSpecialFocusChange(fl);
}
WSCbool WSCvifield::setCurPos(long pos){
  if (pos == -1){
    if (_enable_max != False ){
      pos = _max_length - !_icursor;
    }else{
      pos = 0;
    }
  }
  if (_enable_max != False && pos >= _max_length - !_icursor){
    pos = _max_length - !_icursor;
  }
  if (pos < -1){
    pos = 0;
  }
  _cur_pos = pos;
#if 0
  WSCstring str(_label_string);
  WSCbool on_kanji;
  str.columnToEucByte(pos,&on_kanji);
  if (on_kanji != False){
    if (_cur_pos > 0){
      _cur_pos--;
    }
  }
  if ( _icursor != False){
    if (_cur_pos > str.getColumn() ){
      _cur_pos = str.getColumn();
    } 
  } 
#endif
  _select_pos1 = _cur_pos;
  _select_pos2 = _cur_pos;
  return True;
}
void WSCvifield::_set_text(WSCushort* str){
  if (_ucs2 != NULL){
    delete _ucs2;
    _ucs2 = NULL;
  }
  if (str == NULL){
    _ucs2 = new WSCushort[1];
    _ucs2[0] = 0;
  }
  _ucs2 = str;
  _text_changed = True;
  _update_text();
}
void WSCvifield::_update_text(){
  if (_label_string != NULL){
    delete _label_string;
    _label_string = NULL;
  }
  if (_ucs2 == NULL){
    _ucs2 = new WSCushort[1];
    _ucs2[0] = 0;
  }
  WSCushort* bk = WSGFstrdupUCS2(_ucs2);
  _lines = -1;
  _reset_select_string();
  if (_multi_lines == False){
    WSCushort src[2];
    src[0] = (WSCushort)'\n';
    src[1] = 0;
    WSCushort dest[3];
    dest[0] = (WSCushort)'\\';
    dest[1] = (WSCushort)'n';
    dest[2] = 0;
    long num = 0;
    WSCushort* newstr = WSGFreplaceStringUCS2(_ucs2,src,dest,&num);
    delete _ucs2;
    _ucs2 = newstr;
  }else{
#if 0
    WSCushort src[3];
    src[0] = (WSCushort)'\\';
    src[1] = (WSCushort)'n';
    src[2] = 0;
    WSCushort dest[2];
    dest[0] = (WSCushort)'\n';
    dest[1] = 0;
    long num = 0;
    WSCushort* newstr = WSGFreplaceStringUCS2(_ucs2,src,dest,&num);
    delete _ucs2;
    _ucs2 = newstr;
#endif
  }
  _adjust_max_len();
  _fill_space();
  if ( _text_changed != False ||
       (WSGFstrlenUCS2(_ucs2) != WSGFstrlenUCS2(bk)) || 
       memcmp(_ucs2,bk,WSGFstrlenUCS2(_ucs2))){
    onValueChange();
  }
  _text_changed = False;
  delete bk;
  return;
}
void WSCvifield::onValueChange(){
  if (_data_source_clients != NULL){
    char* ptr = WSGFgetString(_ucs2,WS_EN_DEFAULT);
    WSCvariant val;
    val = ptr;
    delete ptr;
    setDataToDataSourceClients(&val);
  }
  execProcedure(WSEV_VALUE_CH);
}

WSCushort* WSCvifield::getBuf(){
  return _ucs2;
}
void WSCvifield::setBuf(WSCushort* buf){
  _set_text(buf);
}

void WSCvifield::addString(char* str,long encode){
  WSCushort* str2 = WSGFgetUCS2(str,encode);
  WSCushort* newstr = WSGFaddStringUCS2(_ucs2,str2);
  delete str2;
  _set_text(newstr);
}
long WSCvifield::setSelect(long pos,long len){
  if (pos == -1){
    return WS_ERR;
  }
  if (_enable_max != False && pos > _max_length){
    return WS_ERR;
  }
  if (pos < -1){
    return WS_ERR;
  }
  if (_enable_max != False && pos+len > _max_length){
    return WS_ERR;
  }
#if 0
  WSCstring str(_label_string);
  WSCbool on_kanji;
  str.columnToEucByte(pos,&on_kanji);
  if (on_kanji != False){
    if (pos > 0){
      pos--;
    }
  }
#endif
  if (pos+len > WSGFstrlenUCS2(_ucs2)){
    return WS_ERR;
  } 
  _cur_pos = pos;
  _select_pos1 = pos;
#if 0
  str.columnToEucByte(pos+len,&on_kanji);
  if (on_kanji != False){
    if (len > 0){
      len--;
    }
  }
#endif
  _select_pos2 = pos+len;
  WSCbool _cur_adjust_bk = _no_mcur_adjust;
  _no_mcur_adjust = False;
  _absolute_draw = True;
  WSCbool fl;
  getPropertyV(WSNblinkRefreshing,&fl);
  setAbsoluteDraw(True);
  if (fl == False){
    draw();
  }else{
    redraw();
  }
  _no_mcur_adjust = _cur_adjust_bk;
  return True;
}
long WSCvifield::getSelectedPos(){
  if (_select_pos1 > _select_pos2){
    return _select_pos2;
  }
  return _select_pos1;
}
void WSCvifield::onSelectionChange(WSCbool fl){
  if (_deleting != False){
    return;
  }
  if (fl == False){
    _reset_select_string();
    setAbsoluteDraw(True);
    WSCbool fl;
    getPropertyV(WSNblinkRefreshing,&fl);
    if (fl == False){
      draw();
    }else{
      redraw();
    }
  }
  WSCvlabel::onSelectionChange(fl);
}
WSCstring WSCvifield::getString(){
  WSCstring ret;
  if (_ucs2 == NULL){
    ret = "";
    return ret;
  }
  char* str = WSGFgetString(_ucs2,WS_EN_UTF8);
  ret.setString(str,WS_EN_UTF8);
  delete str;
  return ret;
}
void WSCvifield::setData(WSCvariant* val,long code){
  if (code == WS_EN_DEFAULT){
    WSCstring str;
    str.setString(val->getCharPtr(),code);
    setProperty(WSNlabelString,str.getString());
  }else{
    setProperty(WSNlabelString,val->getCharPtr());
  }
}
long WSCvifield::getDataSourceType(){
  return _data_source_type;
}
char* WSCvifield::getDataSourcePropertyName(){
  return WSNlabelString;
}
long WSCvifield::setFepStatus(WSCbool fl){
  if (_kanji_in == False){
    return WS_ERR;
  }
  if (getowndev() == NULL){
    if (fl != False){
      _fep_set_focus = True;
      return WS_NO_ERR;
    }
    return WS_ERR;
  }
  if (fl == False){
    WSGIappKeyboard()->resetFep(getowndev());
  }else{
    long ox,oy;
    if (_multi_lines == False){
      _get_disp_cur_pos(&ox,&oy);
      WSGIappKeyboard()->startKanji(getowndev(),ox + _x,oy + _y,_font,_fore_color,
                          _back_color);
    }else{
      _get_disp_cur_pos(&ox,&oy);
      WSGIappKeyboard()->startKanji(getowndev(),_shadow_thick + ox + _x - _mx,
                          _shadow_thick + oy + _y - _my,_font,
                          _fore_color,_back_color);
    }
  }
  return WS_NO_ERR;
}
void WSCvifield::update(){
  if (_need_ds_update != False){
    _need_ds_update = False;
    _set_ds_instance();
  }
  WSCvlabel::update();
}
void WSCvifield::onVisibleChange(WSCbool fl){
  if (fl == False){
    if (getFocus() != False){
      setFocus(False);
    }
  }
  WSCvlabel::onVisibleChange(fl);
}
void WSCvifield::onParentVisibleChange(WSCbool fl){
//printf("WSCvifield::onParentVisibleChange %d\n",fl);
  if (fl == False){
    if (getFocus() != False){
//printf("WSCvifield::onParentVisibleChange setFocus False\n");
      setFocus(False);
    }
  }
  WSCvlabel::onParentVisibleChange(fl);
}
void WSCvifield::onWindowFocusChange(WSCbool fl){
  if (fl == False && _use_pix == False && _dev != NULL){
    char fl = False;
    _dev->setValue(WSDEV_USE_PIXMAP,&fl);
  }
  if (fl != False){
    WSGIappKeyboard()->setFocusInputWorkProc(_key_handler,NULL,this);
    if (_return_key_focus != False){
      WSGIappKeyboard()->setSpecialInputWorkProc(_special_key_handler,this);
    }
    if (_kanji_in == False){
      WSGIappKeyboard()->setEnableFep(getowndev(),False);
    }else{
      WSGIappKeyboard()->setEnableFep(getowndev(),True);
    }
    if (_cur_timer_id != 0){
WSMFtrace("WSCvifiled::onWindowFocusChange(%d)   _cur_timer_id ERROR!!!!\n",fl);
    }else{
      _cur_timer_id = WSGIappTimer()->addTimerProc(_cursor_blink_handler,WS500MS,this);
      setCursorFore(True);
    }
    _fep_cursor_adjust(WSGIappKeyboard());

    if (_kanji_in != False && _fep_set_focus != False){
      _fep_set_focus = False;
      long ox,oy;
      if (_multi_lines == False){
        _get_disp_cur_pos(&ox,&oy);
        WSGIappKeyboard()->startKanji(getowndev(),ox + _x,oy + _y,_font,_fore_color,
                          _back_color);
      }else{
        _get_disp_cur_pos(&ox,&oy);
        WSGIappKeyboard()->startKanji(getowndev(),_shadow_thick + ox + _x - _mx,
                          _shadow_thick + oy + _y - _my,_font,
                          _fore_color,_back_color);
      }
    }

  }else{
    WSGIappKeyboard()->resetFocusInputWorkProc();
    WSGIappTimer()->delTimerProc( _cur_timer_id );
    _cur_timer_id = 0;
    setCursorFore(False);
    if (_return_key_focus != False){
      WSGIappKeyboard()->resetSpecialInputWorkProc();
    }
  }
  setAbsoluteDraw(True);
  draw();

  if (fl == False && getowndev() != NULL){
    WSGIappKeyboard()->resetFep(getowndev());
  }
}
