#include <stdio.h>
#include <unistd.h>

#include "sopnamsp.h"
#include "piwindowx.h"

#include <X11/Xlib.h>

#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/IntrinsicP.h>
#include <X11/Shell.h>
#include <Xm/Form.h>

/* Fonctions (Callback et action) pour traiter le message Close de WM  */

/* Nouvelle-Fonction */
static void popdwn_cb(Widget /*w*/, XtPointer *usd,  XtPointer * )
{
PIWindowX * dw = (PIWindowX *) usd;
dw->Process(dw->BuildMsg(dw->Msg(),PIMsg_Close), dw, NULL) ;
}


/* *** ATTENTION *** La constante ci-dessous PIXMFORMFRACBASE
   doit etre identique ds piwdgx.cc  picontainerx.cc et piwindowx.cc
   ***************************************************************** */
#define PIXMFORMFRACBASE 1000


/* --Methode-- */
PIWindowX::PIWindowX(PIMsgHandler *par, const char *nom, PIWindowKind k, 
                     int sx, int sy, int px, int py)
: PIWindowGen(par, nom, k, -1, -1, 0, 0)
{
XtTranslations trans;

pwm = new PIWdgX(NULL, nom, sx, sy, px, py);

switch (k)
  {
  case PIWK_normal :
  case PIWK_floating :
    pwm->CreateXtWdg(nom, topLevelShellWidgetClass, NULL, sx, sy, px, py);
    break;
  case PIWK_dialog :
    pwm->CreateXtWdg(nom, transientShellWidgetClass, NULL, sx, sy, px, py);
    break;
  case PIWK_transient :
    pwm->CreateXtWdg(nom, overrideShellWidgetClass, NULL, sx, sy, px, py);
    break;
  }


/*  Il faut "attraper" l'action close, genere par le window-manager       */
/*  2 actions sont necessaires, installation d'une action (CloseWindow()) */
/*  et j'utilise ensuite un callback ds CloseWindow()                     */
/*  Il faut aussi desactiver l'action de destruction du widget par defaut */
/*  (XtSetArg(warg, XmNdeleteResponse, ...                                */
/*  Attention, voir la fonction Show(), pour l'appel a XSetWMProptocols() */
/*  Pour une fenetre donnee, on peut recuperer les Map, UnMap, Destroy,   */
/*  etc... il faut appeler XtAddEventHandler( w, Mask, ...)               */
/*    Mask =  StructureNotifyMask | SubstructureNotifyMask                */



if ((k == PIWK_normal) || (k == PIWK_floating) || (k == PIWK_dialog))
  { 
  if (k == PIWK_dialog)  AutoHideOnClose(false);
  /* XtAddEventHandler(pwm->XtWdg(), StructureNotifyMask | SubstructureNotifyMask, 
                  FALSE, wmaction_evthandler, this);*/

  XtAddCallback(pwm->XtWdg(), XtNpopdownCallback,
                (XtCallbackProc)popdwn_cb, (XtPointer)this);


  trans = XtParseTranslationTable("<Message>WM_PROTOCOLS:CloseWindow()");
  XtOverrideTranslations(pwm->XtWdg() , trans);
  Arg warg[2];
  XtSetArg(warg[0], XmNdeleteResponse, XmDO_NOTHING);
  XtSetValues(pwm->XtWdg(), warg, 1);
  }

CreateXtWdg(nom, xmFormWidgetClass, pwm->XtWdg(), sx, sy, 0, 0);
int fbase = 1000 ;  // Valeur de XmNfractionBase des XmForm ds PIContainerX
Arg  wargs[2];
int n=0;
XtSetArg(wargs[n],XmNfractionBase, fbase);  n++;
XtSetValues(XtWdg(), wargs, n);

wmis = k_wmi_cascade;
}

/* --Methode-- */
PIWindowX::~PIWindowX()
{
Hide();
delete pwm;
}

/* --Methode-- */
void PIWindowX::BindWdgtoParent()
{
// On ne doit rien faire pour les fenetres 
return;
}

/* --Methode-- */
void PIWindowX::SetSize(int sx, int sy)
{
pwm->SetSize(sx, sy);
PIWdgX::SetSize(sx, sy);
return;
}

/* --Methode-- */
void PIWindowX::SetPos(int px, int py)
{
pwm->SetPos(px, py);
PIWdgX::SetPos(px, py);
return;
}


/* --Methode-- */
void PIWindowX::Show()
{
int fgr = 0;
Display *mdsp;

mdsp = XtDisplay(pwm->XtWdg());

PIContainerGen::Show();
// Manage();  $CHECK$ Ca ne doit plus etre necessaire Reza 9/7/97
if (!XtIsRealized(pwm->XtWdg()))  fgr = 1;
pwm->Manage();
if (fgr) 
  {
  Atom wmd;
  if ((mWtyp == PIWK_normal) || (mWtyp == PIWK_floating) || (mWtyp == PIWK_dialog))
    { 
    wmd = XInternAtom(mdsp, "WM_DELETE_WINDOW",False);
    XSetWMProtocols(mdsp, XtWindow(pwm->XtWdg()), &wmd, 1);
    }
  else 
    XSetTransientForHint(mdsp, XtWindow(PIXtTopWdg()), XtWindow(pwm->XtWdg()));
  //  Pour faire les actions sur les fenetres X, sinon fenetre pas cree 
  PIContainerGen::FinishCreate();
  }

// XRaiseWindow est necessaire, sinon la fenetre passe des fois derriere ...
//if (mWtyp == PIWK_transient)  
  XRaiseWindow(mdsp, XtWindow(pwm->XtWdg()));
  // cmv+rz Fevrier 2009 (retour Moriond) - Suppression de XFlush() / usleep  
  // Probleme regle par gestion VisibilityChange event ds pixtbase.cc
  // cmv+rz 09/08/2007 Ajout XFlush() + usleep 
  // pour regler le probleme de  perte d'evenement expose a la creation
  //  XFlush(mdsp);   usleep(5000);
return;
}

/* --Methode-- */
void PIWindowX::Hide()
{
PIWindowGen::Hide();
// UnManage();  $CHECK$ Ca ne doit plus etre necessaire Reza 9/7/97
pwm->UnManage();
}


