/* GKrellM
|  Copyright (C) 1999-2002 Bill Wilson
|
|  Author:  Bill Wilson    bill@gkrellm.net
|  Latest versions might be found at:  http://gkrellm.net
|
|  This program is free software which I release under the GNU General Public
|  License. You may redistribute and/or modify this program under the terms
|  of that license as published by the Free Software Foundation; either
|  version 2 of the License, 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.  Version 2 is in the
|  COPYRIGHT file in the top level directory of this distribution.
| 
|  To get a copy of the GNU General Puplic License, write to the Free Software
|  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

/*
|  5/7/2000 Applied code from Takeshi Aihana <takeshi@turbolinux.co.jp>
|		ENABLE_NLS defines and string internationalizations code modifications.
|		Strings in most files are touched, but I just note this here in
|		gkrellm.h
*/

#ifdef HAVE_CONFIG_H
#  include "config.h"
#endif  

#include <sys/param.h>

#include <gtk/gtk.h>
#include <gdk_imlib.h>

/* To get at the private structure of pixmaps (for sizes)
*/
#include <gdk/gdkx.h>

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <fcntl.h>
#include <time.h>
#include <signal.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/stat.h>

#include <locale.h>

#if defined(__sun) && defined(__SVR4)
#define __solaris__
#endif

#if !defined(__FreeBSD__) && !defined(__linux__) && !defined(__NetBSD__) \
	&& !defined(__OpenBSD__) && !defined(__solaris__)
#define  USE_LIBGTOP
#endif

#if defined(USE_LIBGTOP)
#include <glibtop.h>
#include <glibtop/open.h>
#include <glibtop/close.h>
#include <glibtop/xmalloc.h>
#include <glibtop/parameter.h>
#include <glibtop/netload.h>
#endif


/* Internationalization support.
*/
#if defined(ENABLE_NLS) && ! defined(PACKAGE)
#	define PACKAGE	"gkrellm"
#endif

#if defined (ENABLE_NLS)
#	include <libintl.h>
#	ifdef PACKAGE
#		undef _
#		define _(String) dgettext(PACKAGE,String)
#	else
#		define _(String) gettext(String)
#	endif	/* PACKAGE */
#	ifdef gettext_noop
#		define N_(String) gettext_noop(String)
#	else
#		define N_(String) (String)
#	endif	/* gettext_noop */
#else
#	define _(String) (String)
#	define N_(String) (String)
#	define textdomain(String) (String)
#	define gettext(String) (String)
#	define dgettext(Domain,String) (String)
#	define dcgettext(Domain,String,Type) (String)
#	define bindtextdomain(Domain,Directory) (Domain) 
#endif	/* ENABLE_NLS */




/* -------------------------------------------------------------------
*/
#define	GKRELLM_VERSION_MAJOR	1
#define	GKRELLM_VERSION_MINOR	2
#define	GKRELLM_VERSION_REV		8
/* Backward compatibility */
#define	VERSION_MAJOR			GKRELLM_VERSION_MAJOR
#define	VERSION_MINOR			GKRELLM_VERSION_MINOR
#define	VERSION_REV				GKRELLM_VERSION_REV

#define	GKRELLM_DIR				".gkrellm"
#define	GKRELLM_USER_CONFIG		".gkrellm/user_config"
#define	GKRELLM_THEME_CONFIG	".gkrellm/theme_config"
#define GKRELLM_THEMES_DIR		".gkrellm/themes"
#define	GKRELLM_DATA_DIR		".gkrellm/data"
#define	GKRELLM_PLUGINS_DIR		".gkrellm/plugins"
#define GKRELLMRC				"gkrellmrc"

#define	PLUGINS_INSTALL_FILE		".gkrellm/plugins_install"
#define	PLUGINS_PLACEMENT_FILE	".gkrellm/plugins_placement"

