//
// 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 <Carbon/Carbon.h>
#include <WSCdevice.h>
#include <WSCimageSet.h>
#include <WSCcolorSet.h>
#include <WSDtimer.h>
#include <WSCbase.h>
#include <WSDmouse.h>
#include <WSClocaleSet.h>
#include <mac/WSmcom.h>
#include <mac/WSDmacWinDev.h>
#include <mac/WSDmacAppDev.h>
#include <mac/WSDmacDraw.h>
//#include <mac/Shell.h>
//#include <mac/StringDefs.h>
//#include <form.h>

//#if 1 //UNICODE
//#include <xunicode.h>
//#endif //UNICODE

WSMFclassInit(WSDmacWinDev,WSDmacFormDev);
WSDdev* _wsdmacWindev_init_(){
  return new WSDmacWinDev();
}

class _WSDmacWinDev_init_ {
  public:_WSDmacWinDev_init_(){
     WSGIappDevice()->setCreateHandler("windowDev",_wsdmacWindev_init_);
  };
};
static _WSDmacWinDev_init_ _init_to_run_WSDmacWinDev_;
//static Atom wm_protocols = 0;
//static Atom wm_delete = 0;

WSDmacWinDev::WSDmacWinDev(){
//  _mouse_press_target = NULL;
//  _mouse_move_target = NULL;
  _is_win = True;
  _already_exposed = False;
  _win  = 0;
  _win2  = 0;
  _dialog  = 0;
//  _widget  = 0;
  _title_bar_style = 0;
  _no_frame = 0;
  _no_frame_first_time = 0;
  _requested_top = 0;
  _transient = False;
  _top_float = 0;
  _modal = 0;
//  _sizehints = NULL;
  _title_bar = 0;
  _setv = kWindowStandardDocumentAttributes;
//  _setv = kWindowIgnoreClicksAttribute;
//  _setv = kWindowNoConstrainAttribute;
//  _setv = kWindowInWindowMenuAttribute;
//  _setv = kWindowHideOnFullScreenAttribute;
//  _setv = kWindowNoShadowAttribute;
//  _setv = kWindowCompositingAttribute;
//  _setv = kWindowNoActivatesAttribute;
//  _setv = kWindowNoUpdatesAttribute;
//  _setv = kWindowMetalAttribute;
//  _setv = kWindowSideTitlebarAttribute;
  _clv = 0;
//  _win_type = kDocumentWindowClass;
//  _win_type = kHelpWindowClass;
  _win_type = 6;
}

WSDmacWinDev::~WSDmacWinDev(){
  destroyWindow();
}

WSDdev* WSDmacWinDev::getVisibleParentDev(){
  return this;
}

