//
// Copyright (C) 1999-2002 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 <win/WSDwinKeyboard.h>
#include <windows.h>
#include <win/WSDwinfont.h>
#include <WSDcolor.h>
#include <win/WSDwinAppDev.h>
#include <WSDmouse.h>
#include <WSCbase.h>
#include <WSCcolorSet.h>
#include <WSCfontSet.h>
#include <WSClocaleSet.h>

WSMFclassInit(WSDwinKeyboard,WSDkeyboard);


WSDwinKeyboard* WSGIwinKeyboard(){
  WSDkeyboard* keybd = WSGIappKeyboard();
  if (keybd == NULL){
    return NULL;
  }
  WSDwinKeyboard* xkeybd =(WSDwinKeyboard*)keybd->cast("WSDwinKeyboard");
  return xkeybd;
}

WSDkeyboard* _winKeyboard_create_handler(){
  WSDkeyboard* keybd =  new WSDwinKeyboard();
  keybd->initialize();
  return keybd;
}

class _winKeyboard_init{
  public: _winKeyboard_init(){
    WSDkeyboard::setCreateInstanceHandler(_winKeyboard_create_handler);
  };
};
_winKeyboard_init _winKeyboard_init_execute;

WSDwinKeyboard::WSDwinKeyboard(){
  _hwnd = 0;
  _himc = 0;
  _font_no = -1;
  _fep_on = 0;
  _pos = 0;
}

WSDwinKeyboard::~WSDwinKeyboard(){
  if (_hwnd != 0){
    ImmAssociateContext(_hwnd,0);
    _hwnd = 0;
  }
  if (_himc != 0){
    ImmDestroyContext(_himc);
    _himc = 0;
  }
}

long WSDwinKeyboard::initialize(){
  _himc = ImmCreateContext();
  setSelectedString("");
  return WS_NO_ERR;
}

long WSDwinKeyboard::startKanji(WSDdev* dev,short x,short y,short fontno,short fgno,short bgno){
  HWND wnd = (HWND)dev->getWindowResource();
  if (wnd == NULL || wnd == (HWND)-1){
    return WS_ERR;
  }
  SetFocus(wnd);
  if (_hwnd != wnd){
    if (_hwnd != NULL){
      ImmAssociateContext(_hwnd,0);
    }
    _hwnd = wnd;
    ImmAssociateContext(_hwnd,_himc);
  }
  ImmSetOpenStatus(_himc, TRUE);
  DWORD conversion = IME_CMODE_ROMAN | IME_CMODE_NATIVE | IME_CMODE_FULLSHAPE;
  DWORD sentence = IME_SMODE_PHRASEPREDICT;
  ImmSetConversionStatus(_himc,conversion,sentence);


  short sx,sy;
  dev->getAbsoluteAddr(x,y,&sx,&sy);
  dev->setAbsoluteAddrChangeHandler(_device_move_handler,this);
  
  COMPOSITIONFORM cf;
  cf.dwStyle = CFS_POINT;
  cf.ptCurrentPos.x = sx;
  cf.ptCurrentPos.y = sy;
  ImmSetCompositionWindow(_himc,&cf);
  if (fontno != _font_no){
    WSDfont* fn = WSGIappFontSet()->getFont(fontno);
    if (fn == NULL){
      fn = WSGIappFontSet()->getDefaultFont();
    }
    if (fn != NULL){
      WSDwinfont* wfont = (WSDwinfont*)fn->cast("WSDwinfont");
      if (wfont != NULL){
        LOGFONT* lf = wfont->getLogFont();
        ImmSetCompositionFont(_himc,lf);
        _font_no = fontno;
      }
    }
  }
  _fep_on = True;
  return WS_NO_ERR;
}

long WSDwinKeyboard::startAscii(WSDdev* dev,short ,short ,short ,short ,short ){
  HWND wnd = (HWND)dev->getWindowResource();
  if (wnd == NULL || wnd == (HWND)-1){
    return WS_ERR;
  }
  SetFocus(wnd);
  resetFep(dev);
  return WS_NO_ERR;
}


long WSDwinKeyboard::resetFep(WSDdev* dev){
  HWND wnd = (HWND)dev->getWindowResource();
  if (wnd == NULL || wnd == (HWND)-1){
    return WS_ERR;
  }
  if (_hwnd != wnd){
    if (_hwnd != NULL){
      ImmAssociateContext(_hwnd,0);
    }
    _hwnd = wnd;
    ImmAssociateContext(_hwnd,_himc);
  }
  ImmSetOpenStatus(_himc, FALSE);
  _fep_on = False;

  return WS_NO_ERR;
}

