//
// 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/WSDwinAppDev.h>
#include <WSCbaseList.h>
#include <win/WSDwinKeyboard.h>
#include <WSCbase.h>
#include <WSCdevice.h>
#include <win/WSDwinformDev.h>
#include <WSCcolorSet.h>
#include <win/WSDwinPrivateTimer.h>
#include <win/WSDwinExecute.h>
#include <win/WSDwinCodeConvert.h>
#include <WSCinitializeManager.h>
#include <WSCimageSet.h>
#include <WSDtimer.h>
#include <win/WSDwinMessage.h>
#include <win/WSDwinsocket.h>
#include <WSCinitializeManager.h>
#include <win/WSDwinThread.h>
#include <win/WSDwinMutex.h>
#include <win/WSDwinSemaphore.h>

#define COLOR_MAX 256
WSMFclassInit(WSDwinAppDev,WSDappDev);
WSDappDev* _winAppDev_create_handler(){
  return new WSDwinAppDev();
}
static long _init_app = 0;
HWND WSDwinAppDev::_event_wnd = 0;
WSDwinAppDev* WSGIwinAppDev(){
  if ( _init_app == 0){
    WSDappDev::setCreateInstanceHandler(_winAppDev_create_handler);
  }
  WSDappDev* appdev = WSGIappDev();
  if (appdev == NULL){
    return NULL;
  }
  WSDwinAppDev* winAppdev =(WSDwinAppDev*)appdev->cast("WSDwinAppDev");
  return winAppdev;
}

class _winAppDev_init{
  public: _winAppDev_init(){
    _init_app = 1;
    WSDappDev::setCreateInstanceHandler(_winAppDev_create_handler);
  };
};

_winAppDev_init _winAppDev_init_run_constructor;

