//
// 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 <assert.h>
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/Xatom.h>
#include <X11/Shell.h>
#include <WSCbaseList.h>
#include <WSCbase.h>
#include <WSCdevice.h>
#include <WSCcolorSet.h>
#include <WSCfontSet.h>
#include <WSClocaleSet.h>
#include <x11/WSDxappDev.h>
#include <x11/WSDxkeyboard.h>
#include <x11/WSDxcodeConvert.h>
#include <WSCinitializeManager.h>
#include <WSDmouse.h>
#include <WSCdevice.h>
#include <x11/WSDxsocket.h>
#include <x11/WSDunixExecute.h>
#include <WSDfile.h>
#include <x11/WSDxdragDrop.h>
#include <x11/WSDxmessage.h>
#include <x11/WSDxmouse.h>
#include <x11/WSDxprivateTimer.h>
#include <x11/WSDxtimer.h>
#include <x11/WSDxsocket.h>
#include <x11/WSDunixThread.h>
#include <x11/WSDunixMutex.h>
#include <x11/WSDunixSemaphore.h>

#if 1 //UNICODE
#include <xunicode.h>
XUInfoDisplay *_info_disp = NULL;
#endif //UNICODE

int _ehandler(Display *d,XErrorEvent *e);
extern char *_err_strings[];

WSMFclassInit(WSDxappDev,WSDappDev);

WSDxappDev* WSGIxwinAppDev(){
  WSDappDev* appdev = WSGIappDev();
  if (appdev == NULL){
    return NULL;
  }
  WSDxappDev* xappdev =(WSDxappDev*)appdev->cast("WSDxappDev");
  return xappdev;
}

WSDappDev* _xappDev_create_handler(){
  return new WSDxappDev();
}

class _xappDev_init{
  public: _xappDev_init(){
    WSDappDev::setCreateInstanceHandler(_xappDev_create_handler);
  };
};

_xappDev_init _xappDev_init_run_constructor;

void WSGFdeviceInitialize(){
  static WSCbool initialized = False;
  if (initialized == False){
extern WSDfile* _unix_sem_chandler();
    WSDmutex::setCreateInstanceHandler((void*)_unix_sem_chandler);
extern WSDfile* _unix_mutex_chandler();
    WSDmutex::setCreateInstanceHandler((void*)_unix_mutex_chandler);
extern WSDfile* _unix_th_chandler();
    WSDthread::setCreateInstanceHandler((void*)_unix_th_chandler);
extern WSDfile* _unix_fp_chandler();
    WSDfile::setCreateInstanceHandler((void*)_unix_fp_chandler);
extern WSDdragDrop* _xdrag_drop_create_handler_();
    WSDdragDrop::setCreateHandler(_xdrag_drop_create_handler_);
extern WSDmessage* _xclient_msg_create();
    WSDmessage::setCreateHandler(_xclient_msg_create);
extern WSDmouse* _xmouse_create_handler();
    WSDmouse::setCreateInstanceHandler(_xmouse_create_handler);
extern WSDprivateTimer* _xprivatetimer_create();
    WSDprivateTimer::setCreateInstanceHandler((void*)_xprivatetimer_create);
extern WSDsocket* _xsocket_create_handler();
    WSDsocket::setCreateHandler(_xsocket_create_handler);
extern WSDtimer* _xtimer_create_handler();
    WSDtimer::setCreateInstanceHandler(_xtimer_create_handler);

extern WSDdev* _wsdxformdev_init_();
    WSGIappDevice()->setCreateHandler("formDev",_wsdxformdev_init_);
extern WSDdev* _wsdxwindev_init_();
    WSGIappDevice()->setCreateHandler("windowDev",_wsdxwindev_init_);
extern WSDdev* _wsdxnwdev_init_();
    WSGIappDevice()->setCreateHandler("nwDev",_wsdxnwdev_init_);
extern WSDdev* _wsdxscrdev_init_();
    WSGIappDevice()->setCreateHandler("scrFrameDev",_wsdxscrdev_init_);
extern WSDdev* _wsdxmwindev_init_();
    WSGIappDevice()->setCreateHandler("mwindowDev",_wsdxmwindev_init_);

extern WSDkeyboard* _xkeyboard_create_handler();
    WSDkeyboard::setCreateInstanceHandler(_xkeyboard_create_handler);

    WSDappDev::setCreateInstanceHandler(_xappDev_create_handler);
extern WSDcodeConvert* _code_convert_create_handler_();
    WSDcodeConvert::_set_code_convert_handler(_code_convert_create_handler_);
    WSGIappCodeConvert()->initialize();
    initialized = True;
extern void _xfont_init();
    _xfont_init();
extern void _xcolor_init();
    _xcolor_init();
extern void _ximage_init();
    _ximage_init();
    WSGIappInitializeManager()->execInitializeProcs();
  }
}
WSDxappDev::WSDxappDev(){
  _gc = 0;
  _gc2 = 0;
  _accept_atom_for_sock = 0;
  _read_event_for_execute = 0;
  _callback_event_for_thread = 0;
}
WSDxappDev::~WSDxappDev(){}