WSDdev* _fep_dev = NULL;
short _fep_pos_x = -1;
short _fep_pos_y = -1;
short _fep_font_no = -1;
short _fep_fg_no = -1;
short _fep_bg_no = -1;

long WSDwinKeyboard::setFepPos(WSDdev* dev,short x,short y,short fontno,short fgno,short bgno){
WSMFtrace("WSDwinKeyboard::setFepPos x,y=%d,%d\n",x,y);
//printf("WSDwinKeyboard::setFepPos x,y=%d,%d\n",x,y);
  HWND wnd = (HWND)dev->getWindowResource();
  if (wnd == NULL || wnd == (HWND)-1){
    return WS_ERR;
  }
  SetFocus(wnd);
  if (_hwnd != wnd){
    if (_hwnd != NULL){
      ImmAssociateContext(_hwnd,0);
    }
    _hwnd = wnd;
    ImmAssociateContext(_hwnd,_himc);
  }

  short sx,sy;
  dev->getAbsoluteAddr(x,y,&sx,&sy);
  dev->setAbsoluteAddrChangeHandler(_device_move_handler,this);
  
  COMPOSITIONFORM cf;
  cf.dwStyle = CFS_POINT;
  cf.ptCurrentPos.x = sx;
  cf.ptCurrentPos.y = sy;
  ImmSetCompositionWindow(_himc,&cf);
  _fep_dev = dev;
  _fep_pos_x = x;
  _fep_pos_y = y;
  _fep_font_no = fontno;
  _fep_fg_no = fgno;
  _fep_bg_no = bgno;
WSMFtrace("WSDwinKeyboard::setFepPos()  fontno=%d fno=%d\n",fontno,_font_no);
//printf("WSDwinKeyboard::setFepPos()  fontno=%d fno=%d\n",fontno,_font_no);
  if (fontno != _font_no){
    WSDfont* fn = WSGIappFontSet()->getFont(fontno);
    if (fn == NULL){
      fn = WSGIappFontSet()->getDefaultFont();
    }
    if (fn != NULL){
      WSDwinfont* wfont = (WSDwinfont*)fn->cast("WSDwinfont");
      if (wfont != NULL){
        LOGFONT* lf = wfont->getLogFont();
WSMFtrace("WSDwinKeyboard::setFepPos() setfl=0x%x\n",lf);
        ImmSetCompositionFont(_himc,lf);
        _font_no = fontno;
      }
    }
  }
  return WS_NO_ERR;
}