#define	LOCAL_THEMES_DIR		"/usr/local/share/gkrellm/themes"
#if !defined(SYSTEM_THEMES_DIR)
#define	SYSTEM_THEMES_DIR		"/usr/share/gkrellm/themes"
#endif

#define	LOCAL_PLUGINS_DIR		"/usr/local/lib/gkrellm/plugins"
#if !defined(SYSTEM_PLUGINS_DIR)
#define	SYSTEM_PLUGINS_DIR		"/usr/lib/gkrellm/plugins"
#endif
#define	OLD_LOCAL_PLUGINS_DIR	"/usr/local/share/gkrellm/plugins"
#define	OLD_SYSTEM_PLUGINS_DIR	"/usr/share/gkrellm/plugins"

#define	ON				1
#define	OFF				0

#define	CFG_BUFSIZE		384

  /* Label midpoints are positioned as a percent of chart_width.
  */
#define	LABEL_NONE		-1
#define	LABEL_CENTER	50
#define LABEL_MAX		100

#define	GRID_MODE_NORMAL		0
#define	GRID_MODE_RESTRAINED	1


  /* Decals in the decal_misc_image.
  */
#define	D_MISC_BLANK			0
#define	D_MISC_AC				1
#define	D_MISC_BATTERY			2
#define	D_MISC_BATTERY_WARN		3
#define	D_MISC_LED0				4
#define	D_MISC_LED1				5
#define	D_MISC_FS_UMOUNTED		6
#define	D_MISC_FS_MOUNTED		7
#define D_MISC_FS_PRESSED		8
#define D_MISC_BUTTON_OUT		9
#define D_MISC_BUTTON_ON		10
#define D_MISC_BUTTON_IN		11
#define	N_MISC_DECALS			12


  /* For formatting sizes in decimal or binary abbreviated notation.
  */
#define	KB_SIZE(s)	((s) * 1e3)
#define	KiB_SIZE(s)	((s) * 1024.0)
#define	MB_SIZE(s)	((s) * 1e6)
#define	MiB_SIZE(s)	((s) * 1024.0 * 1024.0)
#define	GB_SIZE(s)	((s) * 1e9)
#define	GiB_SIZE(s)	((s) * 1024.0 * 1024.0 * 1024.0)
#define	TB_SIZE(s)	((s) * 1e12)
#define	TiB_SIZE(s)	((s) * 1024.0 * 1024.0 * 1024.0 * 1024.0)

typedef struct
	{
	gfloat	limit,
			divisor;
	gchar	*format;
	}
	size_abbrev_table;


  /* Sensor types so CPU and Proc monitors  can get info from the Sensors
  |  module.  The sensor module readings for temperature and fan are
  |  reported on CPU and Proc panels.
  */
#define SENSOR_TEMPERATURE  1
#define SENSOR_FAN          2
#define SENSOR_VOLTAGE      4


#ifdef CLK_TCK
#define	CPU_TICKS_PER_SECOND	CLK_TCK
#else
#define	CPU_TICKS_PER_SECOND	100		/* XXX */
#endif

#define	FULL_SCALE_GRIDS		5


typedef struct
	{
	GdkFont		*font;
	GdkFont		**font_seed;
	gint		effect;
	gint		internal;
	GdkColor	color;
	GdkColor	shadow_color;
	}
	TextStyle;



  /* Values for Decal flags
  */
#define DF_LOCAL_PIXMAPS	0x1
#define DF_TOP_LAYER		0x2

  /* Values for Decal state
  */
#define	DS_INVISIBLE	0
#define	DS_ERASING		1
#define	DS_VISIBLE		2

  /* A decal is a pixmap or a part of a pixmap drawn on a panel.  The
  |  pixmap can be a graphic, a vertical stack of graphics, or a drawn
  |  text string
  */
