/*
 * DWN - Desktop Window Manager
 * retoor <retoor@molodetz.nl>
 * X11 Atoms management (EWMH/ICCCM compliance)
 */

#ifndef DWN_ATOMS_H
#define DWN_ATOMS_H

#include <X11/Xlib.h>
#include <stdbool.h>

typedef struct {
    Atom NET_SUPPORTED;
    Atom NET_SUPPORTING_WM_CHECK;
    Atom NET_CLIENT_LIST;
    Atom NET_CLIENT_LIST_STACKING;
    Atom NET_NUMBER_OF_DESKTOPS;
    Atom NET_DESKTOP_GEOMETRY;
    Atom NET_DESKTOP_VIEWPORT;
    Atom NET_CURRENT_DESKTOP;
    Atom NET_DESKTOP_NAMES;
    Atom NET_ACTIVE_WINDOW;
    Atom NET_WORKAREA;

    Atom NET_WM_NAME;
    Atom NET_WM_VISIBLE_NAME;
    Atom NET_WM_DESKTOP;
    Atom NET_WM_WINDOW_TYPE;
    Atom NET_WM_STATE;
    Atom NET_WM_ALLOWED_ACTIONS;
    Atom NET_WM_STRUT;
    Atom NET_WM_STRUT_PARTIAL;
    Atom NET_WM_PID;

    Atom NET_WM_WINDOW_TYPE_DESKTOP;
    Atom NET_WM_WINDOW_TYPE_DOCK;
    Atom NET_WM_WINDOW_TYPE_TOOLBAR;
    Atom NET_WM_WINDOW_TYPE_MENU;
    Atom NET_WM_WINDOW_TYPE_UTILITY;
    Atom NET_WM_WINDOW_TYPE_SPLASH;
    Atom NET_WM_WINDOW_TYPE_DIALOG;
    Atom NET_WM_WINDOW_TYPE_NORMAL;
    Atom NET_WM_WINDOW_TYPE_NOTIFICATION;

    Atom NET_WM_STATE_MODAL;
    Atom NET_WM_STATE_STICKY;
    Atom NET_WM_STATE_MAXIMIZED_VERT;
    Atom NET_WM_STATE_MAXIMIZED_HORZ;
    Atom NET_WM_STATE_SHADED;
    Atom NET_WM_STATE_SKIP_TASKBAR;
    Atom NET_WM_STATE_SKIP_PAGER;
    Atom NET_WM_STATE_HIDDEN;
    Atom NET_WM_STATE_FULLSCREEN;
    Atom NET_WM_STATE_ABOVE;
    Atom NET_WM_STATE_BELOW;
    Atom NET_WM_STATE_DEMANDS_ATTENTION;
    Atom NET_WM_STATE_FOCUSED;

    Atom NET_WM_ACTION_MOVE;
    Atom NET_WM_ACTION_RESIZE;
    Atom NET_WM_ACTION_MINIMIZE;
    Atom NET_WM_ACTION_SHADE;
    Atom NET_WM_ACTION_STICK;
    Atom NET_WM_ACTION_MAXIMIZE_HORZ;
    Atom NET_WM_ACTION_MAXIMIZE_VERT;
    Atom NET_WM_ACTION_FULLSCREEN;
    Atom NET_WM_ACTION_CHANGE_DESKTOP;
    Atom NET_WM_ACTION_CLOSE;

    Atom NET_CLOSE_WINDOW;
    Atom NET_MOVERESIZE_WINDOW;
    Atom NET_WM_MOVERESIZE;
    Atom NET_REQUEST_FRAME_EXTENTS;
    Atom NET_FRAME_EXTENTS;

    Atom NET_SYSTEM_TRAY_OPCODE;
    Atom NET_SYSTEM_TRAY_S0;
    Atom NET_SYSTEM_TRAY_ORIENTATION;
    Atom NET_SYSTEM_TRAY_VISUAL;
    Atom MANAGER;
    Atom XEMBED;
    Atom XEMBED_INFO;
} EWMHAtoms;

typedef struct {
    Atom WM_PROTOCOLS;
    Atom WM_DELETE_WINDOW;
    Atom WM_TAKE_FOCUS;
    Atom WM_STATE;
    Atom WM_CHANGE_STATE;
    Atom WM_CLASS;
    Atom WM_NAME;
    Atom WM_TRANSIENT_FOR;
    Atom WM_CLIENT_LEADER;
    Atom WM_WINDOW_ROLE;
} ICCCMAtoms;

typedef struct {
    Atom UTF8_STRING;
    Atom COMPOUND_TEXT;
    Atom MOTIF_WM_HINTS;
    Atom CLIPBOARD;
    Atom PRIMARY;
    Atom DWN_RESTART;
} MiscAtoms;

extern EWMHAtoms ewmh;
extern ICCCMAtoms icccm;
extern MiscAtoms misc_atoms;

void atoms_init(Display *display);
void atoms_cleanup(void);

void atoms_setup_ewmh(void);
void atoms_update_client_list(void);
void atoms_update_desktop_names(void);
void atoms_set_current_desktop(int desktop);
void atoms_set_active_window(Window window);
void atoms_set_number_of_desktops(int count);

bool atoms_get_window_type(Window window, Atom *type);
bool atoms_get_window_state(Window window, Atom **states, int *count);
bool atoms_set_window_state(Window window, Atom *states, int count);
bool atoms_get_window_desktop(Window window, int *desktop);
bool atoms_set_window_desktop(Window window, int desktop);
char *atoms_get_window_name(Window window);
bool atoms_get_wm_class(Window window, char *class_name, char *instance_name, size_t len);

bool atoms_window_supports_protocol(Window window, Atom protocol);
void atoms_send_protocol(Window window, Atom protocol, Time timestamp);

void atoms_send_client_message(Window window, Atom message_type,
                               long data0, long data1, long data2, long data3, long data4);

bool atoms_update_wm_state(Window window, Atom state, bool add);

#endif
