/* 
 * Oroborus Window Manager
 * X11 Hints Utility Library 
 *
 * Copyright (C) 2001 Ken Lynch
 * Copyright (C) 2002 Stefan Pfetzing
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2, or (at your option)
 * any later version.
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  
 */

#ifndef __HINTS_H
#define __HINTS_H

#include <X11/Xatom.h>

#define MWM_HINTS_FUNCTIONS     (1L << 0)
#define MWM_HINTS_DECORATIONS   (1L << 1)
#define MWM_HINTS_INPUT_MODE    (1L << 2)
#define MWM_HINTS_STATUS        (1L << 3)

#define MWM_FUNC_ALL            (1L << 0)
#define MWM_FUNC_RESIZE         (1L << 1)
#define MWM_FUNC_MOVE           (1L << 2)
#define MWM_FUNC_MINIMIZE       (1L << 3)
#define MWM_FUNC_MAXIMIZE       (1L << 4)
#define MWM_FUNC_CLOSE          (1L << 5)

#define MWM_DECOR_ALL           (1L << 0)
#define MWM_DECOR_BORDER        (1L << 1)
#define MWM_DECOR_RESIZEH       (1L << 2)
#define MWM_DECOR_TITLE         (1L << 3)
#define MWM_DECOR_MENU          (1L << 4)
#define MWM_DECOR_MINIMIZE      (1L << 5)
#define MWM_DECOR_MAXIMIZE      (1L << 6)

#define MWM_INPUT_MODELESS 0
#define MWM_INPUT_PRIMARY_APPLICATION_MODAL 1
#define MWM_INPUT_SYSTEM_MODAL 2
#define MWM_INPUT_FULL_APPLICATION_MODAL 3
#define MWM_INPUT_APPLICATION_MODAL MWM_INPUT_PRIMARY_APPLICATION_MODAL

#define MWM_TEAROFF_WINDOW	(1L<<0)

#define MARGIN_LEFT				0
#define MARGIN_RIGHT			1
#define MARGIN_TOP				2
#define MARGIN_BOTTOM			3
#define MARGIN_LEFT_START_Y		4
#define MARGIN_LEFT_END_Y		5
#define MARGIN_RIGHT_START_Y	6
#define MARGIN_RIGHT_END_Y		7
#define MARGIN_TOP_START_X		8
#define MARGIN_TOP_END_X		9
#define MARGIN_BOTTOM_START_X	10
#define MARGIN_BOTTOM_END_X		11

typedef enum {
	PROTOCOL_WM_TAKE_FOCUS = (1L << 0),
	PROTOCOL_WM_DELETE_WINDOW = (1L << 1),
	PROTOCOL_WM_PING = (1L << 2),
	PROTOCOL_WM_SAVE_YOURSELF = (1L << 3)
} WMprotocol;

enum {
	NET_WM_STATE_REMOVE,		/* remove/unset property */
	NET_WM_STATE_ADD,			/* add/set property */
	NET_WM_STATE_TOGGLE			/* toggle property  */
};


/* _NET_WM_STATE_* , meant to replace motif hints */

typedef enum {
	STATE_UNSET = 0,
	STATE_MODAL = (1 << 0),
	STATE_STICKY = (1 << 1),
	STATE_MAXIMIZED_VERT = (1 << 2),
	STATE_MAXIMIZED_HORZ = (1 << 3),
	STATE_SHADED = (1 << 4),
	STATE_SKIP_TASKBAR = (1 << 5),
	STATE_SKIP_PAGER = (1 << 6),
	STATE_HIDDEN = (1 << 7),
	STATE_ABOVE = (1 << 8),
	STATE_BELOW = (1 << 9),
	STATE_FULLSCREEN = (1 << 10)
} WindowState;

typedef enum {
	TYPE_UNSET,
	WINDOW_NORMAL = (1 << 0),
	WINDOW_DESKTOP = (1 << 1),
	WINDOW_DOCK = (1 << 2),
	WINDOW_DIALOG = (1 << 3),
	WINDOW_TOOLBAR = (1 << 4),
	WINDOW_MENU = (1 << 5),
	WINDOW_UTILITY = (1 << 6),
	WINDOW_SPLASHSCREEN = (1 << 7),
	WINDOW_INPUT = (1 << 8)		
} WindowType;