WSCushort WSDxappDev::getWidth(){
  return (WSCushort)DisplayWidth(display(),DefaultScreen(display()));
}
WSCushort WSDxappDev::getHeight(){
  return (WSCushort)DisplayHeight(display(),DefaultScreen(display()));
}

long WSDxappDev::getDeviceResource(){
  return (long)XtDisplay(appWidget());
}

long WSDxappDev::getWindowResource(){
  return (long)XtWindow(appWidget());
}

long WSDxappDev::getContextResource(){
  return 0;
}

long WSDxappDev::getSpecialResource(){
  return (long)appWidget();
}

long WSDxappDev::setInitPrm(int iprm,char** cprm){
   _iprm = iprm;
   _cprm = cprm;
   return WS_NO_ERR;
}

long WSDxappDev::loadGuiPolicy(){
  WSCstring* envstr = WSGFreadTextFile("$(HOME)/.wsrc");
  if (envstr != NULL){
    while(envstr->eof() == False){
      WSCstring index = envstr->gets();
      WSCstring data = envstr->gets();
      WSCstring data2;
      data2 = data;
      index.delHeadSpace();
      index.delTailSpace();
      index.delLineFeed();
      data.delHeadSpace();
      data.delTailSpace();
      data.delLineFeed();
      if (!strcmp((char*)index,"#POLICY") && strcmp((char*)data,"")){
        long val = atoi((char*)data);
        if (_policy == -1){
          setGuiPolicy(val,False);
        }
      }else
      if (!strcmp((char*)index,"#EXPOLICY") && strcmp((char*)data,"")){
        setExtGuiPolicy((char*)data,True);
      }else
      if (!strcmp((char*)index,"#TOPSHADOWCOLOR") && strcmp((char*)data,"")){
        short cno = WSGIappColorSet()->getColorNo((char*)data);
        WSGIappColorSet()->setDefaultColorNo(WS_DF_TOPSHADOWCOLOR,cno);
      }else
      if (!strcmp((char*)index,"#BOTTOMSHADOWCOLOR") && strcmp((char*)data,"")){
        short cno = WSGIappColorSet()->getColorNo((char*)data);
        WSGIappColorSet()->setDefaultColorNo(WS_DF_BOTTOMSHADOWCOLOR,cno);
      }else
      if (!strcmp((char*)index,"#BACKCOLOR") && strcmp((char*)data,"")){
        short cno = WSGIappColorSet()->getColorNo((char*)data);
        WSGIappColorSet()->setDefaultColorNo(WS_DF_BACKCOLOR,cno);
      }else
      if (!strcmp((char*)index,"#FORECOLOR") && strcmp((char*)data,"")){
        short cno = WSGIappColorSet()->getColorNo((char*)data);
        WSGIappColorSet()->setDefaultColorNo(WS_DF_FORECOLOR,cno);
      }else
      if (!strcmp((char*)index,"#MENUFORECOLOR") && strcmp((char*)data,"")){
        short cno = WSGIappColorSet()->getColorNo((char*)data);
        WSGIappColorSet()->setDefaultColorNo(WS_DF_MENUFORECOLOR,cno);
      }else
      if (!strcmp((char*)index,"#MENUBACKCOLOR") && strcmp((char*)data,"")){
        short cno = WSGIappColorSet()->getColorNo((char*)data);
        WSGIappColorSet()->setDefaultColorNo(WS_DF_MENUBACKCOLOR,cno);
      }else
      if (!strcmp((char*)index,"#MENUSELECTCOLOR") && strcmp((char*)data,"")){
        short cno = WSGIappColorSet()->getColorNo((char*)data);
        WSGIappColorSet()->setDefaultColorNo(WS_DF_MENUSELECTCOLOR,cno);
      }else
      if (!strcmp((char*)index,"#MENUTOPSHADOWCOLOR") && strcmp((char*)data,"")){
        short cno = WSGIappColorSet()->getColorNo((char*)data);
        WSGIappColorSet()->setDefaultColorNo(WS_DF_MENUTOPSHADOWCOLOR,cno);
      }else
      if (!strcmp((char*)index,"#MENUBOTTOMSHADOWCOLOR") && strcmp((char*)data,"")){
        short cno = WSGIappColorSet()->getColorNo((char*)data);
        WSGIappColorSet()->setDefaultColorNo(WS_DF_MENUBOTTOMSHADOWCOLOR,cno);
      }else
      if (!strcmp((char*)index,"#WORKBACKCOLOR") && strcmp((char*)data,"")){
        short cno = WSGIappColorSet()->getColorNo((char*)data);
        WSGIappColorSet()->setDefaultColorNo(WS_DF_WORKBACKCOLOR,cno);
      }else
      if (!strcmp((char*)index,"#DARKBACKCOLOR") && strcmp((char*)data,"")){
        short cno = WSGIappColorSet()->getColorNo((char*)data);
        WSGIappColorSet()->setDefaultColorNo(WS_DF_DARKBACKCOLOR,cno);
      }else
      if (!strcmp((char*)index,"#BARSHADOWCOLOR") && strcmp((char*)data,"")){
        short cno = WSGIappColorSet()->getColorNo((char*)data);
        WSGIappColorSet()->setDefaultColorNo(WS_DF_BARSHADOWCOLOR,cno);
      }else
      if (!strcmp((char*)index,"#NWTOPSHADOWCOLOR") && strcmp((char*)data,"")){
        short cno = WSGIappColorSet()->getColorNo((char*)data);
        WSGIappColorSet()->setDefaultColorNo(WS_DF_NWTOPSHADOWCOLOR,cno);
      }else
      if (!strcmp((char*)index,"#NWBOTTOMSHADOWCOLOR") && strcmp((char*)data,"")){
        short cno = WSGIappColorSet()->getColorNo((char*)data);
        WSGIappColorSet()->setDefaultColorNo(WS_DF_NWBOTTOMSHADOWCOLOR,cno);
      }else
      if (!strcmp((char*)index,"#NWBACKCOLOR") && strcmp((char*)data,"")){
        short cno = WSGIappColorSet()->getColorNo((char*)data);
        WSGIappColorSet()->setDefaultColorNo(WS_DF_NWBACKCOLOR,cno);
      }else
      if (!strcmp((char*)index,"#NWFORECOLOR") && strcmp((char*)data,"")){
        short cno = WSGIappColorSet()->getColorNo((char*)data);
        WSGIappColorSet()->setDefaultColorNo(WS_DF_NWFORECOLOR,cno);
      }else
      if (!strcmp((char*)index,"#DARKBOTTOMSHADOWCOLOR") && strcmp((char*)data,"")){
        short cno = WSGIappColorSet()->getColorNo((char*)data);
        WSGIappColorSet()->setDefaultColorNo(WS_DF_DARKBOTTOMSHADOWCOLOR,cno);
      }else
      if (!strcmp((char*)index,"#MENUSELECTFORECOLOR") && strcmp((char*)data,"")){
        short cno = WSGIappColorSet()->getColorNo((char*)data);
        WSGIappColorSet()->setDefaultColorNo(WS_DF_MENUSELECTFORECOLOR,cno);
      }else
      if (!strcmp((char*)index,"#AQUAFORECOLOR") && strcmp((char*)data,"")){
        short cno = WSGIappColorSet()->getColorNo((char*)data);
        WSGIappColorSet()->setDefaultColorNo(WS_DF_AQUAFORECOLOR,cno);
      }else
      if (!strcmp((char*)index,"#AQUAHIGHLIGHTCOLOR") && strcmp((char*)data,"")){
        short cno = WSGIappColorSet()->getColorNo((char*)data);
        WSGIappColorSet()->setDefaultColorNo(WS_DF_AQUAHIGHLIGHTCOLOR,cno);
      }else
      if (!strcmp((char*)index,"#DEFAULTFONT") && strcmp((char*)data2,"")){
        WSDfont* font = WSGIappFontSet()->getFont(8);
        font->setFontName(data2);
      }
    }
    if (_policy == -1){
      _policy = WS_POLICY_WINDOWS;
    }
    delete envstr;
    return WS_NO_ERR;
  }
  return WS_ERR;
}
long WSDxappDev::saveGuiPolicy(){
  WSCstring str;
  str << "#POLICY\n";
  str << getGuiPolicy() << "\n";
  str << "#EXPOLICY\n";
  str << getExtGuiPolicyName() << "\n";
  str << "#TOPSHADOWCOLOR\n";
  str << WSGIappColorSet()->getColor(WS_DF_TOPSHADOWCOLOR)->getSrc() << "\n";
  str << "#BOTTOMSHADOWCOLOR\n";
  str << WSGIappColorSet()->getColor(WS_DF_BOTTOMSHADOWCOLOR)->getSrc() << "\n";
  str << "#BACKCOLOR\n";
  str << WSGIappColorSet()->getColor(WS_DF_BACKCOLOR)->getSrc() << "\n";
  str << "#FORECOLOR\n";
  str << WSGIappColorSet()->getColor(WS_DF_FORECOLOR)->getSrc() << "\n";
  str << "#MENUFORECOLOR\n";
  str << WSGIappColorSet()->getColor(WS_DF_MENUFORECOLOR)->getSrc() << "\n";
  str << "#MENUBACKCOLOR\n";
  str << WSGIappColorSet()->getColor(WS_DF_MENUBACKCOLOR)->getSrc() << "\n";
  str << "#MENUSELECTCOLOR\n";
  str << WSGIappColorSet()->getColor(WS_DF_MENUSELECTCOLOR)->getSrc() << "\n";
  str << "#MENUSELECTFORECOLOR\n";
  str << WSGIappColorSet()->getColor(WS_DF_MENUSELECTFORECOLOR)->getSrc() << "\n";
  str << "#MENUTOPSHADOWCOLOR\n";
  str << WSGIappColorSet()->getColor(WS_DF_MENUTOPSHADOWCOLOR)->getSrc() << "\n";
  str << "#MENUBOTTOMSHADOWCOLOR\n";
  str << WSGIappColorSet()->getColor(WS_DF_MENUBOTTOMSHADOWCOLOR)->getSrc() << "\n";
  str << "#WORKBACKCOLOR\n";
  str << WSGIappColorSet()->getColor(WS_DF_WORKBACKCOLOR)->getSrc() << "\n";
  str << "#DARKBACKCOLOR\n";
  str << WSGIappColorSet()->getColor(WS_DF_DARKBACKCOLOR)->getSrc() << "\n";
  str << "#BARSHADOWCOLOR\n";
  str << WSGIappColorSet()->getColor(WS_DF_BARSHADOWCOLOR)->getSrc() << "\n";
  str << "#NWTOPSHADOWCOLOR\n";
  str << WSGIappColorSet()->getColor(WS_DF_NWTOPSHADOWCOLOR)->getSrc() << "\n";
  str << "#NWBOTTOMSHADOWCOLOR\n";
  str << WSGIappColorSet()->getColor(WS_DF_NWBOTTOMSHADOWCOLOR)->getSrc() << "\n";
  str << "#NWBACKCOLOR\n";
  str << WSGIappColorSet()->getColor(WS_DF_NWBACKCOLOR)->getSrc() << "\n";
  str << "#NWFORECOLOR\n";
  str << WSGIappColorSet()->getColor(WS_DF_NWFORECOLOR)->getSrc() << "\n";
  str << "#DARKBOTTOMSHADOWCOLOR\n";
  str << WSGIappColorSet()->getColor(WS_DF_DARKBOTTOMSHADOWCOLOR)->getSrc() << "\n";
  str << "#AQUAHIGHLIGHTCOLOR\n";
  str << WSGIappColorSet()->getColor(WS_DF_AQUAHIGHLIGHTCOLOR)->getSrc() << "\n";
  str << "#AQUAFORECOLOR\n";
  str << WSGIappColorSet()->getColor(WS_DF_AQUAFORECOLOR)->getSrc() << "\n";
  str << "#DEFAULTFONT\n";
  str << WSGIappFontSet()->getDefaultFont()->getFontName() << "\n";

  return WSGFreplaceTextFile("$(HOME)/.wsrc",str,False);
}

