//////////////////////////////////////////////
// NovaWM - Nova Window Manager for X11     //
//////////////////////////////////////////////
// By: Tim Walters                          //
//////////////////////////////////////////////
// Copyright (C) 2001-2002 Tim Walters      //
//////////////////////////////////////////////

////////////////////////////////////////////////////////////////
//This code is released under the terms of the GNU GPL. Refer //
//to the license file included with this source code.         //
////////////////////////////////////////////////////////////////


#ifndef NOVAWM_H
#define NOVAWM_H

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include <string.h>
#include <time.h>

//X11 Includes
#include <X11/X.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/keysym.h>
#include <X11/cursorfont.h>
#include <X11/Xatom.h>
#include <X11/Xmd.h>
#include <X11/xpm.h>

#include <list>
#include <string>
#include <vector>

#define COLOR_GREY "grey"
#define COLOR_BLUE "blue"
#define COLOR_RED  "red"
#define COLOR_DARKBLUE "darkblue"
#define COLOR_NAVYBLUE "navyblue"

//NOTE: The MainColor keyword in the configuration file
//overrides this setting!
#define COLOR_MAIN COLOR_NAVYBLUE

#define VERSION "0.8 Alpha"

using namespace std;

class Novawm_Window
{
public:
  Window window;
  Window titlebar;
  Window kill;
  Window stretch;
  Window hide;
//  Window *tChild;		//Transient Window
  vector <Window> tChild;
  char *title;
  int x, y, width, height, bWidth, layer;
  int orig_x, orig_y, orig_width, orig_height;
  int state;
  int nTChildren;
  int desktop;
  bool hasTitlebar, isTransient, ignoreTransient, isShaded, isSticky, skipBar;
  Colormap colorMap;
  XSizeHints *size_hints;

    Novawm_Window ();
   ~Novawm_Window ();

  void Shade ();
  void SetState (int set_state);
  int GetState ();
  void Destroy ();
  void Get_Net_States ();
};

class NovaWM
{
public:
  void X11_Init ();
  void WM_Start ();		//Reparent All
  void Shutdown ();
  void Quick_Shutdown ();
  void Restart ();
  void Run (char *command);
  void Set_NovaWM_Hints ();
  Pixmap LoadXPM (char **xpm_data, int width, int height, GC * xpmgc);
  void SetNetSupported();
  void UpdateClock ();
  void CreateBar ();
  void DrawBar ();
  void CreateWinList ();
  void DrawWinList ();
  void DrawArrow (Window xWindow);
  void DrawUpArrow (Window xWindow);
  void CreateNovaMenu ();
  char *GetTime (int format);
  void CheckClock ();
  void HighlightListItem (int cY);
  void DestroyBar ();
  void DestroyWinList ();
  void List_Scroll (int units);
  void novaMenu_Click (int item);

  int bar_x;
  int nSeconds;			//Number of Seconds till minute change
  int lstItems, selItem, topItem;


  time_t oldTime;
  Window NovaBar;
  Window nbClock;
  Window nbCurWin;
  Window nbListButton;
  Window nbWinList;
  Window nbWLstScrllBar;
  Window nbWLstItemWin;
  Window nbWLstScrllUp;
  Window nbWLstScrllDwn;
  Window nbButton;
};

//Stores configuration data and operations
class Config
{
public:
  int shwFocusMode;		//Show Focus Mode
  int focusType;
  unsigned int ntbColor;
  unsigned int ftbColor;
  int tbTextStyle;
  bool disableBar;
  bool enableRootMenus;
  int clockFormat;
  bool disableBarMenu;
  int barPosition;
  bool hideClock;
  bool enableBorder;
  bool nonStandardMenu;
  string mainColor;

    vector < string > itemExec;

    Config ();
   ~Config ();

