/*
** XmgAction.c for  in 
** 
** Made by vianney rancurel
** Login   <vianney@epita.fr>
** 
** Started on  Wed Aug 25 14:15:17 1999 vianney rancurel
** Last update Thu Oct 28 20:22:37 1999 
*/
#include <X11/IntrinsicP.h>
#include <X11/ShellP.h>
#include <X11/StringDefs.h>
#include "XmgAction.h"

extern Widget		toplevel;

/* this is an XtActionProc.
   It does nothing. */
VOID_FUNC		XmgActionNop(w,event,params,num_params)
Widget			w;
XEvent			*event;
String			*params;
Cardinal		*num_params;
{
  /* NOP */
}

/* this is an XtActionProc.
   It popdowns the widget. */
VOID_FUNC		XmgActionPopdown(w,event,params,num_params)
Widget			w;
XEvent			*event;
String			*params;
Cardinal		*num_params;
{
  XtPopdown(w);
}

/* this is an XtActionProc.
   It destroys the widget. */
VOID_FUNC		XmgActionDestroy(w,event,params,num_params)
Widget			w;
XEvent			*event;
String			*params;
Cardinal		*num_params;
{
  if (w == toplevel)
    {
      XtDestroyApplicationContext(XtWidgetToApplicationContext(w));
      exit(0);
    }
  else
    XtDestroyWidget(w);
}

/* this is an XtActionProc.
   It sets the focus to the widget. */
VOID_FUNC		XmgActionSetFocus(w,event,params,num_params)
Widget			w;
XEvent			*event;
String			*params;
Cardinal		*num_params;
{
  XtSetKeyboardFocus(XtParent(w),w);
}

/* acts like XtPopdown(3) but doesn't call XtRemoveGrab(3).
   (as it is called by another routine: see XmgActionPopdownAllMenus(3).) */
VOID_FUNC		XmgPopdown(widget)
Widget			widget;
{
  ShellWidget		shell_widget;

  shell_widget = (ShellWidget)widget;
  if (!XtIsShell(widget)) 
    {
      XtAppErrorMsg(XtWidgetToApplicationContext(widget),
		    "invalidClass","xmgPopdown","XmgToolkitError",
		    "XmgPopdown requires a subclass of shellWidgetClass",
		    (String *)NULL,
		    (Cardinal *)NULL);
    }
  if (shell_widget->shell.popped_up) 
    {
      XtGrabKind	grab_kind;

      grab_kind = shell_widget->shell.grab_kind;
      XtUnmapWidget(widget);
      XWithdrawWindow(XtDisplay(widget),
		      XtWindow(widget),
		      XScreenNumberOfScreen(XtScreen(widget)));
      if (grab_kind != XtGrabNone)
	{
#ifdef NOTDEF
	  XtRemoveGrab(widget);
#endif
        }
      shell_widget->shell.popped_up = FALSE;
      XtCallCallbacks(widget,XtNpopdownCallback,(XtPointer)&grab_kind);
    }
}

/* this is an XtActionProc.
 Should be used instead of MenuPopdown() on <BtnUp> translations in the
 top cascaded menu. */
VOID_FUNC		XmgActionPopdownAllMenus(w,event,params,num_params)
Widget			w;
XEvent			*event;
String			*params;
Cardinal		*num_params;
{
  int			i;
  CoreWidget		parent;

  parent = XtParent(w);
  i = 0;
  while (i < parent->core.num_popups)
    {
#ifdef NOTDEF
      XtCallActionProc(parent->core.popup_list[i],
		       "XtMenuPopdown",
		       event,
		       params,
		       *num_params);
#else
      XmgPopdown(parent->core.popup_list[i]);
#endif
      i++;
    }
  XtRemoveGrab(w);
}

/* this is an XtActionProc.
 Should be used on <EnterWindow> translations in cascaded menus. */
VOID_FUNC	XmgActionPopdownAllMenusAfterMe(w,event,params,num_params)
Widget			w;
XEvent			*event;
String			*params;
Cardinal		*num_params;
{
  int			i;
  CoreWidget		parent;
  Boolean		ok;

  ok = False;
  parent = XtParent(w);
  i = 0;
  while (i < parent->core.num_popups)
    {
      if (ok)
	{
#ifdef NOTDEF
	  XtCallActionProc(parent->core.popup_list[i],
			   "XtMenuPopdown",
			   event,
			   params,
			   *num_params);
#else
	  XmgPopdown(parent->core.popup_list[i]);
#endif
	}
      if (parent->core.popup_list[i] == w)
	ok = True;
      i++;
    }
}

#ifdef DEBUG
/* is an XtActionProc.
   Echoes string. This is a debug feature used to test translations */
VOID_FUNC		XmgActionEcho(w,event,params,num_params)
Widget			w;
XEvent			*event;
String			*params;
Cardinal		*num_params;
{
  int			i;
  char			buf[STR_BUFSIZ];
  t_status		status;

  buf[0] = 0;
  i = 0;
  while (i < *num_params)
    {
      if ((status = str_cat_fmt_va(buf,
				   sizeof (buf),
				   "%s ",
				   params[i])) != 0)
	goto end;
      i++;
    }
end:
  XtWarning(buf);
}
#endif

XtActionsRec            XmgActions[] =
{
  {"XmgNop",		XmgActionNop},
  {"XmgPopdown",	XmgActionPopdown},
  {"XmgDestroy",	XmgActionDestroy},
  {"XmgSetFocus",	XmgActionSetFocus},
  {"XmgPopdownAllMenus",XmgActionPopdownAllMenus},
  {"XmgPopdownAllMenusAfterMe",XmgActionPopdownAllMenusAfterMe},
#ifdef DEBUG
  {"XmgEcho",		XmgActionEcho},
#endif
};

Cardinal		XmgNumActions = XtNumber(XmgActions);

/* installs a WM_DELETE_WINDOW action which destroys the widget. */
VOID_FUNC		XmgSetDestroyOnDelete(w)
Widget			w;
{
  Atom			atom;

  atom = XInternAtom(XtDisplay(w),"WM_DELETE_WINDOW",False);
  XtOverrideTranslations(w,
               XtParseTranslationTable("<Message>WM_PROTOCOLS: XmgDestroy()"));
  XSetWMProtocols(XtDisplay(w),XtWindow(w),&atom,1);
}

/* installs a WM_DELETE_WINDOW action which popdowns the widget. */
VOID_FUNC		XmgSetPopdownOnDelete(w)
Widget			w;
{
  Atom			atom;

  atom = XInternAtom(XtDisplay(w),"WM_DELETE_WINDOW",False);
  XtOverrideTranslations(w,
                 XtParseTranslationTable("<Message>WM_PROTOCOLS: XmgPopdown()"));
  XSetWMProtocols(XtDisplay(w),XtWindow(w),&atom,1);
}

/* installs a <Key>Return action which does nothing. */
VOID_FUNC		XmgSetNopOnReturn(w)
Widget			w;
{
  XtOverrideTranslations(w,
                         XtParseTranslationTable("<Key>Return: XmgNop()"));
}
