//
// 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 <windows.h>
#include <win/WSDwinformDev.h>
#include <win/WSDwinAppDev.h>
#include <WSCdevice.h>
#include <win/WSDwindraw.h>
#include <WSCcolorSet.h>
#include <WSCimageSet.h>
#include <WSCbase.h>
//#include <WSwincom.h>
#include <win/WSDwinDragDrop.h>
#include <WSDmouse.h>
#include <WSCbaseList.h>

#define DEBUG

WSMFclassInit(WSDwinformDev,WSDwindowDev);

WSDdev* _wscdwinformdev_init_(){
  return new WSDwinformDev();
}

class _WSDwinformDev_init_ {
  public:_WSDwinformDev_init_(){
     WSGIappDevice()->setCreateHandler("formDev",_wscdwinformdev_init_);
  };
};
static _WSDwinformDev_init_ _init_to_run_WSDwinformDev_;

//static WSDwindraw* draw_of_winform = NULL;
static long _os_flag = -1;

WSDwinformDev::WSDwinformDev(){
dbprintf("WSDwinformDev::WSDwinformDev %s:%d start\n",__FILE__,__LINE__);
  _click_time = 0;
  if (_os_flag == -1){
    OSVERSIONINFO osvi;
    osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
    GetVersionEx(&osvi);
    _os_flag = osvi.dwPlatformId;
  }
  _mouse_val = 0;
  _pwnd = 0;
  _wnd  = 0;
  _pixmap  = 0;
  _pixmap_mdc  = 0;
  _back_cno = -1;
  _back_pixno = -1;
  _abs_x = 0;
  _abs_y = 0;
  _dc = 0;
  _mdc = 0;
  _exposed = False;
  _moved = False;
  _resized = False;
  _grabed = False;
  _bg_image = 0;
  _mouse_no = 0;
//WSMFtrace("WSDwinformDev::WSDwinformDev this=0x%x\n",this);
//  if (draw_of_winform == NULL){
//      draw_of_winform = new WSDwindraw();
//  }
//  setDraw(draw_of_winform);
dbprintf("WSDwinformDev::WSDwinformDev %s:%d done\n",__FILE__,__LINE__);
}

WSDwinformDev::~WSDwinformDev(){
dbprintf("WSDwinformDev::~WSDwinformDev %s:%d start\n",__FILE__,__LINE__);
//printf("WSDwinformDev::~WSDwinformDev this=0x%x XXZZff1\n",this);
//WSMFtrace("WSDwinformDev::~WSDwinformDev 0x%x\n",this);
//  destroyContext();
  destroyPixmap();
  destroyWindow();
  setExposed(False);
dbprintf("WSDwinformDev::~WSDwinformDev %s:%d done\n",__FILE__,__LINE__);
}
void WSDwinformDev::setExposed(WSCbool fl){
  if (fl != False){
    WSGIwinAppDev()->delUpdateDev(this);
  }else{
    WSGIwinAppDev()->addUpdateDev(this);
  }
  _exposed = fl;
}
short WSDwinformDev::getAbsoluteX(){
  RECT r;
  GetWindowRect(_wnd,&r);
  return r.left;
}
short WSDwinformDev::getAbsoluteY(){
  RECT r;
  GetWindowRect(_wnd,&r);
  return r.top;
}

WSDdev* WSDwinformDev::getEventParentDev(){
  return this;
}

HWND WSDwinformDev::getHWND(){
  return _wnd;
}

long WSDwinformDev::setValue(long kind,void* data){
//  short bx,by;
//  WSCushort bw,bh;
  if (kind == WSDEV_X && *(short*)data == _w_x){
    return WS_NO_ERR;
  }
  if (kind == WSDEV_Y && *(short*)data == _w_y){
    return WS_NO_ERR;
  }
  if (kind == WSDEV_WIDTH && *(WSCushort*)data == _w_w){
    return WS_NO_ERR;
  }
  if (kind == WSDEV_HEIGHT && *(WSCushort*)data == _w_h){
    return WS_NO_ERR;
  }


//  Arg args[4];
  WSDcolor* color;
  WSDimage* image;
//  WSCbool unmanaged = False;
//  WSCbool fl;
  RECT p;
  switch(kind){
    case WSDEV_X: 
             if (_wnd == NULL){
               break;
             }
             _moved = True;
             GetClientRect(_wnd,&p);
//printf("WSDwinformdev::setValue x p.left=%d ",p.left);
//printf(" -> %d  w=0x%d\n",p.left,p.right - p.left);
             _w_x = *(short*)data;
             MoveWindow(_wnd,_w_x,_w_y,p.right,p.bottom, True);
             if (getVisible() != False){
               _expose_children(0,0,_w_w,_w_h);
             }
             break;
    case WSDEV_Y:
             if (_wnd == NULL){
               break;
             }
             _moved = True;
             GetClientRect(_wnd,&p);
//printf("WSDwinformdev::setValue y p.top=%d ",p.top);
             _w_y = *(short*)data;
             MoveWindow(_wnd,_w_x,_w_y,p.right,p.bottom, True);
//printf(" -> %d  w=0x%d\n",p.top,p.bottom - p.top);
             if (getVisible() != False){
               _expose_children(0,0,_w_w,_w_h);
             }
             break;
    case WSDEV_WIDTH:
             if (_wnd == NULL){
               break;
             }
//             _resized = True;
             if (getPixmapStyle() != WS_DIRECT_WINDOW){
               destroyPixmap();
             }
             if (_resize_sequence != False && *(short*)data == _w_now){
               break;
             }             
             if (*(WSCushort*)data > 0){
               GetClientRect(_wnd,&p);
               p.right = p.left + *(WSCushort*)data;
               MoveWindow(_wnd,_w_x,_w_y,p.right,p.bottom, True);
             }
             break;
    case WSDEV_HEIGHT:
             if (_wnd == NULL){
               break;
             }
             _resized = True;
             if (getPixmapStyle() != WS_DIRECT_WINDOW){
               destroyPixmap();
             }
             if (_resize_sequence != False && *(short*)data == _h_now){
               break;
             }             
             if (*(WSCushort*)data > 0){
               GetClientRect(_wnd,&p);
               p.bottom = p.top + *(WSCushort*)data;
               MoveWindow(_wnd,_w_x,_w_y,p.right,p.bottom, True);
             }
             break;
    case WSDEV_BACKCOLOR:
             color = WSGIappColorSet()->getColor(*(short*)data);
             _back_cno = *(short*)data;
             if (color != NULL){
               _bg_cref = (COLORREF)color->getValue1();
             }
             if (_wnd == NULL){
               break;
             }
             setExposed(False);
             invalidate(TRUE);
             break;
    case WSDEV_BACK_PIXMAP:
             _back_pixno = *(short*)data;
//printf("BACK_PIX ino=%d\n",_back_pixno);
             if (*(short*)data == -1){
               _bg_image = 0;
             }else{
               image = WSGIappImageSet()->getImage(*(short*)data);
               if (image != NULL){
                 if (image->getValue1() == -1){
                   _bg_image = 0;
                 }else{
                   _bg_image = (HBITMAP)image->getValue1();
//printf("WSDwinformDev::setValue BACK_PIX _bg_image=0x%x\n",_bg_image);
                 }
               }
             }
             if (_wnd != 0){
               setExposed(False);
               invalidate(TRUE);
             }
             break;
    case WSDEV_GRAB_POINTER:
             if (_wnd == NULL){
               break;
             }
             _grabed = *(WSCbool*)data;
             if (_grabed != False){
//WSMFtrace("WSDwinformDev::setValue grab on  this=0x%x wnd=0x%x  XXZZgb1\n",this,_wnd);
               WSGIwinAppDev()->setGrabedWnd(_wnd);
             }else{
//WSMFtrace("WSDwinformDev::setValue grab off  this=0x%x wnd=0x%x  XXZZgb1\n",this,_wnd);
               long state = WSGIappMouse()->getStatus();
               if (state > 0){
                 break;
               }
               WSGIwinAppDev()->setGrabedWnd(NULL);
             }
#if 0
             fl = *(WSCbool*)data;
             if (fl != False){
//               XGrabPointer(XtDisplay(_wnd),XtWindow(_wnd),True,0,GrabModeAsync,GrabModeAsync,None,None,CurrentTime);
               XGrabPointer(XtDisplay(_wnd),XtWindow(_wnd),False,
                  ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
                  GrabModeAsync,GrabModeAsync,None,None,CurrentTime);
             }else{
               XUngrabPointer(XtDisplay(_wnd),CurrentTime);
             }
#endif
             break;
     case WSDEV_MOUSE_NO:
             _mouse_no = *(WSCushort*)data;
             _mouse_val = (HCURSOR)WSGIappMouse()->getMouseCursor(*(WSCushort*)data);
//WSMFtrace("WSDwinformDev::setValue MOUSE_NO 0x%x %d\n",_mouse_val,*(WSCushort*)data);

             break;
     default:
//      return WS_NO_ERR;
             break;
  }
  WSDwindowDev::setValue(kind,data);
  return WS_NO_ERR;
}