long WSDxappDev::initialize(){
  WSDappDev::initialize();


  short cno;

  cno = WSGIappColorSet()->getColorNo("gray85");
  WSGIappColorSet()->setDefaultColorNo(WS_DF_BACKCOLOR,cno);

  cno = WSGIappColorSet()->getColorNo("black");
  WSGIappColorSet()->setDefaultColorNo(WS_DF_FORECOLOR,cno);

  cno = WSGIappColorSet()->getColorNo("gray95");
  WSGIappColorSet()->setDefaultColorNo(WS_DF_TOPSHADOWCOLOR,cno);

  cno = WSGIappColorSet()->getColorNo("gray55");
  WSGIappColorSet()->setDefaultColorNo(WS_DF_BOTTOMSHADOWCOLOR,cno);

  cno = WSGIappColorSet()->getColorNo("black");
  WSGIappColorSet()->setDefaultColorNo(WS_DF_MENUFORECOLOR,cno);

  cno = WSGIappColorSet()->getColorNo("white");
  WSGIappColorSet()->setDefaultColorNo(WS_DF_MENUSELECTFORECOLOR,cno);

  cno = WSGIappColorSet()->getColorNo("gray80");
  WSGIappColorSet()->setDefaultColorNo(WS_DF_MENUBACKCOLOR,cno);

  cno = WSGIappColorSet()->getColorNo("slategray4");
  WSGIappColorSet()->setDefaultColorNo(WS_DF_MENUSELECTCOLOR,cno);


  cno = WSGIappColorSet()->getColorNo("gray95");
  WSGIappColorSet()->setDefaultColorNo(WS_DF_MENUTOPSHADOWCOLOR,cno);

  cno = WSGIappColorSet()->getColorNo("gray55");
  WSGIappColorSet()->setDefaultColorNo(WS_DF_MENUBOTTOMSHADOWCOLOR,cno);

  cno = WSGIappColorSet()->getColorNo("gray80");
  WSGIappColorSet()->setDefaultColorNo(WS_DF_DARKBACKCOLOR,cno);

  cno = WSGIappColorSet()->getColorNo("white");
  WSGIappColorSet()->setDefaultColorNo(WS_DF_WORKBACKCOLOR,cno);

  cno = WSGIappColorSet()->getColorNo("gray80");
  WSGIappColorSet()->setDefaultColorNo(WS_DF_BARSHADOWCOLOR,cno);

  cno = WSGIappColorSet()->getColorNo("gray85");
  WSGIappColorSet()->setDefaultColorNo(WS_DF_NWBACKCOLOR,cno);

  cno = WSGIappColorSet()->getColorNo("black");
  WSGIappColorSet()->setDefaultColorNo(WS_DF_NWFORECOLOR,cno);
  WSGIappColorSet()->setDefaultColorNo(WS_DF_DARKBOTTOMSHADOWCOLOR,cno);

  cno = WSGIappColorSet()->getColorNo("gray95");
  WSGIappColorSet()->setDefaultColorNo(WS_DF_NWTOPSHADOWCOLOR,cno);

  cno = WSGIappColorSet()->getColorNo("gray55");
  WSGIappColorSet()->setDefaultColorNo(WS_DF_NWBOTTOMSHADOWCOLOR,cno);

  cno = WSGIappColorSet()->getColorNo("#e0e0ff");
  WSGIappColorSet()->setDefaultColorNo(WS_DF_AQUAFORECOLOR,cno);

  cno = WSGIappColorSet()->getColorNo("#d0d0ff");
  WSGIappColorSet()->setDefaultColorNo(WS_DF_AQUAHIGHLIGHTCOLOR,cno);

  loadGuiPolicy();

  _gc = 0;
  _gc2 = 0;
  if (_alt_context != NULL){
    _app_context = (XtAppContext)_alt_context;
    Display** displays;
    Cardinal dnum = 0;
    XtGetDisplays(_app_context,&displays,&dnum);
    Display* primary = NULL;
    if (dnum < 1){
      return WS_ERR;
    }
    primary = displays[0];
    _app_widget = XtAppCreateShell(
                (const char *)"Application", 
                (const char *)"Application", 
                applicationShellWidgetClass,
                primary, (ArgList)NULL, 0 );
  }else{
    _app_widget = XtAppInitialize ( &_app_context, 
                (const char *)"Application", (XrmOptionDescList)NULL, 0, 
                &_iprm, _cprm,(char**)NULL, (ArgList)NULL, 0 );
  }
  _disp = XtDisplay(_app_widget);

  XSetErrorHandler(_ehandler);

  XtVaSetValues ( _app_widget, XtNmappedWhenManaged, FALSE,
           XtNx, 0, XtNy, 0, XtNwidth,  1, XtNheight, 1, NULL );

  XtRealizeWidget( _app_widget );

  return WS_NO_ERR;
}

