//
// Copyright (C) 1999-2004 Toshikaz Hirabayashi
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
// TOSHIKAZ HIRABAYASHI BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
// OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
// Except as contained in this notice, the name of Toshikaz Hirabayashi shall
// not be used in advertising or otherwise to promote the sale, use or other
// dealings in this Software without prior written authorization from
// Toshikaz Hirabayashi.

#include <WScom.h>
#include <WSDwindowDev.h>
#include <WSCdevice.h>
#include <WSDdraw.h>
#include <WSCbase.h>
#include <WSDmouse.h>
#include <WSDappDev.h>

WSMFclassInit(WSDwindowDev,WSDdev);
#define DELETED_CL_LIST "_cl_list"

WSDwindowDev::WSDwindowDev(){
  _pixmap_created = False;
  _expose_sequence = False;
  _event_delivering_sequence = False;
  _client_deleted = False;
  _bg_no = 0;
  _bp_no = 0;
  _w_x = 0;
  _w_y = 0;
  _w_w = 100;
  _w_h = 100;
  _diff_x = 0;
  _diff_y = 0;
  _mouse_no = 0;
  _exposed_x = 0;
  _exposed_y = 0;
  _exposed_w = 0;
  _exposed_h = 0;
  _pixmap_style = WS_DIRECT_WINDOW;
}

#if 0
static void (*_mouse_in_handler)(WSDdev*) = NULL;
static void (*_mouse_press_handler)(WSDdev*) = NULL;
static void (*_mouse_release_handler)(WSDdev*) = NULL;
void* WSDwindowDev::setGlobalMouseInHandler( void(*hd)(WSDdev*) ){
  void* ret = _mouse_in_handler;
  _mouse_in_handler = hd;
  return ret;
}
void* WSDwindowDev::setGlobalMousePressHandler( void(*hd)(WSDdev*) ){
  void* ret = _mouse_press_handler;
  _mouse_press_handler = hd;
  return ret;
}
void* WSDwindowDev::setGlobalMouseReleaseHandler( void(*hd)(WSDdev*) ){
  void* ret = _mouse_release_handler;
  _mouse_release_handler = hd;
  return ret;
}
#endif

long WSDwindowDev::detachClient(){
   destroyPixmap();
   return WSDdev::detachClient();
}
WSCushort WSDwindowDev::getWidth(){
  return _w_w;
}
WSCushort WSDwindowDev::getHeight(){
  return _w_h;
}

void WSDwindowDev::getDispAddr(short* ox,short* oy){
   short px = 0;
   short py = 0;
   WSDdev* parent = getParentDev();
   if (parent != NULL){
     parent->getDispAddr(&px,&py);
   }
   short ax;
   short ay;
   getAbsoluteAddr(_w_x,_w_y,&ax,&ay);
   *ox = px + ax + _diff_x;
   *oy = py + ay + _diff_y;

   return;
}

WSCbool WSDwindowDev::getAbsoluteDraw(){
  return _absolute_draw;
}

long WSDwindowDev::getValue(long kind,void* data){
  switch(kind){
    case WSDEV_EXPOSE_SEQUENCE:
             *(char*)data = _expose_sequence;
             break;
    case WSDEV_PIXMAP_STYLE:
	         *(char*)data = getPixmapStyle();
             break;
  }
  return WS_NO_ERR;
}

