/**
 *
 * $Id: GrabShell.c,v 1.4 1997/08/24 12:40:35 pgw Exp $
 *
 * Copyright (C) 1997 Free Software Foundation, Inc.
 *
 * This file is part of the GNU LessTif Library.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, write to the Free
 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 **/

static char rcsid[] = "$Id: GrabShell.c,v 1.4 1997/08/24 12:40:35 pgw Exp $";

#include <LTconfig.h>
#include <XmI/XmI.h>

#include <Xm/XmP.h>
#include <Xm/GrabShellP.h>
#include <Xm/MwmUtil.h>
#include <Xm/TransltnsP.h>

#include <XmI/PixConvI.h>

#include <XmI/MessagesI.h>
#include <XmI/DebugUtil.h>


/*
  MODULE: GrabShell.c
  DESCRIPTION:
  Contains the routines that compose the GrabShell widget.

  Warning, this widget is under construction.
  END:
*/

#define VALID(w) (w && XtIsManaged(w))
#define Unused(x) (void)(x)
#define superclass (&vendorShellClassRec)
#define Offset(field) XtOffsetOf(XmGrabShellRec, grab_shell.field)

/* Forward declarations */
static void BtnDown(Widget,XEvent *,String *,Cardinal *);
static void BtnUp(Widget,XEvent *,String *,Cardinal *);
static void ChangeManaged(Widget w);
static void ClassPartInitialize(WidgetClass class);
static void CreateBottomShadowGC(Widget w);
static void CreateTopShadowGC(Widget w);
static void Destroy(Widget w);
static void DoLayout(Widget w);
static void DrawBorder(Widget w, XEvent *xev, Region region);
static void GSAllowEvents(Widget w);
static XtGeometryResult GeometryManager(Widget w, 
   XtWidgetGeometry *request, 
   XtWidgetGeometry *reply);
static int IgnoreXErrors(Display *dpy, XErrorEvent *xev);
static void Initialize(Widget request, 
   Widget c_new,
   ArgList args,
   Cardinal *num_args);
static void MapNotifyHandler(Widget w);
static void Popdown(Widget,XEvent *,String *,Cardinal *);
static void Resize(Widget w);
static Boolean SetValues(Widget current, 
   Widget request, 
   Widget c_new, 
   ArgList args,
   Cardinal *num_args);

/* Resources for the GrabShell class */
static XtResource resources[] = {

   {
     XmNbottomShadowColor,
     XmCBottomShadowColor,
     XmRPixel,
     sizeof(Pixel),
     Offset(bottom_shadow_color),
     XmRCallProc,
     (XtPointer)_XmBottomShadowColorDefault
   },

   {
     XmNbottomShadowPixmap,
     XmCBottomShadowPixmap,
     XmRBottomShadowPixmap,
     sizeof(Pixmap),
     Offset(bottom_shadow_pixmap),
     XmRImmediate,
     (XtPointer)XmUNSPECIFIED_PIXMAP
   },

   {
     XmNgrabStyle,
     XmCGrabStyle,
     XmRInt,
     sizeof(int),
     Offset(grab_style),
     XmRImmediate,
     (XtPointer)0 
   },

#if 0
   {
     XmNmwmDecorations, 
     XmCMwmDecorations, 
     XmRInt,
     sizeof(int), 
     XtOffsetOf(XmGrabShellRec, vendor_shell.mwm_hints.decorations),
     XmRImmediate, 
     (XtPointer)0
   },
#endif

   {
     XmNownerEvents,
     XmCOwnerEvents,
     XmRBoolean,
     sizeof(Boolean),
     Offset(owner_events),
     XmRImmediate,
     (XtPointer)True
   },

   {
     XmNshadowThickness,
     XmCShadowThickness,
     XmRHorizontalDimension,
     sizeof(Dimension),
     Offset(shadow_thickness),
     XmRImmediate,
     (XtPointer)2
   },

   {
     XmNtopShadowColor,
     XmCTopShadowColor,
     XmRPixel,
     sizeof(Pixel),
     Offset(top_shadow_color),
     XmRCallProc,
     (XtPointer)_XmTopShadowColorDefault
   },

   {
     XmNtopShadowPixmap,
     XmCTopShadowPixmap,
     XmRTopShadowPixmap,
     sizeof(Pixmap),
     Offset(top_shadow_pixmap),
     XmRCallProc,
     (XtPointer)_XmTopShadowPixmapDefault
   }

};