void WSGFdeviceInitialize(){
WSMFtrace("WSGFdeviceInitialize start:\n");
  static WSCbool initialized = False;
  if (initialized == False){
    WSDappDev::setCreateInstanceHandler(_winAppDev_create_handler);
extern WSDcodeConvert* _code_convert_create_handler_();
    WSDcodeConvert::_set_code_convert_handler(_code_convert_create_handler_);
    WSGIappCodeConvert()->initialize();
    initialized = True;
    WSGIappInitializeManager()->execInitializeProcs();
    WSGIappImageSet()->setDefaultImageHandle("$(WSDIR)/sys/pixmaps/psave.ico",(void*)202);
    WSGIappImageSet()->setDefaultImageHandle("$(WSDIR)/sys/pixmaps/pend.ico",(void*)203);
    WSGIappImageSet()->setDefaultImageHandle("$(WSDIR)/sys/pixmaps/wload.ico",(void*)204);
    WSGIappImageSet()->setDefaultImageHandle("$(WSDIR)/sys/pixmaps/wsave.ico",(void*)205);
    WSGIappImageSet()->setDefaultImageHandle("$(WSDIR)/sys/pixmaps/obox.ico",(void*)206);
    WSGIappImageSet()->setDefaultImageHandle("$(WSDIR)/sys/pixmaps/make.ico",(void*)207);
    WSGIappImageSet()->setDefaultImageHandle("$(WSDIR)/sys/pixmaps/run.ico",(void*)208);
    WSGIappImageSet()->setDefaultImageHandle("$(WSDIR)/sys/pixmaps/search.ico",(void*)209);
    WSGIappImageSet()->setDefaultImageHandle("$(WSDIR)/sys/pixmaps/search2.ico",(void*)210);
    WSGIappImageSet()->setDefaultImageHandle("$(WSDIR)/sys/pixmaps/help.ico",(void*)211);
    WSGIappImageSet()->setDefaultImageHandle("$(WSDIR)/sys/pixmaps/runx.ico",(void*)212);

    WSGIappImageSet()->setDefaultImageHandle("$(WSDIR)/sys/pixmaps/bi4.ico",(void*)213);
    WSGIappImageSet()->setDefaultImageHandle("$(WSDIR)/sys/pixmaps/bi13.ico",(void*)214);
    WSGIappImageSet()->setDefaultImageHandle("$(WSDIR)/sys/pixmaps/bi15.ico",(void*)215);
    WSGIappImageSet()->setDefaultImageHandle("$(WSDIR)/sys/pixmaps/bi16.ico",(void*)216);
    WSGIappImageSet()->setDefaultImageHandle("$(WSDIR)/sys/pixmaps/bi17.ico",(void*)217);
    WSGIappImageSet()->setDefaultImageHandle("$(WSDIR)/sys/pixmaps/bi18.ico",(void*)218);
    WSGIappImageSet()->setDefaultImageHandle("$(WSDIR)/sys/pixmaps/bi19.ico",(void*)219);
    WSGIappImageSet()->setDefaultImageHandle("$(WSDIR)/sys/pixmaps/bi23.ico",(void*)220);
    WSGIappImageSet()->setDefaultImageHandle("$(WSDIR)/sys/pixmaps/bi24.ico",(void*)221);
    WSGIappImageSet()->setDefaultImageHandle("$(WSDIR)/sys/pixmaps/bi25.ico",(void*)222);
    WSGIappImageSet()->setDefaultImageHandle("$(WSDIR)/sys/pixmaps/endbtn.ico",(void*)223);
    WSGIappImageSet()->setDefaultImageHandle("$(WSDIR)/sys/pixmaps/ope.ico",(void*)224);
    WSGIappImageSet()->setDefaultImageHandle("$(WSDIR)/sys/pixmaps/wcreate.ico",(void*)225);
    WSGIappImageSet()->setDefaultImageHandle("$(WSDIR)/sys/pixmaps/wtrash.ico",(void*)226);
    WSGIappImageSet()->setDefaultImageHandle("$(WSDIR)/sys/pixmaps/edit.ico",(void*)227);
    WSGIappImageSet()->setDefaultImageHandle("$(WSDIR)/sys/pixmaps/pset.ico",(void*)228);
    WSGIappImageSet()->setDefaultImageHandle("$(WSDIR)/sys/pixmaps/bi8.ico",(void*)229);
    WSGIappImageSet()->setDefaultImageHandle("$(WSDIR)/sys/pixmaps/pcreate.ico",(void*)230);
    WSGIappImageSet()->setDefaultImageHandle("$(WSDIR)/sys/pixmaps/pload.ico",(void*)231);
    WSGIappImageSet()->setDefaultImageHandle("$(WSDIR)/sys/pixmaps/bi40.ico",(void*)232);
    WSGIappImageSet()->setDefaultImageHandle("$(WSDIR)/sys/pixmaps/bi41.ico",(void*)233);
    WSGIappImageSet()->setDefaultImageHandle("$(WSDIR)/sys/pixmaps/bi42.ico",(void*)234);
    WSGIappImageSet()->setDefaultImageHandle("$(WSDIR)/sys/pixmaps/bi43.ico",(void*)235);
extern void WSGFinitializeWinMutex();
    WSGFinitializeWinMutex();
extern void WSGFinitializeWinThread();
    WSGFinitializeWinThread();
extern void WSGFinitializeWinSemaphore();
    WSGFinitializeWinSemaphore();
extern void _win_font_init();
    _win_font_init();
extern void _win_color_init();
    _win_color_init();
extern void _win_image_init();
    _win_image_init();
WSMFtrace("WSGFdeviceInitialize done:\n");
  }
}
WSDwinAppDev::WSDwinAppDev(){
  _hinst = 0;
  _mfocus_dev = NULL;
  _palette = 0;
  _wnd_proc = NULL;
}
WSDwinAppDev::~WSDwinAppDev(){}
void WSDwinAppDev::setMouseFocusDev(WSDwinformDev* mdev){
  _mfocus_dev = mdev;
}
WSDwinformDev* WSDwinAppDev::getMouseFocusDev(){
  return _mfocus_dev;
}
WSCushort WSDwinAppDev::getWidth(){
  HWND dw = GetDesktopWindow();
  RECT r;
  GetClientRect(dw,&r);
  return (WSCushort)r.right; //DEVELOP...
}
WSCushort WSDwinAppDev::getHeight(){
  HWND dw = GetDesktopWindow();
  RECT r;
  GetClientRect(dw,&r);
  return (WSCushort)r.bottom; //DEVELOP...
}

long WSDwinAppDev::getDeviceResource(){
  return (long)_hinst;
}

long WSDwinAppDev::getWindowResource(){
  return (long)_hwnd;
}

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

long WSDwinAppDev::getSpecialResource(){
  return 0;
}

long WSDwinAppDev::setInitPrm(LPSTR cmdline){
  _lpCmdLine = cmdline;
  return WS_NO_ERR;
}