long WSDwindowDev::setValue(long kind,void* data){
  char val;
  switch(kind){
    case WSDEV_X: 
             _w_x = *(short*)data;
             break;
    case WSDEV_Y:
             _w_y = *(short*)data;
             break;
    case WSDEV_WIDTH:
             if (getPixmapStyle() != WS_DIRECT_WINDOW){
                destroyPixmap();
             }
             _w_w = *(WSCushort*)data;
             break;
    case WSDEV_HEIGHT:
             if (getPixmapStyle() != WS_DIRECT_WINDOW){
                destroyPixmap();
             }
             _w_h = *(WSCushort*)data;
             break;
    case WSDEV_BACKCOLOR:
            _bg_no = *(short*)data;
             break;
    case WSDEV_BACK_PIXMAP:
            _bp_no = *(short*)data;
             break;
    case WSDEV_PIXMAP_STYLE:
             val = *(char*)data;
             if (getPixmapStyle() != WS_DIRECT_WINDOW &&
                 val == WS_DIRECT_WINDOW){
               destroyPixmap();
             }
             setPixmapStyle(val);
             break;
    case WSDEV_EXPOSE_SEQUENCE:
             val = *(char*)data;
             _expose_sequence = val;
             break;
    case WSDEV_SCALE_OFFSET:
             setScalePtr((double*)data);
             break;
    case WSDEV_X_OFFSET:
             setXOffsetPtr((short*)data);
             break;
    case WSDEV_Y_OFFSET:
             setYOffsetPtr((short*)data);
             break;
    case WSDEV_MOUSE_NO: 
             _mouse_no = *(WSCushort*)data;
             break;
  }
  return WS_NO_ERR;
}

void WSDwindowDev::onFocusChange(){
  if (getAttachedClient() != NULL){
//printf("WSDwindowDev::onFocusChange..\n");
    getAttachedClient()->setFocus();
  }
}

void WSDwindowDev::onUnmap(){
  if (getAttachedClient() != NULL){
    getAttachedClient()->setVisible(False);
  }
}

void WSDwindowDev::onMousePress(WSCpoint* pt){
//  if (_mouse_press_handler != NULL){
//    _mouse_press_handler(this);
//  }
  execEvent(WSEV_MOUSE_PRESS,pt);
}

void WSDwindowDev::onMouseDoubleClick(WSCpoint* pt){
//  if (_mouse_press_handler != NULL){
//    _mouse_press_handler(this);
//  }
  execEvent(WSEV_MOUSE_DOUBLE_CLICK,pt);
}

void WSDwindowDev::onMouseRelease(WSCpoint* pt){
//  if (_mouse_release_handler != NULL){
//    _mouse_release_handler(this);
//  }
  execEvent(WSEV_MOUSE_RELEASE,pt);
}

void WSDwindowDev::onMouseIn(WSCpoint* pt){
//  if (_mouse_in_handler != NULL){
//    _mouse_in_handler(this);
//  }
  execEvent(WSEV_MOUSE_IN,pt);
}

void WSDwindowDev::onMouseOut(){
  execEvent(WSEV_MOUSE_OUT,NULL);
}

void WSDwindowDev::onMouseMove(WSCpoint* pt){
   execEvent(WSEV_MOUSE_MOVE,pt);
}

void WSDwindowDev::onResize(WSCrect* area){
//#if 0
  if (_w_x == area->x &&
      _w_y == area->y &&
      _w_w == area->width &&
      _w_h == area->height){
    return;
  }
//#endif
  _w_x = area->x;
  _w_y = area->y;
  _w_w = area->width;
  _w_h = area->height;
  execEvent(WSEV_RESIZE,area);
}

WSCbool WSDwindowDev::getReady(){
  long d1 = getDeviceResource();
  long d2 = getWindowResource();
  long d3 = getContextResource();
//printf("WSDwindowDev::getReady %d %d %d\n",d1,d2,d3);
  if (d1 == -1 || d2 == -1 || d3 == -1){
     return False;
  }
  return True;
}

void WSDwindowDev::onExpose(WSCrect* area){
   _expose_sequence = True;
   setExposedArea( area->x, area->y, area->width, area->height );
   if ( getPixmapStyle() != WS_DIRECT_WINDOW ){
     if ( _pixmap_created == False ){
       if (createPixmap() == WS_NO_ERR){
         _pixmap_created = True;
       }
     }
     if (_pixmap_created != False){
       _copy_area(area->x,area->y, area->width, area->height, area->x, area->y,
             WS_PIXMAP_TO_WINDOW);
     }else{
       execEvent(WSEV_EXPOSE,area);
     }
   }else{
     execEvent(WSEV_EXPOSE,area);
   }
   _expose_sequence = False;
   setExposedArea( 0,0,0,0 );
   return;
}