typedef struct
	{
	GdkPixmap	*pixmap;
	GdkBitmap	*mask;
	GdkBitmap	*stencil;
	gint		y_src;		/* Offset into pixmap if a vertical stack	*/
	gint		w, h;		/* Size of the decal						*/
	gint		x, y;		/* Position of decal in a drawable			*/	
	gshort		flags,
				state;
	gint		value,		/* Index into stack, text value, etc	*/
				modified;
	gint		x_off,
				y_baseline;
	TextStyle	text_style;	/* Used if decal is a drawn text string		*/
	}
	Decal;

  /* Get the first decal in a panel decal list.  Use if only one decal in list.
  */
#define	DECAL(p)	((Decal *)(((p)->decal)->data))



typedef struct
	{
	gchar		*string;
	gint		lbearing,
				rbearing,
				width,
				ascent,
				descent;
	gint		position;		/* 0 - 100 %	*/
	gint		x_panel;		/* x position of label start in panel */
	gint		y_baseline;
	gint		h_panel;
	}
	Label;



typedef struct
	{
	gint		x_src;
	gint		y_src;
	gint		x_dst;
	gint		y_dst;
	gint		w;
	gint		h;
	}
	Draw_rec;



  /* Bit flags for setting styles in config.c.  Also used as override flags.
  */
#define	SET_KRELL_YOFF			1
#define	SET_KRELL_EXPAND		2
#define	SET_KRELL_X_HOT			3
#define	SET_KRELL_EMA_PERIOD	4
#define	SET_KRELL_DEPTH			5
#define	SET_LABEL_POSITION		6
#define	SET_MARGIN				7
#define	SET_TOP_MARGIN			8
#define	SET_BOTTOM_MARGIN		9
#define	SET_TEXTCOLOR_A			10
#define	SET_TEXTCOLOR_B			11
#define	SET_TEXTFONT_A			12
#define	SET_TEXTFONT_B			13
#define	SET_BORDER				14
#define	SET_TRANSPARENCY		15

#define	TS_A		1
#define	TS_B		2

#define BIT(a)	(1 << (a))

  /* Some of these style entries do not apply to all monitors.
  */
typedef struct
	{
	gint		override;		/* Flag which entries have override status */
	gint		ref_count;

	gint		krell_yoff,
				krell_expand,
				krell_x_hot,
				krell_ema_period,
				krell_depth,
				krell_spare;

	gint		label_position,
				margin,			/* Text left/right margins in a panel */
				spare;
	TextStyle	label_tsA;
	TextStyle	label_tsB;

	GdkImlibBorder
				border;			/* Border for background panel image */
	gint		transparency;
	gint		top_margin,		/* Text top margin in a panel */
				bottom_margin;	/* Text bottom margin in a panel */
	gboolean	themed;			/* True if theme has custom assignments */
	}
	Style;



  /* The Panel of each Chart or Meter can have a moving indicator
  |  representing a current sampled data value as a fraction of some full
  |  scale value.  Since there can be quite a few of them dancing around on
  |  a maxed out GKrellM display, I call them Krells - inspired by the
  |  wall full of power monitoring meters the Krell had in Forbidden Planet.
  */
  /* Krell.expand values */
#define	KRELL_EXPAND_NONE		0
#define	KRELL_EXPAND_LEFT		1
#define	KRELL_EXPAND_RIGHT		2
#define	KRELL_EXPAND_BAR_MODE	3

typedef struct
	{
	GdkPixmap	*pixmap;
	GdkBitmap	*mask;
	gint		w, h;	/* Of the full Krell - all the frames included */
	gint		expand;	/* How this Krell was preprocessed in config.c */
	gint		depth;	/* How many vertical frames in the krell image */

	GdkBitmap	*stencil;
	gint		h_stencil;	/* Height of one frame + y0 offset	*/
							/* Include y0 here so no need to set_clip_origin */
	gint		reading;
	gint		last_reading;
	gint		full_scale;
	gulong		previous;
	gulong		value;

	gint		modified;	/* True if krell has moved.			*/

	gint		x_hot;		/* Offset in Krell pixmap to hot spot */
	gint		x_position;	/* Current position of x_hot in Panel */

	gint		x0,		/* Offset in Panel to start of Krell scale range */
				y0;
	gint		w_scale;		/* Width of active range. */
	gint		h_frame;		/* Height of one frame */

	gint		ema;		/* exponential moving average */
	gint		period;		/* of ema */
	gint		full_scale_expand;
	gboolean	monotonic;
	gboolean	bar_mode;

	Draw_rec	old_draw;	/* Last draw for restoring background.	*/
	Draw_rec	draw;		/* Parameters to currently drawn krell	*/
	}
	Krell;

  /* Get the first krell in a panel krell list.  Use if only one krell in list.
  */
