1 /* AADL plugin for DIA
2 *
3 * Copyright (C) 2005 Laboratoire d'Informatique de Paris 6
4 * Author: Pierre Duquesne
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 */
20 
21 
22 /* AADL plugin for DIA
23  * Author: Pierre Duquesne
24  *
25  * This program is free software; you can redistribute it and/or modify
26  * it under the terms of the GNU General Public License as published by
27  * the Free Software Foundation; either version 2 of the License, or
28  * (at your option) any later version.
29  *
30  * This program is distributed in the hope that it will be useful,
31  * but WITHOUT ANY WARRANTY; without even the implied warranty of
32  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
33  * GNU General Public License for more details.
34  *
35  * You should have received a copy of the GNU General Public License
36  * along with this program; if not, write to the Free Software
37  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
38  */
39 
40 #include "aadl.h"
41 
42 /***********************************************
43  **           PORT-RELATED FUNCTIONS          **
44  ***********************************************/
45 
46 void
rotate_around_origin(Point * p,real angle)47 rotate_around_origin (Point *p, real angle)   /* FIXME: no namespace */
48 {
49   coord x = p->x;
50   coord y = p->y;
51 
52   p->x = x * cos(angle) - y * sin(angle) ;
53   p->y = x * sin(angle) + y * cos(angle) ;
54 
55 }
56 
57 
58 
59 
60 #define AADL_PORT_WIDTH_A  0.2
61 #define AADL_PORT_WIDTH_B  0.5
62 #define AADL_PORT_HEIGHT 0.6
63 #define AADL_PORT_LINEWIDTH 0.1
64                                             /*	   A| B C	   */
65 #define AADL_ACCESS_WIDTH_A 0.2             /* 	    ---\	   */
66 #define AADL_ACCESS_WIDTH_B 0.3             /*	   |    +	   */
67 #define AADL_ACCESS_WIDTH_C 0.2	            /*	    ---/	   */
68 #define AADL_ACCESS_HEIGHT 0.9	            /* 	    | 	       	   */
69 
70 #define AADL_EVENT_DELTA_WIDTH 0.4
71 #define AADL_EVENT_DELTA_HEIGHT 0.3
72 
73 
74 
75 #define draw_in_data_port()                                       \
76     p[0].x =  AADL_PORT_WIDTH_A;				  \
77     p[0].y =  -AADL_PORT_HEIGHT/2;				  \
78 								  \
79     p[1].x =  -AADL_PORT_WIDTH_B;				  \
80     p[1].y =  0;						  \
81 								  \
82     p[2].x =  AADL_PORT_WIDTH_A;				  \
83     p[2].y =  AADL_PORT_HEIGHT/2;				  \
84 								  \
85     rotate_around_origin(p, port->angle);			  \
86     rotate_around_origin(p+1, port->angle);			  \
87     rotate_around_origin(p+2, port->angle);			  \
88 								  \
89     point_add(p, &port->handle->pos);				  \
90     point_add(p+1, &port->handle->pos);				  \
91     point_add(p+2, &port->handle->pos);				  \
92 								  \
93     renderer_ops->set_linewidth(renderer, AADL_PORT_LINEWIDTH);	  \
94     renderer_ops->set_linejoin(renderer, LINEJOIN_MITER);	  \
95     renderer_ops->set_linestyle(renderer, LINESTYLE_SOLID);	  \
96 								  \
97     renderer_ops->fill_polygon(renderer, p,  3, &color_black);    \
98     renderer_ops->draw_polygon(renderer, p,  3, &color_black);
99 
100 #define draw_in_event_port()                                         \
101     p[0].x =  AADL_PORT_WIDTH_A;				     \
102     p[0].y =  -AADL_PORT_HEIGHT/2 - AADL_EVENT_DELTA_HEIGHT;	     \
103 								     \
104     p[1].x =  - AADL_PORT_WIDTH_B - AADL_EVENT_DELTA_WIDTH;	     \
105     p[1].y =  0;						     \
106 								     \
107     p[2].x =  AADL_PORT_WIDTH_A;				     \
108     p[2].y =  AADL_PORT_HEIGHT/2 + AADL_EVENT_DELTA_HEIGHT;	     \
109 								     \
110     rotate_around_origin(p, port->angle);			     \
111     rotate_around_origin(p+1, port->angle);			     \
112     rotate_around_origin(p+2, port->angle);			     \
113 								     \
114     point_add(p, &port->handle->pos);				     \
115     point_add(p+1, &port->handle->pos);				     \
116     point_add(p+2, &port->handle->pos);				     \
117 								     \
118     renderer_ops->set_linewidth(renderer, AADL_PORT_LINEWIDTH);	     \
119     renderer_ops->set_linejoin(renderer, LINEJOIN_MITER);	     \
120     renderer_ops->set_linestyle(renderer, LINESTYLE_SOLID);	     \
121                                                                      \
122     renderer_ops->draw_polyline(renderer, p,  3, &color_black);
123 
124 #define draw_out_data_port()                                        \
125     p[0].x =  -AADL_PORT_WIDTH_A;                                   \
126     p[0].y =  -AADL_PORT_HEIGHT/2;				    \
127 								    \
128     p[1].x =  AADL_PORT_WIDTH_B;				    \
129     p[1].y =  0;						    \
130 								    \
131     p[2].x =  -AADL_PORT_WIDTH_A;				    \
132     p[2].y =  AADL_PORT_HEIGHT/2;				    \
133 								    \
134     rotate_around_origin(p, port->angle);			    \
135     rotate_around_origin(p+1, port->angle);			    \
136     rotate_around_origin(p+2, port->angle);			    \
137 								    \
138     point_add(p, &port->handle->pos);				    \
139     point_add(p+1, &port->handle->pos);				    \
140     point_add(p+2, &port->handle->pos);				    \
141 								    \
142     renderer_ops->set_linewidth(renderer, AADL_PORT_LINEWIDTH);	    \
143     renderer_ops->set_linejoin(renderer, LINEJOIN_MITER);	    \
144     renderer_ops->set_linestyle(renderer, LINESTYLE_SOLID);	    \
145 								    \
146     renderer_ops->fill_polygon(renderer, p,  3, &color_black);      \
147     renderer_ops->draw_polygon(renderer, p,  3, &color_black);
148 
149 #define draw_out_event_port()                                       \
150     p[0].x =  - AADL_PORT_WIDTH_A;                                  \
151     p[0].y =  - AADL_PORT_HEIGHT/2 - AADL_EVENT_DELTA_HEIGHT;	    \
152 								    \
153     p[1].x =  AADL_PORT_WIDTH_B + AADL_EVENT_DELTA_WIDTH;	    \
154     p[1].y =  0;						    \
155 								    \
156     p[2].x =  - AADL_PORT_WIDTH_A;				    \
157     p[2].y =  AADL_PORT_HEIGHT/2 + AADL_EVENT_DELTA_HEIGHT;	    \
158 								    \
159     rotate_around_origin(p, port->angle);			    \
160     rotate_around_origin(p+1, port->angle);			    \
161     rotate_around_origin(p+2, port->angle);			    \
162 								    \
163     point_add(p, &port->handle->pos);				    \
164     point_add(p+1, &port->handle->pos);				    \
165     point_add(p+2, &port->handle->pos);				    \
166 								    \
167     renderer_ops->set_linewidth(renderer, AADL_PORT_LINEWIDTH);	    \
168     renderer_ops->set_linejoin(renderer, LINEJOIN_MITER);	    \
169     renderer_ops->set_linestyle(renderer, LINESTYLE_SOLID);	    \
170 								    \
171     renderer_ops->draw_polyline(renderer, p,  3, &color_black);
172 
173 #define draw_in_out_data_port()                                     \
174     p[0].x =  0;						    \
175     p[0].y =  -AADL_PORT_HEIGHT/2;				    \
176 								    \
177     p[1].x =  AADL_PORT_WIDTH_B;				    \
178     p[1].y =  0;						    \
179 								    \
180     p[2].x =  0;						    \
181     p[2].y =  AADL_PORT_HEIGHT/2;				    \
182 								    \
183     p[3].x =  -AADL_PORT_WIDTH_B;				    \
184     p[3].y =  0;						    \
185 								    \
186     rotate_around_origin(p, port->angle);			    \
187     rotate_around_origin(p+1, port->angle);			    \
188     rotate_around_origin(p+2, port->angle);			    \
189     rotate_around_origin(p+3, port->angle);			    \
190 								    \
191     point_add(p, &port->handle->pos);				    \
192     point_add(p+1, &port->handle->pos);				    \
193     point_add(p+2, &port->handle->pos);				    \
194     point_add(p+3, &port->handle->pos);				    \
195 								    \
196     renderer_ops->set_linewidth(renderer, AADL_PORT_LINEWIDTH);	    \
197     renderer_ops->set_linejoin(renderer, LINEJOIN_MITER);	    \
198     renderer_ops->set_linestyle(renderer, LINESTYLE_SOLID);	    \
199 								    \
200     renderer_ops->fill_polygon(renderer, p,  4, &color_black);	    \
201     renderer_ops->draw_polygon(renderer, p,  4, &color_black);
202 
203 
204 
205 #define draw_in_out_event_port()                                   \
206     p[0].x =  0;						   \
207     p[0].y =  -AADL_PORT_HEIGHT/2 - AADL_EVENT_DELTA_HEIGHT;	   \
208 								   \
209     p[1].x =  AADL_PORT_WIDTH_B + AADL_EVENT_DELTA_WIDTH;	   \
210     p[1].y =  0;						   \
211 								   \
212     p[2].x =  0;						   \
213     p[2].y =  AADL_PORT_HEIGHT/2 + AADL_EVENT_DELTA_HEIGHT;	   \
214 								   \
215     p[3].x =  -AADL_PORT_WIDTH_B - AADL_EVENT_DELTA_WIDTH;	   \
216     p[3].y =  0;						   \
217 								   \
218     rotate_around_origin(p, port->angle);			   \
219     rotate_around_origin(p+1, port->angle);			   \
220     rotate_around_origin(p+2, port->angle);			   \
221     rotate_around_origin(p+3, port->angle);			   \
222 								   \
223     point_add(p, &port->handle->pos);				   \
224     point_add(p+1, &port->handle->pos);				   \
225     point_add(p+2, &port->handle->pos);				   \
226     point_add(p+3, &port->handle->pos);				   \
227 								   \
228     renderer_ops->set_linewidth(renderer, AADL_PORT_LINEWIDTH);	   \
229     renderer_ops->set_linejoin(renderer, LINEJOIN_MITER);	   \
230     renderer_ops->set_linestyle(renderer, LINESTYLE_SOLID);	   \
231 								   \
232     renderer_ops->draw_polygon(renderer, p,  4, &color_black);
233 
234 
235 /* FIXME: should i make methods from this function ? */
236 
237 void
aadlbox_draw_port(Aadlport * port,DiaRenderer * renderer)238 aadlbox_draw_port(Aadlport *port, DiaRenderer *renderer)
239 {
240   DiaRendererClass *renderer_ops = DIA_RENDERER_GET_CLASS (renderer);
241   Point p[5];
242 
243   assert(port!=NULL);
244   assert(renderer!=NULL);
245 
246   switch(port->type) {
247 
248   case ACCESS_PROVIDER:
249     p[0].x = - AADL_ACCESS_WIDTH_A;
250     p[0].y = - AADL_ACCESS_HEIGHT/2;
251 
252     p[1].x =   AADL_ACCESS_WIDTH_B;
253     p[1].y = - AADL_ACCESS_HEIGHT/2;
254 
255     p[2].x =   AADL_ACCESS_WIDTH_B + AADL_ACCESS_WIDTH_C ;
256     p[2].y =   0;
257 
258     p[3].x =   AADL_ACCESS_WIDTH_B;
259     p[3].y =   AADL_ACCESS_HEIGHT/2;
260 
261     p[4].x = - AADL_ACCESS_WIDTH_A;
262     p[4].y =   AADL_ACCESS_HEIGHT/2;
263 
264     rotate_around_origin(p, port->angle);
265     rotate_around_origin(p+1, port->angle);
266     rotate_around_origin(p+2, port->angle);
267     rotate_around_origin(p+3, port->angle);
268     rotate_around_origin(p+4, port->angle);
269 
270     point_add(p, &port->handle->pos);
271     point_add(p+1, &port->handle->pos);
272     point_add(p+2, &port->handle->pos);
273     point_add(p+3, &port->handle->pos);
274     point_add(p+4, &port->handle->pos);
275 
276     renderer_ops->set_linewidth(renderer, AADL_PORT_LINEWIDTH);
277     renderer_ops->set_linejoin(renderer, LINEJOIN_MITER);
278     renderer_ops->set_linestyle(renderer, LINESTYLE_SOLID);
279 
280     renderer_ops->fill_polygon(renderer, p,  5, &color_white);
281     renderer_ops->draw_polygon(renderer, p,  5, &color_black);
282 
283     break;
284 
285   case ACCESS_REQUIRER:
286     p[0].x =   AADL_ACCESS_WIDTH_A;
287     p[0].y = - AADL_ACCESS_HEIGHT/2;
288 
289     p[1].x = - AADL_ACCESS_WIDTH_B;
290     p[1].y = - AADL_ACCESS_HEIGHT/2;
291 
292     p[2].x = - AADL_ACCESS_WIDTH_B - AADL_ACCESS_WIDTH_C ;
293     p[2].y =   0;
294 
295     p[3].x = - AADL_ACCESS_WIDTH_B;
296     p[3].y =   AADL_ACCESS_HEIGHT/2;
297 
298     p[4].x =   AADL_ACCESS_WIDTH_A;
299     p[4].y =   AADL_ACCESS_HEIGHT/2;
300 
301     rotate_around_origin(p, port->angle);
302     rotate_around_origin(p+1, port->angle);
303     rotate_around_origin(p+2, port->angle);
304     rotate_around_origin(p+3, port->angle);
305     rotate_around_origin(p+4, port->angle);
306 
307     point_add(p, &port->handle->pos);
308     point_add(p+1, &port->handle->pos);
309     point_add(p+2, &port->handle->pos);
310     point_add(p+3, &port->handle->pos);
311     point_add(p+4, &port->handle->pos);
312 
313     renderer_ops->set_linewidth(renderer, AADL_PORT_LINEWIDTH);
314     renderer_ops->set_linejoin(renderer, LINEJOIN_MITER);
315     renderer_ops->set_linestyle(renderer, LINESTYLE_SOLID);
316 
317     renderer_ops->fill_polygon(renderer, p,  5, &color_white);
318     renderer_ops->draw_polygon(renderer, p,  5, &color_black);
319 
320     break;
321 
322   case IN_DATA_PORT:
323     draw_in_data_port();
324     break;
325 
326   case IN_EVENT_PORT:
327     draw_in_event_port()
328     break;
329 
330   case IN_EVENT_DATA_PORT:
331     draw_in_data_port();
332     draw_in_event_port();
333     break;
334 
335   case OUT_DATA_PORT:
336     draw_out_data_port();
337     break;
338 
339   case OUT_EVENT_PORT:
340     draw_out_event_port();
341     break;
342 
343   case OUT_EVENT_DATA_PORT:
344     draw_out_data_port();
345     draw_out_event_port();
346     break;
347 
348   case IN_OUT_DATA_PORT:
349     draw_in_out_data_port();
350     break;
351 
352   case  IN_OUT_EVENT_PORT:
353     draw_in_out_event_port();
354     break;
355 
356   case  IN_OUT_EVENT_DATA_PORT:
357     draw_in_out_data_port();
358     draw_in_out_event_port();
359     break;
360 
361 #define AADL_PORT_GROUP_SIZE 0.1
362 
363   case PORT_GROUP:    /* quick n dirty - should use macros*/
364     {
365       BezPoint b[5];
366       int i;
367 
368       p[0].x = 0;  p[0].y = 0;
369 
370       rotate_around_origin(p, port->angle);
371       point_add(p, &port->handle->pos);
372 
373       renderer_ops->set_linewidth(renderer, AADL_PORT_LINEWIDTH);
374       renderer_ops->set_linejoin(renderer, LINEJOIN_MITER);
375       renderer_ops->set_linestyle(renderer, LINESTYLE_SOLID);
376 
377       renderer_ops->fill_ellipse(renderer, p,
378 				 6 * AADL_PORT_GROUP_SIZE,
379 				 6 * AADL_PORT_GROUP_SIZE,
380 				 &color_black);
381       renderer_ops->draw_ellipse(renderer, p,
382 				 6 * AADL_PORT_GROUP_SIZE,
383 				 6 * AADL_PORT_GROUP_SIZE,
384 				 &color_black);
385 
386 
387       b[0].type = BEZ_MOVE_TO;
388       b[1].type = BEZ_CURVE_TO;
389       b[2].type = BEZ_LINE_TO;
390       b[3].type = BEZ_CURVE_TO;
391       b[4].type = BEZ_LINE_TO;
392 
393       b[0].p1.x = -2         * AADL_PORT_GROUP_SIZE;
394       b[0].p1.y = -6         * AADL_PORT_GROUP_SIZE;
395 
396       b[1].p1.x = -6         * AADL_PORT_GROUP_SIZE;
397       b[1].p1.y = -4         * AADL_PORT_GROUP_SIZE;
398       b[1].p2.x = -6         * AADL_PORT_GROUP_SIZE;
399       b[1].p2.y =  4         * AADL_PORT_GROUP_SIZE;
400       b[1].p3.x = -2         * AADL_PORT_GROUP_SIZE;
401       b[1].p3.y =  6         * AADL_PORT_GROUP_SIZE;
402 
403       b[2].p1.x = -2         * AADL_PORT_GROUP_SIZE;
404       b[2].p1.y =  9         * AADL_PORT_GROUP_SIZE;
405 
406       b[3].p1.x = -9         * AADL_PORT_GROUP_SIZE;
407       b[3].p1.y =  7         * AADL_PORT_GROUP_SIZE;
408       b[3].p2.x = -9         * AADL_PORT_GROUP_SIZE;
409       b[3].p2.y = -7         * AADL_PORT_GROUP_SIZE;
410       b[3].p3.x = -2         * AADL_PORT_GROUP_SIZE;
411       b[3].p3.y = -9         * AADL_PORT_GROUP_SIZE;
412 
413       b[4].p1.x = -2         * AADL_PORT_GROUP_SIZE;
414       b[4].p1.y = -6         * AADL_PORT_GROUP_SIZE;
415 
416       for (i=0; i<5; i++) {
417 	rotate_around_origin(&b[i].p1, port->angle);
418 	point_add(&b[i].p1, &port->handle->pos);
419 
420 	if (b[i].type == BEZ_CURVE_TO) {
421 	  rotate_around_origin(&b[i].p2, port->angle);
422 	  rotate_around_origin(&b[i].p3, port->angle);
423 
424 	  point_add(&b[i].p2, &port->handle->pos);
425 	  point_add(&b[i].p3, &port->handle->pos);
426 	}
427       }
428 
429       renderer_ops->fill_bezier(renderer, b, 5, &color_black);
430       renderer_ops->draw_bezier(renderer, b, 5, &color_black);
431 
432     }
433     break;
434 
435   default:
436     break;
437 
438   }
439 }
440 
441 
442 
aadlbox_update_port(Aadlbox * aadlbox,Aadlport * port)443 void aadlbox_update_port(Aadlbox *aadlbox, Aadlport *port)
444 {
445   /* Ports are always kept on the borders of the box */
446   aadlbox->specific->project_point_on_nearest_border(aadlbox,
447 					     &port->handle->pos, &port->angle);
448 
449   /* reinit in & out connection point to default position */
450   /* FIXME: should i make methods ? */
451   switch (port->type) {
452 
453   case ACCESS_PROVIDER:
454     port->in.pos.x = - AADL_ACCESS_WIDTH_A;
455     port->in.pos.y=0;
456 
457     port->out.pos.x=   AADL_ACCESS_WIDTH_B + AADL_ACCESS_WIDTH_C;
458     port->out.pos.y=0;
459     break;
460 
461   case ACCESS_REQUIRER:
462     port->in.pos.x =   AADL_ACCESS_WIDTH_A;
463     port->in.pos.y=0;
464 
465     port->out.pos.x=  - AADL_ACCESS_WIDTH_B - AADL_ACCESS_WIDTH_C;
466     port->out.pos.y=0;
467     break;
468 
469   case IN_DATA_PORT:
470     port->in.pos.x =  AADL_PORT_WIDTH_A; port->in.pos.y=0;
471     port->out.pos.x= -AADL_PORT_WIDTH_B; port->out.pos.y=0;
472     break;
473 
474   case IN_EVENT_PORT:
475   case IN_EVENT_DATA_PORT:
476     port->in.pos.x =  AADL_PORT_WIDTH_A;
477     port->in.pos.y=0;
478 
479     port->out.pos.x= -AADL_PORT_WIDTH_B - AADL_EVENT_DELTA_WIDTH;
480     port->out.pos.y=0;
481     break;
482 
483   case OUT_DATA_PORT:
484     port->in.pos.x = -AADL_PORT_WIDTH_A; port->in.pos.y=0;
485     port->out.pos.x=  AADL_PORT_WIDTH_B; port->out.pos.y=0;
486     break;
487 
488   case OUT_EVENT_PORT:
489   case OUT_EVENT_DATA_PORT:
490     port->in.pos.x = -AADL_PORT_WIDTH_A;
491     port->in.pos.y=0;
492 
493     port->out.pos.x=  AADL_PORT_WIDTH_B + AADL_EVENT_DELTA_WIDTH;
494     port->out.pos.y=0;
495     break;
496 
497   case IN_OUT_DATA_PORT:
498     port->in.pos.x = -AADL_PORT_WIDTH_B; port->in.pos.y=0;
499     port->out.pos.x=  AADL_PORT_WIDTH_B; port->out.pos.y=0;
500     break;
501 
502   case  IN_OUT_EVENT_PORT:
503   case  IN_OUT_EVENT_DATA_PORT:
504     port->in.pos.x = -AADL_PORT_WIDTH_B - AADL_EVENT_DELTA_WIDTH;
505     port->in.pos.y=0;
506     port->out.pos.x=  AADL_PORT_WIDTH_B + AADL_EVENT_DELTA_HEIGHT;
507     port->out.pos.y=0;
508     break;
509 
510   case PORT_GROUP:  /* quick n dirty */
511     port->in.pos.x = -9*AADL_PORT_GROUP_SIZE; port->in.pos.y=0;
512     port->out.pos.x = 3*AADL_PORT_GROUP_SIZE; port->out.pos.y=0;
513     break;
514 
515   default:
516     break;
517 
518 
519   }
520 
521   rotate_around_origin(&port->in.pos, port->angle);
522   rotate_around_origin(&port->out.pos, port->angle);
523 
524   point_add(&port->in.pos, &port->handle->pos);
525   point_add(&port->out.pos, &port->handle->pos);
526 
527   /* direction hints */
528 /*
529   if (port->angle >= M_PI/4.0 && port->angle < 3.0*M_PI/4.0)
530     port->out.directions = DIR_SOUTH;
531   else if (port->angle >= 3.0*M_PI/4.0 && port->angle < 5.0*M_PI/4.0)
532     port->out.directions = DIR_WEST;
533   else if (port->angle >= 5.0*M_PI/4.0 && port->angle < 7.0*M_PI/4.0)
534     port->out.directions = DIR_NORTH;
535   else
536     port->out.directions = DIR_EAST;
537 */
538 }
539 
540 
aadlbox_update_ports(Aadlbox * aadlbox)541 void aadlbox_update_ports(Aadlbox *aadlbox)
542 {
543   int i;
544 
545   for (i=0;i<aadlbox->num_ports;i++)
546     aadlbox_update_port(aadlbox, aadlbox->ports[i]);
547 }
548 
549 
550