/* Action table */
static XtActionsRec actionsList[] = {
   {"BtnDown", BtnDown},
   {"BtnUp", BtnUp},
   {"Popdown", Popdown} 
};

/* ========================================================================== */
/* Class record */

XmGrabShellClassRec xmGrabShellClassRec = {
   /* Core class part */
   {
      (WidgetClass) &vendorShellClassRec,     /* superclass */
      "XmGrabShell",                          /* class_name */
      sizeof(XmGrabShellRec),                 /* widget_size */
      NULL,                                   /* class_initialize */
      ClassPartInitialize,                    /* class_part_initialize */
      FALSE,                                  /* class_inited */
      Initialize,                             /* initialize */
      NULL,                                   /* initialize_hook */
      0,/*************XtInheritRealize,*/                       /* realize */
      actionsList,                            /* actions */
      XtNumber(actionsList),                  /* num_actions */
      resources,                              /* resources */
      XtNumber(resources),                    /* num_resources */
      NULLQUARK,                              /* xrm_class */
      TRUE,                                   /* compress_motion */
      XtExposeCompressMaximal,                /* compress_exposure */
      TRUE,                                   /* compress_enterleave */
      FALSE,                                  /* visible_interest */
      Destroy,                                /* destroy */
      Resize, /* XtInheritResize,  */         /* resize */
      DrawBorder, /* XtInheritExpose  */      /* expose */
      SetValues,                              /* set_values */
      NULL,                                   /* set_values_hook */
      0,/*******XtInheritSetValuesAlmost,*/               /* set_values_almost */
      NULL,                                   /* get_values_hook */
      NULL,                                   /* accept_focus */
      XtVersion,                              /* version */
      NULL,                                   /* callback offsets */
      0,/**********XtInheritTranslations,*/                  /* tm_table */
      NULL,                                   /* query_geometry */
      NULL,                                   /* display_accelerator */
      NULL                                    /* extension */ 
   },
   /* Composite class part */
   {
      GeometryManager,        /* geometry manager */
      ChangeManaged,          /* ChangeManaged */
      0,/*********XtInheritInsertChild,*/   /* insert_child */ 
      0,/*********XtInheritDeleteChild,*/   /* delete_child */ 
      NULL                    /* extension */ 
   },
   /* Shell class part */
   {
      NULL                    /* extension */ 
   },
   /* WMShell class part */
   {
      NULL                    /* extension */ 
   },
   /* VendorShell class part */
   {
      NULL                    /* extension */ 
   },
   /* XmGrabShell class part */
   {
      NULL                    /* extension */ 
   }
};

int AMIWIN_GrabShell(void)
{
xmGrabShellClassRec.realize=XtInheritRealize;
xmGrabShellClassRec.set_values_almost=XtInheritSetValuesAlmost;
xmGrabShellClassRec.tm_table=AMIWIN_XtInheritTranslations;
xmGrabShellClassRec.insert_child=XtInheritInsertChild;
xmGrabShellClassRec.delete_child=XtInheritDeleteChild;
return(0);
}


WidgetClass xmGrabShellWidgetClass = (WidgetClass) &xmGrabShellClassRec;

/*
  FUNCTION: BtnDown
  SYNOPSIS: static void BtnDown(Widget, XEvent *, String *, Cardinal *)
  DESCRIPTION:
  This function handles button down actions. 
  END:
  FIXTHIS: Needs to be implemented.
*/
static void 
BtnDown(
   Widget w,
   XEvent * xev,
   String * params,
   Cardinal * num_params)
{
   Unused(w);
   Unused(xev);
   Unused(params);
   Unused(num_params);

   XdbDebug(__FILE__, w, "BtnDown\n");
}

/*
  FUNCTION: BtnUp
  SYNOPSIS: static void BtnUp(Widget, XEvent *, String *, Cardinal *)
  DESCRIPTION:
  This function handles button up actions. 
  END:
  FIXTHIS: Needs to be implemented.
*/
static void 
BtnUp(
   Widget w,
   XEvent * xev,
   String * params,
   Cardinal * num_params)
{
   Unused(w);
   Unused(xev);
   Unused(params);
   Unused(num_params);

   XdbDebug(__FILE__, w, "BtnUp\n");
}