long WSDwinAppDev::loadGuiPolicy(){
  WSCstring* envstr = WSGFreadTextFile("$(HOME)/.wsrc");
  if (envstr != NULL){
    while(envstr->eof() == False){
      WSCstring index = envstr->gets();
      WSCstring data = envstr->gets();
      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);
      }
    }
    if (_policy == -1){
      _policy = WS_POLICY_WINDOWS;
    }
    delete envstr;
    return WS_NO_ERR;
  }
  return WS_ERR;
}

long WSDwinAppDev::saveGuiPolicy(){
  WSCstring str;
  str << "#POLICY\n";
  str << getGuiPolicy() << "\n";
  str << "#EXPOLICY\n";
  str << getExtGuiPolicyName() << "\n";

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


long WSDwinAppDev::setWnd(HWND wnd){
  _hwnd = wnd;
  WSGIappTimer();
  return WS_NO_ERR;
}

#define _DARK_1 1
#define _DARK_2 2
#define _LIGHT_1 3
#define _LIGHT_2 4
static void _set_color(short c,long val,long dark){
  long r = 0xff & val;
  long g = (0xff00 & val) >> 8;
  long b = (0xff0000 & val) >> 16;
  if (dark == _DARK_1){
    r = r * 31 /32;
    g = g * 31 /32;
    b = b * 31 /32;
  }
  if (dark == _DARK_2){
    r = r * 5 /10;
    g = g * 5 /10;
    b = b * 5 /10;
  }
  if (dark == _LIGHT_1){
    r = r + (0xff -r) * 5 /10;
    g = g + (0xff -g) * 5 /10;
    b = b + (0xff -b) * 5 /10;
  }
  if (dark == _LIGHT_2){
    r = r + 0x10;
    g = g + 0x10;
    b = b + 0x10;
    if (r > 0xff){
      r = 0xff;
    }
    if (g > 0xff){
      g = 0xff;
    }
    if (b > 0xff){
      b = 0xff;
    }
  }
  char buffer[32];
  sprintf(buffer,"#%02x%02x%02x",r,g,b);
  short cno = WSGIappColorSet()->getColorNo(buffer);
  WSGIappColorSet()->setDefaultColorNo(c,cno);
}

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

  long val;
  val = GetSysColor(COLOR_BTNFACE);
  _set_color(WS_DF_BACKCOLOR,val,_LIGHT_2);
  _set_color(WS_DF_DARKBACKCOLOR,val,0);
  _set_color(WS_DF_NWBACKCOLOR,val,0);

  val = GetSysColor(COLOR_WINDOWTEXT);
  _set_color(WS_DF_FORECOLOR,val,0);

  val = GetSysColor(COLOR_MENU);
  _set_color(WS_DF_MENUBACKCOLOR,val,0);

  val = GetSysColor(COLOR_MENUTEXT);
  _set_color(WS_DF_MENUFORECOLOR,val,0);

  val = GetSysColor(COLOR_HIGHLIGHT);
  _set_color(WS_DF_MENUSELECTCOLOR,val,0);

  val = GetSysColor(COLOR_HIGHLIGHTTEXT);
  _set_color(WS_DF_MENUSELECTFORECOLOR,val,0);

  val = GetSysColor(COLOR_WINDOW);
  _set_color(WS_DF_WORKBACKCOLOR,val,0);

  val = GetSysColor(COLOR_SCROLLBAR);
  _set_color(WS_DF_BARSHADOWCOLOR,val,_DARK_1);

  val = GetSysColor(COLOR_BTNTEXT);
  _set_color(WS_DF_NWFORECOLOR,val,0);

  val = GetSysColor(COLOR_3DDKSHADOW);
  _set_color(WS_DF_DARKBOTTOMSHADOWCOLOR,val,0);

  val = GetSysColor(COLOR_3DHILIGHT);
  _set_color(WS_DF_NWTOPSHADOWCOLOR,val,0);
  _set_color(WS_DF_TOPSHADOWCOLOR,val,0);
  _set_color(WS_DF_MENUTOPSHADOWCOLOR,val,0);

  val = GetSysColor(COLOR_3DSHADOW);
  _set_color(WS_DF_NWBOTTOMSHADOWCOLOR,val,0);
  _set_color(WS_DF_BOTTOMSHADOWCOLOR,val,0);
  _set_color(WS_DF_MENUBOTTOMSHADOWCOLOR,val,0);

  _set_color(WS_DF_AQUAHIGHLIGHTCOLOR,0xffe0e0,0);
  _set_color(WS_DF_AQUAFORECOLOR,0xffd0d0,0);

  loadGuiPolicy();

  return WS_NO_ERR;
}

