1 /*
2 * Copyright (c) 1999-2000, Eric Moon.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions, and the following disclaimer.
11 *
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.
15 *
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.
18 *
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.
29 */
30
31
32 // MediaIcon.cpp
33
34 #include "MediaIcon.h"
35 #include "MediaIconBits.h"
36 #include "AddOnHostProtocol.h"
37
38 // Application Kit
39 #include <Application.h>
40 #include <Roster.h>
41 // Media Kit
42 #include <MediaDefs.h>
43 #include <MediaNode.h>
44 #include <MediaRoster.h>
45 #include <MediaAddOn.h>
46 // Storage Kit
47 #include <NodeInfo.h>
48 // Support Kit
49 #include <String.h>
50 // Interface Kit
51 #include <IconUtils.h>
52
53
54 __USE_CORTEX_NAMESPACE
55
56 #include <Debug.h>
57 #define D_ALLOC(x) //PRINT (x)
58 #define D_INTERNAL(x) //PRINT (x)
59
60 // -------------------------------------------------------- //
61 // *** ctor/dtor
62 // -------------------------------------------------------- //
63
MediaIcon(const live_node_info & nodeInfo,icon_size size)64 MediaIcon::MediaIcon(
65 const live_node_info &nodeInfo,
66 icon_size size)
67 : BBitmap(BRect(0.0, 0.0, size - 1.0, size - 1.0), B_RGBA32),
68 m_size(size),
69 m_nodeKind(nodeInfo.node.kind) {
70 D_ALLOC(("MediaIcon::MediaIcon(live_node_info '%s')\n", nodeInfo.name));
71
72 _findIconFor(nodeInfo);
73 }
74
MediaIcon(const dormant_node_info & nodeInfo,icon_size size)75 MediaIcon::MediaIcon(
76 const dormant_node_info &nodeInfo,
77 icon_size size)
78 : BBitmap(BRect(0.0, 0.0, size - 1.0, size - 1.0), B_RGBA32),
79 m_size(size),
80 m_nodeKind(0) {
81 D_ALLOC(("MediaIcon::MediaIcon(dormant_node_info '%s')\n", nodeInfo.name));
82
83 _findIconFor(nodeInfo);
84 }
85
~MediaIcon()86 MediaIcon::~MediaIcon() {
87 D_ALLOC(("MediaIcon::~MediaIcon()\n"));
88
89 }
90
91 // -------------------------------------------------------- //
92 // *** internal accessors (private)
93 // -------------------------------------------------------- //
94
_isPhysicalInput() const95 bool MediaIcon::_isPhysicalInput() const {
96 D_INTERNAL(("MediaIcon::_isPhysicalInput()\n"));
97
98 return ((m_nodeKind & B_PHYSICAL_INPUT)
99 && (m_nodeKind & B_BUFFER_PRODUCER));
100 }
101
_isPhysicalOutput() const102 bool MediaIcon::_isPhysicalOutput() const {
103 D_INTERNAL(("MediaIcon::_isPhysicalOutput()\n"));
104
105 return ((m_nodeKind & B_PHYSICAL_OUTPUT)
106 && (m_nodeKind & B_BUFFER_CONSUMER));;
107 }
108
_isProducer() const109 bool MediaIcon::_isProducer() const {
110 D_INTERNAL(("MediaIcon::_isProducer()\n"));
111
112 return (!(m_nodeKind & B_BUFFER_CONSUMER) &&
113 (m_nodeKind & B_BUFFER_PRODUCER) &&
114 !(m_nodeKind & B_PHYSICAL_INPUT) &&
115 !(m_nodeKind & B_PHYSICAL_OUTPUT));
116 }
117
_isFilter() const118 bool MediaIcon::_isFilter() const {
119 D_INTERNAL(("MediaIcon::_isFilter()\n"));
120
121 return ( (m_nodeKind & B_BUFFER_CONSUMER) &&
122 (m_nodeKind & B_BUFFER_PRODUCER) &&
123 !(m_nodeKind & B_PHYSICAL_INPUT) &&
124 !(m_nodeKind & B_PHYSICAL_OUTPUT));
125 }
126
_isConsumer() const127 bool MediaIcon::_isConsumer() const {
128 D_INTERNAL(("MediaIcon::_isConsumer()\n"));
129
130 return ( (m_nodeKind & B_BUFFER_CONSUMER) &&
131 !(m_nodeKind & B_BUFFER_PRODUCER) &&
132 !(m_nodeKind & B_PHYSICAL_INPUT) &&
133 !(m_nodeKind & B_PHYSICAL_OUTPUT));
134 }
135
_isSystemMixer() const136 bool MediaIcon::_isSystemMixer() const {
137 D_INTERNAL(("MediaIcon::_isSystemMixer()\n"));
138
139 return (m_nodeKind & B_SYSTEM_MIXER);
140 }
141
_isTimeSource() const142 bool MediaIcon::_isTimeSource() const {
143 D_INTERNAL(("MediaIcon::_isTimeSource()\n"));
144
145 return ((m_nodeKind & B_TIME_SOURCE) &&
146 !(m_nodeKind & B_PHYSICAL_INPUT) &&
147 !(m_nodeKind & B_PHYSICAL_OUTPUT));
148 }
149
150 // -------------------------------------------------------- //
151 // *** internal operations (private)
152 // -------------------------------------------------------- //
153
_findIconFor(const live_node_info & nodeInfo)154 void MediaIcon::_findIconFor(
155 const live_node_info &nodeInfo) {
156 D_INTERNAL(("MediaIcon::_findIconFor(live_node_info)\n"));
157
158 BMediaRoster *roster = BMediaRoster::CurrentRoster();
159 if (m_nodeKind & B_FILE_INTERFACE) {
160 entry_ref ref;
161 if ((roster && (roster->GetRefFor(nodeInfo.node, &ref) == B_OK))
162 && (BNodeInfo::GetTrackerIcon(&ref, this, m_size) == B_OK)) {
163 return;
164 }
165 }
166 dormant_node_info dormantNodeInfo;
167 if (roster
168 && (roster->GetDormantNodeFor(nodeInfo.node, &dormantNodeInfo) == B_OK)) {
169 D_INTERNAL((" -> instantiated from dormant node\n"));
170 _findIconFor(dormantNodeInfo);
171 }
172 else {
173 D_INTERNAL((" -> application internal node\n"));
174 port_info portInfo;
175 app_info appInfo;
176 if ((get_port_info(nodeInfo.node.port, &portInfo) == B_OK)
177 && (be_roster->GetRunningAppInfo(portInfo.team, &appInfo) == B_OK)) {
178 D_INTERNAL((" -> application info found: %s\n", appInfo.signature));
179 app_info thisAppInfo;
180 if ((be_app->GetAppInfo(&thisAppInfo) != B_OK)
181 || ((strcmp(appInfo.signature, thisAppInfo.signature) != 0)
182 && (strcmp(appInfo.signature, addon_host::g_appSignature) != 0))) {
183 // only use app icon if the node doesn't belong to our team
184 // or the addon-host
185 BNodeInfo::GetTrackerIcon(&appInfo.ref, this, m_size);
186 return;
187 }
188 }
189 bool audioIn = false, audioOut = false, videoIn = false, videoOut = false;
190 _getMediaTypesFor(nodeInfo, &audioIn, &audioOut, &videoIn, &videoOut);
191 _findDefaultIconFor(audioIn, audioOut, videoIn, videoOut);
192 }
193 }
194
195
196 void
_findIconFor(const dormant_node_info & nodeInfo)197 MediaIcon::_findIconFor(const dormant_node_info &nodeInfo)
198 {
199 D_INTERNAL(("MediaIcon::_findIconFor(dormant_node_info)\n"));
200
201 dormant_flavor_info flavorInfo;
202 BMediaRoster *roster = BMediaRoster::CurrentRoster();
203 status_t error = roster->GetDormantFlavorInfoFor(nodeInfo, &flavorInfo);
204 if (error == B_OK) {
205 m_nodeKind = flavorInfo.kinds;
206 bool audioIn = false, audioOut = false;
207 bool videoIn = false, videoOut = false;
208 _getMediaTypesFor(flavorInfo, &audioIn, &audioOut, &videoIn, &videoOut);
209 _findDefaultIconFor(audioIn, audioOut, videoIn, videoOut);
210 } else if (BString(nodeInfo.name).Compare("System clock") == 0) {
211 BIconUtils::GetVectorIcon(M_TIME_SOURCE_ICON,
212 sizeof(M_TIME_SOURCE_ICON), this);
213 } else {
214 // use generic icon in case we couldn't get any info
215 BIconUtils::GetVectorIcon(M_GENERIC_ICON,
216 sizeof(M_GENERIC_ICON), this);
217 }
218 }
219
220
221 void
_getMediaTypesFor(const live_node_info & nodeInfo,bool * audioIn,bool * audioOut,bool * videoIn,bool * videoOut)222 MediaIcon::_getMediaTypesFor(const live_node_info &nodeInfo, bool *audioIn,
223 bool *audioOut, bool *videoIn, bool *videoOut)
224 {
225 D_INTERNAL(("MediaIcon::_getMediaTypeFor(live_node_info)\n"));
226
227 // get the media_types supported by this node
228 const int32 numberOfInputs = 4;
229 int32 numberOfFreeInputs, numberOfConnectedInputs;
230 media_input inputs[numberOfInputs];
231 const int32 numberOfOutputs = 4;
232 int32 numberOfFreeOutputs, numberOfConnectedOutputs;
233 media_output outputs[numberOfOutputs];
234 BMediaRoster *roster = BMediaRoster::CurrentRoster();
235 if (roster->GetFreeInputsFor(nodeInfo.node, inputs, numberOfInputs,
236 &numberOfFreeInputs) == B_OK) {
237 for (int32 i = 0; i < numberOfFreeInputs; i++) {
238 if ((inputs[i].format.type == B_MEDIA_RAW_AUDIO)
239 || (inputs[i].format.type == B_MEDIA_ENCODED_AUDIO)) {
240 *audioIn = true;
241 continue;
242 }
243 if ((inputs[i].format.type == B_MEDIA_RAW_VIDEO)
244 || (inputs[i].format.type == B_MEDIA_ENCODED_VIDEO)) {
245 *videoIn = true;
246 }
247 }
248 }
249 if (roster->GetConnectedInputsFor(nodeInfo.node, inputs, numberOfInputs,
250 &numberOfConnectedInputs) == B_OK) {
251 for (int32 i = 0; i < numberOfConnectedInputs; i++) {
252 if ((inputs[i].format.type == B_MEDIA_RAW_AUDIO)
253 || (inputs[i].format.type == B_MEDIA_ENCODED_AUDIO)) {
254 *audioIn = true;
255 continue;
256 }
257 if ((inputs[i].format.type == B_MEDIA_RAW_VIDEO)
258 || (inputs[i].format.type == B_MEDIA_ENCODED_VIDEO)) {
259 *videoIn = true;
260 }
261 }
262 }
263 if (roster->GetFreeOutputsFor(nodeInfo.node, outputs, numberOfOutputs,
264 &numberOfFreeOutputs) == B_OK) {
265 for (int32 i = 0; i < numberOfFreeOutputs; i++) {
266 if ((outputs[i].format.type == B_MEDIA_RAW_AUDIO)
267 || (outputs[i].format.type == B_MEDIA_ENCODED_AUDIO)) {
268 *audioOut = true;
269 continue;
270 }
271 if ((outputs[i].format.type == B_MEDIA_RAW_VIDEO)
272 || (outputs[i].format.type == B_MEDIA_ENCODED_VIDEO)) {
273 *videoOut = true;
274 }
275 }
276 }
277 if (roster->GetConnectedOutputsFor(nodeInfo.node, outputs, numberOfOutputs,
278 &numberOfConnectedOutputs) == B_OK) {
279 for (int32 i = 0; i < numberOfConnectedOutputs; i++) {
280 if ((outputs[i].format.type == B_MEDIA_RAW_AUDIO)
281 || (outputs[i].format.type == B_MEDIA_ENCODED_AUDIO)) {
282 *audioOut = true;
283 continue;
284 }
285 if ((outputs[i].format.type == B_MEDIA_RAW_VIDEO)
286 || (outputs[i].format.type == B_MEDIA_ENCODED_VIDEO)) {
287 *videoOut = true;
288 }
289 }
290 }
291 }
292
_getMediaTypesFor(const dormant_flavor_info & flavorInfo,bool * audioIn,bool * audioOut,bool * videoIn,bool * videoOut)293 void MediaIcon::_getMediaTypesFor(
294 const dormant_flavor_info &flavorInfo,
295 bool *audioIn,
296 bool *audioOut,
297 bool *videoIn,
298 bool *videoOut) {
299 D_INTERNAL(("MediaIcon::_getMediaTypeFor(dormant_flavor_info)\n"));
300
301 for (int32 i = 0; i < flavorInfo.in_format_count; i++) {
302 if ((flavorInfo.in_formats[i].type == B_MEDIA_RAW_AUDIO)
303 || (flavorInfo.in_formats[i].type == B_MEDIA_ENCODED_AUDIO)) {
304 *audioIn = true;
305 continue;
306 }
307 if ((flavorInfo.in_formats[i].type == B_MEDIA_RAW_VIDEO)
308 || (flavorInfo.in_formats[i].type == B_MEDIA_ENCODED_VIDEO)) {
309 *videoIn = true;
310 }
311 }
312 for (int32 i = 0; i < flavorInfo.out_format_count; i++) {
313 if ((flavorInfo.out_formats[i].type == B_MEDIA_RAW_AUDIO)
314 || (flavorInfo.out_formats[i].type == B_MEDIA_ENCODED_AUDIO)) {
315 *audioOut = true;
316 continue;
317 }
318 if ((flavorInfo.out_formats[i].type == B_MEDIA_RAW_VIDEO)
319 || (flavorInfo.out_formats[i].type == B_MEDIA_ENCODED_VIDEO)) {
320 *videoOut = true;
321 }
322 }
323 }
324
_findDefaultIconFor(bool audioIn,bool audioOut,bool videoIn,bool videoOut)325 void MediaIcon::_findDefaultIconFor(
326 bool audioIn,
327 bool audioOut,
328 bool videoIn,
329 bool videoOut) {
330 D_INTERNAL(("MediaIcon::_findDefaultIcon()\n"));
331
332 if (_isTimeSource()) {
333 BIconUtils::GetVectorIcon(M_TIME_SOURCE_ICON,
334 sizeof(M_TIME_SOURCE_ICON), this);
335 return;
336 }
337
338 if (_isSystemMixer()) {
339 BIconUtils::GetVectorIcon(M_AUDIO_MIXER_ICON,
340 sizeof(M_AUDIO_MIXER_ICON), this);
341 return;
342 }
343
344 if (m_nodeKind & B_FILE_INTERFACE) {
345 if (_isProducer()) {
346 BIconUtils::GetVectorIcon(M_FILE_READER_ICON,
347 sizeof(M_FILE_READER_ICON), this);
348 return;
349 } else {
350 BIconUtils::GetVectorIcon(M_FILE_WRITER_ICON,
351 sizeof(M_FILE_WRITER_ICON), this);
352 return;
353 }
354 }
355
356 if (_isPhysicalInput()) {
357 if (audioIn) {
358 BIconUtils::GetVectorIcon(M_AUDIO_DEVICE_ICON,
359 sizeof(M_AUDIO_DEVICE_ICON), this);
360 return;
361 } else if (audioOut) {
362 BIconUtils::GetVectorIcon(M_AUDIO_INPUT_ICON,
363 sizeof(M_AUDIO_INPUT_ICON), this);
364 return;
365 } else if (videoOut) {
366 BIconUtils::GetVectorIcon(M_VIDEO_INPUT_ICON,
367 sizeof(M_VIDEO_INPUT_ICON), this);
368 return;
369 }
370 }
371
372 if (_isPhysicalOutput()) {
373 if (audioIn) {
374 BIconUtils::GetVectorIcon(M_AUDIO_OUTPUT_ICON,
375 sizeof(M_AUDIO_OUTPUT_ICON), this);
376 return;
377 } else if (videoIn) {
378 BIconUtils::GetVectorIcon(M_VIDEO_OUTPUT_ICON,
379 sizeof(M_VIDEO_OUTPUT_ICON), this);
380 return;
381 }
382 }
383
384 if (_isProducer()) {
385 if (audioOut) {
386 BIconUtils::GetVectorIcon(M_AUDIO_PRODUCER_ICON,
387 sizeof(M_AUDIO_PRODUCER_ICON), this);
388 return;
389 } else if (videoOut) {
390 BIconUtils::GetVectorIcon(M_VIDEO_PRODUCER_ICON,
391 sizeof(M_VIDEO_PRODUCER_ICON), this);
392 return;
393 }
394 }
395
396 if (_isFilter()) {
397 if (audioIn && audioOut && !videoIn && !videoOut) {
398 BIconUtils::GetVectorIcon(M_AUDIO_FILTER_ICON,
399 sizeof(M_AUDIO_FILTER_ICON), this);
400 return;
401 } else if (audioIn && !videoIn && videoOut) {
402 BIconUtils::GetVectorIcon(M_AUDIO_CONSUMER_ICON,
403 sizeof(M_AUDIO_CONSUMER_ICON), this);
404 return;
405 } else if (!audioIn && !audioOut && videoIn && videoOut) {
406 BIconUtils::GetVectorIcon(M_VIDEO_FILTER_ICON,
407 sizeof(M_VIDEO_FILTER_ICON), this);
408 return;
409 }
410 }
411
412 if (_isConsumer()) {
413 if (audioIn) {
414 BIconUtils::GetVectorIcon(M_AUDIO_CONSUMER_ICON,
415 sizeof(M_AUDIO_CONSUMER_ICON), this);
416 return;
417 } else if (videoIn) {
418 BIconUtils::GetVectorIcon(M_VIDEO_CONSUMER_ICON,
419 sizeof(M_VIDEO_CONSUMER_ICON), this);
420 return;
421 }
422 }
423
424 // assign a default icon
425 BIconUtils::GetVectorIcon(M_GENERIC_ICON, sizeof(M_GENERIC_ICON), this);
426 }
427