long WSDwindowDev::beginDraw(short x,short y,
                              WSCushort w,WSCushort h,
                              WSCbool absolute,WSCbool scaling){

  if (scaling != False){
    double scale = getScale();
    if ( scale != 1){
      x = (short)((x + getXOffset()) * scale);
      y = (short)((y + getYOffset()) * scale);
      w = (WSCushort)(w * scale);
      h = (WSCushort)(h * scale);
    }else{
      x = x + getXOffset();
      y = y + getYOffset();
    }
  }

  if (getPixmapStyle() != WS_DIRECT_WINDOW){
     _pix_draw_x = x;
     _pix_draw_y = y;
     _pix_draw_w = w;
     _pix_draw_h = h;
  }

  WSDdraw* draw = getDraw();
  if (draw == NULL){
    return WS_ERR;
  }
  _absolute_draw = absolute;

  _x = x; 
  _y = y; 
  _w = w; 
  _h = h; 
  short ex,ey;
  WSCushort ew,eh;
  long ret = getExposedArea(&ex,&ey,&ew,&eh);
  if (ret != WS_NO_ERR){
    return WS_ERR;
  }
  if (getReady() == False){
    if (getPixmapStyle() == WS_DYNAMIC_PIXMAP && 
        _pixmap_created == False  && createPixmap() == WS_NO_ERR){
          _pixmap_created = True;
    }else{
      return WS_ERR;
    }
  }
  if (getReady() == False){
    return WS_ERR;
  }
  draw->beginDraw(this,getDeviceResource(),getWindowResource(),getContextResource());


  short ex2 = ex + ew < x + w ? ex + ew : x + w; 
  short ey2 = ey + eh < y + h ? ey + eh : y + h; 
  ex = ex > x ? ex : x; 
  ey = ey > y ? ey : y; 
  ew = ex2 - ex;
  eh = ey2 - ey;

  if (absolute == False){
    draw->setRegion(ex,ey,ew,eh);
  }else{
    draw->setRegion(x,y,w,h);
  }

  return WS_NO_ERR;
}

long WSDwindowDev::endDraw(){
  WSDdraw* draw = getDraw();
  if (draw == NULL){
    _absolute_draw = False;
    return WS_ERR;
  }
  draw->endDraw();

  if (getAbsoluteDraw() != False && getPixmapStyle() != WS_DIRECT_WINDOW &&
      _expose_sequence == False){
     _copy_area( _pix_draw_x, _pix_draw_y, _pix_draw_w, _pix_draw_h,
                _pix_draw_x, _pix_draw_y,WS_PIXMAP_TO_WINDOW);
  }
  _absolute_draw = False;
  return WS_NO_ERR;
}

void WSDwindowDev::_copy_area(long,long,WSCulong,WSCulong,long,long,WSCuchar){
}

void WSDwindowDev::_clear_area(long ,long ,WSCulong ,WSCulong){
}

void WSDwindowDev::_setup_pixmap(short ,short ,WSCushort ,WSCushort ,short /*bg*/,short /*img_no*/){
}
short WSDwindowDev::getBackColorNo(){
  return _bg_no;
}

void WSDwindowDev::setBackColorNo(short bg){
  _bg_no = bg;
}

void WSDwindowDev::setExposeSequence(WSCbool fl){
  _expose_sequence = fl;
}
WSCbool WSDwindowDev::getExposeSequence(){
  return _expose_sequence;
}
long WSDwindowDev::exposeArea(long x,long y,WSCulong w,WSCulong h,WSCbool scaling){
  if (getReady() == False){
    if (getPixmapStyle() == WS_DYNAMIC_PIXMAP && 
        _pixmap_created == False  && createPixmap() == WS_NO_ERR){
          _pixmap_created = True;
    }else{
      return WS_ERR;
    }
  }
  if (getReady() == False){
    return WS_ERR;
  }
  if (scaling != False){
    double scale = getScale();
    if ( scale != 1){
      x = (short)((x + getXOffset())* scale);
      y = (short)((y + getYOffset())* scale);
      w = (WSCushort)(w * scale);
      h = (WSCushort)(h * scale);
    }else{
      x = x + getXOffset();
      y = y + getYOffset();
    }
  }

  if (getPixmapStyle() == WS_DIRECT_WINDOW){
//printf("WSDwindowDev::expose %d,%d,%d,%d\n",x,y,w,h);
    exposeExecute(x,y,w,h);
  }else{
//printf("WSDwindowDev::expose  XXZZredraw1 %d,%d,%d,%d\n",x,y,w,h);
    _setup_pixmap(x,y,w,h,_bg_no,_bp_no);
    exposeExecute(x,y,w,h);
    _copy_area(x,y,w,h,x,y,WS_PIXMAP_TO_WINDOW);
  }
  return WS_NO_ERR;
}