WSCbool WSDwinKeyboard::_dispatch_key(MSG* msg){
  if (msg->message == WM_KEYDOWN && msg->wParam ==VK_PROCESSKEY){
//printf("process key ev=%d\n",msg->message);
    if (WSGIappLocaleSet()->getSystemLocaleEncoding()==WS_EN_EUCKR &&
        _fep_dev != NULL && msg->message != WM_KEYUP){
      setFepPos(_fep_dev,_fep_pos_x,_fep_pos_y,_fep_font_no,_fep_fg_no,_fep_bg_no);
    }else
    if (WSGIappLocaleSet()->getSystemLocaleEncoding()==WS_EN_EUCCN &&
        _fep_dev != NULL && msg->message != WM_KEYUP){
      setFepPos(_fep_dev,_fep_pos_x,_fep_pos_y,_fep_font_no,_fep_fg_no,_fep_bg_no);
    }
    return False;
  }
//printf("here001 ev=%d code=0x%x\n",msg->message,msg->wParam);
  if (msg->message == WM_CHAR || msg->message == WM_SYSCHAR){
    setIsPressed(True);
//printf("here001 code=0x%x\n",msg->wParam);
    if (GetKeyState(VK_CONTROL) <0){
      if (msg->message == WM_CHAR ){
//printf("here001 return..1\n");
        return True;
      }
      return False;
    }
    if (msg->wParam == VK_CANCEL ||
        msg->wParam == VK_BACK ||
        msg->wParam == VK_TAB ||
        msg->wParam == VK_RETURN ||
        msg->wParam == VK_ESCAPE ){
      return False;
    }
    if (msg->wParam != VK_CANCEL &&
        msg->wParam != VK_BACK &&
        msg->wParam != VK_TAB &&
        msg->wParam != VK_RETURN &&
        msg->wParam != VK_ESCAPE ){
      if (_pos == 0){
        _buf[_pos] = (char)msg->wParam;
        _buf[_pos+1] = 0;
        if ((((msg->wParam >= 0x80 && msg->wParam < 0xa0 ) ||
             msg->wParam > 0xdf) && 
        WSGIappLocaleSet()->getSystemLocaleEncoding()==WS_EN_SJIS) ||
        ((msg->wParam & 0x80 && msg->wParam < 0xff) && 
        WSGIappLocaleSet()->getSystemLocaleEncoding()==WS_EN_EUCKR) ||
        ((msg->wParam & 0x80 && msg->wParam < 0xff) && 
        WSGIappLocaleSet()->getSystemLocaleEncoding()==WS_EN_EUCCN)){
          _pos = 1;
//printf("here001 return..2\n");
          setKey(0);
          return True;
        }else{
WSMFtrace("key pressed key=#%s#  XXZZk1 xx\n",_buf);
//printf("key pressed key=#%s#  XXZZk1 xx\n",_buf);
          setText(_buf,WS_EN_LOCALE);
          _is_tty_function = False;
          if (_buf[0] == '!'){
            setKey(WSK_exclam);
          }else
          if (_buf[0] == '"'){
            setKey(WSK_quotedbl);
          }else
          if (_buf[0] == '#'){
            setKey(WSK_numbersign);
          }else
          if (_buf[0] == '$'){
            setKey(WSK_dollar);
          }else
          if (_buf[0] == '%'){
            setKey(WSK_percent);
          }else
          if (_buf[0] == '&'){
            setKey(WSK_ampersand);
          }else
          if (_buf[0] == '\''){
            setKey(WSK_apostrophe);
          }else
          if (_buf[0] == ')'){
            setKey(WSK_parenright);
          }else
          if (_buf[0] == '('){
            setKey(WSK_parenleft);
          }else
          if (_buf[0] == '*'){
            setKey(WSK_asterisk);
          }else
          if (_buf[0] == '+'){
            setKey(WSK_plus);
          }else
          if (_buf[0] == '-'){
            setKey(WSK_minus);
          }else
          if (_buf[0] == ','){
            setKey(WSK_comma);
          }else
          if (_buf[0] == '.'){
            setKey(WSK_period);
          }else
          if (_buf[0] == '/'){
            setKey(WSK_slash);
          }else
          if (_buf[0] == ':'){
            setKey(WSK_colon);
          }else
          if (_buf[0] == ';'){
            setKey(WSK_semicolon);
          }else
          if (_buf[0] == '<'){
            setKey(WSK_less);
          }else
          if (_buf[0] == '>'){
            setKey(WSK_greater);
          }else
          if (_buf[0] == '='){
            setKey(WSK_equal);
          }else
          if (_buf[0] == '?'){
            setKey(WSK_question);
          }else
          if (_buf[0] == '@'){
            setKey(WSK_at);
          }else
          if (_buf[0] == '['){
            setKey(WSK_bracketleft);
          }else
          if (_buf[0] == ']'){
            setKey(WSK_bracketright);
          }else
          if (_buf[0] == '\\'){
            setKey(WSK_backslash);
          }else
          if (_buf[0] == '_'){
            setKey(WSK_underscore);
          }else
          if (_buf[0] == '^'){
            setKey(WSK_asciicircum);
          }else
          if (_buf[0] == '`'){
            setKey(WSK_quoteleft);
          }else
          if (_buf[0] == '{'){
            setKey(WSK_braceleft);
          }else
          if (_buf[0] == '}'){
            setKey(WSK_braceright);
          }else
          if (_buf[0] == '|'){
            setKey(WSK_bar);
          }else
          if (_buf[0] == '~'){
            setKey(WSK_asciitilde);
          }else
          if (_buf[0] > '0' -1 && _buf[0] < '9' +1){
            setKey(WSK_0 + _buf[0] - '0');
          }else
          if (_buf[0] > 'a' -1 && _buf[0] < 'z' +1){
            setKey(WSK_a + _buf[0] - 'a');
          }else
          if (_buf[0] > 'A' -1 && _buf[0] < 'Z' +1){
            setKey(WSK_A + _buf[0] - 'A');
          } 
#if 0
          if ( msg->wParam == WSK_Left ||
               msg->wParam == WSK_Up ||
               msg->wParam == WSK_Right ||
               msg->wParam == WSK_Down ){
            _is_cursor = True;
          }else{
            _is_cursor = False;
          }
#endif
          if (msg->wParam > VK_F1 -1 && msg->wParam < VK_F12 +1){
            _is_function = True;
          }else{
            _is_function = False;
          }
        }
      }else{
//        if(getEnableFep() != False){
          _buf[_pos] = (char)msg->wParam;
          _buf[_pos+1] = 0;
//        }else{
//          _buf[0] = 0;
//        }
WSMFtrace("key pressed key=#%s#  XXZZk1 xx2\n",_buf);
//printf("key pressed2 key=#%s#  XXZZk1 xx2 pos=%d\n",_buf,_pos);
        setText(_buf,WS_EN_LOCALE);
        _pos = 0;
        _is_tty_function = False;
        _is_cursor = False;
        _is_function = False;
      }
WSMFtrace("key pressed getkey=0x%x  XXZZk1\n",getKey());
#if 0
      setKey((long) msg->wParam);
#endif      
      _with_cntl = False;
      if (GetKeyState(VK_MENU) < 0){
        _with_alt = True;
      }else{
        _with_alt = False;
      }
      if (GetKeyState(VK_SHIFT) < 0){
        _with_shift = True;
      }else{
        _with_shift = False;
      }
WSMFtrace("key pressed shift=%d alt=%d XXZZk1\n",_with_shift,_with_alt);
//printf("key pressed executed.. shift=%d alt=%d XXZZk1\n",_with_shift,_with_alt);

      WSCbool executed = executeHandler(True);
      if (executed != False){
        return False;
      }else{
        return True;
      }
    }
  }else if (msg->message == WM_KEYDOWN){
    setIsPressed(True);
//printf("keydown key=0x%x  encode=%d\n",msg->wParam,WSGIappLocaleSet()->getSystemLocaleEncoding());
//printf("here01 0x%x 0x%x\n",msg->wParam,msg->lParam);
WSMFtrace("key down setkey=0x%x  XXZZk141\n",msg->wParam);
    if (GetKeyState(VK_CONTROL) < 0){
WSMFtrace("key pressed key=#%s#  XXZZk12\n",_buf);
      long key1 = (long)msg->wParam;
//printf("key1=0x%x %d\n",key1,key1);
      if ( msg->wParam == VK_LEFT ||
           msg->wParam == VK_RIGHT ||
           msg->wParam == VK_UP ||
           msg->wParam == VK_DOWN ||
           msg->wParam == VK_BACK ||
           msg->wParam == VK_RETURN ||
           msg->wParam == VK_SHIFT ||
           msg->wParam == VK_MENU ||
           msg->wParam == VK_ESCAPE ||
           msg->wParam == VK_INSERT ||
           msg->wParam == VK_DELETE ||
           msg->wParam == VK_TAB ||
           msg->wParam == VK_CANCEL ||
           msg->wParam == VK_PRIOR ||
           msg->wParam == VK_CLEAR ||
           msg->wParam == VK_NEXT ||
           msg->wParam == VK_END ||
           msg->wParam == VK_HOME ||
           msg->wParam == VK_PAUSE ||
           msg->wParam == VK_CAPITAL ||
           msg->wParam == VK_NUMLOCK ||
           msg->wParam == VK_SCROLL ||
           msg->wParam == VK_SNAPSHOT ||
           (msg->wParam > VK_F1 -1 && msg->wParam < VK_F12 +1)){
        long key1 = (long)msg->wParam;
//printf("key2=0x%x %d\n",key1,key1);
        setKey(key1);
      }else
      if (key1 == '!'){
        setKey(WSK_exclam);
      }else
      if (key1 == '"'){
        setKey(WSK_quotedbl);
      }else
      if (key1 == '#'){
        setKey(WSK_numbersign);
      }else
      if (key1 == '$'){
        setKey(WSK_dollar);
      }else
      if (key1 == '%'){
        setKey(WSK_percent);
      }else
      if (key1 == '&'){
        setKey(WSK_ampersand);
      }else
      if (key1 == '\''){
        setKey(WSK_apostrophe);
      }else
      if (key1 == ')'){
        setKey(WSK_parenright);
      }else
      if (key1 == '('){
        setKey(WSK_parenleft);
      }else
      if (key1 == '*'){
        setKey(WSK_asterisk);
      }else
      if (key1 == '+'){
        setKey(WSK_plus);
      }else
      if (key1 == '-'){
        setKey(WSK_minus);
      }else
      if (key1 == ','){
        setKey(WSK_comma);
      }else
      if (key1 == '.'){
        setKey(WSK_period);
      }else
      if (key1 == '/'){
        setKey(WSK_slash);
      }else
      if (key1 == ':'){
        setKey(WSK_colon);
      }else
      if (key1 == ';'){
        setKey(WSK_semicolon);
      }else
      if (key1 == '<'){
        setKey(WSK_less);
      }else
      if (key1 == '>'){
        setKey(WSK_greater);
      }else
      if (key1 == '='){
        setKey(WSK_equal);
      }else
      if (key1 == '?'){
        setKey(WSK_question);
      }else
      if (key1 == '@'){
        setKey(WSK_at);
      }else
      if (key1 == '['){
        setKey(WSK_bracketleft);
      }else
      if (key1 == ']'){
        setKey(WSK_bracketright);
      }else
      if (key1 == '\\'){
        setKey(WSK_backslash);
      }else
      if (key1 == '_'){
        setKey(WSK_underscore);
      }else
      if (key1 == '^'){
        setKey(WSK_asciicircum);
      }else
      if (key1 == '`'){
        setKey(WSK_quoteleft);
      }else
      if (key1 == '{'){
        setKey(WSK_braceleft);
      }else
      if (key1 == '}'){
        setKey(WSK_braceright);
      }else
      if (key1 == '|'){
        setKey(WSK_bar);
      }else
      if (key1 == '~'){
        setKey(WSK_asciitilde);
      }else
      if (key1 > '0' -1 && key1 < '9' +1){
        setKey(WSK_0 + key1 - '0');
      }else
      if (key1 == VK_CAPITAL){
        GetKeyState(VK_CAPITAL);
        setKey(key1);
      }else
      if (key1 > 'A' -1 && key1 < 'Z' +1){
        if (GetKeyState(VK_SHIFT) < 0){
          if (GetKeyState(VK_CAPITAL) != 0){
            setKey(WSK_a + key1 - 'a'+ WSK_a - WSK_A);
          }else{
            setKey(WSK_A + key1 - 'A');
          }
        }else{
          if (GetKeyState(VK_CAPITAL) != 0){
            setKey(WSK_A + key1 - 'A');
          }else{
            setKey(WSK_a + key1 - 'a'+ WSK_a - WSK_A);
          }
        }
      }else{
        setKey(key1);
      }
WSMFtrace("key pressed setkey=0x%x  XXZZk12\n",msg->wParam);
//printf("key pressed executed2.. setkey=0x%x  #%s# encode=%d\n",msg->wParam,_buf,WSGIappLocaleSet()->getSystemLocaleEncoding());
      _buf[0] = 0;
      setText(_buf,WS_EN_LOCALE);
      _with_cntl = True;
      if (GetKeyState(VK_MENU) < 0){
        _with_alt = True;
      }else{
        _with_alt = False;
      }
      if (GetKeyState(VK_SHIFT) < 0){
        _with_shift = True;
      }else{
        _with_shift = False;
      }
      if (msg->wParam == VK_PRIOR || 
          msg->wParam == VK_NEXT || 
          msg->wParam == VK_END || 
          msg->wParam == VK_HOME || 
          msg->wParam == VK_LEFT || 
          msg->wParam == VK_RIGHT || 
          msg->wParam == VK_UP || 
          msg->wParam == VK_DOWN ){
        _is_cursor = True;
      }
      if (msg->wParam > VK_F1 -1 && msg->wParam < VK_F12 +1){
        _is_function = True;
      }else{
        _is_function = False;
      }
      if (msg->wParam == VK_INSERT || msg->wParam == VK_DELETE){
        _is_tty_function = True;
      }else{
        _is_tty_function = False;
      }
      WSCbool dispatched = executeHandler(True);
      if (dispatched != False){
        return False;
      }else{
        return True;
      }
    }else{
//printf("here0\n");
      if ( msg->wParam == VK_LEFT ||
           msg->wParam == VK_RIGHT ||
           msg->wParam == VK_UP ||
           msg->wParam == VK_DOWN ||
           msg->wParam == VK_BACK ||
           msg->wParam == VK_RETURN ||
           msg->wParam == VK_SHIFT ||
           msg->wParam == VK_MENU ||
           msg->wParam == VK_ESCAPE ||
           msg->wParam == VK_INSERT ||
           msg->wParam == VK_DELETE ||
           msg->wParam == VK_TAB ||
           msg->wParam == VK_CANCEL ||
           msg->wParam == VK_PRIOR ||
           msg->wParam == VK_CLEAR ||
           msg->wParam == VK_NEXT ||
           msg->wParam == VK_END ||
           msg->wParam == VK_HOME ||
           msg->wParam == VK_PAUSE ||
           msg->wParam == VK_CAPITAL ||
           msg->wParam == VK_NUMLOCK ||
           msg->wParam == VK_SCROLL ||
           msg->wParam == VK_SNAPSHOT ||
           (msg->wParam > VK_F1 -1 && msg->wParam < VK_F12 +1)){
        long key1 = (long)msg->wParam;
//printf("key2=0x%x %d\n",key1,key1);
        setKey(key1);
  
WSMFtrace("key pressed setkey=0x%x  XXZZk14\n",msg->wParam);
        _buf[0] = 0;
        setText(_buf,WS_EN_LOCALE);
        _with_cntl = False;
        if (GetKeyState(VK_MENU) < 0){
          _with_alt = True;
        }else{
          _with_alt = False;
        }
        if (GetKeyState(VK_SHIFT) < 0){
          _with_shift = True;
        }else{
          _with_shift = False;
        }
        if (msg->wParam == VK_PRIOR || 
            msg->wParam == VK_NEXT || 
            msg->wParam == VK_END || 
            msg->wParam == VK_HOME || 
            msg->wParam == VK_LEFT || 
            msg->wParam == VK_RIGHT || 
            msg->wParam == VK_UP || 
            msg->wParam == VK_DOWN ){
          _is_cursor = True;
        }
        if (msg->wParam > VK_F1 -1 && msg->wParam < VK_F12 +1){
          _is_function = True;
        }else{
          _is_function = False;
        }
        if (msg->wParam == VK_INSERT || msg->wParam == VK_DELETE){
          _is_tty_function = True;
        }else{
          _is_tty_function = False;
        }
//printf("executed3.. buf=#%s#\n",_buf);
        WSCbool dispatched = executeHandler(True);
        if (dispatched != False){
          return False;
        }else{
          return True;
        }
      }else{
        long key1 = (long)msg->wParam;
//printf("key3=0x%x %d\n",key1,key1);
        if (key1 == '!'){
          setKey(WSK_exclam);
        }else
        if (key1 == '"'){
          setKey(WSK_quotedbl);
        }else
        if (key1 == '#'){
          setKey(WSK_numbersign);
        }else
        if (key1 == '$'){
          setKey(WSK_dollar);
        }else
        if (key1 == '%'){
          setKey(WSK_percent);
        }else
        if (key1 == '&'){
          setKey(WSK_ampersand);
        }else
        if (key1 == '\''){
          setKey(WSK_apostrophe);
        }else
        if (key1 == ')'){
          setKey(WSK_parenright);
        }else
        if (key1 == '('){
          setKey(WSK_parenleft);
        }else
        if (key1 == '*'){
          setKey(WSK_asterisk);
        }else
        if (key1 == '+'){
          setKey(WSK_plus);
        }else
        if (key1 == '-'){
          setKey(WSK_minus);
        }else
        if (key1 == ','){
          setKey(WSK_comma);
        }else
        if (key1 == '.'){
          setKey(WSK_period);
        }else
        if (key1 == '/'){
          setKey(WSK_slash);
        }else
        if (key1 == ':'){
          setKey(WSK_colon);
        }else
        if (key1 == ';'){
          setKey(WSK_semicolon);
        }else
        if (key1 == '<'){
          setKey(WSK_less);
        }else
        if (key1 == '>'){
          setKey(WSK_greater);
        }else
        if (key1 == '='){
          setKey(WSK_equal);
        }else
        if (key1 == '?'){
          setKey(WSK_question);
        }else
        if (key1 == '@'){
          setKey(WSK_at);
        }else
        if (key1 == '['){
          setKey(WSK_bracketleft);
        }else
        if (key1 == ']'){
          setKey(WSK_bracketright);
        }else
        if (key1 == '\\'){
          setKey(WSK_backslash);
        }else
        if (key1 == '_'){
          setKey(WSK_underscore);
        }else
        if (key1 == '^'){
          setKey(WSK_asciicircum);
        }else
        if (key1 == '`'){
          setKey(WSK_quoteleft);
        }else
        if (key1 == '{'){
          setKey(WSK_braceleft);
        }else
        if (key1 == '}'){
          setKey(WSK_braceright);
        }else
        if (key1 == '|'){
          setKey(WSK_bar);
        }else
        if (key1 == '~'){
          setKey(WSK_asciitilde);
        }else
        if (key1 > '0' -1 && key1 < '9' +1){
          setKey(WSK_0 + key1 - '0');
        }else
        if (key1 > 'A' -1 && key1 < 'Z' +1){
          setKey(WSK_A + key1 - 'A');
        }else{
          setKey(key1);
        }
WSMFtrace("key pressed setkey=0x%x  XXZZk142\n",msg->wParam);
//printf("key pressed4 setkey=0x%x  XXZZk142\n",msg->wParam);
        if ( msg->wParam == WSK_Left ||
             msg->wParam == WSK_Up ||
             msg->wParam == WSK_Right ||
             msg->wParam == WSK_Down ){
          _is_cursor = True;
        }else{
          _is_cursor = False;
        }
        _with_cntl = False;
        if (GetKeyState(VK_MENU) < 0){
          _with_alt = True;
        }else{
          _with_alt = False;
        }
        if (GetKeyState(VK_SHIFT) < 0){
          _with_shift = True;
        }else{
          _with_shift = False;
        }
        if (msg->wParam > VK_F1 -1 && msg->wParam < VK_F12 +1){
          _is_function = True;
        }else{
          _is_function = False;
        }
        return True;
      }
    }
  }else if (msg->message == WM_KEYUP){
    setIsPressed(False);
    if (msg->wParam == VK_MENU){
      _with_alt = False;
    }
    if (msg->wParam == VK_SHIFT){
      _with_shift = False;
    }
    if (msg->wParam == VK_CONTROL){
      _with_cntl = False;
    }
    if (msg->wParam == VK_PRIOR || 
        msg->wParam == VK_NEXT || 
        msg->wParam == VK_END || 
        msg->wParam == VK_HOME || 
        msg->wParam == VK_LEFT || 
        msg->wParam == VK_RIGHT || 
        msg->wParam == VK_UP || 
        msg->wParam == VK_DOWN ){
      _is_cursor = False;
    }
    if (msg->wParam > VK_F1 -1 && msg->wParam < VK_F12 +1){
      _is_function = False;
    }
    if (msg->wParam == VK_INSERT || msg->wParam == VK_DELETE){
      _is_tty_function = False;
    }
    WSCbool dispatched = executeHandler(False);
    if (dispatched != False){
      return False;
    }else{
      return True;
    }
  }else if (msg->message == WM_SYSKEYDOWN){
    setIsPressed(True);
    long key1 = (long)msg->wParam;
//printf("key6=0x%x %d\n",key1,key1);
    if (key1 == '!'){
      setKey(WSK_exclam);
    }else
    if (key1 == '"'){
      setKey(WSK_quotedbl);
    }else
    if (key1 == '#'){
      setKey(WSK_numbersign);
    }else
    if (key1 == '$'){
      setKey(WSK_dollar);
    }else
    if (key1 == '%'){
      setKey(WSK_percent);
    }else
    if (key1 == '&'){
      setKey(WSK_ampersand);
    }else
    if (key1 == '\''){
      setKey(WSK_apostrophe);
    }else
    if (key1 == ')'){
      setKey(WSK_parenright);
    }else
    if (key1 == '('){
      setKey(WSK_parenleft);
    }else
    if (key1 == '*'){
      setKey(WSK_asterisk);
    }else
    if (key1 == '+'){
      setKey(WSK_plus);
    }else
    if (key1 == '-'){
      setKey(WSK_minus);
    }else
    if (key1 == ','){
      setKey(WSK_comma);
    }else
    if (key1 == '.'){
      setKey(WSK_period);
    }else
    if (key1 == '/'){
      setKey(WSK_slash);
    }else
    if (key1 == ':'){
      setKey(WSK_colon);
    }else
    if (key1 == ';'){
      setKey(WSK_semicolon);
    }else
    if (key1 == '<'){
      setKey(WSK_less);
    }else
    if (key1 == '>'){
      setKey(WSK_greater);
    }else
    if (key1 == '='){
      setKey(WSK_equal);
    }else
    if (key1 == '?'){
      setKey(WSK_question);
    }else
    if (key1 == '@'){
      setKey(WSK_at);
    }else
    if (key1 == '['){
      setKey(WSK_bracketleft);
    }else
    if (key1 == ']'){
      setKey(WSK_bracketright);
    }else
    if (key1 == '\\'){
      setKey(WSK_backslash);
    }else
    if (key1 == '_'){
      setKey(WSK_underscore);
    }else
    if (key1 == '^'){
      setKey(WSK_asciicircum);
    }else
    if (key1 == '`'){
      setKey(WSK_quoteleft);
    }else
    if (key1 == '{'){
      setKey(WSK_braceleft);
    }else
    if (key1 == '}'){
      setKey(WSK_braceright);
    }else
    if (key1 == '|'){
      setKey(WSK_bar);
    }else
    if (key1 == '~'){
      setKey(WSK_asciitilde);
    }else
    if (key1 > '0' -1 && key1 < '9' +1){
      setKey(WSK_0 + key1 - '0');
    }else
    if (key1 > 'A' -1 && key1 < 'Z' +1){
      setKey(WSK_A + key1 - 'A');
    }else{
      setKey(key1);
    }
WSMFtrace("key pressed XXZZk13 0x%x\n",getKey());
    if (msg->wParam > 0x1f && msg->wParam < 0x80){
      _buf[0] = (char)msg->wParam;
      _buf[1] = 0;
    }else{
      _buf[0] = 0;
    }
    if (GetKeyState(VK_MENU) < 0){
      _with_alt = True;
      setText(_buf,WS_EN_LOCALE);
    }else{
      _with_alt = False;
      _buf[0] = 0;
      setText(_buf,WS_EN_LOCALE);
    }
    if (GetKeyState(VK_SHIFT) < 0){
      _with_shift = True;
    }else{
      _with_shift = False;
    }
    if (GetKeyState(VK_CONTROL) < 0){
      _with_cntl = True;
    }else{
      _with_cntl = False;
    }
//    WSCbool dispatched = executeHandler(True);
    executeHandler(True);
    return False;
#if 0
    if (dispatched != False){
      return False;
    }else{
      return True;
    }
#endif
  }else if (msg->message == WM_SYSKEYUP){
    setIsPressed(False);
WSMFtrace("key released  XXZZk14 0x%x\n",msg->wParam);
    if (msg->wParam == VK_MENU){
      _with_alt = False;
    }
    if (msg->wParam == VK_SHIFT){
      _with_shift = False;
    }
    if (msg->wParam == VK_CONTROL){
      _with_cntl = False;
    }
    if (msg->wParam == VK_PRIOR || 
        msg->wParam == VK_NEXT || 
        msg->wParam == VK_END || 
        msg->wParam == VK_HOME || 
        msg->wParam == VK_LEFT || 
        msg->wParam == VK_RIGHT || 
        msg->wParam == VK_UP || 
        msg->wParam == VK_DOWN ){
      _is_cursor = False;
    }
    if (msg->wParam > VK_F1 -1 && msg->wParam < VK_F12 +1){
      _is_function = False;
    }
    if (msg->wParam == VK_INSERT || msg->wParam == VK_DELETE){
      _is_tty_function = False;
    }
//    WSCbool dispatched = executeHandler(False);
    executeHandler(False);
    return False;
#if 0
    if (dispatched != False){
      return False;
    }else{
      return True;
    }
#endif
  }
  return True;
}

