Re: [sugar] [PATCH] Add speaker device and icon by default

2008-05-30 Thread Martin Dengler
On Wed, May 14, 2008 at 12:14:57PM +0200, Tomeu Vizoso wrote:
> Hi, sorry for the delay.

Same here - was on holiday.

> 
> On Tue, May 13, 2008 at 12:43 AM, Martin Dengler
> <[EMAIL PROTECTED]> wrote:
> >  +def get_mute(self):
> 
> You use 'muted' instead of 'mute' below, which one is more correct?

I prefer 'muted', because 'muted' sounds more like a predicate/boolean
to me and 'mute' sounds more like a verb.  (consider 'get_stopped()'
vs. 'get_stop').  Changed get_mute() to get_muted().

> >  +if not self._mixer or not self._master:
> >  +logging.error('Cannot get the mute status')
> >  +return False
> 
> Shouldn't we return True if there's no way to get the volume?

I thought we should assume we're not muted if we don't know what the
volume is, but I think I see your point.  I don't think the return
value is sensible in this scenario, though, so perhaps we should
raise()?  I don't have strong feelings, so I've changed to return
True.

> >  diff --git a/src/model/devices/Makefile.am b/src/model/devices/Makefile.am
> >  index 5440eeb..3124144 100644
> >  --- a/src/model/devices/Makefile.am
> >  +++ b/src/model/devices/Makefile.am
> >  @@ -5,4 +5,6 @@ sugar_PYTHON =  \
> > __init__.py \
> > device.py   \
> > devicesmodel.py \
> >  -   battery.py
> >  +   battery.py  \
> >  +   speaker.py
> 
> Just as a comment, the convention is to sort files alphabetically (it
> was already wrong).

Gotcha - I didn't want to reorder but as I'm changing the battery.py
line anyway I'll reorder it.

> >  @@ -54,6 +55,13 @@ class DevicesModel(gobject.GObject):
> >
> >  for udi in hal_manager.FindDeviceByCapability('battery'):
> >  self.add_device(battery.Device(udi))
> >
> >  +try:
> >
> > +self.add_device(speaker.Device())
> >  +except Exception, speaker_fail_msg:
> >  +logging.error("could not initialize speaker device: %s" %
> >  +  speaker_fail_msg)
> >  +logging.debug(traceback.format_exc())
> 
> I would add the speaker device in the constructor, instead of in
> _observe_hal_manager().

It should be in the constructor, I agree.  I'm sure I put it there
but...must've slipped a method somehow.  Scary.  Moved.

> Perhaps we should add try..except blocks to all the add_device calls?
> Not in this patch, though.

Yes, possibly.  It's the Device-subclass __init__ and the .py file
import itself that we have to worry about, though, I think (consider
that the logical extension of what you've said would be to just put a
try...except in add_device()).  Something to think about in a later
patch, I agree.

> >  +def get_type(self):
> >  +return 'speaker'
> 
> Maybe should be a constant at the module level?

Every Device-subclass implements this method in a similar form.  I'm
not a huge fan of this function - __name__ should be enough.
AFAICS, it's just a way of helping deviceview.py with the fact that
model & view implementations are split at a high level
(src/{model,view}/...):
http://dev.laptop.org/git?p=sugar;a=blob;f=src/view/devices/deviceview.py;h=90ebbf55413925f537a9e9e900d3828bb4f28bac;hb=HEAD
.

Assuming you prefer the consistency I'll leave this as-is, but I'm not
at all bothered about changing it.

> >  +def do_get_property(self, pspec):
> >  +if pspec.name == "level":
> >  +return self._get_level()
> >  +elif pspec.name == "muted":
> >  +return self._get_muted()
> 
> See above comment about muted vs mute.

ibid/fixed.

> >  +self._adjustment = gtk.Adjustment(
> >  +self._model.props.level, 0.0, 101.0, 1, 1, 1)
> 
> Not the most common of breaking an arg list, but I don't particularly care.

I don't know much gtk so the Adjustment positional args mean little to
me - I have to look them up each time I care - so far about twice :).
I've looked them up a third time and tried a bit more sensical split.

> Thanks!

Thank you!

> Tomeu

Martin


pgpeYmngRZ2Hb.pgp
Description: PGP signature
___
Sugar mailing list
Sugar@lists.laptop.org
http://lists.laptop.org/listinfo/sugar


Re: [sugar] [PATCH] Add speaker device and icon by default

2008-05-14 Thread Tomeu Vizoso
Hi, sorry for the delay.

On Tue, May 13, 2008 at 12:43 AM, Martin Dengler
<[EMAIL PROTECTED]> wrote:
>  +def get_mute(self):

You use 'muted' instead of 'mute' below, which one is more correct?

>  +if not self._mixer or not self._master:
>  +logging.error('Cannot get the mute status')
>  +return False

Shouldn't we return True if there's no way to get the volume?

>  diff --git a/src/model/devices/Makefile.am b/src/model/devices/Makefile.am
>  index 5440eeb..3124144 100644
>  --- a/src/model/devices/Makefile.am
>  +++ b/src/model/devices/Makefile.am
>  @@ -5,4 +5,6 @@ sugar_PYTHON =  \
> __init__.py \
> device.py   \
> devicesmodel.py \
>  -   battery.py
>  +   battery.py  \
>  +   speaker.py

Just as a comment, the convention is to sort files alphabetically (it
was already wrong).

>  @@ -54,6 +55,13 @@ class DevicesModel(gobject.GObject):
>
>  for udi in hal_manager.FindDeviceByCapability('battery'):
>  self.add_device(battery.Device(udi))
>
>  +try:
>
> +self.add_device(speaker.Device())
>  +except Exception, speaker_fail_msg:
>  +logging.error("could not initialize speaker device: %s" %
>  +  speaker_fail_msg)
>  +logging.debug(traceback.format_exc())

I would add the speaker device in the constructor, instead of in
_observe_hal_manager().

Perhaps we should add try..except blocks to all the add_device calls?
Not in this patch, though.

>  +def get_type(self):
>  +return 'speaker'

Maybe should be a constant at the module level?

>  +def do_get_property(self, pspec):
>  +if pspec.name == "level":
>  +return self._get_level()
>  +elif pspec.name == "muted":
>  +return self._get_muted()

See above comment about muted vs mute.

>  +self._adjustment = gtk.Adjustment(
>  +self._model.props.level, 0.0, 101.0, 1, 1, 1)

Not the most common of breaking an arg list, but I don't particularly care.

Thanks!

Tomeu
___
Sugar mailing list
Sugar@lists.laptop.org
http://lists.laptop.org/listinfo/sugar


[sugar] [PATCH] Add speaker device and icon by default

2008-05-12 Thread Martin Dengler
Add speaker device and icon by default, as in
http://wiki.laptop.org/go/Designs/Frame#07
---
 src/hardware/hardwaremanager.py   |   31 +-
 src/model/devices/Makefile.am |4 +-
 src/model/devices/devicesmodel.py |8 +++
 src/model/devices/speaker.py  |   59 ++
 src/view/devices/Makefile.am  |4 +-
 src/view/devices/speaker.py   |  119 +
 6 files changed, 220 insertions(+), 5 deletions(-)
 create mode 100644 src/model/devices/speaker.py
 create mode 100644 src/view/devices/speaker.py

diff --git a/src/hardware/hardwaremanager.py b/src/hardware/hardwaremanager.py
index 5b9e330..284a283 100644
--- a/src/hardware/hardwaremanager.py
+++ b/src/hardware/hardwaremanager.py
@@ -50,6 +50,13 @@ class HardwareManager(object):
 if track.flags & gst.interfaces.MIXER_TRACK_MASTER:
 self._master = track
 
+def get_mute(self):
+if not self._mixer or not self._master:
+logging.error('Cannot get the mute status')
+return False
+return self._master.flags & gst.interfaces.MIXER_TRACK_MUTE \
+ == gst.interfaces.MIXER_TRACK_MUTE
+
 def get_volume(self):
 if not self._mixer or not self._master:
 logging.error('Cannot get the volume')
@@ -57,9 +64,19 @@ class HardwareManager(object):
 
 max_volume = self._master.max_volume
 min_volume = self._master.min_volume
-volume = self._mixer.get_volume(self._master)[0]
 
-return volume * 100.0 / (max_volume - min_volume) + min_volume
+volumes = self._mixer.get_volume(self._master)
+
+#sometimes we get a spurious zero from one/more channel(s)
+#TODO: consider removing this when trac #6933 is resolved
+nonzero_volumes = [v for v in volumes if v > 0]
+
+if len(nonzero_volumes) > 0:
+#we could just pick the first nonzero volume, but this converges
+volume = sum(nonzero_volumes) / len(nonzero_volumes)
+return volume * 100.0 / (max_volume - min_volume) + min_volume
+else:
+return 0
 
 def set_volume(self, volume):
 if not self._mixer or not self._master:
@@ -76,7 +93,15 @@ class HardwareManager(object):
 volume = volume * (max_volume - min_volume) / 100.0 + min_volume
 volume_list = [ volume ] * self._master.num_channels
 
-self._mixer.set_volume(self._master, tuple(volume_list))
+#sometimes alsa sets one/more channels' volume to zero instead
+# of what we asked for, so try a few times
+#TODO: consider removing this loop when trac #6934 is resolved
+last_volumes_read = [0]
+read_count = 0
+while (0 in last_volumes_read) and (read_count < 3):
+self._mixer.set_volume(self._master, tuple(volume_list))
+last_volumes_read = self._mixer.get_volume(self._master)
+read_count += 1
 
 def set_mute(self, mute):
 if not self._mixer or not self._master:
diff --git a/src/model/devices/Makefile.am b/src/model/devices/Makefile.am
index 5440eeb..3124144 100644
--- a/src/model/devices/Makefile.am
+++ b/src/model/devices/Makefile.am
@@ -5,4 +5,6 @@ sugar_PYTHON =  \
__init__.py \
device.py   \
devicesmodel.py \
-   battery.py
+   battery.py  \
+   speaker.py
+
diff --git a/src/model/devices/devicesmodel.py 
b/src/model/devices/devicesmodel.py
index 691e19e..e72a9d4 100644
--- a/src/model/devices/devicesmodel.py
+++ b/src/model/devices/devicesmodel.py
@@ -23,6 +23,7 @@ from model.devices import device
 from model.devices.network import wireless
 from model.devices.network import mesh
 from model.devices import battery
+from model.devices import speaker
 from hardware import hardwaremanager
 from hardware import nmclient
 
@@ -54,6 +55,13 @@ class DevicesModel(gobject.GObject):
 for udi in hal_manager.FindDeviceByCapability('battery'):
 self.add_device(battery.Device(udi))
 
+try:
+self.add_device(speaker.Device())
+except Exception, speaker_fail_msg:
+logging.error("could not initialize speaker device: %s" %
+  speaker_fail_msg)
+logging.debug(traceback.format_exc())
+
 def _observe_network_manager(self):
 network_manager = hardwaremanager.get_network_manager()
 if not network_manager:
diff --git a/src/model/devices/speaker.py b/src/model/devices/speaker.py
new file mode 100644
index 000..d3b9967
--- /dev/null
+++ b/src/model/devices/speaker.py
@@ -0,0 +1,59 @@
+# Copyright (C) 2008 Martin Dengler
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+

Re: [sugar] [PATCH] Add speaker device and icon by default

2008-05-12 Thread Martin Dengler
On Tue, May 06, 2008 at 05:40:30PM +0100, Martin Dengler wrote:
> On Tue, May 06, 2008 at 04:39:30PM +0200, Tomeu Vizoso wrote:
> > On 5/4/08, Martin Dengler <[EMAIL PROTECTED]> wrote:
> > > On Tue, Apr 29, 2008 at 02:12:58PM +0200, Tomeu Vizoso wrote:
> > > > I think that Michael has spotted here a wonderful opportunity for
> > > > making Sugar more robust, thanks to your patch.
> ...
> > > I haven't forgotten this thread, just been unable to work on it.

After working on it a bit more I think the right thing to do is just
the small change Tomeu suggested.

I would really like in the future to submit a patch that allows one to
place a few files in a devices.d/ subdir - like model.py, view.py,
icon.svg, etc. - and then the devicesmodel.py code could try to load
each model.py appropriately, and so forth, but right now most of our
"devices" really are device brokers (hal-dbus, networkmanager) and
such a setup doesn't mesh well with them.  Obviously in this patch
would be the "do the initialization lazily and safely"-type of code
that would make m_stone a lot happier.

But in the meantime the two/three lines Tomeu suggested will still
make things safer without adding lots of code; I will resubmit the
patch and hopefully that will make everyone a bit happier.

> > Thanks,
> > 
> > Tomeu
> 
> Martin

Martin




pgp19PvPR6OJ3.pgp
Description: PGP signature
___
Sugar mailing list
Sugar@lists.laptop.org
http://lists.laptop.org/listinfo/sugar


Re: [sugar] [PATCH] Add speaker device and icon by default

