vfs: check userland buffers before reading them.
[haiku.git] / src / apps / cortex / MediaRoutingView / MediaWire.cpp
blob8f40f362cea76b96e1fe8ca54b3f13f56d076d75
1 /*
2 * Copyright (c) 1999-2000, Eric Moon.
3 * All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions, and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions, and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * 3. The name of the author may not be used to endorse or promote products
17 * derived from this software without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESS OR
20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21 * OF TITLE, NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY
23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
26 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
27 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 // MediaWire.cpp
34 #include "MediaWire.h"
35 // InfoWindow
36 #include "InfoWindowManager.h"
37 // MediaRoutingView
38 #include "MediaJack.h"
39 #include "MediaRoutingDefs.h"
40 #include "MediaRoutingView.h"
41 // Support
42 #include "cortex_ui.h"
43 #include "MediaString.h"
44 // TipManager
45 #include "TipManager.h"
47 // Application Kit
48 #include <Application.h>
49 // Interface Kit
50 #include <MenuItem.h>
51 #include <PopUpMenu.h>
52 // Media Kit
53 #include <MediaDefs.h>
55 __USE_CORTEX_NAMESPACE
57 #include <Debug.h>
58 #define D_METHOD(x) //PRINT (x)
59 #define D_DRAW(x) //PRINT (x)
60 #define D_MOUSE(x) //PRINT (x)
62 // -------------------------------------------------------- //
63 // constants
64 // -------------------------------------------------------- //
66 const float MediaWire::M_WIRE_OFFSET = 4.0;
68 // -------------------------------------------------------- //
69 // *** ctor/dtor
70 // -------------------------------------------------------- //
72 MediaWire::MediaWire(
73 Connection connection,
74 MediaJack *outputJack,
75 MediaJack *inputJack)
76 : DiagramWire(outputJack, inputJack),
77 connection(connection)
79 D_METHOD(("MediaWire::MediaWire()\n"));
82 MediaWire::MediaWire(
83 MediaJack *jack,
84 bool isStartPoint)
85 : DiagramWire(jack, isStartPoint)
87 D_METHOD(("MediaWire::MediaWire(temp)\n"));
90 MediaWire::~MediaWire()
92 D_METHOD(("MediaWire::~MediaWire()\n"));
95 // -------------------------------------------------------- //
96 // *** derived from DiagramWire (public)
97 // -------------------------------------------------------- //
99 void MediaWire::attachedToDiagram()
101 D_METHOD(("MediaWire::detachedFromDiagram()\n"));
103 endPointMoved(startPoint());
104 endPointMoved(endPoint());
107 void MediaWire::detachedFromDiagram()
109 D_METHOD(("MediaWire::detachedFromDiagram()\n"));
111 // make sure we're no longer displaying a tooltip
112 TipManager *tips = TipManager::Instance();
113 tips->hideTip(view()->ConvertToScreen(Frame()));
116 BRect MediaWire::Frame() const
118 D_DRAW(("MediaWire::Frame()\n"));
119 return m_frame;
122 float MediaWire::howCloseTo(
123 BPoint point) const
125 D_MOUSE(("MediaWire::howCloseTo()\n"));
126 if (Frame().Contains(point))
128 BPoint sp = m_startPoint;
129 BPoint ep = m_endPoint;
130 BPoint so = m_startOffset;
131 BPoint eo = m_endOffset;
132 BRect wireFrame, startFrame, endFrame;
133 wireFrame.left = so.x < eo.x ? so.x : eo.x;
134 wireFrame.top = so.y < eo.y ? so.y : eo.y;
135 wireFrame.right = so.x > eo.x ? so.x : eo.x;
136 wireFrame.bottom = so.y > eo.y ? so.y : eo.y;
137 startFrame.Set(sp.x, sp.y, so.x, so.y);
138 endFrame.Set(ep.x, ep.y, eo.x, eo.y);
139 wireFrame.InsetBy(-1.0, -1.0);
140 startFrame.InsetBy(-1.0, -1.0);
141 endFrame.InsetBy(-1.0, -1.0);
142 if ((wireFrame.Width() <= 5.0) || (wireFrame.Height() <= 5.0) || startFrame.Contains(point) || endFrame.Contains(point))
144 return 1.0;
146 else
148 float length, result;
149 length = sqrt(pow(eo.x - so.x, 2) + pow(eo.y - so.y, 2));
150 result = ((so.y - point.y) * (eo.x - so.x)) - ((so.x - point.x) * (eo.y - so.y));
151 result = 3.0 - fabs(result / length);
152 return result;
155 return 0.0;
158 void MediaWire::drawWire()
160 D_DRAW(("MediaWire::drawWire()\n"));
162 rgb_color border = isSelected() ? M_BLUE_COLOR : M_DARK_GRAY_COLOR;
163 rgb_color fill = isSelected() ? M_LIGHT_BLUE_COLOR : M_LIGHT_GRAY_COLOR;
164 view()->SetPenSize(3.0);
165 view()->BeginLineArray(3);
166 view()->AddLine(m_startPoint, m_startOffset, border);
167 view()->AddLine(m_startOffset, m_endOffset, border);
168 view()->AddLine(m_endOffset, m_endPoint, border);
169 view()->EndLineArray();
170 view()->SetPenSize(1.0);
171 view()->BeginLineArray(3);
172 view()->AddLine(m_startPoint, m_startOffset, fill);
173 view()->AddLine(m_startOffset, m_endOffset, fill);
174 view()->AddLine(m_endOffset, m_endPoint, fill);
175 view()->EndLineArray();
178 void MediaWire::MouseDown(
179 BPoint point,
180 uint32 buttons,
181 uint32 clicks)
183 D_MOUSE(("MediaWire::MouseDown()\n"));
184 _inherited::MouseDown(point, buttons, clicks);
186 switch (buttons)
188 case B_SECONDARY_MOUSE_BUTTON:
190 if (clicks == 1)
192 showContextMenu(point);
198 void MediaWire::MouseOver(
199 BPoint point,
200 uint32 transit)
202 D_MOUSE(("MediaWire::MouseOver()\n"));
204 if (isDragging())
206 return;
208 switch (transit)
210 case B_ENTERED_VIEW:
212 TipManager *tips = TipManager::Instance();
213 BString tipText = MediaString::getStringFor(connection.format(), false);
214 tips->showTip(tipText.String(), view()->ConvertToScreen(Frame()),
215 TipManager::LEFT_OFFSET_FROM_POINTER, BPoint(12.0, 8.0));
216 be_app->SetCursor(M_CABLE_CURSOR);
217 break;
219 case B_EXITED_VIEW:
221 be_app->SetCursor(B_HAND_CURSOR);
222 TipManager *tips = TipManager::Instance();
223 tips->hideTip(view()->ConvertToScreen(Frame()));
224 break;
229 void MediaWire::selected()
231 D_METHOD(("MediaWire::selected()\n"));
232 if (startPoint())
234 MediaJack *outputJack = static_cast<MediaJack *>(startPoint());
235 outputJack->select();
237 if (endPoint())
239 MediaJack *inputJack = static_cast<MediaJack *>(endPoint());
240 inputJack->select();
244 void MediaWire::deselected()
246 D_METHOD(("MediaWire::deselected()\n"));
247 if (startPoint())
249 MediaJack *outputJack = static_cast<MediaJack *>(startPoint());
250 outputJack->deselect();
252 if (endPoint())
254 MediaJack *inputJack = static_cast<MediaJack *>(endPoint());
255 inputJack->deselect();
259 void MediaWire::endPointMoved(
260 DiagramEndPoint *which)
262 if (which == startPoint())
264 m_startPoint = startConnectionPoint();
265 switch (dynamic_cast<MediaRoutingView *>(view())->getLayout())
267 case MediaRoutingView::M_ICON_VIEW:
269 m_startOffset = m_startPoint + BPoint(M_WIRE_OFFSET, 0.0);
270 break;
272 case MediaRoutingView::M_MINI_ICON_VIEW:
274 m_startOffset = m_startPoint + BPoint(0.0, M_WIRE_OFFSET);
275 break;
278 m_frame.left = m_startPoint.x < m_endOffset.x ? m_startPoint.x - 2.0: m_endOffset.x - 2.0;
279 m_frame.top = m_startPoint.y < m_endOffset.y ? m_startPoint.y - 2.0 : m_endOffset.y - 2.0;
280 m_frame.right = m_startOffset.x > m_endPoint.x ? m_startOffset.x + 2.0 : m_endPoint.x + 2.0;
281 m_frame.bottom = m_startOffset.y > m_endPoint.y ? m_startOffset.y + 2.0 : m_endPoint.y + 2.0;
283 else if (which == endPoint())
285 m_endPoint = endConnectionPoint();
286 switch (dynamic_cast<MediaRoutingView *>(view())->getLayout())
288 case MediaRoutingView::M_ICON_VIEW:
290 m_endOffset = m_endPoint - BPoint(M_WIRE_OFFSET, 0.0);
291 break;
293 case MediaRoutingView::M_MINI_ICON_VIEW:
295 m_endOffset = m_endPoint - BPoint(0.0, M_WIRE_OFFSET);
296 break;
299 m_frame.left = m_startPoint.x < m_endOffset.x ? m_startPoint.x - 2.0: m_endOffset.x - 2.0;
300 m_frame.top = m_startPoint.y < m_endOffset.y ? m_startPoint.y - 2.0 : m_endOffset.y - 2.0;
301 m_frame.right = m_startOffset.x > m_endPoint.x ? m_startOffset.x + 2.0 : m_endPoint.x + 2.0;
302 m_frame.bottom = m_startOffset.y > m_endPoint.y ? m_startOffset.y + 2.0 : m_endPoint.y + 2.0;
306 // -------------------------------------------------------- //
307 // *** internal operations (protected)
308 // -------------------------------------------------------- //
310 void MediaWire::showContextMenu(
311 BPoint point)
313 D_METHOD(("MediaWire::showContextMenu()\n"));
315 BPopUpMenu *menu = new BPopUpMenu("MediaWire PopUp", false, false, B_ITEMS_IN_COLUMN);
316 menu->SetFont(be_plain_font);
317 BMenuItem *item;
319 // add the "Get Info" item
320 media_output output;
321 connection.getOutput(&output);
322 BMessage *message = new BMessage(InfoWindowManager::M_INFO_WINDOW_REQUESTED);
323 message->AddData("connection", B_RAW_TYPE,
324 reinterpret_cast<const void *>(&output), sizeof(output));
325 menu->AddItem(item = new BMenuItem("Get info", message, 'I'));
327 // add the "Disconnect" item
328 menu->AddItem(item = new BMenuItem("Disconnect", new BMessage(MediaRoutingView::M_DELETE_SELECTION), 'T'));
329 if (connection.flags() & Connection::LOCKED)
331 item->SetEnabled(false);
334 menu->SetTargetForItems(view());
335 view()->ConvertToScreen(&point);
336 point -= BPoint(1.0, 1.0);
337 menu->Go(point, true, true, true);
340 // END -- MediaWire.cpp --