long WSDwindowDev::clearArea(long x,long y,WSCulong w,WSCulong h,WSCbool fl,WSCbool scaling){
  if (getReady() == False){
    if (getPixmapStyle() == WS_DYNAMIC_PIXMAP && 
        _pixmap_created == False  && createPixmap() == WS_NO_ERR){
          _pixmap_created = True;
    }else{
      return WS_ERR;
    }
  }
  if (getReady() == False){
    return WS_ERR;
  }
  if (scaling != False){
    double scale = getScale();
    if ( scale != 1){
      x = (short)((x + getXOffset())* scale);
      y = (short)((y + getYOffset())* scale);
      w = (WSCushort)(w * scale);
      h = (WSCushort)(h * scale);
    }else{
      x = x + getXOffset();
      y = y + getYOffset();
    }
  }

  if (getPixmapStyle() == WS_DIRECT_WINDOW){
    _clear_area(x,y,w,h);
    if ( fl != False ){
      exposeExecute(x,y,w,h);
    }

  }else{ //ピクスマップの場合
    _setup_pixmap(x,y,w,h,_bg_no,_bp_no);
    if ( fl != False ){ 
      exposeExecute(x,y,w,h);
    }
    _copy_area(x,y,w,h,x,y,WS_PIXMAP_TO_WINDOW);
  }
  return WS_NO_ERR;
}
long WSDwindowDev::copyArea(long x,long y,WSCulong w,WSCulong h,long dx,long dy){
  if (getReady() == False){
    if (getPixmapStyle() == WS_DYNAMIC_PIXMAP && 
        _pixmap_created == False  && createPixmap() == WS_NO_ERR){
          _pixmap_created = True;
    }else{
      return WS_ERR;
    }
  }
  if (getReady() == False){
    return WS_ERR;
  }
  double scale = getScale();
  if ( scale != 1){
    x = (short)((x + getXOffset())* scale);
    y = (short)((y + getYOffset())* scale);
    w = (WSCushort)(w * scale);
    h = (WSCushort)(h * scale);
    dx = (short)((dx + getXOffset())* scale);
    dy = (short)((dy + getYOffset())* scale);
  }else{
    x = x + getXOffset();
    y = y + getYOffset();
    dx = dx + getXOffset();
    dy = dy + getYOffset();
  }
  _copy_area(x,y,w,h,dx,dy,WS_WINDOW_TO_WINDOW);

  return WS_NO_ERR;
}


void WSDwindowDev::exposeExecute(short x,short y,WSCushort w,WSCushort h){
      short oldx,oldy;
      WSCushort oldw,oldh;
      getExposedArea(&oldx,&oldy,&oldw,&oldh);
      WSCbool ebk = _expose_sequence;
      _expose_sequence = True;

      setExposedArea(x,y,w,h);
      WSCrect rect;
      rect.setRect(x,y,w,h);
      execEvent(WSEV_EXPOSE,&rect);

      _expose_sequence = ebk;
      setExposedArea(oldx,oldy,oldw,oldh);
}