typedef enum {
	ACTION_UNSET = 0,
	ACTION_MOVE = (1 << 0),
	ACTION_RESIZE = (1 << 1),
	ACTION_MINIMIZE = (1 << 2),
	ACTION_SHADE = (1 << 3),
	ACTION_STICK = (1 << 4),
	ACTION_MAXIMIZE_HORZ = (1 << 5),
	ACTION_MAXIMIZE_VERT = (1 << 6),
	ACTION_FULLSCREEN = (1 << 7),
	ACTION_CHANGE_DESKTOP = (1 << 8),
	ACTION_CLOSE = (1 << 9)
} AllowedActions;

/* MWM hints about features of window */
typedef enum {
	MWM_HAS_HINTS = (1 << 0),
	MWM_HAS_RESIZE_FUNC = (1 << 1),
	MWM_HAS_MOVE_FUNC = (1 << 2),
	MWM_HAS_MINIMIZE_FUNC = (1 << 3),
	MWM_HAS_MAXIMIZE_FUNC = (1 << 4),
	MWM_HAS_CLOSE_FUNC = (1 << 5),
	MWM_DECORATED = (1 << 6),
	MWM_BORDER_ONLY = (1 << 7)
} MWMHints;


/* OroboROX doesn't handle these yet */
typedef enum {
	MOVERESIZE_SIZE_TOPLEFT,
	MOVERESIZE_SIZE_TOP,
	MOVERESIZE_SIZE_TOPRIGHT,
	MOVERESIZE_SIZE_RIGHT,
	MOVERESIZE_SIZE_BOTTOMRIGHT,
	MOVERESIZE_SIZE_BOTTOM,
	MOVERESIZE_SIZE_BOTTOMLEFT,
	MOVERESIZE_SIZE_LEFT,
	MOVERESIZE_MOVE,			/* movement only */
	MOVERESIZE_SIZE_KEYBOARD,	/* size via keyboard */
	MOVERESIZE_MOVE_KEYBOARD	/* move via keyboard */
} WindowMoveResize;


typedef enum {
		
	/* ICCM */
	XA_WM_STATE,
	XA_WM_CHANGE_STATE,
	XA_WM_TAKE_FOCUS,
	XA_WM_DELETE_WINDOW,
	XA_WM_SAVE_YOURSELF,
	XA_WM_PROTOCOLS,
	XA_WM_WINDOW_ROLE,
	XA_WM_CLIENT_LEADER,
	XA_SM_CLIENT_ID,
	XA_UTF8_STRING,

	/* ICCM or what? */
	WM_TRANSIENT_FOR,
	WM_COLORMAP_WINDOWS,
	WM_CLIENT_MACHINE,
	
	/* Motif */
	XA_MOTIF_WM_HINTS,

	/* EWMH */
	NET_SUPPORTED,
	NET_CLIENT_LIST,
	NET_CLIENT_LIST_STACKING,

	NET_WM_WINDOW_TYPE,
	NET_WM_WINDOW_TYPE_NORMAL,
	NET_WM_WINDOW_TYPE_DESKTOP,
	NET_WM_WINDOW_TYPE_DOCK,
	NET_WM_WINDOW_TYPE_DIALOG,
	NET_WM_WINDOW_TYPE_TOOLBAR,
	NET_WM_WINDOW_TYPE_MENU,
	NET_WM_WINDOW_TYPE_UTILITY,
	NET_WM_WINDOW_TYPE_SPLASH,
	NET_WM_WINDOW_TYPE_INPUT,

	NET_WM_STATE,
	NET_WM_STATE_MODAL,
	NET_WM_STATE_STICKY,
	NET_WM_STATE_MAXIMIZED_VERT,
	NET_WM_STATE_MAXIMIZED_HORZ,
	NET_WM_STATE_SHADED,
	NET_WM_STATE_SKIP_TASKBAR,
	NET_WM_STATE_SKIP_PAGER,
	NET_WM_STATE_HIDDEN,
	NET_WM_STATE_ABOVE,
	NET_WM_STATE_BELOW,
	NET_WM_STATE_FULLSCREEN,

	NET_WM_NAME,
	NET_WM_DESKTOP,
	NET_NUMBER_OF_DESKTOPS,
	NET_CURRENT_DESKTOP,
	NET_ACTIVE_WINDOW,
	NET_SUPPORTING_WM_CHECK,
	NET_WM_WORKAREA,
	NET_WORKAREA,
	NET_CLOSE_WINDOW,
	NET_WM_STRUT,
	NET_WM_STRUT_PARTIAL,
	NET_WM_ICON_NAME,
	NET_WM_MOVERESIZE,
	NET_DESKTOP_VIEWPORT,
	NET_DESKTOP_GEOMETRY,

	NET_WM_ALLOWED_ACTIONS,
	NET_WM_ACTION_MOVE,
	NET_WM_ACTION_RESIZE,
	NET_WM_ACTION_MINIMIZE,
	NET_WM_ACTION_SHADE,
	NET_WM_ACTION_STICK,
	NET_WM_ACTION_MAXIMIZE_HORZ,
	NET_WM_ACTION_MAXIMIZE_VERT,
	NET_WM_ACTION_FULLSCREEN,
	NET_WM_ACTION_CHANGE_DESKTOP,
	NET_WM_ACTION_CLOSE,
	NET_SHOWING_DESKTOP,
	NET_FRAME_EXTENTS,
	NET_REQUEST_FRAME_EXTENTS,

#ifdef NOT_YET_IMPLEMENTED
	NET_DESKTOP_LAYOUT,
	NET_DESKTOP_NAMES,
	NET_WM_ICON,
	NET_WM_ICON_GEOMETRY,

	NET_WM_SYNC_REQUEST_COUNTER,
    NET_WM_SYNC_REQUEST,
	NET_WM_CONTEXT_HELP,
    NET_WM_CONTEXT_ACCEPT,
	NET_WM_CONTEXT_CUSTOM,
#endif

#ifdef HAVE_STARTUP_NOTIFICATION
	NET_STARTUP_ID,
#endif
	NET_WM_PING,
	NET_WM_PID,

	INTERN_ATOM_COUNT
} InternAtom;


