/* * $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 */ /* * This program leaves behind two files in /tmp * conf.dot, conf.xml and conf.svg */ #include #include #include #include #include #include #include #include #include #include #include #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 */