long WSDwindowDev::execEvent(long ev_kind,void* data){
  if (getAttachedClient() == NULL){
    return WS_NO_ERR;
  }
  long i;
  long num = _event_clients.getNum();
  WSDdev**  array = new WSDdev*[num];

  if (num > 0){
    memcpy(array,_event_clients.getBuf(),sizeof(void*)*num);
  }
  long ev_bit = WSGFeventToMaskBit(ev_kind);
  _event_delivering_sequence = True;
  _client_deleted = False;
  long need_execute_later = 0;
//  long exclusive_mask = WSEV_MOUSE_PRESS_BIT | WSEV_MOUSE_RELEASE_BIT | WSEV_MOUSE_DOUBLE_CLICK_BIT;
  long exclusive_mask = WSEV_MOUSE_PRESS_BIT | WSEV_MOUSE_RELEASE_BIT;

//long t1 = WSGFclocktime(); //TEST
//printf("WSDwindowDev::execEvent ev=%d %s\n",ev_kind,getAttachedClient()->getInstanceName());

  for(i=0; i < num; i++){
    WSDdev* dev = array[i];
    if (dev == this && (ev_bit & exclusive_mask)){
//printf("WSDwindowDev::execEv   skipped.\n");
      need_execute_later = 1;
      continue;
    }
    long deleted = 0;
    if (_client_deleted == True){
      WSClistData* list = (WSClistData*)_client->getUserData(DELETED_CL_LIST);
      long j;
      long num2 = list->getNum();
      for(j=0; j < num2; j++){
        WSDdev* data = (WSDdev*)(*list)[j];
        if (data == dev){
          deleted = 1;
          break;
        } 
      }
    }
    if (deleted == 0 && ((WSCulong)dev->_event_mask & ev_bit)){
      long ret = dev->informEventToClient(ev_kind,data);
//printf("WSDwindowDev::execEv  %d exec ret=%d.\n",i,ret);
      if (ret == WS_NO_ERR && (ev_bit & exclusive_mask)){
//printf("WSDwindowDev::execEv   canceled.\n");
        need_execute_later = 0;
        break;
      }
    }
  }
//printf("WSDwindowDev::execEvent t1=%d %s\n",WSGFclocktime() - t1,getAttachedClient()->getInstanceName());
  WSClistData* list = NULL;
  if (need_execute_later != 0){
    long deleted = 0;
    if (_client_deleted == True){
      list = (WSClistData*)_client->getUserData(DELETED_CL_LIST);
      long j;
      long num2 = list->getNum();
      for(j=0; j < num2; j++){
        WSDdev* data = (WSDdev*)(*list)[j];
        if (data == this){
          deleted = 1;
        } 
      }
    }
    if (deleted == 0 && ((WSCulong)this->_event_mask & ev_bit)){
      this->informEventToClient(ev_kind,data);
    }
  }

//  if (_client_deleted == True){
  if (list != NULL){
    delete list;
    if (_client != NULL){
      _client->setUserData(DELETED_CL_LIST,NULL);
    }
  }

  delete array;
  _event_delivering_sequence = False;
//printf("WSDwindowDev::execEvent t2=%d %s\n",WSGFclocktime() - t1,getAttachedClient()->getInstanceName());
  return WS_NO_ERR;
}

WSCbool WSDwindowDev::isExposed(short x,short y,WSCushort w,WSCushort h,WSCbool scaling){
  if (scaling != False){
    double scale = getScale();
    if ( scale != 1){
      x = (short)((x + getXOffset())* scale);
      y = (short)((y + getYOffset())* scale);
      w = (WSCushort)(w * scale);
      h = (WSCushort)(h * scale);
    }else{
      x = x + getXOffset();
      y = y + getYOffset();
    }
  }
  short ex,ey;
  WSCushort ew,eh;
  getExposedArea(&ex,&ey,&ew,&eh);
  return WSGFareaInclude(x,y,w,h,ex,ey,ew,eh);
}


