1
/* $Id: viewport.c,v 1.4 2008/03/04 17:54:51 arif Exp $ $Revision: 1.4 $ */
2
/* vim:set shiftwidth=4 ts=8: */
4
/**********************************************************
5
* This software is part of the graphviz package *
6
* http://www.graphviz.org/ *
8
* Copyright (c) 1994-2004 AT&T Corp. *
9
* and is licensed under the *
10
* Common Public License, Version 1.0 *
13
* Information and Software Systems Research *
14
* AT&T Research, Florham Park NJ *
15
**********************************************************/
24
#include <glade/glade.h>
28
#include "gltemplate.h"
29
#include "colorprocs.h"
32
#define countof( array ) ( sizeof( array )/sizeof( array[0] ) )
35
/*these two global variables should be wrapped in somethign else*/
36
GtkMessageDialog* Dlg;
39
void clear_viewport(ViewInfo* view)
42
/*free topview if there is one*/
45
cleartopview(view->Topview);
46
/*all cgraph graphs should be freed*/
47
for (ind=0;ind < view->graphCount;ind ++)
49
agclose(view->g[ind]);
55
void init_viewport(ViewInfo* view)
59
view->g=NULL; //no graph, gl screen should check it
60
view->graphCount=0; //and disable interactivity if count is zero
70
view->borderColor.R=1;
71
view->borderColor.G=0;
72
view->borderColor.B=0;
73
view->borderColor.A=1;
75
view->bdVisible=1; //show borders red
78
view->gridColor.R=0.5;
79
view->gridColor.G=0.5;
80
view->gridColor.B=0.5;
82
view->gridVisible=0; //show grids in light gray
85
view->mouse.mouse_mode=0;
96
//background color , default white
102
//selected objets are drawn with this color
103
view->selectColor.R=1;
104
view->selectColor.G=0;
105
view->selectColor.B=0;
106
view->selectColor.A=1;
108
//default line width;
111
//default view settings , camera is not active
112
view->GLDepth=1; //should be set before GetFixedOGLPos(int x, int y,float kts) funtion is used!!!!
125
view->topviewusermode =TOP_VIEW_USER_NOVICE_MODE; //for demo
129
view->mg.width=DEFAULT_MAGNIFIER_WIDTH;
130
view->mg.height=DEFAULT_MAGNIFIER_HEIGHT;
131
view->mg.kts=DEFAULT_MAGNIFIER_KTS;
132
view->fmg.R=DEFAULT_FISHEYE_MAGNIFIER_RADIUS;
134
view->mouse.mouse_down=0;
135
view->activeGraph=-1;
137
view->Selection.Active=0;
138
view->Selection.SelectionColor.R=0.5;
139
view->Selection.SelectionColor.G=(float)0.2;
140
view->Selection.SelectionColor.B=1;
141
view->Selection.SelectionColor.A=1;
142
view->Selection.Anti=0;
143
view->Topview=malloc(sizeof(topview));
146
int add_graph_to_viewport_from_file (char* fileName)
148
//returns 1 if successfull else 0
150
graph=loadGraph(fileName);
153
view->graphCount = view->graphCount + 1;
154
view->g= (Agraph_t**)realloc(view->g,sizeof(Agraph_t*)*view->graphCount);
155
view->g[view->graphCount-1]=graph;
156
view->activeGraph=view->graphCount-1;
157
//GUI update , graph combo box on top-right should be updated
158
refreshControls(view);
166
int add_new_graph_to_viewport()
168
//returns graph index , otherwise -1
170
graph=(Agraph_t*) malloc(sizeof(Agraph_t));
173
view->graphCount = view->graphCount + 1;
174
view->g[view->graphCount-1]=graph;
175
return (view->graphCount-1);
182
void refreshControls(ViewInfo* v)
187
widget=get_SelectGraph();
188
//load graph names to combobox
189
for (i=0; i < v->graphCount; i ++)
191
gtk_combo_box_append_text(widget,((custom_graph_data*)(AGDATA(v->g[i])))->GraphFileName);
193
view->SignalBlock=1; //HACK
194
gtk_combo_box_set_active (widget,view->activeGraph);
198
//change button colors
199
Color_Widget_bg ("gray",glade_xml_get_widget(xml, "btnDot"));
200
Color_Widget_bg ("gray",glade_xml_get_widget(xml, "btnNeato"));
201
Color_Widget_bg ("gray",glade_xml_get_widget(xml, "btnTwopi"));
202
Color_Widget_bg ("gray",glade_xml_get_widget(xml, "btnCirco"));
203
Color_Widget_bg ("gray",glade_xml_get_widget(xml, "btnFdp"));
206
switch( ((custom_graph_data*)(AGDATA(view->g[view->activeGraph])))->Engine )
209
Color_Widget_bg ("red",glade_xml_get_widget(xml, "btnDot"));
213
Color_Widget_bg ("red",glade_xml_get_widget(xml, "btnNeato"));
217
Color_Widget_bg ("red",glade_xml_get_widget(xml, "btnTwopi"));
221
Color_Widget_bg ("red",glade_xml_get_widget(xml, "btnCirco"));
225
Color_Widget_bg ("red",glade_xml_get_widget(xml, "btnFdp"));
239
void update_graph_params(Agraph_t* graph) //adds gledit params
243
char tempString[100];
244
agattr(graph,AGRAPH,"GraphFileName",((custom_graph_data*)(AGDATA(graph)))->GraphFileName);
245
agattr(graph,AGRAPH,"GraphName",((custom_graph_data*)(AGDATA(graph)))->GraphName);
246
sprintf( tempString, "%i", ((custom_graph_data*)(AGDATA(graph)))->AlwaysShow );
247
agattr(graph,AGRAPH,"AlwaysShow",tempString);
248
sprintf( tempString, "%i", ((custom_graph_data*)(AGDATA(graph)))->TopView);
249
agattr(graph,AGRAPH,"TopView",tempString);
250
sprintf( tempString, "%i", ((custom_graph_data*)(AGDATA(graph)))->Locked);
251
agattr(graph,AGRAPH,"Locked",tempString);
252
sprintf( tempString, "%i", ((custom_graph_data*)(AGDATA(graph)))->Engine);
253
agattr(graph,AGRAPH,"Engine",tempString);
257
void load_graph_params(Agraph_t* graph) //run once right after loading graph
259
//file may or may have not gl edit attributes
260
//first defaults are set in loading function
261
//here file is checked for previously saved gledit attributes
262
if(agget(graph, "GraphName")) //Graph Name
264
((custom_graph_data*)AGDATA(graph))->GraphName=(char*)malloc((strlen(agget(graph, "GraphName"))+1)*sizeof(char));
265
strcpy(((custom_graph_data*)AGDATA(graph))->GraphName,agget(graph, "GraphName"));
267
if(agget(graph, "AlwaysShow")) //Graph Name
268
((custom_graph_data*)AGDATA(graph))->AlwaysShow=atoi(agget(graph, "AlwaysShow"));
270
((custom_graph_data*)AGDATA(graph))->AlwaysShow=0;
272
if(agget(graph, "TopView")) //Graph Name
273
((custom_graph_data*)AGDATA(graph))->TopView=atoi(agget(graph, "TopView"));
275
((custom_graph_data*)AGDATA(graph))->TopView=0;
276
if(agget(graph, "Locked")) //Graph Name
277
((custom_graph_data*)AGDATA(graph))->Locked=atoi(agget(graph, "Locked"));
279
((custom_graph_data*)AGDATA(graph))->Locked=0;
280
if(agget(graph, "Engine")) //Graph Name
281
((custom_graph_data*)AGDATA(graph))->Engine=atoi(agget(graph, "Engine"));
283
((custom_graph_data*)AGDATA(graph))->Engine=0; //DOT
285
((custom_graph_data*)AGDATA(graph))->Modified=0; //not modified yet
286
((custom_graph_data*)AGDATA(graph))->selectedEdges='\0';
287
((custom_graph_data*)AGDATA(graph))->selectedNodes='\0';
288
((custom_graph_data*)AGDATA(graph))->selectedGraphs='\0';
290
((custom_graph_data*)AGDATA(graph))->selectedNodesCount=0;
291
((custom_graph_data*)AGDATA(graph))->selectedEdgesCount=0;
292
((custom_graph_data*)AGDATA(graph))->selectedGraphsCount=0;
296
/* if(agget((void*)g, "xdotversion")) //xdot exists
297
((custom_graph_data*)AGDATA(g))->view->Topview=0; //need to check xdot version attribute
298
else //we dont know if it is view->Topview or simply a graph with no xdot, for testing i ll use view->Topview
299
((custom_graph_data*)AGDATA(g))->view->Topview=1; */
307
int save_graph() //save without prompt
309
//check if there is an active graph
310
if(view->activeGraph > -1)
312
//check if active graph has a file name
313
if (((custom_graph_data*)AGDATA(view->g[view->activeGraph]))->GraphFileName)
315
return save_graph_with_file_name(view->g[view->activeGraph],((custom_graph_data*)AGDATA(view->g[view->activeGraph]))->GraphFileName);
318
return save_as_graph();
323
int save_as_graph() //save with prompt
325
//check if there is an active graph
326
if(view->activeGraph > -1)
329
dialog = gtk_file_chooser_dialog_new ("Save File",
331
GTK_FILE_CHOOSER_ACTION_SAVE,
332
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
333
GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
335
gtk_file_chooser_set_do_overwrite_confirmation (GTK_FILE_CHOOSER (dialog), TRUE);
336
if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
339
filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
340
save_graph_with_file_name(view->g[view->activeGraph],filename);
342
gtk_widget_destroy (dialog);
348
gtk_widget_destroy (dialog);
354
int save_graph_with_file_name(Agraph_t* graph,char* fileName) //saves graph with file name,if file name is NULL save as is ++
356
//if file name is NULL save to graph's filename
357
//else use file name, this implements save as..
359
update_graph_params(graph);
361
output_file = fopen(fileName, "w");
364
if ( ((custom_graph_data*)(AGDATA(graph)))->GraphFileName )
365
output_file = fopen(((custom_graph_data*)(AGDATA(graph)))->GraphFileName, "w");
368
g_print("there is no file name to save! Programmer error\n");
372
if (output_file == NULL)
374
g_print("Cannot create file \n");
377
else if (agwrite(graph,(void*) output_file))
379
g_print("%s sucessfully saved \n", fileName);
385
int create_xdot_for_graph(Agraph_t* graph,int keeppos)
387
//0 failed , 1 successfull
388
//save graph to __temp.dot
389
//run dot/neato whatever to create the xdot version __temp.xdot
391
//use this function to do layouts too
394
update_graph_params(graph);
396
if(output_file = fopen("c:/__tempfile.dot", "w"))
398
if(output_file = fopen("/tmp/__tempfile.dot", "w"))
401
clear_graph_xdot(graph);
402
agwrite(graph,(void*) output_file); //save graph
403
fclose(output_file);//close file desc
408
if ( ((custom_graph_data*)AGDATA(graph))->Engine == 0)
409
system("\"C:/Program Files/Graphviz2.15/bin/dot.exe\" -Txdot -Kdot c:/__tempfile.dot -oc:/__tempfile.xdot");
410
if ( ((custom_graph_data*)AGDATA(graph))->Engine == 1)
411
system("\"C:/Program Files/Graphviz2.15/bin/dot.exe\" -Txdot -Kneato c:/__tempfile.dot -oc:/__tempfile.xdot");
412
if ( ((custom_graph_data*)AGDATA(graph))->Engine == 2)
413
system("\"C:/Program Files/Graphviz2.15/bin/dot.exe\" -Txdot -Ktwopi c:/__tempfile.dot -oc:/__tempfile.xdot");
414
if ( ((custom_graph_data*)AGDATA(graph))->Engine == 3)
415
system("\"C:/Program Files/Graphviz2.15/bin/dot.exe\" -Txdot -Kcirco c:/__tempfile.dot -oc:/__tempfile.xdot");
416
if ( ((custom_graph_data*)AGDATA(graph))->Engine == 4)
417
system("\"C:/Program Files/Graphviz2.15/bin/dot.exe\" -Txdot -Kfdp c:/__tempfile.dot -oc:/__tempfile.xdot");
419
if ( ((custom_graph_data*)AGDATA(graph))->Engine == 0)
420
system("\"dot\" -Txdot -Kdot /tmp/__tempfile.dot -o/tmp/__tempfile.xdot");
421
if ( ((custom_graph_data*)AGDATA(graph))->Engine == 1)
422
system("\"dot\" -Txdot -Kneato /tmp/__tempfile.dot -o/tmp/__tempfile.xdot");
423
if ( ((custom_graph_data*)AGDATA(graph))->Engine == 2)
424
system("\"dot\" -Txdot -Ktwopi /tmp/__tempfile.dot -o/tmp/__tempfile.xdot");
425
if ( ((custom_graph_data*)AGDATA(graph))->Engine == 3)
426
system("\"dot\" -Txdot -Kcirco /tmp/__tempfile.dot -o/tmp/__tempfile.xdot");
427
if ( ((custom_graph_data*)AGDATA(graph))->Engine == 4)
428
system("\"dot\" -Txdot -Kfdp /tmp/__tempfile.dot -o/tmp/__tempfile.xdot");
435
system("\"C:/Program Files/Graphviz2.15/bin/neato.exe\" -n2 -Txdot c:/__tempfile.dot -oc:/__tempfile.xdot");
437
system("\"neato\" -n2 -Txdot /tmp/__tempfile.dot -o/tmp/__tempfile.xdot");
440
if(r) //load the new graph and change file name
442
clear_graph(graph); //i am not sure about this, need to talk to North
453
int do_graph_layout(Agraph_t* graph,int Engine,int keeppos) //changes the layout, all user relocations are reset unless keeppos is set to 1
462
char* _filename=(char*)malloc((strlen(((custom_graph_data*)(AGDATA(view->g[view->activeGraph])))->GraphFileName)+1)*sizeof(char));
463
strcpy(_filename,((custom_graph_data*)AGDATA(view->g[view->activeGraph]))->GraphFileName);
466
((custom_graph_data*)AGDATA(view->g[view->activeGraph]))->Engine=Engine;
467
create_xdot_for_graph(view->g[view->activeGraph],keeppos);
470
input_file = fopen("c:/__tempfile.xdot", "r");
472
input_file = fopen("/tmp/__tempfile.xdot", "r");
474
clear_graph(view->g[view->activeGraph]);
475
agclose(view->g[view->activeGraph]);
476
if (input_file == NULL)
477
g_print("temp file Cannot open n");
478
else if (view->g[view->activeGraph]= agread(input_file,NIL(Agdisc_t*)))
481
//attaching rec for graph fields
482
attach_object_custom_data_to_graph(view->g[view->activeGraph]);
484
((custom_graph_data*)AGDATA(view->g[view->activeGraph]))->GraphFileName=(char*)malloc((strlen(_filename)+1)*sizeof(char));
485
load_graph_params(view->g[view->activeGraph]); //init glparams
486
strcpy(((custom_graph_data*)AGDATA(view->g[view->activeGraph]))->GraphFileName,_filename);
489
((custom_graph_data*)AGDATA(view->g[view->activeGraph]))->Engine=Engine;
490
((custom_graph_data*)AGDATA(view->g[view->activeGraph]))->Modified=1;
491
refreshControls(view);
504
void clear_graph(Agraph_t* graph)
505
//clears custom data binded
511
Agraph_t* loadGraph(char* filename)
516
input_file = fopen(filename, "r");
517
if (input_file == NULL)
518
g_print("Cannot open %s\n", filename);
519
else if (g = agread(input_file,NIL(Agdisc_t*)))
521
attach_object_custom_data_to_graph(g);
522
load_graph_params(g);
525
( !agget(g, "xdotversion"))
528
( agget(g, "TopView")=="0")
536
create_xdot_for_graph(g,0);
539
input_file = fopen("c:/__tempfile.xdot", "r");
541
input_file = fopen("/tmp/__tempfile.xdot", "r");
543
while(input_file== NULL) //HACK!!!!
545
input_file = fopen("c:/__tempfile.xdot", "r");
546
// g_print("Cannot open xdot error %si\n",strerror(errno));
549
g = agread(input_file,NIL(Agdisc_t*));
550
g_print("xdot is being loaded\n");
551
//attaching rec for graph fields
552
attach_object_custom_data_to_graph(g);
553
load_graph_params(g);
554
// fclose(input_file);
556
((custom_graph_data*)AGDATA(g))->GraphFileName=(char*)malloc((strlen(filename)+1)*sizeof(char));
557
//attaching rec for graph objects
558
strcpy(((custom_graph_data*)AGDATA(g))->GraphFileName,filename);
559
/*if(strcasecmp(agget(g, "TopView"),"1")==0)
562
TopviewNodeCount > 0)
564
Dlg=gtk_message_dialog_new (NULL,
568
"For Performance issues , this program does not support multiple Topview graphs!");
569
respond=gtk_dialog_run (Dlg);
570
gtk_object_destroy (Dlg);
577
preparetopview(g,view->Topview);
586
int clear_object_xdot(void* obj)
590
if(agattrsym(obj,"_draw_"))
591
agset(obj,"_draw_","");
592
if(agattrsym(obj,"_ldraw_"))
593
agset(obj,"_ldraw_","");
594
if(agattrsym(obj,"_hdraw_"))
595
agset(obj,"_hdraw_","");
596
if(agattrsym(obj,"_tdraw_"))
597
agset(obj,"_tdraw_","");
598
if(agattrsym(obj,"_hldraw_"))
599
agset(obj,"_hldraw_","");
600
if(agattrsym(obj,"_tldraw_"))
601
agset(obj,"_tldraw_","");
608
int clear_graph_xdot(Agraph_t* graph) //clears all xdot attributes, used especially before layout change
615
clear_object_xdot(graph);
616
n = agfstnode(graph);
618
for (s = agfstsubg(graph); s; s = agnxtsubg(s))
619
clear_object_xdot(s);
621
for (n = agfstnode(graph); n; n = agnxtnode(graph, n))
623
clear_object_xdot(n);
624
for (e = agfstout(graph,n) ; e ; e = agnxtout (graph,e))
626
clear_object_xdot(e);
636
Object Custom Data Functions
641
int attach_object_custom_data_to_graph(Agraph_t* graph)
647
agbindrec(graph,"custom_graph_data",sizeof(custom_graph_data),TRUE);//graph custom data
648
init_object_custom_data(graph,graph); //attach to graph itself
650
n = agfstnode(graph);
652
for (s = agfstsubg(graph); s; s = agnxtsubg(s))
653
init_object_custom_data(graph,s); //attach to subgraph
655
for (n = agfstnode(graph); n; n = agnxtnode(graph, n))
657
init_object_custom_data(graph,n); //attach to node
658
for (e = agfstout(graph,n) ; e ; e = agnxtout (graph,e))
660
init_object_custom_data(graph,e); //attach to edge
668
int init_object_custom_data(Agraph_t* graph,void* obj)//creates a custom_object_data
670
agdelrec(graph, "custom_object_data");
671
agbindrec(obj,"custom_object_data",sizeof(custom_object_data),TRUE);
672
((custom_object_data*)AGDATA(obj))->ID=0;
673
((custom_object_data*)AGDATA(obj))->ObjName=NULL;
674
((custom_object_data*)AGDATA(obj))->ObjType=AGTYPE(obj);
675
((custom_object_data*)AGDATA(obj))->Layer=-1;
676
((custom_object_data*)AGDATA(obj))->Visible=1;
677
((custom_object_data*)AGDATA(obj))->Locked=0;
678
((custom_object_data*)AGDATA(obj))->Highlighted=0;
679
((custom_object_data*)AGDATA(obj))->NumDataCount=0;
680
((custom_object_data*)AGDATA(obj))->NumData=NULL;
681
((custom_object_data*)AGDATA(obj))->StrDataCount=0;
682
((custom_object_data*)AGDATA(obj))->StrData=NULL;
687
int clear_object_custom_data(void* obj) //frees memory allocated for cutom object data
689
return ( (clear_string_data_from_object_custom_data(obj)) || (clear_numeric_data_from_object_custom_data(obj)));
692
int add_string_data_to_object_custom_data(void* obj,char* data)
694
if ((obj != NULL) && (data !=NULL))
696
((custom_object_data*)AGDATA(obj))->StrData=realloc( ((custom_object_data*)AGDATA(obj))->StrData , sizeof(char*)*(((custom_object_data*)AGDATA(obj))->StrDataCount +1));
697
((custom_object_data*)AGDATA(obj))->StrData[((custom_object_data*)AGDATA(obj))->StrDataCount]=malloc((strlen(data)+1) * sizeof(char));
698
strcpy(((custom_object_data*)AGDATA(obj))->StrData[((custom_object_data*)AGDATA(obj))->StrDataCount],data);
699
((custom_object_data*)AGDATA(obj))->StrDataCount++;
705
int add_numeric_data_to_object_custom_data(void* obj,float data)
709
((custom_object_data*)AGDATA(obj))->NumData=realloc( ((custom_object_data*)AGDATA(obj))->StrData , sizeof(char*)*(((custom_object_data*)AGDATA(obj))->NumDataCount+1));
710
((custom_object_data*)AGDATA(obj))->NumData[((custom_object_data*)AGDATA(obj))->NumDataCount]=data;
711
((custom_object_data*)AGDATA(obj))->NumDataCount++;
717
int clear_string_data_from_object_custom_data(void* obj)
722
for (ind=0; ind < ((custom_object_data*)AGDATA(obj))->StrDataCount;ind ++)
724
free ( ((custom_object_data*)AGDATA(obj))->StrData[ind]);
726
free(((custom_object_data*)AGDATA(obj))->StrData);
732
int clear_numeric_data_from_object_custom_data(void* obj)
736
free(((custom_object_data*)AGDATA(obj))->NumData);
741
void move_node(void* obj,float dx,float dy)
748
if( (agget(obj,"pos")) && ( AGTYPE(obj)==AGNODE ))
751
strcpy(buf,agget(obj, "pos"));
753
pch=strtok (buf,"," );
757
a=sprintf(buf2+a,"%i,",atoi(pch)-(int)dx);
759
a=sprintf(buf2+a,"%i,",atoi(pch)-(int)dy);
760
pch=strtok (NULL,"," );
763
buf2[strlen(buf2)-1]='\0';
764
agset(obj,"pos",buf2);
768
void move_nodes(Agraph_t* g) //move selected nodes
775
dx=view->GLx-view->GLx2;
776
dy=view->GLy-view->GLy2;
778
if(((custom_graph_data*)AGDATA(view->g[view->activeGraph]))->TopView == 0)
780
for (i=0;i < ((custom_graph_data*)AGDATA(g))->selectedNodesCount;i++)
782
obj=((custom_graph_data*)AGDATA(g))->selectedNodes[i];
783
bf=parseXDot (agget(obj,"_draw_"));
784
agset(obj,"_draw_",move_xdot(obj,bf,(int)dx,(int)dy,0));
786
bf=parseXDot (agget(obj,"_ldraw_"));
787
agset(obj,"_ldraw_",move_xdot(obj,bf,(int)dx,(int)dy,0));
789
move_node(obj,dx,dy);
791
/*for (e = agfstout(g,obj) ; e ; e = agnxtout (g,e))
793
bf=parseXDot (agget(e,"_tdraw_"));
794
agset(e,"_tdraw_",move_xdot(e,bf,(int)dx,(int)dy,0.00));
796
bf=parseXDot (agget(e,"_tldraw_"));
797
agset(e,"_tldraw_",move_xdot(e,bf,(int)dx,(int)dy,0.00));
799
bf=parseXDot (agget(e,"_draw_"));
800
agset(e,"_draw_",offset_spline(bf,(int)dx,(int)dy,0.00,0.00,0.00));
802
bf=parseXDot (agget(e,"_ldraw_"));
803
agset(e,"_ldraw_",offset_spline(bf,(int)dx,(int)dy,0.00,0.00,0.00));
806
/* for (e = agfstin(g,obj) ; e ; e = agnxtin (g,e))
809
bf=parseXDot (agget(e,"_hdraw_"));
810
agset(e,"_hdraw_",move_xdot(e,bf,(int)dx,(int)dy,0.00));
812
bf=parseXDot (agget(e,"_hldraw_"));
813
agset(e,"_hldraw_",move_xdot(e,bf,(int)dx,(int)dy,0.00));
815
bf=parseXDot (agget(e,"_draw_"));
816
agset(e,"_draw_",offset_spline(e,bf,(int)dx,(int)dy,0.00,0.00,0.00));
818
bf=parseXDot (agget(e,"_ldraw_"));
819
agset(e,"_ldraw_",offset_spline(e,bf,(int)dx,(int)dy,0.00,0.00,0.00));
828
int SetGdkColor(GdkColor* c,char* color)
833
colorxlate(color, &cl, RGBA_DOUBLE);
834
c->red=(int)(cl.u.RGBA[0]*65535.0);
835
c->green=(int)(cl.u.RGBA[1]*65535.0);
836
c->blue=(int)(cl.u.RGBA[2]*65535.0);
846
expose_event (view->drawing_area,NULL,NULL);