  void SetDefaults ();
  void LoadConfig ();
  int Load (char *filename);
    vector < string > SplitStr (string str, char tok);
    vector < string > GetKeywordInfo (string * keyword);
  void AnalyzeKeyword (string keyword, vector < string > argVec, int nArgs);

  void CreateNew ();
  void LoadMenu ();
  void Search ();
  int IncludeFile (char *file);
};

class WinMgr
{
public:
  WinMgr ();
  ~WinMgr ();
  void NewWindow (Window x11_window);
  Novawm_Window *WindowSearch (Window x11_window);
  void Redraw (Novawm_Window * novawm_window);
  void Move (Novawm_Window * novawm_window);
  void Stretch (Novawm_Window * novawm_window);
  void Raise (Novawm_Window * novawm_window);
  void SetFocus (Novawm_Window * novawm_window);
  void Hide (Novawm_Window * novawm_window);
  void Resize (Novawm_Window * novawm_window);
  void SetSize (Novawm_Window * novawm_window, int wWidth, int wHeight);
  void Kill (Novawm_Window * novawm_window);
  void Create_ListMenu (int menu_x, int menu_y);
  void listMenu_Click (int item);
  void SetDesktop (int desktop);
  int AddDesktop ();
  void RemoveDesktop ();
  void SendToDesktop (Novawm_Window * window, int desktop);
  void AddUnmapIgnore (Window ignoreWindow);
  void RemoveUnmapIgnore (Window ignoreWindow);
  int Find_UnmapIgnore (Window ignoreWindow);

#ifdef _WIN_GNOME_SUPPORT
  void _WIN_CLIENT_LIST_UpdateList ();
#endif

  int cDesktop;			//Current Desktop
  int nDesktops;
  int maxDesktops;
    list < Window > ignoreUnmapList;
  //Window ignoreUnmapList[255];
  int nListWindow;
  //int unmapignore;
  int nClients;

    list < Novawm_Window * >novawm_window_List;
  Novawm_Window *focusWindow;
};

class Events
{
public:
  void NovaWM_EventLoop ();
  void Event_Expose (XExposeEvent * event);
  void Event_ButtonDown (XButtonEvent * event);
  void Event_ButtonUp (XButtonEvent * event);
  void Event_Map (XMapRequestEvent * event);
  void Event_Unmap (XUnmapEvent * event);
  void Event_Motion (XCrossingEvent * event);
  void Event_Destroy (XDestroyWindowEvent * event);
  void Event_Configure (XConfigureRequestEvent * event);
  void Event_Property (XPropertyEvent * Event);
  void Event_ClientMessage (XClientMessageEvent * event);
  void Event_FocusIn (XFocusChangeEvent * event);
  void Event_FocusOut (XFocusChangeEvent * event);
  void Event_EnterWindow (XCrossingEvent * event);
  void Event_LeaveWindow (XCrossingEvent * event);
  void Event_KeyUp (XKeyEvent * event);
  void Event_Colormap (XColormapEvent * event);
  void DrawDown (Window window);
  void DrawUp (Window window);

  void rootMenu_Click (int item);
  void windowMenu_Click (int item);

  Window downWindow;
};

class MotifHints
{
public:
  unsigned long flags;
  unsigned long functions;
  unsigned long decorations;
};

//NEW - Better menu code!
//NOTE: ?+MENU_SPLIT+? as a item text will be a splitter
class NovaWM_Menu
{
private:
  int x, y, width, height;
  int nItems;
  int itemHeight;
    vector < string > itemText;
  Window x11_window;
  int sel;			//Selected Item
  bool open;
  XFontStruct *font;

public:
    NovaWM_Menu ();
   ~NovaWM_Menu ();
  int Create (int c_x, int c_y);
  void AddItem (char *text);
  int GetSelection ();
  void HighlightItem (int cusor_x, int cursor_y);
  void DrawItems ();
  void DrawSelection ();
  void Clear ();
  bool isOpen ();
  Window menuWindow ();
  void Destroy ();
  void SetItemHeight (int height);
  void SetFont (XFontStruct * xfont);
};

