]> git.siccegge.de Git - frida/frida.git/blob - src/gui/widgets/CFGScene.cxx
Add option to comment on instructions (in GUI)
[frida/frida.git] / src / gui / widgets / CFGScene.cxx
1 #include "CFGScene.hxx"
2
3 void CFGScene::drawBackground(QPainter* painter, const QRectF & rect) {
4 QGraphicsScene::drawBackground(painter, rect);
5
6 spaceWidgets();
7
8 for (BasicBlockWidget * widget : widgets) {
9 QPointF kopf = widget->getEntry();
10 painter->setPen(QColor(0x00, 0xff, 0x00, 0xff));
11 painter->drawLine(kopf, kopf - QPointF(0, 20));
12
13 auto tails = widget->getExits();
14 auto next = widget->getNext();
15 if (NULL != next[0]) {
16 if (NULL != next[1]) {
17 painter->setPen(QColor(0xff, 0x00, 0x00, 0xff));
18 painter->drawLine(std::get<0>(tails), std::get<0>(tails) + QPointF(0, 20));
19 drawLine(painter, widget, next[1], -1);
20
21 painter->setPen(QColor(0x00, 0xff, 0x00, 0xff));
22 painter->drawLine(std::get<2>(tails), std::get<2>(tails) + QPointF(0, 20));
23 drawLine(painter, widget, next[0], 1);
24 } else {
25 painter->setPen(QColor(0x00, 0x00, 0x00, 0xff));
26 painter->drawLine(std::get<1>(tails), std::get<1>(tails) + QPointF(0, 20));
27 drawLine(painter, widget, next[0], 0);
28 }
29 }
30 }
31 }
32
33 void CFGScene::drawLine(QPainter* painter, BasicBlockWidget * from, BasicBlockWidget * to, int8_t side) {
34 QPointF from_p = from->getExits()[side+1] + QPointF(0, 20);
35 QPointF to_p = to->getEntry() - QPointF(0, 20);
36 if ((to_p - from_p).y() > 0) {
37 /* Forward Edge */
38 QPointF angle1(from_p + QPointF(0, (to_p - from_p).y()));
39 painter->drawLine(from_p, angle1);
40 painter->drawLine(angle1, to_p);
41 } else {
42 /* Backward Edge */
43 QRectF from_r(from->boundingRect()), to_r(to->boundingRect());
44 from_r.moveTo(from->scenePos());
45 to_r.moveTo(to->scenePos());
46 QRectF bound = from_r | to_r;
47 if (std::abs(bound.right() - from_p.x()) > std::abs(bound.left() - to_p.x())) {
48 /* we go left */
49 QPointF middle1 = from_p + QPointF(bound.left() - from_p.x() - 20, 0);
50 QPointF middle2 = to_p + QPointF(bound.left() - to_p.x() - 20, 0);
51
52 painter->drawLine(from_p, middle1);
53 painter->drawLine(middle1, middle2);
54 painter->drawLine(middle2, to_p);
55 } else {
56 /* we go right */
57 QPointF middle1 = from_p - QPointF(from_p.x() - bound.right() - 20, 0);
58 QPointF middle2 = to_p - QPointF(to_p.x() - bound.right() - 20, 0);
59
60 painter->drawLine(from_p, middle1);
61 painter->drawLine(middle1, middle2);
62 painter->drawLine(middle2, to_p);
63 }
64 }
65 }
66
67 void CFGScene::spaceWidgets() {
68 bool changed = false;
69 do {
70 changed = false;
71 for (BasicBlockWidget * widget : widgets) {
72 QPointF out(std::get<0>(widget->getExits()));
73 BasicBlockWidget ** next = widget->getNext();
74
75 if (NULL != next[0]
76 && (next[0]->getEntry() - widget->getEntry()).y() > 0
77 && (next[0]->getEntry() - out).y() < 50) {
78 next[0]->moveBy(0, 1);
79 changed = true;
80 }
81 if (NULL != next[1]
82 && (next[1]->getEntry() - widget->getEntry()).y() > 0
83 && (next[1]->getEntry() - out).y() < 50) {
84 next[1]->moveBy(0, 1);
85 changed = true;
86 }
87 }
88 } while (changed);
89
90 for (BasicBlockWidget * widget : widgets) {
91 QRectF relevantRect = widget->boundingRect();
92 relevantRect.moveTo(widget->scenePos());
93 relevantRect.adjust(-20, -20, 20, 20);
94 for (QGraphicsItem * item : items(relevantRect)) {
95 if (item == widget) continue;
96 if (std::find(widgets.begin(), widgets.end(), item) == widgets.end()) continue;
97 QRectF itemrect = item->boundingRect();
98 itemrect.moveTo(item->scenePos());
99 while (relevantRect.intersects(itemrect)) {
100 if (widget->scenePos().x() > item->scenePos().x()) {
101 widget->moveBy(1, 0);
102 relevantRect.moveTo(widget->scenePos());
103 } else {
104 item->moveBy(1, 0);
105 itemrect.moveTo(item->scenePos());
106 }
107 }
108 }
109 }
110 }