#define	KRELL(p)	((Krell *)(((p)->krell)->data))

typedef struct
	{
	GtkWidget	*hbox;			/* Container box this area is packed into */
	GtkWidget	*fixed;
	GtkWidget	*drawing_area;
	GdkPixmap	*pixmap;		/* Expose pixmap */
	GdkBitmap	*bg_mask;
	GdkPixmap	*bg_pixmap;		/* Bg of panel, may be dirtied with label */

	Label		*label;
	TextStyle	*textstyle;
	GList		*decal;			/* Linked list of decals for this panel	*/
	GList		*krell;			/* Linked list of krells for this panel	*/
	Style		*style;
	gint		modified;		/* True if decal/krell modified.		*/
	gint		x, y, w, h;
	GdkPixmap	*bg_clean_pixmap;	/* A no label bg_pixmap				*/

	gint		transparency;
	gboolean	keep_lists;
	gboolean	shown;
	gboolean	bg_image_override;
	GdkImlibImage *bg_image;
	gpointer	monitor;
	}
	Panel;


#define CHART_WIDTH_MAX	1000
#define CHART_WIDTH_MIN	25

  /* Each chart must have a ChartConfig struct associated with it.
  */
#define	GKRELLM_CHARTCONFIG_KEYWORD	"chart_config"

  /* Values for ChartConfig flags */
#define	NO_CONFIG_AUTO_GRID_RESOLUTION	1
#define	NO_CONFIG_FIXED_GRIDS			2

typedef struct
	{
	gint		flags;
	gboolean	config_loaded;
	gboolean	log;

	gint		h;
	void		(*cb_height)();
	gpointer	cb_height_data;
	GtkWidget	*height_spin_button;

	/* grid_resolution must be an integer and will be mapped into an integer
	|  1,2,5 or 1,1.5,2,3,5,7 sequence if map_sequence is TRUE.  If
	|  map_sequence is false, grid_resolution will be the spin_button
	|  value * spin_factor so spin buttons may have non-integer settings.
	*/
	gint		grid_resolution;
	gboolean	auto_grid_resolution;
	gboolean	auto_resolution_stick;
	gboolean	sequence_125;
	void		(*cb_grid_resolution)();
	gpointer	cb_grid_resolution_data;
	GtkWidget	*grid_resolution_spin_button;
	GtkWidget	*auto_resolution_control_menubar;
	GtkItemFactory	*auto_resolution_item_factory;
	gchar		*grid_resolution_label;
	gboolean	adjustment_is_set;
	gboolean	map_sequence;
	gfloat		spin_factor;
	gfloat		low,		/* Stuff for the grid_resolution spin adjustment */
				high,
				step0,
				step1;
	gint		digits,
				width;

	gboolean	fixed_grids;
	void		(*cb_fixed_grids)();
	gpointer	cb_fixed_grids_data;
	GtkWidget	*fixed_grids_spin_button;

	GList		*cd_list;			/* Same list as in parent Chart */
	GList		**chart_cd_list;
	}
	ChartConfig;

  /* Charts are drawn in layers and each data value drawn has its own layer
  |  (the ChartData struct -> image/color of the drawn data and
  |  the data colored grid lines).  Each layer is a chart sized pixmap
  |  with grid lines drawn on it.  A chart is drawn by drawing the
  |  background followed by stenciling each data layer through a
  |  data_bitmap.
  */
