This commit is contained in:
Adam D. Ruppe 2014-12-22 13:54:23 -05:00
parent 6c3507ca3b
commit 92ad388884
4 changed files with 70 additions and 11 deletions

View File

@ -438,7 +438,13 @@ version(linux) {
private void addFileToLoopImplementation(int fd, int events) {
epoll_event ev;
ev.events = EPOLL_EVENTS.EPOLLET; // edge triggered
// I don't remember why I made it edge triggered in the first
// place as that requires a bit more care to do correctly and I don't
// think I've ever taken that kind of care. I'm going to try switching it
// to level triggered (the event fires whenever the loop goes through and
// there's still data available) and see if things work better.
// ev.events = EPOLL_EVENTS.EPOLLET; // edge triggered
if(events & FileEvents.read)
ev.events |= EPOLL_EVENTS.EPOLLIN;

View File

@ -636,8 +636,9 @@ struct var {
this._type = Type.Array;
var[] arr;
arr.length = t.length;
foreach(i, item; t)
arr[i] = var(item);
static if(!is(T == void[])) // we can't append a void array but it is nice to support x = [];
foreach(i, item; t)
arr[i] = var(item);
this._payload._array = arr;
} else static if(is(T == bool)) {
this._type = Type.Boolean;
@ -647,6 +648,10 @@ struct var {
return this;
}
public size_t opDollar() {
return this.length().get!size_t;
}
public var opOpAssign(string op, T)(T t) {
if(payloadType() == Type.Object) {
var* operator = this._payload._object._peekMember("opOpAssign", true);

View File

@ -294,6 +294,7 @@ struct MidiOutput {
}
}
// FIXME: maybe add a PC speaker beep function for completeness
/// Interfaces with the default sound card. You should only have a single instance of this and it should
@ -317,7 +318,7 @@ struct AudioMixer {
snd_mixer_selem_id_t* sid;
snd_mixer_elem_t* selem;
c_long maxVolume, minVolume;
c_long maxVolume, minVolume; // these are ok to use if you are writing ALSA specific code i guess
enum selemName = "Master";
}
@ -353,16 +354,45 @@ struct AudioMixer {
if(auto err = snd_mixer_selem_get_playback_volume_range(selem, &minVolume, &maxVolume))
throw new AlsaException("get volume range", err);
version(with_eventloop) {
import arsd.eventloop;
addFileEventListeners(getAlsaFileDescriptors()[0], &eventListener, null, null);
setAlsaElemCallback(&alsaCallback);
}
} else static assert(0);
}
~this() {
version(ALSA) {
version(with_eventloop) {
import arsd.eventloop;
removeFileEventListeners(getAlsaFileDescriptors()[0]);
}
snd_mixer_selem_id_free(sid);
snd_mixer_close(handle);
} else static assert(0);
}
version(ALSA)
version(with_eventloop) {
static struct MixerEvent {}
nothrow @nogc
extern(C) static int alsaCallback(snd_mixer_elem_t*, uint) {
import arsd.eventloop;
try
send(MixerEvent());
catch(Exception)
return 1;
return 0;
}
void eventListener(int fd) {
handleAlsaEvents();
}
}
/// Gets the master channel's mute state
/// Note: this affects shared system state and you should not use it unless the end user wants you to.
@property bool muteMaster() {
@ -384,12 +414,19 @@ struct AudioMixer {
}
/// returns a percentage, between 0 and 100 (inclusive)
/// Note: this affects shared system state and you should not use it unless the end user wants you to.
int getMasterVolume() {
version(ALSA) {
auto volume = getMasterVolumeExact();
return volume * 100 / (maxVolume - minVolume);
} else static assert(0);
}
/// Gets the exact value returned from the operating system. The range may vary.
int getMasterVolumeExact() {
version(ALSA) {
c_long volume;
snd_mixer_selem_get_playback_volume(selem, 0, &volume);
return volume * 100 / (maxVolume - minVolume);
return volume;
} else static assert(0);
}
@ -398,8 +435,15 @@ struct AudioMixer {
void setMasterVolume(int volume) {
version(ALSA) {
assert(volume >= 0 && volume <= 100);
snd_mixer_selem_set_playback_volume_all(selem,
volume * (maxVolume - minVolume) / 100);
setMasterVolumeExact(volume * (maxVolume - minVolume) / 100);
} else static assert(0);
}
/// Sets an exact volume. Must be in range of the OS provided min and max.
void setMasterVolumeExact(int volume) {
version(ALSA) {
if(auto err = snd_mixer_selem_set_playback_volume_all(selem, volume))
throw new AlsaException("set volume", err);
} else static assert(0);
}

View File

@ -2350,6 +2350,10 @@ void main() {
FIXME: support lines that wrap
FIXME: better controls maybe
FIXME: support multi-line "lines" and some form of line continuation, both
from the user (if permitted) and from the application, so like the user
hits "class foo { \n" and the app says "that line needs continuation" automatically.
FIXME: fix lengths on prompt and suggestion
A note on history:
@ -2757,7 +2761,7 @@ class LineGetter {
case InputEvent.Type.EndOfFileEvent:
justHitTab = false;
return false;
break;
//break;
case InputEvent.Type.CharacterEvent:
if(e.characterEvent.eventType == CharacterEvent.Type.Released)
return true;
@ -2899,11 +2903,11 @@ class LineGetter {
case InputEvent.Type.UserInterruptionEvent:
/* I'll take this as canceling the line. */
throw new Exception("user canceled"); // FIXME
break;
//break;
case InputEvent.Type.HangupEvent:
/* I'll take this as canceling the line. */
throw new Exception("user hanged up"); // FIXME
break;
//break;
default:
/* ignore. ideally it wouldn't be passed to us anyway! */
}