static void 
ChangeManaged(Widget w)
{

   XdbDebug(__FILE__, w, "ChangeManaged ...\n");

   if(!XtIsManaged(w))
   {
      /* 
      FIXTHIS: This is a hack to get around "Error: Shell widget GrabShell has zero width and/or height" */
      XtWidth(w) = 1;
      XtHeight(w) = 1;
#if 0
     {
      int decor;
      /* remove any decorations */
      XtVaGetValues(w, XmNmwmDecorations, &decor, NULL);
      decor &= ~MWM_DECOR_ALL;
      XtVaSetValues(w, XmNmwmDecorations, decor, NULL);
     }
#endif
  
      return;
   }

   DoLayout(w);
}

static void
ClassPartInitialize(WidgetClass widget_class)
{
#if 0
   /* FIXTHIS: do something here with the extension pointer */
   XmGrabShellWidgetClass nbclass = (XmGrabShellWidgetClass)widget_class;
   XmVendorShellExtObjectClass ext, *extptr;
   extptr = (XmVendorShellExtObjectClass *)_XmGetClassExtensionPtr(
                    (XmGenericClassExt *)&(nbclass->vendor_class.extension),
                                                                   NULLQUARK);

#endif

   _XmFastSubclassInit(widget_class, XmGRAB_SHELL_BIT);

}

/*
  FUNCTION: CreateBottomShadowGC
  SYNOPSIS: static void CreateBottomShadowGC(Widget w)
  DESCRIPTION:
  This function does not exist in Motif 2.0 but allows for better
  organization of the code.  This function gets/creates the bottom 
  shadow GC.
  END:
*/
static void
CreateBottomShadowGC(Widget w)
{
   XGCValues values;
   XtGCMask mask;

   mask = GCLineWidth;
   values.line_width = 1;
   GS_BottomShadowGC(w) = _XmGetPixmapBasedGC(w,
      GS_BottomShadowPixmap(w),
      GS_BottomShadowColor(w),
      mask,
      &values);
}

/*
  FUNCTION: CreateTopShadowGC
  SYNOPSIS: static void CreateTopShadowGC(Widget w)
  DESCRIPTION:
  This function does not exist in Motif 2.0 but allows for better
  organization of the code.  This function gets/creates the top
  shadow GC.
  END:
*/
static void
CreateTopShadowGC(Widget w)
{
   XGCValues values;
   XtGCMask mask;

   /* get top shadow GC values */
   mask = GCLineWidth | GCLineStyle | GCJoinStyle | GCCapStyle;
   values.line_width = 1;
   values.line_style = LineSolid;
   values.join_style = JoinMiter;
   values.cap_style = CapButt;

   GS_TopShadowGC(w) = _XmGetPixmapBasedGC(w,
      GS_TopShadowPixmap(w),
      GS_TopShadowColor(w),
      mask,
      &values);
}

/*
  FUNCTION: Destroy
  SYNOPSIS: static void Destroy(Widget w)
  DESCRIPTION:
  This function releases allocated memory done by the widgets instance. 
  END:
*/
static void
Destroy(Widget w)
{
   Unused(w);

   /* release GC's */
   XtReleaseGC(w,GS_TopShadowGC(w));
   XtReleaseGC(w,GS_BottomShadowGC(w));
}

/*
  FUNCTION: DoLayout
  SYNOPSIS: static void DoLayout(Widget w)
  DESCRIPTION:
  This function repositions child windows according to its own geometry.
  END:
*/
static void
DoLayout(Widget w)
{
   XdbDebug(__FILE__, w, "DoLayout ...\n");
   Unused(w);
}

/*
  FUNCTION: DrawBorder
  SYNOPSIS: static void DrawBorder(Widget w)
  DESCRIPTION:
  This function draws the widget border.
  END:
*/
static void
DrawBorder(Widget w, XEvent *xev, Region region)
{
   XmeDrawShadows(XtDisplayOfObject(w),       /* display */
                  XtWindowOfObject(w),        /* window */
                  GS_TopShadowGC(w),          /* top gc */
                  GS_BottomShadowGC(w),       /* bottom gc */
                  0,                          /* position x */
                  0,                          /* position y */
                  XtWidth(w),                 /* width */
                  XtHeight(w),                /* height */
                  GS_ShadowThickness(w),      /* shadow thickness */
                  0);                         /* shadow type */

   Unused(w);
   Unused(xev);
   Unused(region);
}