long WSDwindowDev::cancelEvent(WSDdev* client_dev){
  _event_clients.del((void*)client_dev);
  if (client_dev == this){
    setEventRegistered(False);
  }
  if (_event_delivering_sequence){
    WSClistData* list = (WSClistData*)_client->getUserData(DELETED_CL_LIST);
    if (list == NULL){
      list = new WSClistData();
      _client->setUserData(DELETED_CL_LIST,list);
    }
    list->add(client_dev);
    _client_deleted = True;
//printf("WSDwindowDev::cancelEvent canceled client_dev=0x%x\n",client_dev);
  }
  return WS_NO_ERR;
}
long WSDwindowDev::raise(){
  printf("WSDwindowDev::raise() this system does not support..\n");
  return WS_ERR;
}
long WSDwindowDev::lower(){
  printf("WSDwindowDev::lower() this system does not support..\n");
  return WS_ERR;
}

long WSDwindowDev::setEventOrder(WSDdev* client_dev,char direction){
//if it is own dev, no need to change event stack order...
  if (client_dev == this){
    if (direction == WS_TOP){ //TOP event order is bottom window stack..
      lower();
    }else
    if (direction == WS_BOTTOM){ //BOTTOM event order is top window stack..
      raise();
    }
    return WS_NO_ERR; 
  }
  long num;
  long i;
  num = _event_clients.getNum();
  if (direction == WS_TOP){
    for(i=0; i < num; i++){
       WSDdev* item = (WSDdev*)_event_clients[i];
       if (item == client_dev){
          _event_clients.delPos(i);
          if (client_dev == this){
            _event_clients.add((void*)item,0);
          }else{
            WSDdev* top = (WSDdev*)_event_clients[0];
            if (top == this){
              _event_clients.add((void*)item,1);
            }else{
              _event_clients.add((void*)item,0);
            }
          }
          return WS_NO_ERR;
       }
    }
  }else{
    for(i=0; i < num; i++){
       WSDdev* item = (WSDdev*)_event_clients[i];
       if (item == client_dev){
          _event_clients.delPos(i);
          _event_clients.add((void*)item);
          return WS_NO_ERR;
       }
    }
  }
  return WS_NO_ERR;

}

long WSDwindowDev::setEvent(WSDdev* client_dev,WSCbool fl){
  if (fl == False){
    return cancelEvent(client_dev);
  }

  _event_clients.add((void*)client_dev);

  if (client_dev == this){
    WSDdev* dev = (WSDdev*)_event_clients[0];
    if (dev != client_dev){
      setEventOrder(this,WS_TOP);
    }
  }

  return WS_NO_ERR;
}

long WSDwindowDev::getExposedArea(short* x,short* y,WSCushort* w,WSCushort* h,WSCbool scaling){
  if (scaling != False){
    double scale = getScale();
    if ( scale != 1){
      *x = (short)((_exposed_x - getXOffset()) * scale);
      *y = (short)((_exposed_y - getYOffset()) * scale);
      *w = (WSCushort)(_exposed_w * scale);
      *h = (WSCushort)(_exposed_h * scale);
    }else{
      *x = _exposed_x - getXOffset();
      *y = _exposed_y - getYOffset();
      *w = _exposed_w;
      *h = _exposed_h;
    }
    return WS_NO_ERR;
  }
  *x = _exposed_x;
  *y = _exposed_y;
  *w = _exposed_w;
  *h = _exposed_h;
  return WS_NO_ERR;
}

long WSDwindowDev::setEnableEventBit(long ev_bit){
  if (getEventRegistered() != False){
    if ( ev_bit & getAvailableEventBit() ){
      long evmask = getEventMaskBit();
      evmask |= ( ev_bit & getAvailableEventBit() ); 
      setEventMaskBit(evmask);
    }
    return WS_NO_ERR;
  }


  if ( ev_bit & getAvailableEventBit() ){
    setEventRegistered(True);
    setEventMaskBit( (ev_bit & getAvailableEventBit()) );
    setEvent(this,True);
    return WS_NO_ERR;
  }
  return WS_ERR;

}

long WSDwindowDev::setEnableEvent(long ev_kind){
  if (getEventRegistered() != False){
    if (isAvailableEvent(ev_kind) != False){
      long evmask = getEventMaskBit();
      evmask |= WSGFeventToMaskBit(ev_kind); 
      setEventMaskBit(evmask);
    }
    return WS_NO_ERR;
  }


  if (isAvailableEvent(ev_kind) != False){
    setEventRegistered(True);
    setEventMaskBit(WSGFeventToMaskBit(ev_kind));
    setEvent(this,True);
    return WS_NO_ERR;
  }
  return WS_ERR;
}

