tcp: Fix 64 bit build with debugging features enabled.
[haiku.git] / src / kits / interface / ChannelControl.cpp
blob4e8f51ea1ad1ba08c6da1d5f0eebc845f6fac4bd
1 /*
2 * Copyright 2005-2014 Haiku Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 */
7 #include <ChannelControl.h>
8 #include <PropertyInfo.h>
10 #include <map>
11 #include <string>
13 struct limit_label {
14 std::string min_label;
15 std::string max_label;
18 typedef std::map<int32, limit_label> label_map;
20 static property_info
21 sPropertyInfo[] = {
22 { "ChannelCount",
23 { B_GET_PROPERTY, B_SET_PROPERTY, 0 },
24 { B_DIRECT_SPECIFIER, 0 }, NULL, 0, { B_INT32_TYPE }
27 { "CurrentChannel",
28 { B_GET_PROPERTY, B_SET_PROPERTY, 0 },
29 { B_DIRECT_SPECIFIER, 0 }, NULL, 0, { B_INT32_TYPE }
32 { "MaxLimitLabel",
33 { B_GET_PROPERTY, B_SET_PROPERTY, 0 },
34 { B_DIRECT_SPECIFIER, 0 }, NULL, 0, { B_STRING_TYPE }
37 { "MinLimitLabel",
38 { B_GET_PROPERTY, B_SET_PROPERTY, 0 },
39 { B_DIRECT_SPECIFIER, 0 }, NULL, 0, { B_STRING_TYPE }
42 { 0 }
46 BChannelControl::BChannelControl(BRect frame, const char* name,
47 const char* label, BMessage* model, int32 channel_count,
48 uint32 resizingMode, uint32 flags)
50 BControl(frame, name, label, model, resizingMode, flags),
51 fChannelCount(channel_count),
52 fCurrentChannel(0),
53 fChannelMin(NULL),
54 fChannelMax(NULL),
55 fChannelValues(NULL),
56 fMultiLabels(NULL),
57 fModificationMsg(NULL)
59 fChannelMin = new int32[channel_count];
60 memset(fChannelMin, 0, sizeof(int32) * channel_count);
62 fChannelMax = new int32[channel_count];
63 for (int32 i = 0; i < channel_count; i++)
64 fChannelMax[i] = 100;
66 fChannelValues = new int32[channel_count];
67 memset(fChannelValues, 0, sizeof(int32) * channel_count);
69 fMultiLabels = (void*)new label_map;
73 BChannelControl::BChannelControl(const char* name, const char* label,
74 BMessage* model, int32 channelCount, uint32 flags)
76 BControl(name, label, model, flags),
77 fChannelCount(channelCount),
78 fCurrentChannel(0),
79 fChannelMin(NULL),
80 fChannelMax(NULL),
81 fChannelValues(NULL),
82 fMultiLabels(NULL),
83 fModificationMsg(NULL)
85 fChannelMin = new int32[channelCount];
86 memset(fChannelMin, 0, sizeof(int32) * channelCount);
88 fChannelMax = new int32[channelCount];
89 for (int32 i = 0; i < channelCount; i++)
90 fChannelMax[i] = 100;
92 fChannelValues = new int32[channelCount];
93 memset(fChannelValues, 0, sizeof(int32) * channelCount);
95 fMultiLabels = (void*)new label_map;
99 BChannelControl::BChannelControl(BMessage* archive)
101 BControl(archive),
102 fChannelCount(0),
103 fCurrentChannel(0),
104 fChannelMin(NULL),
105 fChannelMax(NULL),
106 fChannelValues(NULL),
107 fMultiLabels(NULL),
108 fModificationMsg(NULL)
110 archive->FindInt32("be:_m_channel_count", &fChannelCount);
111 archive->FindInt32("be:_m_value_channel", &fCurrentChannel);
113 if (fChannelCount > 0) {
114 fChannelMin = new int32[fChannelCount];
115 memset(fChannelMin, 0, sizeof(int32) * fChannelCount);
117 fChannelMax = new int32[fChannelCount];
118 for (int32 i = 0; i < fChannelCount; i++)
119 fChannelMax[i] = 100;
121 fChannelValues = new int32[fChannelCount];
122 memset(fChannelValues, 0, sizeof(int32) * fChannelCount);
124 for (int32 c = 0; c < fChannelCount; c++) {
125 archive->FindInt32("be:_m_channel_min", c, &fChannelMin[c]);
126 archive->FindInt32("be:_m_channel_max", c, &fChannelMax[c]);
127 archive->FindInt32("be:_m_channel_val", c, &fChannelValues[c]);
131 const char* label = NULL;
132 if (archive->FindString("be:_m_min_label", &label) == B_OK)
133 fMinLabel = label;
135 if (archive->FindString("be:_m_max_label", &label) == B_OK)
136 fMaxLabel = label;
138 BMessage* modificationMessage = new BMessage;
139 if (archive->FindMessage("_mod_msg", modificationMessage) == B_OK)
140 fModificationMsg = modificationMessage;
141 else
142 delete modificationMessage;
144 fMultiLabels = (void*)new label_map;
148 BChannelControl::~BChannelControl()
150 delete[] fChannelMin;
151 delete[] fChannelMax;
152 delete[] fChannelValues;
153 delete fModificationMsg;
154 delete reinterpret_cast<label_map*>(fMultiLabels);
158 status_t
159 BChannelControl::Archive(BMessage* data, bool deep) const
161 status_t status = BControl::Archive(data, deep);
162 if (status == B_OK)
163 status = data->AddInt32("be:_m_channel_count", fChannelCount);
165 if (status == B_OK)
166 status = data->AddInt32("be:_m_value_channel", fCurrentChannel);
168 if (status == B_OK)
169 status = data->AddString("be:_m_min_label", fMinLabel.String());
171 if (status == B_OK)
172 status = data->AddString("be:_m_max_label", fMaxLabel.String());
174 if (status == B_OK && fChannelValues != NULL
175 && fChannelMax != NULL && fChannelMin != NULL) {
176 for (int32 i = 0; i < fChannelCount; i++) {
177 status = data->AddInt32("be:_m_channel_min", fChannelMin[i]);
178 if (status < B_OK)
179 break;
181 status = data->AddInt32("be:_m_channel_max", fChannelMax[i]);
182 if (status < B_OK)
183 break;
185 status = data->AddInt32("be:_m_channel_val", fChannelValues[i]);
186 if (status < B_OK)
187 break;
191 return status;
195 void
196 BChannelControl::FrameResized(float newWidth, float newHeight)
198 BView::FrameResized(newWidth, newHeight);
202 void
203 BChannelControl::SetFont(const BFont* font, uint32 mask)
205 BView::SetFont(font, mask);
209 void
210 BChannelControl::AttachedToWindow()
212 BControl::AttachedToWindow();
216 void
217 BChannelControl::DetachedFromWindow()
219 BControl::DetachedFromWindow();
223 void
224 BChannelControl::ResizeToPreferred()
226 BControl::ResizeToPreferred();
230 void
231 BChannelControl::MessageReceived(BMessage* message)
233 BControl::MessageReceived(message);
237 BHandler*
238 BChannelControl::ResolveSpecifier(BMessage* message, int32 index,
239 BMessage* specifier, int32 what, const char* property)
241 BHandler* target = this;
242 BPropertyInfo propertyInfo(sPropertyInfo);
243 if (propertyInfo.FindMatch(message, index, specifier, what, property)
244 < B_OK) {
245 target = BControl::ResolveSpecifier(message, index, specifier,
246 what, property);
249 return target;
253 status_t
254 BChannelControl::GetSupportedSuites(BMessage* data)
256 if (data == NULL)
257 return B_BAD_VALUE;
259 status_t err = data->AddString("suites", "suite/vnd.Be-channel-control");
261 BPropertyInfo propertyInfo(sPropertyInfo);
262 if (err == B_OK)
263 err = data->AddFlat("messages", &propertyInfo);
265 if (err == B_OK)
266 return BControl::GetSupportedSuites(data);
268 return err;
272 void
273 BChannelControl::SetModificationMessage(BMessage* message)
275 delete fModificationMsg;
276 fModificationMsg = message;
280 BMessage*
281 BChannelControl::ModificationMessage() const
283 return fModificationMsg;
287 status_t
288 BChannelControl::Invoke(BMessage* message)
290 bool notify = false;
291 BMessage invokeMessage(InvokeKind(&notify));
293 if (message != NULL)
294 invokeMessage = *message;
295 else if (Message() != NULL)
296 invokeMessage = *Message();
298 invokeMessage.AddInt32("be:current_channel", fCurrentChannel);
300 return BControl::Invoke(&invokeMessage);
304 status_t
305 BChannelControl::InvokeChannel(BMessage* message, int32 fromChannel,
306 int32 channelCount, const bool* _mask)
308 bool notify = false;
309 BMessage invokeMessage(InvokeKind(&notify));
311 if (message != NULL)
312 invokeMessage = *message;
313 else if (Message() != NULL)
314 invokeMessage = *Message();
316 invokeMessage.AddInt32("be:current_channel", fCurrentChannel);
317 if (channelCount < 0)
318 channelCount = fChannelCount - fromChannel;
320 for (int32 i = 0; i < channelCount; i++) {
321 invokeMessage.AddInt32("be:channel_value",
322 fChannelValues[fromChannel + i]);
323 invokeMessage.AddBool("be:channel_changed", _mask ? _mask[i] : true);
326 return BControl::Invoke(&invokeMessage);
330 status_t
331 BChannelControl::InvokeNotifyChannel(BMessage* message, uint32 kind,
332 int32 fromChannel, int32 channelCount, const bool* _mask)
334 BeginInvokeNotify(kind);
335 status_t status = InvokeChannel(message, fromChannel, channelCount, _mask);
336 EndInvokeNotify();
338 return status;
342 void
343 BChannelControl::SetValue(int32 value)
345 // Get real
346 if (value > fChannelMax[fCurrentChannel])
347 value = fChannelMax[fCurrentChannel];
349 if (value < fChannelMin[fCurrentChannel])
350 value = fChannelMin[fCurrentChannel];
352 if (value != fChannelValues[fCurrentChannel]) {
353 StuffValues(fCurrentChannel, 1, &value);
354 BControl::SetValue(value);
359 status_t
360 BChannelControl::SetCurrentChannel(int32 channel)
362 if (channel < 0 || channel >= fChannelCount)
363 return B_BAD_INDEX;
365 if (channel != fCurrentChannel) {
366 fCurrentChannel = channel;
367 BControl::SetValue(fChannelValues[fCurrentChannel]);
370 return B_OK;
374 int32
375 BChannelControl::CurrentChannel() const
377 return fCurrentChannel;
381 int32
382 BChannelControl::CountChannels() const
384 return fChannelCount;
388 status_t
389 BChannelControl::SetChannelCount(int32 channel_count)
391 if (channel_count < 0 || channel_count >= MaxChannelCount())
392 return B_BAD_VALUE;
394 // TODO: Currently we only grow the buffer. Test what BeOS does
395 if (channel_count > fChannelCount) {
396 int32* newMin = new int32[channel_count];
397 int32* newMax = new int32[channel_count];
398 int32* newVal = new int32[channel_count];
400 memcpy(newMin, fChannelMin, fChannelCount);
401 memcpy(newMax, fChannelMax, fChannelCount);
402 memcpy(newVal, fChannelValues, fChannelCount);
404 delete[] fChannelMin;
405 delete[] fChannelMax;
406 delete[] fChannelValues;
408 fChannelMin = newMin;
409 fChannelMax = newMax;
410 fChannelValues = newVal;
413 fChannelCount = channel_count;
415 return B_OK;
419 int32
420 BChannelControl::ValueFor(int32 channel) const
422 int32 value = 0;
423 if (GetValue(&value, channel, 1) <= 0)
424 return -1;
426 return value;
430 int32
431 BChannelControl::GetValue(int32* outValues, int32 fromChannel,
432 int32 channelCount) const
434 int32 i = 0;
435 for (i = 0; i < channelCount; i++)
436 outValues[i] = fChannelValues[fromChannel + i];
438 return i;
442 status_t
443 BChannelControl::SetValueFor(int32 channel, int32 value)
445 return SetValue(channel, 1, &value);
449 status_t
450 BChannelControl::SetValue(int32 fromChannel, int32 channelCount,
451 const int32* values)
453 return StuffValues(fromChannel, channelCount, values);
457 status_t
458 BChannelControl::SetAllValue(int32 values)
460 int32* newValues = new int32[fChannelCount];
461 for (int32 i = 0; i < fChannelCount; i++) {
462 int32 limitedValue = max_c(values, MinLimitList()[i]);
463 limitedValue = min_c(limitedValue, MaxLimitList()[i]);
465 newValues[i] = limitedValue;
468 delete[] fChannelValues;
469 fChannelValues = newValues;
470 BControl::SetValue(fChannelValues[fCurrentChannel]);
472 return B_OK;
476 status_t
477 BChannelControl::SetLimitsFor(int32 channel, int32 minimum, int32 maximum)
479 return SetLimitsFor(channel, 1, &minimum, &maximum);
483 status_t
484 BChannelControl::GetLimitsFor(int32 channel, int32* minimum,
485 int32* maximum) const
487 return GetLimitsFor(channel, 1, minimum, maximum);
491 status_t
492 BChannelControl::SetLimitsFor(int32 fromChannel, int32 channelCount,
493 const int32* minimum, const int32* maximum)
495 if (fromChannel + channelCount > CountChannels())
496 channelCount = CountChannels() - fromChannel;
498 for (int i = 0; i < channelCount; i++) {
499 if (minimum[i] > maximum[i])
500 return B_BAD_VALUE;
502 fChannelMin[fromChannel + i] = minimum[i];
503 fChannelMax[fromChannel + i] = maximum[i];
504 if (fChannelValues[fromChannel + i] < minimum[i])
505 fChannelValues[fromChannel + i] = minimum[i];
506 else if (fChannelValues[fromChannel + i] > maximum[i])
507 fChannelValues[fromChannel + i] = maximum[i];
510 return B_OK;
514 status_t
515 BChannelControl::GetLimitsFor(int32 fromChannel, int32 channelCount,
516 int32* minimum, int32* maximum) const
518 if (minimum == NULL || maximum == NULL)
519 return B_BAD_VALUE;
521 if (fChannelMin == NULL || fChannelMax == NULL)
522 return B_ERROR;
523 if (fromChannel + channelCount > CountChannels())
524 channelCount = CountChannels() - fromChannel;
526 for (int i = 0; i < channelCount; i++) {
527 minimum[i] = fChannelMin[fromChannel + i];
528 maximum[i] = fChannelMax[fromChannel + i];
531 return B_OK;
535 status_t
536 BChannelControl::SetLimits(int32 minimum, int32 maximum)
538 if (minimum > maximum)
539 return B_BAD_VALUE;
541 int32 numChannels = CountChannels();
543 for (int32 c = 0; c < numChannels; c++) {
544 fChannelMin[c] = minimum;
545 fChannelMax[c] = maximum;
546 if (fChannelValues[c] < minimum)
547 fChannelValues[c] = minimum;
548 else if (fChannelValues[c] > maximum)
549 fChannelValues[c] = maximum;
552 return B_OK;
556 status_t
557 BChannelControl::GetLimits(int32* outMinimum, int32* outMaximum) const
559 if (outMinimum == NULL || outMaximum == NULL)
560 return B_BAD_VALUE;
562 if (fChannelMin == NULL || fChannelMax == NULL)
563 return B_ERROR;
565 int32 numChannels = CountChannels();
566 for (int32 c = 0; c < numChannels; c++) {
567 outMinimum[c] = fChannelMin[c];
568 outMaximum[c] = fChannelMax[c];
571 return B_OK;
575 status_t
576 BChannelControl::SetLimitLabels(const char* minLabel, const char* maxLabel)
578 if (minLabel != fMinLabel)
579 fMinLabel = minLabel;
581 if (maxLabel != fMaxLabel)
582 fMaxLabel = maxLabel;
584 Invalidate();
586 return B_OK;
590 const char*
591 BChannelControl::MinLimitLabel() const
593 return fMinLabel.String();
597 const char*
598 BChannelControl::MaxLimitLabel() const
600 return fMaxLabel.String();
604 status_t
605 BChannelControl::SetLimitLabelsFor(int32 channel, const char* minLabel,
606 const char* maxLabel)
608 (*(label_map*)fMultiLabels)[channel].max_label = maxLabel;
609 (*(label_map*)fMultiLabels)[channel].min_label = minLabel;
610 return B_OK;
614 status_t
615 BChannelControl::SetLimitLabelsFor(int32 fromChannel, int32 channelCount,
616 const char* minLabel, const char* maxLabel)
618 for (int32 i = fromChannel; i < fromChannel + channelCount; i++) {
619 SetLimitLabelsFor(i, minLabel, maxLabel);
621 return B_OK;
625 const char*
626 BChannelControl::MinLimitLabelFor(int32 channel) const
628 if (fMultiLabels != NULL) {
629 label_map::const_iterator iter = ((label_map*)fMultiLabels)->find(channel);
630 if (iter != ((label_map*)fMultiLabels)->end())
631 return (*iter).second.min_label.c_str();
633 return NULL;
637 const char*
638 BChannelControl::MaxLimitLabelFor(int32 channel) const
640 if (fMultiLabels != NULL) {
641 label_map::const_iterator iter = ((label_map*)fMultiLabels)->find(channel);
642 if (iter != ((label_map*)fMultiLabels)->end())
643 return (*iter).second.max_label.c_str();
645 return NULL;
649 status_t
650 BChannelControl::StuffValues(int32 fromChannel, int32 channelCount,
651 const int32* values)
653 if (values == NULL)
654 return B_BAD_VALUE;
656 if (fromChannel < 0 || fromChannel > fChannelCount
657 || fromChannel + channelCount > fChannelCount) {
658 return B_BAD_INDEX;
661 for (int32 i = 0; i < channelCount; i++) {
662 if (values[i] <= fChannelMax[fromChannel + i]
663 && values[i] >= fChannelMin[fromChannel + i]) {
664 fChannelValues[fromChannel + i] = values[i];
668 // if the current channel was updated, update also the control value
669 if (fCurrentChannel >= fromChannel
670 && fCurrentChannel <= fromChannel + channelCount) {
671 BControl::SetValue(fChannelValues[fCurrentChannel]);
674 return B_OK;
678 void BChannelControl::_Reserverd_ChannelControl_0(void*, ...) {}
679 void BChannelControl::_Reserverd_ChannelControl_1(void*, ...) {}
680 void BChannelControl::_Reserverd_ChannelControl_2(void*, ...) {}
681 void BChannelControl::_Reserverd_ChannelControl_3(void*, ...) {}
682 void BChannelControl::_Reserverd_ChannelControl_4(void*, ...) {}
683 void BChannelControl::_Reserverd_ChannelControl_5(void*, ...) {}
684 void BChannelControl::_Reserverd_ChannelControl_6(void*, ...) {}
685 void BChannelControl::_Reserverd_ChannelControl_7(void*, ...) {}
686 void BChannelControl::_Reserverd_ChannelControl_8(void*, ...) {}
687 void BChannelControl::_Reserverd_ChannelControl_9(void*, ...) {}
688 void BChannelControl::_Reserverd_ChannelControl_10(void*, ...) {}
689 void BChannelControl::_Reserverd_ChannelControl_11(void*, ...) {}