long WSDmacWinDev::setValue(long kind,void* data){
  short val;
  switch(kind){
    case WSDEV_Y: 
      if (_no_frame == False){
//        val = *(short*)data + _diff_y;
        val = *(short*)data;
      }else{
        val = *(short*)data;
      }
{ //XXZZ
printf("WSDmacWinDev::setValue y=%d _diff_y=%d XXZZy1 %s\n",val,_diff_y,getAttachedClient()->getInstanceName());
WSCbase* client = getAttachedClient();
if (client != NULL){
WSCbase* parent = client->getParentWindow();
  if (parent != NULL){
printf("WSDmacWinDev::setValue y=%d XXZZy13\n",(long)parent->getProperty(WSNy));
  }
}
if (val==226){
long* ptr=0;
//long tmp =*ptr;
}
}
      WSDwindowDev::setValue(kind,(void*)&val);
      break;
    default:
      WSDwindowDev::setValue(kind,data);
  }
  switch(kind){
    case WSDEV_X: 
    case WSDEV_Y: {
       if (_win != NULL){
printf("WSDmacWinDev::setValue x,y=%d,%d _diff_y=%d XXZZy1\n",_w_x,_w_y,_diff_y);
         MoveWindow(_win,_w_x,_w_y,false);
         Rect tr;
         GetWindowBounds(_win,kWindowContentRgn,&tr);
         Rect tr2;
         GetWindowBounds(_win,kWindowStructureRgn,&tr2);
         if (_no_frame == False){
           _diff_x = tr.left - tr2.left;
           _diff_y = tr.top - tr2.top;
           MoveWindow(_win,_w_x,_w_y + _diff_y,false);
           MoveWindow(_win2,_w_x,_w_y,false);
printf("WSDmacWinDev::setValue x,y=%d,%d _diff_y=%d XXZZy12\n",_w_x,_w_y-_diff_y,_diff_y);
         }else{
           _diff_x = 0;
           _diff_y = 0;
           _diff_x2 = tr.left - tr2.left;
           _diff_y2 = tr.top - tr2.top;
           MoveWindow(_win,_w_x,_w_y + _diff_y2,false);
           MoveWindow(_win2,_w_x,_w_y,false);
         }
printf("WSDmacWinDev::setValue get y=%d diff_x,y=%d,%d \n",tr.top,_diff_x,_diff_y);
         
       }
       break;
    }
    case WSDEV_WIDTH: 
    case WSDEV_HEIGHT: 
       if (_win != NULL){
printf("WSDmacWinDev::setValue w,h=%d,%d\n",_w_w,_w_h);
         SizeWindow(_win,_w_w,_w_h,false);
         SizeWindow(_win2,_w_w,_w_h,false);
         _clear_area(0,0,_w_w,_w_h);
       }
       break;
    case WSDEV_BACKCOLOR:{
       _bg = *(short*)data;
       WSDcolor* color = WSGIappColorSet()->getColor(*(short*)data);
       if (color != NULL){
         RGBColor* col = (RGBColor*)color->getValue1();
         if (col != NULL){
           _bgc.red = col->red;
           _bgc.green = col->green;
           _bgc.blue = col->blue;
printf("%s %d color=%x %x %x\n",__FILE__,__LINE__,_bgc.red,_bgc.green,_bgc.blue);
         }
         if (_win != NULL){
           SetWindowContentColor(_win,&_bgc);
         }
         if (_win2 != NULL){
           SetWindowContentColor(_win2,&_bgc);
         }
       }
       break;
    }
    case WSDEV_TITLE_STRING:{
      char* vstr = (char*)data;
      if (_win != NULL){
        Str255 buffer;
        c2pstrcpy(buffer,vstr);
        SetWTitle( _win,buffer);
      }
       break;
    }
    case WSDEV_NO_FRAME: {
      _top_float = False;
      if (*(char*)data == False &&
           _no_frame != False &&
           _win != NULL){
        break;
      }
      WSCbool vis = getVisible();
      if (vis != False){
        setVisible(False);
      }
      _no_frame = *(char*)data;
      if (_no_frame != False && _win != NULL){
        _diff_x2 = _diff_x;
        _diff_y2 = _diff_y;
        _diff_x = 0;
        _diff_y = 0;
      }
//        short val = _w_y - _diff_y2;
//        WSDwindowDev::setValue(WSDEV_Y,&val);
//        MoveWindow(_win2,_w_x,_w_y - _diff_y2,false);
printf("WSDmacWinDev::setValue NO_FRAME val=_w_y=%d _diff_y=%d _diff_y2=%d XXZZy17\n",_w_y,_diff_y,_diff_y2);
      if (vis != False){
        setVisible(True);
      }
      break;
    }
    case WSDEV_FLOAT_ON_TOP:{
      if (*(char*)data == False){
         _top_float = False;
      }else{
         _top_float = True;
      }
//printf("WSDmacWinDev::setValue FLOAT_ON_TOP %d\n",_top_float);
      break;
    }
    case WSDEV_TITLE_BAR:{
      char val = *(char*)data;
      _title_bar =val;
      if (val != WS_NO_TITLE){
        if (_no_frame != False){
printf("WSDmacWinDev::setValue NO_TITLE no_frame -> 0 XXZZy17\n");
          _no_frame = False;
          _diff_x = _diff_x2;
          _diff_y = _diff_y2;
        }
      }
      switch(val){
        case WS_NO_TITLE:{
printf("WSDmacWinDev::setValue D2 TITLE_BAR no title..\n");
          _setv = kWindowNoAttributes;
          _clv = kWindowStandardDocumentAttributes;
          if (_no_frame == False){
            _diff_x2 = _diff_x;
            _diff_y2 = _diff_y;
            _diff_x = 0;
            _diff_y = 0;
            WSCbool vis = getVisible();
            if (vis != False){
              setVisible(False);
            }
            _no_frame = 1;
//            short val = _w_y - _diff_y2;
//            WSDwindowDev::setValue(WSDEV_Y,&val);
//            MoveWindow(_win2,_w_x,_w_y - _diff_y2,false);
printf("WSDmacWinDev::setValue NO_TITLE y=%d diff_y2=%d XXZZy17\n",_w_y,_diff_y2);
            if (vis != False){
              setVisible(True);
            }
          }
          _no_frame = 1;

//          if (_win != NULL){
//            SetWindowClass(_win,_win_type);
//          }
          break;
        }
        case WS_ONLY_TITLE:{
          break;
        }
        case WS_MINI_BTN:{
          break;
        }
        case WS_MAX_BTN:{
          break;
        }
        case WS_FRAME:{
          break;
        }
        case WS_FULL_TITLE:
        default:{
printf("WSDmacWinDev::setValue TITLE_BAR full title..\n");
          _setv = kWindowStandardDocumentAttributes;
          _clv = kWindowNoAttributes;
          break;
        }
      }
      if (_no_frame == False){
        if (_win != NULL){
printf("WSDmacWinDev::setValue TITLE_BAR D2 set title..\n");
          ChangeWindowAttributes(_win,_setv,_clv);
        }
      }
      break;
    }
  }
#if 0 //XXZZ
  Arg args[4];
  char val;
  long vl;
  char* vstr;
  WSDcolor* color;
  WSDimage* image;
  XWindowChanges wc;
  WSCbase* pparent;
  WSDmacWinDev*  pdev;
  Widget    pwidget;
  WSCbool   fl;
  WSCstring tmpstr;
  switch(kind){
    case WSDEV_X: 
             if (getVisible() == False){
               _diff_x = 0;
             }
             if (_swidget != 0){
               if (getVisible() != False){
                 XtSetArg(args[0],XtNx,*(short*)data);
                 XtSetValues((Widget)_swidget,args,1);
               }
             }
             break;
    case WSDEV_Y:
             if (getVisible() == False){
               _diff_y = 0;
             }
             if (_swidget != 0){
               if (getVisible() != False){
                 XtSetArg(args[0],XtNy,*(short*)data);
                 XtSetValues((Widget)_swidget,args,1);
               }
             }
             break;
    case WSDEV_WIDTH:
             if (_swidget != 0){
               if (getVisible() != False && *(WSCushort*)data > 0){

                 WSCushort val;
                 XtSetArg(args[0],XtNwidth,&val);
                 XtGetValues((Widget)_swidget,args,1);
                 if ( *(WSCushort*)data != val){
                   XtSetArg(args[0],XtNwidth,*(WSCushort*)data);
                   XtSetValues((Widget)_swidget,args,1);
                 }
               }
             }
             break;
    case WSDEV_HEIGHT:
WSMFtrace("WSCmacWinDev::setValue height=%d _w_h=%d\n",*(WSCushort*)data,_w_h);
             if (_swidget != 0){
               if (getVisible() != False && *(WSCushort*)data > 0){
                 WSCushort val;
                 XtSetArg(args[0],XtNheight,&val);
                 XtGetValues((Widget)_swidget,args,1);
                 if ( *(WSCushort*)data != val){
                   XtSetArg(args[0],XtNheight,*(WSCushort*)data);
                   XtSetValues((Widget)_swidget,args,1);
                 }
               }
             }
             break;
    case WSDEV_BACKCOLOR:
             _bg = *(short*)data;
             color = WSGIappColorSet()->getColor(*(short*)data);
             if (color != NULL && _widget != NULL){
               XtSetArg(args[0],XtNbackground,color->getValue1());
               XtSetValues((Widget)_widget,args,1);
             }
             break;
    case WSDEV_BACK_PIXMAP:
             _bg_pix = *(short*)data;
             if (_widget == NULL){
               break;
             }
             if (*(short*)data == -2 ){
               XtSetArg(args[0],XtNbackgroundPixmap,0);
               XtSetValues((Widget)_widget,args,1);
             }else
             if (*(short*)data == -1 ){
               XtSetArg(args[0],XtNbackgroundPixmap,UNSPECIFIED_PIXMAP);
               XtSetValues((Widget)_widget,args,1);
             }else{
               image = WSGIappImageSet()->getImage(*(short*)data);
               if (image != NULL){
                 if (image->getValue1() == -1){
                   XtSetArg(args[0],XtNbackgroundPixmap,UNSPECIFIED_PIXMAP);
                 }else{
                   XtSetArg(args[0],XtNbackgroundPixmap,image->getValue1());
                 }
                 XtSetValues((Widget)_widget,args,1);
               }
             }
             break;
    case WSDEV_TITLE_BAR:
             val = *(char*)data;
             _title_bar = val;
             switch(val){
               case WS_NO_TITLE:   vl = 0; break;
               case WS_FULL_TITLE: vl = 1; break;
               case WS_ONLY_TITLE: vl = 8; break;
               case WS_MINI_BTN:   vl = 40; break;
               case WS_MAX_BTN:    vl = 104; break;
               case WS_FRAME:      vl = 4; break;
               default: vl = 1;
             };
#if 0 //DEVELOP
             if ((Widget)_widget != (Widget)NULL){
               XtSetArg(args[0],"mwmDecorations",vl);
               XtSetValues((Widget)_swidget,args,1);
             }
#endif
             _title_bar_style = vl;
             if (vl == 0){
               _diff_x = 0;
               _diff_y = 0;
             }
             break;
    case WSDEV_TITLE_STRING:
             vstr = (char*)data;
             if ((Widget)_swidget != (Widget)NULL){
               tmpstr.setString(vstr,WSGIappLocaleSet()->getDefaultEncoding());
               XtSetArg(args[0],XtNtitle,
                   tmpstr.getString(WSGIappLocaleSet()->getSystemLocaleEncoding()));
               XtSetValues((Widget)_swidget,args,1);
             }

             break;
    case WSDEV_NO_FRAME:  
             _top_float = False;
             if (*(char*)data == False &&
                  _no_frame != False &&
                  (Widget)_swidget != (Widget)NULL){
               //In this case,if it sets this data,it will be curruped.
               break;
             }
             _no_frame = *(char*)data;
             if (_no_frame != False && (Widget)_swidget != (Widget)NULL){
               XtSetArg(args[0],XtNoverrideRedirect,True);
               XtSetValues((Widget)_swidget,args,1);
               _no_frame_first_time = True;
             }else if (_no_frame == True && (Widget)_swidget == (Widget)NULL){
               _no_frame_first_time = True;
             }else if (_no_frame == False && (Widget)_swidget == (Widget)NULL){
               _no_frame_first_time = False;
             }
             break;
    case WSDEV_POPUP_PARENT: 
             pparent = (WSCbase*)data;
             if (pparent != NULL){
               if (pparent->getowndev() != NULL ){
                 pdev = (WSDmacWinDev*)pparent->getowndev()->cast("WSDmacWinDev");
                 if (pdev != NULL){
                   pwidget = pdev->_swidget;
                   if ( (Widget)_swidget != (Widget)NULL && pwidget != (Widget)NULL){
                     XtSetArg(args[0],XtNtransient,True);
                     XtSetArg(args[1],XtNtransientFor,pwidget);
                     XtSetValues(_swidget,args,2);
                     _transient = True;
                   }
                 }
               }
             }else if (_transient != False){
               if ( (Widget)_swidget != (Widget)NULL ){
                 XtSetArg(args[0],XtNtransient,False);
                 XtSetValues(_swidget,args,1);
                 _transient = False;
               }
             }
             break;
    case WSDEV_MAP_STATUS: 
             if (getVisible()== True){
                if (*(long*)data == WS_TOP){
                  wc.stack_mode = TopIf;
                }else{
                  wc.stack_mode = BottomIf;
                }
                XConfigureWindow(XtDisplay((Widget)_swidget),XtWindow((Widget)_swidget),CWStackMode,&wc);
             }
             break;
    case WSDEV_WIN_ACTIVE: 
             if (getVisible()== True){
                if (*(char*)data == True){
                  XSetInputFocus(XtDisplay((Widget)_swidget),XtWindow((Widget)_swidget),
                                 RevertToParent,CurrentTime);
                }
             }
             break;
    case WSDEV_FLOAT_ON_TOP:
             if (*(char*)data == False){
                _top_float = False;
             }else{
                _top_float = True;
             }
//printf("WSDmacWinDev::setValue FLOAT_ON_TOP %d\n",_top_float);
             break;
    case WSDEV_GRAB_POINTER:
             if (_widget == NULL){
               break;
             }
             fl = *(WSCbool*)data;
             if (fl != False){
               XGrabPointer(XtDisplay(_widget),XtWindow(_widget),False,
                            ButtonPressMask | ButtonReleaseMask | PointerMotionMask,
                            GrabModeAsync,GrabModeAsync,None,None,CurrentTime);
               XGrabKeyboard(XtDisplay(_widget),XtWindow(_widget),False,
                            GrabModeAsync,GrabModeAsync,CurrentTime);
             }else{
               XUngrabPointer(XtDisplay(_widget),CurrentTime);
               XUngrabKeyboard(XtDisplay(_widget),CurrentTime);
             }
             break;
    case WSDEV_MODAL:
             if (*(char*)data == False){
               _modal = False;
             }else{
               _modal = True;
             }
             if (_widget == NULL){
               break;
             }
//printf("WSDmacWinDev::setValue modal=%d\n",_modal);
             XtSetArg(args[0],"dialogStyle",_modal);
             XtSetValues(_swidget,args,1);
             break;
    case WSDEV_WINDOW_STATE:
             vl = *(long*)data;
             if (_swidget != NULL){
               if (getVisible() == False){
                 return WS_ERR;
               }
               if (vl == WS_WINDOW_MINIMIZE){
                 XIconifyWindow(XtDisplay(_swidget),XtWindow(_swidget), 0);
               }else{
                 XMapWindow(XtDisplay(_swidget),XtWindow(_swidget));
               }
               return WS_NO_ERR;
             }else{
               return WS_ERR;
             }
    default:
      return WS_ERR;
  }
#endif //XXZZ
printf("WSDmacWinDev::setValue not supported.. %s %d\n",__FILE__,__LINE__);
  return WS_NO_ERR;
}