void WSDwinformDev::_copy_area(long x,long y,WSCulong w,WSCulong h,long dx,long dy,WSCuchar fl){
//WSMFtrace("WSDwinformDev::_copy_area  XXZZp3 %d %d %d %d _mdc=0x%x\n",x,y,w,h,_mdc);
  if (_exposed == False){
    return;
  }
  if (_wnd == 0){
    return;
  }

  WSCbool release_dc = False;
  if (_dc == 0){
    _dc = GetDC(_wnd);
    if (_dc == 0){
      return;
    }
    release_dc = True;
  }
  HPALETTE palette = WSGIwinAppDev()->getPalette();
  HPALETTE palette_bk = 0;
  if (palette != 0 ){
     palette_bk = SelectPalette(_dc,palette,False);
     RealizePalette(_dc);
  }
  if (fl == WS_PIXMAP_TO_WINDOW){
    if (_mdc != 0){
//WSMFtrace("WSDwinformDev::_copy_area %d,%d,%d,%d ->%d,%d XXZZp1\n",x,y,w,h,dx,dy);
      BitBlt(_dc,dx,dy,w,h,_mdc,x,y,SRCCOPY);
    } 
  }else{ 
//WSMFtrace("WSDwinformDev::_copy_area %d,%d,%d,%d ->%d,%d XXZZp3\n",x,y,w,h,dx,dy);
    BitBlt(_dc,dx,dy,w,h,_dc,x,y,SRCCOPY);
#if 0
    HDC mdc2 = CreateCompatibleDC(_dc);
    HBITMAP pix = CreateCompatibleBitmap(_dc,w,h);
    HBITMAP bbk = (HBITMAP)SelectObject(mdc2,(void*)pix);
    SetMapMode(mdc2,GetMapMode(_dc));
    BitBlt(mdc2,0,0,w,h,_dc,x,y,SRCCOPY);
    BitBlt(_dc,dx,dy,w,h,mdc2,0,0,SRCCOPY);
    SelectObject(mdc2,(void*)bbk);
    DeleteObject((void*)pix);
    DeleteDC(mdc2);
#endif
  }
  if (palette != 0){
    SelectPalette(_dc,palette_bk,False);
  }
  if (release_dc != 0){
    ReleaseDC(_wnd,_dc);
    _dc = 0;
  }

#ifdef DEBUG
WSMFtrace("WSDwinformDev::_copy_area() is not implemented..\n");
#endif
#if 0
  GC gc = getGC();
  if (fl == WS_PIXMAP_TO_WINDOW){
     Pixmap pix = getPixmap();
     if (pix == 0 || gc  == 0){
        return;
     }
     //ピクスマップからウィンドウにコピーする
     XCopyArea( XtDisplay(_wnd),pix,XtWindow(_wnd),gc,
          (int)x, (int)y, (WSCuint)w, (WSCuint)h, (int)dx, (int)dy);
  }else{
     XCopyArea( XtDisplay(_wnd),XtWindow(_wnd),XtWindow(_wnd),gc,
          (int)x, (int)y, (WSCuint)w, (WSCuint)h, (int)dx, (int)dy);
     while(1){
       XFlush(XtDisplay(_wnd));
       WinEvent e;
       Bool fl =  XCheckTypedWindowEvent(XtDisplay(_wnd),XtWindow(_wnd),
                   GraphicsExpose,&e);
       if (fl == 1){
         e.type = Expose;
         XtDispatchEvent(&e);
         WSGIappObjectList()->execInitialize();
         WSGIappObjectList()->execUpdate();
         break;
       }
       fl =  XCheckTypedWindowEvent(XtDisplay(_wnd),XtWindow(_wnd),
                   NoExpose,&e);
       if (fl == 1){
         break;
       }
     }
  }
#endif
}