2008-05-06 Thread Martin Dengler
On Tue, May 06, 2008 at 04:39:30PM +0200, Tomeu Vizoso wrote:
> On 5/4/08, Martin Dengler <[EMAIL PROTECTED]> wrote:
> > On Tue, Apr 29, 2008 at 02:12:58PM +0200, Tomeu Vizoso wrote:
> > > I think that Michael has spotted here a wonderful opportunity for
> > > making Sugar more robust, thanks to your patch.
...
> > I haven't forgotten this thread, just been unable to work on it.
> > After an hour of messing about with some ideas/code today, my current
> > approach is a bit more involved than just a try/except but nothing too
> > dramatic (just a small yak to shave):
> >
> > - refactor sugar/model/devices/device{,smodel}.py to make
> >  adding/removing device.Device subclasses safe
> >
> > ... this begs one to do the next step or be left with many many
> >  try/excepts and very ugly code (or just one try/except around
> >  speaker.py, which kind of doesn't improve matters that much - though
> >  it's very simple code and I'm happy to move on to other things if
> >  people would accept that :) )
> >
> > - refactor sugar/model/devices/device{,semodel}.py to make discovering
> >  device python files safe using metaclasses (see
> >  http://blogs.gnome.org/jamesh/2008/02/12/python-metaclasses/ ); I
> >  have considered the objections and alternatives including martian,
> >  Zope's plugin framework design, and settled on this approach because
> >  it's very simple, meets the very simple needs we have, and is very
> >  little code
> >
> > ...this requires one to remove the networkmanager- and
> > halmanager-specific logic in devicesmodel.py:
> >
> > - create a new networkmanager model class that will add_device() and
> >  remove_device() using the same logic that used to be in
> >  devicesmodel.py
> >
> > - create a new halmanager model class in the same way
> >
> > ...and then we only need to:
> >
> > - trivially update battery.py and speaker.py
> >
> > - pretty trivially update network/mesh.py, wired.py, wireless.py;
> >  these are only slightly more than trivial because devicesmodel.py
> >  used to define some very network-specific variables that (IMO)
> >  should be exposed by the networkmanager model (above) instead
> >
> > This explanation is long-winded only because I wanted to allow people
> > to poke holes in the approach, not because it's a lot of work.
> 
> If it's not much work, can you provide a patch that gives an idea of
> what you plan to do? No need to be the final patch right now.
> 
> Your ideas look interesting but I'm having a bit of difficulty in
> visualizing how you would refactor things.

This is not a patch because I think it's easier to read due to the
volume of refactoring, and it's very very much incomplete and
unpolished (as I said it's an hour's work), but if you look at them in
order you'll get an idea of what I'm trying, hopefully:

http://pastebin.be/11020 - devicesmodel.py - note this is refactored
to be much simpler, and the major *new* feature is simply the
metaclass usage (I still have to make it import everything in the
model.devices subtree, but you see where it's going)

http://pastebin.be/11021 - device.py - again, much simpler now and the
main changes are 1) register with the metaclass; and 2) subclassers
shoudl implement realize() rather than __init__() to do the real work

http://pastebin.be/11022 - battery.py - example of the changes; they
are basically trivial (superclass, move __init__() to realize(), call
super in realize())

http://pastebin.be/11023 - networkmanagermodel.py - this is where a
lot of devicesmodel.py has gone, because this is really a "meta
device" that creates new devices.Device subclasses as NM tells us
about device appearance/disappearance.  This is completely in flux and
definitely doesn't work, but at least the comments might show you
where I'm going (this is my bullet point #3 above)

> Thanks,
> 
> Tomeu

Martin


pgp6oA04ymjJy.pgp
Description: PGP signature
___
Sugar mailing list
Sugar@lists.laptop.org
http://lists.laptop.org/listinfo/sugar


Re: [sugar] [PATCH] Add speaker device and icon by default

2008-05-06 Thread Tomeu Vizoso
On 5/4/08, Martin Dengler <[EMAIL PROTECTED]> wrote:
> On Tue, Apr 29, 2008 at 02:12:58PM +0200, Tomeu Vizoso wrote:
> > I think that Michael has spotted here a wonderful opportunity for
> > making Sugar more robust, thanks to your patch.
> >
> > What about just making the shell to catch (and log) any exception
> > resulting from the initialization of a device? That should amount to
> > just add one try..except block.
> >
> > Devices are thought to be easily added, so its an expected source of
> > new bugs. The shell should be able to start when any of them fail.
>
> I haven't forgotten this thread, just been unable to work on it.
> After an hour of messing about with some ideas/code today, my current
> approach is a bit more involved than just a try/except but nothing too
> dramatic (just a small yak to shave):
>
> - refactor sugar/model/devices/device{,smodel}.py to make
>  adding/removing device.Device subclasses safe
>
> ... this begs one to do the next step or be left with many many
>  try/excepts and very ugly code (or just one try/except around
>  speaker.py, which kind of doesn't improve matters that much - though
>  it's very simple code and I'm happy to move on to other things if
>  people would accept that :) )
>
> - refactor sugar/model/devices/device{,semodel}.py to make discovering
>  device python files safe using metaclasses (see
>  http://blogs.gnome.org/jamesh/2008/02/12/python-metaclasses/ ); I
>  have considered the objections and alternatives including martian,
>  Zope's plugin framework design, and settled on this approach because
>  it's very simple, meets the very simple needs we have, and is very
>  little code
>
> ...this requires one to remove the networkmanager- and
> halmanager-specific logic in devicesmodel.py:
>
> - create a new networkmanager model class that will add_device() and
>  remove_device() using the same logic that used to be in
>  devicesmodel.py
>
> - create a new halmanager model class in the same way
>
> ...and then we only need to:
>
> - trivially update battery.py and speaker.py
>
> - pretty trivially update network/mesh.py, wired.py, wireless.py;
>  these are only slightly more than trivial because devicesmodel.py
>  used to define some very network-specific variables that (IMO)
>  should be exposed by the networkmanager model (above) instead
>
> This explanation is long-winded only because I wanted to allow people
> to poke holes in the approach, not because it's a lot of work.

If it's not much work, can you provide a patch that gives an idea of
what you plan to do? No need to be the final patch right now.

Your ideas look interesting but I'm having a bit of difficulty in
visualizing how you would refactor things.

Thanks,

Tomeu
___
Sugar mailing list
Sugar@lists.laptop.org
http://lists.laptop.org/listinfo/sugar


Re: [sugar] [PATCH] Add speaker device and icon by default

2008-05-04 Thread Martin Dengler
On Tue, Apr 29, 2008 at 02:12:58PM +0200, Tomeu Vizoso wrote:
> I think that Michael has spotted here a wonderful opportunity for
> making Sugar more robust, thanks to your patch.
> 
> What about just making the shell to catch (and log) any exception
> resulting from the initialization of a device? That should amount to
> just add one try..except block.
> 
> Devices are thought to be easily added, so its an expected source of
> new bugs. The shell should be able to start when any of them fail.

I haven't forgotten this thread, just been unable to work on it.
After an hour of messing about with some ideas/code today, my current
approach is a bit more involved than just a try/except but nothing too
dramatic (just a small yak to shave):

- refactor sugar/model/devices/device{,smodel}.py to make
  adding/removing device.Device subclasses safe

... this begs one to do the next step or be left with many many
  try/excepts and very ugly code (or just one try/except around
  speaker.py, which kind of doesn't improve matters that much - though
  it's very simple code and I'm happy to move on to other things if
  people would accept that :) )

