/* $Id: Manage.c,v 1.2 1997/05/01 15:22:09 archer Exp $
 *	MANAGE.C - Generic Widget management functions
 *
 */
#include <Widget/Manage.h>
#include <Widget/WidgetsP.h>
#include <Widget/ShellP.h>
#if 0
#include <Widget/MenuP.h>
#else
static char x11__menu_class[1];
#endif
#include <X11/Xutil.h>


/**
 ** Internal: RECURSIVE_CREATE_MANAGED
 **/
static void recursive_create_managed(X11_widget wdg)
{
/*
 * Terminal case
 */
	if (!wdg || wdg->unmanaged)
		return;
/*
 * Create
 */
	if (!wdg->id)
		(*wdg->on_window_create)(wdg, (XEvent *)0);
/*
 * Recursion
 */
	for (wdg = wdg->child; wdg; wdg = wdg->sibling)
		recursive_create_managed(wdg);
}


/**
 ** Internal:SHELL_WM_HINTS
 **	Sets WM size hints
 **/
static void shell_WMhints(X11_widget wdg)
{
XSizeHints	*hint;
XWMHints	wm_hint;
/*
 * Create and fill size hints
 */
	hint = XAllocSizeHints();
	hint->flags      = PSize|PMinSize|PMaxSize;
	hint->width      = wdg->w;
	hint->height     = wdg->h;
	hint->min_width  = wdg->w_min;
	hint->min_height = wdg->h_min;
	if (wdg->fixed_w)
		hint->max_width = hint->min_width;
	else
		hint->max_width = x11__widget_root->w;
	if (wdg->fixed_h)
		hint->max_height = hint->min_height;
	else
		hint->max_height = x11__widget_root->h;
/*
 * Special hints?
 */
	if (wdg->hint_x || wdg->hint_y) {
		hint->flags |= PPosition;
		if (wdg->hint_x < 0)
			hint->x = x11__widget_root->w - wdg->w;
		else
			hint->x = 0;
		if (wdg->hint_y < 0)
			hint->y = x11__widget_root->h - wdg->h;
		else
			hint->y = 0;
		hint->x += wdg->hint_x;
		hint->y += wdg->hint_y;
		wdg->hint_x = 0;
		wdg->hint_y = 0;
	}
	if (wdg->hint_w < wdg->w_min)
		wdg->hint_w = 0;
	if (wdg->hint_w) {
		hint->width = wdg->hint_w;
		wdg->hint_w = 0;
	}
	if (wdg->hint_h < wdg->h_min)
		wdg->hint_h = 0;
	if (wdg->hint_h) {
		hint->height = wdg->hint_h;
		wdg->hint_h = 0;
	}
/*
 * Special WM Hints
 */
	wm_hint.flags = 0;
/*
 * Hints set
 */
	XSetWMProperties(x11__screen, wdg->id,
				(XTextProperty *)0, (XTextProperty *)0,
				(char **)0, 0, hint, &wm_hint, (XClassHint *)0);
	XFree(hint);
/*
 * Now the extended hints
 */
/*** HACK ***/
}


/**
 ** X11_MANAGE
 **	Sets the widget to the "managed" state
 **/
void X11_Manage(X11_widget wdg)
{
X11_widget	sub;
x11__shell	*shell;
/*
 * Job already done?
 */
	if (!wdg || !wdg->unmanaged)
		return;
/*
 * Create the widgets
 */
	(*wdg->on_geometry_check)(wdg, (XEvent *)0);
	wdg->unmanaged = False;
	recursive_create_managed(wdg);
/*
 * For shell objects...
 */
	if (wdg->shell == wdg)
		shell_WMhints(wdg);
/*
 * For direct children of shells...
 */
	else
		if (wdg->parent == wdg->shell) {
			shell = (x11__shell *)wdg->shell;
			for (sub = shell->core.child; sub; sub = sub->sibling)
				if (!sub->unmanaged && sub != wdg) {
					X11_UnManage(sub);
/*
 * Previous defaults and focus vanish
 */
					if (shell->current_default)
						x11__default_loses(shell->current_default);
					if (shell->current_focus)
						x11__focus_loses(shell->current_focus);
				}
		}
/*
 * Now maps the object
 */
	if (wdg->unmapped && wdg->id) {
		wdg->unmapped = False;
		XMapWindow(x11__screen, wdg->id);
	}
}


/**
 ** X11_UNMANAGE
 **	Sets the widget to the "unmanaged" state
 **/
void X11_UnManage(X11_widget wdg)
{
	if (!wdg)
		return;
	if (wdg->id)
		XUnmapWindow(x11__screen, wdg->id);
	wdg->unmanaged = True;
	wdg->unmapped  = True;
}


/**
 ** X11_IS_MANAGED
 **	Return True is an object is managed and visible on screen
 **/
boolean X11_IsManaged(X11_widget wdg)
{
X11_widget	o;

	for (o = wdg; o->parent; o = o->parent)
		if ((o->unmapped || o->unmanaged) &&
		    strcmp(o->class, x11__menu_class))
			return False;
	return True;
}