void WSDwinformDev::_clear_area(long x,long y,WSCulong w,WSCulong h){
//printf("WSDwinformDev::_clear_area %d %d %d %d  _wnd=0x%x _dc=0x%x\n",x,y,w,h,_wnd,_dc);
  if (w == 23767){
    return;
  }
  if (h == 23767){
    return;
  }
  if (x+(long)w < 0){
    return;
  }
  if (y+(long)h < 0){
    return;
  }
  if (_wnd == 0){
    return;
  }
  RECT r;
  r.left = x;
  r.right = x + w;
  r.top = y;
  r.bottom = y + h;
  HDC dc = 0;
  WSCbool release_dc = False;
  if (getPixmapStyle() == WS_DIRECT_WINDOW){
    if (_dc == 0){
      _dc = GetDC(_wnd);
      if (_dc == 0){
        return;
      }
      release_dc = True;
    }
    dc = _dc;
  }else{
    if (_mdc == 0){
      createPixmap();
    }
    dc = _mdc;
  }
  HPALETTE palette = WSGIwinAppDev()->getPalette();
  HPALETTE palette_bk = 0;
  if (palette != 0 ){
     palette_bk = SelectPalette(dc,palette,False);
     RealizePalette(dc);
  }
  if (_bg_image != 0){
    WSDimage* img = WSGIappImageSet()->getImage(_back_pixno);
//printf("WSDwinformDev::_clear_area XXZZ11 _back_pixno=%d 0x%x\n",_back_pixno,img);
    if (img != NULL){
      HDC mdc2 = CreateCompatibleDC(dc);
      HBITMAP bbk = (HBITMAP)SelectObject(mdc2,(void*)_bg_image);
      SetMapMode(mdc2,GetMapMode(dc));
      POINT p;
      p.x = img->getImageWidth();
      p.y = img->getImageHeight();
      DPtoLP(dc,&p,1);
      WSCushort pw = p.x;
      WSCushort ph = p.y;
      if (pw < 1){
        pw = 1;
      }
      if (ph < 1){
        ph = 1;
      }
      HRGN rgn = CreateRectRgn(x,y,x+w,y+h);
      SelectClipRgn(dc,rgn);
//printf("WSDwinformDev::_clear_area XXZZ _bg_image=0x%x %d,%d\n",_bg_image,pw,ph);
//WSMFtrace("WSDwinformDev::_clear_area XXZZp1  x,y,w,h=%d,%d,%d,%d  pw,ph=%d,%d\n",x,y,w,h,pw,ph);
      long dx,dy;
      for(dx = 0; dx < (signed long)(x+w); dx = dx + pw){
        for(dy = 0; dy < (signed long)(y+h); dy = dy + ph){
          if ( dx < (signed long)(x+w) && dy < (signed long)(y+h)){
//WSMFtrace("WSDwinformDev::_clear_area XXZZp1c x,y,w,h=%d,%d,%d,%d \n",dx,dy,pw,ph,pw,ph);
            BitBlt(dc,dx,dy,pw,ph,mdc2,0,0,SRCCOPY);
          }
        }
      }
//printf("WSDwinformDev::_clear_area here1 \n",_bg_image);
      SelectClipRgn(dc,(HRGN)0);
      SelectObject(mdc2,(void*)bbk);
      DeleteObject((void*)rgn);
      DeleteDC(mdc2);
    }
  }else{
    HBRUSH brush = CreateSolidBrush(_bg_cref);
    FillRect(dc,&r,brush);
    DeleteObject(brush);
  }
  if (palette != 0){
    SelectPalette(dc,palette_bk,False);
  }
  if (release_dc != 0){
    ReleaseDC(_wnd,_dc);
    _dc = 0;
  }
}
WSDwinformDev* WSDwinformDev::getParentAreaDev(){
  WSDdev*      pdev = WSDwinformDev::getParentDev();
  if (pdev == NULL){
    return NULL;
  }

  WSDwinformDev* windev = (WSDwinformDev*)pdev->cast("WSDwinformDev");
  if (windev == NULL){
    while(windev == NULL){
      pdev = pdev->getParentDev();
      if (pdev == NULL){
        return NULL;
      }
      windev = (WSDwinformDev*)pdev->cast("WSDwinformDev");
    }
  }
  return windev;
}

void WSDwinformDev::_setup_pixmap(short x,short y,WSCushort w,WSCushort h,short bg,short img_no){
//printf("WSDwinformDev::_setup_pixmap XXZZ33   mdc=0x%x w,h=%d,%d------------\n",_mdc,w,h);
  if (_exposed == False){
    return;
  }
  if (_mdc == (HDC)0 ||_wnd == (HWND)0){
    return;
  }

  WSDcolor*  color = WSGIappColorSet()->getColor(bg);
  COLORREF bgref = 0;
  if (color != NULL){
    bgref = (COLORREF)color->getValue1();
  }

  if (getPixmap() == (HBITMAP)0){
    createPixmap();
    if (getPixmap() == (HBITMAP)0){
//WSMFtrace("Error: can not create pixmap WSDwinformdev::_setup_pixmap.\n");
      return;
    } 
  }
  HPALETTE pl = WSGIwinAppDev()->getPalette();
  HPALETTE plbk = 0;
  if (pl != (HPALETTE)0){
    plbk = SelectPalette(_mdc,pl,FALSE);
    RealizePalette(_mdc);
  }
  RECT r;
  r.left =x;
  r.top  =y;
  r.right = x+w;
  r.bottom = y+h;
  if (_bg_image != (HBITMAP)0){
    WSDimage* img = WSGIappImageSet()->getImage(_back_pixno);
    if (img != NULL){
      SIZE size1; 
      GetBitmapDimensionEx(_bg_image,&size1);
      HDC mdc2 = CreateCompatibleDC(_mdc);
      HBITMAP bbk = (HBITMAP)SelectObject(mdc2,(void*)_bg_image);
      SetMapMode(mdc2,GetMapMode(_mdc));
      POINT p;
      p.x = img->getImageWidth();
      p.y = img->getImageHeight();
      DPtoLP(_mdc,&p,1);
      WSCushort pw = p.x;
      WSCushort ph = p.y;
      if (pw < 1){
        pw = 1;
      }
      if (ph < 1){
        ph = 1;
      }
      HRGN rgn = CreateRectRgn(x,y,x+w,y+h);
      SelectClipRgn(_mdc,rgn);
//WSMFtrace("WSDwinformDev::_setup_pixmap XXZZp1  x,y,w,h=%d,%d,%d,%d\n",x,y,w,h);
      long dx,dy;
      for(dx = 0; dx < x+w; dx = dx + pw){
        for(dy = 0; dy < y+h; dy = dy + ph){
          if ( dx < x+w && dy < y+h){
            BitBlt(_mdc,dx,dy,pw,ph,mdc2,0,0,SRCCOPY);
          }
        }
      }
      SelectClipRgn(_mdc,(HRGN)0);
      SelectObject(mdc2,(void*)bbk);
      DeleteObject((void*)rgn);
      DeleteDC(mdc2);
    }
  }else{
//printf("WSDwinformDev::_setup_pixmap XXZZredraw1 filled this=0x%x w,h=%d,%d\n",this,w,h);
    HBRUSH br = CreateSolidBrush(bgref);
    SelectClipRgn(_mdc,(HRGN)0);
    FillRect(_mdc,&r,br);
    DeleteObject((void*)br);
//WSMFtrace("WSDwinformDev::_setup_pix  XXZZp3 %d %d %d %d _mdc=0x%x\n",x,y,w,h,_mdc);
  }
  if (plbk != (HPALETTE)0){
    SelectPalette(_mdc,plbk,FALSE);
  }

  return;
}