typedef struct
	{
	GdkPixmap	*pixmap;			/* Working layer pixmap with grid lines	*/
	GdkPixmap	**src_pixmap;		/* The layer source image/color		*/
	GdkPixmap	*grid_pixmap;		/* The grid pixmap to draw on src 	*/
	}
	ChartLayer;

typedef struct
	{
	GtkWidget	*hbox;			/* Container box this chart is packed into */
	GtkWidget	*drawing_area;

	Panel		*panel;
	GList		*cd_list;		/* Same cd_list as in ChartConfig struct */
	gint		cd_list_index;
	void		(*draw_chart)(gpointer);
	gpointer	draw_chart_data;

	gint		x, y, w, h;		/* h tracks h in ChartConfig	*/

	ChartConfig	*config;
	gboolean	shown;
	gboolean	redraw_all;

	gint		position,
				tail;
	gboolean	primed;

	gint		privat;
	gint		i0;				/* Draw start index */
	gint		alloc_width;

	gint		scale_max;
	gint		maxval,
				maxval_auto,
				maxval_auto_base,
				maxval_peak;
	gulong		previous_total;

	gint		style_id;

	GdkPixmap	*pixmap;			/* The expose pixmap.			*/

	GdkImlibImage
				*bg_image,
				*bg_grid_image;
	GdkPixmap	*bg_pixmap,			/* Working bg with grid lines	*/
				*bg_src_pixmap,		/* bg with no grid lines		*/
				*bg_grid_pixmap,	/* This + bg_src_pixmap builds bg_pixmap*/
				*bg_clean_pixmap;	/* This + trans builds bg_src_pixmap */
	GdkBitmap	*bg_mask;
	gint		transparency;
	gboolean	bg_image_override;

	GtkWidget	*config_window;
	gpointer	*monitor;
	}
	Chart;


  /* Values for ChartData draw_style */
#define	CHARTDATA_IMPULSE	0
#define	CHARTDATA_LINE		1

  /* Values for ChartData flags */
#define CHARTDATA_ALLOW_HIDE			1
#define CHARTDATA_NO_CONFIG_DRAW_STYLE	2
#define CHARTDATA_NO_CONFIG_INVERTED	4
#define CHARTDATA_NO_CONFIG_SPLIT		8
#define CHARTDATA_NO_CONFIG				0xf

typedef struct
	{
	gint		flags;

	Chart		*chart;			/* Chart this data belong to */
	gchar		*label;
	gulong		current,
				previous,
				discard;
	gboolean	monotonic;
	ChartLayer	layer;			/* The image + grid for this data layer */
	GdkBitmap	*data_bitmap;	/* Draw data here, use as clipmask for layer*/
	gint		*data;

	gint		draw_style;
	gboolean	inverted;
	gboolean	hide;

	gboolean	split_chart;
	gfloat		split_fraction,
				split_share;
	GtkWidget	*split_fraction_spin_button;

	gint		y_p,
				y_pp;
	gint		y,				/* Each data layer draws at an offset y and */
				h,				/* within height h of its parent Chart	*/
				w;				/* Width of data allocated.				*/
	gint		maxval;
	}
	ChartData;


typedef struct
	{
	Panel		*p;
	Decal		*d;
	void		(*cb_button_click)();
	gint		(*cb_in_button)();
	gpointer	data;
	gint		cur_index;
	gint		pressed_index;
	gint		saved_index;
	gint		sensitive;
	gint		type;
	gint		id_press,
				id_release,
				id_enter,
				id_leave;
	void		(*cb_button_right_click)();
	gpointer	right_data;
	}
	DecalButton;



typedef struct
	{
	gchar		*command;
	gint		type;
	gint		pad;
	FILE		*pipe;		/* I read the output of some commands */
	DecalButton	*button;
	GtkTooltips	*tooltip;
	gchar		*tooltip_comment;
	}
	Launcher;


