bd83bd725e4332f6d30e35670d56ee60785f7a4f
[scilab.git] / scilab / modules / scicos / macros / scicos_scicos / getlink.sci
1 //  Scicos
2 //
3 //  Copyright (C) INRIA - METALAU Project <scicos@inria.fr>
4 //                      - Alan Layec <alan.layec@inria.fr>
5 //                      - Simone Mannori <simone.mannori@scilab.org>
6 // //
7 // This program is free software; you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by
9 // the Free Software Foundation; either version 2 of the License, or
10 // (at your option) any later version.
11 //
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 // GNU General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 //
21 // See the file ../license.txt
22 //
23
24 function [scs_m, needcompile] = getlink(%pt, scs_m, needcompile,smart)
25 //** Edition of a link from an output block to an input  block
26
27 //** 28/11/08: Preparation of the "SL" operation
28 //** 24/07/07: Al@n's patch for rotation of blocks
29
30 //** N.B : Please set %scicos_debug_gr="%t" to activate the debug mode 
31 //** BEWARE: "d9" state is not yet tested after Replot removal
32   if argn(2)<4 then smart=%f,end
33   
34   outin = ['out','in']
35   //----------- get link origin --------------------------------------
36   //------------------------------------------------------------------
37   win = %win;
38   xc1 = %pt(1);
39   yc1 = %pt(2);
40
41   [kfrom, wh] = getblocklink(scs_m,[xc1;yc1]); //** recover information 
42                                                //** about the starting point
43   //** kfrom is the id of the selected block or link 
44
45   if kfrom<>[] then //** check for the presence of a valid output 
46     o1 = scs_m.objs(kfrom) ; //** acquire the object 
47   else
48     return ; //** EXIT if no valid output is found 
49   end
50
51  
52   scs_m_save = scs_m;
53   nc_save    = needcompile; 
54
55   //** new graphics
56   gh_curwin = scf(%win) ;
57   gh_axes = gca();        //** acquire the current window handler
58
59
60   if typeof(o1)=="Link" then  //** add a split block
61     //** ------------------- start from a LINK ------------------------------
62     pt = [xc1;yc1] ; 
63     [xx,yy,ct,from,to] = (o1.xx,o1.yy,o1.ct,o1.from,o1.to);
64     if (-wh==size(xx,'*')) then
65       wh = -(wh+1) //** avoid with clicking at the end-point of link
66     end
67
68     //** get split type
69     [xout,yout,typout] = getoutputports(scs_m.objs(from(1))); 
70     clr = ct(1); 
71     [m,kp1] = mini((yc1-yout)^2+(xc1-xout)^2); 
72     k = kp1 ; 
73     typo = ct(2) ; 
74
75     if typo==-1 then //** old link comes from an event output port
76       typp = "evtout"
77     else //** old link comes from an regular output or input (implicit) port
78       typp = outin(from(3)+1)
79     end
80
81     //** get port size
82     szout = getportsiz(scs_m.objs(from(1)),from(2),typp)
83     //** get port data type
84     if typp=='out'|typp=='in' then
85      szouttyp = getporttyp(scs_m.objs(from(1)),from(2),typp)
86     end
87
88     //** get initial split position
89     wh = wh(1)
90     if wh>0 then
91       d = projaff(xx(wh:wh+1), yy(wh:wh+1),pt)
92     else //** a corner
93       wh = -wh ;
94       d  = [xx(wh);yy(wh)] ;
95     end
96     // Note : creation of the split block and modifications of links are
97     //        done later, the sequel assumes that the split block is added
98     //        at the end of scs_m
99     ks = kfrom; // selected link number
100     kfrom = size(scs_m.objs)+1;
101     port_number = 2; // to be created split block number
102
103     fromsplit = %t; 
104     // to be created link from origin
105
106     from = [kfrom,port_number,0] 
107     xo = d(1);yo=d(2)
108     xl = d(1);yl=d(2)
109
110   else // connection comes from a block
111     //** ------------------- start from a BLOCK ------------------------------
112     graphics1 = o1.graphics
113     orig  = graphics1.orig
114     sz    = graphics1.sz
115     theta = graphics1.theta
116     io    = graphics1.flip
117     op    = graphics1.pout
118     impi  = graphics1.pin
119     cop   = graphics1.peout
120     [xout,yout,typout] = getoutputports(o1)
121
122     i_ImplIndx = find(graphics1.in_implicit=='I');
123
124     if xout==[] then
125         hilite_obj(kfrom);
126         message("This block has no output port"); 
127         unhilite_obj(kfrom);
128       return ; //** EXIT 
129     end
130
131     //** geometrical conversion for rotated block 
132     xxx = rotate([xout;yout],...
133                  theta*%pi/180,...
134                  [orig(1)+sz(1)/2; orig(2)+sz(2)/2]);
135     xout= xxx(1,:);
136     yout= xxx(2,:);
137
138     [m,kp1] = mini((yc1-yout)^2+(xc1-xout)^2) ; 
139     k = kp1 ; 
140     xo = xout(k); yo = yout(k); 
141     typo = typout(k) ; 
142
143     //** ---------------------- Checking ------------------------------------------- 
144     //** Check if the new requested link creation is compatible with the diagram 
145     // Check if selected port is already connected and get port type ('in' or 'out')
146
147     if typo==1  then // regular output port
148       port_number = k ;
149       if op(port_number)<>0 then
150           hilite_obj(kfrom)
151            message(["Selected port is already connected.";..
152                     "To start a link off another link, place the cursor";..
153                     "on the split point and double click, or type l."])
154           unhilite_obj(kfrom); 
155         return
156       end
157       typpfrom='out'
158     elseif (typo==2 & k<=size(op,'*')) then // implicit  output port
159       port_number = k ; 
160       if op(port_number)<>0 then
161           hilite_obj(kfrom);
162           message(["Selected port is already connected.";..
163                    "To start a link off another link, place the cursor";..
164                    "on the split point and double click, or type l."])
165           unhilite_obj(kfrom); 
166         return
167       end
168       typpfrom='out'
169     elseif (typo==2 & k>size(op,'*')+size(cop,'*')) then // implicit  input port
170       typpfrom = 'in' ; 
171       k = k-size(op,'*')-size(cop,'*'); 
172       port_number = i_ImplIndx(k)
173       if impi(port_number)<>0 then
174           hilite_obj(kfrom) ; 
175           message(["Selected port is already connected.";..
176                    "To start a link off another link, place the cursor";..
177                    "on the split point and double click, or type l."])
178           unhilite_obj(kfrom) ;
179         return
180       end
181       typpfrom='in'
182     else // event output port
183       port_number = k - size(op,'*') ;
184       if cop(port_number)<>0 then
185           hilite_obj(kfrom);
186           message(["Selected port is already connected.";..
187                    "To start a link off another link, place the cursor";..
188                    "on the split point and double click, or type l."])
189           unhilite_obj(kfrom);
190         return ; 
191       end
192       typpfrom = 'evtout' ;
193     end
194     fromsplit = %f ; 
195     clr = default_color(typo) ;
196
197     // get port size
198     szout=getportsiz(o1,port_number,typpfrom)
199     // get port data type
200     if typpfrom=='out'|typpfrom=='in' then
201       szouttyp = getporttyp(o1,port_number,typpfrom); 
202     end
203
204     // to be created link from origin 
205     from = [kfrom,port_number, bool2s(typpfrom=='in'|typpfrom=='evtin')] ;
206     xl = xo ;
207     yl = yo ; 
208
209   end
210   //** ---------------------- Checking Ends ----------------------------------------
211   
212   //----------- get link path ----------------------------------------
213   //------------------------------------------------------------------
214
215   drawlater(); //** draw later mode
216   
217   //** These indexes will be used to destroy the intermediate objects created below
218   //** during the "interactive" section 
219
220   o_size = size(gh_axes.children) ; //** o_size(1) is the number of compound object
221   p_size = o_size ;
222
223   //** there are two nested infinite while(%t) loops:
224   //** the outher loop control the sequence of segment 
225   //**   the inner loop handle the interactive operation on the single link segment
226
227   while %t do // loop on link segments
228     xe = xo; ye = yo ; //** o > origin ---- e > end
229     //** the first step is the the creation of a dummy graphic object (a link of ZERO leght)
230     //** and store this handler to modify it later 
231     xpoly([xo;xe] , [yo;ye], 'lines') ; //** create the first 'dummy' object
232     gh_link = gh_axes.children(1) ; //** the last object is the above link :)
233
234     rep(3) = -1; //** initialization (as Claudio Macchiavelli has teached me :) )
235     while %t do //** infinite loop
236       drawlater() ;
237       //** for positive event exit from the loop
238       //** Any event on the [right] button OR a window closing => END the inner loop
239       if or(rep(3)==[0,2,3,5,-5,-1000]) then
240          break; //** EXIT
241       end
242
243       //** otherwise ... get a new point
244
245       //** mouse event queque is cleared (15 Mar 2007 bugfix)
246       rep = xgetmouse([%t, %t]) ; //** looks better :)
247
248       gh_figure = gcf();
249       //** focus has changed OR active window has been closed
250       if gh_figure.figure_id<>curwin | rep(3)==-1000 then
251         [%win, Cmenu] = resume(curwin,'Quit'); 
252       end
253
254       //** any rigth mouse event OR [Esc] OR [d] key : I want to disengage the current Link action
255       if or(rep(3)==[2 5 12 27 100]) then
256           p_size = size(gh_axes.children); 
257           d_size = p_size(1)-o_size(1);
258           if d_size > 0 then
259             gh_compound_delete = glue(gh_axes.children(1:d_size) );
260             delete (gh_compound_delete); //** delete the object
261             drawnow(); //** update the screen
262           end
263
264           if %scicos_debug_gr then
265             disp("d1"); //** Debug
266           end
267           return; //** -----> Exit from the function
268       end //**
269
270       //plot new position of last link segment
271       xe = rep(1); ye = rep(2) ;
272       gh_link.data =  [xo yo ; xe ye ] ;   //** put the coordinate here
273       gh_link.foreground = clr             //** put the color here ( 5 = red )
274       drawnow(); //** update the buffer
275     end
276     //** ----------------- end of last segment while loop ------------------------------
277
278     if %scicos_debug_gr then
279       disp("-->"); //** debug only
280     end
281
282     //** ---------- YOU ARE STILL IN THE "Link" Block-to-Block MAIN LOOP ----------------
283     //** The last segment end with [xe ye] coordinate:
284     //**
285     //** look for a block with a valid (good) input
286
287     kto = getblock(scs_m,[xe;ye]) ;
288     if kto<>[] then // new point designs the "to block"
289       o2 = scs_m.objs(kto);
290       graphics2 = o2.graphics;
291       orig  = graphics2.orig
292       sz    = graphics2.sz
293       theta = graphics2.theta
294       ip    = graphics2.pin
295       impo  = graphics2.pout
296       cip   = graphics2.pein
297       [xin,yin,typin] = getinputports(o2)
298
299       o_ImplIndx = find(graphics2.out_implicit=='I'); 
300
301       //** check connection
302       if xin==[] then
303          hilite_obj(kto)
304           message("This block has no input port.");
305          p_size = size(gh_axes.children);
306          d_size = p_size(1) - o_size(1);
307          if d_size > 0 then
308             gh_compound_delete = glue(gh_axes.children(1:d_size));
309              delete (gh_compound_delete); //** delete the object
310          end
311          if %scicos_debug_gr then
312            disp("d2");   //** Debug
313          end
314          unhilite_obj(kto);
315          drawnow(); //** update the diagram 
316          return;      //** EXIT point : link failed ! 
317       end
318
319       //** Connection is OK : compensate for block's rotation 
320
321       xxx = rotate([xin;yin],...
322                    theta*%pi/180,...
323                    [orig(1)+sz(1)/2;orig(2)+sz(2)/2]);
324       xin = xxx(1,:); yin = xxx(2,:);
325       [m,kp2] = mini((ye-yin)^2+(xe-xin)^2);
326       k = kp2 ;
327       xc2 = xin(k); yc2 = yin(k); 
328       typi = typin(k);
329
330       //** check connection for "type"
331       if typo<>typi
332         hilite_obj(kto)
333         message(["Selected ports don''t have the same type"
334                  "The port at the origin of the link has type "+string(typo);
335                  "the port at the end has type "+string(typin(k))+'.'])
336           p_size = size(gh_axes.children)
337           d_size = p_size(1)-o_size(1);
338           if d_size > 0 then
339              gh_compound_delete = glue(gh_axes.children(1:d_size));
340              delete (gh_compound_delete); //** delete the object
341           end
342           if %scicos_debug_gr then
343              disp("d3"); //** Debug
344           end
345           unhilite_obj(kto)
346           drawnow(); 
347           return; //** EXIT point from the function
348       end
349
350       //** check if is a normal regular input port (not an event input port)
351       if typi==1  then // regular input port
352         port_number = k ;
353         if ip(port_number)<>0 then
354              hilite_obj(kto)
355              message(["Selected port is already connected.";..
356                       "To start a link off another link, place the cursor";..
357                       "on the split point and double click, or type l."]),
358              p_size = size(gh_axes.children); 
359              d_size = p_size(1)-o_size(1);
360              if d_size > 0 then
361                gh_compound_delete = glue(gh_axes.children(1:d_size) );
362                delete (gh_compound_delete); //** delete the object
363              end
364              if %scicos_debug_gr then
365                disp("d4");//** Debug
366              end
367              unhilite_obj(kto);
368              drawnow();
369            return
370         end
371
372         typpto = 'in' ; 
373         szin = getportsiz(o2,port_number,'in')
374         
375         //** further check for warning message about "size" 
376         need_warning = %f ; //** flag initialization 
377         if (szin(1)<>szout(1)) & mini([szin(1) szout(1)])>0 then
378           need_warning = %t ; 
379         end
380
381         // check for different number of dimension
382         szout2 = []; szin2 = [];
383         if size(szout,'*')==1 then
384            szout2 = 1;
385         else
386            szout2 = szout(2);
387         end
388
389         if size(szin,'*')==1 then
390            szin2 = 1;
391         else
392            szin2 = szin(2);
393         end
394
395         if (szin2<>szout2) & mini([szin2 szout2])>0 then
396           need_warning = %t
397         end
398
399         if need_warning then
400             hilite_obj(kto)
401             message(["Warning :";
402                      "Selected ports don''t have the same size";
403                      "The port at the origin of the link has size " + sci2exp(szout);
404                      "the port at the end has size " + sci2exp(szin)+"."])
405             unhilite_obj(kto)
406         end
407
408         // get port data type
409         // and say warning if doesn't match with szouttyp
410         szintyp = getporttyp(o2,port_number,'in')
411         if (szintyp>0 & szouttyp>0) then // if-then-else, event-select blocks case and all the -1 intyp/outtyp
412           if szintyp<>szouttyp then
413             tt_typ=['double';'complex';'int32';'int16';
414                     'int8';'uint32';'uint16';'uint8']
415
416             hilite_obj(kto)
417             message(["Warning :";
418                      "Selected ports don''t have the same data type";
419                      "The port at the origin of the link has datatype "+...
420                       tt_typ(szouttyp)+' ('+sci2exp(szouttyp)+')';
421                      "the port at the end has datatype "+...
422                       tt_typ(szintyp)+' ('+sci2exp(szintyp)+')'+'.'])
423             unhilite_obj(kto);
424           end
425         end
426
427       elseif typi==2 & k<=size(ip,'*') then // implicit "input" port
428         port_number = k
429         if ip(port_number)<>0 then
430            message(["Selected port is already connected.";..
431                     "To start a link off another link, place the cursor";..
432                     "on the split point and double click."]),
433            p_size = size(gh_axes.children)
434            d_size = p_size(1)-o_size(1);
435            if d_size > 0 then
436                gh_compound_delete = glue(gh_axes.children(1:d_size) );
437                delete (gh_compound_delete); //** delete the object
438            end
439            if %scicos_debug_gr then
440              disp("d5");//** Debug
441            end
442            drawnow();
443            return ; //** Exit point
444         end
445         typpto='in'
446         szin = getportsiz(o2,port_number,'in')
447
448         if szin<>szout & mini([szin szout])>0 then
449           message(["Warning :';
450                    "Selected ports don''t have the same size";
451                    "The port at the origin of the link has size "+string(szout);
452                    "the port at the end has size "+string(szin)])
453         end
454
455       elseif (typi==2 & k>size(ip,'*')+size(cip,'*')) then // implicit "output" port
456         k = k-size(ip,'*')-size(cip,'*')
457         typpto='out'; 
458         port_number = o_ImplIndx(k)  //RN: explicit outputs are excluded
459                                      //    in the computation of k
460         if impo(port_number)<>0 then
461            message(["Selected port is already connected.";..
462                     "To start a link off another link, place the cursor";..
463                     "on the split point and double click"]),
464            p_size = size(gh_axes.children);
465            d_size = p_size(1)-o_size(1);
466            if d_size > 0 then
467              gh_compound_delete = glue(gh_axes.children(1:d_size) );
468              delete (gh_compound_delete); //** delete the object
469            end
470            if %scicos_debug_gr then
471              disp("d6");//** Debug
472            end
473            drawnow();
474            return; //** Exit point
475         end
476         typpto='out'
477         szin=getportsiz(o2,port_number,'out')
478
479         if szin<>szout & mini([szin szout])>0 then
480           message(["Warning :";
481                    "Selected ports don''t have the same  size";
482                    "The port at the origin of the link has size " + string(szout);
483                    "the port at the end has size " + string(szin)+'.'])
484         end
485
486       //** otherwise is an event input port
487       else // event input port
488
489         port_number = k-size(ip,'*');
490
491         if cip(port_number)<>0 then
492             hilite_obj(kto)
493             message(["Selected port is already connected.";..
494                      "To start a link off another link, place the cursor";..
495                      "on the split point and double click."]),
496             p_size = size(gh_axes.children); 
497             d_size = p_size(1)-o_size(1);
498             if d_size > 0 then
499               gh_compound_delete = glue(gh_axes.children(1:d_size) );
500               delete (gh_compound_delete); //** delete the object
501             end
502             if %scicos_debug_gr then
503               disp("d7");//** Debug
504             end
505             unhilite_obj(kto)
506             drawnow();
507             return; //** Exit point
508         end
509
510         typpto = 'evtin'; 
511         szin = getportsiz(o2,port_number,'evtin'); 
512         if szin<>szout & mini([szin szout])>0 then
513           message(["Warning :";
514                    "Selected ports don''t have the same  size"
515                    "The port at the origin of the link has size " + string(szout);
516                    "the port at the end has size " + string(szin)+'.'])
517         end
518
519       end
520       //** "fin" : this end a very long list of check on the final destination of the link *****
521    
522       if %scicos_debug_gr then
523         disp("|->>")
524       end
525
526       break; //** this break the outher loop 
527
528     else // (kto==[]) new point ends current line segment: you remain in the outher loop 
529
530       if xe<>xo|ye<>yo then // to avoid null length segments
531         xc2 = xe; yc2 = ye ; 
532
533         if abs(xo-xc2)<abs(yo-yc2) then
534           xc2 = xo ;
535         else
536           yc2 = yo ; 
537         end
538
539         gh_link.data =  [xo yo ; xc2 yc2 ] ; //** temp
540         gh_link.foreground = clr           ; //** put the color here
541
542         drawnow();      
543         
544         if %scicos_debug_gr then
545           disp("d8");//** Debug
546         end
547
548         xl = [xl;xc2]; yl = [yl;yc2] ;
549         xo = xc2     ; yo = yc2    ;
550       end
551
552     end
553
554   end // This is the end of the outher loop (loop on link segments)
555   //**---------------------------------------------------------------------------------------------
556
557   gh_figure = gcf();
558   if gh_figure.figure_id<>curwin | rep(3)==-1000 then
559       //active window has been closed
560       [%win,Cmenu] = resume(curwin,'Quit')
561   end
562
563   // make last segment horizontal or vertical
564   typ = typo
565   to = [kto,port_number,bool2s(typpto=='in'|typpto=='evtin')]
566   nx = prod(size(xl))
567
568   if from==to then
569       message(["Selected port is already connected.";..
570                "To start a link off another link, place the cursor";..
571                "on the split point and double click"]),
572       p_size = size(gh_axes.children)
573       d_size = p_size(1)-o_size(1);
574       if d_size > 0 then
575         gh_compound_delete = glue(gh_axes.children(1:d_size) );
576         delete (gh_compound_delete); //** delete the object
577         drawnow();
578       end
579       if %scicos_debug_gr then
580         disp("d9");//** Debug
581       end
582       drawnow();
583       return //** EXIT point
584   end
585
586   //**-----------------------------------------------------------------------------------
587   //** the link is a valid link
588
589   //** from here the data strucures are update BUT not draw !  
590   drawlater(); //** DO NOT UPDATE THE CANVAS ! 
591  
592   if nx==1 then // 1 segment link
593
594     if fromsplit&(xl<>xc2|yl<>yc2) then
595       // try to move split point
596       if xx(wh)==xx(wh+1) then // split is on a vertical link
597         if (yy(wh)-yc2)*(yy(wh+1)-yc2)<0 then
598           yl = yc2 ;
599           gh_link.data =  [xl yl ; xc2 yc2] ; //** put the coordinate here
600         end
601       elseif yy(wh)==yy(wh+1) then //split is on a horizontal link
602         if (xx(wh)-xc2)*(xx(wh+1)-xc2)<0 then
603           xl = xc2 ;
604           gh_link.data = [xl yl ; xc2 yc2 ] ; //** put the coordinate here
605         end
606       end
607       d = [xl,yl]
608       //** Alan's fix, 17/10/07
609       //** create a point in the middle of the link
610       //** in the case of a direct link between two port
611       //** of the same block
612     elseif kto==kfrom then
613       xl = [xl;(xl+xc2)/2]
614       yl = [yl;(yl+yc2)/2]
615     end
616     //form link datas
617     xl = [xl;xc2];yl=[yl;yc2]
618   else
619     if xl(nx)==xl(nx-1) then
620       // previous segment is vertical
621       nx = prod(size(xl)) ;
622       gh_link_del = gh_axes.children(1) ;
623       delete( gh_link_del );
624       gh_link_del = gh_axes.children(1) ;
625       delete( gh_link_del );
626       xpoly([xl(nx-1) ; xl(nx) ; xc2] , [yl(nx-1) ; yc2 ; yc2] ,'lines');
627       gh_link = gh_axes.children(1) ;
628       gh_link.foreground = clr
629       // form link datas
630       xl = [xl;xc2]; yl = [yl(1:nx-1);yc2;yc2]
631
632     //** ---- Previous segment is horizontal
633     elseif yl(nx)==yl(nx-1) then
634       // previous segment is horizontal
635       nx = prod(size(xl)) ;
636       gh_link_del = gh_axes.children(1) ;
637       delete( gh_link_del );
638       gh_link_del = gh_axes.children(1) ;
639       delete( gh_link_del );
640       xpoly([xl(nx-1);xc2;xc2],[yl(nx-1);yl(nx);yc2],'lines')
641       gh_link = gh_axes.children(1) ;
642       gh_link.foreground = clr
643
644       // form link datas
645       xl = [xl(1:nx-1);xc2;xc2]; yl = [yl;yc2]
646     else 
647       // previous segment is oblique
648       // nothing particular is done
649       xl = [xl;xc2]; yl = [yl;yc2]
650     end
651   end
652
653   lk = scicos_link(xx=xl,yy=yl,ct=[clr,typ],from=from,to=to)
654
655   //**---- Mr. Clean :) -----------------------------------------------------------------------
656   p_size = size(gh_axes.children) ; //** p_size(1) is the number of compound object
657   d_size = p_size(1) - o_size(1) ;  //** at the and of this "Link" operation
658   if d_size > 0 then
659     gh_compound_delete = glue(gh_axes.children(1:d_size) );
660     delete (gh_compound_delete); //** delete the object
661   end
662   //**------------------------------------------------------------------------------------------
663
664   //----------- update objects structure -----------------------------
665   //------------------------------------------------------------------
666
667   if fromsplit then // link comes from a split
668     nx=size(scs_m.objs)+1
669     //split old link
670     from1=o1.from
671     to1=o1.to
672     link1=o1;
673     link1.xx   = [xx(1:wh);d(1)];
674     link1.yy   = [yy(1:wh);d(2)];
675     link1.to   = [nx,1,1]
676
677     link2=o1;
678     link2.xx   = [d(1);xx(wh+1:size(xx,1))];
679     link2.yy   = [d(2);yy(wh+1:size(yy,1))];
680     link2.from = [nx,1,0];
681
682
683     // create split block
684     if typo==1 then
685       sp=SPLIT_f('define')
686       sp.graphics.orig = d;
687       sp.graphics.pin  = ks;
688       sp.graphics.pout = [nx+1;nx+2];
689
690       SPLIT_f('plot',sp)
691     elseif typo==2 then
692       sp=IMPSPLIT_f('define')
693       sp.graphics.orig = d;
694       sp.graphics.pin  = ks;
695       sp.graphics.pout = [nx+1;nx+2];
696       inoutfrom='out' 
697       IMPSPLIT_f('plot',sp)
698     else
699       sp=CLKSPLIT_f('define')
700       sp.graphics.orig  = d;
701       sp.graphics.pein  = ks;
702       sp.graphics.peout = [nx+1;nx+2];
703       CLKSPLIT_f('plot',sp)
704     end
705
706     glue(gh_axes.children(1) ); //** create the compound
707     //** be very careful: here the graphics datastructure has ONE more element than the
708     //** "scs_m.objs" ;)
709     //---------------------------
710       scs_m.objs(ks)   = link1 ; //** adjust the data of the first half of the old "splitted" link
711
712       gh_ks = get_gri(ks,o_size(1)) + 1 ; //** I need to compensate for the last entry
713
714       gh_axes.children(gh_ks).children.data = [ link1.xx , link1.yy]  ; //** update the graphics datastructure
715       link1_color = gh_axes.children(gh_ks).children.foreground       ; //** save the color
716
717       //---------------------------
718
719       scs_m.objs(nx)  = sp    ; //** the graphics datastructure is already up to date in "nx" position
720
721       //---------------------------
722
723       scs_m.objs(nx+1) = link2 ;
724
725       xpoly (link2.xx , link2.yy) ;
726       gh_axes.children(1).foreground = link1_color ;
727       glue(gh_axes.children(1) ); //** create the compound :)
728
729     //** update the diagram 
730     scs_m.objs(to1(1)) = mark_prt(scs_m.objs(to1(1)),to1(2),outin(to1(3)+1),typ,nx+1)
731
732   end
733
734   //**----------------------------------------------------------------------------------
735
736   //** add new link in objects structure
737   nx = size(scs_m.objs)+1 ;
738   
739   if smart then lk=scicos_route(lk,scs_m),end
740   
741   scs_m.objs($+1) = lk ;
742
743   drawlater(); 
744     drawobj(lk) ;
745   drawnow();
746
747   //** update connected blocks
748   scs_m.objs(kfrom) = mark_prt(scs_m.objs(kfrom),from(2),outin(from(3)+1),typ,nx)
749   scs_m.objs(kto)   = mark_prt(scs_m.objs(kto),to(2),outin(to(3)+1),typ,nx)
750
751   needcompile = 4; 
752
753   [scs_m_save,nc_save,enable_undo,edited] = resume(scs_m_save,nc_save,%t,%t)
754
755 endfunction