long WSDwinformDev::createWindow(){
#ifdef DEBUG
WSMFtrace("WSDwinformDev::createWindow() this=0x%x\n",this);
WSMFtrace("WSDwinformDev::createWindow() remove delete callback is not implemented..\n");
#endif
#if 0
  if (_wnd != 0){
//    WSDwinformDev* xdev = getParentPublicAreaDev();
    WSDwinformDev* xdev = getParentAreaDev();
    if (xdev != NULL && xdev->getHWND() != _pwnd){
      XtRemoveCallback(_wnd,XtNdestroyCallback,_evh_delete2,this);
    }else{
      //それ以外は作りなおすひつようなし。
      return WS_NO_ERR;
    }
  }
#endif
  if (getVisible() == False){
    return WS_NO_ERR;
  }
  short x,y;    
  WSCushort w,h;    
  getWindowSize(&x,&y,&w,&h);
  if (w == 0){
    w = 1;
  }
  if (h == 0){
    h = 1;
  }

  WSDwinformDev* windev;
  windev = getParentAreaDev();

  if (windev == NULL){
    return WS_ERR;
  }

  //エリアの作成
extern char szAppName[];
//  _wnd = CreateWindow( szAppName,"",WS_CHILD,x,y,w,h,windev->getHWND(),
//WSMFtrace("CreateWindow  x,y,w,h=%d,%d,%d,%d\n",x,y,w,h);
  _pwnd = windev->getHWND();
  _wnd = CreateWindow( szAppName,"",WS_CHILD | WS_OVERLAPPED | WS_CLIPCHILDREN | WS_CLIPSIBLINGS,x,y,w,h,windev->getHWND(),
                        NULL,WSGIwinAppDev()->getInstanceHandle(),NULL);
  if (WSGIwinAppDev()->getWndProc() != NULL){
    SetWindowLong(_wnd,GWL_WNDPROC,(LONG)WSGIwinAppDev()->getWndProc());
  }
//WSMFtrace("x,y,w,h=%d,%d,%d,%d\n",x,y,w,h);
#if 0
  SetWindowLong(_wnd,GWL_USERDATA,(long)this);
#else
  SetProp(_wnd,"frm",(HANDLE)this);
#endif
//WSMFtrace("WSDwinformDev  this=0x%x wnd=0x%x    pwnd=0x%x\n",this,_wnd,windev->getHWND());
#ifdef DEBUG
WSMFtrace("WSDwinformDev::createWindow() add callbacks is not implemented..\n");
#endif

#if 0
  Arg args[15];
  long anum = 0;
  XtSetArg(args[anum],XtNx,x); anum++;
  XtSetArg(args[anum],XtNy,y); anum++;
  XtSetArg(args[anum],XtNwidth,w); anum++;
  XtSetArg(args[anum],XtNheight,h); anum++;
  if (_back_cno != -1){
    WSDcolor* color = WSGIappColorSet()->getColor(_back_cno);
    if (color != NULL){
       XtSetArg(args[anum],XtNbackground,color->getValue1()); anum++;
    }
  }
  if (_back_pixno == -1){
    XtSetArg(args[anum],XtNbackgroundPixmap,UNSPECIFIED_PIXMAP); anum++;
  }else{
    WSDimage*  image = WSGIappImageSet()->getImage(_back_pixno);
    if (image != NULL){
      if (image->getValue1() == -1){
          XtSetArg(args[anum],XtNbackgroundPixmap,UNSPECIFIED_PIXMAP); anum++;
      }else{
         Pixmap pid = (Pixmap)image->getValue1();
         XtSetArg(args[anum],XtNbackgroundPixmap,pid); anum++;
      }
    }else{
      XtSetArg(args[anum],XtNbackgroundPixmap,UNSPECIFIED_PIXMAP); anum++;
    }
  }
  XtSetArg(args[anum],XtNborderWidth,0); anum++;
  _pwnd = windev->getHWND();
  _wnd = XtCreateHWND("wscdxwa",formHWNDClass,xdev->getHWND(),args,anum);

//printf("dev=0x%x _wnd=x0%x\n",this,_wnd);
  XtAddEventHandler(_wnd,ExposureMask,False,(XtEventHandler)_evh_expose,this);
  XtAddEventHandler(_wnd,ButtonPressMask,False,(XtEventHandler)_evh_btn_press,this);
  XtAddEventHandler(_wnd,ButtonReleaseMask,False,(XtEventHandler)_evh_btn_release,this);
  XtAddEventHandler(_wnd,ButtonMotionMask | PointerMotionMask,False,(XtEventHandler)_evh_mouse_move,this);
  XtAddEventHandler(_wnd,StructureNotifyMask,False,(XtEventHandler)_evh_resize,this);
  XtAddEventHandler(_wnd,EnterWindowMask,False,(XtEventHandler)_evh_mouse_in,this);
  XtAddEventHandler(_wnd,LeaveWindowMask,False,(XtEventHandler)_evh_mouse_out,this);
  XtAddEventHandler(_wnd,KeyPressMask | KeyReleaseMask,False,(XtEventHandler)_evh_dummy,this);
  XtAddCallback(_wnd,XtNdestroyCallback,_evh_delete2,this);
#endif

  return WS_NO_ERR;
}

long WSDwinformDev::setPixmap(HBITMAP pixmap){
  if (pixmap == 0 && _mdc != NULL){
    if (_pixmap_mdc != 0){
      SelectObject(_mdc,_pixmap_mdc); //leaks the gdi objects on win98..
    }
    _pixmap_mdc = 0;
  }
  if (_pixmap != (HBITMAP)0){
    DeleteObject((void*)_pixmap);
    _pixmap = (HBITMAP)0;
  }
  _pixmap = pixmap;
  if (pixmap == 0 && _mdc != NULL){
    DeleteDC(_mdc);
    _mdc = 0;
    _pixmap_mdc = 0;
  }
  return WS_NO_ERR;
}

long WSDwinformDev::getDeviceResource(){
  return 0;
}

