gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[GNUnet-SVN] r1316 - in gnunet-gtk/src/plugins: . stats


From: grothoff
Subject: [GNUnet-SVN] r1316 - in gnunet-gtk/src/plugins: . stats
Date: Fri, 8 Jul 2005 12:34:56 -0700 (PDT)

Author: grothoff
Date: 2005-07-08 12:34:52 -0700 (Fri, 08 Jul 2005)
New Revision: 1316

Added:
   gnunet-gtk/src/plugins/stats/
   gnunet-gtk/src/plugins/stats/statistics.c
   gnunet-gtk/src/plugins/stats/statistics.h
Log:
rescue from 0.6.6b

Added: gnunet-gtk/src/plugins/stats/statistics.c
===================================================================
--- gnunet-gtk/src/plugins/stats/statistics.c   2005-07-08 19:31:29 UTC (rev 
1315)
+++ gnunet-gtk/src/plugins/stats/statistics.c   2005-07-08 19:34:52 UTC (rev 
1316)
@@ -0,0 +1,949 @@
+/*
+     This file is part of GNUnet
+
+     GNUnet 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.
+
+     GNUnet 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 GNUnet; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+
+     Portions of this code were adopted from the
+     gnome-system-monitor v2.0.5, (C) 2001 Kevin Vandersloot
+
+
+     Todo:
+     - add any more StatEntries, update menu accordingly.
+*/
+
+#include "gnunet_afs_esed2.h"
+#include "statistics.h"
+#include "helper.h"
+#include "main.h"
+#include <glib.h>
+
+#define UPDATE_INTERVAL (30 * cronSECONDS)
+
+typedef struct {
+  char * statName;
+  long long value;
+  long long lvalue;
+  cron_t delta;
+} StatPair;
+
+static StatPair * lastStatValues;
+static unsigned int lsv_size;
+static cron_t lastUpdate;
+static Mutex lock;
+
+static void updateStatValues(GNUNET_TCP_SOCKET * sock) {
+  STATS_CS_MESSAGE * statMsg;
+  CS_HEADER csHdr;
+  unsigned int count;
+  unsigned int i;
+  int j;
+  int mpos;
+  int found;
+  char * optName;
+  cron_t now;
+  cron_t prev;
+    
+  cronTime(&now);
+  MUTEX_LOCK(&lock);
+  if (now - lastUpdate < UPDATE_INTERVAL) { 
+    MUTEX_UNLOCK(&lock);
+    return;
+  }
+  prev = lastUpdate;
+  lastUpdate = now;
+  csHdr.size 
+    = htons(sizeof(CS_HEADER));
+  csHdr.tcpType
+    = htons(STATS_CS_PROTO_GET_STATISTICS);
+  if (SYSERR == writeToSocket(sock,
+                             &csHdr)) {
+    MUTEX_UNLOCK(&lock);
+    return;
+  }
+  statMsg 
+    = MALLOC(MAX_BUFFER_SIZE);
+  statMsg->totalCounters 
+    = htonl(1); /* to ensure we enter the loop */
+  count = 0;
+  while ( count < ntohl(statMsg->totalCounters) ) {
+    if (SYSERR == readFromSocket(sock,
+                                (CS_HEADER**)&statMsg)) {
+      FREE(statMsg);
+      MUTEX_UNLOCK(&lock);
+      return;    
+    }
+    if (ntohs(statMsg->header.size) < sizeof(STATS_CS_MESSAGE)) {
+      BREAK();
+      break;
+    }
+    mpos = sizeof(unsigned long long) * ntohl(statMsg->statCounters);
+    if ( ((char*)(((STATS_CS_MESSAGE_GENERIC*)statMsg)->values))
+        [ntohs(statMsg->header.size) - sizeof(STATS_CS_MESSAGE) - 1] != '\0') {
+      BREAK();
+      break;
+    }      
+    for (i=0;i<ntohl(statMsg->statCounters);i++) {
+      optName = &((char*)(((STATS_CS_MESSAGE_GENERIC*)statMsg)->values))[mpos];
+      if ( (mpos > ntohs(statMsg->header.size) - sizeof(STATS_CS_MESSAGE)) ||
+          (mpos + strlen(optName) + 1 > 
+           ntohs(statMsg->header.size) - sizeof(STATS_CS_MESSAGE)) ) {
+       BREAK();
+       break; /* out of bounds! */      
+      }
+      found = -1;
+      for (j=0;j<lsv_size;j++) 
+       if (0 == strcmp(optName,
+                       lastStatValues[j].statName))
+         found = j;
+      if (found == -1) {
+       found = lsv_size;
+       GROW(lastStatValues,
+            lsv_size,
+            lsv_size+1);
+       lastStatValues[found].statName
+         = STRDUP(optName);
+      }
+      lastStatValues[found].lvalue
+       = lastStatValues[found].value;
+      lastStatValues[found].value
+       = ntohll(((STATS_CS_MESSAGE_GENERIC*)statMsg)->values[i]);      
+      lastStatValues[found].delta
+       = now-prev;
+      mpos += strlen(optName)+1;
+    }    
+    count += ntohl(statMsg->statCounters);
+  } /* end while */
+  FREE(statMsg);
+  MUTEX_UNLOCK(&lock);
+}
+
+static int getStatValue(long long * value,
+                       long long * lvalue,
+                       cron_t * dtime,
+                       GNUNET_TCP_SOCKET * sock,
+                       const char * optName) {
+  unsigned int i;
+
+  *value = 0;
+  if (lvalue != NULL)
+    *lvalue = 0;
+  updateStatValues(sock);
+  MUTEX_LOCK(&lock);
+  for (i=0;i<lsv_size;i++) {
+    if (0 == strcmp(optName,
+                   lastStatValues[i].statName)) {
+      *value = lastStatValues[i].value;
+      if (lvalue != NULL)
+       *lvalue = lastStatValues[i].lvalue;
+      if (dtime != NULL)
+       *dtime = lastStatValues[i].delta;
+      MUTEX_UNLOCK(&lock);
+      return OK;
+    }      
+  }
+  MUTEX_UNLOCK(&lock);
+  return SYSERR;
+}
+
+/**
+ * Callback function to obtain the latest stats
+ * data for this stat display.
+ */
+typedef int (*UpdateData)(GNUNET_TCP_SOCKET * sock,
+                         const void * closure,
+                         gfloat ** data);
+
+static int getConnectedNodesStat(GNUNET_TCP_SOCKET * sock,
+                                const void * closure,
+                                gfloat ** data) {
+  long long val;
+  char * cmh;
+  long cval;
+
+  cmh = getConfigurationOptionValue(sock,
+                                   "gnunetd",
+                                   "connection-max-hosts");
+  if (cmh == NULL)
+    return SYSERR;
+  cval = atol(cmh);
+  FREE(cmh);
+  if (OK != getStatValue(&val,
+                        NULL,
+                        NULL,
+                        sock,
+                        _("# currently connected nodes"))) 
+    return SYSERR;
+  data[0][0] = 0.8 * val / cval;
+  return OK;
+}
+
+static int getCPULoadStat(GNUNET_TCP_SOCKET * sock,
+                         const void * closure,
+                         gfloat ** data) {
+  long long val;
+
+  if (OK != getStatValue(&val,
+                        NULL,
+                        NULL,
+                        sock,
+                        _("% of allowed cpu load")))
+    return SYSERR;
+  data[0][0] = val / 125.0;
+  return OK;
+}
+
+static const unsigned short afs_protocol_messages_queries[] = {
+  AFS_p2p_PROTO_QUERY,
+  AFS_p2p_PROTO_NSQUERY,
+  0,
+};
+
+static const unsigned short afs_protocol_messages_content[] = {
+  AFS_p2p_PROTO_3HASH_RESULT,
+  AFS_p2p_PROTO_CHK_RESULT,
+  AFS_p2p_PROTO_SBLOCK_RESULT,
+  0,
+};
+
+static int getTrafficRecvStats(GNUNET_TCP_SOCKET * sock,
+                              const void * closure,
+                              gfloat ** data) {
+  long long total;
+  long long noise;
+  long long content;
+  long long queries;
+  long long ltotal;
+  long long lnoise;
+  long long lcontent;
+  long long lqueries;
+  long long band;
+  long long tmp;
+  long long ltmp;
+  cron_t dtime;
+  char * available;
+  char * buffer;
+  int i;
+
+  MUTEX_LOCK(&lock);
+  if (OK != getStatValue(&total,       
+                        &ltotal,
+                        &dtime,
+                        sock,
+                        _("# bytes decrypted")))
+    return SYSERR;
+  if (OK != getStatValue(&noise,
+                        &lnoise,
+                        NULL,
+                        sock,
+                        _("# bytes of noise received")))
+    return SYSERR;
+  i = 0;
+  content = lcontent = 0;
+  buffer = MALLOC(512);
+  while (afs_protocol_messages_content[i] != 0) {
+    SNPRINTF(buffer, 
+            512,
+            _("# bytes received of type %d"),
+            afs_protocol_messages_content[i++]);
+    if (OK == getStatValue(&tmp,
+                          &ltmp,
+                          NULL,
+                          sock,
+                          buffer)) {
+      content += tmp;
+      lcontent += ltmp;
+    }
+  }
+  i = 0;
+  while (afs_protocol_messages_queries[i] != 0) {
+    SNPRINTF(buffer, 
+            512,
+            _("# bytes received of type %d"),
+            afs_protocol_messages_queries[i++]);
+    if (OK == getStatValue(&tmp,
+                          &ltmp,
+                          NULL,
+                          sock,
+                          buffer)) {
+      queries += tmp;
+      lqueries += ltmp;
+    }
+  }
+  FREE(buffer);
+  MUTEX_UNLOCK(&lock);
+  available = getConfigurationOptionValue(sock,
+                                         "LOAD",
+                                         "MAXNETDOWNBPSTOTAL");
+  if (available == NULL)
+    return SYSERR; 
+  band = atol(available) * dtime / cronSECONDS;
+  FREE(available);
+  total -= ltotal;
+  noise -= lnoise;
+  queries -= lqueries;
+  content -= lcontent;
+  if (band <= 0) {
+    data[0][0] = 0.0;
+    data[0][1] = 0.0;
+    data[0][2] = 0.0;
+    data[0][3] = 0.0;
+    return OK;
+  }
+  data[0][0] = 0.8 * noise / band; /* red */
+  data[0][1] = 0.8 * (content+noise) / band; /* green */
+  data[0][2] = 0.8 * (queries+content+noise) / band; /* yellow */
+  data[0][3] = 0.8 * total / band; /* blue */
+  /*printf("I: %f %f %f\n", 
+        data[0][0],
+        data[0][1],
+        data[0][2]);*/
+
+  return OK;
+}
+
+
+  static int getTrafficSendStats(GNUNET_TCP_SOCKET * sock,
+                              const void * closure,
+                              gfloat ** data) {
+  long long total;
+  long long noise;
+  long long content;
+  long long queries;
+  long long ltotal;
+  long long lnoise;
+  long long lcontent;
+  long long lqueries;
+  long long band;
+  long long tmp;
+  long long ltmp;
+  cron_t dtime;
+  char * available;
+  char * buffer;
+  int i;
+
+  MUTEX_LOCK(&lock);
+  if (OK != getStatValue(&total,       
+                        &ltotal,
+                        &dtime,
+                        sock,
+                        _("# encrypted bytes sent")))
+    return SYSERR;
+  if (OK != getStatValue(&noise,
+                        &lnoise,
+                        NULL,
+                        sock,
+                        _("# bytes noise sent")))
+    return SYSERR;
+  i = 0;
+  content = lcontent = 0;
+  buffer = MALLOC(512);
+  while (afs_protocol_messages_content[i] != 0) {
+    SNPRINTF(buffer, 
+            512,
+            _("# bytes transmitted of type %d"),
+            afs_protocol_messages_content[i++]);
+    if (OK == getStatValue(&tmp,
+                          &ltmp,
+                          NULL,
+                          sock,
+                          buffer)) {
+      content += tmp;
+      lcontent += ltmp;
+    }
+  }
+  i = 0;
+  while (afs_protocol_messages_queries[i] != 0) {
+    SNPRINTF(buffer, 
+            512,
+            _("# bytes received of type %d"),
+            afs_protocol_messages_queries[i++]);
+    if (OK == getStatValue(&tmp,
+                          &ltmp,
+                          NULL,
+                          sock,
+                          buffer)) {
+      queries += tmp;
+      lqueries += ltmp;
+    }
+  }
+  FREE(buffer);
+  MUTEX_UNLOCK(&lock);
+  available = getConfigurationOptionValue(sock,
+                                         "LOAD",
+                                         "MAXNETUPBPSTOTAL");
+  if (available == NULL)
+    return SYSERR;
+  band = atol(available) * dtime / cronSECONDS;
+  FREE(available);
+  total -= ltotal;
+  noise -= lnoise;
+  queries -= lqueries;
+  content -= lcontent;
+  if (band <= 0) {
+    data[0][0] = 0.0;
+    data[0][1] = 0.0;
+    data[0][2] = 0.0;
+    data[0][3] = 0.0;
+    return OK;
+  }
+  data[0][0] = 0.8 * noise / band; /* red */
+  data[0][1] = 0.8 * (noise + content) / band; /* green */
+  data[0][2] = 0.8 * (noise + content + queries) / band; /* yellow */
+  data[0][3] = 0.8 * total / band; /* yellow */
+  /* printf("O: %f %f %f\n", 
+     data[0][0],
+     data[0][1],
+        data[0][2]);*/
+  
+  return OK;
+}
+
+
+
+typedef struct SE_ {
+  char * paneName;
+  char * frameName;
+  UpdateData getData;
+  void * get_closure;
+  unsigned int count;
+  int fill; /* YES / NO */
+} StatEntry;
+
+#define STATS_COUNT 4
+
+static StatEntry stats[] = {
+  { 
+    gettext_noop("Connectivity"),
+    gettext_noop("# connected nodes (100% = connection table size)"),
+    &getConnectedNodesStat,
+    NULL,
+    1,
+    NO,
+  }, 
+  { 
+    gettext_noop("CPU load"),
+    gettext_noop("CPU load (in percent of allowed load)"),
+    &getCPULoadStat,
+    NULL,
+    1,
+    NO,
+  },
+  { 
+    gettext_noop("Inbound Traffic"),
+    gettext_noop("Noise (red), Content (green), Queries (yellow), other 
(blue)"),
+    &getTrafficRecvStats,
+    NULL,
+    4,
+    YES,
+  },
+  { 
+    gettext_noop("Outbound Traffic"),
+    gettext_noop("Noise (red), Content (green), Queries (yellow), other 
(blue)"),
+    &getTrafficSendStats,
+    NULL,
+    4,
+    YES,
+  },
+  {
+    NULL,
+    NULL,
+    NULL,
+    NULL,
+    1,
+    NO,
+  },
+};
+
+
+/**
+ * Remove the active page from the notebook.
+ */
+static void statClose(void) {
+  gint pagenr;
+
+  pagenr = gtk_notebook_get_current_page(notebook);
+  gtk_notebook_remove_page(notebook, pagenr);
+  /* Need to refresh the widget --
+     This forces the widget to redraw itself. */
+  gtk_widget_draw(GTK_WIDGET(notebook), NULL);
+}
+
+static GtkItemFactoryEntry statWindowMenu[] = {
+  { 
+    gettext_noop("/Close display"),   
+    NULL, 
+    statClose, 
+    0, 
+    "<Item>" 
+  }
+};
+static gint statWindowMenuItems 
+  = sizeof (statWindowMenu) / sizeof (statWindowMenu[0]);
+
+
+/**
+ */
+static void addClosePopupMenu(GtkWidget * widget) {
+  GtkWidget * menu;
+  GtkItemFactory * popupFactory;
+
+  popupFactory = gtk_item_factory_new(GTK_TYPE_MENU, "<main>",
+                                     NULL);
+  gtk_item_factory_create_items(popupFactory,
+                               statWindowMenuItems,
+                               statWindowMenu,
+                               NULL);
+  menu = gtk_item_factory_get_widget(popupFactory, "<main>");
+  gtk_signal_connect(GTK_OBJECT(widget),
+                    "button_press_event",
+                    GTK_SIGNAL_FUNC(popupCallback),
+                    menu); 
+}
+
+
+typedef struct {
+  gint type;
+  guint count;
+  guint speed;
+  guint draw_width, draw_height;
+  guint num_points; 
+  guint allocated;  
+  GdkColor *colors;
+  gfloat **data, **odata;
+  guint data_size;
+  gint colors_allocated;
+  GtkWidget *main_widget;
+  GtkWidget *disp;
+  GtkWidget *label;
+  GdkPixmap *pixmap;
+  GdkGC *gc;
+  int timer_index;  
+  gboolean draw;
+  GNUNET_TCP_SOCKET * sock;
+  int statIdx;
+} LoadGraph;
+
+#define MAX_COLOR 4
+
+typedef struct {
+  gint            graph_update_interval;
+  GdkColor        bg_color;
+  GdkColor        frame_color;
+  GdkColor        mem_color[MAX_COLOR];
+} ProcConfig;
+
+typedef struct ProcData {
+  ProcConfig      config;
+  LoadGraph       *mem_graph;
+  int statIdx;
+} ProcData;
+
+#define GNOME_PAD_SMALL 2
+#define FRAME_WIDTH 0
+
+
+/**
+ * Redraws the backing pixmap for the load graph and updates the window 
+ */
+static void load_graph_draw(LoadGraph *g) {
+  guint i;
+  guint j;
+  gint dely;
+  float delx;
+  
+  if (!g->disp->window)
+    return;
+  
+  g->draw_width = g->disp->allocation.width;
+  g->draw_height = g->disp->allocation.height;
+  
+  if (!g->pixmap)
+    g->pixmap = gdk_pixmap_new (g->disp->window,
+                               g->draw_width, g->draw_height,
+                               gtk_widget_get_visual (g->disp)->depth);
+  
+  /* Create GC if necessary. */
+  if (!g->gc) {
+    g->gc = gdk_gc_new (g->disp->window);
+    gdk_gc_copy (g->gc, g->disp->style->white_gc);
+  }
+  
+  /* Allocate colors. */
+  if (!g->colors_allocated) {
+    GdkColormap *colormap;
+    
+    colormap = gdk_window_get_colormap (g->disp->window);
+    for (i=0;i<2+g->count;i++) 
+      gdk_color_alloc (colormap, &(g->colors [i]));    
+    
+    g->colors_allocated = 1;
+  }
+  /* Erase Rectangle */
+  gdk_gc_set_foreground (g->gc, &(g->colors [0]));
+  gdk_draw_rectangle (g->pixmap,
+                     g->gc,
+                     TRUE, 0, 0,
+                     g->disp->allocation.width,
+                     g->disp->allocation.height);
+  
+  /* draw frame */
+  gdk_gc_set_foreground (g->gc, &(g->colors [1]));
+  gdk_draw_rectangle (g->pixmap,
+                     g->gc,
+                     FALSE, 0, 0,
+                     g->draw_width,
+                     g->disp->allocation.height);
+  
+  dely = g->draw_height / 5;
+  for (i = 1; i <5; i++) {
+    gint y1 = g->draw_height + 1 - i * dely;
+    gdk_draw_line (g->pixmap, g->gc,
+                  0, y1, g->draw_width, y1);
+  }
+  
+  gdk_gc_set_line_attributes (g->gc, 2, GDK_LINE_SOLID, GDK_CAP_ROUND, 
GDK_JOIN_MITER );
+  delx = (float)g->draw_width / ( g->num_points - 1);
+  
+  for (j=0;j<g->count;j++) {
+    gdk_gc_set_foreground (g->gc, &(g->colors [j + 2]));
+    for (i = 0; i < g->num_points - 1; i++) {    
+      gint x1 = i * delx;
+      gint x2 = (i + 1) * delx;
+      gint y1 = g->data[i][j] * g->draw_height - 1;
+      gint y2 = g->data[i+1][j] * g->draw_height - 1;
+      
+      if ((g->data[i][j] != -1) && (g->data[i+1][j] != -1)) {
+       if (stats[g->statIdx].fill == NO) {
+         gdk_draw_line(g->pixmap, g->gc,
+                       g->draw_width - x2, 
+                       g->draw_height - y2,
+                       g->draw_width - x1,
+                       g->draw_height - y1);
+       } else {
+         GdkPoint points[4];
+         
+         points[0].x = g->draw_width - x2;
+         points[0].y = g->draw_height - y2;
+         points[1].x = g->draw_width - x1;
+         points[1].y = g->draw_height - y1;
+         points[2].x = g->draw_width - x1;
+         points[3].x = g->draw_width - x2;
+         if (j == 0) {
+           points[2].y = g->draw_height;
+           points[3].y = g->draw_height;
+         } else {
+           gint ly1 = g->data[i][j-1] * g->draw_height - 1;
+           gint ly2 = g->data[i+1][j-1] * g->draw_height - 1;
+           points[2].y = g->draw_height - ly1;
+           points[3].y = g->draw_height - ly2;
+         }
+         gdk_draw_polygon(g->pixmap,
+                          g->gc,
+                          1,
+                          points,
+                          4);  
+       }
+      }
+    }
+  }
+
+  gdk_gc_set_line_attributes (g->gc, 1, GDK_LINE_SOLID, GDK_CAP_ROUND, 
GDK_JOIN_MITER );
+  
+  gdk_draw_pixmap (g->disp->window,
+                  g->disp->style->fg_gc [GTK_WIDGET_STATE(g->disp)],
+                  g->pixmap,
+                  0, 0,
+                  0, 0,
+                  g->disp->allocation.width,
+                  g->disp->allocation.height);
+}
+
+
+/* Updates the load graph when the timeout expires */
+static int load_graph_update(LoadGraph *g) {
+  guint i;  
+  guint j;
+
+  for (i=0;i<g->num_points;i++)
+    memcpy(g->odata[i], 
+          g->data[i],
+          g->data_size * g->count); 
+  stats[g->statIdx].getData(g->sock,
+                           stats[g->statIdx].get_closure,
+                           g->data);
+  for (i=0;i<g->num_points-1;i++)
+    for (j=0;j<g->count;j++)
+      g->data[i+1][j] = g->odata[i][j];  
+  if (g->draw)
+    load_graph_draw (g);  
+  return TRUE;
+}
+
+static void load_graph_unalloc (LoadGraph *g) {
+  int i;
+  if (!g->allocated)
+    return;
+  for (i = 0; i < g->num_points; i++) {
+    FREE(g->data[i]);
+    FREE(g->odata[i]);
+  }
+  FREE(g->data);
+  FREE(g->odata);
+  g->data = g->odata = NULL;
+  if (g->pixmap) {
+    gdk_pixmap_unref(g->pixmap);
+    g->pixmap = NULL;
+  }
+  g->allocated = FALSE;
+}
+
+static void load_graph_alloc (LoadGraph *g) {
+  int i;
+  int j;
+
+  if (g->allocated)
+    return;
+  
+  g->data = MALLOC(sizeof(gfloat *) * g->num_points);
+  g->odata = MALLOC(sizeof(gfloat*) * g->num_points);
+  g->data_size = sizeof (gfloat);  
+  for (i = 0; i < g->num_points; i++) {
+    g->data[i] = MALLOC(g->data_size * g->count);
+    g->odata[i] = MALLOC(g->data_size * g->count);
+  }  
+  for (i=0;i<g->num_points;i++) 
+    for (j=0;j<g->count;j++)
+      g->data[i][j] = -1;
+  g->allocated = TRUE;
+}
+
+static gint load_graph_configure(GtkWidget *widget, 
+                                GdkEventConfigure *event,
+                                gpointer data_ptr) {
+  LoadGraph *c = (LoadGraph *) data_ptr;
+  
+  if (c->pixmap) {
+    gdk_pixmap_unref (c->pixmap);
+    c->pixmap = NULL;
+  }
+  
+  if (!c->pixmap)
+    c->pixmap = gdk_pixmap_new (widget->window,
+                               widget->allocation.width,
+                               widget->allocation.height,
+                               gtk_widget_get_visual (c->disp)->depth);
+  gdk_draw_rectangle (c->pixmap,
+                     widget->style->black_gc,
+                     TRUE, 0,0,
+                     widget->allocation.width,
+                     widget->allocation.height);
+  gdk_draw_pixmap (widget->window,
+                  c->disp->style->fg_gc [GTK_WIDGET_STATE(widget)],
+                  c->pixmap,
+                  0, 0,
+                  0, 0,
+                  c->disp->allocation.width,
+                  c->disp->allocation.height);  
+
+  load_graph_draw (c); 
+  return TRUE;
+}
+
+static gint load_graph_expose(GtkWidget *widget,
+                             GdkEventExpose *event,
+                             gpointer data_ptr) {
+  LoadGraph *g = (LoadGraph *) data_ptr;
+  
+  gdk_draw_pixmap (widget->window,
+                  widget->style->fg_gc [GTK_WIDGET_STATE(widget)],
+                  g->pixmap,
+                  event->area.x, event->area.y,
+                  event->area.x, event->area.y,
+                  event->area.width, event->area.height);
+  return FALSE;
+}
+
+static void load_graph_stop (LoadGraph *g) {
+  if (g->timer_index != -1) {
+    gtk_timeout_remove (g->timer_index);
+    g->timer_index = -1;
+  }
+  if (!g)
+    return;
+  g->draw = FALSE;
+}
+
+static void load_graph_destroy(GtkWidget *widget, 
+                              gpointer data_ptr) {
+  LoadGraph *g = (LoadGraph *) data_ptr;  
+  load_graph_stop(g);  
+  if (g->timer_index != -1)
+    gtk_timeout_remove (g->timer_index);
+  if (g->sock != NULL)
+    releaseClientSocket(g->sock);
+  load_graph_unalloc(g);
+  FREE(g->colors);
+  FREE(g);
+}
+
+static LoadGraph * load_graph_new(ProcData *procdata) {
+  LoadGraph *g;
+  unsigned int i;
+
+  if ( (procdata->statIdx < 0) ||
+       (procdata->statIdx >= STATS_COUNT) ) {
+    BREAK();
+    return NULL;
+  }
+  if (stats[procdata->statIdx].count > MAX_COLOR) {
+    BREAK();
+    return NULL;
+  }
+  
+  g = MALLOC(sizeof(LoadGraph));
+  g->sock = getClientSocket();
+  g->statIdx = procdata->statIdx;
+  g->count = stats[g->statIdx].count;
+  g->speed = procdata->config.graph_update_interval;
+  g->num_points = 600;
+  g->colors = MALLOC(sizeof(GdkColor) * (2+g->count));
+  g->colors[0] = procdata->config.bg_color;
+  g->colors[1] = procdata->config.frame_color;  
+  for (i=0;i<g->count;i++) 
+    g->colors[2+i] = procdata->config.mem_color[i];
+  g->timer_index = -1;
+  g->draw = FALSE;
+  g->main_widget = gtk_vbox_new (FALSE, FALSE);
+  gtk_widget_show (g->main_widget);
+  g->disp = gtk_drawing_area_new();
+  gtk_widget_show (g->disp);
+  gtk_signal_connect (GTK_OBJECT (g->disp),
+                     "expose_event",
+                     GTK_SIGNAL_FUNC (load_graph_expose), g);
+  gtk_signal_connect (GTK_OBJECT(g->disp), 
+                     "configure_event",
+                     GTK_SIGNAL_FUNC (load_graph_configure), g);
+  gtk_signal_connect (GTK_OBJECT(g->disp),
+                     "destroy",
+                     GTK_SIGNAL_FUNC (load_graph_destroy), g); 
+  gtk_widget_add_events(g->disp, GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK);
+  gtk_box_pack_start(GTK_BOX (g->main_widget), g->disp, TRUE, TRUE, 0);
+  load_graph_alloc(g);  
+  gtk_widget_show_all (g->main_widget);  
+  g->timer_index = gtk_timeout_add(g->speed,
+                                  (GtkFunction) load_graph_update, g);
+  
+  return g;
+}
+
+static void load_graph_start(LoadGraph *g) {
+  if (!g)
+    return;
+  
+  if (g->timer_index == -1)
+    g->timer_index = gtk_timeout_add(g->speed,
+                                    (GtkFunction) load_graph_update, g);
+  
+  g->draw = TRUE;
+}
+
+static GtkWidget * create_sys_view(ProcData * procdata) {
+  GtkWidget * mem_frame;
+  LoadGraph * mem_graph;
+
+  mem_graph = load_graph_new(procdata);
+  procdata->mem_graph = mem_graph;
+  if (mem_graph == NULL)
+    return NULL; /* oops */
+  mem_frame = gtk_frame_new(_(stats[procdata->statIdx].frameName));
+  gtk_container_add(GTK_CONTAINER(mem_frame),
+                   mem_graph->main_widget);
+  gtk_container_set_border_width(GTK_CONTAINER(mem_graph->main_widget),
+                                GNOME_PAD_SMALL);
+  gtk_container_set_border_width (GTK_CONTAINER(mem_frame),
+                                 GNOME_PAD_SMALL);
+  gtk_widget_show(mem_frame);
+  addClosePopupMenu(mem_frame);
+  return mem_frame;
+}
+
+
+static GtkWidget * create_main_window(int stat) {
+  GtkWidget *sys_box;
+  ProcData procdata;
+
+    
+  memset(&procdata, 0, sizeof(ProcData));
+  procdata.config.graph_update_interval 
+    = UPDATE_INTERVAL / cronMILLIS;
+  procdata.statIdx = stat;
+  gdk_color_parse("black",
+                 &procdata.config.bg_color);
+  gdk_color_parse("gray",
+                 &procdata.config.frame_color);
+  gdk_color_parse("red",
+                 &procdata.config.mem_color[0]);
+  gdk_color_parse("green",
+                 &procdata.config.mem_color[1]);
+  gdk_color_parse("yellow",
+                 &procdata.config.mem_color[2]);
+  gdk_color_parse("blue",
+                 &procdata.config.mem_color[3]);
+  GNUNET_ASSERT(MAX_COLOR == 4);
+  sys_box = create_sys_view(&procdata);
+  if (sys_box == NULL)
+    return NULL;
+  load_graph_start(procdata.mem_graph); 
+  return sys_box;
+}
+
+
+/**
+ * Display the statistics.
+ */
+void displayStatistics(GtkWidget * widget,
+                      gpointer data) {
+  int dptr;
+  GtkWidget * wid;
+
+  dptr = (int) data;
+  if ( (dptr < 0) ||
+       (dptr >= STATS_COUNT) ) {
+    BREAK();
+  } else {    
+    wid = create_main_window(dptr);
+    if (wid != NULL)
+      addToNotebook(_(stats[dptr].paneName),
+                   wid);
+  }
+}
+
+void initGTKStatistics() {
+  MUTEX_CREATE_RECURSIVE(&lock);
+}
+
+void doneGTKStatistics() {
+  unsigned int i;
+  for (i=0;i<lsv_size;i++)
+    FREE(lastStatValues[i].statName);
+  GROW(lastStatValues,
+       lsv_size,
+       0);
+  MUTEX_DESTROY(&lock);
+}
+
+ 
+/* end of statistics.c */

Added: gnunet-gtk/src/plugins/stats/statistics.h
===================================================================
--- gnunet-gtk/src/plugins/stats/statistics.h   2005-07-08 19:31:29 UTC (rev 
1315)
+++ gnunet-gtk/src/plugins/stats/statistics.h   2005-07-08 19:34:52 UTC (rev 
1316)
@@ -0,0 +1,49 @@
+/*
+     This file is part of GNUnet
+
+     GNUnet 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.
+
+     GNUnet 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 GNUnet; see the file COPYING.  If not, write to the
+     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+     Boston, MA 02111-1307, USA.
+*/
+
+/**
+ * @file applications/afs/gtkui/statistics.h
+ * @author Christian Grothoff 
+ **/
+
+#ifndef GTKUI_STATISTICS_H
+#define GTKUI_STATISTICS_H
+
+#include "platform.h"
+#include <gtk/gtk.h>
+#include <gtk/gtktext.h>
+
+/**
+ * Display the statistics.
+ */
+void displayStatistics(GtkWidget * widget,
+                      gpointer data);
+
+
+void initGTKStatistics();
+ 
+void doneGTKStatistics();
+
+#define STAT_CONNECTIVITY 0
+#define STAT_CPU_LOAD 1
+#define STAT_IN_TRAFFIC 2
+#define STAT_OUT_TRAFFIC 3
+
+
+#endif





reply via email to

[Prev in Thread] Current Thread [Next in Thread]