long WSDwinAppDev::handleEvents(){
  WSGIappInitializeManager()->execInitializeProcs();
  long ret;
  while(1){
    ret = dispatchEvent();
    WSGIappDevice()->clearDeleteList();
    if (ret == 0){
      break;
    }
  }
  return _msg.wParam;
}
long WSDwinAppDev::dispatchEvent(){
 return _dispatchEvent(True);
}
long WSDwinAppDev::processEvent(){
 return _dispatchEvent(False);
}
long WSDwinAppDev::_dispatchEvent(WSCbool wait){
//  HANDLE hAccelTable;
  if (wait != False){
    long ret = GetMessage(&_msg,NULL,0,0);
    TranslateMessage(&_msg);
    DispatchMessage(&_msg);
    return ret;
  }else{
    long ret = PeekMessage(&_msg,NULL,0,0,PM_REMOVE);
    if (ret != FALSE){
      TranslateMessage(&_msg);
      DispatchMessage(&_msg);
    }
    return ret;
  }
}

void WSDwinAppDev::setInstanceHandle(HINSTANCE h){
  _hinst = h;
}
HINSTANCE WSDwinAppDev::getInstanceHandle(){
  return _hinst;
}
LRESULT CALLBACK WndProc(HWND hWnd,UINT message,WPARAM uParam,LPARAM lParam){
//  int wmld, wmEvent;
//  PAINTSTRUCT ps;
//  RECT rect;
//  RECT winsize;
//  char buffer[32];
dbprintf("WndProc %s:%d start hwnd=0x%x message=0x%x message=%d \n",__FILE__,__LINE__,hWnd,message,message);
  WinEvent ev;
  ev.message = message;
  ev.uParam = uParam;
  ev.lParam = lParam;
#if 0
  if (WSGIwinAppDev()->getGrabedWnd() != 0 &&
      GetCapture() != WSGIwinAppDev()->getGrabedWnd()){
    SetCapture(WSGIwinAppDev()->getGrabedWnd());
  }
WSMFtrace("grabed=0x%x\n",WSGIwinAppDev()->getGrabedWnd());
#endif
//printf("message ==0x%x message=%d hwnd=0x%x\n",message,message,hWnd);
  if (message == WM_TIMER && hWnd == WSGIwinAppDev()->getHWND()){
    WSDwinPrivateTimer::_timer_callback(uParam);
dbprintf("WndProc %s:%d done1\n",__FILE__,__LINE__);
    return 0;
  }
  if (message == WM_USER && uParam == WS_WIN_EXECUTE){
    WSDwinExecute* obj = (WSDwinExecute*)lParam;
    obj->_callback();
dbprintf("WndProc %s:%d done2\n",__FILE__,__LINE__);
    return 0;
  }
  if (message == WM_USER && uParam == WS_WIN_ACCEPT){
    _accept_send_type* data = (_accept_send_type*)lParam;
    data->hd(data->sock,(void*)data->socket,data->addr);
    delete data;
dbprintf("WndProc %s:%d done3\n",__FILE__,__LINE__);
    return 0;
  }
  if (message == WM_USER && uParam == WS_WIN_THR){
    WSDwinThread* ptr = (WSDwinThread*)lParam;
    void (*fn)(WSDthread*,void*) =
           (void(*)(WSDthread*,void*))ptr->getCallbackFunction();
    fn(ptr,ptr->getCallbackData());
    WSGIappObjectList()->execInitialize();
    WSGIappObjectList()->execUpdate();
    return 0;
  }
  if (message == WM_USER){
    int ret = WSDwinMessage::receiveMessage((WSDwinMessage*)uParam,(void*)lParam);
    if (ret != False){
dbprintf("WndProc %s:%d done4\n",__FILE__,__LINE__);
      return 0;
    }
  }
#if 0
  long ptr = GetWindowLong(hWnd,GWL_USERDATA);
#else
  HANDLE ptr = GetProp(hWnd,"frm");
#endif
  WSDwinformDev* frm = (WSDwinformDev*)ptr;
  if (message == WM_CHAR ||
      message == WM_KEYDOWN ||
      message == WM_KEYUP ||
      message == WM_SYSKEYDOWN ||
      message == WM_SYSKEYUP){
    MSG msg;
    msg.message = message;
    msg.wParam = uParam;
    msg.lParam = lParam;
    WSCbool ret = WSGIwinKeyboard()->_dispatch_key(&msg);
    if (ret == False){
dbprintf("WndProc %s:%d done5\n",__FILE__,__LINE__);
      return 0;
    }
  }

  if (message == WM_NCHITTEST){
//printf("displatch.. nchittest..\n",hWnd);
    LRESULT ret = DefWindowProc(hWnd,message,uParam,lParam);
//printf("displatch.. ht=%d\n",ret);
    if (ret != HTCLIENT){
      WSDwinformDev* mdev = WSGIwinAppDev()->getMouseFocusDev();
      if (mdev != NULL){
        WSGIwinAppDev()->setMouseFocusDev(NULL);
        mdev->onMouseOut();
      }
dbprintf("WndProc %s:%d done6\n",__FILE__,__LINE__);
      return ret;
    }
dbprintf("WndProc %s:%d done7\n",__FILE__,__LINE__);
    return ret;
  }
  if (frm == NULL){
    HRESULT ret1 = DefWindowProc(hWnd,message,uParam,lParam);
dbprintf("WndProc %s:%d done0\n",__FILE__,__LINE__);
    return ret1;
  }
  WSDwinAppDev::_event_wnd = hWnd;
#if 0 //XXZZXXZZ
   if (message == WM_LBUTTONDOWN ||
       message == WM_MBUTTONDOWN ||
       message == WM_RBUTTONDOWN ){
     HWND fwnd = GetFocus();
     if (fwnd != hWnd || WSGIappDev()->getMode() == WS_MODE_NS_PLUGIN){
       SetFocus(hWnd);
     }
       SetActiveWindow(hWnd);
       SetFocus(hWnd);
   }
#endif 
//printf("WSDwinAppDev::displatch.. wnd=0x%x XXZZff1\n",hWnd);
  long ret = frm->dispatchEvent(&ev);

//for IE escape key navigation...
static long _loop_in = 0;
  if (_loop_in == 0 && GetFocus() == hWnd &&
      (message == WM_LBUTTONDOWN ||
       message == WM_MBUTTONDOWN ||
       message == WM_RBUTTONDOWN )  &&
      WSGIappDev()->getMode() == WS_MODE_NS_PLUGIN){
    if (ret != 0){
      ret = DefWindowProc(hWnd,message,uParam,lParam);
    }
    _loop_in = 1;
    MSG _msg;
    while(1){
      long ret2 = PeekMessage(&_msg,NULL,0,0,PM_NOREMOVE);
      HWND target = _msg.hwnd;
      if (target != hWnd){
        while(1){
          HWND target = GetParent(target);
          if (target == NULL){
            break;
          }else if (target == hWnd){
            break;
          }
        }
        if (target == NULL){ //other hwnd (not hwnd of ws)
          _loop_in = 0;
dbprintf("WndProc %s:%d done8\n",__FILE__,__LINE__);
          return ret;
        }
      }
      if (_msg.message == WM_DESTROY ||
          _msg.message == WM_NCDESTROY){
          _loop_in = 0;
dbprintf("WndProc %s:%d done9\n",__FILE__,__LINE__);
          return ret;
      } 
      ret2 = GetMessage(&_msg,NULL,0,0);
      TranslateMessage(&_msg);
      DispatchMessage(&_msg);
      if ( GetFocus() != hWnd ){
        _loop_in = 0;
dbprintf("WndProc %s:%d done10\n",__FILE__,__LINE__);
        return ret;
      }
    }
dbprintf("WndProc %s:%d done11\n",__FILE__,__LINE__);
    return ret;
  }

  if (ret != 0){
//WSMFtrace("displatch.. wnd=0x%x ev=%d   XXZZm1\n",hWnd,message);
    HRESULT ret1 = DefWindowProc(hWnd,message,uParam,lParam);
dbprintf("WndProc %s:%d done11\n",__FILE__,__LINE__);
    return ret1;
  }
dbprintf("WndProc %s:%d done12\n",__FILE__,__LINE__);
  WSGIappObjectList()->execInitialize();
  WSGIappObjectList()->execUpdate();
  return 0;
#if 0
  switch(message){
    
    case WM_COMMAND:
      wmld = LOWORD(uParam);
      wmEvent = HIWORD(uParam);
    case WM_DESTROY:
      PostQuitMessage(0);
      break;
    case WM_PAINT:
      hdc = BeginPaint(hWnd,&ps);
      GetClientRect(hWnd,&rect);
      GetWindowRect(hWnd,&winsize);
      sprintf(buffer,"size = %d,%d",winsize.right - winsize.left,winsize.bottom - winsize.top);
      DrawText(hdc,buffer,-1,&rect,DT_SINGLELINE | DT_CENTER |DT_VCENTER);
      EndPaint(hWnd,&ps);
      break;
    default:
      return DefWindowProc(hWnd,message,uParam,lParam);
  }
  return 0;
#endif
}
void WSDwinAppDev::addUpdateDev(WSDwinformDev* dev){
  long num = _update_dev_list.getNum();
  long i;
  for(i = 0; i < num; i++){
    WSDwinformDev* d = (WSDwinformDev*)_update_dev_list[i];
    if (d == dev){
      return;
    }
  }
  _update_dev_list.add((void*)dev);
}
void WSDwinAppDev::delUpdateDev(WSDwinformDev* dev){
  _update_dev_list.del((void*)dev);
}