long WSDwinformDev::createPixmap(){
//  if (_exposed == False){
//printf("WSDwinformDev::createPixmap not exposed XXZZ22\n");
//    return WS_ERR;
//  }
  if (_wnd == 0){
//WSMFtrace("WSDwinformDev::createPixmap error1 XXZZ22\n");
    return WS_ERR;
  }
//WSMFtrace("WSDwinformDev::createPixmap create... XXZZ22\n");
  destroyPixmap();
//  RECT r;
//  GetClientRect(_wnd,&r);
//  WSCushort w = r.right - r.left;
//  WSCushort h = r.bottom - r.top;
  WSCushort w = _w_w;
  WSCushort h = _w_h;
//WSMFtrace("WSDwinformDev::createPixmap create... w.h=%d,%dXXZZ22x\n",w,h);
  if (_dc == 0){
    _dc = GetDC(_wnd);
    if (_mdc == 0){
      _mdc = CreateCompatibleDC(_dc);
    }
    if (_mdc == 0){
      ReleaseDC(_wnd,_dc);
      _dc = 0;
      return WS_ERR;
    }
    HBITMAP pix = CreateCompatibleBitmap(_dc,w,h);
    setPixmap(pix);
    if (_mdc == 0){
      ReleaseDC(_wnd,_dc);
      _dc = 0;
      return WS_ERR;
    }
    if (_os_flag == VER_PLATFORM_WIN32_NT){
      SelectObject(_mdc,_pixmap); //leaks the gdi objects on win98..
    }else{
      if (_pixmap_mdc == 0){
        _pixmap_mdc = (HBITMAP)SelectObject(_mdc,_pixmap); //leaks the gdi objects on win98..
      }else{
        SelectObject(_mdc,_pixmap); //leaks the gdi objects on win98..
      }
    }
    ReleaseDC(_wnd,_dc);
    _dc = 0;
  }else{
    if (_mdc == 0){
      _mdc = CreateCompatibleDC(_dc);
    }
    if (_mdc == 0){
      return WS_ERR;
    }
    HBITMAP pix = CreateCompatibleBitmap(_dc,w,h);
    setPixmap(pix);
    if (_mdc == 0){
      return WS_ERR;
    }
    if (_os_flag == VER_PLATFORM_WIN32_NT){
      SelectObject(_mdc,_pixmap); //leaks the gdi objects on win98..
    }else{
      if (_pixmap_mdc == 0){
        _pixmap_mdc = (HBITMAP)SelectObject(_mdc,_pixmap); //leaks the gdi objects on win98..
      }else{
        SelectObject(_mdc,_pixmap); //leaks the gdi objects on win98..
      }
    }
  }
  setExposed(True);
   
  _setup_pixmap(0,0,w,h,_bg_no,_bp_no);
  exposeExecute(0,0,w,h);

  return WS_NO_ERR;
}

long WSDwinformDev::getContextResource(){
  if (getPixmapStyle() != WS_DIRECT_WINDOW ){
    if (_mdc == 0){
      return -1;
    }else{
//WSMFtrace("WSDwinformDev::getContext _mdc=0x%x returned.  XXZZ33\n",_mdc);
      return (long)_mdc;
    }
  }else{
    return (long)_dc;
  }
  return 0;
}

long WSDwinformDev::getSpecialResource(){
   return (long)_wnd;
}
#if 0
long WSDwinformDev::createContext(){
#ifdef DEBUG
WSMFtrace("WSDwinformDev::createContext() is not implemented..\n");
#endif
#if 0
  destroyContext();  
  WSDwinappDev* app   = WSGIwinAppDev();
  GC gc = app->appGC();
  setGC(gc);
#endif
  return WS_NO_ERR;
}
#endif
long WSDwinformDev::getWindowResource(){
  return (long)_wnd;
}


HBITMAP WSDwinformDev::getPixmap(){
  return _pixmap;
}

HWND WSDwinformDev::getWindow(){
  if (getPixmapStyle() != WS_DIRECT_WINDOW ){
    if ( getPixmap() != 0 ){
//WSMFtrace("WSxformDev::getWindow() return pixmap=0x%x\n",getPixmap());
      return (HWND)getPixmap();
    }else{
//WSMFtrace("WSxformDev::getWindow() return pixmap=0x%x\n",getPixmap());
//WSMFtrace("WSxformDev::getWindow() pixmap=0 warring. ------------------- return win\n");
        return (HWND)-1; //エラー
    }
  }
  if (_wnd == 0){
    return (HWND)-1;
  }
  return _wnd;
}

long WSDwinformDev::destroyWindow(){
//printf("WSDwinformDev::destroyWindow this=0x%x _wnd=0x%x XXZZff1\n",this,_wnd);
#ifdef DEBUG
WSMFtrace("WSDwinformDev::destroyWindow() remove callbacks is not implemented..\n");
#endif
  WSDwinformDev* mdev = WSGIwinAppDev()->getMouseFocusDev();
  if (mdev == this){
    WSGIwinAppDev()->setMouseFocusDev(NULL);
  }
  if (_wnd != 0){
#if 0
    SetWindowLong(_wnd,GWL_USERDATA,(long)0);
#else
    SetProp(_wnd,"frm",(HANDLE)0);
#endif
    MSG msg;
    while(PeekMessage(&msg,_wnd,0,0,PM_REMOVE)){
      if (msg.message == WM_PAINT){
          PAINTSTRUCT ps;
//          HDC hdc = BeginPaint(_wnd,&ps);
          BeginPaint(_wnd,&ps);
          EndPaint(_wnd,&ps);
      }
    }
    DestroyWindow(_wnd);

    _wnd = 0;
  }
#if 0
  if (_wnd != 0){
    XtRemoveEventHandler(_wnd,ExposureMask,False,(XtEventHandler)_evh_expose,this);
    XtRemoveEventHandler(_wnd,ButtonPressMask,False,(XtEventHandler)_evh_btn_press,this);
    XtRemoveEventHandler(_wnd,ButtonReleaseMask,False,(XtEventHandler)_evh_btn_release,this);
    XtRemoveEventHandler(_wnd,ButtonMotionMask | PointerMotionMask,False,(XtEventHandler)_evh_mouse_move,this);
    XtRemoveEventHandler(_wnd,StructureNotifyMask,False,(XtEventHandler)_evh_resize,this);
    XtRemoveEventHandler(_wnd,EnterWindowMask,False,(XtEventHandler)_evh_mouse_in,this);
    XtRemoveEventHandler(_wnd,LeaveWindowMask,False,(XtEventHandler)_evh_mouse_out,this);
    XtRemoveEventHandler(_wnd,KeyPressMask | KeyReleaseMask,False,(XtEventHandler)_evh_dummy,this);
    XtRemoveCallback(_wnd,XtNdestroyCallback,_evh_delete2,this);
    XtDestroyHWND(_wnd);
  }
#endif
  _pwnd = 0;
  _wnd = 0;
//  setDependDev(NULL);
  setInitialized(False);
//WSMFtrace("WSxformDev::destroyHWND() XtDestroyHWND here2 0x%x\n",this);
//  destroyAllDependChildren();
//WSMFtrace("WSxformDev::destroyHWND() XtDestroyHWND here3 0x%x\n",this);
  return WS_NO_ERR;
}

long WSDwinformDev::destroyPixmap(){
  if (_mdc != 0){
    if (_pixmap_mdc != 0){
      SelectObject(_mdc,_pixmap_mdc); //leaks the gdi objects on win98..
    }
  }
  if (_pixmap != 0){
    DeleteObject((void*)_pixmap);
    _pixmap = 0;
  }
  if (_mdc != 0){
    DeleteDC(_mdc);
    _mdc = 0;
    _pixmap_mdc = 0;
  }
//  setPixmap(0);
  WSDwindowDev::destroyPixmap();
  return WS_NO_ERR;
}

