/* $Id: Popup.c,v 1.1 1997/04/15 10:09:44 archer Exp $
 *	POPUP.C - Handle popup window
 *
 * Popup are shells, but without the interaction with the WM. It is expected
 * that most popups will be displayed with screen grabs
 */
#include <Widget/PopupP.h>
#include <Widget/drawP.h>
#include <Widget/UnWMP.h>
#include <Widget/Manage.h>


/**
 ** Internal: POPUP_EXPOSE
 **	Redraw the popup borders
 **/
static void popup_expose(X11_widget wdg, XEvent *dummy)
{
/*
 * Quick-n-dirty
 */
	x11__draw_start(wdg);
	x11__shadows_gc();
	x11__draw_upshadow(wdg->shadow_thickness);
	x11__draw_nothing(wdg->margin_inside);
	x11__draw_downshadow(wdg->shadow_thickness);
}


/**
 ** Internal: POPUP_RESIZE
 **	Never occurs... But who knows what evil lurks inside the heart of
 **	X Consortium? (I'm not the Shadow, anyway)
 **/
static void popup_resize(X11_widget wdg, XEvent *size)
{
X11_widget	child;
int		v;
/*
 * Real resize, or just confirmation?
 */
	if (wdg->w == size->xconfigure.width &&
	    wdg->h == size->xconfigure.height)
		return;
/*
 * Resized
 */
	wdg->w = size->xconfigure.width;
	wdg->h = size->xconfigure.height;
	if ((child = wdg->child) == 0)
		return;
/*
 * Child resize
 */
	v = (wdg->shadow_thickness + wdg->margin_inside) * 2;
	child->w = wdg->w - wdg->border2 - v;
	child->h = wdg->h - wdg->border2 - v;
	(*child->on_resize_window)(child, (XEvent *)0);
}


/**
 ** Internal: POPUP_GEOMETRY
 **	Apply geometry from a popup, shell-like thingy
 **/
static void popup_geometry(X11_widget wdg, XEvent *dummy)
{
X11_widget	child;
int		v;
/*
 * Actual geometry is from child
 */
	if ((child = wdg->child) == 0)
		return;
	(*child->on_geometry_check)(child, dummy);
/*
 * Child must be at v,v
 */
	v  = wdg->margin_inside + wdg->shadow_thickness;
	v *= 2;
	if (child->x != v || child->y != v) {
		child->x = v;
		child->y = v;
		if (child->id)
			XMoveWindow(x11__screen, child->id, v, v);
	}
/*
 * Size hints
 */
	v += v + wdg->border2;
	wdg->w       = v + child->w;
	wdg->w_min   = v + child->w_min;
	wdg->fixed_w = child->fixed_w;
	wdg->h       = v + child->h;
	wdg->h_min   = v + child->h_min;
	wdg->fixed_h = child->fixed_h;
/*
 * Window sized
 */
	x11__core_resize(wdg, dummy);
}


/**
 ** X11_POPUP
 **	Create a popup shell window
 **/
X11_widget X11_Popup(char *name, char *title)
{
x11__popup	*object;
/*
 * Get resource
 */
	object = allocator(x11__popup);
	x11__core_setup(&object->shell.core, x11__widget_root, "Popup", name);
/*
 * We're the shell
 */
	object->shell.core.shell = OBJECT_P;
/*
 * Initialize fields
 */
	object->shell.core.on_expose         = popup_expose;
	object->shell.core.on_key_press      = x11__key_act;
	object->shell.core.on_resize_window  = popup_resize;
	object->shell.core.on_destruction    = x11__shell_cleanup;
	object->shell.core.on_geometry_check = popup_geometry;
	object->shell.core.on_window_create  = x11__nowm_create;
	object->shell.core.unmapped          = True;
	object->shell.core.unmanaged         = True;
	object->shell.core.event_mask = ExposureMask;
/*
 * Ressources default
 */
	object->shell.core.border2          = 2;
	object->shell.core.margin_inside    = 4;
	object->shell.core.shadow_thickness = 2;
/*
 * Title
 */
	if (!title)
		title = "Popup";
	object->shell.title = strdup(title);
/*
 * Fetch X11 resources
 */
	x11__resource_basic(&object->shell.core);
/*
 * Done
 */
	object->shell.has_keyboard_focus = True;
	return OBJECT_P;
}


/**
 ** X11_POPUP_DISPLAY
 **	Display a shell window
 **/
void X11_PopupDisplay(X11_widget wdg)
{
	if (wdg->unmanaged) {
/*
 * Do the right thing
 */
		(*wdg->on_geometry_check)(wdg, (XEvent *)0);
		wdg->x = (x11__widget_root->w - wdg->w) / 2;
		wdg->y = (x11__widget_root->h - wdg->h) / 2;
		if (wdg->id)
			XMoveWindow(x11__screen, wdg->id, wdg->x, wdg->y);
		X11_Manage(wdg);
		XRaiseWindow(x11__screen, wdg->id);
		XMapWindow(x11__screen, wdg->id);
	}
}