long WSDxappDev::handleEvents(){
  while(1){
    dispatchEvent();
    WSGIappDevice()->clearDeleteList();
  }
  return WS_NO_ERR;
}

long WSDxappDev::dispatchEvent(){
  return _dispatchEvent(True);
}
long WSDxappDev::processEvent(){
  return _dispatchEvent(False);
}
long WSDxappDev::_dispatchEvent(WSCbool wait,XEvent* ev){
dbprintf("WSDxappDev::_dispatchEvent %s:%d start\n",__FILE__,__LINE__);

static long cnt = 0;
cnt++;
  XEvent e;
  if (ev == NULL){
    if (wait != False){
      XtAppNextEvent(_app_context,&e);
    }else{
      Boolean fl = XtAppPeekEvent(_app_context,&e);
      if (fl == 0){
        return WS_NO_ERR;
      }
    }

#ifndef KINPUT2
    if (XFilterEvent(&e,None)){
dbprintf("WSDxappDev::_dispatchEvent %s:%d done1\n",__FILE__,__LINE__);
      return WS_NO_ERR;
    }
#endif

  }else{
    memcpy(&e,ev,sizeof(e));
  }
  WSCbool dispatch = True; 

dbprintf("WSDxappDev::_dispatchEvent %s:%d ev=%d\n",__FILE__,__LINE__,e.type);
  if (e.type == ClientMessage){
//printf("client message !! here! xappdev \n");
    if (_accept_atom_for_sock == 0){
      _accept_atom_for_sock = XInternAtom(_disp,"SOCK-ACCEPT",False);
    }
    if (_read_event_for_execute == 0){
      _read_event_for_execute = XInternAtom(_disp,"EXEC-READ",False);
    }
    if (_callback_event_for_thread == 0){
      _callback_event_for_thread = XInternAtom(_disp,"THREAD-MESSAGE",False);
    }
    if (e.xclient.message_type == _accept_atom_for_sock){
//printf("client message !! here! execute xappdev \n");
      _accept_send_type data;
      memcpy(&data,e.xclient.data.l,sizeof(_accept_send_type));
      void(*hd)(WSDsocket*,void*,WSCulong) = data.hd;
      if (hd != NULL){
        hd(data.sock,(void*)data.socket,data.addr);
      }
dbprintf("WSDxappDev::_dispatchEvent %s:%d done2\n",__FILE__,__LINE__);
      return WS_NO_ERR;
    }
    if (e.xclient.message_type == _read_event_for_execute){
//printf("client message !! here! execute xappdev for exec_read\n");
      _read_event_send_type data;
      memcpy(&data,e.xclient.data.l,sizeof(_read_event_send_type));
      WSDunixExecute* obj = data.obj;

      if (obj->getId() == data.id){
//printf("client message !! here! execute exec_read\n");
        WSDunixExecute::_callback(obj);
      }
dbprintf("WSDxappDev::_dispatchEvent %s:%d done3\n",__FILE__,__LINE__);
      return WS_NO_ERR;
    }
    if (e.xclient.message_type == _callback_event_for_thread){
//printf("client message !! here! execute xappdev for exec_read\n");
      WSDunixThread* ptr;
      memcpy(&ptr,e.xclient.data.l,sizeof(WSDunixThread*));

      if (ptr->getCallbackFunction() != NULL){
//printf("client message !! here! execute exec_read\n");
        void(*fn)(WSDunixThread*,void*) =
             (void(*)(WSDunixThread*,void*))ptr->getCallbackFunction();
        if (fn != NULL){
          fn(ptr,ptr->getCallbackData());
        }
        WSGIappObjectList()->execInitialize();
        WSGIappObjectList()->execUpdate();
      }
dbprintf("WSDxappDev::_dispatchEvent %s:%d done3\n",__FILE__,__LINE__);
      return WS_NO_ERR;
    }


  }

  if (e.type == SelectionClear){
    setSelectionOwner(NULL);
    WSGIappObjectList()->execInitialize();
    WSGIappObjectList()->execUpdate();
dbprintf("WSDxappDev::_dispatchEvent %s:%d done4\n",__FILE__,__LINE__);
    return WS_NO_ERR;
  }

static Atom prop = 0;
static Atom prop2 = 0;
static Atom prop3 = 0;
static Atom prop4 = 0;
    if (prop == 0){
      prop = XInternAtom(_disp,"TEXT",False);
    }
    if (prop2 == 0){
      prop2 = XInternAtom(_disp,"COMPOUND_TEXT",False);
    }
    if (prop3 == 0){
      prop3 = XInternAtom(_disp,"STRING",False);
    }
    if (prop4 == 0){
      prop4 = XInternAtom(_disp,"TARGETS",False);
    }


  if (e.type == SelectionRequest){
//printf("xappdev:: request data..\n");
    XSelectionEvent se;
    se.type = SelectionNotify;
    se.requestor = e.xselectionrequest.requestor;
    se.selection = e.xselectionrequest.selection;
    se.target = e.xselectionrequest.target;
    se.time = e.xselectionrequest.time;
    se.property = e.xselectionrequest.property;

    if (e.xselectionrequest.selection == XA_PRIMARY &&
        e.xselectionrequest.target == prop4 ){
       Atom ar[3];
       ar[0] = prop4;
       ar[1] = prop2;
       ar[2] = prop3;
      XChangeProperty(_disp,se.requestor,se.property,se.target,
                      32,PropModeReplace,(unsigned char*)ar,3);
//TEST 4 -> 3

    }else if (e.xselectionrequest.selection == XA_PRIMARY &&
        e.xselectionrequest.target == prop ){
      char* str = WSGIappKeyboard()->WSDkeyboard::getSelectedString(
         WSGIappLocaleSet()->getSystemLocaleEncoding());
      XChangeProperty(_disp,se.requestor,se.property,se.target,
                      8,PropModeReplace,(unsigned char*)str,strlen(str)+1);
//printf("xappdev:: send data..#%s# %d %d %d\n",str,XA_PRIMARY,XA_STRING,se.property);
    }else if (e.xselectionrequest.selection == XA_PRIMARY &&
        e.xselectionrequest.target == XA_STRING ){
      char* str = WSGIappKeyboard()->WSDkeyboard::getSelectedString(
         WSGIappLocaleSet()->getSystemLocaleEncoding());
      XChangeProperty(_disp,se.requestor,se.property,se.target,
                      8,PropModeReplace,(unsigned char*)str,strlen(str)+1);

//printf("xappdev:: send data2..#%s# %d %d %d\n",str,XA_PRIMARY,XA_STRING,se.property);
#if 0
    }else if (e.xselectionrequest.selection == XA_PRIMARY &&
        e.xselectionrequest.target == prop2 ){
      char* str = WSGIappKeyboard()->WSDkeyboard::getSelectedString(
         WSGIappLocaleSet()->getSystemLocaleEncoding());
      XTextProperty ct;
      XmbTextListToTextProperty(_disp,&str,1,XCompoundTextStyle,&ct);
      XChangeProperty(_disp,se.requestor,se.property,se.target,
//                      8,PropModeReplace,(unsigned char*)str,strlen(str)+1);
                      8,PropModeReplace,ct.value,ct.nitems);
//printf("xappdev:: send data3..#%s# %d %d %d\n",str,XA_PRIMARY,XA_STRING,se.property);
#endif
    }else{
//printf("xappdev:: send data4.. NONE.. %d %d #%s#\n", e.xselectionrequest.selection, e.xselectionrequest.target,XGetAtomName(_disp,e.xselectionrequest.target));
      se.property = None;
    }

    XSendEvent(_disp,se.requestor,False,0,(XEvent*)&se);
dbprintf("WSDxappDev::_dispatchEvent %s:%d done5\n",__FILE__,__LINE__);
    return WS_NO_ERR;
  }
  if (e.type == SelectionNotify){


    char* buf;
    Atom type;
    int fmt;
    WSCulong nitems;
    WSCulong left;
#if 0
//    if (e.xselectionrequest.selection == prop3){
    if (e.xselectionrequest.selection == prop4){
      Atom *ar;
      if (XGetWindowProperty(_disp,XtWindow(appWidget()),prop2,
                              0,8192,False,XA_ATOM,&type,&fmt,&nitems,
                              &left,(WSCuchar**)&ar) == Success &&
          nitems > 0){
        int i; 
        for(i=0;i<nitems;i++){
          if (ar[i] == prop2 || ar[i] == prop3){
            XConvertSelection(_disp,XA_PRIMARY,ar[i],prop,XtWindow(appWidget()),
                e.xselection.time);
            break;
          }
        }
      }
    }else
#endif
    if (e.xselectionrequest.selection == XA_STRING){

      if (XGetWindowProperty(_disp,XtWindow(appWidget()),prop2,
                              0,8192,False,XA_STRING,&type,&fmt,&nitems,
                              &left,(WSCuchar**)&buf) == Success &&
          nitems > 0){
        char buffer [8193];
        strncpy(buffer,buf,nitems);
        if (nitems < 8193){
          buffer[nitems] = 0;
        }else{
          buffer[8192] = 0;
        }
        WSGIxkeyboard()->WSDkeyboard::setSelectedString(buffer,
          WSGIappLocaleSet()->getSystemLocaleEncoding());
//printf("type=%d fmt=%d left=%d\n",type,fmt,left);
//printf("xappdev:: comming data by cut buffer...#%s# %d\n",buffer, WSGIappLocaleSet()->getSystemLocaleEncoding());
//        WSGIxkeyboard()->WSDkeyboard::setSelectedString(buffer);
//printf("xappdev:: comming data3...type=%d %d nitems=%d #%s#\n",type,fmt,nitems,buf);
      }else{
//printf("xappdev:: comming data... none...\n");
      }
    }else{
      int bytes;
      WSDxappDev* app   = WSGIxwinAppDev();
      char* ret = XFetchBytes(app->display(),&bytes);
      char* str = new char[bytes+1];
      memcpy(str,ret,bytes);
      str[bytes]=0;
      WSGIxkeyboard()->WSDkeyboard::setSelectedString(str,
         WSGIappLocaleSet()->getSystemLocaleEncoding());
      delete str;
//printf("xappdev:: comming data by cut buffer...#%s# %d\n",str, WSGIappLocaleSet()->getSystemLocaleEncoding());
    }
    WSGIxkeyboard()->selectionDataAvailable();
  }

  if (e.type == KeyPress || e.type == KeyRelease || e.type == FocusIn){
    dispatch = WSGIxkeyboard()->deliverKeyEvent(&e);
  }

  if (e.type == GraphicsExpose){
    e.type = Expose;
  }

  if (e.type == ButtonPress){
    long state = WSGIappMouse()->getStatus();
    if (e.xbutton.button == 1){
      state |= WS_MOUSE_BTN1;
      WSGIappMouse()->setTargetBtn(WS_MOUSE_BTN1);
    }else if (e.xbutton.button == 2){
      state |= WS_MOUSE_BTN2;
      WSGIappMouse()->setTargetBtn(WS_MOUSE_BTN2);
    }else if (e.xbutton.button == 3){
      state |= WS_MOUSE_BTN3;
      WSGIappMouse()->setTargetBtn(WS_MOUSE_BTN3);
    }else if (e.xbutton.button == 4){
      state |= WS_MOUSE_BTN4;
      WSGIappMouse()->setTargetBtn(WS_MOUSE_BTN4);
    }else if (e.xbutton.button == 5){
      state |= WS_MOUSE_BTN5;
      WSGIappMouse()->setTargetBtn(WS_MOUSE_BTN5);
    }
    WSGIappMouse()->setStatus(state);
  }else if (e.type == ButtonRelease){
    long state = WSGIappMouse()->getStatus();
    if (e.xbutton.button == 1){
      state &= ~WS_MOUSE_BTN1;
      WSGIappMouse()->setTargetBtn(WS_MOUSE_BTN1);
    }else if (e.xbutton.button == 2){
      state &= ~WS_MOUSE_BTN2;
      WSGIappMouse()->setTargetBtn(WS_MOUSE_BTN2);
    }else if (e.xbutton.button == 3){
      state &= ~WS_MOUSE_BTN3;
      WSGIappMouse()->setTargetBtn(WS_MOUSE_BTN3);
    }else if (e.xbutton.button == 4){
      state &= ~WS_MOUSE_BTN4;
      WSGIappMouse()->setTargetBtn(WS_MOUSE_BTN4);
    }else if (e.xbutton.button == 5){
      state &= ~WS_MOUSE_BTN5;
      WSGIappMouse()->setTargetBtn(WS_MOUSE_BTN5);
    }
    WSGIappMouse()->setStatus(state);
  }

  if (dispatch == True && ev == NULL){
    XtDispatchEvent(&e);
  }
  WSGIappObjectList()->execInitialize();
  WSGIappObjectList()->execUpdate();
dbprintf("WSDxappDev::_dispatchEvent %s:%d done6\n",__FILE__,__LINE__);
  return WS_NO_ERR;
}

