* Replaced the volume slider with one looking just like any other slider.
* This is still work in progress, though. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@30014 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
a353e90fa0
commit
b494a17f1c
@ -110,7 +110,7 @@ DeskButton::MessageReceived(BMessage *message)
|
||||
case B_ABOUT_REQUESTED:
|
||||
(new BAlert("About Desklink", "Desklink (Replicant)\n"
|
||||
" Brought to you by Jérôme DUVAL.\n\n"
|
||||
"Copyright " B_UTF8_COPYRIGHT "2003-2007, Haiku","OK"))->Go();
|
||||
"Copyright " B_UTF8_COPYRIGHT "2003-2009, Haiku","OK"))->Go();
|
||||
break;
|
||||
case OPEN_REF:
|
||||
be_roster->Launch(&fRef);
|
||||
|
@ -2,18 +2,12 @@ SubDir HAIKU_TOP src bin desklink ;
|
||||
|
||||
SetSubDirSupportedPlatformsBeOSCompatible ;
|
||||
|
||||
if ! $(TARGET_PLATFORM_HAIKU_COMPATIBLE) {
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) headers os interface ] : true ;
|
||||
# We need the public interface headers also when not compiling for Haiku.
|
||||
UseHeaders [ FDirName $(HAIKU_TOP) headers os ] : true ;
|
||||
# We need the public headers also when not compiling for Haiku.
|
||||
}
|
||||
|
||||
BinCommand desklink :
|
||||
desklink.cpp
|
||||
VolumeSlider.cpp
|
||||
DeskButton.cpp
|
||||
MixerControl.cpp
|
||||
|
||||
: be libmedia.so
|
||||
: desklink.rdef
|
||||
;
|
||||
|
||||
;
|
||||
|
212
src/bin/desklink/MixerControl.cpp
Normal file
212
src/bin/desklink/MixerControl.cpp
Normal file
@ -0,0 +1,212 @@
|
||||
/*
|
||||
* Copyright 2003-2009, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT license.
|
||||
*
|
||||
* Authors:
|
||||
* Jérôme Duval
|
||||
* François Revol
|
||||
*/
|
||||
|
||||
|
||||
#include "MixerControl.h"
|
||||
|
||||
#include <Debug.h>
|
||||
#include <ParameterWeb.h>
|
||||
|
||||
|
||||
MixerControl::MixerControl(int32 volumeWhich, float* _value,
|
||||
const char** _error)
|
||||
:
|
||||
fAudioMixerNode(NULL),
|
||||
fParameterWeb(NULL),
|
||||
fMixerParameter(NULL),
|
||||
fMin(0.0f),
|
||||
fMax(0.0f),
|
||||
fStep(0.0f)
|
||||
{
|
||||
bool retrying = false;
|
||||
fAudioMixerNode = new media_node();
|
||||
|
||||
status_t err = B_OK;
|
||||
/* BMediaRoster::Roster() doesn't set it if all is ok */
|
||||
const char* errorString = NULL;
|
||||
BMediaRoster* roster = BMediaRoster::Roster(&err);
|
||||
|
||||
retry:
|
||||
// Here we release the BMediaRoster once if we can't access the system
|
||||
// mixer, to make sure it really isn't there, and it's not BMediaRoster
|
||||
// that is messed up.
|
||||
if (retrying) {
|
||||
errorString = NULL;
|
||||
PRINT(("retrying to get a Media Roster\n"));
|
||||
/* BMediaRoster looks doomed */
|
||||
roster = BMediaRoster::CurrentRoster();
|
||||
if (roster) {
|
||||
roster->Lock();
|
||||
roster->Quit();
|
||||
}
|
||||
snooze(10000);
|
||||
roster = BMediaRoster::Roster(&err);
|
||||
}
|
||||
|
||||
if (roster && err == B_OK) {
|
||||
switch (volumeWhich) {
|
||||
case VOLUME_USE_MIXER:
|
||||
err = roster->GetAudioMixer(fAudioMixerNode);
|
||||
break;
|
||||
case VOLUME_USE_PHYS_OUTPUT:
|
||||
err = roster->GetAudioOutput(fAudioMixerNode);
|
||||
break;
|
||||
}
|
||||
if (err == B_OK) {
|
||||
err = roster->GetParameterWebFor(*fAudioMixerNode, &fParameterWeb);
|
||||
if (err == B_OK) {
|
||||
// Finding the Mixer slider in the audio output ParameterWeb
|
||||
int32 numParams = fParameterWeb->CountParameters();
|
||||
BParameter* p = NULL;
|
||||
bool foundMixerLabel = false;
|
||||
for (int i = 0; i < numParams; i++) {
|
||||
p = fParameterWeb->ParameterAt(i);
|
||||
PRINT(("BParameter[%i]: %s\n", i, p->Name()));
|
||||
if (volumeWhich == VOLUME_USE_MIXER) {
|
||||
if (!strcmp(p->Kind(), B_MASTER_GAIN))
|
||||
break;
|
||||
} else if (volumeWhich == VOLUME_USE_PHYS_OUTPUT) {
|
||||
/* not all cards use the same name, and
|
||||
* they don't seem to use Kind() == B_MASTER_GAIN
|
||||
*/
|
||||
if (!strcmp(p->Kind(), B_MASTER_GAIN))
|
||||
break;
|
||||
PRINT(("not MASTER_GAIN \n"));
|
||||
|
||||
/* some audio card
|
||||
*/
|
||||
if (!strcmp(p->Name(), "Master"))
|
||||
break;
|
||||
PRINT(("not 'Master' \n"));
|
||||
|
||||
/* some Ensonic card have all controls names 'Volume', so
|
||||
* need to fint the one that has the 'Mixer' text label
|
||||
*/
|
||||
if (foundMixerLabel && !strcmp(p->Name(), "Volume"))
|
||||
break;
|
||||
if (!strcmp(p->Name(), "Mixer"))
|
||||
foundMixerLabel = true;
|
||||
PRINT(("not 'Mixer' \n"));
|
||||
}
|
||||
#if 0
|
||||
//if (!strcmp(p->Name(), "Master")) {
|
||||
if (!strcmp(p->Kind(), B_MASTER_GAIN)) {
|
||||
for (; i < numParams; i++) {
|
||||
p = fParamWeb->ParameterAt(i);
|
||||
if (strcmp(p->Kind(), B_MASTER_GAIN)) p=NULL;
|
||||
else break;
|
||||
}
|
||||
break;
|
||||
} else p = NULL;
|
||||
#endif
|
||||
p = NULL;
|
||||
}
|
||||
if (p == NULL) {
|
||||
errorString = volumeWhich
|
||||
? "Could not find the soundcard":"Could not find the mixer";
|
||||
} else if (p->Type() != BParameter::B_CONTINUOUS_PARAMETER) {
|
||||
errorString = volumeWhich
|
||||
? "Soundcard control unknown":"Mixer control unknown";
|
||||
} else {
|
||||
fMixerParameter = dynamic_cast<BContinuousParameter*>(p);
|
||||
fMin = fMixerParameter->MinValue();
|
||||
fMax = fMixerParameter->MaxValue();
|
||||
fStep = fMixerParameter->ValueStep();
|
||||
|
||||
if (_value != NULL) {
|
||||
float volume;
|
||||
bigtime_t lastChange;
|
||||
size_t size = sizeof(float);
|
||||
fMixerParameter->GetValue(&volume, &size, &lastChange);
|
||||
|
||||
*_value = volume;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
errorString = "No parameter web";
|
||||
}
|
||||
} else {
|
||||
if (!retrying) {
|
||||
retrying = true;
|
||||
goto retry;
|
||||
}
|
||||
errorString = volumeWhich ? "No Audio output" : "No Mixer";
|
||||
}
|
||||
} else {
|
||||
if (!retrying) {
|
||||
retrying = true;
|
||||
goto retry;
|
||||
}
|
||||
errorString = "No Media Roster";
|
||||
}
|
||||
|
||||
if (err != B_OK) {
|
||||
delete fAudioMixerNode;
|
||||
fAudioMixerNode = NULL;
|
||||
}
|
||||
if (errorString) {
|
||||
fprintf(stderr, "MixerControl: %s.\n", errorString);
|
||||
if (_error)
|
||||
*_error = errorString;
|
||||
}
|
||||
if (fMixerParameter == NULL && _value != NULL)
|
||||
*_value = 0;
|
||||
}
|
||||
|
||||
|
||||
MixerControl::~MixerControl()
|
||||
{
|
||||
delete fParameterWeb;
|
||||
|
||||
BMediaRoster* roster = BMediaRoster::CurrentRoster();
|
||||
if (roster != NULL && fAudioMixerNode != NULL)
|
||||
roster->ReleaseNode(*fAudioMixerNode);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MixerControl::SetVolume(float volume)
|
||||
{
|
||||
if (fMixerParameter == NULL)
|
||||
return;
|
||||
|
||||
if (volume < fMin)
|
||||
volume = fMin;
|
||||
else if (volume > fMax)
|
||||
volume = fMax;
|
||||
|
||||
if (volume != _GetVolume())
|
||||
fMixerParameter->SetValue(&volume, sizeof(float), system_time());
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MixerControl::ChangeVolumeBy(float value)
|
||||
{
|
||||
if (fMixerParameter == NULL || value == 0.0f)
|
||||
return;
|
||||
|
||||
float volume = _GetVolume();
|
||||
SetVolume(volume + value);
|
||||
}
|
||||
|
||||
|
||||
float
|
||||
MixerControl::_GetVolume()
|
||||
{
|
||||
if (fMixerParameter == NULL)
|
||||
return 0.0f;
|
||||
|
||||
float volume = 0;
|
||||
bigtime_t lastChange;
|
||||
size_t size = sizeof(float);
|
||||
fMixerParameter->GetValue(&volume, &size, &lastChange);
|
||||
|
||||
return volume;
|
||||
}
|
46
src/bin/desklink/MixerControl.h
Normal file
46
src/bin/desklink/MixerControl.h
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright 2003-2009, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT license.
|
||||
*
|
||||
* Authors:
|
||||
* Jérôme Duval
|
||||
* François Revol
|
||||
*/
|
||||
#ifndef MIXER_CONTROL_H
|
||||
#define MIXER_CONTROL_H
|
||||
|
||||
|
||||
#include <MediaRoster.h>
|
||||
|
||||
class BParameterWeb;
|
||||
class BContinuousParameter;
|
||||
|
||||
|
||||
// The volume which choices
|
||||
#define VOLUME_USE_MIXER 0 // default
|
||||
#define VOLUME_USE_PHYS_OUTPUT 1
|
||||
|
||||
|
||||
class MixerControl {
|
||||
public:
|
||||
MixerControl(int32 volumeWhich, float *value = NULL,
|
||||
const char **error = NULL);
|
||||
~MixerControl();
|
||||
|
||||
void SetVolume(float volume);
|
||||
void ChangeVolumeBy(float value);
|
||||
|
||||
float Minimum() const { return fMin; }
|
||||
float Maximum() const { return fMax; }
|
||||
|
||||
private:
|
||||
float _GetVolume();
|
||||
void _SetVolume(float volume);
|
||||
|
||||
media_node* fAudioMixerNode;
|
||||
BParameterWeb* fParameterWeb;
|
||||
BContinuousParameter* fMixerParameter;
|
||||
float fMin, fMax, fStep;
|
||||
};
|
||||
|
||||
#endif // MIXER_CONTROL_H
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2007, Haiku, Inc.
|
||||
* Copyright 2003-2009, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT license.
|
||||
*
|
||||
* Authors:
|
||||
@ -7,322 +7,52 @@
|
||||
* François Revol
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include <MediaRoster.h>
|
||||
#include <MediaTheme.h>
|
||||
#include <MultiChannelControl.h>
|
||||
#include <Screen.h>
|
||||
#include <Beep.h>
|
||||
#include <Box.h>
|
||||
#include <stdio.h>
|
||||
#include <Debug.h>
|
||||
|
||||
#include "VolumeSlider.h"
|
||||
#include "iconfile.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <Beep.h>
|
||||
#include <Box.h>
|
||||
#include <ControlLook.h>
|
||||
#include <Debug.h>
|
||||
#include <GroupLayout.h>
|
||||
#include <Screen.h>
|
||||
#include <Slider.h>
|
||||
|
||||
#include "MixerControl.h"
|
||||
|
||||
#define VOLUME_CHANGED 'vlcg'
|
||||
#define VOLUME_UPDATED 'vlud'
|
||||
|
||||
#define REDZONESTART 151
|
||||
|
||||
class SliderView : public BSlider {
|
||||
public:
|
||||
SliderView(const char* name, const char* label,
|
||||
BMessage *message, int32 minValue,
|
||||
int32 maxValue);
|
||||
virtual ~SliderView();
|
||||
|
||||
virtual void MouseDown(BPoint where);
|
||||
virtual void MessageReceived(BMessage* msg);
|
||||
virtual void DrawBar();
|
||||
virtual const char* UpdateText() const;
|
||||
|
||||
private:
|
||||
mutable char fText[64];
|
||||
};
|
||||
|
||||
|
||||
|
||||
MixerControl::MixerControl(int32 volumeWhich, float *value, const char **error)
|
||||
:
|
||||
fAudioMixerNode(NULL),
|
||||
fParamWeb(NULL),
|
||||
fMixerParam(NULL),
|
||||
fMin(0.0),
|
||||
fMax(0.0),
|
||||
fStep(0.0)
|
||||
{
|
||||
bool retrying = false;
|
||||
fAudioMixerNode = new media_node();
|
||||
|
||||
status_t err = B_OK; /* BMediaRoster::Roster() doesn't set it if all is ok */
|
||||
const char *errString = NULL;
|
||||
BMediaRoster* roster = BMediaRoster::Roster(&err);
|
||||
|
||||
retry:
|
||||
/* here we release the BMediaRoster once if we can't access the system mixer,
|
||||
* to make sure it really isn't there, and it's not BMediaRoster that is messed up.
|
||||
*/
|
||||
if (retrying) {
|
||||
errString = NULL;
|
||||
PRINT(("retrying to get a Media Roster\n"));
|
||||
/* BMediaRoster looks doomed */
|
||||
roster = BMediaRoster::CurrentRoster();
|
||||
if (roster) {
|
||||
roster->Lock();
|
||||
roster->Quit();
|
||||
}
|
||||
snooze(10000);
|
||||
roster = BMediaRoster::Roster(&err);
|
||||
}
|
||||
|
||||
if (roster && err == B_OK) {
|
||||
switch (volumeWhich) {
|
||||
case VOLUME_USE_MIXER:
|
||||
err = roster->GetAudioMixer(fAudioMixerNode);
|
||||
break;
|
||||
case VOLUME_USE_PHYS_OUTPUT:
|
||||
err = roster->GetAudioOutput(fAudioMixerNode);
|
||||
break;
|
||||
}
|
||||
if (err == B_OK) {
|
||||
if ((err = roster->GetParameterWebFor(*fAudioMixerNode, &fParamWeb)) == B_OK) {
|
||||
// Finding the Mixer slider in the audio output ParameterWeb
|
||||
int32 numParams = fParamWeb->CountParameters();
|
||||
BParameter* p = NULL;
|
||||
bool foundMixerLabel = false;
|
||||
for (int i = 0; i < numParams; i++) {
|
||||
p = fParamWeb->ParameterAt(i);
|
||||
PRINT(("BParameter[%i]: %s\n", i, p->Name()));
|
||||
if (volumeWhich == VOLUME_USE_MIXER) {
|
||||
if (!strcmp(p->Kind(), B_MASTER_GAIN))
|
||||
break;
|
||||
} else if (volumeWhich == VOLUME_USE_PHYS_OUTPUT) {
|
||||
/* not all cards use the same name, and
|
||||
* they don't seem to use Kind() == B_MASTER_GAIN
|
||||
*/
|
||||
if (!strcmp(p->Kind(), B_MASTER_GAIN))
|
||||
break;
|
||||
PRINT(("not MASTER_GAIN \n"));
|
||||
|
||||
/* some audio card
|
||||
*/
|
||||
if (!strcmp(p->Name(), "Master"))
|
||||
break;
|
||||
PRINT(("not 'Master' \n"));
|
||||
|
||||
/* some Ensonic card have all controls names 'Volume', so
|
||||
* need to fint the one that has the 'Mixer' text label
|
||||
*/
|
||||
if (foundMixerLabel && !strcmp(p->Name(), "Volume"))
|
||||
break;
|
||||
if (!strcmp(p->Name(), "Mixer"))
|
||||
foundMixerLabel = true;
|
||||
PRINT(("not 'Mixer' \n"));
|
||||
}
|
||||
#if 0
|
||||
//if (!strcmp(p->Name(), "Master")) {
|
||||
if (!strcmp(p->Kind(), B_MASTER_GAIN)) {
|
||||
for (; i < numParams; i++) {
|
||||
p = fParamWeb->ParameterAt(i);
|
||||
if (strcmp(p->Kind(), B_MASTER_GAIN)) p=NULL;
|
||||
else break;
|
||||
}
|
||||
break;
|
||||
} else p = NULL;
|
||||
#endif
|
||||
p = NULL;
|
||||
}
|
||||
if (p == NULL) {
|
||||
errString = volumeWhich
|
||||
? "Could not find the soundcard":"Could not find the mixer";
|
||||
} else if (p->Type() != BParameter::B_CONTINUOUS_PARAMETER) {
|
||||
errString = volumeWhich
|
||||
? "Soundcard control unknown":"Mixer control unknown";
|
||||
} else {
|
||||
fMixerParam = dynamic_cast<BContinuousParameter*>(p);
|
||||
fMin = fMixerParam->MinValue();
|
||||
fMax = fMixerParam->MaxValue();
|
||||
fStep = fMixerParam->ValueStep();
|
||||
|
||||
float chanData[2];
|
||||
bigtime_t lastChange;
|
||||
size_t size = sizeof(chanData);
|
||||
|
||||
fMixerParam->GetValue(&chanData, &size, &lastChange);
|
||||
|
||||
if (value)
|
||||
*value = (chanData[0] - fMin) * 100 / ((fMax - fMin) ? (fMax - fMin) : 1);
|
||||
}
|
||||
} else {
|
||||
errString = "No parameter web";
|
||||
}
|
||||
} else {
|
||||
if (!retrying) {
|
||||
retrying = true;
|
||||
goto retry;
|
||||
}
|
||||
errString = volumeWhich ? "No Audio output" : "No Mixer";
|
||||
}
|
||||
} else {
|
||||
if (!retrying) {
|
||||
retrying = true;
|
||||
goto retry;
|
||||
}
|
||||
errString = "No Media Roster";
|
||||
}
|
||||
|
||||
if (err != B_OK) {
|
||||
delete fAudioMixerNode;
|
||||
fAudioMixerNode = NULL;
|
||||
}
|
||||
if (errString) {
|
||||
fprintf(stderr, "MixerControl: %s.\n", errString);
|
||||
if (error)
|
||||
*error = errString;
|
||||
}
|
||||
if (fMixerParam == NULL)
|
||||
*value = -1;
|
||||
}
|
||||
|
||||
|
||||
MixerControl::~MixerControl()
|
||||
SliderView::SliderView(const char* name, const char* label, BMessage *message,
|
||||
int32 minValue, int32 maxValue)
|
||||
: BSlider("slider", label, message, minValue, maxValue, B_HORIZONTAL)
|
||||
{
|
||||
delete fParamWeb;
|
||||
BMediaRoster* roster = BMediaRoster::CurrentRoster();
|
||||
if (roster && fAudioMixerNode)
|
||||
roster->ReleaseNode(*fAudioMixerNode);
|
||||
}
|
||||
font_height fontHeight;
|
||||
GetFontHeight(&fontHeight);
|
||||
SetBarThickness(ceilf((fontHeight.ascent + fontHeight.descent) * 0.7));
|
||||
|
||||
|
||||
void
|
||||
MixerControl::UpdateVolume(int32 value)
|
||||
{
|
||||
if (!fMixerParam)
|
||||
return;
|
||||
|
||||
float chanData[2];
|
||||
bigtime_t lastChange;
|
||||
size_t size = sizeof(chanData);
|
||||
|
||||
fMixerParam->GetValue(&chanData, &size, &lastChange);
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
chanData[i] = (value * (fMax - fMin) / 100) / fStep * fStep + fMin;
|
||||
}
|
||||
|
||||
PRINT(("Min value: %f Max Value: %f\nData: %f %f\n",
|
||||
fMixerParam->MinValue(), fMixerParam->MaxValue(), chanData[0], chanData[1]));
|
||||
fMixerParam->SetValue(&chanData, sizeof(chanData), system_time()+1000);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MixerControl::ChangeVolumeBy(int32 value)
|
||||
{
|
||||
if (!fMixerParam)
|
||||
return;
|
||||
|
||||
float chanData[2];
|
||||
bigtime_t lastChange;
|
||||
size_t size = sizeof(chanData);
|
||||
|
||||
fMixerParam->GetValue(&chanData, &size, &lastChange);
|
||||
|
||||
for (int i = 0; i < 2; i++) {
|
||||
chanData[i] += fStep * value;
|
||||
if (chanData[i] < fMin)
|
||||
chanData[i] = fMin;
|
||||
else if (chanData[i] > fMax)
|
||||
chanData[i] = fMax;
|
||||
}
|
||||
|
||||
PRINT(("Min value: %f Max Value: %f\nData: %f %f\n",
|
||||
fMixerParam->MinValue(), fMixerParam->MaxValue(), chanData[0], chanData[1]));
|
||||
fMixerParam->SetValue(&chanData, sizeof(chanData), system_time()+1000);
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
VolumeSlider::VolumeSlider(BRect frame, bool dontBeep, int32 volumeWhich)
|
||||
: BWindow(frame, "VolumeSlider", B_BORDERED_WINDOW_LOOK, B_FLOATING_ALL_WINDOW_FEEL,
|
||||
B_ASYNCHRONOUS_CONTROLS | B_WILL_ACCEPT_FIRST_CLICK, 0)
|
||||
{
|
||||
// Make sure it's not outside the screen.
|
||||
const int32 kMargin = 3;
|
||||
BRect windowRect = ConvertToScreen(Bounds());
|
||||
BRect screenFrame(BScreen(B_MAIN_SCREEN_ID).Frame());
|
||||
if (screenFrame.right < windowRect.right + kMargin)
|
||||
MoveBy(- kMargin - windowRect.right + screenFrame.right, 0);
|
||||
if (screenFrame.bottom < windowRect.bottom + kMargin)
|
||||
MoveBy(0, - kMargin - windowRect.bottom + screenFrame.bottom);
|
||||
if (screenFrame.left > windowRect.left - kMargin)
|
||||
MoveBy(kMargin + screenFrame.left - windowRect.left, 0);
|
||||
if (screenFrame.top > windowRect.top - kMargin)
|
||||
MoveBy(0, kMargin + screenFrame.top - windowRect.top);
|
||||
|
||||
float value = 0.0;
|
||||
fDontBeep = dontBeep;
|
||||
const char *errString = NULL;
|
||||
fMixerControl = new MixerControl(volumeWhich, &value, &errString);
|
||||
|
||||
BBox *box = new BBox(Bounds(), "sliderbox", B_FOLLOW_LEFT | B_FOLLOW_TOP,
|
||||
B_WILL_DRAW | B_FRAME_EVENTS, B_PLAIN_BORDER);
|
||||
AddChild(box);
|
||||
|
||||
fHasChanged = false; /* make sure we don't beep if we don't change anything */
|
||||
fSlider = new SliderView(box->Bounds().InsetByCopy(1, 1), new BMessage(VOLUME_CHANGED),
|
||||
errString == NULL ? "Volume" : errString, B_FOLLOW_LEFT | B_FOLLOW_TOP, (int32)value);
|
||||
box->AddChild(fSlider);
|
||||
|
||||
fSlider->SetTarget(this);
|
||||
|
||||
SetPulseRate(100);
|
||||
}
|
||||
|
||||
|
||||
VolumeSlider::~VolumeSlider()
|
||||
{
|
||||
delete fMixerControl;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
VolumeSlider::WindowActivated(bool active)
|
||||
{
|
||||
/* don't Quit() ! thanks for FFM users */
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
VolumeSlider::MessageReceived(BMessage *msg)
|
||||
{
|
||||
switch (msg->what) {
|
||||
case VOLUME_UPDATED:
|
||||
PRINT(("VOLUME_UPDATED\n"));
|
||||
fMixerControl->UpdateVolume(fSlider->Value());
|
||||
fHasChanged = true;
|
||||
break;
|
||||
|
||||
case VOLUME_CHANGED:
|
||||
if (fHasChanged) {
|
||||
PRINT(("VOLUME_CHANGED\n"));
|
||||
fMixerControl->UpdateVolume(fSlider->Value());
|
||||
if (!fDontBeep)
|
||||
beep();
|
||||
}
|
||||
Quit();
|
||||
break;
|
||||
|
||||
default:
|
||||
BWindow::MessageReceived(msg); // not a slider message, not our problem
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
SliderView::SliderView(BRect rect, BMessage *msg, const char *title,
|
||||
uint32 resizeFlags, int32 value)
|
||||
: BControl(rect, "slider", NULL, msg, resizeFlags, B_WILL_DRAW | B_PULSE_NEEDED),
|
||||
fLeftBitmap(BRect(0, 0, kLeftWidth - 1, kLeftHeight - 1), B_CMAP8),
|
||||
fRightBitmap(BRect(0, 0, kRightWidth - 1, kRightHeight - 1), B_CMAP8),
|
||||
fButtonBitmap(BRect(0, 0, kButtonWidth - 1, kButtonHeight - 1), B_CMAP8),
|
||||
fTitle(title)
|
||||
{
|
||||
fLeftBitmap.SetBits(kLeftBits, kLeftWidth * kLeftHeight, 0, B_CMAP8);
|
||||
fRightBitmap.SetBits(kRightBits, kRightWidth * kRightHeight, 0, B_CMAP8);
|
||||
fButtonBitmap.SetBits(kButtonBits, kButtonWidth * kButtonHeight, 0, B_CMAP8);
|
||||
|
||||
SetValue(value);
|
||||
SetEventMask(B_POINTER_EVENTS, B_NO_POINTER_HISTORY);
|
||||
}
|
||||
|
||||
@ -333,49 +63,12 @@ SliderView::~SliderView()
|
||||
|
||||
|
||||
void
|
||||
SliderView::Draw(BRect updateRect)
|
||||
SliderView::MouseDown(BPoint where)
|
||||
{
|
||||
SetHighColor(189,186,189);
|
||||
StrokeLine(BPoint(11,1), BPoint(192,1));
|
||||
SetHighColor(0,0,0);
|
||||
StrokeLine(BPoint(11,2), BPoint(192,2));
|
||||
SetHighColor(255,255,255);
|
||||
StrokeLine(BPoint(11,14), BPoint(192,14));
|
||||
SetHighColor(231,227,231);
|
||||
StrokeLine(BPoint(11,15), BPoint(192,15));
|
||||
if (!IsEnabled() || !Bounds().Contains(where))
|
||||
Invoke();
|
||||
|
||||
SetLowColor(ViewColor());
|
||||
|
||||
SetDrawingMode(B_OP_OVER);
|
||||
|
||||
DrawBitmapAsync(&fLeftBitmap, BPoint(5,1));
|
||||
DrawBitmapAsync(&fRightBitmap, BPoint(193,1));
|
||||
|
||||
float position = 11 + (192-11) * ((Value() == -1) ? 0 : Value()) / 100;
|
||||
float right = (position < REDZONESTART) ? position : REDZONESTART;
|
||||
SetHighColor(99,151,99);
|
||||
FillRect(BRect(11,3,right,4));
|
||||
SetHighColor(156,203,156);
|
||||
FillRect(BRect(11,5,right,13));
|
||||
if (right == REDZONESTART) {
|
||||
SetHighColor(156,101,99);
|
||||
FillRect(BRect(REDZONESTART,3,position,4));
|
||||
SetHighColor(255,154,156);
|
||||
FillRect(BRect(REDZONESTART,5,position,13));
|
||||
}
|
||||
SetHighColor(156,154,156);
|
||||
FillRect(BRect(position,3,192,13));
|
||||
|
||||
float width = be_plain_font->StringWidth(fTitle);
|
||||
|
||||
SetHighColor(49,154,49);
|
||||
DrawString(fTitle, BPoint(11 + (192-11-width)/2, 12));
|
||||
|
||||
DrawBitmapAsync(&fButtonBitmap, BPoint(position-5,3));
|
||||
|
||||
Sync();
|
||||
|
||||
SetDrawingMode(B_OP_COPY);
|
||||
BSlider::MouseDown(where);
|
||||
}
|
||||
|
||||
|
||||
@ -422,62 +115,124 @@ SliderView::MessageReceived(BMessage* msg)
|
||||
|
||||
|
||||
void
|
||||
SliderView::MouseDown(BPoint point)
|
||||
SliderView::DrawBar()
|
||||
{
|
||||
if (Bounds().Contains(point)) {
|
||||
SetTracking(true);
|
||||
MouseMoved(point, B_INSIDE_VIEW, NULL);
|
||||
} else
|
||||
Invoke();
|
||||
BRect frame = BarFrame();
|
||||
BView* view = OffscreenView();
|
||||
|
||||
if (be_control_look != NULL) {
|
||||
uint32 flags = be_control_look->Flags(this);
|
||||
rgb_color base = ui_color(B_PANEL_BACKGROUND_COLOR);
|
||||
rgb_color rightFillColor = (rgb_color){255, 109, 38, 255};
|
||||
rgb_color leftFillColor = (rgb_color){116, 224, 0, 255};
|
||||
|
||||
int32 min, max;
|
||||
GetLimits(&min, &max);
|
||||
float position = 1.0f * (max - min - max) / (max - min);
|
||||
|
||||
be_control_look->DrawSliderBar(view, frame, frame, base, leftFillColor,
|
||||
rightFillColor, position, flags, Orientation());
|
||||
return;
|
||||
}
|
||||
|
||||
BSlider::DrawBar();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SliderView::MouseMoved(BPoint point, uint32 transit, const BMessage *message)
|
||||
const char*
|
||||
SliderView::UpdateText() const
|
||||
{
|
||||
if (!IsTracking())
|
||||
return;
|
||||
snprintf(fText, sizeof(fText), "%ld dB", Value());
|
||||
return fText;
|
||||
}
|
||||
|
||||
int32 mouseButtons;
|
||||
Window()->CurrentMessage()->FindInt32("buttons", &mouseButtons);
|
||||
|
||||
// button not pressed, exit
|
||||
if (!(mouseButtons & B_PRIMARY_MOUSE_BUTTON)) {
|
||||
Invoke();
|
||||
SetTracking(false);
|
||||
}
|
||||
// #pragma mark -
|
||||
|
||||
if (Value() == -1)
|
||||
return;
|
||||
|
||||
float v = MIN(MAX(point.x, 11), 192);
|
||||
v = (v - 11) / (192-11) * 100;
|
||||
v = MAX(MIN(v,100), 0);
|
||||
SetValue((int32)v);
|
||||
Draw(Bounds());
|
||||
Flush();
|
||||
VolumeSlider::VolumeSlider(BRect frame, bool dontBeep, int32 volumeWhich)
|
||||
: BWindow(frame, "VolumeSlider", B_BORDERED_WINDOW_LOOK,
|
||||
B_FLOATING_ALL_WINDOW_FEEL,
|
||||
B_ASYNCHRONOUS_CONTROLS | B_WILL_ACCEPT_FIRST_CLICK, 0)
|
||||
{
|
||||
fDontBeep = dontBeep;
|
||||
|
||||
if (Window())
|
||||
Window()->PostMessage(VOLUME_UPDATED);
|
||||
const char *errorString = NULL;
|
||||
float value = 0.0;
|
||||
fMixerControl = new MixerControl(volumeWhich, &value, &errorString);
|
||||
|
||||
SetLayout(new BGroupLayout(B_HORIZONTAL));
|
||||
|
||||
BGroupLayout* layout = new BGroupLayout(B_HORIZONTAL);
|
||||
layout->SetInsets(10, 0, 10, 0);
|
||||
|
||||
BBox* box = new BBox("sliderbox");
|
||||
box->SetLayout(layout);
|
||||
box->SetBorder(B_PLAIN_BORDER);
|
||||
AddChild(box);
|
||||
|
||||
fHasChanged = false;
|
||||
// make sure we don't beep if we don't change anything
|
||||
|
||||
fSlider = new SliderView("volume", errorString ? errorString : "Volume",
|
||||
new BMessage(VOLUME_CHANGED), fMixerControl->Minimum(),
|
||||
fMixerControl->Maximum());
|
||||
fSlider->SetValue((int32)value);
|
||||
fSlider->SetModificationMessage(new BMessage(VOLUME_UPDATED));
|
||||
if (errorString != NULL)
|
||||
fSlider->SetEnabled(false);
|
||||
box->AddChild(fSlider);
|
||||
|
||||
fSlider->SetTarget(this);
|
||||
SetPulseRate(100);
|
||||
ResizeTo(300, 50);
|
||||
|
||||
// Make sure it's not outside the screen.
|
||||
const int32 kMargin = 3;
|
||||
BRect windowRect = Frame();
|
||||
BRect screenFrame(BScreen(B_MAIN_SCREEN_ID).Frame());
|
||||
if (screenFrame.right < windowRect.right + kMargin)
|
||||
MoveBy(- kMargin - windowRect.right + screenFrame.right, 0);
|
||||
if (screenFrame.bottom < windowRect.bottom + kMargin)
|
||||
MoveBy(0, - kMargin - windowRect.bottom + screenFrame.bottom);
|
||||
if (screenFrame.left > windowRect.left - kMargin)
|
||||
MoveBy(kMargin + screenFrame.left - windowRect.left, 0);
|
||||
if (screenFrame.top > windowRect.top - kMargin)
|
||||
MoveBy(0, kMargin + screenFrame.top - windowRect.top);
|
||||
}
|
||||
|
||||
|
||||
VolumeSlider::~VolumeSlider()
|
||||
{
|
||||
delete fMixerControl;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SliderView::MouseUp(BPoint point)
|
||||
VolumeSlider::MessageReceived(BMessage *msg)
|
||||
{
|
||||
if (!IsTracking())
|
||||
return;
|
||||
switch (msg->what) {
|
||||
case VOLUME_UPDATED:
|
||||
puts("updated");
|
||||
PRINT(("VOLUME_UPDATED\n"));
|
||||
fMixerControl->SetVolume(fSlider->Value());
|
||||
fHasChanged = true;
|
||||
break;
|
||||
|
||||
if (Value() != -1 && Bounds().InsetBySelf(2, 2).Contains(point)) {
|
||||
float v = MIN(MAX(point.x, 11), 192);
|
||||
v = (v - 11) / (192-11) * 100;
|
||||
v = MAX(MIN(v,100), 0);
|
||||
SetValue((int32)v);
|
||||
case VOLUME_CHANGED:
|
||||
puts("changed");
|
||||
if (fHasChanged) {
|
||||
PRINT(("VOLUME_CHANGED\n"));
|
||||
fMixerControl->SetVolume(fSlider->Value());
|
||||
if (!fDontBeep)
|
||||
beep();
|
||||
}
|
||||
Quit();
|
||||
break;
|
||||
|
||||
default:
|
||||
BWindow::MessageReceived(msg);
|
||||
break;
|
||||
}
|
||||
|
||||
Invoke();
|
||||
SetTracking(false);
|
||||
Draw(Bounds());
|
||||
Flush();
|
||||
}
|
||||
|
||||
|
@ -1,68 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2003-2007, Haiku, Inc.
|
||||
* Copyright 2003-2009, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT license.
|
||||
*
|
||||
* Authors:
|
||||
* Jérôme Duval
|
||||
* François Revol
|
||||
*/
|
||||
#ifndef VOLUMESLIDER_H
|
||||
#define VOLUMESLIDER_H
|
||||
#ifndef VOLUME_SLIDER_H
|
||||
#define VOLUME_SLIDER_H
|
||||
|
||||
|
||||
#include <Window.h>
|
||||
#include <Control.h>
|
||||
#include <Bitmap.h>
|
||||
#include <ParameterWeb.h>
|
||||
|
||||
#define VOLUME_USE_MIXER 0 /* default */
|
||||
#define VOLUME_USE_PHYS_OUTPUT 1
|
||||
|
||||
|
||||
class MixerControl {
|
||||
public:
|
||||
MixerControl(int32 volumeWhich, float *value = NULL, const char **error = NULL);
|
||||
~MixerControl();
|
||||
|
||||
void UpdateVolume(int32 value);
|
||||
void ChangeVolumeBy(int32 incr);
|
||||
private:
|
||||
media_node *fAudioMixerNode;
|
||||
BParameterWeb* fParamWeb;
|
||||
BContinuousParameter* fMixerParam;
|
||||
float fMin, fMax, fStep;
|
||||
};
|
||||
|
||||
|
||||
class SliderView : public BControl {
|
||||
public:
|
||||
SliderView(BRect rect, BMessage *msg, const char* title, uint32 resizeFlags,
|
||||
int32 value);
|
||||
~SliderView();
|
||||
|
||||
virtual void Draw(BRect);
|
||||
virtual void MessageReceived(BMessage*);
|
||||
virtual void MouseDown(BPoint point);
|
||||
virtual void MouseMoved(BPoint point, uint32 transit, const BMessage *message);
|
||||
virtual void MouseUp(BPoint point);
|
||||
|
||||
private:
|
||||
BBitmap fLeftBitmap, fRightBitmap, fButtonBitmap;
|
||||
const char* fTitle;
|
||||
};
|
||||
class BSlider;
|
||||
class MixerControl;
|
||||
|
||||
class VolumeSlider : public BWindow {
|
||||
public:
|
||||
VolumeSlider(BRect frame, bool dontBeep=false, int32 volumeWhich=0);
|
||||
~VolumeSlider();
|
||||
public:
|
||||
VolumeSlider(BRect frame, bool dontBeep = false,
|
||||
int32 volumeWhich = 0);
|
||||
~VolumeSlider();
|
||||
|
||||
void MessageReceived(BMessage*);
|
||||
void WindowActivated(bool active);
|
||||
protected:
|
||||
void MessageReceived(BMessage* message);
|
||||
|
||||
private:
|
||||
MixerControl *fMixerControl;
|
||||
bool fHasChanged;
|
||||
bool fDontBeep;
|
||||
SliderView *fSlider;
|
||||
private:
|
||||
MixerControl* fMixerControl;
|
||||
bool fHasChanged;
|
||||
bool fDontBeep;
|
||||
BSlider* fSlider;
|
||||
};
|
||||
|
||||
#endif // VOLUMESLIDER_H
|
||||
#endif // VOLUME_SLIDER_H
|
||||
|
@ -11,9 +11,8 @@
|
||||
|
||||
//! VolumeControl and link items in Deskbar
|
||||
|
||||
#include "VolumeSlider.h"
|
||||
#include "DeskButton.h"
|
||||
#include "iconfile.h"
|
||||
#include <stdio.h>
|
||||
#include <strings.h>
|
||||
|
||||
#include <Alert.h>
|
||||
#include <Application.h>
|
||||
@ -33,8 +32,11 @@
|
||||
#include <String.h>
|
||||
#include <View.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <strings.h>
|
||||
#include "DeskButton.h"
|
||||
#include "iconfile.h"
|
||||
#include "MixerControl.h"
|
||||
#include "VolumeSlider.h"
|
||||
|
||||
|
||||
#define MEDIA_SETTINGS 'mese'
|
||||
#define SOUND_SETTINGS 'sose'
|
||||
@ -161,7 +163,7 @@ MediaReplicant::MessageReceived(BMessage *message)
|
||||
case B_ABOUT_REQUESTED:
|
||||
(new BAlert("About Volume Control", "Volume Control (Replicant)\n"
|
||||
" Brought to you by Jérôme DUVAL.\n\n"
|
||||
"Copyright " B_UTF8_COPYRIGHT "2003-2008, Haiku","OK"))->Go(NULL);
|
||||
"Copyright " B_UTF8_COPYRIGHT "2003-2009, Haiku","OK"))->Go(NULL);
|
||||
break;
|
||||
|
||||
case OPEN_MEDIA_PLAYER:
|
||||
@ -424,6 +426,9 @@ MediaReplicant::_AlertFindDirectory(status_t status, const char *where)
|
||||
}
|
||||
|
||||
|
||||
// #pragma mark -
|
||||
|
||||
|
||||
int
|
||||
main(int, char **argv)
|
||||
{
|
||||
@ -455,6 +460,16 @@ main(int, char **argv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (strcmp(argv[i], "--volume") == 0) {
|
||||
entry_ref ref;
|
||||
if (get_ref_for_path(argv[0], &ref) == B_OK) {
|
||||
deskbar.AddItem(&ref);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (strncmp(argv[i], "--remove", 8) == 0) {
|
||||
BString replicant = "DeskButton";
|
||||
if (strncmp(argv[i] + 8, "=", 1) == 0) {
|
||||
|
@ -15,7 +15,7 @@ resource app_version {
|
||||
internal = 0,
|
||||
|
||||
short_info = "desklink",
|
||||
long_info = "desklink ©2003-2007 Haiku"
|
||||
long_info = "desklink ©2003-2009 Haiku"
|
||||
};
|
||||
|
||||
resource app_flags B_MULTIPLE_LAUNCH | B_ARGV_ONLY | B_BACKGROUND_APP ;
|
||||
|
@ -29,65 +29,3 @@ const unsigned char kSpeakerBits [] = {
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x0f,0x0f,0xff,0xff,0xff,0xff,0xff
|
||||
};
|
||||
|
||||
const int32 kButtonWidth = 16;
|
||||
const int32 kButtonHeight = 11;
|
||||
const color_space kButtonColorSpace = B_CMAP8;
|
||||
|
||||
const unsigned char kButtonBits [] = {
|
||||
0xff,0xff,0xff,0x18,0x1d,0x3f,0x1d,0x19,0x12,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0x15,0x1d,0x1e,0x1e,0x1d,0x1e,0x1b,0x19,0x12,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0x1e,0x1e,0x1d,0x1d,0x3f,0x1d,0x1d,0x1b,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0x1a,0x1e,0x1d,0x1d,0x1d,0xff,0x1d,0x1d,0x1d,0x19,0x12,0xff,0xff,0xff,0xff,0xff,
|
||||
0x1e,0x1e,0x1d,0x1d,0x1d,0x3f,0x1d,0x1d,0x1d,0x19,0x11,0xff,0xff,0xff,0xff,0xff,
|
||||
0x3f,0x1d,0x1d,0x1d,0x1d,0xff,0x1d,0x1d,0x1d,0x1c,0x0e,0xff,0xff,0xff,0xff,0xff,
|
||||
0x1e,0x1e,0x1d,0x1d,0x1d,0x3f,0x1d,0x1d,0x1d,0x19,0x11,0xff,0xff,0xff,0xff,0xff,
|
||||
0x1a,0x1d,0x1d,0x1d,0x1d,0xff,0x1d,0x1d,0x1d,0x15,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0x1a,0x19,0x1d,0x1d,0x1d,0x1d,0x1d,0x17,0x12,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0x16,0xff,0x15,0x19,0x1c,0x19,0x15,0x12,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0x14,0x11,0x0e,0x11,0x14,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
|
||||
};
|
||||
|
||||
const int32 kLeftWidth = 16;
|
||||
const int32 kLeftHeight = 15;
|
||||
const color_space kLeftColorSpace = B_CMAP8;
|
||||
|
||||
const unsigned char kLeftBits [] = {
|
||||
0xff,0xff,0xff,0xff,0x19,0x19,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0x1a,0x18,0x11,0x0b,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0x19,0x15,0x0b,0x06,0x0a,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0x1a,0x15,0x09,0x09,0xb6,0x8f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0x18,0x0b,0x09,0x8f,0x8f,0x8f,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0x11,0x07,0xb6,0x8f,0x8f,0x68,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0x0c,0x0c,0x8f,0x8f,0x68,0x68,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0x07,0x10,0x8f,0x68,0x68,0x68,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0x16,0x12,0x8f,0x68,0x68,0x68,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0x1a,0x16,0x11,0x68,0x68,0x68,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0x1a,0x18,0x68,0x68,0x68,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0x1c,0x19,0x68,0x68,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0x1d,0x1c,0x19,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0x1d,0x1e,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0xff,0xff,0xff,0xff,0xff,0x1c,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
|
||||
};
|
||||
|
||||
const int32 kRightWidth = 16;
|
||||
const int32 kRightHeight = 15;
|
||||
const color_space kRightColorSpace = B_CMAP8;
|
||||
|
||||
const unsigned char kRightBits [] = {
|
||||
0x19,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0x11,0x18,0x1a,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0x08,0x0d,0x16,0x1a,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0x11,0x0c,0x0f,0x17,0x1a,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0x13,0x13,0x10,0x14,0x19,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0x13,0x13,0x13,0x15,0x19,0x1a,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0x13,0x13,0x13,0x16,0x1a,0x1a,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0x13,0x13,0x13,0x15,0x1c,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0x13,0x13,0x13,0x19,0x1e,0x1c,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0x13,0x13,0x15,0x1d,0x1d,0x1c,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0x13,0x14,0x1a,0x1e,0x1c,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0x15,0xff,0x3f,0x1d,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0x1d,0x1e,0x1d,0x1c,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0x1d,0x1c,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
|
||||
0x1c,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user