void WSDwinKeyboard::_device_move_handler(WSDdev* dev,void*dt){
  WSDwinKeyboard* obj = (WSDwinKeyboard*)dt;
  if (obj->_fep_on == True){
    obj->startAscii(dev,0,0,0,0,0);
  }
}
void WSDwinKeyboard::setSelectedString(char* str,long encode){
  WSDkeyboard::setSelectedString(str,encode);
  WSCstring tmp(str,encode);
  char buf[3];
  buf[0] = 0x0d;
  buf[1] = 0x0a;
  buf[2] = 0;

  tmp.replaceString("\n",buf,0);
  OpenClipboard(WSGIwinAppDev()->getHWND());
WSMFtrace("WSDwinKeyboard::setSelectedString #%s#\n",str);
  long sysencode = WSGIappLocaleSet()->getSystemLocaleEncoding();
  HANDLE hmem = GlobalAlloc(GHND,strlen(tmp.getString(sysencode))+1);
  char* data = (char*)GlobalLock(hmem);
  strcpy(data,tmp.getString(sysencode));
  GlobalUnlock(hmem);
  EmptyClipboard();
  SetClipboardData(CF_TEXT,hmem);
  CloseClipboard();
}
char* WSDwinKeyboard::getSelectedString(long encode){
  OpenClipboard(WSGIwinAppDev()->getHWND());
  if (IsClipboardFormatAvailable(CF_TEXT)){
    HANDLE data = GetClipboardData(CF_TEXT);
    LPSTR lpData = (LPSTR)GlobalLock(data);
    long sysencode = WSGIappLocaleSet()->getSystemLocaleEncoding();
    WSCstring tmp(lpData,sysencode);
//printf("1#%s#\n",lpData);
    GlobalUnlock(data);
    char buf[3];
    buf[0] = 0x0d;
    buf[1] = 0x0a;
    buf[2] = 0;

    tmp.replaceString(buf,"\n",0);
//printf("2#%s#\n",tmp.getString(encode));
    WSDkeyboard::setSelectedString(tmp.getString(encode),encode);
    CloseClipboard();
    return WSDkeyboard::getSelectedString(encode);
  }else{
    CloseClipboard();
    return "";
  }
}