void WSDwinAppDev::update(){
  long num = _update_dev_list.getNum();
  long i;
  WSClistData bk;
  for(i = 0; i < num; i++){
    bk.add(_update_dev_list[i]);
  }
  for(i = 0; i < num; i++){
    WSDwinformDev* d = (WSDwinformDev*)bk[i];
    d->setExposed(True);
    d->_clear_and_expose();
  }
  while(1){
    long ret = PeekMessage(&_msg,NULL,0,0,PM_REMOVE);
    if (ret != FALSE){
      TranslateMessage(&_msg);
      DispatchMessage(&_msg);
    }else{
      break;
    }
  }
}
struct WSDpalette{
  LOGPALETTE   plt;
  PALETTEENTRY entries[COLOR_MAX];
};

HPALETTE WSDwinAppDev::getPalette(){
  if (_palette == (HPALETTE)-1){
    return 0;
  }
  if (_palette != 0){
    return _palette;
  }
  HDC dc = GetDC(_hwnd);
  if ((GetDeviceCaps(dc,RASTERCAPS) & RC_PALETTE) == 0){
    ReleaseDC(_hwnd,dc);
    _palette = (HPALETTE)-1;
    return (HPALETTE)0;
  }
  ReleaseDC(_hwnd,dc);

  WSDpalette palette_base;
  LOGPALETTE* palette = (LOGPALETTE*)&palette_base;
  palette->palVersion = 0x300;

  int i,j,k;
  int cnt = 0;
//  int _continue =0;
  int r,g,b;

  for(i=0; i<5; i++){
    for(j=0; j<5; j++){
      for(k=0; k<5; k++){
        r = 64 * i;
        g = 64 * j;
        b = 64 * k;
        if (r > 255){
          r = 255;
        }
        if (g > 255){
          g = 255;
        }
        if (b > 255){
          b = 255;
        }
 
        palette->palPalEntry[cnt].peFlags = PC_RESERVED;
        palette->palPalEntry[cnt].peRed = r;
        palette->palPalEntry[cnt].peGreen = g;
        palette->palPalEntry[cnt].peBlue = b;
        cnt++;
      }
    }
  }
  for(i=1; i<25; i++){
    r = 256 - i*10;
    b = g = r;
    palette->palPalEntry[cnt].peFlags = PC_RESERVED;
    palette->palPalEntry[cnt].peRed = r;
    palette->palPalEntry[cnt].peGreen = g;
    palette->palPalEntry[cnt].peBlue = b;
    cnt++;
  }
  palette->palNumEntries = cnt;
  _palette = CreatePalette(palette);

  return _palette;
}
HWND WSDwinAppDev::getHWND(){
  return _hwnd;
}
HWND WSDwinAppDev::getEventWnd(){
  return _event_wnd;
}
void WSDwinAppDev::setGrabedWnd(HWND wnd){
  _grabed_wnd = wnd;
  if (wnd == NULL){
    ReleaseCapture();
  }else{
    SetCapture(wnd);
  }
}
HWND WSDwinAppDev::getGrabedWnd(){
  return _grabed_wnd;
}
long WSDwinAppDev::setInitPrm(int iprm,char** cprm){
  _iprm = iprm;
  _cprm = cprm;
  return WS_NO_ERR;
}
long WSDwinAppDev::setWndProc(void* proc){
  _wnd_proc = proc;
}
void* WSDwinAppDev::getWndProc(){
  return _wnd_proc;
}