- refactor sugar/model/devices/device{,semodel}.py to make discovering
  device python files safe using metaclasses (see
  http://blogs.gnome.org/jamesh/2008/02/12/python-metaclasses/ ); I
  have considered the objections and alternatives including martian,
  Zope's plugin framework design, and settled on this approach because
  it's very simple, meets the very simple needs we have, and is very
  little code

...this requires one to remove the networkmanager- and
halmanager-specific logic in devicesmodel.py:

- create a new networkmanager model class that will add_device() and
  remove_device() using the same logic that used to be in
  devicesmodel.py

- create a new halmanager model class in the same way

...and then we only need to:

- trivially update battery.py and speaker.py

- pretty trivially update network/mesh.py, wired.py, wireless.py;
  these are only slightly more than trivial because devicesmodel.py
  used to define some very network-specific variables that (IMO)
  should be exposed by the networkmanager model (above) instead

This explanation is long-winded only because I wanted to allow people
to poke holes in the approach, not because it's a lot of work.

> Thanks,
> 
> Tomeu

Martin


pgpo4ewaNMhgI.pgp
Description: PGP signature
___
Sugar mailing list
Sugar@lists.laptop.org
http://lists.laptop.org/listinfo/sugar


Re: [sugar] [PATCH] Add speaker device and icon by default

2008-04-29 Thread Tomeu Vizoso
On Tue, Apr 29, 2008 at 2:36 PM, Marco Pesenti Gritti
<[EMAIL PROTECTED]> wrote:
> On Tue, Apr 29, 2008 at 2:28 PM, Tomeu Vizoso <[EMAIL PROTECTED]> wrote:
>  > The idea is that we have a complex system, and that value can be seen
>  >  in having this system degrading gracefully when an unexpected error
>  >  happens.
>
>  I see that point.
>
>
>  > Even more when is an area where kids are supposed to play
>  >  with (adding device icons to the shell).
>
>  I'm not sure we can do this kind of assumption about what kids will play 
> with.

Don't you think there are areas in the shell that are more likely to
be customized?

Tomeu
___
Sugar mailing list
Sugar@lists.laptop.org
http://lists.laptop.org/listinfo/sugar


Re: [sugar] [PATCH] Add speaker device and icon by default

2008-04-29 Thread Marco Pesenti Gritti
On Tue, Apr 29, 2008 at 2:28 PM, Tomeu Vizoso <[EMAIL PROTECTED]> wrote:
> The idea is that we have a complex system, and that value can be seen
>  in having this system degrading gracefully when an unexpected error
>  happens.

I see that point.

> Even more when is an area where kids are supposed to play
>  with (adding device icons to the shell).

I'm not sure we can do this kind of assumption about what kids will play with.

Marco
___
Sugar mailing list
Sugar@lists.laptop.org
http://lists.laptop.org/listinfo/sugar


Re: [sugar] [PATCH] Add speaker device and icon by default

2008-04-29 Thread Tomeu Vizoso
The idea is that we have a complex system, and that value can be seen
in having this system degrading gracefully when an unexpected error
happens. Even more when is an area where kids are supposed to play
with (adding device icons to the shell).

Adding just one try..except block before gtk.main won't give us this
graceful degradation.

Tomeu

On Tue, Apr 29, 2008 at 2:24 PM, Marco Pesenti Gritti
<[EMAIL PROTECTED]> wrote:
> I'm not really sure about the value of this kind of try/except blocks.
>  If the target is to avoid the shell exiting in any case, we could as
>  well try/except the whole code executed before gtk.main().
>
>  Marco
>
>
>
>  On Tue, Apr 29, 2008 at 2:12 PM, Tomeu Vizoso <[EMAIL PROTECTED]> wrote:
>  >
>  > On Tue, Apr 29, 2008 at 1:37 AM, Martin Dengler
>  >  <[EMAIL PROTECTED]> wrote:
>  >  > On Mon, Apr 28, 2008 at 06:12:31PM -0400, Michael Stone wrote:
>  >  >  > On Mon, Apr 28, 2008 at 10:26:21PM +0100, Martin Dengler wrote:
>  >  >  > > On Mon, Apr 28, 2008 at 01:08:04PM -0400, Michael Stone wrote:
>  >  >  > > > Can calls to self._mixer or self._master fail even when these 
> attributes
>  >  >  > > > are not None?
>  >  >  > >
>  >  >  > > It doesn't appear a concern from the existing hardwaremanager.py 
> code,
>  >  >  > > and not in practice: I've tested checking/changing the volume in a 
> few
>  >  >  > > activities.
>  >  >  >
>  >  >  > I seem to recall having encountered situations where sugar startup 
> would
>  >  >  > fail (in early versions of the QEMU image, before sound began 
> working)
>  >  >  > as a result of unchecked use of sound hardware. I fixed the problem 
> by
>  >  >  > commenting out volume control in the sugar shell. It was a 
> particularly
>  >  >  > annoying problem because it was persistent, which meant that X 
> entered
>  >  >  > an infinite reboot loop.
>  >  >
>  >  >  Yes, that problem exists and my patch is no worse in this respect - I
>  >  >  meant to make both points very explicit later in the email to which
>  >  >  you replied.  Given the clear implication that we should do better,
>  >  >  I'll change my patch.
>  >  >
>  >  >  If you, or marco, or anyone has an opinion about where the best place
>  >  >  to introduce the real paranoia, please let me know.  OTTOMH, given we
>  >  >  obviously want to make Sugar not crash and (secondarily) minimize
>  >  >  spamming of 'try:...except's, hardwaremanager.py's where I would
>  >  >  introduce the bulk of the changes (rather than make speaker.py,
>  >  >  randomactivity.py,
>  >  >  presence-palette-that-wants-to-make-a-dinging-noise.py, etc. do this).
>  >  >
>  >  >  If anyone thinks that's controversial let me know.
>  >  >
>  >  >
>  >  >  > > The original author of the hardwaremanager.py trusted the gst 
> classes
>  >  >  > > just as much as I am...  also keep in mind that I actually saw and
>  >  >  > > worked around two failures (#6933, #6934) of exactly these
>  >  >  > > attributes/implementations,
>  >  >  >
>  >  >  > In your opinion, did the original author of hardwaremanager.py (or
>  >  >  > authors of the clients of hardwaremanager.py?) exercise the degree of
>  >  >  > caution necessary to deliver a solid, reliable Sugar experience to 
> our
>  >  >  > present audience? (I say "present" audience because I think that our
>  >  >  > audience has changed from one which consisted primarily of 
> developers to
>  >  >  > one which consists primarily of semi-literate children.)
>  >  >
>  >  >  As a rhetorical question I think I understand the point.  As a
>  >  >  non-rhetorical question, I'll decline to answer due to lack of
>  >  >  context/familiarity with the conditions.
>  >  >
>  >  >
>  >  >  > > > Also, what happens if an exception is thrown by, say, 
> Device.__init__()?
>  >  >  > >
>  >  >  > > Given the current state of error checking, sugar (the shell) will 
> fail
>  >  >  > > to start and matchbox will exit (I saw this during testing, and 
> just
>  >  >  > > now tried 'raise Exception("we love m_stone")' to confirm.)
>  >  >  >
>  >  >  > Is the exception properly recorded?
>  >  >
>  >  >  I'm sorry, I will have to research the proper way to record such an
>  >  >  exception.  I don't know.
>  >  >
>  >  >
>  >  >  > Is it possible (easy?) to send the traceback upstream to us?
>  >  >
>  >  >  Very interesting idea.  Is there a plan for aggregating such data?
>  >  >  cscott's FISL presenation had some (http-sourced?) usage graphs...is
>  >  >  there a "Send Microsoft a Report"- (or "We Share Your Pain" :)) like
>  >  >  server to which our code could send such reports?  Do you want
>  >  >  automated/staged trac submissions? The design/architecture/maintenance
>  >  >  solution space is well beyond my time to explore.  Lacking any leads
>  >  >  therein I'm going to answer to your question as "I know not this
>  >  >  'upstream', would be happy to use one, but have no resources to build
>  >  >  one".
>  >  >
>  >  >
>  >  >  > > Device.__init__() is four lines

Re: [sugar] [PATCH] Add speaker device and icon by default

2008-04-29 Thread Marco Pesenti Gritti
I'm not really sure about the value of this kind of try/except blocks.
If the target is to avoid the shell exiting in any case, we could as
well try/except the whole code executed before gtk.main().

Marco

On Tue, Apr 29, 2008 at 2:12 PM, Tomeu Vizoso <[EMAIL PROTECTED]> wrote:
>
> On Tue, Apr 29, 2008 at 1:37 AM, Martin Dengler
>  <[EMAIL PROTECTED]> wrote:
>  > On Mon, Apr 28, 2008 at 06:12:31PM -0400, Michael Stone wrote:
>  >  > On Mon, Apr 28, 2008 at 10:26:21PM +0100, Martin Dengler wrote:
>  >  > > On Mon, Apr 28, 2008 at 01:08:04PM -0400, Michael Stone wrote:
>  >  > > > Can calls to self._mixer or self._master fail even when these 
> attributes
>  >  > > > are not None?
>  >  > >
>  >  > > It doesn't appear a concern from the existing hardwaremanager.py code,
>  >  > > and not in practice: I've tested checking/changing the volume in a few
>  >  > > activities.
>  >  >
>  >  > I seem to recall having encountered situations where sugar startup would
>  >  > fail (in early versions of the QEMU image, before sound began working)
>  >  > as a result of unchecked use of sound hardware. I fixed the problem by
>  >  > commenting out volume control in the sugar shell. It was a particularly
>  >  > annoying problem because it was persistent, which meant that X entered
>  >  > an infinite reboot loop.
>  >
>  >  Yes, that problem exists and my patch is no worse in this respect - I
>  >  meant to make both points very explicit later in the email to which
>  >  you replied.  Given the clear implication that we should do better,
>  >  I'll change my patch.
>  >
>  >  If you, or marco, or anyone has an opinion about where the best place
>  >  to introduce the real paranoia, please let me know.  OTTOMH, given we
>  >  obviously want to make Sugar not crash and (secondarily) minimize
>  >  spamming of 'try:...except's, hardwaremanager.py's where I would
>  >  introduce the bulk of the changes (rather than make speaker.py,
>  >  randomactivity.py,
>  >  presence-palette-that-wants-to-make-a-dinging-noise.py, etc. do this).
>  >
>  >  If anyone thinks that's controversial let me know.
>  >
>  >
>  >  > > The original author of the hardwaremanager.py trusted the gst classes
>  >  > > just as much as I am...  also keep in mind that I actually saw and
>  >  > > worked around two failures (#6933, #6934) of exactly these
>  >  > > attributes/implementations,
>  >  >
>  >  > In your opinion, did the original author of hardwaremanager.py (or
>  >  > authors of the clients of hardwaremanager.py?) exercise the degree of
>  >  > caution necessary to deliver a solid, reliable Sugar experience to our
>  >  > present audience? (I say "present" audience because I think that our
>  >  > audience has changed from one which consisted primarily of developers to
>  >  > one which consists primarily of semi-literate children.)
>  >
>  >  As a rhetorical question I think I understand the point.  As a
>  >  non-rhetorical question, I'll decline to answer due to lack of
>  >  context/familiarity with the conditions.
>  >
>  >
>  >  > > > Also, what happens if an exception is thrown by, say, 
> Device.__init__()?
>  >  > >
>  >  > > Given the current state of error checking, sugar (the shell) will fail
>  >  > > to start and matchbox will exit (I saw this during testing, and just
>  >  > > now tried 'raise Exception("we love m_stone")' to confirm.)
>  >  >
>  >  > Is the exception properly recorded?
>  >
>  >  I'm sorry, I will have to research the proper way to record such an
>  >  exception.  I don't know.
>  >
>  >
>  >  > Is it possible (easy?) to send the traceback upstream to us?
>  >
>  >  Very interesting idea.  Is there a plan for aggregating such data?
>  >  cscott's FISL presenation had some (http-sourced?) usage graphs...is
>  >  there a "Send Microsoft a Report"- (or "We Share Your Pain" :)) like
>  >  server to which our code could send such reports?  Do you want
>  >  automated/staged trac submissions? The design/architecture/maintenance
>  >  solution space is well beyond my time to explore.  Lacking any leads
>  >  therein I'm going to answer to your question as "I know not this
>  >  'upstream', would be happy to use one, but have no resources to build
>  >  one".
>  >
>  >
>  >  > > Device.__init__() is four lines of code, and depends on
>  >  > > util.unique_id() and gobject.GObject.__init__().
>  >  >
>  >  > Device.__init__() sounds like the sort of thing that I expect will be
>  >  > overridden by subclasses in interesting ways and it sounds like the sort
>  >  > of thing that will break when people try to run Sugar on platforms we
>  >  > haven't tested pre-qualified.
>  >
>  >  I think you're encouraging me to make Device.__init__() a bit safer,
>  >  or add some comments, or something similar, rather than changing
>  >  speaker.py's __init__().  It's going to get a bit hairy if we can't
>  >  trust our superclass(es)'s constructor(s).  Or perhaps you'd have me
>  >  consider patching devices.py, to survive any of

Re: [sugar] [PATCH] Add speaker device and icon by default

2008-04-29 Thread Tomeu Vizoso
On Tue, Apr 29, 2008 at 1:37 AM, Martin Dengler
<[EMAIL PROTECTED]> wrote:
> On Mon, Apr 28, 2008 at 06:12:31PM -0400, Michael Stone wrote:
>  > On Mon, Apr 28, 2008 at 10:26:21PM +0100, Martin Dengler wrote:
>  > > On Mon, Apr 28, 2008 at 01:08:04PM -0400, Michael Stone wrote:
>  > > > Can calls to self._mixer or self._master fail even when these 
> attributes
>  > > > are not None?
>  > >
>  > > It doesn't appear a concern from the existing hardwaremanager.py code,
>  > > and not in practice: I've tested checking/changing the volume in a few
>  > > activities.
>  >
>  > I seem to recall having encountered situations where sugar startup would
>  > fail (in early versions of the QEMU image, before sound began working)
>  > as a result of unchecked use of sound hardware. I fixed the problem by
>  > commenting out volume control in the sugar shell. It was a particularly
>  > annoying problem because it was persistent, which meant that X entered
>  > an infinite reboot loop.
>
>  Yes, that problem exists and my patch is no worse in this respect - I
>  meant to make both points very explicit later in the email to which
>  you replied.  Given the clear implication that we should do better,
>  I'll change my patch.
>
>  If you, or marco, or anyone has an opinion about where the best place
>  to introduce the real paranoia, please let me know.  OTTOMH, given we
>  obviously want to make Sugar not crash and (secondarily) minimize
>  spamming of 'try:...except's, hardwaremanager.py's where I would
>  introduce the bulk of the changes (rather than make speaker.py,
>  randomactivity.py,
>  presence-palette-that-wants-to-make-a-dinging-noise.py, etc. do this).
>
>  If anyone thinks that's controversial let me know.
>
>
>  > > The original author of the hardwaremanager.py trusted the gst classes
>  > > just as much as I am...  also keep in mind that I actually saw and
>  > > worked around two failures (#6933, #6934) of exactly these
>  > > attributes/implementations,
>  >
>  > In your opinion, did the original author of hardwaremanager.py (or
>  > authors of the clients of hardwaremanager.py?) exercise the degree of
>  > caution necessary to deliver a solid, reliable Sugar experience to our
>  > present audience? (I say "present" audience because I think that our
>  > audience has changed from one which consisted primarily of developers to
>  > one which consists primarily of semi-literate children.)
>
>  As a rhetorical question I think I understand the point.  As a
>  non-rhetorical question, I'll decline to answer due to lack of
>  context/familiarity with the conditions.
>
>
>  > > > Also, what happens if an exception is thrown by, say, 
> Device.__init__()?
>  > >
>  > > Given the current state of error checking, sugar (the shell) will fail
>  > > to start and matchbox will exit (I saw this during testing, and just
>  > > now tried 'raise Exception("we love m_stone")' to confirm.)
>  >
>  > Is the exception properly recorded?
>
>  I'm sorry, I will have to research the proper way to record such an
>  exception.  I don't know.
>
>
>  > Is it possible (easy?) to send the traceback upstream to us?
>
>  Very interesting idea.  Is there a plan for aggregating such data?
>  cscott's FISL presenation had some (http-sourced?) usage graphs...is
>  there a "Send Microsoft a Report"- (or "We Share Your Pain" :)) like
>  server to which our code could send such reports?  Do you want
>  automated/staged trac submissions? The design/architecture/maintenance
>  solution space is well beyond my time to explore.  Lacking any leads
>  therein I'm going to answer to your question as "I know not this
>  'upstream', would be happy to use one, but have no resources to build
>  one".
>
>
>  > > Device.__init__() is four lines of code, and depends on
>  > > util.unique_id() and gobject.GObject.__init__().
>  >
>  > Device.__init__() sounds like the sort of thing that I expect will be
>  > overridden by subclasses in interesting ways and it sounds like the sort
>  > of thing that will break when people try to run Sugar on platforms we
>  > haven't tested pre-qualified.
>
>  I think you're encouraging me to make Device.__init__() a bit safer,
>  or add some comments, or something similar, rather than changing
>  speaker.py's __init__().  It's going to get a bit hairy if we can't
>  trust our superclass(es)'s constructor(s).  Or perhaps you'd have me
>  consider patching devices.py, to survive any of its devices' not
>  initializing.
>
>  If you / anyone has a preference for either approach, or how I
>  structure the changes into one or more patches (this is part of the
>  culture that I haven't picked up yet), please let me know.
>
>  Otherwise I will go forward with what you've said on the principle
>  that you/others would rather slap my code back/down than micromanage
>  me forward.
>
>
>  > > and no other similar bit of code... does any more checking than this.
>  >
>  > Is this good? In particular, is it good that an exception that bu

Re: [sugar] [PATCH] Add speaker device and icon by default

2008-04-28 Thread Martin Dengler
On Mon, Apr 28, 2008 at 06:12:31PM -0400, Michael Stone wrote:
> On Mon, Apr 28, 2008 at 10:26:21PM +0100, Martin Dengler wrote:
> > On Mon, Apr 28, 2008 at 01:08:04PM -0400, Michael Stone wrote:
> > > Can calls to self._mixer or self._master fail even when these attributes
> > > are not None?
> > 
> > It doesn't appear a concern from the existing hardwaremanager.py code,
> > and not in practice: I've tested checking/changing the volume in a few
> > activities.
> 
> I seem to recall having encountered situations where sugar startup would
> fail (in early versions of the QEMU image, before sound began working)
> as a result of unchecked use of sound hardware. I fixed the problem by
> commenting out volume control in the sugar shell. It was a particularly
> annoying problem because it was persistent, which meant that X entered
> an infinite reboot loop.

Yes, that problem exists and my patch is no worse in this respect - I
meant to make both points very explicit later in the email to which
you replied.  Given the clear implication that we should do better,
I'll change my patch.

If you, or marco, or anyone has an opinion about where the best place
to introduce the real paranoia, please let me know.  OTTOMH, given we
obviously want to make Sugar not crash and (secondarily) minimize
spamming of 'try:...except's, hardwaremanager.py's where I would
introduce the bulk of the changes (rather than make speaker.py,
randomactivity.py,
presence-palette-that-wants-to-make-a-dinging-noise.py, etc. do this).

If anyone thinks that's controversial let me know.

> > The original author of the hardwaremanager.py trusted the gst classes
> > just as much as I am...  also keep in mind that I actually saw and
> > worked around two failures (#6933, #6934) of exactly these
> > attributes/implementations, 
> 
> In your opinion, did the original author of hardwaremanager.py (or
> authors of the clients of hardwaremanager.py?) exercise the degree of
> caution necessary to deliver a solid, reliable Sugar experience to our
> present audience? (I say "present" audience because I think that our
> audience has changed from one which consisted primarily of developers to
> one which consists primarily of semi-literate children.)

As a rhetorical question I think I understand the point.  As a
non-rhetorical question, I'll decline to answer due to lack of
context/familiarity with the conditions.

> > > Also, what happens if an exception is thrown by, say, Device.__init__()?
> > 
> > Given the current state of error checking, sugar (the shell) will fail
> > to start and matchbox will exit (I saw this during testing, and just
> > now tried 'raise Exception("we love m_stone")' to confirm.)
> 
> Is the exception properly recorded?

I'm sorry, I will have to research the proper way to record such an
exception.  I don't know.

> Is it possible (easy?) to send the traceback upstream to us?

Very interesting idea.  Is there a plan for aggregating such data?
cscott's FISL presenation had some (http-sourced?) usage graphs...is
there a "Send Microsoft a Report"- (or "We Share Your Pain" :)) like
server to which our code could send such reports?  Do you want
automated/staged trac submissions? The design/architecture/maintenance
solution space is well beyond my time to explore.  Lacking any leads
therein I'm going to answer to your question as "I know not this
'upstream', would be happy to use one, but have no resources to build
one".

> > Device.__init__() is four lines of code, and depends on
> > util.unique_id() and gobject.GObject.__init__().  
> 
> Device.__init__() sounds like the sort of thing that I expect will be
> overridden by subclasses in interesting ways and it sounds like the sort
> of thing that will break when people try to run Sugar on platforms we
> haven't tested pre-qualified.

I think you're encouraging me to make Device.__init__() a bit safer,
or add some comments, or something similar, rather than changing
speaker.py's __init__().  It's going to get a bit hairy if we can't
trust our superclass(es)'s constructor(s).  Or perhaps you'd have me
consider patching devices.py, to survive any of its devices' not
initializing.

If you / anyone has a preference for either approach, or how I
structure the changes into one or more patches (this is part of the
culture that I haven't picked up yet), please let me know.

Otherwise I will go forward with what you've said on the principle
that you/others would rather slap my code back/down than micromanage
me forward.

> > and no other similar bit of code... does any more checking than this.
> 
> Is this good? In particular, is it good that an exception that bubbles
> up through Device.__init__() causes X to enter an infinite restart loop?

ibid.

> > And please excuse me if I've missed a howler of a bug that you're
> > socraticly/patiently trying to make me realize - just feel free to say
> > outright what sucks and I'll fix it!
> 
> You seem to be telling me that Sugar will crash if any of its d

Re: [sugar] [PATCH] Add speaker device and icon by default

2008-04-28 Thread Michael Stone
On Mon, Apr 28, 2008 at 10:26:21PM +0100, Martin Dengler wrote:
> On Mon, Apr 28, 2008 at 01:08:04PM -0400, Michael Stone wrote:
> > Can calls to self._mixer or self._master fail even when these attributes
> > are not None?
> 
> It doesn't appear a concern from the existing hardwaremanager.py code,
> and not in practice: I've tested checking/changing the volume in a few
> activities.

I seem to recall having encountered situations where sugar startup would
fail (in early versions of the QEMU image, before sound began working)
as a result of unchecked use of sound hardware. I fixed the problem by
commenting out volume control in the sugar shell. It was a particularly
annoying problem because it was persistent, which meant that X entered
an infinite reboot loop.

> The original author of the hardwaremanager.py trusted the gst classes
> just as much as I am...  also keep in mind that I actually saw and
> worked around two failures (#6933, #6934) of exactly these
> attributes/implementations, 

In your opinion, did the original author of hardwaremanager.py (or
authors of the clients of hardwaremanager.py?) exercise the degree of
caution necessary to deliver a solid, reliable Sugar experience to our
present audience? (I say "present" audience because I think that our
audience has changed from one which consisted primarily of developers to
one which consists primarily of semi-literate children.)

> > Also, what happens if an exception is thrown by, say, Device.__init__()?
> 
> Given the current state of error checking, sugar (the shell) will fail
> to start and matchbox will exit (I saw this during testing, and just
> now tried 'raise Exception("we love m_stone")' to confirm.)

Is the exception properly recorded? Is it possible (easy?) to send the
traceback upstream to us?

> Device.__init__() is four lines of code, and depends on
> util.unique_id() and gobject.GObject.__init__().  

Device.__init__() sounds like the sort of thing that I expect will be
overridden by subclasses in interesting ways and it sounds like the sort
of thing that will break when people try to run Sugar on platforms we
haven't tested pre-qualified.

> and no other similar bit of code... does any more checking than this.

Is this good? In particular, is it good that an exception that bubbles
up through Device.__init__() causes X to enter an infinite restart loop?

> And please excuse me if I've missed a howler of a bug that you're
> socraticly/patiently trying to make me realize - just feel free to say
> outright what sucks and I'll fix it!

You seem to be telling me that Sugar will crash if any of its device
abstractions fails to initialize. That seems like a howler of a bug to
me (though perhaps not one in your code). Is this desirable behavior? Is
it intentional?

Thanks for putting up me,

Michael
___
Sugar mailing list
Sugar@lists.laptop.org
http://lists.laptop.org/listinfo/sugar


Re: [sugar] [PATCH] Add speaker device and icon by default

2008-04-28 Thread Martin Dengler
On Mon, Apr 28, 2008 at 01:08:04PM -0400, Michael Stone wrote:
> Can calls to self._mixer or self._master fail even when these attributes
> are not None?

It doesn't appear a concern from the existing hardwaremanager.py code,
and not in practice: I've tested checking/changing the volume in a few
activities.

The original author of the hardwaremanager.py trusted the gst classes
just as much as I am, though I wouldn't want to hide behind that; if
you're concerned I haven't done enough research about these APIs (I
love abusing abstraction and limited documentation in a language
without checked exceptions to write code fast:)), well, that's
understandable (though I have done some research on GstElement[1,2],
GstState[3], and the anemic state of python-gst documentation (could
be a sign of great code :))[4,5] and I think it's OK enough for me).

Also keep in mind that I actually saw and worked around two failures
(#6933, #6934) of exactly these attributes/implementations, so if your
concern is that they'll DoS/make Sugar more fragile, I'm happy to add
a bit more paranoia to hardwaremanager.py - so far I just have the
existing code to guide me as to what level of paranoia is justified,
but as you're the one paid to be paranoid :) I of course would not
object to being corrected / directed differently.

Can you explain a bit more about your concern(s) so I can address them
better?

> Also, what happens if an exception is thrown by, say, Device.__init__()?

Given the current state of error checking, sugar (the shell) will fail
to start and matchbox will exit (I saw this during testing, and just
now tried 'raise Exception("we love m_stone")' to confirm.)

Device.__init__() is four lines of code, and depends on
util.unique_id() and gobject.GObject.__init__().  I'm no expert on
those two, but that seems trivial/robust enough to not wrap in a
try/except, and no other similar bit of code (battery.py,
network/*.py) that depends on Device.__init__() and has the same
exposure to its behavior does any more checking than this.

Again, can you explain a bit more about your concern(s) - e.g., would
you prefer a try/except in speaker.py, or device.py, or something
else?  Or were you just curious as to the likelihood of
failure/complexity of Device.__init__()?

And please excuse me if I've missed a howler of a bug that you're
socraticly/patiently trying to make me realize - just feel free to say
outright what sucks and I'll fix it!

> Thanks,
> 
> Michael

Martin

1. 
http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstElementFactory.html#gst-element-factory-make

2. 
http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstElement.html

3. 
http://gstreamer.freedesktop.org/data/doc/gstreamer/head/gstreamer/html/GstElement.html#GstState

4. The example for interacting with the mixer:
http://webcvs.freedesktop.org/gstreamer/gst-python/examples/mixer.py?revision=1.2&view=markup
. Of course it's an example and it's got about 4 PEP 008 style
violations that smacked me on the head, but the last commit is an
attempt to make it not grossly fail under some normal error condition
so it's at least a minimum bar of how to interact with the mixer,
which it seems hardwaremanager.py vaults easily, before and after my
patch :).

5. http://www.jonobacon.org/?p=750 <-- this is the author of
python-gst, it seems, complaining about the lack of documentation but
doing a really good job of starting to rectify the situation :)



pgpUOuaQUKeKt.pgp
Description: PGP signature
___
Sugar mailing list
Sugar@lists.laptop.org
http://lists.laptop.org/listinfo/sugar


Re: [sugar] [PATCH] Add speaker device and icon by default

2008-04-28 Thread Michael Stone
Can calls to self._mixer or self._master fail even when these attributes
are not None?

Also, what happens if an exception is thrown by, say, Device.__init__()?

Thanks,

Michael
___
Sugar mailing list
Sugar@lists.laptop.org
http://lists.laptop.org/listinfo/sugar


[sugar] [PATCH] Add speaker device and icon by default

2008-04-28 Thread Martin Dengler
Add speaker device and icon by default, as in
http://wiki.laptop.org/go/Designs/Frame#07
---
 src/hardware/hardwaremanager.py   |   31 +-
 src/model/devices/Makefile.am |4 +-
 src/model/devices/devicesmodel.py |3 +
 src/model/devices/speaker.py  |   59 ++
 src/view/devices/Makefile.am  |4 +-
 src/view/devices/speaker.py   |  119 +
 6 files changed, 215 insertions(+), 5 deletions(-)
 create mode 100644 src/model/devices/speaker.py
 create mode 100644 src/view/devices/speaker.py

diff --git a/src/hardware/hardwaremanager.py b/src/hardware/hardwaremanager.py
index 29be450..42676e4 100644
--- a/src/hardware/hardwaremanager.py
+++ b/src/hardware/hardwaremanager.py
@@ -50,6 +50,13 @@ class HardwareManager(object):
 if track.flags & gst.interfaces.MIXER_TRACK_MASTER:
 self._master = track
 
+def get_mute(self):
+if not self._mixer or not self._master:
+logging.error('Cannot get the mute status')
+return False
+return self._master.flags & gst.interfaces.MIXER_TRACK_MUTE \
+ == gst.interfaces.MIXER_TRACK_MUTE
+
 def get_volume(self):
 if not self._mixer or not self._master:
 logging.error('Cannot get the volume')
@@ -57,9 +64,19 @@ class HardwareManager(object):
 
 max_volume = self._master.max_volume
 min_volume = self._master.min_volume
-volume = self._mixer.get_volume(self._master)[0]
 
-return volume * 100.0 / (max_volume - min_volume) + min_volume
+volumes = self._mixer.get_volume(self._master)
+
+#sometimes we get a spurious zero from one/more channel(s)
+#TODO: consider removing this when trac #6933 is resolved
+nonzero_volumes = [v for v in volumes if v > 0]
+
+if len(nonzero_volumes) > 0:
+#we could just pick the first nonzero volume, but this converges
+volume = sum(nonzero_volumes) / len(nonzero_volumes)
+return volume * 100.0 / (max_volume - min_volume) + min_volume
+else:
+return 0
 
 def set_volume(self, volume):
 if not self._mixer or not self._master:
@@ -76,7 +93,15 @@ class HardwareManager(object):
 volume = volume * (max_volume - min_volume) / 100.0 + min_volume
 volume_list = [ volume ] * self._master.num_channels
 
-self._mixer.set_volume(self._master, tuple(volume_list))
+#sometimes alsa sets one/more channels' volume to zero instead
+# of what we asked for, so try a few times
+#TODO: consider removing this loop when trac #6934 is resolved
+last_volumes_read = [0]
+read_count = 0
+while (0 in last_volumes_read) and (read_count < 3):
+self._mixer.set_volume(self._master, tuple(volume_list))
+last_volumes_read = self._mixer.get_volume(self._master)
+read_count += 1
 
 def set_mute(self, mute):
 if not self._mixer or not self._master:
diff --git a/src/model/devices/Makefile.am b/src/model/devices/Makefile.am
index 5440eeb..3124144 100644
--- a/src/model/devices/Makefile.am
+++ b/src/model/devices/Makefile.am
@@ -5,4 +5,6 @@ sugar_PYTHON =  \
__init__.py \
device.py   \
devicesmodel.py \
-   battery.py
+   battery.py  \
+   speaker.py
+
diff --git a/src/model/devices/devicesmodel.py 
b/src/model/devices/devicesmodel.py
index 691e19e..32c77da 100644
--- a/src/model/devices/devicesmodel.py
+++ b/src/model/devices/devicesmodel.py
@@ -23,6 +23,7 @@ from model.devices import device
 from model.devices.network import wireless
 from model.devices.network import mesh
 from model.devices import battery
+from model.devices import speaker
 from hardware import hardwaremanager
 from hardware import nmclient
 
@@ -54,6 +55,8 @@ class DevicesModel(gobject.GObject):
 for udi in hal_manager.FindDeviceByCapability('battery'):
 self.add_device(battery.Device(udi))
 
+self.add_device(speaker.Device())
+
 def _observe_network_manager(self):
 network_manager = hardwaremanager.get_network_manager()
 if not network_manager:
diff --git a/src/model/devices/speaker.py b/src/model/devices/speaker.py
new file mode 100644
index 000..d3b9967
--- /dev/null
+++ b/src/model/devices/speaker.py
@@ -0,0 +1,59 @@
+# Copyright (C) 2008 Martin Dengler
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for

Re: [sugar] [PATCH] Add speaker device and icon by default

2008-04-28 Thread Martin Dengler
On Mon, Apr 28, 2008 at 03:49:12PM +0200, Tomeu Vizoso wrote:
> On Fri, Apr 25, 2008 at 11:50 PM, Martin Dengler
> <[EMAIL PROTECTED]> wrote:
> 
> >  +self.palette = SpeakerPalette(_('My Speakers'), model=model)
> >  +self.set_palette(self.palette)
> 
> 'set_palette' is the setter for the 'palette' property, so the second
> line shouldn't be needed.

Thanks, I'll remove. That code was cut & pasted from battery.py, so
I'm guilty of cargo-culting here.

> 
> >  +model.connect('notify::level', self._speaker_status_changed_cb)
> >  +model.connect('notify::muted', self._speaker_status_changed_cb)
> >  +self.connect('expose-event', self._expose_event_cb)
> 
> Callbacks should start with two underscores in order to avoid name
> clashes.

Thanks -- others have pointed this out as well in other code sections
and I guess I missed those.

> Tomeu

Martin



pgpVzj1mJl35E.pgp
Description: PGP signature
___
Sugar mailing list
Sugar@lists.laptop.org
http://lists.laptop.org/listinfo/sugar


Re: [sugar] [PATCH] Add speaker device and icon by default

2008-04-28 Thread Tomeu Vizoso
On Fri, Apr 25, 2008 at 11:50 PM, Martin Dengler
<[EMAIL PROTECTED]> wrote:

>  +self.palette = SpeakerPalette(_('My Speakers'), model=model)
>  +self.set_palette(self.palette)

'set_palette' is the setter for the 'palette' property, so the second
line shouldn't be needed.

>  +model.connect('notify::level', self._speaker_status_changed_cb)
>  +model.connect('notify::muted', self._speaker_status_changed_cb)
>  +self.connect('expose-event', self._expose_event_cb)

Callbacks should start with two underscores in order to avoid name clashes.

The rest looks good to me.

Thanks,

Tomeu
___
Sugar mailing list
Sugar@lists.laptop.org
http://lists.laptop.org/listinfo/sugar


Re: [sugar] [PATCH] Add speaker device and icon by default

2008-04-26 Thread Martin Dengler
On Sat, Apr 26, 2008 at 06:07:45AM -0400, Wade Brainerd wrote:
> On Fri, Apr 25, 2008 at 1:56 PM, Eben Eliason <[EMAIL PROTECTED]> wrote:
> > On Fri, Apr 25, 2008 at 1:46 PM, Martin Dengler
> >  >  self._mute_item.get_child().set_text(_(mute_item_text))
> >
> >  Oh, I missed that.  I would wrap the localization around the string
> >  literal, so the connection is clear. (Yes, you have to use it twice
> >  instead of oncebut it was imported as _ for a reason. ;) )
> 
> Won't gettext fail to pick these up when generating the .pot file, the
> way it's written now?
> 
> I was under the impression it just looks blindly through the source
> for _() when building the translation files...

Yes -- I didn't know this at the time.  Thanks for pointing it out.
Others pointed it out to me on IRC, too, and my most recent patch
addresses the point.  Thanks again for the time/feedback.

> Wade

Martin


pgpAhI0Q7Jed4.pgp
Description: PGP signature
___
Sugar mailing list
Sugar@lists.laptop.org
http://lists.laptop.org/listinfo/sugar


Re: [sugar] [PATCH] Add speaker device and icon by default

2008-04-26 Thread Wade Brainerd
On Fri, Apr 25, 2008 at 1:56 PM, Eben Eliason <[EMAIL PROTECTED]> wrote:
> On Fri, Apr 25, 2008 at 1:46 PM, Martin Dengler
>  >  self._mute_item.get_child().set_text(_(mute_item_text))
>
>  Oh, I missed that.  I would wrap the localization around the string
>  literal, so the connection is clear. (Yes, you have to use it twice
>  instead of oncebut it was imported as _ for a reason. ;) )

Won't gettext fail to pick these up when generating the .pot file, the
way it's written now?

I was under the impression it just looks blindly through the source
for _() when building the translation files...

Wade
___
Sugar mailing list
Sugar@lists.laptop.org
http://lists.laptop.org/listinfo/sugar


[sugar] [PATCH] Add speaker device and icon by default

2008-04-25 Thread Martin Dengler
Add speaker device and icon by default, as in
http://wiki.laptop.org/go/Designs/Frame#07
---
 src/hardware/hardwaremanager.py   |   31 +-
 src/model/devices/Makefile.am |4 +-
 src/model/devices/devicesmodel.py |3 +
 src/model/devices/speaker.py  |   59 ++
 src/view/devices/Makefile.am  |4 +-
 src/view/devices/speaker.py   |  118 +
 6 files changed, 214 insertions(+), 5 deletions(-)
 create mode 100644 src/model/devices/speaker.py
 create mode 100644 src/view/devices/speaker.py

diff --git a/src/hardware/hardwaremanager.py b/src/hardware/hardwaremanager.py
index 29be450..42676e4 100644
--- a/src/hardware/hardwaremanager.py
+++ b/src/hardware/hardwaremanager.py
@@ -50,6 +50,13 @@ class HardwareManager(object):
 if track.flags & gst.interfaces.MIXER_TRACK_MASTER:
 self._master = track
 
+def get_mute(self):
+if not self._mixer or not self._master:
+logging.error('Cannot get the mute status')
+return False
+return self._master.flags & gst.interfaces.MIXER_TRACK_MUTE \
+ == gst.interfaces.MIXER_TRACK_MUTE
+
 def get_volume(self):
 if not self._mixer or not self._master:
 logging.error('Cannot get the volume')
@@ -57,9 +64,19 @@ class HardwareManager(object):
 
 max_volume = self._master.max_volume
 min_volume = self._master.min_volume
-volume = self._mixer.get_volume(self._master)[0]
 
-return volume * 100.0 / (max_volume - min_volume) + min_volume
+volumes = self._mixer.get_volume(self._master)
+
+#sometimes we get a spurious zero from one/more channel(s)
+#TODO: consider removing this when trac #6933 is resolved
+nonzero_volumes = [v for v in volumes if v > 0]
+
+if len(nonzero_volumes) > 0:
+#we could just pick the first nonzero volume, but this converges
+volume = sum(nonzero_volumes) / len(nonzero_volumes)
+return volume * 100.0 / (max_volume - min_volume) + min_volume
+else:
+return 0
 
 def set_volume(self, volume):
 if not self._mixer or not self._master:
@@ -76,7 +93,15 @@ class HardwareManager(object):
 volume = volume * (max_volume - min_volume) / 100.0 + min_volume
 volume_list = [ volume ] * self._master.num_channels
 
-self._mixer.set_volume(self._master, tuple(volume_list))
+#sometimes alsa sets one/more channels' volume to zero instead
+# of what we asked for, so try a few times
+#TODO: consider removing this loop when trac #6934 is resolved
+last_volumes_read = [0]
+read_count = 0
+while (0 in last_volumes_read) and (read_count < 3):
+self._mixer.set_volume(self._master, tuple(volume_list))
+last_volumes_read = self._mixer.get_volume(self._master)
+read_count += 1
 
 def set_mute(self, mute):
 if not self._mixer or not self._master:
diff --git a/src/model/devices/Makefile.am b/src/model/devices/Makefile.am
index 5440eeb..3124144 100644
--- a/src/model/devices/Makefile.am
+++ b/src/model/devices/Makefile.am
@@ -5,4 +5,6 @@ sugar_PYTHON =  \
__init__.py \
device.py   \
devicesmodel.py \
-   battery.py
+   battery.py  \
+   speaker.py
+
diff --git a/src/model/devices/devicesmodel.py 
b/src/model/devices/devicesmodel.py
index 691e19e..32c77da 100644
--- a/src/model/devices/devicesmodel.py
+++ b/src/model/devices/devicesmodel.py
@@ -23,6 +23,7 @@ from model.devices import device
 from model.devices.network import wireless
 from model.devices.network import mesh
 from model.devices import battery
+from model.devices import speaker
 from hardware import hardwaremanager
 from hardware import nmclient
 
@@ -54,6 +55,8 @@ class DevicesModel(gobject.GObject):
 for udi in hal_manager.FindDeviceByCapability('battery'):
 self.add_device(battery.Device(udi))
 
+self.add_device(speaker.Device())
+
 def _observe_network_manager(self):
 network_manager = hardwaremanager.get_network_manager()
 if not network_manager:
diff --git a/src/model/devices/speaker.py b/src/model/devices/speaker.py
new file mode 100644
index 000..d3b9967
--- /dev/null
+++ b/src/model/devices/speaker.py
@@ -0,0 +1,59 @@
+# Copyright (C) 2008 Martin Dengler
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for

[sugar] [PATCH] Add speaker device and icon by default

2008-04-25 Thread Martin Dengler
Add speaker device and icon by default, as in
http://wiki.laptop.org/go/Designs/Frame#07
---
 src/hardware/hardwaremanager.py   |   26 -
 src/model/devices/Makefile.am |4 +-
 src/model/devices/devicesmodel.py |3 +
 src/model/devices/speaker.py  |   59 ++
 src/view/devices/Makefile.am  |4 +-
 src/view/devices/speaker.py   |  118 +
 6 files changed, 210 insertions(+), 4 deletions(-)
 create mode 100644 src/model/devices/speaker.py
 create mode 100644 src/view/devices/speaker.py

diff --git a/src/hardware/hardwaremanager.py b/src/hardware/hardwaremanager.py
index 29be450..5a8f0ad 100644
--- a/src/hardware/hardwaremanager.py
+++ b/src/hardware/hardwaremanager.py
@@ -50,6 +50,13 @@ class HardwareManager(object):
 if track.flags & gst.interfaces.MIXER_TRACK_MASTER:
 self._master = track
 
+def get_mute(self):
+if not self._mixer or not self._master:
+logging.error('Cannot get the mute status')
+return False
+return self._master.flags & gst.interfaces.MIXER_TRACK_MUTE \
+ == gst.interfaces.MIXER_TRACK_MUTE
+
 def get_volume(self):
 if not self._mixer or not self._master:
 logging.error('Cannot get the volume')
@@ -57,7 +64,14 @@ class HardwareManager(object):
 
 max_volume = self._master.max_volume
 min_volume = self._master.min_volume
-volume = self._mixer.get_volume(self._master)[0]
+
+#sometimes we get a spurious zero from one/more channel(s)
+#TODO: consider removing this when trac # is resolved
+nonzero_volumes = [v for v in self._mixer.get_volume(self._master)
+   if v > 0]
+
+#we could just pick the first channel's volume, but this converges
+volume = sum(nonzero_volumes) / len(nonzero_volumes)
 
 return volume * 100.0 / (max_volume - min_volume) + min_volume
 
@@ -76,7 +90,15 @@ class HardwareManager(object):
 volume = volume * (max_volume - min_volume) / 100.0 + min_volume
 volume_list = [ volume ] * self._master.num_channels
 
-self._mixer.set_volume(self._master, tuple(volume_list))
+#sometimes alsa sets one/more channels' volume to zero instead
+# of what we asked for, so try a few times
+#TODO: consider removing this when trac # is resolved
+last_volumes_read = [0]
+read_count = 0
+while (0 in last_volumes_read) and (read_count < 3):
+self._mixer.set_volume(self._master, tuple(volume_list))
+last_volumes_read = self._mixer.get_volume(self._master)
+read_count += 1
 
 def set_mute(self, mute):
 if not self._mixer or not self._master:
diff --git a/src/model/devices/Makefile.am b/src/model/devices/Makefile.am
index 5440eeb..3124144 100644
--- a/src/model/devices/Makefile.am
+++ b/src/model/devices/Makefile.am
@@ -5,4 +5,6 @@ sugar_PYTHON =  \
__init__.py \
device.py   \
devicesmodel.py \
-   battery.py
+   battery.py  \
+   speaker.py
+
diff --git a/src/model/devices/devicesmodel.py 
b/src/model/devices/devicesmodel.py
index 691e19e..32c77da 100644
--- a/src/model/devices/devicesmodel.py
+++ b/src/model/devices/devicesmodel.py
@@ -23,6 +23,7 @@ from model.devices import device
 from model.devices.network import wireless
 from model.devices.network import mesh
 from model.devices import battery
+from model.devices import speaker
 from hardware import hardwaremanager
 from hardware import nmclient
 
@@ -54,6 +55,8 @@ class DevicesModel(gobject.GObject):
 for udi in hal_manager.FindDeviceByCapability('battery'):
 self.add_device(battery.Device(udi))
 
+self.add_device(speaker.Device())
+
 def _observe_network_manager(self):
 network_manager = hardwaremanager.get_network_manager()
 if not network_manager:
diff --git a/src/model/devices/speaker.py b/src/model/devices/speaker.py
new file mode 100644
index 000..d3b9967
--- /dev/null
+++ b/src/model/devices/speaker.py
@@ -0,0 +1,59 @@
+# Copyright (C) 2008 Martin Dengler
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+import gobject
+
+from 

[sugar] [PATCH] Add speaker device and icon by default

2008-04-25 Thread Martin Dengler
Add speaker device and icon by default, as in
http://wiki.laptop.org/go/Designs/Frame#07
---
 src/hardware/hardwaremanager.py   |   24 +++-
 src/model/devices/Makefile.am |4 +-
 src/model/devices/devicesmodel.py |3 +
 src/model/devices/speaker.py  |   59 ++
 src/view/devices/Makefile.am  |4 +-
 src/view/devices/speaker.py   |  118 +
 6 files changed, 208 insertions(+), 4 deletions(-)
 create mode 100644 src/model/devices/speaker.py
 create mode 100644 src/view/devices/speaker.py

diff --git a/src/hardware/hardwaremanager.py b/src/hardware/hardwaremanager.py
index 29be450..b52a30a 100644
--- a/src/hardware/hardwaremanager.py
+++ b/src/hardware/hardwaremanager.py
@@ -50,6 +50,13 @@ class HardwareManager(object):
 if track.flags & gst.interfaces.MIXER_TRACK_MASTER:
 self._master = track
 
+def get_mute(self):
+if not self._mixer or not self._master:
+logging.error('Cannot get the mute status')
+return False
+return self._master.flags & gst.interfaces.MIXER_TRACK_MUTE \
+ == gst.interfaces.MIXER_TRACK_MUTE
+
 def get_volume(self):
 if not self._mixer or not self._master:
 logging.error('Cannot get the volume')
@@ -57,7 +64,13 @@ class HardwareManager(object):
 
 max_volume = self._master.max_volume
 min_volume = self._master.min_volume
-volume = self._mixer.get_volume(self._master)[0]
+
+#sometimes we get a spurious zero from one/more channel(s)
+nonzero_volumes = [v for v in self._mixer.get_volume(self._master)
+   if v > 0]
+
+#we could just pick the first channel's volume, but this converges
+volume = sum(nonzero_volumes) / len(nonzero_volumes)
 
 return volume * 100.0 / (max_volume - min_volume) + min_volume
 
@@ -76,7 +89,14 @@ class HardwareManager(object):
 volume = volume * (max_volume - min_volume) / 100.0 + min_volume
 volume_list = [ volume ] * self._master.num_channels
 
-self._mixer.set_volume(self._master, tuple(volume_list))
+#sometimes alsa sets one/more channels' volume to zero instead
+# of what we asked for, so try a few times
+last_volumes_read = [0]
+read_count = 0
+while (0 in last_volumes_read) and (read_count < 3):
+self._mixer.set_volume(self._master, tuple(volume_list))
+last_volumes_read = self._mixer.get_volume(self._master)
+read_count += 1
 
 def set_mute(self, mute):
 if not self._mixer or not self._master:
diff --git a/src/model/devices/Makefile.am b/src/model/devices/Makefile.am
index 5440eeb..3124144 100644
--- a/src/model/devices/Makefile.am
+++ b/src/model/devices/Makefile.am
@@ -5,4 +5,6 @@ sugar_PYTHON =  \
__init__.py \
device.py   \
devicesmodel.py \
-   battery.py
+   battery.py  \
+   speaker.py
+
diff --git a/src/model/devices/devicesmodel.py 
b/src/model/devices/devicesmodel.py
index 691e19e..32c77da 100644
--- a/src/model/devices/devicesmodel.py
+++ b/src/model/devices/devicesmodel.py
@@ -23,6 +23,7 @@ from model.devices import device
 from model.devices.network import wireless
 from model.devices.network import mesh
 from model.devices import battery
+from model.devices import speaker
 from hardware import hardwaremanager
 from hardware import nmclient
 
@@ -54,6 +55,8 @@ class DevicesModel(gobject.GObject):
 for udi in hal_manager.FindDeviceByCapability('battery'):
 self.add_device(battery.Device(udi))
 
+self.add_device(speaker.Device())
+
 def _observe_network_manager(self):
 network_manager = hardwaremanager.get_network_manager()
 if not network_manager:
diff --git a/src/model/devices/speaker.py b/src/model/devices/speaker.py
new file mode 100644
index 000..d3b9967
--- /dev/null
+++ b/src/model/devices/speaker.py
@@ -0,0 +1,59 @@
+# Copyright (C) 2008 Martin Dengler
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+import gobject
+
+from hardware import hardwaremanager
+from model.devices import device
+
+class Device(device.Device):
+__gproperties__ = {
+'le

Re: [sugar] [PATCH] Add speaker device and icon by default

2008-04-25 Thread Eben Eliason
On Fri, Apr 25, 2008 at 1:46 PM, Martin Dengler
<[EMAIL PROTECTED]> wrote:
> On Fri, Apr 25, 2008 at 01:21:50PM -0400, Eben Eliason wrote:
>  > Alright...I'll go at it again, sits it's been sitting around for a day... 
> =)
>  >
>  > >  +nonzero_vols = [v for v in volumes if v > 0.0]
>  >
>  > Is it actually necessary to compare against a forced float (0.0) here?
>
>  Probably not.  The sequence elements are floats, so I figured why not.

It's not wrong.  I've just never seen it done. =) Obviously, 0 is
losslessly representable as both int and float.

>  > >  +if len(nonzero_vols) != 0 and len(nonzero_vols) != 
> len(volumes):
>  > >  +volumes = nonzero_vols
>  >
>  > The second condition seems unnecessary.
>
>  Possibly.  We want to eliminate the nonzero volumes, but what if there
>  are no nonzero volumes?  It's only unnecessary because sum([]) - used

If there are none at all, then the first condition short circuits
anyway, and we're in good shape.

>  later on - turns out to be zero (which I thought of now because it
>  wasn't 5am).  So I could just replace the whole volumes = ... return
>  volumne ... with:
>
>  ...
>  # sometimes we get a spurious zero from one/more channel(s)
>  nonzero_volumes = self._mixer.get_volume(self._master)
>  volume = sum(nonzero_volumes) / len(nonzero_volumes)
>  ...
>
>  ...and then it'd work.  I'll do that.

Sounds much nicer.

>  > >  +#sometimes alsa fails to set all channels' volume, so try a 
> few times
>  >
>  > What's the rate of failure here?
>
>  About 25-50% if I hold down one of the arrow kesy while the slider has
>  focus and watch alsamixer's indication of the L+R channels' volume
>  from an ssh session into the laptop.
>
>  >  If we're always ignoring the zeros when reading the volume, does it
>  > matter if we do extra work to be sure to set them all?
>
>  Yes, because reading of zeros and the failure to set the volumes have
>  different solutions.  The comment should better read
>
>  # sometimes alsa sets a channel's volume to zero rather than what we
>   tell it to
>
>  ...and the problem is now sufficiently clear to justify the retry code.

Yuck.  And OK.


>  > >  +mute_item_text = 'Unmute'
>  > ...
>  > >  +mute_item_text = 'Mute'
>  >
>  > These should be localized!
>
>  They are:
>
>
>  self._mute_item.get_child().set_text(_(mute_item_text))

Oh, I missed that.  I would wrap the localization around the string
literal, so the connection is clear. (Yes, you have to use it twice
instead of oncebut it was imported as _ for a reason. ;) )

- Eben
___
Sugar mailing list
Sugar@lists.laptop.org
http://lists.laptop.org/listinfo/sugar


Re: [sugar] [PATCH] Add speaker device and icon by default

2008-04-25 Thread Martin Dengler
On Fri, Apr 25, 2008 at 01:21:50PM -0400, Eben Eliason wrote:
> Alright...I'll go at it again, sits it's been sitting around for a day... =)
> 
> >  +nonzero_vols = [v for v in volumes if v > 0.0]
> 
> Is it actually necessary to compare against a forced float (0.0) here?

Probably not.  The sequence elements are floats, so I figured why not.

> 
> >  +if len(nonzero_vols) != 0 and len(nonzero_vols) != len(volumes):
> >  +volumes = nonzero_vols
> 
> The second condition seems unnecessary.

Possibly.  We want to eliminate the nonzero volumes, but what if there
are no nonzero volumes?  It's only unnecessary because sum([]) - used
later on - turns out to be zero (which I thought of now because it
wasn't 5am).  So I could just replace the whole volumes = ... return
volumne ... with:

...
# sometimes we get a spurious zero from one/more channel(s)
nonzero_volumes = self._mixer.get_volume(self._master)
volume = sum(nonzero_volumes) / len(nonzero_volumes)
...

...and then it'd work.  I'll do that.


> >  +#sometimes alsa fails to set all channels' volume, so try a few 
> > times
> 
> What's the rate of failure here?

About 25-50% if I hold down one of the arrow kesy while the slider has
focus and watch alsamixer's indication of the L+R channels' volume
from an ssh session into the laptop.

>  If we're always ignoring the zeros when reading the volume, does it
> matter if we do extra work to be sure to set them all?

Yes, because reading of zeros and the failure to set the volumes have
different solutions.  The comment should better read 

# sometimes alsa sets a channel's volume to zero rather than what we
  tell it to

...and the problem is now sufficiently clear to justify the retry code.

> >  +TrayIcon.__init__(self, icon_name=_ICON_NAME,
> >  +  xo_color=profile.get_color())
> 
> You can align this with "self, ..."

Will do...code was cut & pasted...

> +class SpeakerPalette(Palette):
> >  +
> >  +def __init__(self, primary_text, model):
> >  +Palette.__init__(self, primary_text)
> 
> It would be better to pass primary text as a keyword arg, using the
> property API.  Passing the standard arg directly is deprecated.

Again, cut & pasted...will do.

> >  +self._mute_item = MenuItem(_('Unmute'))
> 
> Tomeu will whine here because you use this string in two places.

I didn't like this either...I wasn't sure about initializing it to
None, and now you've clarified that, so I'll set it to ''.

> >  +self.set_content(vbox)
> 
> Any need to put this down below the MenuItem creation?  It seems oddly
> detatched from the other VBox stuff.

Nope.

> >  +mute_item_text = 'Unmute'
> ...
> >  +mute_item_text = 'Mute'
> 
> These should be localized!

They are:

self._mute_item.get_child().set_text(_(mute_item_text))

> - Eben

Martin


pgpKbLYPCrhhu.pgp
Description: PGP signature
___
Sugar mailing list
Sugar@lists.laptop.org
http://lists.laptop.org/listinfo/sugar


Re: [sugar] [PATCH] Add speaker device and icon by default

2008-04-25 Thread Eben Eliason
Alright...I'll go at it again, sits it's been sitting around for a day... =)

>  +nonzero_vols = [v for v in volumes if v > 0.0]

Is it actually necessary to compare against a forced float (0.0) here?

>  +if len(nonzero_vols) != 0 and len(nonzero_vols) != len(volumes):
>  +volumes = nonzero_vols

The second condition seems unnecessary.  If they are the same length,
they are the same, and performing the reassignment is not an issue.
Also, the first comparison would read more clearly if it used a
greater than comparison, instead of inequality, since the length
cannot be negative.

>  +#sometimes alsa fails to set all channels' volume, so try a few 
> times

What's the rate of failure here?  If we're always ignoring the zeros
when reading the volume, does it matter if we do extra work to be sure
to set them all?  For that matter, why do we need to mess with a bunch
of channels at all? (Pardon my ignorance...feel free to ignore these
questions entirely.)

>  +TrayIcon.__init__(self, icon_name=_ICON_NAME,
>  +  xo_color=profile.get_color())

You can align this with "self, ..."

+class SpeakerPalette(Palette):
>  +
>  +def __init__(self, primary_text, model):
>  +Palette.__init__(self, primary_text)

It would be better to pass primary text as a keyword arg, using the
property API.  Passing the standard arg directly is deprecated.

>  +self._mute_item = MenuItem(_('Unmute'))

Tomeu will whine here because you use this string in two places.  You
could instead initialize it with a null string and call _update_info
to set the label appropriately.  For some reason, it seem that you
cannot simply pass None (or leave out the argument completely), but
must instead pass '' (null string) instead.

>  +self.set_content(vbox)

Any need to put this down below the MenuItem creation?  It seems oddly
detatched from the other VBox stuff.

>  +mute_item_text = 'Unmute'
...
>  +mute_item_text = 'Mute'

These should be localized!

- Eben
___
Sugar mailing list
Sugar@lists.laptop.org
http://lists.laptop.org/listinfo/sugar


[sugar] [PATCH] Add speaker device and icon by default

2008-04-24 Thread Martin Dengler
Add speaker device and icon by default, as in
http://wiki.laptop.org/go/Designs/Frame#07
---
 src/hardware/hardwaremanager.py   |   26 -
 src/model/devices/Makefile.am |4 +-
 src/model/devices/devicesmodel.py |3 +
 src/model/devices/speaker.py  |   59 ++
 src/view/devices/Makefile.am  |4 +-
 src/view/devices/speaker.py   |  119 +
 6 files changed, 211 insertions(+), 4 deletions(-)
 create mode 100644 src/model/devices/speaker.py
 create mode 100644 src/view/devices/speaker.py

diff --git a/src/hardware/hardwaremanager.py b/src/hardware/hardwaremanager.py
index 29be450..434f481 100644
--- a/src/hardware/hardwaremanager.py
+++ b/src/hardware/hardwaremanager.py
@@ -50,6 +50,13 @@ class HardwareManager(object):
 if track.flags & gst.interfaces.MIXER_TRACK_MASTER:
 self._master = track
 
+def get_mute(self):
+if not self._mixer or not self._master:
+logging.error('Cannot get the mute status')
+return False
+return self._master.flags & gst.interfaces.MIXER_TRACK_MUTE \
+ == gst.interfaces.MIXER_TRACK_MUTE
+
 def get_volume(self):
 if not self._mixer or not self._master:
 logging.error('Cannot get the volume')
@@ -57,7 +64,16 @@ class HardwareManager(object):
 
 max_volume = self._master.max_volume
 min_volume = self._master.min_volume
-volume = self._mixer.get_volume(self._master)[0]
+
+volumes = self._mixer.get_volume(self._master)
+
+#sometimes we get a spurious zero from one/more channel(s)
+nonzero_vols = [v for v in volumes if v > 0.0]
+if len(nonzero_vols) != 0 and len(nonzero_vols) != len(volumes):
+volumes = nonzero_vols
+
+#we could just pick the first channel's volume, but this converges
+volume = sum(volumes) / len(volumes)
 
 return volume * 100.0 / (max_volume - min_volume) + min_volume
 
@@ -76,7 +92,13 @@ class HardwareManager(object):
 volume = volume * (max_volume - min_volume) / 100.0 + min_volume
 volume_list = [ volume ] * self._master.num_channels
 
-self._mixer.set_volume(self._master, tuple(volume_list))
+#sometimes alsa fails to set all channels' volume, so try a few times
+last_volumes_read = [0]
+read_count = 0
+while (0 in last_volumes_read) and (read_count < 3):
+self._mixer.set_volume(self._master, tuple(volume_list))
+last_volumes_read = self._mixer.get_volume(self._master)
+read_count += 1
 
 def set_mute(self, mute):
 if not self._mixer or not self._master:
diff --git a/src/model/devices/Makefile.am b/src/model/devices/Makefile.am
index 5440eeb..3124144 100644
--- a/src/model/devices/Makefile.am
+++ b/src/model/devices/Makefile.am
@@ -5,4 +5,6 @@ sugar_PYTHON =  \
__init__.py \
device.py   \
devicesmodel.py \
-   battery.py
+   battery.py  \
+   speaker.py
+
diff --git a/src/model/devices/devicesmodel.py 
b/src/model/devices/devicesmodel.py
index 691e19e..32c77da 100644
--- a/src/model/devices/devicesmodel.py
+++ b/src/model/devices/devicesmodel.py
@@ -23,6 +23,7 @@ from model.devices import device
 from model.devices.network import wireless
 from model.devices.network import mesh
 from model.devices import battery
+from model.devices import speaker
 from hardware import hardwaremanager
 from hardware import nmclient
 
@@ -54,6 +55,8 @@ class DevicesModel(gobject.GObject):
 for udi in hal_manager.FindDeviceByCapability('battery'):
 self.add_device(battery.Device(udi))
 
+self.add_device(speaker.Device())
+
 def _observe_network_manager(self):
 network_manager = hardwaremanager.get_network_manager()
 if not network_manager:
diff --git a/src/model/devices/speaker.py b/src/model/devices/speaker.py
new file mode 100644
index 000..d3b9967
--- /dev/null
+++ b/src/model/devices/speaker.py
@@ -0,0 +1,59 @@
+# Copyright (C) 2008 Martin Dengler
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+import gobject
+
+from hardware import hardwaremanager
+from model.devices import device
+
+class Device(dev

Re: [sugar] [PATCH] Add speaker device and icon by default

2008-04-24 Thread Martin Dengler
On Thu, Apr 24, 2008 at 12:47:11PM -0400, Eben Eliason wrote:
> On Thu, Apr 24, 2008 at 12:40 PM, Martin Dengler wrote:
> > On Thu, Apr 24, 2008 at 12:01:52PM -0400, Eben Eliason wrote:
> >  > On Thu, Apr 24, 2008 at 7:33 AM, Martin Dengler wrote:
> >  > >  +return self._master.flags & gst.interfaces.MIXER_TRACK_MUTE \
> >  > >  + == gst.interfaces.MIXER_TRACK_MUTE
> >  >
> >  > If MIXER_TRACK_MUTE is a bit mask, isn't the equality check redundant?
> >
> >  It's not a bitmask, IIUC.  So no, it's not redundant AFAICS.  But yes,
> >  it'd read much more nicely without the equality check if it wasn't.
> 
> Hmmm, but you appear to be using it as such anyway.  How else could
> the boolean & be interpreted logically otherwise?  (I may very well be
> missing something here.)

the GFlags class overrides the __and__ method...nice, eh?

>>> master.flags

>>> gst.interfaces.MIXER_TRACK_MUTE.__and__

>>> type(gst.interfaces.MIXER_TRACK_MUTE)

>>> type(gst.interfaces.MIXER_TRACK_MUTE & gst.interfaces.MIXER_TRACK_MUTE)


> - Eben

Martin


pgplSrcTMG9Dw.pgp
Description: PGP signature
___
Sugar mailing list
Sugar@lists.laptop.org
http://lists.laptop.org/listinfo/sugar


Re: [sugar] [PATCH] Add speaker device and icon by default

2008-04-24 Thread Eben Eliason
On Thu, Apr 24, 2008 at 12:40 PM, Martin Dengler
<[EMAIL PROTECTED]> wrote:
> On Thu, Apr 24, 2008 at 12:01:52PM -0400, Eben Eliason wrote:
>  > I'll /try/ to keep my comments mostly to the UI and leave the code
>  > review for others.  I'll also fail at that to some extent, since I
>  > have curiosities about bits and pieces.
>  >
>  > On Thu, Apr 24, 2008 at 7:33 AM, Martin Dengler
>  > <[EMAIL PROTECTED]> wrote:
>  >
>  > >  +return self._master.flags & gst.interfaces.MIXER_TRACK_MUTE \
>  > >  + == gst.interfaces.MIXER_TRACK_MUTE
>  >
>  > If MIXER_TRACK_MUTE is a bit mask, isn't the equality check redundant?
>
>  It's not a bitmask, IIUC.  So no, it's not redundant AFAICS.  But yes,
>  it'd read much more nicely without the equality check if it wasn't.

Hmmm, but you appear to be using it as such anyway.  How else could
the boolean & be interpreted logically otherwise?  (I may very well be
missing something here.)  It was pointed out to me that one reason for
it would be to return a boolean type, instead of an int, which is a
valid assessment (I'm too familiar with C).  If that's the core
reason, however, I might find simply casting to bool clearer.

>  > Let's use the dialog-ok and dialog-cancel icons for now, which will
>  > match the current mockups for the mic and camera.  We can change them
>  > easily later if we need to.
>
>  dialog-ok to go with the "Unmute" text, and -cancel to go with "Mute"?

Yup.

>  > >  +mute_item_text += '...'
>  >
>  > This is a bad habit that everyone seems to get into.  Cut this line.
>
>  Sorry!  I know the rule(s) you cite, and must blame lack of sleep for
>  leaving this in.  I was cargo-culting "Disconnect..." from
>  network/wireless.py, I think.

Good!  I expect not to have to slap you again for this.  :-P

- Eben
___
Sugar mailing list
Sugar@lists.laptop.org
http://lists.laptop.org/listinfo/sugar


Re: [sugar] [PATCH] Add speaker device and icon by default

2008-04-24 Thread Martin Dengler
On Thu, Apr 24, 2008 at 12:01:52PM -0400, Eben Eliason wrote:
> I'll /try/ to keep my comments mostly to the UI and leave the code
> review for others.  I'll also fail at that to some extent, since I
> have curiosities about bits and pieces.
> 
> On Thu, Apr 24, 2008 at 7:33 AM, Martin Dengler
> <[EMAIL PROTECTED]> wrote:
> 
> >  +return self._master.flags & gst.interfaces.MIXER_TRACK_MUTE \
> >  + == gst.interfaces.MIXER_TRACK_MUTE
> 
> If MIXER_TRACK_MUTE is a bit mask, isn't the equality check redundant?

It's not a bitmask, IIUC.  So no, it's not redundant AFAICS.  But yes,
it'd read much more nicely without the equality check if it wasn't.

> >  +#sometimes we get a spurious zero from one/more channel(s)
> >  +#we could just pick the first channel's volume, but this converges
> >  +#sometimes alsa fails to set all channels' volume, so try a few 
> > times
> 
> That's all fairly ugly, huh?  Oh well.

I know!

> >  +badge_name = None
> ...
> >  +self.icon.props.badge_name = badge_name
> 
> What's the logic for leaving this in?

Hmmm...I must've missed that pylint warning.  The variable goes.

> >  +def _mute_item_text(self):
> ...
> >  +return _(mute_item_text)
> 
> Defining this in a function seems to work OK here, but I think I also
> want icons on the menu item, which also depends on the current state.
> As such, it may actually be cleaner to have an _update function of
> some kind which handles both text and image together, setting them
> directly instead of returning a value.

Agree -- I just didn't have any icons, so no use for such a function
yet.

> Let's use the dialog-ok and dialog-cancel icons for now, which will
> match the current mockups for the mic and camera.  We can change them
> easily later if we need to.

dialog-ok to go with the "Unmute" text, and -cancel to go with "Mute"?

> >  +mute_item_text = self._model.props.muted and 'Unmute' or 'Mute'
> 
> This is a tricky ternary stand-in.  Very clever.  Is it clear enough for 
> others?
> 

I'll change to the proper ternary clause as recommended by bemasc.


> >  +mute_item_text += '...'
> 
> This is a bad habit that everyone seems to get into.  Cut this line.

Sorry!  I know the rule(s) you cite, and must blame lack of sleep for
leaving this in.  I was cargo-culting "Disconnect..." from
network/wireless.py, I think.

> - Eben

Martin



pgpTWPw2nOiy6.pgp
Description: PGP signature
___
Sugar mailing list
Sugar@lists.laptop.org
http://lists.laptop.org/listinfo/sugar


Re: [sugar] [PATCH] Add speaker device and icon by default

2008-04-24 Thread Martin Dengler
On Thu, Apr 24, 2008 at 12:13:19PM -0400, Benjamin M. Schwartz wrote:
> I would prefer a true ternary expression (new in 2.5):
> mute_item_text = 'Unmute' if self._model.props.muted else 'Mute'

Doh -- I forgot we're on 2.5.  Of course this is the right thing to
do.  Thanks.

> - --Ben

Martin



pgp7SSjrlo6ER.pgp
Description: PGP signature
___
Sugar mailing list
Sugar@lists.laptop.org
http://lists.laptop.org/listinfo/sugar


Re: [sugar] [PATCH] Add speaker device and icon by default

2008-04-24 Thread Eben Eliason
On Thu, Apr 24, 2008 at 12:14 PM, Bert Freudenberg <[EMAIL PROTECTED]> wrote:
>
>  On 24.04.2008, at 18:01, Eben Eliason wrote:
>  >
>  >> +mute_item_text = self._model.props.muted and 'Unmute' or
>  >> 'Mute'
>  >
>  > This is a tricky ternary stand-in.  Very clever.  Is it clear enough
>  > for others?
>
>
>  It's an abuse of Python, IMHO.

Tricky and abusive often go hand in hand, and abuses of languages are
often the most interesting, though clearly not the most transparent.
=)  C, for instance, seems to taunt with all of the glorious hacks it
is capable of executing as syntactically correct code. Duff's Device
[1], anyone?  Of course, usually susceptibility to such temptations
result in a clean shot through one's own foot, with a sharp segfault
bullet or worse.

- Eben

[1] http://en.wikipedia.org/wiki/Duff's_device
___
Sugar mailing list
Sugar@lists.laptop.org
http://lists.laptop.org/listinfo/sugar


Re: [sugar] [PATCH] Add speaker device and icon by default

2008-04-24 Thread Bert Freudenberg

On 24.04.2008, at 18:01, Eben Eliason wrote:
>
>> +mute_item_text = self._model.props.muted and 'Unmute' or  
>> 'Mute'
>
> This is a tricky ternary stand-in.  Very clever.  Is it clear enough  
> for others?


It's an abuse of Python, IMHO.


- Bert -


___
Sugar mailing list
Sugar@lists.laptop.org
http://lists.laptop.org/listinfo/sugar


Re: [sugar] [PATCH] Add speaker device and icon by default

2008-04-24 Thread Benjamin M. Schwartz
-BEGIN PGP SIGNED MESSAGE-
Hash: SHA1

Eben Eliason wrote:
|>  +mute_item_text = self._model.props.muted and 'Unmute' or 'Mute'
|
| This is a tricky ternary stand-in.  Very clever.  Is it clear enough for
others?

If you want it on one line, I would prefer a true ternary expression (new
in 2.5):
mute_item_text = 'Unmute' if self._model.props.muted else 'Mute'

- --Ben
-BEGIN PGP SIGNATURE-
Version: GnuPG v2.0.7 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFIELGfUJT6e6HFtqQRAsmlAJ0UFPQhOLuWvvW7zFwR38ZjaB161ACbBhuc
9JJaPTMpBtNfOOwyzTaFv3g=
=Ot34
-END PGP SIGNATURE-
___
Sugar mailing list
Sugar@lists.laptop.org
http://lists.laptop.org/listinfo/sugar


Re: [sugar] [PATCH] Add speaker device and icon by default

2008-04-24 Thread Eben Eliason
I'll /try/ to keep my comments mostly to the UI and leave the code
review for others.  I'll also fail at that to some extent, since I
have curiosities about bits and pieces.

On Thu, Apr 24, 2008 at 7:33 AM, Martin Dengler
<[EMAIL PROTECTED]> wrote:

>  +return self._master.flags & gst.interfaces.MIXER_TRACK_MUTE \
>  + == gst.interfaces.MIXER_TRACK_MUTE

If MIXER_TRACK_MUTE is a bit mask, isn't the equality check redundant?

>  +#sometimes we get a spurious zero from one/more channel(s)
>  +#we could just pick the first channel's volume, but this converges
>  +#sometimes alsa fails to set all channels' volume, so try a few 
> times

That's all fairly ugly, huh?  Oh well.

>  +badge_name = None
...
>  +self.icon.props.badge_name = badge_name

What's the logic for leaving this in?  Is there a circumstance in
which you think we may later add a badge, because at the moment this
variable is never used.

>  +def _mute_item_text(self):
...
>  +return _(mute_item_text)

Defining this in a function seems to work OK here, but I think I also
want icons on the menu item, which also depends on the current state.
As such, it may actually be cleaner to have an _update function of
some kind which handles both text and image together, setting them
directly instead of returning a value.  I suppose you could also have
separate functions for _mute_item_text and _mute_item_icon, as
wellI'll let the others decide.

Let's use the dialog-ok and dialog-cancel icons for now, which will
match the current mockups for the mic and camera.  We can change them
easily later if we need to.

>  +mute_item_text = self._model.props.muted and 'Unmute' or 'Mute'

This is a tricky ternary stand-in.  Very clever.  Is it clear enough for others?

>  +mute_item_text += '...'

This is a bad habit that everyone seems to get into.  Cut this line.
Every menu item takes an action when clicked, and that's implicit,
making the ellipsis effectively redundant. The ellipsis should only be
used when (a) the text represents a "state of flux", eg. in the AP
palettes /while/ "Connecting..." (not on the "Connect" menu item
itself, which initiates it) or (b) The action of the menu item itself
reveals a dialog which requires further feedback before actually
initiating a "real" action.

- Eben
___
Sugar mailing list
Sugar@lists.laptop.org
http://lists.laptop.org/listinfo/sugar


[sugar] [PATCH] Add speaker device and icon by default

2008-04-24 Thread Martin Dengler
Add speaker device and icon by default, as in
http://wiki.laptop.org/go/Designs/Frame#07
---
 src/hardware/hardwaremanager.py   |   28 +-
 src/model/devices/Makefile.am |4 +-
 src/model/devices/devicesmodel.py |3 +
 src/model/devices/speaker.py  |   59 +++
 src/view/devices/Makefile.am  |4 +-
 src/view/devices/speaker.py   |  113 +
 6 files changed, 207 insertions(+), 4 deletions(-)
 create mode 100644 src/model/devices/speaker.py
 create mode 100644 src/view/devices/speaker.py

diff --git a/src/hardware/hardwaremanager.py b/src/hardware/hardwaremanager.py
index 29be450..f5bb0e3 100644
--- a/src/hardware/hardwaremanager.py
+++ b/src/hardware/hardwaremanager.py
@@ -50,6 +50,13 @@ class HardwareManager(object):
 if track.flags & gst.interfaces.MIXER_TRACK_MASTER:
 self._master = track
 
+def get_mute(self):
+if not self._mixer or not self._master:
+logging.error('Cannot get the mute status')
+return False
+return self._master.flags & gst.interfaces.MIXER_TRACK_MUTE \
+ == gst.interfaces.MIXER_TRACK_MUTE
+
 def get_volume(self):
 if not self._mixer or not self._master:
 logging.error('Cannot get the volume')
@@ -57,7 +64,16 @@ class HardwareManager(object):
 
 max_volume = self._master.max_volume
 min_volume = self._master.min_volume
-volume = self._mixer.get_volume(self._master)[0]
+
+volumes = self._mixer.get_volume(self._master)
+
+#sometimes we get a spurious zero from one/more channel(s)
+nonzero_vols = [v for v in volumes if v > 0.0]
+if len(nonzero_vols) != 0 and len(nonzero_vols) != len(volumes):
+volumes = nonzero_vols
+
+#we could just pick the first channel's volume, but this converges
+volume = sum(volumes) / len(volumes)
 
 return volume * 100.0 / (max_volume - min_volume) + min_volume
 
@@ -73,10 +89,18 @@ class HardwareManager(object):
 max_volume = self._master.max_volume
 min_volume = self._master.min_volume
 
+logging.debug("setting volume: %s (%s/%s/%s)" % (volume, min_volume, 
max_volume, self._master.num_channels))
 volume = volume * (max_volume - min_volume) / 100.0 + min_volume
 volume_list = [ volume ] * self._master.num_channels
 
-self._mixer.set_volume(self._master, tuple(volume_list))
+#sometimes alsa fails to set all channels' volume, so try a few times
+last_volumes_read = [0]
+read_count = 0
+while (0 in last_volumes_read) and (read_count < 3):
+logging.debug("setting volume_list %d: %s" % (read_count, 
volume_list))
+self._mixer.set_volume(self._master, tuple(volume_list))
+last_volumes_read = self._mixer.get_volume(self._master)
+read_count += 1
 
 def set_mute(self, mute):
 if not self._mixer or not self._master:
diff --git a/src/model/devices/Makefile.am b/src/model/devices/Makefile.am
index 5440eeb..3124144 100644
--- a/src/model/devices/Makefile.am
+++ b/src/model/devices/Makefile.am
@@ -5,4 +5,6 @@ sugar_PYTHON =  \
__init__.py \
device.py   \
devicesmodel.py \
-   battery.py
+   battery.py  \
+   speaker.py
+
diff --git a/src/model/devices/devicesmodel.py 
b/src/model/devices/devicesmodel.py
index 691e19e..32c77da 100644
--- a/src/model/devices/devicesmodel.py
+++ b/src/model/devices/devicesmodel.py
@@ -23,6 +23,7 @@ from model.devices import device
 from model.devices.network import wireless
 from model.devices.network import mesh
 from model.devices import battery
+from model.devices import speaker
 from hardware import hardwaremanager
 from hardware import nmclient
 
@@ -54,6 +55,8 @@ class DevicesModel(gobject.GObject):
 for udi in hal_manager.FindDeviceByCapability('battery'):
 self.add_device(battery.Device(udi))
 
+self.add_device(speaker.Device())
+
 def _observe_network_manager(self):
 network_manager = hardwaremanager.get_network_manager()
 if not network_manager:
diff --git a/src/model/devices/speaker.py b/src/model/devices/speaker.py
new file mode 100644
index 000..d3b9967
--- /dev/null
+++ b/src/model/devices/speaker.py
@@ -0,0 +1,59 @@
+# Copyright (C) 2008 Martin Dengler
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have 

Re: [sugar] [PATCH] Add speaker device and icon by default

2008-04-24 Thread Marco Pesenti Gritti
On Thu, Apr 24, 2008 at 4:24 AM, Martin Dengler
<[EMAIL PROTECTED]> wrote:
>  Should I be submitting patches that include the Makefile.am changes?
>  Or does automake magically figure that out for me somehow?
>

Nope, you have to do it manually.

Marco
___
Sugar mailing list
Sugar@lists.laptop.org
http://lists.laptop.org/listinfo/sugar


Re: [sugar] [PATCH] Add speaker device and icon by default

2008-04-23 Thread Martin Dengler
I forgot - as in, wasn't aware - that/whether I should be adding the
new files to Makefile.am(s) in the new files' directories.  I've a
patch that does this.  It seemed to do the job for my sugar-jhbuild
emulation; I've been manually scp'ing the files to my XO to test "for
real".

Should I be submitting patches that include the Makefile.am changes?
Or does automake magically figure that out for me somehow?

Martin

On Thu, Apr 24, 2008 at 03:13:19AM +0100, Martin Dengler wrote:
> Add speaker device and icon by default, as in
> http://wiki.laptop.org/go/Designs/Frame#07
> ---
>  src/model/devices/devicesmodel.py |3 +
>  src/model/devices/speaker.py  |   59 ++
>  src/view/devices/speaker.py   |   99 
> +
>  3 files changed, 161 insertions(+), 0 deletions(-)
>  create mode 100644 src/model/devices/speaker.py
>  create mode 100644 src/view/devices/speaker.py
> 

...


pgpVJBHQhqKWJ.pgp
Description: PGP signature
___
Sugar mailing list
Sugar@lists.laptop.org
http://lists.laptop.org/listinfo/sugar


[sugar] [PATCH] Add speaker device and icon by default

2008-04-23 Thread Martin Dengler
Add speaker device and icon by default, as in
http://wiki.laptop.org/go/Designs/Frame#07
---
 src/model/devices/devicesmodel.py |3 +
 src/model/devices/speaker.py  |   59 ++
 src/view/devices/speaker.py   |   99 +
 3 files changed, 161 insertions(+), 0 deletions(-)
 create mode 100644 src/model/devices/speaker.py
 create mode 100644 src/view/devices/speaker.py

diff --git a/src/model/devices/devicesmodel.py 
b/src/model/devices/devicesmodel.py
index 691e19e..32c77da 100644
--- a/src/model/devices/devicesmodel.py
+++ b/src/model/devices/devicesmodel.py
@@ -23,6 +23,7 @@ from model.devices import device
 from model.devices.network import wireless
 from model.devices.network import mesh
 from model.devices import battery
+from model.devices import speaker
 from hardware import hardwaremanager
 from hardware import nmclient
 
@@ -54,6 +55,8 @@ class DevicesModel(gobject.GObject):
 for udi in hal_manager.FindDeviceByCapability('battery'):
 self.add_device(battery.Device(udi))
 
+self.add_device(speaker.Device())
+
 def _observe_network_manager(self):
 network_manager = hardwaremanager.get_network_manager()
 if not network_manager:
diff --git a/src/model/devices/speaker.py b/src/model/devices/speaker.py
new file mode 100644
index 000..9f84b81
--- /dev/null
+++ b/src/model/devices/speaker.py
@@ -0,0 +1,59 @@
+# Copyright (C) 2008 Martin Dengler
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+import gobject
+
+from hardware import hardwaremanager
+from model.devices import device
+
+class Device(device.Device):
+__gproperties__ = {
+'level'   : (int, None, None, 0, 100, 0, gobject.PARAM_READWRITE),
+'muted'   : (bool, None, None, False, gobject.PARAM_READWRITE),
+}
+
+def __init__(self):
+device.Device.__init__(self)
+self._manager = hardwaremanager.get_manager()
+
+def _get_level(self):
+return self._manager.get_volume()
+
+def _set_level(self, new_volume):
+self._manager.set_volume(new_volume)
+self.notify('level')
+
+def _get_muted(self):
+return self.props.level == 0.0
+
+def _set_muted(self, mute):
+self._manager.set_mute(mute)
+self.notify('muted')
+
+def get_type(self):
+return 'speaker'
+
+def do_get_property(self, pspec):
+if pspec.name == "level":
+return self._get_level()
+elif pspec.name == "muted":
+return self._get_muted()
+
+def do_set_property(self, pspec, value):
+if pspec.name == "level":
+self._set_level(value)
+elif pspec.name == "muted":
+self._set_muted(value)
diff --git a/src/view/devices/speaker.py b/src/view/devices/speaker.py
new file mode 100644
index 000..3fe36eb
--- /dev/null
+++ b/src/view/devices/speaker.py
@@ -0,0 +1,99 @@
+# Copyright (C) 2008 Martin Dengler
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+from gettext import gettext as _
+
+import gtk
+
+from sugar import profile
+from sugar.graphics import style
+from sugar.graphics.icon import get_icon_state
+from sugar.graphics.tray import TrayIcon
+from sugar.graphics.palette import Palette
+from sugar.graphics.xocolor import XoColor
+
+from view.frame.frameinvoker import FrameWidgetInvoker
+
+_ICON_NAME = 'speaker'
+
+class DeviceView(TrayIcon):
+def __init__(self, model):
+TrayIcon.__init__(self, icon_name=_ICON_NAME,
+  xo_color=profile.get_color())
+
+self._model = model
+self.palette = SpeakerPalette(_('My Speakers'), mo