long WSDwindowDev::setDisableEvent(long ev_kind){
  long mask = getEventMaskBit();
  mask &= ~WSGFeventToMaskBit(ev_kind);
  setEventMaskBit(mask);

  WSDdev* parent = getParentDev();
  if (parent == NULL){
    return WS_ERR;
  }

  if (mask == 0){
    setEvent(this,False);
    return WS_NO_ERR;
  }

  return WS_ERR;
}

long WSDwindowDev::getAvailableEventBit(){
  return (
     WSEV_MOUSE_MOVE_BIT   |
     WSEV_EXPOSE_BIT       |
     WSEV_RESIZE_BIT       |
     WSEV_FOCUS_CH_BIT     |
     WSEV_MOUSE_IN_BIT     |
     WSEV_MOUSE_OUT_BIT    |
     WSEV_MOUSE_PRESS_BIT    |
     WSEV_MOUSE_RELEASE_BIT  |
     WSEV_INITIALIZE_BIT   |
     WSEV_VISIBLE_CH_BIT   |
     WSEV_KEY_PRESS_BIT    |
     WSEV_KEY_RELEASE_BIT  |
     WSEV_KEY_HOOK_BIT 
     );
}

WSCbool WSDwindowDev::isAvailableEvent(long ev_kind){
  switch(ev_kind){
     case  WSEV_MOUSE_MOVE:   return True;
     case  WSEV_EXPOSE:       return True;
     case  WSEV_RESIZE:       return True;
     case  WSEV_FOCUS_CH:     return True;
     case  WSEV_MOUSE_IN:     return True;
     case  WSEV_MOUSE_OUT:    return True;
     case  WSEV_MOUSE_PRESS:    return True;
     case  WSEV_MOUSE_RELEASE:  return True;
     case  WSEV_MOUSE_DOUBLE_CLICK:  return True;
     case  WSEV_INITIALIZE:   return True;
     case  WSEV_VISIBLE_CH:   return True;
     case  WSEV_KEY_PRESS:    return True;
     case  WSEV_KEY_RELEASE:  return True;
     case  WSEV_KEY_HOOK:     return True;
  }
  return False;
}

void WSDwindowDev::setExposedArea(short x,short y,WSCushort w,WSCushort h){
  _exposed_x = x;
  _exposed_y = y;
  _exposed_w = w;
  _exposed_h = h;
}

void WSDwindowDev::setPixmapStyle(char val){
  _pixmap_style = val;
}

char WSDwindowDev::getPixmapStyle(){
  return _pixmap_style;
}

void WSDwindowDev::getWindowSize(short* x,short* y,WSCushort* w,WSCushort* h){
  *x = _w_x;
  *y = _w_y;
  *w = _w_w;
  *h = _w_h;
}

long WSDwindowDev::createWindow(){
  return WS_NO_ERR;
}

long WSDwindowDev::createPixmap(){
  _pixmap_created = True;
  return WS_NO_ERR;
}

long WSDwindowDev::createContext(){
  return WS_NO_ERR;
}
long WSDwindowDev::initialize(){
  return createWindow();
}

long WSDwindowDev::destroyPixmap(){
  _pixmap_created = False;
  return WS_NO_ERR;
}

long WSDwindowDev::destroyWindow(){
  return WS_NO_ERR;
}

long WSDwindowDev::destroyContext(){
  return WS_NO_ERR;
}

#if 0
WSDdev* WSDwindowDev::getDependDev(){
  return _depend_dev;
}

void WSDwindowDev::setDependDev(WSDdev* dpdev){
//WSMFtrace("WSDwindowDev::setDependDev this=0x%x dpdev=0x%x  <*><*><*> \n",this,dpdev);
  _depend_dev = dpdev;
}

WSCbool WSDwindowDev::isIndependent(){
  return False;
}
#endif