/* ------- Alerts ------- */
#define	GKRELLM_ALERTCONFIG_KEYWORD	"alert_config"

typedef struct
	{
	gboolean	warn_on,
				alarm_on;
	gfloat		warn_limit,
				alarm_limit;
	GtkWidget	*warn_limit_spin_button,
				*alarm_limit_spin_button;
	}
	Trigger;

typedef struct
	{
	Decal		*decal;
	gint		x, y, w, h;
	GdkPixmap	*pixmap;
	GdkBitmap	*mask;
	gint		frame,
				nframes,
				dir;
	}
	AlertDecal;

typedef struct
	{
	Krell	*krell;
	gint	krell_position;
	}
	AlertKrell;

typedef struct
	{
	Panel		*panel;
	gchar		*name,
				*unit_string;
	AlertDecal	ad;
	AlertKrell	ak;

	gboolean	activated,
				freeze,
				do_panel_updates,
				suppress_command,
				check_low,
				check_high,
				check_boolean;
	gchar		*warn_command,
				*alarm_command,
				*voice_string;
	gint		warn_repeat_set,
				warn_repeat,
				alarm_repeat_set,
				alarm_repeat,
				voice_repeat_set,
				voice_repeat;

	void		(*cb_trigger)();
	gpointer	cb_trigger_data;
	void		(*cb_stop)();
	gpointer	cb_stop_data;
	void		(*cb_config)();
	gpointer	cb_config_data;

	GtkWidget	*config_window,
				*warn_command_entry,
				*alarm_command_entry,
				*voice_string_entry,
				*warn_repeat_spin_button,
				*alarm_repeat_spin_button,
				*voice_repeat_spin_button;

	gfloat		max_high,		/* Adjustment values */
				min_low,
				step0,
				step1;
	gint		digits;

	Trigger		low,
				high;
	}
	Alert;

/* ------------------------ */


/* ================= Theme Config ==================*/

#define	CHART_PANEL_TYPE	0
#define	METER_PANEL_TYPE	1
#define	N_PANEL_TYPES		2

#define	DEFAULT_STYLE_ID	0
/* Old one */
#define	DEFAULT_STYLE		0



/* Style names for the builtin monitors.  Define them globally so plugins
|  can lookup a builtin style_id.  These names are used as subdirectory
|  names under the current theme where monitor specific images are located.
|  They also are used in the Style lines in the gkrellmrc
|		(eg. StyleMeter  cpu.textcolor ....
*/
#define	CPU_STYLE_NAME			"cpu"
#define	DISK_STYLE_NAME			"disk"
#define	NET_STYLE_NAME			"net"
#define	PROC_STYLE_NAME			"proc"
#define	INET_STYLE_NAME			"inet"

#define	MEM_STYLE_NAME			"mem"
#define SWAP_STYLE_NAME			"swap"
#define	FS_STYLE_NAME			"fs"
#define	MAIL_STYLE_NAME			"mail"
#define	APM_STYLE_NAME			"apm"
#define UPTIME_STYLE_NAME		"uptime"
#define	CLOCK_STYLE_NAME		"clock"
#define	CAL_STYLE_NAME			"cal"
#define	HOST_STYLE_NAME			"host"
#define	TIMER_STYLE_NAME		"timer"

#define	GKRELLM_SM_ARGC_MAX		16

