/*
* Copyright (c) 2007
* Rodney (moonbeam) Cryderman <rcryderman@gmail.com>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
#include <glibtop/uptime.h>
#include <glibtop/proclist.h>
#include <glibtop/procstate.h>
#include <glibtop/proctime.h>
#include <glibtop/procuid.h>
#include <glibtop/procmem.h>
#include <glibtop/cpu.h>
#include <glibtop/mem.h>
#include <glibtop/procargs.h>
#define _GNU_SOURCE
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <pwd.h>
#include <signal.h>
#include <sys/types.h>
#include <dirent.h>
#include <libgen.h>
#include <libawn/awn-applet.h>
#include <glib/gmacros.h>
#include <glib/gerror.h>
#include <gconf/gconf-value.h>
#include <libawn/awn-applet-dialog.h>
#include <libawn/awn-applet-simple.h>
#include <glib.h>
#include <gtk/gtk.h>
#include <libawn/awn-applet.h>
#include <libawn/awn-cairo-utils.h>
#include <libawn/awn-title.h>
#include "awntop_cairo_component.h"
#include "dashboard_util.h"
#include "dashboard.h"
#include "config.h"
#include "gconf-config.h"
//#undef NDEBUG
#include <assert.h>
#define GCONF_AWNTOP_CAIRO_SIZE_MULT GCONF_PATH "/component_awntop_cairo_scale"
#define GCONF_AWNTOP_CAIRO_NO_GTK_FG GCONF_PATH "/component_awntop_cairo_fg"
#define GCONF_AWNTOP_CAIRO_NO_GTK_BG GCONF_PATH "/component_awntop_cairo_bg"
#define GCONF_AWNTOP_CAIRO_NUM_PROCS GCONF_PATH "/component_awntop_cairo_num_procs"
#define GCONF_AWNTOP_CAIRO_KILL_SIG_METH GCONF_PATH "/component_awntop_cairo_kill_sig_meth"
#define GCONF_AWNTOP_CAIRO_USER_FILTER GCONF_PATH "/component_awntop_cairo_user_filter"
typedef struct
{
guint64 proctime;
gboolean accessed;
}Proctimeinfo;
typedef struct
{
dashboard_cairo_widget *w;
guint64 *lookup_table;
int size;
int head;
int tail;
}Small_Pixmap_cache;
typedef struct
{
long pid;
int uid;
int pri;
int nice;
guint virt;
guint res;
long shr;
long cpu;
guint64 mem;
long time;
char cmd[40];
}Topentry;
typedef struct
{
float size_mult;
AwnColor bg; /*colours if gtk colours are overridden */
AwnColor fg;
GtkWidget *table;
int maxtopentries;
int (*compar)(const void *, const void *);
long * displayed_pid_list;
GTree* proctimes;
GTree* icons;
GTree* pixbufs;
Topentry **topentries;
int num_top_entries;
int filterlevel;
glibtop_mem libtop_mem;
guint updateinterval;
gboolean forceupdatefixup;
guint accum_interval;
GtkWidget * widgets[9][70]; /*FIXME*/
long prev_pid[70];
gboolean invalidate_pixmaps;
Small_Pixmap_cache *pid_pixmaps;
Small_Pixmap_cache *uid_pixmaps;
Small_Pixmap_cache *virt_res_pixmaps;
Small_Pixmap_cache *cpu_mem_pixmaps;
Small_Pixmap_cache *procname_pixmaps;
}Awntop_cairo_plug_data;
typedef struct
{
char * name;
gboolean (*fn) (GtkWidget *, GdkEventButton *, Awntop_cairo_plug_data *);
int unscaled_width;
}Tableheader;
static int _Dummy_DUMMY=0;
static int G_kill_signal_method=1;
static GdkPixbuf* Stock_Image_Used=(GdkPixbuf* ) (&_Dummy_DUMMY);
static void * check_ptr;
static gboolean decrease_step(Awntop_cairo_plug_data **p);
static gboolean increase_step(Awntop_cairo_plug_data **p);
static gboolean render(GtkWidget ** pwidget,gint interval,
Awntop_cairo_plug_data **p);
static gboolean query_support_multiple(void);
static void destruct(Awntop_cairo_plug_data **p);
static void construct(Awntop_cairo_plug_data **p);
static const char* get_component_name(Awntop_cairo_plug_data **p);
static const char* get_component_friendly_name(Awntop_cairo_plug_data **p);
static GtkWidget* attach_right_click_menu(Awntop_cairo_plug_data **p);
static gboolean _set_fg(GtkWidget *widget, GdkEventButton *event,
Awntop_cairo_plug_data *p);
static gboolean _set_bg(GtkWidget *widget, GdkEventButton *event,
Awntop_cairo_plug_data *p);
static gboolean _increase_awntop_rows (GtkWidget *widget, GdkEventButton *event,
Awntop_cairo_plug_data *awntop);
static gboolean _decrease_awntop_rows (GtkWidget *widget, GdkEventButton *event,
Awntop_cairo_plug_data *awntop);
static gboolean _toggle_display_freeze(GtkWidget *widget, GdkEventButton *event,
Awntop_cairo_plug_data *awntop);
static gboolean _click_set_term (GtkWidget *widget, GdkEventButton *event,
Awntop_cairo_plug_data*awntop);
static gboolean _click_set_kill (GtkWidget *widget, GdkEventButton *event,
Awntop_cairo_plug_data *awntop);
static gboolean _click_set_term_kill (GtkWidget *widget, GdkEventButton *event,
Awntop_cairo_plug_data*awntop);
static gboolean _toggle_user_filter (GtkWidget *widget, GdkEventButton *event,
Awntop_cairo_plug_data *awntop);
static void set_colour(Awntop_cairo_plug_data *p,AwnColor* colour,
const char * mess,const char * gconf_key);
static void build_top_table_headings(Awntop_cairo_plug_data * data);
static Topentry ** fill_topentries(Awntop_cairo_plug_data *awntop,int *numel);
static gboolean proctime_find_inactive(gpointer key,gpointer value,
gpointer data);
static void proctimes_remove_inactive(gpointer data,gpointer user_data);
static gboolean proctime_reset_active(gpointer key,gpointer value,
gpointer data);
static gint proctime_key_compare_func(gconstpointer a,gconstpointer b,
gpointer user_data);
static int cmppid(const void *, const void *);
static int cmpuser(const void *, const void *);
static int cmpvirt(const void *, const void *);
static int cmpres(const void *, const void *);
static int cmpcpu(const void *, const void *);
static int cmpmem(const void *, const void *);
static int cmpcommand(const void *, const void *);
static void invalidate_pixmap_cache(Small_Pixmap_cache *p);
static Small_Pixmap_cache * get_s_pixmap_cache(long size);
static GdkPixmap * lookup_pixmap(Small_Pixmap_cache *p, guint64 key);
static GtkWidget * lookup_icon(Awntop_cairo_plug_data * awntop,
Topentry **topentries,int i);
static void invalidate_pixmap_cache(Small_Pixmap_cache *p);
static void invalidate_all_pixmap_caches(Awntop_cairo_plug_data * data);
static gint icons_key_compare_func(gconstpointer a,gconstpointer b,
gpointer user_data);
static GtkWidget * get_icon_event_box(Awntop_cairo_plug_data * awntop,
char *name,const gchar *stock_id, GtkIconSize size);
static void parse_desktop_entries(Awntop_cairo_plug_data * awntop);
static void free_topentries(Topentry **topentries, int num_top_entries);
static void set_foreground(Awntop_cairo_plug_data * data, cairo_t * cr );
static void set_background(A