/*-
 * Copyright (c) 2001 Jordan DeLong
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the author nor the names of contributors may be
 *    used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */
#ifndef CLIENT_H
#define CLIENT_H

/* various flags set on clients */
struct clientflags {
	u_int nofocus:1;		/* don't allow input focus */
	u_int noresize:1;		/* don't allow resizing */
	u_int nomove:1;			/* don't allow moving */
	u_int noiconify:1;		/* don't allow iconification */
	u_int nodelete:1;		/* don't allow window deletion */

	u_int zoomed:1;			/* is this window zoomed (maximized, etc) */
	u_int internal:1;		/* this managed window is one of ours */
	u_int transient:1;		/* this is a transient window */
	u_int shaped:1;			/* have shaped frame window */
	u_int sticky:1;			/* is this window sticky */

	u_int unmap_from_reparent:1;	/* the unmap_notify we get is from reparenting */
};

/*
 * structure describing a managed client.  this is the place where we keep
 * all of the data relating to individually managed windows; the windows
 * may or may not be made by other X11 clients; if flags.internal it means
 * it is one of our internal windows (created by a plugin).
 */
struct client {
	Window		window;			/* the client window */
	screen_t	*screen;		/* screen this client is on */
	workspace_t	*workspace;		/* workspace on the screen for this client */
	int		state;			/* the window's state (X states) */
	int		stacklayer;		/* stacking layer this client is on */

	int		x, y;			/* geometry information */
	int		width, height;
	int		save_x, save_y;		/* saved geometry (while zoomed, etc) */
	int		save_width, save_height;
	int		last_width, last_height;/* last width and height for hinting reshapes */

	XWMHints	*wmhints;		/* hints from the client */
	XSizeHints	normalhints;
	XClassHint	classhint;

	char		*store_name;		/* the window's name */

	Window	 	frame;			/* frame window (reparent of window) */
	Window		*decorwin;		/* decoration windows */

	dgroup_t	*save_dgroup;		/* saved dgroup; used in fullscreen zoom */
	dgroup_t	*dgroup;		/* decoration group this client uses */
	clientflags_t	flags;			/* flags for this client */

	TAILQ_ENTRY(client)	c_stacking;	/* stacking layer list entry */
	TAILQ_ENTRY(client)	c_focus;	/* focus list entry */
	LIST_ENTRY(client)	c_list;		/* list of all clients */
};

/*
 * accessors for size information with regard to
 * the client's dgroup.
 */
#define DWIDTH(client)		((client)->dgroup->left_space + (client)->dgroup->right_space)
#define DHEIGHT(client)		((client)->dgroup->top_space + (client)->dgroup->bottom_space)
#define FULLWIDTH(client)	(DWIDTH(client) + (client)->width)
#define FULLHEIGHT(client)	(DHEIGHT(client) + (client)->height)

typedef LIST_HEAD(, client) clientlist_t;
extern clientlist_t client_list;
extern client_t *client_focused;

void client_shutdown();
client_t *client_add(screen_t *screen, Window w,
	clientflags_t *flags, dgroup_t *dgroup);
void client_map(client_t *client, int allowplace);
void client_rm(client_t *client);
void client_shape(client_t *client);
void client_gravitate(client_t *client);
void client_sizeframe(client_t *client);
void client_setstate(client_t *client, int state);

#endif