struct	ThemeConfig
	{
	gint		timer_ticks;
	gint		second_tick,
				two_second_tick,
				five_second_tick,
				ten_second_tick,
				minute_tick,
				hour_tick,
				day_tick;

	gint		debug;
	gint		spare;
	gint		debug_level;
	gint		demo;
	gint		test;

	gint		up_minutes;
	gint		base_uptime;
	time_t		start_time;
	gint		cpu_sys_activity;
	gint		sensor_temp_files;

	gboolean	initialized;
	gint		max_chart_height;
	gint		monitor_height;

	gint		sm_argc;
	gchar		*sm_argv[GKRELLM_SM_ARGC_MAX];
	gchar		*theme_path;
	gchar		*config_suffix;		/* Overrides host_configs below */
	gchar		*command_line_theme;
	gchar		*command_line_plugin;
	gint		force_host_config;
	gint		found_host_config;
	gint		no_config;

	gint		frame_left_width,
				frame_right_width,
				frame_top_height,
				frame_bottom_height;
	gint		chart_width_ref;

	gint		chart_history_length;
	gint		chart_height_min;
	gint		chart_height_max;
	gint		allow_scaling;
	gboolean	config_modified;
	gboolean	any_transparency;

	gint		update_HZ;
	gint		chart_width;
	gboolean	save_position;
	gboolean	large_info_font;
	gboolean	track_gtk_rcfiles;

	gboolean	enable_hostname,		/* No separate hostname config. */
				hostname_short,
				enable_system_name;

	gint		rx_led_x;				/* Move these to net monitor */
	gint		rx_led_y;
	gint		tx_led_x;
	gint		tx_led_y;

	Style		*krell_slider_style,
				*krell_mini_style;

	GdkImlibImage
				*frame_top_image,
				*frame_bottom_image,
				*frame_left_image,
				*frame_right_image;

	GdkImlibImage
				*button_panel_out_image,
				*button_panel_in_image,
				*button_meter_out_image,
				*button_meter_in_image;

	GdkImlibImage
				*bg_slider_image[N_PANEL_TYPES];

	GdkImlibImage
				*krell_slider_image,
				*krell_mini_image;

	GdkImlibBorder
				bg_slider_border[N_PANEL_TYPES];

	GdkImlibBorder
				frame_top_border,
				frame_bottom_border,
				frame_left_border,
				frame_right_border,
				button_panel_border,
				button_meter_border;

	GdkImlibImage
				*decal_misc_image;
	GdkPixmap	*decal_misc_pixmap;
	GdkBitmap	*decal_misc_mask;

	/* These two vars should be handled in mail.c, but for historical reasons
	|  gkrellmrcs define them in a way that must be handled in config.c
	*/
	gint		decal_mail_frames,
				decal_mail_delay;


	GdkGC		*draw1_GC,
				*draw2_GC,
				*draw3_GC,
				*draw_stencil_GC,
				*text_GC;

	GdkGC		*bit1_GC,		/* Depth 1 GCs		*/
				*bit0_GC;

	GdkFont		*large_font,
				*normal_font,
				*small_font;

	gchar		*large_font_string,
				*normal_font_string,
				*small_font_string;

	GdkImlibImage *decal_alarm_image;
	GdkImlibImage *decal_warn_image;
	gint		decal_alarm_frames,
				decal_warn_frames;

	GdkImlibImage *bg_separator_image;
	GdkPixmap	*bg_separator_pixmap;
	gint		bg_separator_height;

	GdkImlibImage *data_in_image,		/* Default data layers 0,2, ... */
				*data_in_grid_image;
	GdkPixmap	*data_in_pixmap,
				*data_out_pixmap;

	GdkImlibImage *data_out_image,		/* Default data layers 1,3, ... */
				*data_out_grid_image;
	GdkPixmap	*data_in_grid_pixmap,
				*data_out_grid_pixmap;

	gchar		*chart_in_color,
				*chart_in_color_grid,
				*chart_out_color,
				*chart_out_color_grid;

	GdkColor	in_color;	/* For cpu user, disk read, rx data	*/
	GdkColor	out_color;	/* For cpu sys, disk writes, tx data	*/
	GdkColor	in_color_grid;
	GdkColor	out_color_grid;
	GdkColor	background_color;
	GdkColor	white_color;

	gint		bg_grid_mode;
	gint		theme_n_alternatives;
	gint		theme_alternative;
	gboolean	font_override,
				use_fontset;
	gint		m2;
	gint		use_top_bottom_margins;

	GList		*chart_name_list,		/* Move these lists to monitor_list */
				*meter_name_list,
				*bg_chart_image_list,
				*bg_grid_image_list,
				*bg_panel_image_list,
				*bg_meter_image_list,
				*krell_panel_image_list,
				*krell_meter_image_list,
				*chart_style_list,
				*panel_style_list,
				*meter_style_list;
	};

  /* Debugs for debug_level	*/
