/*
* $xforce: geomgui/geomgui.c,v 1.22 2006/05/21 08:40:49 xride Exp $
*
*
* BEERWARE LICENSE
* If you like this code, then you may buy me a beer.
* You may use this code in any way, aslong as this text follows it.
* Ver 42 of BEERWARE LICENSE Søren (Xride) Straarup <xride@x12.dk>
*/
/*
* This program leaves behind two files in /tmp
* conf.dot, conf.xml and conf.svg
*/
#include <sys/types.h>
#include <sys/sysctl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gvc.h>
#include <unistd.h>
#include <sys/stat.h>
#include <gtk/gtk.h>
#include <gdk-pixbuf/gdk-pixbuf.h>
#include <librsvg/rsvg.h>
#include "geomgui.h"
#define BUFSIZE 100000
/*
* Help text
*/
void usage()
{
printf("\n\tProgram %s version %s\n",program_name,VERSION);
printf("\tparameters:\n");
printf("\t\t-r user@host\tHost to ssh into to grab geom layout\n");
printf("\n");
printf("\tkeys:\n");
printf("\t\th\tscroll left\n");
printf("\t\tj\tscroll up\n");
printf("\t\tk\tscroll down\n");
printf("\t\tl\tscroll right\n");
printf("\t\tz\tzoom out\n");
printf("\t\tZ\tzoom in\n");
printf("\t\tu\tupdate\n");
printf("\t\tq\tquit\n");
printf("\n");
printf("\n");
}
/*
* this is used to "lock" geom2svg() from beeing run multiple times at once
*/
int lock_graph;
/*
* this gets xml and makes a svg of it.
* currently it doesn't work the second time it is called.
*/
int geom2svg(struct myconfigs *configs)
{
char str[BUFSIZE];
char dot[BUFSIZE];
char buf[BUFSIZE];
int ret;
size_t len;
/*
* fool graphviz to output in svg format and to a file called conf.svg
*/
int argg=5;
char *argh[5];
argh[0] = malloc(3 * sizeof(char));
argh[1] = malloc(6 * sizeof(char));
argh[2] = malloc(3 + strlen(configs->svgfile));
argh[3] = malloc(19 * sizeof(char));
argh[4] = malloc(19 * sizeof(char));
FILE *fp;
FILE *fpxml;
struct stat *statxml = malloc(sizeof(struct stat));
char *bufcmd = malloc(256 * sizeof(char));
if(!argh[0])
perror("argh[0]");
if(!argh[1])
perror("argh[1]");
if(!argh[2])
perror("argh[2]");
if(!argh[3])
perror("argh[3]");
if(!argh[4])
perror("argh[4]");
if(!statxml)
perror("statxml");
if(!bufcmd)
perror("bufcmd");
strcpy(argh[0],"gg");
strcpy(argh[1],"-Tsvg");
strcpy(argh[2],"-o");
strcat(argh[2],configs->svgfile);
strcpy(argh[3],"-Nfontname=luximr");
strcpy(argh[4],"-s100");
#if DEBUG
printf("XXX -> argh[2]=%s\n",argh[2]);
#endif
/*
* Fetch the data in xml form out of the kernel
*/
if(strlen(configs->userhost)) {
#if DEBUG
printf("XXX: sizeof(argh[1]) = %i\n",sizeof(argh[1]));
#endif
snprintf(bufcmd,256 * sizeof(bufcmd)
,"ssh %s 'sysctl -b kern.geom.confxml' > %s"
,configs->userhost,configs->xmlfile);
#if DEBUG
printf("XXX: bufcmd %s\n",bufcmd);
#endif
ret = system(bufcmd);
if (ret)
perror("system");
} else {
len = sizeof(str);
ret = sysctlbyname("kern.geom.confxml",str,&len,NULL,0);
fpxml = fopen(configs->xmlfile,"w+");
if(fpxml == NULL){
printf("error in writting to %s\n",configs->xmlfile);
return 1;
}
fprintf(fpxml,"%s",str);
fclose(fpxml);
}
if(ret != 0){
printf("error in sysctl\n");
return 1;
}
fp = fopen(configs->dotfile,"w+");
if(fp == NULL){
printf("error in writting to %s\n",configs->dotfile);
return 1;
}
strcpy(buf,"");
strcpy(str,"");
fpxml = fopen(configs->xmlfile,"r");
ret = stat(configs->xmlfile,statxml);
if (ret)
perror(configs->xmlfile);
while(!feof(fpxml)) {
fgets(buf,BUFSIZE,fpxml);
if(!strlen(str))
snprintf(str,statxml->st_size,"%s",buf);
else
snprintf(str,statxml->st_size,"%s%s",str,buf);
}
fclose(fpxml);
//printf("XML: %s",str);
strcpy(dot,"");
if(geom_xml2dot(configs, dot, str) != 0 ) {
printf("error in geom_xml2dot\n");
}
fprintf(fp,"digraph geom {\n\n");
fprintf(fp,"%s",dot);
fprintf(fp,"};\n");
/*
* rewind the file pointer
*/
rewind(fp);
/*
* Do the actual graphing
*/
Agraph_t* g;
static GVC_t *gvc;
if (!gvc) gvc = gvContext();
gvParseArgs(gvc,argg,argh);
g = agread (fp);
gvLayout(gvc, g, &"dot");
gvRenderJobs(gvc, g);
fclose(fp);
gvFreeLayout(gvc, g);
/*
free(argh[0]);
free(argh[1]);
free(argh[2]);
free(argh[3]);
free(argh[4]);
*/
free(statxml);
free(bufcmd);
return 0;
}
/*
* doh quit
*/
void quit ()
{
gtk_exit (0);
}
/*
* Scale the picture and show it for the first or twentysencond time
*/
gint CheckVal(GtkScrolledWindow *win) {
GtkAdjustment *adj;
adj = gtk_scrolled_window_get_hadjustment((GtkScrolledWindow *)win);
printf("scrolledwin - lower %.2f ", adj->lower);
printf("upper %.2f ", adj->upper);
printf("value %.2f\n", adj->value);
free(adj);
return 0;
}
int scaleandshow(GtkWidget *window, struct myconfigs *configs, char *filename)
{
GdkPixbuf *pixbuf_scaled;
GdkPixbuf *pixbuf;
GError **error;
gint x;
gint y;
if (configs->scale < 1 )
configs->scale = 1;
if ( configs->scale > 5 )
configs->scale = 5;
#if DEBUG
printf("XXX scale = %i\n",configs->scale);
#endif
pixbuf = rsvg_pixbuf_from_file(filename, error);
if(pixbuf == NULL)
printf("error openning %s\n\n",filename);
x=gdk_pixbuf_get_width(pixbuf)/configs->scale;
y=gdk_pixbuf_get_height(pixbuf)/configs->scale;
#if DEBUG
printf("XXX -> x:%i y:%i\n",x,y);
#endif
pixbuf_scaled = gdk_pixbuf_scale_simple(pixbuf,x,y,GDK_INTERP_BILINEAR);
if(pixbuf_scaled == NULL) {
printf("error pixbuf_scaled\n\n");
exit(1);
}
if(configs->image == NULL) {
printf("error configs->image\n\n");
exit(2);
}
gtk_image_set_from_pixbuf(GTK_IMAGE(configs->image),pixbuf_scaled);
g_object_unref(pixbuf);
g_object_unref(pixbuf_scaled);
if(configs->scrolled == NULL)
printf("error configs->scrolled\n\n");
if(configs->image == NULL) {
printf("error configs->image\n\n");
exit(3);
}
if ( configs->first == 0)
{
gtk_scrolled_window_add_with_viewport((GtkScrolledWindow
*)configs->scrolled,GTK_WIDGET(configs->image));
configs->first = 1;
}
gtk_widget_queue_draw(configs->scrolled);
gtk_widget_queue_draw(window);
configs->hadjustment = gtk_scrolled_window_get_hadjustment(
(GtkScrolledWindow*)configs->scrolled);
configs->vadjustment = gtk_scrolled_window_get_vadjustment(
(GtkScrolledWindow*)configs->scrolled);
#if DEBUG
printf("XXX: hadjustment->lower: %.2f, hadjustment->upper: %.2f,hadjustment->value: %.2f\n", configs->hadjustment->lower,configs->hadjustment->upper,configs->hadjustment->value);
printf("XXX: vadjustment->lower: %.2f, vadjustment->upper: %.2f,vadjustment->value: %.2f\n", configs->vadjustment->lower,configs->vadjustment->upper,configs->vadjustment->value);
#endif
return 0;
}
/*
* Event for key presses
* Currently zZu
*/
gboolean keypressed(GtkWidget *window, GdkEventKey *event, gpointer data)
{
struct myconfigs *configs;
configs = (struct myconfigs *) data;
gdouble temp_adj;
#if DEBUG
printf("event->string = %s\n",event->string);
#endif
if ( !strcmp(event->string,"z")) {
configs->scale++;
scaleandshow(window,configs,configs->svgfile);
}
if ( !strcmp(event->string,"Z")) {
configs->scale--;
scaleandshow(window,configs,configs->svgfile);
}
if ( !strcmp(event->string,"u")) {
if ( lock_graph == 0 ) {
lock_graph = 1;
geom2svg(configs);
lock_graph = 0;
scaleandshow(window,configs,configs->svgfile);
} else
printf("lock_graph is not zero, graphviz is already running\n");
}
if ( !strcmp(event->string,"q")) {
quit();
}
if ( !strcmp(event->string,"c")) {
if ( configs->color == 0 ) {
configs->color = 1;
}
else {
configs->color = 0;
}
if ( lock_graph == 0 ) {
lock_graph = 1;
geom2svg(configs);
lock_graph = 0;
scaleandshow(window,configs,configs->svgfile);
} else
printf("lock_graph is not zero, graphviz is already running\n");
}
if ( !strcmp(event->string,"H")) {
if ( configs->human == 0 ) {
configs->human = 1;
}
else {
configs->human = 0;
}
if ( lock_graph == 0 ) {
lock_graph = 1;
geom2svg(configs);
lock_graph = 0;
scaleandshow(window,configs,configs->svgfile);
} else
printf("lock_graph is not zero, graphviz is already running\n");
}
if ( !strcmp(event->string,"h") || event->hardware_keycode == 100) {
configs->hadjustment = gtk_scrolled_window_get_hadjustment(
(GtkScrolledWindow*)configs->scrolled);
configs->hadjustment->value = configs->hadjustment->value
- configs->hadjustment->step_increment;
if ( configs->hadjustment->value < configs->hadjustment->lower)
configs->hadjustment->value = configs->hadjustment->lower;
if ( configs->hadjustment->value > configs->hadjustment->upper)
configs->hadjustment->value = configs->hadjustment->upper;
//configs->hadjustment->value = temp_adj;
gtk_scrolled_window_set_hadjustment((GtkScrolledWindow*)configs->scrolled,
configs->hadjustment);
gtk_adjustment_value_changed(configs->hadjustment);
#if DEBUG
printf("XXXh: hadjustment->lower: %.2f, hadjustment->upper: %.2f,hadjustment->value: %.2f\n", configs->hadjustment->lower,configs->hadjustment->upper,configs->hadjustment->value);
#endif
}
if ( !strcmp(event->string,"j") || event->hardware_keycode == 98) {
configs->vadjustment = gtk_scrolled_window_get_vadjustment(
(GtkScrolledWindow*)configs->scrolled);
temp_adj = configs->vadjustment->value
- configs->vadjustment->step_increment;
if ( temp_adj >= configs->vadjustment->lower &&
temp_adj <= configs->vadjustment->upper) {
configs->vadjustment->value = temp_adj;
gtk_scrolled_window_set_vadjustment((GtkScrolledWindow*)configs->scrolled,
configs->vadjustment);
gtk_adjustment_value_changed(configs->vadjustment);
#if DEBUG
printf("XXXj: vadjustment->lower: %.2f, vadjustment->upper: %.2f,vadjustment->value: %.2f\n", configs->vadjustment->lower,configs->vadjustment->upper,configs->vadjustment->value);
#endif
}
}
if ( !strcmp(event->string,"k") || event->hardware_keycode == 104) {
configs->vadjustment = gtk_scrolled_window_get_vadjustment(
(GtkScrolledWindow*)configs->scrolled);
configs->vadjustment->value += configs->vadjustment->step_increment;
if ( configs->vadjustment->value < configs->vadjustment->lower) {
configs->vadjustment->value = configs->vadjustment->lower;
}
if ( (configs->vadjustment->value+configs->vadjustment->page_size) > configs->vadjustment->upper) {
configs->vadjustment->value = configs->vadjustment->upper - configs->vadjustment->page_size;
}
gtk_scrolled_window_set_vadjustment((GtkScrolledWindow*)configs->scrolled,
configs->vadjustment);
gtk_adjustment_value_changed(configs->vadjustment);
#if DEBUG
printf("XXXk: vadjustment->lower: %.2f, vadjustment->upper: %.2f,vadjustment->value: %.2f\n", configs->vadjustment->lower,configs->vadjustment->upper,configs->vadjustment->value);
#endif
}
if ( !strcmp(event->string,"l") || event->hardware_keycode == 102) {
configs->hadjustment = gtk_scrolled_window_get_hadjustment(
(GtkScrolledWindow*)configs->scrolled);
configs->hadjustment->value = configs->hadjustment->value
+ configs->hadjustment->step_increment;
if ( configs->hadjustment->value < configs->hadjustment->lower)
configs->hadjustment->value = configs->hadjustment->lower;
if ( (configs->hadjustment->value+configs->hadjustment->page_size) > configs->hadjustment->upper)
configs->hadjustment->value = configs->hadjustment->upper - configs->hadjustment->page_size;
gtk_scrolled_window_set_hadjustment((GtkScrolledWindow*)configs->scrolled,
configs->hadjustment);
gtk_adjustment_value_changed(configs->hadjustment);
#if DEBUG
printf("XXXl: hadjustment->lower: %.2f, hadjustment->upper: %.2f,hadjustment->value: %.2f\n", configs->hadjustment->lower,configs->hadjustment->upper,configs->hadjustment->value);
#endif
}
return TRUE;
}
int main(int argc, char *argv[])
{
GtkWidget *window;
//GtkWidget *scrolled;
struct myconfigs *configs;
GdkFont *font = NULL;
char xmlfile[] = "/tmp/geomgui.xml-XXXX";
char dotfile[] = "/tmp/geomgui.dot-XXXX";
char svgfile[] = "/tmp/geomgui.svg-XXXX";
mkstemp(xmlfile);
mkstemp(dotfile);
mkstemp(svgfile);
printf("files used in this go around:\n");
printf("xml file: %s\n",xmlfile);
printf("dot file: %s\n",dotfile);
printf("svg file: %s\n\n",svgfile);
configs=malloc(sizeof(struct myconfigs));
if(!configs)
perror("configs");
configs->xmlfile = xmlfile;
configs->dotfile = dotfile;
configs->svgfile = svgfile;
configs->human = 0;
configs->color = 0;
int ch;
configs->userhost = "";
while ((ch = getopt(argc, argv, "vhcr:")) != -1) {
switch(ch) {
case 'a':
break;
case 'c':
configs->color = 1;
break;
case 'h':
configs->human = 1;
break;
case 'v':
usage();
exit(0);
break;
case 'r':
configs->userhost = optarg;
break;
default:
usage();
exit(0);
}
}
/*
#if DEBUG
if ( configs->userhost )
printf("userhost: %s",configs->userhost);
#endif
*/
lock_graph=1;
geom2svg(configs);
lock_graph=0;
configs->scale = 2;
configs->first = 0;
/*
* Show what we got
*/
gtk_init(&argc, &argv);
font = gdk_fontset_load("-*-courier-*-*-*-*-*-*-*-*-*-*-*-*");
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_widget_set_name(window, "geomgui");
gtk_window_set_default_size(GTK_WINDOW(window),800,600);
configs->scrolled = gtk_scrolled_window_new(NULL, NULL);
configs->image = GTK_IMAGE(gtk_image_new());
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (configs->scrolled),
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_container_add(GTK_CONTAINER(window), configs->scrolled);
g_signal_connect(G_OBJECT (window), "destroy",
G_CALLBACK (quit), NULL);
scaleandshow(window,configs,configs->svgfile);
g_signal_connect (G_OBJECT (window),"key-press-event",
G_CALLBACK (keypressed), configs);
gtk_widget_show_all(window);
gtk_main ();
/*
* This has to be at the bottom cause it terminates the program
*/
return 0;
}
/*
* The end no more
*/
syntax highlighted by Code2HTML, v. 0.9.1