long WSDmacWinDev::createWindow(){
  OSErr error = noErr;
  Rect windowRect;
  _diff_y = 0;
  _already_exposed = False;
  SetRect(&windowRect,_w_x,_w_y,_w_w,_w_h);
//TEST
//_no_frame = 1;

  _dialog = NewDialog(NULL,&windowRect,"",false,kWindowPlainDialogProc,
//    _dialog = NewDialog(NULL,&windowRect,"",true,kWindowDocumentProc,
                  -1,false, (long)((WSDmacFormDev*)this),0);
  _win2 = GetDialogWindow(_dialog);
printf("WSDmacWinDev::createWindow D2 _dialog. 0x%x\n",_dialog);
//    SetPortWindowPort( _win );
//XXZZ

printf("WSDmacWinDev::createWindow D2 _win_type %d\n",_win_type);
//TEST

  error = CreateNewWindow( _win_type,
                           kWindowStandardDocumentAttributes,
                           &windowRect,&_win);

// Set ResizeLimits..
  if (error != noErr){
    return WS_ERR;
  }
  if (_setv != kWindowStandardDocumentAttributes ||
    _clv != kWindowNoAttributes ){
    ChangeWindowAttributes(_win,_setv,_clv);
  }

//  GetWindowBounds(_win,kWindowStructureRgn,&windowRect);
  GetWindowBounds(_win,kWindowContentRgn,&windowRect);
  _diff_y = windowRect.top - _w_y;
printf("WSDmacWinDev::createWindow y=%d _w_y=%d diff_y=%d\n",windowRect.top,_w_y,_diff_y);
  SetWindowContentColor(_win,&_bgc);

  _rect.x = 0;
  _rect.y = 0;
  _rect.width = _w_w;
  _rect.height = _w_h;
  SetWRefCon(_win,(long)((WSDmacFormDev*)this));

//  SetRect(&windowRect,0,0,_w_w,_w_h);
//  error = CreateUserPaneControl(_win,&windowRect,0,&_cntl);

//printf("WSDmacWinDev::createWindow _win=0x%x _cntl=0x%x\n",_win,_cntl);
printf("WSDmacWinDev::createWindow _win=0x%x\n",_win);

  if (error == noErr){

//    SetWRefCon(_win,_cntl); //setUserData..

    error = RepositionWindow( _win, NULL, kWindowCascadeOnMainScreen);
    Str255 tstr;
    c2pstrcpy(tstr,"");
    SetWTitle( _win,tstr);
//TEST
//    SetPortWindowPort( _win );
//    ActivateControl(_cntl);

    EventTypeSpec eventTypes[20];

    eventTypes[0].eventClass = kEventClassMouse;
    eventTypes[0].eventKind = kEventMouseUp;
    error = InstallEventHandler(GetWindowEventTarget(_win),
                              NewEventHandlerUPP(_evh_mouse_released),
                              1,eventTypes, this,NULL);
    error = InstallEventHandler(GetWindowEventTarget(_win2),
                              NewEventHandlerUPP(_evh_mouse_released),
                              1,eventTypes, this,NULL);

    eventTypes[0].eventClass = kEventClassMouse;
    eventTypes[0].eventKind = kEventMouseDown;
    error = InstallEventHandler(GetWindowEventTarget(_win),
                              NewEventHandlerUPP(_evh_mouse_pressed),
                              1,eventTypes, this,NULL);
    error = InstallEventHandler(GetWindowEventTarget(_win2),
                              NewEventHandlerUPP(_evh_mouse_pressed),
                              1,eventTypes, this,NULL);

    eventTypes[0].eventClass = kEventClassMouse;
    eventTypes[0].eventKind = kEventMouseMoved;
    error = InstallEventHandler(GetWindowEventTarget(_win),
                              NewEventHandlerUPP(_evh_mouse_moved),
                              1,eventTypes, this,NULL);
    error = InstallEventHandler(GetWindowEventTarget(_win2),
                              NewEventHandlerUPP(_evh_mouse_moved),
                              1,eventTypes, this,NULL);

    eventTypes[0].eventClass = kEventClassMouse;
    eventTypes[0].eventKind = kEventMouseEntered;
    error = InstallEventHandler(GetWindowEventTarget(_win),
                              NewEventHandlerUPP(_evh_mouse_entered),
                              1,eventTypes, this,NULL);
    error = InstallEventHandler(GetWindowEventTarget(_win2),
                              NewEventHandlerUPP(_evh_mouse_entered),
                              1,eventTypes, this,NULL);

    eventTypes[0].eventClass = kEventClassMouse;
    eventTypes[0].eventKind = kEventMouseExited;
    error = InstallEventHandler(GetWindowEventTarget(_win),
                              NewEventHandlerUPP(_evh_mouse_leaved),
                              1,eventTypes, this,NULL);
    error = InstallEventHandler(GetWindowEventTarget(_win2),
                              NewEventHandlerUPP(_evh_mouse_leaved),
                              1,eventTypes, this,NULL);

    eventTypes[0].eventClass = kEventClassWindow;
    eventTypes[0].eventKind = kEventWindowUpdate;
    error = InstallEventHandler(GetWindowEventTarget(_win),
                              NewEventHandlerUPP(_evh_exposed),
                              1,eventTypes, this,NULL);
    error = InstallEventHandler(GetWindowEventTarget(_win2),
                              NewEventHandlerUPP(_evh_exposed),
                              1,eventTypes, this,NULL);
#if 0
    eventTypes[0].eventClass = kEventClassWindow;
    eventTypes[0].eventKind = kEventWindowResizeCompleted;
    error = InstallEventHandler(GetWindowEventTarget(_win),
                              NewEventHandlerUPP(_evh_resized),
                              1,eventTypes, this,NULL);
    error = InstallEventHandler(GetWindowEventTarget(_win2),
                              NewEventHandlerUPP(_evh_resized),
                              1,eventTypes, this,NULL);
#endif
    eventTypes[0].eventClass = kEventClassMouse;
    eventTypes[0].eventKind = kEventMouseDragged;
    error = InstallEventHandler(GetWindowEventTarget(_win),
                              NewEventHandlerUPP(_evh_mouse_dragged),
                              1,eventTypes, this,NULL);
    error = InstallEventHandler(GetWindowEventTarget(_win2),
                              NewEventHandlerUPP(_evh_mouse_dragged),
                              1,eventTypes, this,NULL);

    eventTypes[0].eventClass = kEventClassMouse;
    eventTypes[0].eventKind = kEventMouseWheelMoved;
    error = InstallEventHandler(GetWindowEventTarget(_win),
                              NewEventHandlerUPP(_evh_mouse_wheel_moved),
                              1,eventTypes, this,NULL);
    error = InstallEventHandler(GetWindowEventTarget(_win2),
                              NewEventHandlerUPP(_evh_mouse_wheel_moved),
                              1,eventTypes, this,NULL);

#if 0
    eventTypes[1].eventClass = kEventClassMouse;
    eventTypes[1].eventKind = kEventMouseMoved;
    eventTypes[2].eventClass = kEventClassMouse;
    eventTypes[2].eventKind = kEventMouseDragged;
    eventTypes[3].eventClass = kEventClassMouse;
    eventTypes[3].eventKind = kEventMouseDown;
    eventTypes[4].eventClass = kEventClassMouse;
    eventTypes[4].eventKind = kEventMouseWheelMoved;

    eventTypes[5].eventClass = kEventClassMouse;
    eventTypes[5].eventKind = kEventMouseEntered;

    eventTypes[6].eventClass = kEventClassMouse;
    eventTypes[6].eventKind = kEventMouseExited;

    eventTypes[7].eventClass = kEventClassWindow;
    eventTypes[7].eventKind = kEventWindowUpdate;

//    eventTypes[7].eventClass = kEventClassWindow;
//    eventTypes[7].eventKind = kEventWindowDrawContent;



    error = InstallEventHandler(GetWindowEventTarget(_win),
                              NewEventHandlerUPP(_handle_events_),
                              8,eventTypes,
                              this,NULL);
#endif
#if 0
    EventTypeSpec eventTypes[4];
    eventTypes[0].eventClass = kEventClassMouse;
    eventTypes[0].eventKind = kEventMouseMoved;
    error = InstallEventHandler(GetWindowEventTarget(_win),
                              NewEventHandlerUPP(_handle_events_),
                              1,eventTypes,
                              this,NULL);
#endif
  }else{
    if (_win ){
      DisposeWindow(_win);
      ReleaseWindow(_win);
    }
    if (_dialog){
      DisposeDialog(_dialog); 
    }
    _dialog = NULL;
    _win = NULL;
    _win2 = NULL;
  }

printf("WSDmacWinDev::createWindow isnot set enough event handler.. %s %d\n",__FILE__,__LINE__);

  

#if 0 //XXZZ
  if (_swidget != 0){
    return WS_NO_ERR;
  }
  _no_frame_first_time = 0;
//  _top_float = False;

  short x,y;    
  WSCushort w,h;    
  getWindowSize(&x,&y,&w,&h);
  if (w == 0){
    w = 1;
  }
  if (h == 0){
    h = 1;
  }
  _transient = False;

  Arg args[10];
  long anum=0;
  XtSetArg(args[anum],XtNinput,True);anum++;
  XtSetArg(args[anum],XtNtransient,False);anum++;
  XtSetArg(args[anum],XtNx,x);anum++;
  XtSetArg(args[anum],XtNy,y);anum++;
  XtSetArg(args[anum],XtNwidth,w);anum++;
  XtSetArg(args[anum],XtNheight,h);anum++;
  XtSetArg(args[anum],"mwmDecorations",_title_bar_style);anum++;
  XtSetArg(args[anum],"dialogStyle",_modal);anum++;

  if (_title_bar_style == 0 && _no_frame == 1){
    XtSetArg(args[anum],XtNoverrideRedirect,True);anum++;
  }else{
    XtSetArg(args[anum],XtNoverrideRedirect,False);anum++;
  }
  XtSetArg(args[anum],XtNborderWidth,0); anum++;
  WSDxappDev* app = WSGImacWinAppDev(); 
  Widget parent = app->appWidget();
  WSDxformDev* xdev = getParentAreaDev();
  if (xdev != NULL){
    parent = xdev->getWidget();
  }

  _swidget = XtCreatePopupShell ( "wsshell", transientShellWidgetClass, parent,
               (ArgList)args, anum );
  XtAddEventHandler(_swidget,StructureNotifyMask | SubstructureNotifyMask,False,(XtEventHandler)_evh_resize,this);
  XtAddEventHandler(_swidget,FocusChangeMask,False,(XtEventHandler)_evh_focus_ch,this);
  XtAddEventHandler(_swidget,NoEventMask,True,(XtEventHandler)_evh_client_message,this);

  anum =0;
  if (_bg != -1){
    WSDcolor* color = WSGIappColorSet()->getColor(_bg);
    if (color != NULL){
       XtSetArg(args[anum],XtNbackground,color->getValue1()); anum++;
    }
  }
  if (_bg_pix == -1){
    XtSetArg(args[anum],XtNbackgroundPixmap,UNSPECIFIED_PIXMAP); anum++;
  }else{
    WSDimage*  image = WSGIappImageSet()->getImage(_bg_pix);
    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++;
  _widget = XtCreateWidget ( "wswina", formWidgetClass, _swidget,args,anum);
  XtManageChild(_widget);
  XtAddEventHandler(_widget,ExposureMask,False,(XtEventHandler)_evh_expose,this);
  XtAddEventHandler(_widget,ButtonPressMask,False,(XtEventHandler)_evh_btn_press,(WSDxformDev*)this);
  XtAddEventHandler(_widget,ButtonReleaseMask,False,(XtEventHandler)_evh_btn_release,(WSDxformDev*)this);
  XtAddEventHandler(_widget,ButtonMotionMask | PointerMotionMask,False,(XtEventHandler)_evh_mouse_move,(WSDxformDev*)this);
  XtAddEventHandler(_widget,EnterWindowMask,False,(XtEventHandler)_evh_mouse_in,this);
  XtAddEventHandler(_widget,LeaveWindowMask,False,(XtEventHandler)_evh_mouse_out,(WSDxformDev*)this);
  XtAddEventHandler(_widget,KeyPressMask | KeyReleaseMask,False,(XtEventHandler)_evh_dummy,(WSDxformDev*)this);
  XtAddCallback(_widget,XtNdestroyCallback,_evh_delete2,this);
  return WS_NO_ERR;
#endif //XXZZ
  return WS_ERR;
}

long WSDmacWinDev::destroyWindow(){
  WSDmacFormDev::destroyWindow();
  if (_dialog != NULL){
    DisposeDialog(_dialog); 
  }
  if (_win != NULL){
    DisposeWindow(_win);
    ReleaseWindow(_win);
  }
  _dialog = NULL;
  _win = NULL;
  _win2 = NULL;
  _already_exposed = False;
  return WS_NO_ERR;
}

#if 0 //XXZZ
void WSDmacWinDev::_float_top_timer_proc(WSCuchar,void* data){
  WSDmacWinDev* dev = (WSDmacWinDev*)data;
  WSCbool fl = _chk_popup(dev);
  if (fl == False){
    dev->_requested_top = 0;
    return;
  }
  if (dev->getVisible() != False &&
      dev->_swidget != 0 ){
    XWindowChanges wc;
    wc.stack_mode = TopIf;
    if (dev->_top_float != False){
      XConfigureWindow(XtDisplay(dev->_swidget),XtWindow(dev->_swidget),CWStackMode,&wc);
    }
    WSGIappTimer()->addTriggerProc(_float_top_timer_proc,WS500MS,dev);
    dev->_requested_top = 1;
  }else{
    dev->_requested_top = 0;
  }
}
#endif //XXZZ

long WSDmacWinDev::setVisible(WSCbool fl){
printf("WSDmacWinDev::setVisible(%d) D2 win=0x%x\n",fl,_win);
  if (_win == (WindowRef)NULL){
    return WS_ERR;
  }
  if (_win2 == (WindowRef)NULL){
    return WS_ERR;
  }
  WSCbool bk = getVisible();
  WSDdev::setVisible(fl);
  if (bk == fl){
    return WS_NO_ERR;
  }
  if (fl == False){
//printf("WSDmacWinDev::setVisible(False) not supported %s %d\n",__FILE__,__LINE__);
    if (_no_frame == False){
      HideWindow(_win);
    }else{
      HideWindow(_win2);
    }
//    SetControlVisibility(_cntl,false,true);
    return WS_NO_ERR;
  }else{
    if (_no_frame == False){
      ShowWindow(_win);
    }else{
      ShowWindow(_win2);
    }

//TEST
//    SetPortWindowPort( _win );
    if (_no_frame == False){
printf("WSDmacWinDev::setVisible(True) D2 bring to front 0x%x\n",_win);
      BringToFront(_win);
    }else{
      BringToFront(_win2);
    }
//    SetControlVisibility(_cntl,true,true);
    return WS_NO_ERR;
  }
  return WS_ERR;
}

WSDdev* WSDmacWinDev::getParentDev(){
  return NULL;
}
#if 0 //XXZZ
void WSDmacWinDev::_evh_focus_ch(Widget w,XtPointer ptr,XEvent* ev,WSCbool* fl){
  WSDmacWinDev* dev = (WSDmacWinDev*)ptr;
  if (dev->_swidget == NULL){
    return;
  }
  if (ev->type == FocusIn){
    dev->onFocusChange();
  }
}
void WSDmacWinDev::_evh_mouse_in(Widget w,XtPointer ptr,XEvent* ev,WSCbool* fl){
  WSDmacWinDev* dev = (WSDmacWinDev*)ptr;
  if (dev->_swidget == NULL){
    return;
  }
//printf("dev=0x%x _swidget=0x%x\n",dev,dev->_swidget);
//fflush(stdout);
  long val = WSGIappMouse()->getMouseCursor(dev->_mouse_no);
  if (val != 0){
    XDefineCursor(XtDisplay((Widget)dev->_swidget),XtWindow((Widget)dev->_swidget),val);
  }
  WSDxformDev::_evh_mouse_in(w,(WSDxformDev*)dev,ev,fl);
}

void WSDmacWinDev::_evh_delete2(Widget w,XtPointer ptr,XtPointer ){
   WSDmacWinDev* dev = (WSDmacWinDev*)ptr;
   if (dev->_widget != w){
     return;
   }

   dev->_swidget = 0;
   dev->_widget = 0;
//   dev->setDependDev(NULL);
   dev->setInitialized(False);
//   dev->destroyAllDependChildren();
   dev->onUnmap();
}

WSClistData WSDmacWinDev::_no_frame_list;

void WSDmacWinDev::_add_list(WSDmacWinDev* dev){
  long num = _no_frame_list.getNum();
  long i;
  WSCbool fl = False;
  for(i=0; i < num; i++){
    WSDmacWinDev* item = (WSDmacWinDev*)_no_frame_list.getData(i);
    if (item == dev){
      fl = True;
      break;
    }
  }
  if (fl == False){
    _no_frame_list.add((void*)dev);
  }
}

void WSDmacWinDev::_del_list(WSDmacWinDev* dev){
  _no_frame_list.del((void*)dev);
}

WSCbool WSDmacWinDev::_chk_popup(WSDmacWinDev* dev){
    //force popup at first time...
    if (dev->_no_frame_first_time != 0){
      dev->_no_frame_first_time = 0;
      return True;
    }
    long i;
    for(i=0; i<_no_frame_list.getNum(); i++){
      WSDmacWinDev* item = (WSDmacWinDev*)_no_frame_list.getData(i);
      if (item != dev ){
        if ( item->getVisible() == False){
           _del_list(item);
           i--;
        }else{
          long dx,dy;
          WSCulong dw,dh;
          if (WSGFandArea(item->_w_x,item->_w_y,item->_w_w,item->_w_h,
                          dev->_w_x,dev->_w_y,dev->_w_w,dev->_w_h,
                          &dx,&dy,&dw,&dh) == WS_NO_ERR){
            return False;
          }

        }
      } 
    }
    return True;
}

void WSDmacWinDev::_popup_window(WSDmacWinDev* dev){
//printf("WSDmacWinDev::_popup_window \n");
    _add_list(dev);
    WSCbool fl = _chk_popup(dev);
    if (fl == False){
      return;
    }

//    XWindowChanges wc;
//    wc.stack_mode = TopIf;
//    XConfigureWindow(XtDisplay(dev->_swidget),XtWindow(dev->_swidget),CWStackMode,&wc);
    if (dev->_requested_top == 0){
      _float_top_timer_proc(0,dev);
    }
}
#endif

long WSDmacWinDev::move_execute(long x,long y){
  WSCrect area;
//  area.setRect(x,y + _diff_y ,_w_w,_w_h);
  area.setRect(x,y,_w_w,_w_h);
printf("WSDmacWinDev::move_exec %d,%d,%d,%d _diff_y=%d XXZZy14\n",area.x,area.y,area.width,area.height,_diff_y);
  onResize(&area);
  return WS_NO_ERR;
}
long WSDmacWinDev::resize_execute(long w,long h){
  if (w > 0 && h > 0){
    WSCrect area;
    area.setRect(_w_x,_w_y,w,h);
printf("WSDmacWinDev::resize_exec D13 %s %d,%d -> %d,%d,%d,%d XXZZy14\n",getAttachedClient()->getInstanceName(),_w_w,_w_h,area.x,area.y,area.width,area.height);
    onResize(&area);
    return WS_NO_ERR;
  }
  return WS_ERR;

#if 0 //XXZZ
  if (dev->_title_bar_style == 0 && dev->_no_frame == 1 &&
      ev->type == ConfigureNotify){
    _popup_window(dev);
  }else if (dev->_top_float == 1 && dev->_requested_top == 0){
    _popup_window(dev);
  }
  if (ev->type == ConfigureNotify &&
      XtWindow(dev->_swidget) == ev->xconfigure.window){
    int dustx,dusty;
    WSCuint vw,vh,vborder,vdepth;
    Window root;
    XGetGeometry( XtDisplay((Widget)dev->_swidget),
                  XtWindow((Widget)dev->_swidget),&root,&dustx,&dusty,
                  &vw,&vh,&vborder,&vdepth);
    if (ev->xconfigure.width != vw ||
        ev->xconfigure.height != vh ){
      return;
    }

    short x,y;
    WSCushort w,h;
    Arg args[4];
    XtSetArg(args[0],XtNy,&y);
    XtSetArg(args[1],XtNx,&x);
    XtGetValues(dev->_swidget,args,2);
    WSCrect area;

    area.setRect(x - dev->_diff_x,
                 y - dev->_diff_y,
                 ev->xconfigure.width,
                 ev->xconfigure.height);
WSMFtrace("WSDmacWinDev::_evh_resize2 %d,%d,%d,%d XXZZy14\n",area.x,area.y,area.width,area.height);
    dev->onResize(&area);
    WSGImacWinAppDev()->setXEvent(NULL);

  }
#endif //XXZZ
}

#if 0
Widget WSDmacWinDev::getShell(){
  return _swidget;
}

void WSDmacWinDev::_evh_client_message(Widget w,XtPointer ptr,XEvent* ev,WSCbool* fl){
  WSDmacWinDev* dev = (WSDmacWinDev*)ptr;
  if (ev->type == ClientMessage){
    WSCbase* client = dev->getAttachedClient();
	if (client != NULL){
	  client->setVisible(False);
	}
  }
}
#endif //XXZZ

long WSDmacWinDev::getValue(long kind,void* val){
printf("not supported.. %s %d\n",__FILE__,__LINE__);
#if 0 //XXZZ
  switch(kind){
    case WSDEV_WINDOW_STATE:
      if (getVisible() == False){
        return WS_WINDOW_NORMAL;
      }
      if (_swidget == NULL){
        return WS_ERR;
      }
      XWindowAttributes att;
      Display* disp =  XtDisplay(_swidget);
      Window   target =  XtWindow(_swidget);
      XGetWindowAttributes(disp, target, &att);
      if (att.map_state == IsUnmapped){
        return WS_WINDOW_MINIMIZE;
      }
      return WS_WINDOW_NORMAL;
  }
#endif //XXZZ
  return WSDwindowDev::getValue(kind,val);
}
WindowRef WSDmacWinDev::getShellWindow(){
  if (_no_frame == False){
    return _win;
  }else{
    return _win2;
  }
}

pascal OSStatus WSDmacWinDev::_evh_mouse_wheel_moved(EventHandlerCallRef nh,
EventRef ev,void* ptr){
printf("WSDmacWinDev::_evh_mouse_wheel_moved.. \n");
  WSDmacWinDev* _this = (WSDmacWinDev*)ptr;
  if (_this->_win == NULL){
    return eventNotHandledErr;
  }
  if (_this->_win2 == NULL){
    return eventNotHandledErr;
  }

  HIPoint where;
  GetEventParameter(ev,kEventParamWindowMouseLocation,typeHIPoint,NULL,
                    sizeof(HIPoint),NULL,&where);
  long  delta;
  GetEventParameter(ev,kEventParamMouseWheelDelta,typeLongInteger,NULL,
                    sizeof(long),NULL,&delta);
//  btn >>= 16;
  WSCpoint pt;
  if (delta > 0){
    WSGIappMouse()->setTargetBtn(WS_MOUSE_BTN4);
    WSCbase* fcl = WSGIappMouse()->getMouseFocusClient();
    if (fcl != NULL){
      WSDdev* dev = fcl->getowndev();
      if (dev != NULL){
        long cx,cy,cw,ch;
        WSDmacFormDev* mdev = (WSDmacFormDev*)dev->cast("WSDmacFormDev");
        if (mdev != NULL){
          mdev->getAbsoluteGeometry(&cx,&cy,&cw,&ch);
          pt.setPoint((long)where.x - cx - _this->_diff_x,
                      (long)where.y - cy - _this->_diff_y);
          fcl->onMousePress(&pt);
        }
      }
    }
    return eventNotHandledErr;
  }else{
    WSGIappMouse()->setTargetBtn(WS_MOUSE_BTN5);
    WSCbase* fcl = WSGIappMouse()->getMouseFocusClient();
    if (fcl != NULL){
      WSDdev* dev = fcl->getowndev();
      if (dev != NULL){
        long cx,cy,cw,ch;
        WSDmacFormDev* mdev = (WSDmacFormDev*)dev->cast("WSDmacFormDev");
        if (mdev != NULL){
          mdev->getAbsoluteGeometry(&cx,&cy,&cw,&ch);
          pt.setPoint((long)where.x - cx - _this->_diff_x,
                      (long)where.y - cy - _this->_diff_y);
          fcl->onMousePress(&pt);
        }
      }
    }
    return eventNotHandledErr;
  }

//  unsigned int mod;
//  GetEventParameter(ev,kEventParamKeyModifiers,typeUInt32,NULL,
//                    sizeof(unsigned int),NULL,&mod);

  return eventNotHandledErr;
}

pascal OSStatus WSDmacWinDev::_evh_mouse_pressed(EventHandlerCallRef nh,
EventRef ev,void* ptr){
printf("WSDmacWinDev::_evh_mouse_pressed.. D5 XXZZms1\n");
  WSDmacWinDev* _this = (WSDmacWinDev*)ptr;
  if (_this->_win == NULL){
    return eventNotHandledErr;
  }
  if (_this->_win2 == NULL){
    return eventNotHandledErr;
  }

  HIPoint where;
  GetEventParameter(ev,kEventParamWindowMouseLocation,typeHIPoint,NULL,
                    sizeof(HIPoint),NULL,&where);
  int btn;
  GetEventParameter(ev,kEventParamMouseButton,typeMouseButton,NULL,
                    sizeof(int),NULL,&btn);
  btn >>= 16;

  unsigned int mod;
  GetEventParameter(ev,kEventParamKeyModifiers,typeUInt32,NULL,
                    sizeof(unsigned int),NULL,&mod);
  long status = WSGIappMouse()->getStatus();
  if (btn == 1){
    status |= WS_MOUSE_BTN1;
    WSGIappMouse()->setTargetBtn(WS_MOUSE_BTN1);
  }
  if (btn == 3){
    status |= WS_MOUSE_BTN2;
    WSGIappMouse()->setTargetBtn(WS_MOUSE_BTN2);
  }
  if (btn == 2){
    status |= WS_MOUSE_BTN3;
    WSGIappMouse()->setTargetBtn(WS_MOUSE_BTN3);
  }
  WSGIappMouse()->setStatus(status);
  _this->_mouse_press_target = _this;

  WSCpoint pt;
#if 0
  pt.setPoint((long)where.x - _this->_diff_x,(long)where.y - _this->_diff_y);
#endif
  pt.setPoint((long)where.x,(long)where.y);
printf("WSDmacWinDev::_evh_mouse_pressed D4 diff=%d,%d XXZZms1\n",_this->_diff_x,_this->_diff_y);
  long i;
  long num = _this->_child_list.getNum();
  for(i=num-1; i> -1; i--){
    WSDmacFormDev* child = (WSDmacFormDev*)_this->_child_list[i];
printf("WSDmacWinDev::_evh_mouse_press D21 child=%s vis=%d XXZZms1\n",child->getAttachedClient()->getInstanceName(),child->getVisible());
    if (child->getVisible() == False){
      continue;
    }
    long cx,cy,cw,ch;
    child->getGeometry(&cx,&cy,&cw,&ch);
    WSCpoint* basept = (WSCpoint*)child->getContextResource();
    cx = basept->x + _this->_diff_x;
    cy = basept->y + _this->_diff_y;
printf("search:mouse D4 press=%d %s\n",i,child->getAttachedClient()->getInstanceName());
printf("mouse pressed D4 target=%d pt=%d,%d  cx,cy,cw,ch=%d,%d,%d,%d XXZZms1\n",i,pt.x,pt.y,cx,cy,cw,cy);
    if (cx < pt.x && pt.x <= cx + cw && 
        cy < pt.y && pt.y <= cy + ch){
printf("hit mouse pressed D4 target=%d %d,%d XXZZms1\n",i,pt.x,pt.y);
      _this->_mouse_press_target = child->getChildByPoint(pt.x -cx,pt.y -cy);
      break;
    }
  }

printf("mouse pressed=%lf,%lf  btn=0x%x %s XXZZms1\n",where.x,where.y,btn,_this->getAttachedClient()->getInstanceName());
  if (_this->_mouse_press_target != NULL){
    if (_this != _this->_mouse_press_target){
      WSCpoint* basept = (WSCpoint*)_this->_mouse_press_target->getContextResource();
      pt.x = where.x - (basept->x + _this->_diff_x);
      pt.y = where.y - (basept->y + _this->_diff_y);
      _this->_mouse_press_target->mouse_press_execute(&pt);
    }else{
      pt.setPoint((long)where.x - _this->_diff_x,(long)where.y - _this->_diff_y);
      _this->onMousePress(&pt);
    }
  }else{
    pt.setPoint((long)where.x - _this->_diff_x,(long)where.y - _this->_diff_y);
    _this->onMousePress(&pt);
  }
  return eventNotHandledErr;
}
pascal OSStatus WSDmacWinDev::_evh_mouse_released(EventHandlerCallRef nh,
EventRef ev,void* ptr){
printf("WSDmacWinDev::_evh_mouse_released.. D5 XXZZms2\n");
  WSDmacWinDev* _this = (WSDmacWinDev*)ptr;
  if (_this->_win == NULL){
printf("WSDmacWinDev::_evh_mouse_released.. error1 XXZZms2\n");
    return eventNotHandledErr;
  }
  if (_this->_win2 == NULL){
printf("WSDmacWinDev::_evh_mouse_released.. error2 XXZZms2\n");
    return eventNotHandledErr;
  }

  HIPoint where;
  GetEventParameter(ev,kEventParamWindowMouseLocation,typeHIPoint,NULL,
                    sizeof(HIPoint),NULL,&where);
  int btn;
  GetEventParameter(ev,kEventParamMouseButton,typeMouseButton,NULL,
                    sizeof(int),NULL,&btn);
  btn >>= 16;

  unsigned int mod;
  GetEventParameter(ev,kEventParamKeyModifiers,typeUInt32,NULL,
                    sizeof(unsigned int),NULL,&mod);
  long status = WSGIappMouse()->getStatus();

  if (btn == 1){
    status &= ~WS_MOUSE_BTN1;
    WSGIappMouse()->setTargetBtn(WS_MOUSE_BTN1);
  }
  if (btn == 3){
    status &= ~WS_MOUSE_BTN2;
    WSGIappMouse()->setTargetBtn(WS_MOUSE_BTN2);
  }
  if (btn == 2){
    status &= ~WS_MOUSE_BTN3;
    WSGIappMouse()->setTargetBtn(WS_MOUSE_BTN3);
  }
  WSGIappMouse()->setStatus(status);

printf("mouse released=%lf,%lf  btn=0x%x %s XXZZms1\n",where.x,where.y,btn,_this->getAttachedClient()->getInstanceName());
  WSCpoint pt;
fflush(stdout);
#if 0
  pt.setPoint((long)where.x - _this->_diff_x, (long)where.y - _this->_diff_y);
#endif
  pt.setPoint((long)where.x, (long)where.y);

  if (_this->_mouse_press_target != NULL){
    if (_this->_mouse_press_target != _this){
      WSCpoint* basept = (WSCpoint*)
                           _this->_mouse_press_target->getContextResource();
      pt.x -= (basept->x + _this->_diff_x);
      pt.y -= (basept->y + _this->_diff_y);
printf("WSDmacWinDev::_evh_mouse_release D4 target=%s %d,%d XXZZms1\n",_this->_mouse_press_target->getAttachedClient()->getInstanceName(),pt.x,pt.y);
      _this->_mouse_press_target->mouse_release_execute(&pt);
    }else{
      pt.setPoint((long)where.x - _this->_diff_x, (long)where.y - _this->_diff_y);
      _this->onMouseRelease(&pt);
    }
    _this->_mouse_press_target = NULL;
printf("mouse_released target=0x%x this=0x%x\n",_this->_mouse_press_target,_this);
  }else{
printf("mouse_released target=0x%x(this)\n",_this);
    pt.setPoint((long)where.x - _this->_diff_x, (long)where.y - _this->_diff_y);
    _this->onMouseRelease(&pt);
  }
  return eventNotHandledErr;
}
pascal OSStatus WSDmacWinDev::_evh_mouse_entered(EventHandlerCallRef nh,
EventRef ev,void* ptr){
printf("WSDmacWinDev::_evh_mouse_entered.. \n");

  WSDmacWinDev* _this = (WSDmacWinDev*)ptr;
  HIPoint where;
  GetEventParameter(ev,kEventParamWindowMouseLocation,typeHIPoint,NULL,
                    sizeof(HIPoint),NULL,&where);

  WSCpoint pt;
#if 0
  pt.setPoint((long)where.x - _this->_diff_x, (long)where.y - _this->_diff_y);
#endif
  pt.setPoint((long)where.x, (long)where.y);
  _this->_mouse_move_target = _this;
  long i;
  long num = _this->_child_list.getNum();
  for(i=num-1; i> -1; i--){
    WSDmacFormDev* child = (WSDmacFormDev*)_this->_child_list[i];
    long cx,cy,cw,ch;
    child->getGeometry(&cx,&cy,&cw,&ch);
    WSCpoint* basept = (WSCpoint*) child->getContextResource();
    cx = basept->x + _this->_diff_x;
    cy = basept->y + _this->_diff_y;

    if (cx < pt.x && pt.x <= cx + cw &&
        cy < pt.y && pt.y <= cy + ch){
      _this->_mouse_move_target = child;
      pt.x -= cx;
      pt.y -= cy;
      break;
    }
  }
  if (_this->_mouse_move_target != NULL){
    if (_this != _this->_mouse_move_target){
      _this->_mouse_move_target->mouse_entered_execute(&pt);
    }else{
      pt.setPoint((long)where.x - _this->_diff_x, (long)where.y - _this->_diff_y);
      _this->onMouseIn(&pt);
    }
  }else{
    pt.setPoint((long)where.x - _this->_diff_x, (long)where.y - _this->_diff_y);
    _this->onMouseIn(&pt);
  }
  return eventNotHandledErr;
}
pascal OSStatus WSDmacWinDev::_evh_mouse_leaved(EventHandlerCallRef nh,
EventRef ev,void* ptr){
printf("WSDmacWinDev::_evh_mouse_leaved.. \n");

  WSDmacWinDev* _this = (WSDmacWinDev*)ptr;

//  HIPoint where;
//  GetEventParameter(ev,kEventParamWindowMouseLocation,typeHIPoint,NULL,
//                    sizeof(HIPoint),NULL,&where);
//  WSCpoint pt;
//  pt.setPoint(where.x,where.y);

  if (_this->_mouse_move_target != NULL){
    if (_this->_mouse_move_target != _this){
      _this->_mouse_move_target->mouse_leaved_execute();
    }else{
      _this->onMouseOut();
    }
    _this->_mouse_move_target = NULL;
  }else{
    _this->onMouseOut();
  }
  return eventNotHandledErr;
}
#if 0
pascal OSStatus WSDmacWinDev::_evh_resized(EventHandlerCallRef nh,
EventRef ev,void* ptr){
  WSDmacWinDev* _this = (WSDmacWinDev*)ptr;
printf("WSDmacWinDev::_evh_resized.. D13 %s\n",_this->getAttachedClient()->getInstanceName());
  return eventNotHandledErr;
}
#endif

pascal OSStatus WSDmacWinDev::_evh_mouse_moved(EventHandlerCallRef nh,
EventRef ev,void* ptr){
printf("WSDmacWinDev::_evh_mouse_moved.. \n");

  WSDmacWinDev* _this = (WSDmacWinDev*)ptr;
  HIPoint where;
  GetEventParameter(ev,kEventParamWindowMouseLocation,typeHIPoint,NULL,
                    sizeof(HIPoint),NULL,&where);

  WSCpoint pt;
#if 0
  pt.setPoint((long)where.x - _this->_diff_x, (long)where.y - _this->_diff_y);
#endif
  pt.setPoint((long)where.x, (long)where.y);

  WSDmacFormDev* bk = _this->_mouse_move_target;
  long i;
  long num = _this->_child_list.getNum();
  for(i=num-1; i> -1; i--){
    WSDmacFormDev* child = (WSDmacFormDev*)_this->_child_list[i];
    long cx,cy,cw,ch;
    child->getGeometry(&cx,&cy,&cw,&ch);
    WSCpoint* basept = (WSCpoint*) child->getContextResource();
    cx = basept->x + _this->_diff_x;
    cy = basept->y + _this->_diff_y;

    if (cx < pt.x && pt.x <= cx + cw &&
        cy < pt.y && pt.y <= cy + ch){
      _this->_mouse_move_target = child;
      pt.x -= cx;
      pt.y -= cy;
      break;
    }
  }
  if (_this->_mouse_move_target != bk){
    if (bk != NULL){
      bk->onMouseOut();
    }
  }
  if (_this->_mouse_move_target != NULL){
    if (_this->_mouse_move_target != bk){
      if (_this != _this->_mouse_move_target){
        _this->_mouse_move_target->mouse_entered_execute(&pt);
      }else{
        pt.setPoint((long)where.x - _this->_diff_x, (long)where.y - _this->_diff_y);
        _this->onMouseIn(&pt);
      }
    }else{
      if (_this != _this->_mouse_move_target){
        _this->_mouse_move_target->mouse_moved_execute(&pt);
      }else{
        pt.setPoint((long)where.x - _this->_diff_x, (long)where.y - _this->_diff_y);
        _this->onMouseMove(&pt);
      }
    }
  }else{
    pt.setPoint((long)where.x - _this->_diff_x, (long)where.y - _this->_diff_y);
    _this->onMouseMove(&pt);
  }
  return eventNotHandledErr;
}
pascal OSStatus WSDmacWinDev::_evh_mouse_dragged(EventHandlerCallRef nh,
EventRef ev,void* ptr){
printf("WSDmacWinDev::_evh_mouse_dragged.. \n");

  WSDmacWinDev* _this = (WSDmacWinDev*)ptr;
  HIPoint where;
  GetEventParameter(ev,kEventParamWindowMouseLocation,typeHIPoint,NULL,
                    sizeof(HIPoint),NULL,&where);
  WSCpoint pt;
  pt.setPoint((long)where.x,(long)where.y);

  if (_this->_mouse_press_target != NULL){
    if (_this->_mouse_press_target != _this){
      WSCpoint* basept = (WSCpoint*)
                           _this->_mouse_press_target->getContextResource();
      pt.x -= (basept->x + _this->_diff_x);
      pt.y -= (basept->y + _this->_diff_y);
printf("WSDmacWinDev::_evh_mouse_dragged target=%s pt=%d,%d XXZZm1\n",_this->_mouse_press_target->getAttachedClient()->getInstanceName(),pt.x,pt.y);
      _this->_mouse_press_target->mouse_dragged_execute(&pt);
    }else{
      pt.setPoint((long)where.x - _this->_diff_x, (long)where.y - _this->_diff_y);
      _this->onMouseMove(&pt);
    }
  }else{
     pt.setPoint((long)where.x - _this->_diff_x, (long)where.y - _this->_diff_y);
    _this->onMouseMove(&pt);
  }
  return eventNotHandledErr;
}
pascal OSStatus WSDmacWinDev::_evh_exposed(EventHandlerCallRef nh,
EventRef ev,void* ptr){
  WSDmacWinDev* _this = (WSDmacWinDev*)ptr;
printf("WSDmacWinDev::_evh_exposed.. D2 _win=0x%x\n",_this->_win);
  if (_this->getAttachedClient() == NULL){
printf("WSDmacWinDev::_evh_exposed  err return 1\n");
    _this->setVisible(False);
    return eventNotHandledErr;
  }else if (_this->getAttachedClient()->getVisible() == False){
    _this->setVisible(False);
printf("WSDmacWinDev::_evh_exposed  err return 2\n");
    return eventNotHandledErr;
  }
  WSCrect area;
  _this->_already_exposed = True;
  if (_this->_no_frame == False){
    BeginUpdate(_this->_win);
  }else{
    BeginUpdate(_this->_win2);
  }

  WSDdraw* d = getDraw();
  WSDmacDraw* md = NULL;
  if (d != NULL){
    md = (WSDmacDraw*)d->cast("WSDmacDraw");
  }
  if (md != NULL){
    md->setExposed(True);
printf("WSDmacWinDev::_evh_exposed D5 exposed=1 win=0x%x\n",_this->_win);
  }
printf("WSDmacWinDev::_evh_exposed win=0x%x\n",_this->_win);
#if 0
    RGBColor col;
    col.red = 0;     
    col.green = 0;
    col.blue = 0xffff;
    RGBForeColor(&col);
    Rect r;
    SetRect(&r,0,0,0x7fff,0x7fff);  
    PaintRect(&r);
#endif
#if 0
  RGBForeColor(&(_this->_bgc));
  RGBBackColor(&(_this->_bgc));
  Pattern whitept;
  GetQDGlobalsWhite(&whitept);
  Rect rect;
  SetRect(&rect,0,0,_this->_w_w,_this->_w_h);
  FillRect(&rect,&whitept);
printf("%s %d fillrect! Fore=%x %x %x\n",__FILE__,__LINE__,_this->_bgc.red,_this->_bgc.green,_this->_bgc.blue);
printf("%s %d fillrect! wh=%d %d \n",__FILE__,__LINE__,_this->_w_w,_this->_w_h);
#endif 
  area.setRect(_this->_w_x,_this->_w_y,_this->_w_w,_this->_w_h);
  _this->onExpose(&area);
printf("WSDmacWinDev::_evh_exposed: must call with exposed area..\n");

  long ex = 0;
  long ey = 0;
  long ew = _this->_w_w; 
  long eh = _this->_w_h; 

  long i;
  long num = _this->_child_list.getNum();
  for(i=num-1; i> -1; i--){
    WSDmacFormDev* child = (WSDmacFormDev*)_this->_child_list[i];

    if (child->getAttachedClient() == NULL){
      continue;
    }
    WSCbool vis = child->getAttachedClient()->getVisible();
    if (vis == False){
      continue;
    }
    if (child->getVisible() == False){
      child->setVisible(True);
    }

    long dx,dy,dw,dh;
    long cx,cy,cw,ch;
    child->getGeometry(&cx,&cy,&cw,&ch);
    WSCpoint* basept = (WSCpoint*) child->getContextResource();
    cx = basept->x + _this->_diff_x;
    cy = basept->y + _this->_diff_y;

    WSGFandArea(ex,ey,ew,eh,cx,cy,cw,ch, &dx,&dy,&dw,&dh);
printf("hit child exposed. c= %d,%d,%d,%d\n",cx,cy,cw,ch);

    if (dw > 0 && dh > 0){
      WSCrect r;
      r.setRect(dx - cx,dy - cy,dw,dh);
printf("hit child exposed. %d,%d,%d,%d\n",dx -cx,dy -cy,dw,dh);
      child->expose_execute(&r);
    }
  }

  if (_this->_no_frame == False){
    EndUpdate(_this->_win);
  }else{
    EndUpdate(_this->_win2);
  }
  if (md != NULL){
    md->setExposed(False);
printf("WSDmacWinDev::_evh_exposed D5 exposed=0 win=0x%x\n",_this->_win);
  }
  return eventNotHandledErr;
}
WindowRef WSDmacWinDev::getBaseWindow(){
  if (_no_frame == False){
    return _win;
  }else{
    return _win2;
  }
}

long WSDmacWinDev::getWindowResource(){
  if (_already_exposed == False){
    return -1;
  }
  if (_no_frame == False){
    if (_win == 0){
      return -1;
    }
    return _win;
  }else{
    if (_win2 == 0){
      return -1;
    }
    return _win2;
  }
}
long WSDmacWinDev::getContextResource(){
//  if (_no_frame == False){
//    _top_left.x = _diff_x;
//    _top_left.y = _diff_y;
//  }else{
    _top_left.x = 0;
    _top_left.y = 0;
//  }
  return (long)&_top_left;
}

void WSDmacWinDev::getVaridArea(long* x,long* y,long* w,long* h){
  *x = 0;
  *y = 0;
  *w = _w_w;
  *h = _w_h;
}
void WSDmacWinDev::getAbsoluteVaridArea(long* x,long* y,long* w,long* h){
  *x = 0;
  *y = 0;
  *w = _w_w;
  *h = _w_h;
}
void WSDmacWinDev::getGeometry(long* x,long* y,long* w,long* h){
  *x = 0;
  *y = 0;
  *w = _w_w;           
  *h = _w_h;
}
void WSDmacWinDev::getAbsoluteGeometry(long* x,long* y,long* w,long* h){
  *x = 0;
  *y = 0;
  *w = _w_w;           
  *h = _w_h;
}

#if 0 //XXZZ
pascal OSStatus WSDmacWinDev::_evh_mouse_pressed(EventHandlerCallRef nh,
EventRef ev,void* d){
  WindowPtr win;
  EventRecord event;
  Boolean fl = ConvertEventRefToEventRecord(ev,&event);
printf("WSDmacWinDev::_handler_events_().. this=0x%x fl=%d\n",d,fl);
  if (fl != FALSE){
    switch(event.what){
      case mouseDown:
printf("WSDmacWinDev::_handle_events_ mouseDown\n");
        break;
      case mouseUp:
printf("WSDmacWinDev::_handle_events_ mouseUp\n");
        break;
      case mouseMoved:
printf("WSDmacWinDev::_handle_events_ mouseMoved\n");
        break;
      case windowUpdate:
printf("WSDmacWinDev::_handle_events_ windowUpdate\n");
        break;


    }
  }
  return eventNotHandledErr;
}
#endif