Display* WSDxappDev::display(){
  return _disp;
}
Widget WSDxappDev::appWidget(){
  return _app_widget;
}
GC WSDxappDev::appGC(){
  if (_gc == 0 && _disp != NULL){
    _gc = XCreateGC(_disp,XtWindow(appWidget()),0,0);
    XSetGraphicsExposures(_disp,_gc,1);
  }
  return _gc;
}
GC WSDxappDev::appGC2(){
  if (_gc2 == 0 && _disp != NULL){
    _gc2 = XCreateGC(_disp,XtWindow(appWidget()),0,0);
    XSetGraphicsExposures(_disp,_gc2,1);
  }
  return _gc2;
}
XtAppContext WSDxappDev::appContext(){
  return _app_context;
}
void WSDxappDev::setXEvent(XEvent* ev){
  _ev = ev;
}

XEvent* WSDxappDev::getEvent(){
  return _ev;
}

void WSDxappDev::update(){
  while(1){
    Boolean fl = XtAppPending(_app_context);
    if (fl == 0){
	  break;
	}
    XEvent e;
    XtAppNextEvent(_app_context,&e);
    WSCbool dispatch = True; 

#ifndef KINPUT2
    //is the event for input method?
    if (XFilterEvent(&e,None)){
      continue; //do not dispatch..
    }
#endif

#if 0
    if (getLockStatus() != False){
      if (e.type == KeyPress || e.type == KeyRelease ||
          e.type == ButtonPress ||
          e.type == ButtonRelease){
          continue;
      }
    }
#endif

    if (e.type == KeyPress || e.type == KeyRelease || e.type == FocusIn){
       dispatch = WSGIxkeyboard()->deliverKeyEvent(&e);
    }
    if (e.type == GraphicsExpose){
     e.type = Expose;
    }
    if (dispatch == True){
      XtDispatchEvent(&e);
    }
  }
  XFlush(display());
}

