/*********************************************************************
 *
 *         EZWGL, the EZ Widget and Graphics Library
 *
 *             Copyright (C) 1996, 1997  Maorong Zou
 *  
 * 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.
 *
 **********************************************************************/
/*
 *  June 1996.  Beta Release.
 *  Sept 1996.  Release Version 1.0
 *  Dec 1996.  Release Version 1.1 Beta
 *  April 1997.  Release Version 1.2
 *  November 1997.  Release Version 1.3
 */
/*****************************************************************
 *
 *   Utility functions.
 *
 *****************************************************************/
#define _EZ_WIDGET_MISC_C_
#include "EZ_Widget.h"

void EZ_CallWidgetCallbacks(widget)
     EZ_Widget *widget;
{
  EZ_ExecuteWidgetCallBacks(widget);
}

void EZ_CallWidgetMotionCallbacks(widget)
     EZ_Widget *widget;
{
  if(EZ_LookupWidgetFromAllHT(widget) != (EZ_Widget *)NULL)
    {
      EZ_HandleMotionCallBacks(widget,
			       EZ_WidgetMotionCallBack(widget));
    }
}
EZ_Widget *EZ_GetToplevelWidget(widget)
     EZ_Widget *widget;
{
  if(EZ_LookupWidgetFromAllHT(widget) != (EZ_Widget *)NULL)
    {
      EZ_Widget *parent = widget;
      while(EZ_WidgetParent(parent) != NULL)
	{ parent = EZ_WidgetParent(parent);}
      return(parent);
    }
  return(NULL);
}

/* Find a window with WM_STATE, else return win itself, as per ICCCM */
/* modified from:  $XConsortium: ClientWin.c */

static Window TryChildren MY_ANSIARGS((Display *dpy, Window win, Atom atom));

Window EZ_FindClientWindow(win)
     Window  win;
{
    Atom          WM_STATE;
    Atom          type = None;
    int           format;
    unsigned long nitems, after;
    unsigned char *data;
    Window        inf;
    Display       *dpy = EZ_Display;
    int            (*OldErrorHandler)();
      
    WM_STATE = XInternAtom(dpy, "WM_STATE", True);
    if(!WM_STATE) return win;
    
    if(!EZ_WindowExist(win)) return(None);
    EZ_XErrorCode = 0;
    OldErrorHandler = XSetErrorHandler(EZ_XErrorHandler);
    XGetWindowProperty(dpy, win, WM_STATE, 0, 0, False, AnyPropertyType,
		       &type, &format, &nitems, &after, &data);
    XSync(EZ_Display, False);
    XSetErrorHandler(OldErrorHandler);  
    if(EZ_XErrorCode != 0) return(win);

    if(type) return(win);
    inf = TryChildren(dpy, win, WM_STATE);
    if(!inf) inf = win;
    return(inf);
}

static Window TryChildren(dpy, win, WM_STATE)
     Display *dpy;
     Window win;
     Atom WM_STATE;
{
    Window        root, parent, *children;
    unsigned int  i, nchildren;
    Atom          type = None;
    int           format;
    unsigned long nitems, after;
    unsigned char *data;
    Window        inf = None;

    if(!XQueryTree(dpy, win, &root, &parent, &children, &nchildren)) return(None);
    for(i = 0; !inf && (i < nchildren); i++) 
      {
	XGetWindowProperty(dpy, children[i], WM_STATE, 0, 0, False,
			   AnyPropertyType, &type, &format, &nitems,
			   &after, &data);
	if(type)inf = children[i];
      }
    for(i = 0; !inf && (i < nchildren); i++)
      inf = TryChildren(dpy, children[i], WM_STATE);
    if(children) XFree((char *)children);
    return(inf);
}
/*****************************************************************/
#undef _EZ_WIDGET_MISC_C_