typedef struct {
	gulong flags;
	gulong functions;
	gulong decorations;
	long inputMode;
	gulong status;
} PropMwmHints;

extern Atom intern_atoms[INTERN_ATOM_COUNT];

#define xa_wm_state intern_atoms[XA_WM_STATE]
#define xa_wm_change_state intern_atoms[XA_WM_CHANGE_STATE]
#define xa_motif_wm_hints intern_atoms[XA_MOTIF_WM_HINTS]
#define xa_wm_take_focus intern_atoms[XA_WM_TAKE_FOCUS]
#define xa_wm_delete_window intern_atoms[XA_WM_DELETE_WINDOW]
#define xa_wm_save_yourself intern_atoms[XA_WM_SAVE_YOURSELF]
#define xa_wm_protocols intern_atoms[XA_WM_PROTOCOLS]
#define xa_wm_window_role intern_atoms[XA_WM_WINDOW_ROLE]
#define xa_utf8_string intern_atoms[XA_UTF8_STRING]
#define xa_wm_client_leader intern_atoms[XA_WM_CLIENT_LEADER]
#define xa_sm_client_id intern_atoms[XA_SM_CLIENT_ID]

void initHints(void);
gulong get_wm_state(Window w);
void set_wm_state(Window, gulong state);

gboolean get_property_card32(Window, Atom, gulong *);
void set_property_card32(Window, Atom, gulong);
void set_property_xy(Window w, Atom a, gulong x, gulong y);

void set_window_hint(Atom, Window);
void *getPropDataWithItems(Window w, Atom prop, Atom type, gulong *items_ret);


#include "client.h"

void get_size_hints(Client *);
void HasMotifDecor(Client * c);

void get_transientFor(Client * c, Display * dpy, int screen);
void get_net_wm_type(Client * c);
void get_net_wm_state(Client * c);
void set_net_wm_state(Client * c);
void get_wm_protocols(Client * c);
void get_mwm_hints(Client * c);
void set_mapping_state(Client * c, long state);
void set_allowed_actions_hint(Client * c);
gboolean get_window_role(Display * dpy, Window window, char **role);
Window get_client_leader(Display *, Window);
gboolean get_client_id(Display *, Window, char **);
gboolean get_window_command(Display * dpy, Window window, char ***argv, int *argc);
#endif /* __HINTS_H */