int _ehandler(Display *d,XErrorEvent *e){
//TEST
//assert(0);
//TEST
#if 1 //UNICODE
 if (!XUErrorHandler(d, e)) return 0;
#endif //UNICODE

 char string[64];
 XGetErrorText(d,e->error_code,string,64);
 printf("ERROR: WSDxappDev, X Server Error %s\n",string);
 printf("error   message = %s\n",string);
 printf("error   code    = %d\n",e->error_code);
 if (e->request_code < 128 && e->request_code > 0){
   printf("request code  = %s\n",_err_strings[e->request_code]);
 }
 printf("minor   code  = %d\n",e->minor_code);
 return 0;
}

/* Request codes */
char *_err_strings[] = {
"---------------------------",
" XCreateWindow            1",
" XChangeWindowAttributes  2",
" XGetWindowAttributes     3",
" XDestroyWindow           4",
" XDestroySubwindows       5",
" XChangeSaveSet           6",
" XReparentWindow          7",
" XMapWindow               8",
" XMapSubwindows           9",
" XUnmapWindow             10",
" XUnmapSubwindows         11",
" XConfigureWindow         12",
" XCirculateWindow         13",
" XGetGeometry             14",
" XQueryTree               15",
" XInternAtom              16",
" XGetAtomName             17",
" XChangeProperty          18",
" XDeleteProperty          19",
" XGetProperty             20",
" XListProperties          21",
" XSetSelectionOwner       22",
" XGetSelectionOwner       23",
" XConvertSelection        24",
" XSendEvent               25",
" XGrabPointer             26",
" XUngrabPointer           27",
" XGrabButton              28",
" XUngrabButton            29",
" XChangeActivePointerGrab 30",
" XGrabKeyboard            31",
" XUngrabKeyboard          32",
" XGrabKey                 33",
" XUngrabKey               34",
" XAllowEvents             35",
" XGrabServer              36",
" XUngrabServer            37",
" XQueryPointer            38",
" XGetMotionEvents         39",
" XTranslateCoords         40",
" XWarpPointer             41",
" XSetInputFocus           42",
" XGetInputFocus           43",
" XQueryKeymap             44",
" XOpenFont                45",
" XCloseFont               46",
" XQueryFont               47",
" XQueryTextExtents        48",
" XListFonts               49",
" XListFontsWithInfo       50",
" XSetFontPath             51",
" XGetFontPath             52",
" XCreatePixmap            53",
" XFreePixmap              54",
" XCreateGC                55",
" XChangeGC                56",
" XCopyGC                  57",
" XSetDashes               58",
" XSetClipRectangles       59",
" XFreeGC                  60",
" XClearArea               61",
" XCopyArea                62",
" XCopyPlane               63",
" XPolyPoint               64",
" XPolyLine                65",
" XPolySegment             66",
" XPolyRectangle           67",
" XPolyArc                 68",
" XFillPoly                69",
" XPolyFillRectangle       70",
" XPolyFillArc             71",
" XPutImage                72",
" XGetImage                73",
" XPolyText8               74",
" XPolyText16              75",
" XImageText8              76",
" XImageText16             77",
" XCreateColormap          78",
" XFreeColormap            79",
" XCopyColormapAndFree     80",
" XInstallColormap         81",
" XUninstallColormap       82",
" XListInstalledColormaps  83",
" XAllocColor              84",
" XAllocNamedColor         85",
" XAllocColorCells         86",
" XAllocColorPlanes        87",
" XFreeColors              88",
" XStoreColors             89",
" XStoreNamedColor         90",
" XQueryColors             91",
" XLookupColor             92",
" XCreateCursor            93",
" XCreateGlyphCursor       94",
" XFreeCursor              95",
" XRecolorCursor           96",
" XQueryBestSize           97",
" XQueryExtension          98",
" XListExtensions          99",
" XChangeKeyboardMapping   100",
" XGetKeyboardMapping      101",
" XChangeKeyboardControl   102",
" XGetKeyboardControl      103",
" XBell                    104",
" XChangePointerControl    105",
" XGetPointerControl       106",
" XSetScreenSaver          107",
" XGetScreenSaver          108",
" XChangeHosts             109",
" XListHosts               110",
" XSetAccessControl        111",
" XSetCloseDownMode        112",
" XKillClient              113",
" XRotateProperties        114",
" XForceScreenSaver        115",
" XSetPointerMapping       116",
" XGetPointerMapping       117",
" XSetModifierMapping      118",
" XGetModifierMapping      119",
" XNoOperation             127"};