#define DEBUG_MAIL		0x10
#define DEBUG_NET		0x20
#define DEBUG_TIMER		0x40
#define	DEBUG_SENSORS	0x80


extern struct ThemeConfig  GK;


/* ================= User Config ==================*/

  /* Values for Monitor id
  |  Give an id number to all builtin monitors
  |				____ cccc ___i iiii
  */
#define	MON_CPU		0
#define	MON_PROC	1
#define	MON_DISK	2
#define	MON_NET		3
#define	MON_INET	4
#define	N_CHART_MONITORS 5

#define	MON_MEM		5
#define	MON_FS		6
#define	MON_MAIL	7
#define	MON_APM		8
#define	MON_UPTIME	9
#define	MON_CLOCK	10
#define	MON_CAL		11
#define	MON_TIMER	12
#define	MON_HOST	13
#define	MON_SWAP	14
#define MON_VOLTAGE	15
#define N_BUILTIN_MONITORS	16
#define MON_PLUGIN	16

#define	MON_ID_MASK		0x1f

#define MON_INSERT_AFTER		0x200
#define MON_CONFIG_MASK			0xf00
#define	MON_GRAVITY_MASK		0xf000

#define	GRAVITY(n)			((n) << 12)
#define	PLUGIN_GRAVITY(m)	(((m)->insert_before_id & MON_GRAVITY_MASK) >> 12)

#define	PLUGIN_INSERT_BEFORE_ID(p)	((p)->insert_before_id & MON_ID_MASK)
#define PLUGIN_INSERT_AFTER(p)	\
							(((p)->insert_before_id & MON_INSERT_AFTER) >> 9)

#define	MONITOR_ID(m)			((m)->id & MON_ID_MASK)
#define	MONITOR_CONFIG(m,flag)	(((m)->id & MON_CONFIG_MASK) & flag)



typedef struct
	{
	GtkWidget		*main_vbox,
					*spacer_top_vbox,
					*vbox,
					*spacer_bottom_vbox,
					*notebook_config_widget;
	gint			notebook_config_page;
	GtkCTreeNode	*ctree_config_node;
	void			(*cb_disable_plugin)(void);
	gint			insert_before_id,
					gravity,
					button_id;
	gboolean		insert_after;
	gboolean		enabled,
					created,
					from_command_line,
					spacers_shown;
	gchar			*style_name;
	gint			style_type,
					style_id;	/* helper until I consolidate image lists */
	GdkImlibImage	*bg_chart_image,
					*bg_panel_image,
					*bg_grid_image,
					*krell_image;
	GdkImlibImage	*spacer_top_image,
					*spacer_bottom_image;
	GtkWidget		*top_pixmapwid,
					*bottom_pixmapwid;
	gint			spacer_top_height,
					spacer_bottom_height;
	}
	MonPrivate;



typedef struct
	{
	gchar		*name;
	gint		id;
	void		(*create_monitor)(GtkWidget *, gint);
	void		(*update_monitor)(void);
	void		(*create_config)(GtkWidget *);
	void		(*apply_config)(void);

	void		(*save_user_config)(FILE *);
	void		(*load_user_config)(gchar *);
	gchar		*config_keyword;
	
	void		(*undef2)(void);
	void		(*undef1)(void);
	MonPrivate	*privat;

	gint		insert_before_id;		/* If plugin, insert before this mon*/
	
	void		*handle;				/* If monitor is a plugin.	*/
	gchar		*path;					/* 	"						*/
	}
	Monitor;

extern GList	*gkrellm_monitor_list;


#include "gkrellm_public_proto.h"