extern NovaWM novawm;
extern WinMgr winmgr;
extern Events events;
extern Config cfg;
extern Display *display;
extern Window root;
extern int screen;
extern unsigned int mainPixel;
extern GC novawm_gc;
extern XFontStruct *novawmFont;
extern XFontStruct *nbFont;

extern Cursor Arrow;
extern Cursor MoveCursor;
extern Cursor ResizeCursor;
extern Cursor ResizeRightCursor;
extern Cursor ResizeDownCursor;

extern Atom stateAtom;
extern Atom deleteAtom;
extern Atom protocolAtom;
extern Atom motifAtom;
extern Atom novawmAtom;
extern Atom takefocusAtom;
extern Atom changestateAtom;
extern Atom gnomeSupportAtom;

extern Pixmap killPixmap;
extern Pixmap stretchPixmap;
extern Pixmap hidePixmap;

extern GC killIconGC;
extern GC stretchIconGC;
extern GC hideIconGC;

extern Window gnomeSupportWindow;

extern NovaWM_Menu rootMenu;
extern NovaWM_Menu windowMenu;
extern NovaWM_Menu listMenu;
extern NovaWM_Menu novaMenu;

extern int focusType;

#define NOVABAR_HEIGHT	18

//Extended Window Manager Hints
extern Atom netSupportAtom;
extern Atom netClientListAtom;
extern Atom netDesktopAtom;
extern Atom netDesktopCountAtom;
extern Atom netCurrentDesktopAtom;
extern Atom netStateAtom;
extern Atom netStateStickyAtom;
extern Atom netStateShadedAtom;
extern Atom netStateHiddenAtom;
extern Atom netStateSkipBarAtom;
extern Atom netStateFloatingAtom;
extern Atom netStateFullscreenAtom;
extern Atom netSupportedAtom;

#define _NET_WM_STATE_REMOVE	0
#define _NET_WM_STATE_ADD		1
#define _NET_WM_STATE_TOGGLE	2

#ifdef _WIN_GNOME_SUPPORT
extern Atom winProtocolsAtom;
extern Atom winProtocols_ClientList;
extern Atom winProtocols_Workspace;
extern Atom winProtocols_WorkspaceCount;
extern Atom winProtocols_Layer;
extern Atom winProtocols_State;
extern Atom winProtocols_Hints;
extern Atom winProtocols_AppState;
extern Atom winProtocols_ExpandedSize;

// _WIN_STATE bitmask
#define WIN_STATE_MINIMIZED       (1<<1)	//Reserved - definition is unclear
#define WIN_STATE_HIDDEN          (1<<4)	//not on taskbar but window visible
#define WIN_STATE_HID_WORKSPACE   (1<<6)	//not on current desktop
#define WIN_STATE_HID_TRANSIENT   (1<<7)	//owner of transient is hidden
#define WIN_STATE_FIXED_POSITION  (1<<8)	//window is fixed in position even
#define WIN_STATE_ARRANGE_IGNORE  (1<<9)	//ignore for auto arranging
#define WIN_STATE_STICKY          (1<<0)	//On all desktops
#define WIN_STATE_SHADED          (1<<5)	//shaded (MacOS / Afterstep style)
//Unsupported States
//#define WIN_STATE_MAXIMIZED_VERT  (1<<2) //window in maximized V state
//#define WIN_STATE_MAXIMIZED_HORIZ (1<<3) //window in maximized H state

#define WIN_LAYER_DESKTOP                0
#define WIN_LAYER_BELOW                  2
#define WIN_LAYER_NORMAL                 4
#define WIN_LAYER_ONTOP                  6
#define WIN_LAYER_DOCK                   8
//#define WIN_LAYER_ABOVE_DOCK             10
//#define WIN_LAYER_MENU                   12
#endif


#endif


syntax highlighted by Code2HTML, v. 0.9.1