//long WSDwinformDev::setGC(GC gc){
//  _gc = gc;
//  return WS_NO_ERR;
//}
#if 0
long WSDwinformDev::destroyContext(){
#ifdef DEBUG
WSMFtrace("WSDwinformDev::destroyContext is not implemented.\n");
#endif
#if 0
  setGC(0);
#endif
 return WS_NO_ERR;
}
#endif
long WSDwinformDev::setVisible(WSCbool fl){
  WSCbool bk = getVisible();
  WSDdev::setVisible(fl);
//WSMFtrace("WSDwinformDev::setVisible %d this=0x%x client->%s  parent=0x%x  parent=%s========================\n",fl,this,getAttachedClient()->getInstanceName(),getParentDev(),getParentDev()->getAttachedClient()->getInstanceName());
  if (fl == True){
    if (getAttachedClient() == NULL){
      fl = False;
    }else if (getAttachedClient()->getVisible() == False){
      fl = False;
    }
  }
  if (fl == False){
    WSDwinformDev* mdev = WSGIwinAppDev()->getMouseFocusDev();
    if (mdev == this){
      WSGIwinAppDev()->setMouseFocusDev(NULL);
    }
    WSDwinformDev* windev = getParentAreaDev();
    if (windev != NULL && windev->getHWND() == 0){
      destroyWindow();
    }else{
      if (_wnd != 0){
        ShowWindow(_wnd,SW_HIDE);
      }
    }
  }else{
    if (_wnd == 0){
//WSMFtrace("WSDwinformDev::setVisible create HWND ============\n");
       createWindow();
    }

    if (getPixmapStyle() != WS_DIRECT_WINDOW){
      if (bk == False){
        destroyPixmap(); //expose handler 内で作成するため、消しておく
      }
//TEST//////////////////////////////////////////////////////////////////////
//       //XXXXXXXXXXXXXXXXXXXXXXXXXXXx
//       //後ほど、pixmap style で static dynamic の処理をそれぞれ行なう
//        createPixmap();
//TEST//////////////////////////////////////////////////////////////////////
    }
    ShowWindow(_wnd,SW_SHOW);
    SetWindowPos(_wnd,HWND_TOP,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
    if (bk == False){
      setExposed(False);
      invalidate(False);
    }
  }
  return WS_NO_ERR;
}

long WSDwinformDev::dispatchEvent(WinEvent* e){
//printf("WSDwinformDev::dispatchEvent e=%d this=0x%x XXZZff1\n",e->message,this);
//WSMFtrace("WSDwinformDev::dispatchEvent e=%d this=0x%x XXZZee\n",e->message,this);
//WSMFtrace("WSDwinformDev::dispatchEvent param=0x%x 0x%x XXZZee\n",e->uParam,e->lParam);
   if (e->message == WM_PAINT){
     _evh_expose(e);
     return 0;
   }else
   if (e->message == WM_MOUSEMOVE){
     _evh_mouse_move(e);
     return 0;
   }else
   if (e->message == WM_ERASEBKGND){
//     _clear_and_expose();
     return 0;
   }else
   if (e->message == WM_LBUTTONDOWN){
     _evh_btn_press(e,1);
     return 0;
   }else
   if (e->message == WM_MBUTTONDOWN){
     _evh_btn_press(e,2);
     return 0;
   }else
   if (e->message == WM_RBUTTONDOWN){
     _evh_btn_press(e,3);
     return 0;
   }else
   if (e->message == WM_MOUSEWHEEL && e->uParam == 0xff880000){
     _evh_btn_press(e,5);
     return 0;
   }else
   if (e->message == WM_MOUSEWHEEL && e->uParam == 0x780000){
     _evh_btn_press(e,4);
     return 0;
   }else
   if (e->message == WM_LBUTTONUP){
     _evh_btn_release(e,1);
     return 0;
   }else
   if (e->message == WM_MBUTTONUP){
     _evh_btn_release(e,2);
     return 0;
   }else
   if (e->message == WM_RBUTTONUP){
     _evh_btn_release(e,3);
     return 0;
   }else
   if (e->message == WM_MOVE){
     _evh_move(e);
     return 0;
   }else
   if (e->message == WM_SIZE){
     _evh_resize(e);
     return 0;
   }else
   if (e->message == WM_DESTROY){
     _evh_delete(e);
     return 0;
   }else
   if (e->message == WM_KILLFOCUS){
     WSCbase* fcl = WSCbase::getFocusInstance();
     if (fcl != NULL){
       fcl->onWindowFocusChange(False);
     }
     return 0;
   }else
   if (e->message == WM_SETFOCUS){
     WSCbase* fcl = WSCbase::getFocusInstance();
     if (fcl != NULL){
       WSCbase* cl = getAttachedClient();
       WSCbase* pcl = fcl;
       if (cl != NULL){
         WSCbool fl = False;
         while(1){
           if (pcl == NULL){
             break;
           }
           if (cl == pcl){
             fl = True;
             break;
           }
           pcl = pcl->getParent();
         }
         if (fl != False){
           fcl->onWindowFocusChange(True);
         }else{
           fcl->setFocus(False);
         }
       }else{
         fcl->onWindowFocusChange(True);
       }
     }
     return 0;
   }
   return 1;
}
WSCushort WSDwinformDev::getMouseNo(){
  return _mouse_no;
}
void WSDwinformDev::_evh_mouse_in(WinEvent* ev){
  WSCpoint point;
  point.setPoint( LOWORD(ev->lParam), HIWORD(ev->lParam) );
  WSGIwinAppDev()->setMouseFocusDev(this);

//WSMFtrace("WSDwinformDev::_evh_mouse_in() mouse cursor is not implemented.\n");
#if 0
  long val = WSGIappMouse()->getMouseCursor(dev->_mouse_no);
  if (val != 0){
    XDefineCursor(XtDisplay((HWND)dev->_wnd),XtWindow((HWND)dev->_wnd),val);
  }
#endif

  onMouseIn(&point);
}

void WSDwinformDev::_evh_mouse_out(WinEvent* ev){
//WSMFtrace("WSCwinformDev::_evh_mouse_out()...\n");
#if 0
   if (ev->xcrossing.mode != NotifyNormal){
     return;
   }
#endif
  WSDwinformDev* mdev = WSGIwinAppDev()->getMouseFocusDev();
  if (mdev == NULL){
    onMouseOut();
  }else if (mdev == this){
    WSGIwinAppDev()->setMouseFocusDev(NULL);
    onMouseOut();
  }
}
void WSDwinformDev::_evh_mouse_move(WinEvent* ev){
  WSDwinformDev* mdev = WSGIwinAppDev()->getMouseFocusDev();
//WSMFtrace("WSDwinformDev::_evh_mouse_move() this=0x%x focus_dev=0x%x\n",this,mdev);
  if (_mouse_val == 0){
    _mouse_val = (HCURSOR)WSGIappMouse()->getMouseCursor(0);
  }
//WSMFtrace("WSDwinformDev::_evh_mouse_move() this=0x%x mouse_no=0x%x 0x%x\n",this,_mouse_val,_mouse_no);
  SetCursor(_mouse_val);

  if (mdev == NULL){
    _evh_mouse_in(ev);
    return;
  }else if (mdev != this){
    mdev->_evh_mouse_out(ev);
    _evh_mouse_in(ev);
    return;
  }

  WSCpoint point;
  point.setPoint( (short)LOWORD(ev->lParam), (short)HIWORD(ev->lParam) );
//WSMFtrace("WSDwinformDev::_evh_mouse_move()  pt=%d,%d\n",point.x,point.y);

  WSCbool b1 =  (ev->uParam & MK_LBUTTON) != 0 ? True:False;
  WSCbool b2 =  (ev->uParam & MK_MBUTTON) != 0 ? True:False;
  WSCbool b3 =  (ev->uParam & MK_RBUTTON) != 0 ? True:False;

  long state = WSGIappMouse()->getStatus();
  if (b1){
    state |= WS_MOUSE_BTN1;
  }
  if (b2){
    state |= WS_MOUSE_BTN2;
  }
  if (b3){
    state |= WS_MOUSE_BTN3;
  }
  WSGIappMouse()->setStatus(state);

  onMouseMove(&point);
}

void WSDwinformDev::_evh_move(WinEvent* ev){
return;
#if 0
  if (_moved == 1){
    _moved = 0;
    return;
  }
  RECT r;
  GetClientRect(_wnd,&r);
WSMFtrace("WSDwinformDev::_evh_move 0x%x %d %d %d %d\n",this,r.left,r.top,r.right - r.left,r.bottom - r.top);
  WSCrect area;
  area.setRect(r.left,r.top,_w_w ,_w_h);
  onResize(&area);
#endif
}

void WSDwinformDev::_evh_resize(WinEvent* ev){
//  if (_resized == 1){
//    _resized = 0;
//    return;
//  }

  RECT r;
  GetClientRect(_wnd,&r);
  
//WSMFtrace("WSDwinformDev::_evh_resize 0x%x %d %d %d %d\n",this,r.left,r.top,r.right - r.left,r.bottom - r.top);
  WSCrect area;
  area.setRect(_w_x,_w_y,r.right - r.left ,r.bottom - r.top);
#if 0
  if (area.width >= 32760 || area.width < 3){
WSMFtrace("resize canceled.....\n");
    return;
  }
#endif
  _w_now = area.width;
  _h_now = area.height;
  _resize_sequence = True;
  onResize(&area);
  _resize_sequence = False;
}

void WSDwinformDev::_evh_expose(WinEvent* ev){
//WSMFtrace("WSDwinformDev::_evh_expose().. this=0x%x  getPixmapStyle()=%d\n",this,getPixmapStyle());
  PAINTSTRUCT ps;
  BeginPaint(_wnd,&ps);
#if 0
  HDC hdc = BeginPaint(_wnd,&ps);
  RECT r;
  GetClientRect(_wnd,&r);
  char buffer[1024];
  sprintf(buffer,"this=0x%x",this);
  DrawText(hdc,buffer,-1,&r,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
#endif

#if 0
   WSGIwinAppDev()->setWinEvent(ev);
   WSDwinformDev* dev = (WSDwinformDev*)ptr;

   if (dev->getAttachedClient() == NULL){
//WSMFtrace("WSDwinformDev::_evh_expose visible error! this=0x%x client=NULL\n",dev);
      dev->setVisible(False);
      return ;
   }

   if (dev->getAttachedClient()->getVisible() == False){
//WSMFtrace("WSDwinformDev::_evh_expose visible error!\n");
      dev->setVisible(False);
      return ;
   }

//WSMFtrace("WSDwinformDev::_evh_expose visible !\n");

   //GCが未初期化な場合、作成
   GC gc = dev->getGC();
   if (gc == 0){
      dev->createContext();
   }
#endif

  WSCrect area;
  area.setRect( (short)ps.rcPaint.left, (short)ps.rcPaint.top,
     (WSCushort)ps.rcPaint.right - ps.rcPaint.left,
     (WSCushort)ps.rcPaint.bottom - ps.rcPaint.top);
//WSMFtrace("winform::_evh_expose %d,%d %d,%d this=0x%x\n",area.x,area.y,area.width,area.height,this);
  setExposed(True);

  if (_exposed == False || getPixmapStyle() == WS_DIRECT_WINDOW){
    _clear_area(area.x, area.y, area.width, area.height);
  }

  onExpose(&area);
//WSMFtrace("winform::_evh_expose done.\n",area.x,area.y,area.width,area.height,this);

  EndPaint(_wnd,&ps);
}

void WSDwinformDev::_evh_btn_press(WinEvent* ev,int no){
//WSMFtrace("WSDwinformDev::_evh_btn_press() this=0x%x\n",this);
  WSCpoint point;
  point.setPoint( LOWORD(ev->lParam),HIWORD(ev->lParam));
  long clk = WSGFclocktime();
  WSCbool dclicked = False;
  if ((WSCulong)clk - (WSCulong)_click_time<250){
    dclicked = True;
  }
  _click_time = clk;
  if (_grabed == False){
    if (no == 4){
      WSGIappMouse()->setTargetBtn(WS_MOUSE_BTN4);
      WSCbase* fcl = WSGIappMouse()->getMouseFocusClient();
      if (fcl != NULL){
        fcl->onMousePress(&point);
      }
//WSMFtrace("WSDwinformDev::_evh_btn_press() done. this=0x%x\n",this);
      return;
    }else
    if (no == 5){
      WSGIappMouse()->setTargetBtn(WS_MOUSE_BTN5);
      WSCbase* fcl = WSGIappMouse()->getMouseFocusClient();
      if (fcl != NULL){
        fcl->onMousePress(&point);
      }
//WSMFtrace("WSDwinformDev::_evh_btn_press() done. this=0x%x\n",this);
      return;
    }
    WSGIwinAppDev()->setGrabedWnd(_wnd);
  }
  if (no == 4 || no == 5){
    return;
  }
//WSMFtrace("mouse press %d,%d\n",point.x,point.y);
  long state = WSGIappMouse()->getStatus();
//WSMFtrace("XXZZmb1 0x%x\n",no);
  if (no == 1){
    state |= WS_MOUSE_BTN1;
    WSGIappMouse()->setTargetBtn(WS_MOUSE_BTN1);
  }else
  if (no == 2){
    state |= WS_MOUSE_BTN2;
    WSGIappMouse()->setTargetBtn(WS_MOUSE_BTN2);
  }else
  if (no == 3){
    state |= WS_MOUSE_BTN3;
    WSGIappMouse()->setTargetBtn(WS_MOUSE_BTN3);
  }
  WSGIappMouse()->setStatus(state);

  onMousePress(&point);
  if (dclicked != False){
    onMouseDoubleClick(&point);
  }
}

void WSDwinformDev::_evh_btn_release(WinEvent* ev,int no){
//WSMFtrace("WSDwinformDev::_evh_btn_release() this=0x%x\n",this);
//printf("WSDwinformDev::_evh_btn_release() this=0x%x\n",this);
//printf("WSDwinformDev::_evh_btn_release() drop is not implemented..\n");
  WSCpoint point;
  point.setPoint( LOWORD(ev->lParam),HIWORD(ev->lParam) );
  if (_grabed == False){
    WSGIwinAppDev()->setGrabedWnd(NULL);
  }
  WSDwinDragDrop* xdd = WSGIwinAppDragDrop();
  if (xdd != NULL){
    if (xdd->getDragState() != 0){
      xdd->executeDrop();
      return;
    }
  }

  long state = WSGIappMouse()->getStatus();
  if (no == 1){
    state &= ~WS_MOUSE_BTN1;
    WSGIappMouse()->setTargetBtn(WS_MOUSE_BTN1);
  }else
  if (no == 2){
    state &= ~WS_MOUSE_BTN2;
    WSGIappMouse()->setTargetBtn(WS_MOUSE_BTN2);
  }else
  if (no == 3){
    state &= ~WS_MOUSE_BTN3;
    WSGIappMouse()->setTargetBtn(WS_MOUSE_BTN3);
  }
  WSGIappMouse()->setStatus(state);

  onMouseRelease(&point);

}


void WSDwinformDev::_evh_dummy(WinEvent*){
}

void WSDwinformDev::_evh_delete(WinEvent* ev){
dbprintf("WSDwinformDev::_evh_delete %s:%d start\n",__FILE__,__LINE__);
  _pwnd = 0;
  _wnd = 0;
  setInitialized(False);
#if 0
  if (ev->type == ClientMessage){
    if (ev->xclient.message_type ==  XInternAtom(XtDisplay(w),"WM_PROTOCOLS",False) &&
        (WSCulong)ev->xclient.data.l[0] == XInternAtom(XtDisplay(w),"WM_DELETE_WINDOW",False)){
      WSDwinformDev* dev = (WSDwinformDev*)ptr;
      dev->onUnmap();
    }
  }
#endif
dbprintf("WSDwinformDev::_evh_delete %s:%d done\n",__FILE__,__LINE__);
}


void WSDwinformDev::_evh_delete2(void* ptr){
dbprintf("WSDwinformDev::_evh_delete2 %s:%d start\n",__FILE__,__LINE__);
   WSDwinformDev* dev = (WSDwinformDev*)ptr;

   dev->_pwnd = 0;
   dev->_wnd = 0;
   dev->setInitialized(False);
//   dev->detachClient();
dbprintf("WSDwinformDev::_evh_delete2 %s:%d done\n",__FILE__,__LINE__);
}

void WSDwinformDev::setHWND(HWND w){
  _wnd = w;
}
long WSDwinformDev::beginDraw(short x,short y,WSCushort w,WSCushort h,WSCbool absolute,WSCbool scaling){
  if ((short)w < 1){
    return WS_ERR;
  }
  if ((short)h < 1){
    return WS_ERR;
  }
//WSMFtrace("WSDwinformDev::beginDraw this=0x%x  XXZZ44x st=%d %d,%d,%d,%d %s\n",this,getPixmapStyle(),x,y,w,h,getAttachedClient()->getInstanceName());
  if (_exposed == False){
    return WS_ERR;
  }
  if (w == 23767){
    return WS_ERR;
  }
  if (h == 23767){
    return WS_ERR;
  }
  if (_wnd == 0){
    return WS_ERR;
  }

  if (getPixmapStyle() != WS_DIRECT_WINDOW){
    long ret = WS_NO_ERR;
    if (_mdc == 0){
      ret = createPixmap();
    }
    if (ret != WS_NO_ERR){
      setPixmapStyle(WS_DIRECT_WINDOW);
      _dc = GetDC(_wnd);
WSMFtrace("WSDwinformDev::beginDraw this=0x%x  error _dc=0x%x XXabc1\n",this,_dc);
    }
  }else{
    _dc = GetDC(_wnd);
  }
  return WSDwindowDev::beginDraw(x,y,w,h,absolute,scaling);
}
long WSDwinformDev::endDraw(){
  WSDwindowDev::endDraw();
  if (_dc != 0){
    ReleaseDC(_wnd,_dc);
    _dc = 0;
  }
  return WS_OK;
}
void WSDwinformDev::invalidate(WSCbool fl){
  if (_wnd == 0){
    return;
  }
  RECT r;
  GetClientRect(_wnd,&r);
  InvalidateRect(_wnd,&r,fl);
  setExposed(False);
  return;
}
void WSDwinformDev::_clear_and_expose(){
  WSCrect r;
  r.setRect(0,0,_w_w,_w_h);
  _clear_area(0,0,_w_w,_w_h);
  setExposed(True);
  onExpose(&r);
}
long WSDwinformDev::raise(){
  if (_wnd == 0){
    return WS_ERR;
  }
  SetWindowPos(_wnd,HWND_TOP,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
  return WS_NO_ERR;
}
long WSDwinformDev::lower(){
  if (_wnd == 0){
    return WS_ERR;
  }
  SetWindowPos(_wnd,HWND_BOTTOM,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
  return WS_NO_ERR;
}

void WSDwinformDev::_expose_children(int x,int y,unsigned long w,unsigned long h){
  WSCbase* client = getAttachedClient();
  if (client == NULL){
    return;
  }

  WSClistData list = client->getChildren();
  long i;
  long num = list.getNum();
  for(i=0; i<num; i++){
    WSCbase* child = (WSCbase*)list[i];
    if (child->getVisible() == False){
      continue;
    }
    WSDdev* dev = child->getdev();
    if (dev == NULL){
      continue;
    }
    WSDwinformDev* wdev =(WSDwinformDev*)dev->cast("WSDwinformDev");
    if (wdev == NULL){
      continue;
    }
    long ex,ey;
    unsigned long ew,eh;
    short dx,dy;
    unsigned short dw,dh;
    wdev->getWindowSize(&dx,&dy,&dw,&dh);
    WSGFandArea(0,0,w,h,dx,dy,dw,dh,
                &ex,&ey,&ew,&eh);
    if (ew != 0 && eh != 0){
      wdev->exposeArea(ex-dx,ey-dy,ew,eh);
      wdev->_expose_children(ex-dx,ey-dy,ew,eh);
    }
  }
}