static void
GSAllowEvents(Widget w)
{
   Unused(w);

   XAllowEvents(XtDisplayOfObject(w), SyncPointer, CurrentTime);
}

static XtGeometryResult 
GeometryManager(Widget w, XtWidgetGeometry *request, XtWidgetGeometry *reply)
{
   XdbDebug(__FILE__, w, "GeometryManager ...\n");

   /* FIXTHIS: */

   Unused(w);
   Unused(request);
   Unused(reply);
   return (XtGeometryResult) NULL;
}

/*
  FUNCTION: IgnoreXErrors
  SYNOPSIS: static int IgnoreXErrors(Display *dpy, XErrorEvent *xev);
  DESCRIPTION:
  This function ignores all X errors.
  END:
*/
static int 
IgnoreXErrors(Display *dpy, XErrorEvent *xev)
{
   Unused(dpy);
   Unused(xev);

   /* 
   FIXTHIS: where do I set this?

   XSetErrorHandler((XErrorHandler) IgnoreXErrors);
   */

   /* X doesn't care what you return from here */
   return 0;
}

/*
  FUNCTION: Initialize
  SYNOPSIS: static void Initialize(Widget,Widget,ArgList,Cardinal *)
  DESCRIPTION:
  This function initializes the instance data.
  END:
*/
static void
Initialize(Widget request,
           Widget c_new,
           ArgList args,
           Cardinal *num_args)
{
   Unused(request);
   Unused(c_new);
   Unused(args);
   Unused(num_args);


   if (!XtIsSubclass(XtParent(c_new), shellWidgetClass))
   {
      XmeWarning(c_new, _XmMsgGrabS_0000);
   }

   CreateBottomShadowGC(c_new);
   CreateTopShadowGC(c_new);

}

static void 
MapNotifyHandler(Widget w)
{
   Unused(w);
}

/*
  FUNCTION: Popdown
  SYNOPSIS: static void Popdown(Widget, XEvent *, String *, Cardinal *)
  DESCRIPTION:
  This function handles popdown actions. 
  END:
  FIXTHIS: Needs to be implemented.
*/
static void 
Popdown(
   Widget w,
   XEvent * xev,
   String * params,
   Cardinal * num_params)
{
   Unused(w);
   Unused(xev);
   Unused(params);
   Unused(num_params);

   XdbDebug(__FILE__, w, "Popdown\n");
}

/* 
  FUNCTION: Resize
  SYNOPSIS: static void Resize(Widget w)
  DESCRIPTION:
  This routine handles resizing
  END:
*/
static void 
Resize(Widget w)
{
   XdbDebug(__FILE__, w, "Resize ...\n");

   if(XtIsRealized(w))
   {  /* widgets must be resized */
      DoLayout(w);
   }

   (*superclass->core_class.resize)(w);
}

/* 
  FUNCTION: SetValues
  SYNOPSIS: static Boolean SetValues(Widget,Widget,Widget,ArgList,Cardinal *)
  DESCRIPTION:
  This routine handles the setting of widget resources.
  END:
*/
static Boolean 
SetValues(Widget old, 
          Widget request, 
          Widget c_new, 
          ArgList args,
          Cardinal *num_args)
{
   XmGrabShellWidget ow = (XmGrabShellWidget) old;
   XmGrabShellWidget nw = (XmGrabShellWidget) c_new;
   Boolean need_refresh = False;

   /* FIXTHIS: SetValues is not implemented yet. */

   XdbDebug(__FILE__, old, "SetValues ...\n");

   Unused(request);
   Unused(args);
   Unused(num_args);
   Unused(ow);
   Unused(nw);

   return need_refresh;
}

/* Public routines */
/*
  FUNCTION: XmCreateGrabShell
  SYNOPSIS: Widget XmCreateGrabShell(Widget,char *,ArgList,Cardinal)
  DESCRIPTION:
  Creates an instance of a XmGrabShellWidget.
  END:
*/
Widget
XmCreateGrabShell(Widget parent, char *name, ArgList arglist,
                 Cardinal cnt)
{
   return XtCreateWidget(name,
                         xmGrabShellWidgetClass,
                         parent,
                         arglist,
                         cnt);
}


