Merge branch 'master' into datetime

This commit is contained in:
David Zeuthen 2010-10-20 13:55:41 -04:00
commit 1ca1a2712d
54 changed files with 10059 additions and 1671 deletions

View File

@ -75,7 +75,8 @@ PKG_CHECK_MODULES(MUTTER_PLUGIN, gio-2.0 >= $GIO_MIN_VERSION
clutter-x11-1.0 >= $CLUTTER_MIN_VERSION
clutter-glx-1.0 >= $CLUTTER_MIN_VERSION
libstartup-notification-1.0
gobject-introspection-1.0 >= $GOBJECT_INTROSPECTION_MIN_VERSION)
gobject-introspection-1.0 >= $GOBJECT_INTROSPECTION_MIN_VERSION
libcanberra)
saved_CFLAGS=$CFLAGS
saved_LIBS=$LIBS
@ -90,6 +91,7 @@ PKG_CHECK_MODULES(TIDY, clutter-1.0)
PKG_CHECK_MODULES(ST, clutter-1.0 gtk+-3.0 libcroco-0.6 gnome-desktop-3.0 >= 2.90.0)
PKG_CHECK_MODULES(GDMUSER, dbus-glib-1 gtk+-3.0)
PKG_CHECK_MODULES(TRAY, gtk+-3.0)
PKG_CHECK_MODULES(GVC, libpulse libpulse-mainloop-glib gobject-2.0)
MUTTER_BIN_DIR=`$PKG_CONFIG --variable=exec_prefix mutter-plugins`/bin
# FIXME: metacity-plugins.pc should point directly to its .gir file

View File

@ -235,10 +235,6 @@ StTooltip {
spacing: 4px;
}
#statusTray {
spacing: 14px;
}
#legacyTray {
spacing: 14px;
padding-left: 14px;
@ -903,9 +899,19 @@ StTooltip {
padding-bottom: 8px;
}
#summary-notification-bin #notification {
/* message-tray.height + notification.padding-bottom */
padding-bottom: 44px;
.summary-notification-boxpointer {
-arrow-border-radius: 9px;
-arrow-background-color: rgba(0,0,0,0.9);
-arrow-border-width: 2px;
-arrow-border-color: #5f5f5f;
-arrow-base: 30px;
-arrow-rise: 15px;
}
.summary-notification-boxpointer #notification {
border-radius: 9px;
background: rgba(0,0,0,0) !important;
padding-bottom: 12px;
}
#notification-scrollview {

View File

@ -44,6 +44,7 @@ nobase_dist_js_DATA = \
ui/statusIconDispatcher.js \
ui/statusMenu.js \
ui/status/accessibility.js \
ui/status/volume.js \
ui/telepathyClient.js \
ui/tweener.js \
ui/windowAttentionHandler.js \

View File

@ -5,6 +5,10 @@ const Lang = imports.lang;
const St = imports.gi.St;
const Shell = imports.gi.Shell;
const Tweener = imports.ui.tweener;
const POPUP_ANIMATION_TIME = 0.15;
/**
* BoxPointer:
* @side: A St.Side type; currently only St.Side.TOP is implemented
@ -38,6 +42,80 @@ BoxPointer.prototype = {
this.bin.raise(this._border);
},
animateAppear: function(onComplete) {
let x = this.actor.x;
let y = this.actor.y;
let themeNode = this.actor.get_theme_node();
let [found, rise] = themeNode.get_length('-arrow-rise', false);
if (!found)
rise = 0;
this.actor.opacity = 0;
this.actor.show();
switch (this._arrowSide) {
case St.Side.TOP:
this.actor.y -= rise;
break;
case St.Side.BOTTOM:
this.actor.y += rise;
break;
case St.Side.LEFT:
this.actor.x -= rise;
break;
case St.Side.RIGHT:
this.actor.x += rise;
break;
}
Tweener.addTween(this.actor, { opacity: 255,
x: x,
y: y,
transition: "linear",
onComplete: onComplete,
time: POPUP_ANIMATION_TIME });
},
animateDisappear: function(onComplete) {
let x = this.actor.x;
let y = this.actor.y;
let originalX = this.actor.x;
let originalY = this.actor.y;
let themeNode = this.actor.get_theme_node();
let [found, rise] = themeNode.get_length('-arrow-rise', false);
if (!found)
rise = 0;
switch (this._arrowSide) {
case St.Side.TOP:
y += rise;
break;
case St.Side.BOTTOM:
y -= rise;
break;
case St.Side.LEFT:
x += rise;
break;
case St.Side.RIGHT:
x -= rise;
break;
}
Tweener.addTween(this.actor, { opacity: 0,
x: x,
y: y,
transition: "linear",
time: POPUP_ANIMATION_TIME,
onComplete: Lang.bind(this, function () {
this.actor.hide();
this.actor.x = originalX;
this.actor.y = originalY;
if (onComplete)
onComplete();
})
});
},
_adjustAllocationForArrow: function(isWidth, alloc) {
let themeNode = this.actor.get_theme_node();
let found, borderWidth, base, rise;
@ -186,6 +264,92 @@ BoxPointer.prototype = {
cr.stroke();
},
setPosition: function(sourceActor, gap, alignment) {
let primary = global.get_primary_monitor();
// We need to show it now to force an allocation,
// so that we can query the correct size.
this.actor.show();
// Position correctly relative to the sourceActor
let [sourceX, sourceY] = sourceActor.get_transformed_position();
let [sourceWidth, sourceHeight] = sourceActor.get_transformed_size();
let [minWidth, minHeight, natWidth, natHeight] = this.actor.get_preferred_size();
let resX, resY;
switch (this._arrowSide) {
case St.Side.TOP:
resY = sourceY + sourceHeight + gap;
break;
case St.Side.BOTTOM:
resY = sourceY - natHeight - gap;
break;
case St.Side.LEFT:
resX = sourceX + sourceWidth + gap;
break;
case St.Side.RIGHT:
resX = sourceX - natWidth - gap;
break;
}
// Now align and position the pointing axis, making sure
// it fits on screen
switch (this._arrowSide) {
case St.Side.TOP:
case St.Side.BOTTOM:
switch (alignment) {
case St.Align.START:
resX = sourceX;
break;
case St.Align.MIDDLE:
resX = sourceX - Math.floor((natWidth - sourceWidth) / 2);
break;
case St.Align.END:
resX = sourceX - (natWidth - sourceWidth);
break;
}
resX = Math.min(resX, primary.x + primary.width - natWidth);
resX = Math.max(resX, primary.x);
this.setArrowOrigin((sourceX - resX) + Math.floor(sourceWidth / 2));
break;
case St.Side.LEFT:
case St.Side.RIGHT:
switch (alignment) {
case St.Align.START:
resY = sourceY;
break;
case St.Align.MIDDLE:
resY = sourceY - Math.floor((natHeight - sourceHeight) / 2);
break;
case St.Align.END:
resY = sourceY - (natHeight - sourceHeight);
break;
}
resY = Math.min(resY, primary.y + primary.height - natHeight);
resY = Math.max(resY, primary.y);
this.setArrowOrigin((sourceY - resY) + Math.floor(sourceHeight / 2));
break;
}
let parent = this.actor.get_parent();
let success, x, y;
while (!success) {
[success, x, y] = parent.transform_stage_point(resX, resY);
parent = parent.get_parent();
}
// Actually set the position
this.actor.x = Math.floor(x);
this.actor.y = Math.floor(y);
},
// @origin: Coordinate specifying middle of the arrow, along
// the Y axis for St.Side.LEFT, St.Side.RIGHT from the top and X axis from
// the left for St.Side.TOP and St.Side.BOTTOM.

View File

@ -51,6 +51,12 @@ function loadExtension(dir, enabled, type) {
return;
}
}
if (extensions[meta.uuid] != undefined) {
global.logError(baseErrorString + "extension already loaded");
return;
}
// Encourage people to add this
if (!meta['url']) {
global.log(baseErrorString + 'Warning: Missing "url" property in metadata.json');

View File

@ -135,9 +135,12 @@ function IconGrid(params) {
IconGrid.prototype = {
_init: function(params) {
params = Params.parse(params, { rowLimit: null, columnLimit: null });
params = Params.parse(params, { rowLimit: null,
columnLimit: null,
xAlign: St.Align.MIDDLE });
this._rowLimit = params.rowLimit;
this._colLimit = params.columnLimit;
this._xAlign = params.xAlign;
this.actor = new St.BoxLayout({ style_class: 'icon-grid',
vertical: true });
@ -189,9 +192,19 @@ IconGrid.prototype = {
let [nColumns, usedWidth] = this._computeLayout(availWidth);
let overallPaddingX = Math.floor((availWidth - usedWidth) / 2);
let leftPadding;
switch(this._xAlign) {
case St.Align.START:
leftPadding = 0;
break;
case St.Align.MIDDLE:
leftPadding = Math.floor((availWidth - usedWidth) / 2);
break;
case St.Align.END:
leftPadding = availWidth - usedWidth;
}
let x = box.x1 + overallPaddingX;
let x = box.x1 + leftPadding;
let y = box.y1;
let columnIndex = 0;
let rowIndex = 0;
@ -231,7 +244,7 @@ IconGrid.prototype = {
if (columnIndex == 0) {
y += this._item_size + this._spacing;
x = box.x1 + overallPaddingX;
x = box.x1 + leftPadding;
} else {
x += this._item_size + this._spacing;
}

View File

@ -12,6 +12,7 @@ const St = imports.gi.St;
const Tweener = imports.ui.tweener;
const Main = imports.ui.main;
const BoxPointer = imports.ui.boxpointer;
const Params = imports.misc.params;
const ANIMATION_TIME = 0.2;
@ -778,15 +779,19 @@ MessageTray.prototype = {
this._summaryBin.child = this._summary;
this._summaryBin.opacity = 0;
this._summaryNotificationBin = new St.Bin({ name: 'summary-notification-bin',
anchor_gravity: Clutter.Gravity.NORTH_EAST,
reactive: true,
this._summaryMotionId = 0;
this._summaryNotificationBoxPointer = new BoxPointer.BoxPointer(St.Side.BOTTOM,
{ reactive: true,
track_hover: true });
this.actor.add_actor(this._summaryNotificationBin);
this._summaryNotificationBin.lower_bottom();
this._summaryNotificationBin.hide();
this._summaryNotificationBoxPointer.actor.style_class = 'summary-notification-boxpointer';
this.actor.add_actor(this._summaryNotificationBoxPointer.actor);
this._summaryNotificationBoxPointer.actor.lower_bottom();
this._summaryNotificationBoxPointer.actor.hide();
this._summaryNotification = null;
this._clickedSummaryItem = null;
this._clickedSummaryItemAllocationChangedId = 0;
this._expandedSummaryItem = null;
this._summaryItemTitleWidth = 0;
@ -817,7 +822,7 @@ MessageTray.prototype = {
Main.chrome.addActor(this.actor, { affectsStruts: false,
visibleInOverview: true });
Main.chrome.trackActor(this._notificationBin);
Main.chrome.trackActor(this._summaryNotificationBin);
Main.chrome.trackActor(this._summaryNotificationBoxPointer.actor);
global.gdk_screen.connect('monitors-changed', Lang.bind(this, this._setSizePosition));
@ -859,7 +864,6 @@ MessageTray.prototype = {
// These work because of their anchor_gravity
this._summaryBin.x = primary.width;
this._summaryNotificationBin.x = primary.width;
},
contains: function(source) {
@ -964,7 +968,7 @@ MessageTray.prototype = {
needUpdate = true;
}
if (this._clickedSummaryItem && this._clickedSummaryItem.source == source) {
this._clickedSummaryItem = null;
this._unsetClickedSummaryItem();
needUpdate = true;
}
@ -993,7 +997,7 @@ MessageTray.prototype = {
if (!this._locked)
return;
this._locked = false;
this._clickedSummaryItem = null;
this._unsetClickedSummaryItem();
this._updateState();
},
@ -1116,7 +1120,7 @@ MessageTray.prototype = {
if (!this._clickedSummaryItem || this._clickedSummaryItem != summaryItem)
this._clickedSummaryItem = summaryItem;
else
this._clickedSummaryItem = null;
this._unsetClickedSummaryItem();
this._updateState();
},
@ -1478,25 +1482,51 @@ MessageTray.prototype = {
if (index != -1)
this._notificationQueue.splice(index, 1);
this._summaryNotificationBin.child = this._summaryNotification.actor;
this._summaryNotificationBoxPointer.bin.child = this._summaryNotification.actor;
this._summaryNotification.grabFocus(true);
this._summaryNotificationBin.opacity = 0;
this._summaryNotificationBin.y = this.actor.height;
this._summaryNotificationBin.show();
if (!this._summaryNotificationExpandedId)
this._summaryNotificationExpandedId = this._summaryNotification.connect('expanded', Lang.bind(this, this._onSummaryNotificationExpanded));
this._summaryNotification.expand(false);
this._clickedSummaryItemAllocationChangedId =
this._clickedSummaryItem.actor.connect('allocation-changed',
Lang.bind(this, this._adjustNotificationBoxPointerPosition));
// _clickedSummaryItem.actor can change absolute postiion without changing allocation
this._summaryMotionId = this._summary.connect('allocation-changed',
Lang.bind(this, this._adjustNotificationBoxPointerPosition));
this._summaryNotificationBoxPointer.actor.opacity = 0;
this._summaryNotificationBoxPointer.actor.show();
this._adjustNotificationBoxPointerPosition();
this._summaryNotificationState = State.SHOWNING;
this._summaryNotificationBoxPointer.animateAppear(Lang.bind(this, function() {
this._summaryNotificationState = State.SHOWN;
}));
},
_adjustNotificationBoxPointerPosition: function() {
// The position of the arrow origin should be the same as center of this._clickedSummaryItem.actor
if (!this._clickedSummaryItem)
return;
this._summaryNotificationBoxPointer.setPosition(this._clickedSummaryItem.actor, 0, St.Align.MIDDLE);
},
_unsetClickedSummaryItem: function() {
if (this._clickedSummaryItemAllocationChangedId) {
this._clickedSummaryItem.actor.disconnect(this._clickedSummaryItemAllocationChangedId);
this._summary.disconnect(this._summaryMotionId);
this._clickedSummaryItemAllocationChangedId = 0;
this._summaryMotionId = 0;
}
this._clickedSummaryItem = null;
},
_onSummaryNotificationExpanded: function() {
this._tween(this._summaryNotificationBin, '_summaryNotificationState', State.SHOWN,
{ y: this.actor.height - this._summaryNotificationBin.height,
opacity: 255,
time: ANIMATION_TIME,
transition: 'easeOutQuad'
});
this._adjustNotificationBoxPointerPosition();
},
_hideSummaryNotification: function() {
@ -1504,25 +1534,18 @@ MessageTray.prototype = {
this._summaryNotification.disconnect(this._summaryNotificationExpandedId);
this._summaryNotificationExpandedId = 0;
}
// Unset this._clickedSummaryItem if we are no longer showing the summary
if (this._summaryState != State.SHOWN)
this._clickedSummaryItem = null;
this._summaryNotification.ungrabFocus();
this._unsetClickedSummaryItem();
this._tween(this._summaryNotificationBin, '_summaryNotificationState', State.HIDDEN,
{ y: this.actor.height,
opacity: 0,
time: ANIMATION_TIME,
transition: 'easeOutQuad',
onComplete: this._hideSummaryNotificationCompleted,
onCompleteScope: this
});
this._summaryNotification.ungrabFocus();
this._summaryNotificationState = State.HIDING;
this._summaryNotificationBoxPointer.animateDisappear(Lang.bind(this, this._hideSummaryNotificationCompleted));
},
_hideSummaryNotificationCompleted: function() {
this._summaryNotificationBin.hide();
this._summaryNotificationBin.child = null;
this._summaryNotificationState = State.HIDDEN;
this._summaryNotificationBoxPointer.bin.child = null;
this._summaryNotification.collapseCompleted();
let summaryNotification = this._summaryNotification;
this._summaryNotification = null;

View File

@ -32,7 +32,8 @@ const SPINNER_SPEED = 0.02;
const STANDARD_TRAY_ICON_ORDER = ['a11y', 'display', 'keyboard', 'volume', 'bluetooth', 'network', 'battery'];
const STANDARD_TRAY_ICON_SHELL_IMPLEMENTATION = {
'a11y': imports.ui.status.accessibility.ATIndicator
'a11y': imports.ui.status.accessibility.ATIndicator,
'volume': imports.ui.status.volume.Indicator,
};
function AnimatedIcon(name, size) {

View File

@ -16,8 +16,6 @@ const Tweener = imports.ui.tweener;
const Gettext = imports.gettext.domain('gnome-shell');
const _ = Gettext.gettext;
const POPUP_ANIMATION_TIME = 0.1;
function Switch() {
this._init.apply(this, arguments);
}
@ -178,7 +176,7 @@ PopupSliderMenuItem.prototype = {
if (isNaN(value))
// Avoid spreading NaNs around
throw TypeError('The slider value must be a number');
this._displayValue = this._value = Math.max(Math.min(value, 1), 0);
this._value = Math.max(Math.min(value, 1), 0);
this._slider = new St.DrawingArea({ style_class: 'popup-slider-menu-item', reactive: true });
this.actor.set_child(this._slider);
@ -193,7 +191,7 @@ PopupSliderMenuItem.prototype = {
if (isNaN(value))
throw TypeError('The slider value must be a number');
this._displayValue = this._value = Math.max(Math.min(value, 1), 0);
this._value = Math.max(Math.min(value, 1), 0);
this._slider.queue_repaint();
},
@ -233,7 +231,7 @@ PopupSliderMenuItem.prototype = {
cr.stroke();
let handleY = height / 2;
let handleX = handleRadius + (width - 2 * handleRadius) * this._displayValue;
let handleX = handleRadius + (width - 2 * handleRadius) * this._value;
let color = new Clutter.Color();
themeNode.get_foreground_color(color);
@ -271,8 +269,7 @@ PopupSliderMenuItem.prototype = {
Clutter.ungrab_pointer();
this._dragging = false;
this._value = this._displayValue;
this.emit('value-changed', this._value);
this.emit('drag-end');
}
return true;
},
@ -301,8 +298,9 @@ PopupSliderMenuItem.prototype = {
newvalue = 1;
else
newvalue = (relX - handleRadius) / (width - 2 * handleRadius);
this._displayValue = newvalue;
this._value = newvalue;
this._slider.queue_repaint();
this.emit('value-changed', this._value);
},
get value() {
@ -313,9 +311,10 @@ PopupSliderMenuItem.prototype = {
let key = event.get_key_symbol();
if (key == Clutter.Right || key == Clutter.Left) {
let delta = key == Clutter.Right ? 0.1 : -0.1;
this._value = this._displayValue = Math.max(0, Math.min(this._value + delta, 1));
this._value = Math.max(0, Math.min(this._value + delta, 1));
this._slider.queue_repaint();
this.emit('value-changed', this._value);
this.emit('drag-end');
return true;
}
return false;
@ -552,7 +551,6 @@ PopupMenu.prototype = {
let [minWidth, minHeight, natWidth, natHeight] = this.actor.get_preferred_size();
let menuX, menuY;
let menuWidth = natWidth, menuHeight = natHeight;
// Position the non-pointing axis
@ -575,75 +573,12 @@ PopupMenu.prototype = {
this._boxPointer._arrowSide = this._arrowSide = St.Side.LEFT;
}
}
switch (this._arrowSide) {
case St.Side.TOP:
menuY = sourceY + sourceHeight + this._gap;
break;
case St.Side.BOTTOM:
menuY = sourceY - menuHeight - this._gap;
break;
case St.Side.LEFT:
menuX = sourceX + sourceWidth + this._gap;
break;
case St.Side.RIGHT:
menuX = sourceX - menuWidth - this._gap;
break;
}
// Now align and position the pointing axis, making sure
// it fits on screen
switch (this._arrowSide) {
case St.Side.TOP:
case St.Side.BOTTOM:
switch (this._alignment) {
case St.Align.START:
menuX = sourceX;
break;
case St.Align.MIDDLE:
menuX = sourceX - Math.floor((menuWidth - sourceWidth) / 2);
break;
case St.Align.END:
menuX = sourceX - (menuWidth - sourceWidth);
break;
}
menuX = Math.min(menuX, primary.x + primary.width - menuWidth);
menuX = Math.max(menuX, primary.x);
this._boxPointer.setArrowOrigin((sourceX - menuX) + Math.floor(sourceWidth / 2));
break;
case St.Side.LEFT:
case St.Side.RIGHT:
switch (this._alignment) {
case St.Align.START:
menuY = sourceY;
break;
case St.Align.MIDDLE:
menuY = sourceY - Math.floor((menuHeight - sourceHeight) / 2);
break;
case St.Align.END:
menuY = sourceY - (menuHeight - sourceHeight);
break;
}
menuY = Math.min(menuY, primary.y + primary.height - menuHeight);
menuY = Math.max(menuY, primary.y);
this._boxPointer.setArrowOrigin((sourceY - menuY) + Math.floor(sourceHeight / 2));
break;
}
// Actually set the position
this.actor.x = Math.floor(menuX);
this.actor.y = Math.floor(menuY);
this._boxPointer.setPosition(this.sourceActor, this._gap, this._alignment);
// Now show it
this.actor.opacity = 0;
this.actor.reactive = true;
Tweener.addTween(this.actor, { opacity: 255,
transition: "easeOutQuad",
time: POPUP_ANIMATION_TIME });
this._boxPointer.animateAppear();
this.isOpen = true;
this.emit('open-state-changed', true);
},
@ -657,11 +592,7 @@ PopupMenu.prototype = {
if (this._activeMenuItem)
this._activeMenuItem.setActive(false);
this.actor.reactive = false;
Tweener.addTween(this.actor, { opacity: 0,
transition: "easeOutQuad",
time: POPUP_ANIMATION_TIME,
onComplete: Lang.bind(this, function () { this.actor.hide(); })});
this._boxPointer.animateDisappear();
this.isOpen = false;
this.emit('open-state-changed', false);
},

206
js/ui/status/volume.js Normal file
View File

@ -0,0 +1,206 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
const DBus = imports.dbus;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Shell = imports.gi.Shell;
const Gvc = imports.gi.Gvc;
const Signals = imports.signals;
const St = imports.gi.St;
const PanelMenu = imports.ui.panelMenu;
const PopupMenu = imports.ui.popupMenu;
const Gettext = imports.gettext.domain('gnome-shell');
const _ = Gettext.gettext;
const VOLUME_MAX = 65536.0; /* PA_VOLUME_NORM */
function Indicator() {
this._init.apply(this, arguments);
}
Indicator.prototype = {
__proto__: PanelMenu.SystemStatusButton.prototype,
_init: function() {
PanelMenu.SystemStatusButton.prototype._init.call(this, 'audio-volume-muted', null);
this._control = new Gvc.MixerControl({ name: 'GNOME Shell Volume Control' });
this._control.connect('ready', Lang.bind(this, this._onControlReady));
this._control.connect('default-sink-changed', Lang.bind(this, this._readOutput));
this._control.connect('default-source-changed', Lang.bind(this, this._readInput));
this._control.connect('stream-added', Lang.bind(this, this._maybeShowInput));
this._control.connect('stream-removed', Lang.bind(this, this._maybeShowInput));
this._output = null;
this._outputVolumeId = 0;
this._outputMutedId = 0;
this._outputSwitch = new PopupMenu.PopupSwitchMenuItem(_("Output: Muted"), false);
this._outputSwitch.connect('toggled', Lang.bind(this, this._switchToggled, '_output'));
this._outputSlider = new PopupMenu.PopupSliderMenuItem(0);
this._outputSlider.connect('value-changed', Lang.bind(this, this._sliderChanged, '_output'));
this._outputSlider.connect('drag-end', Lang.bind(this, this._notifyVolumeChange));
this.menu.addMenuItem(this._outputSwitch);
this.menu.addMenuItem(this._outputSlider);
this._separator = new PopupMenu.PopupSeparatorMenuItem();
this.menu.addMenuItem(this._separator);
this._input = null;
this._inputVolumeId = 0;
this._inputMutedId = 0;
this._inputSwitch = new PopupMenu.PopupSwitchMenuItem(_("Input: Muted"), false);
this._inputSwitch.connect('toggled', Lang.bind(this, this._switchToggled, '_input'));
this._inputSlider = new PopupMenu.PopupSliderMenuItem(0);
this._inputSlider.connect('value-changed', Lang.bind(this, this._sliderChanged, '_input'));
this._inputSlider.connect('drag-end', Lang.bind(this, this._notifyVolumeChange));
this.menu.addMenuItem(this._inputSwitch);
this.menu.addMenuItem(this._inputSlider);
this.menu.addMenuItem(new PopupMenu.PopupSeparatorMenuItem());
this.menu.addAction(_("Sound Preferences"), function() {
let p = new Shell.Process({ args: ['gnome-control-center', 'volume'] });
p.run();
});
this._control.open();
},
_onControlReady: function() {
this._readOutput();
this._readInput();
},
_readOutput: function() {
if (this._outputVolumeId) {
this._output.disconnect(this._outputVolumeId);
this._output.disconnect(this._outputMutedId);
this._outputVolumeId = 0;
this._outputMutedId = 0;
}
this._output = this._control.get_default_sink();
if (this._output) {
this._outputMutedId = this._output.connect('notify::is-muted', Lang.bind(this, this._mutedChanged, '_output'));
this._outputVolumeId = this._output.connect('notify::volume', Lang.bind(this, this._volumeChanged, '_output'));
this._mutedChanged (null, null, '_output');
this._volumeChanged (null, null, '_output');
this.setIcon(this._volumeToIcon(this._output.volume));
} else {
this._outputSwitch.label.text = _("Output: Muted");
this._outputSwitch.setToggleState(false);
this.setIcon('audio-volume-muted-symbolic');
}
},
_readInput: function() {
if (this._inputVolumeId) {
this._input.disconnect(this._inputVolumeId);
this._input.disconnect(this._inputMutedId);
this._inputVolumeId = 0;
this._inputMutedId = 0;
}
this._input = this._control.get_default_source();
if (this._input) {
this._inputMutedId = this._input.connect('notify::is-muted', Lang.bind(this, this._mutedChanged, '_input'));
this._inputVolumeId = this._input.connect('notify::volume', Lang.bind(this, this._volumeChanged, '_input'));
this._mutedChanged (null, null, '_input');
this._volumeChanged (null, null, '_input');
} else {
this._separator.actor.hide();
this._inputSwitch.actor.hide();
this._inputSlider.actor.hide();
}
},
_maybeShowInput: function() {
// only show input widgets if any application is recording audio
let showInput = false;
let recordingApps = this._control.get_source_outputs();
if (this._source && recordingApps) {
for (let i = 0; i < recordingApp.length; i++) {
let outputStream = recordingApp[i];
let id = outputStream.get_application_id();
// but skip gnome-volume-control and pavucontrol
// (that appear as recording because they show the input level)
if (!id || (id != 'org.gnome.VolumeControl' && id != 'org.PulseAudio.pavucontrol')) {
showInput = true;
break;
}
}
}
if (showInput) {
this._separator.actor.show();
this._inputSwitch.actor.show();
this._inputSlider.actor.show();
} else {
this._separator.actor.hide();
this._inputSwitch.actor.hide();
this._inputSlider.actor.hide();
}
},
_volumeToIcon: function(volume) {
if (volume <= 0) {
return 'audio-volume-muted';
} else {
let v = volume / VOLUME_MAX;
if (v < 0.33)
return 'audio-volume-low';
if (v > 0.8)
return 'audio-volume-high';
return 'audio-volume-medium';
}
},
_sliderChanged: function(slider, value, property) {
if (this[property] == null) {
log ('Volume slider changed for %s, but %s does not exist'.format(property, property));
return;
}
this[property].volume = value * VOLUME_MAX;
this[property].push_volume();
},
_notifyVolumeChange: function() {
global.play_theme_sound('audio-volume-change');
},
_switchToggled: function(switchItem, state, property) {
if (this[property] == null) {
log ('Volume mute switch toggled for %s, but %s does not exist'.format(property, property));
return;
}
this[property].change_is_muted(!state);
this._notifyVolumeChange();
},
_mutedChanged: function(object, param_spec, property) {
let muted = this[property].is_muted;
let toggleSwitch = this[property+'Switch'];
toggleSwitch.setToggleState(!muted);
this._updateLabel(property);
if (property == '_output') {
if (muted)
this.setIcon('audio-volume-muted');
else
this.setIcon(this._volumeToIcon(this._output.volume));
}
},
_volumeChanged: function(object, param_spec, property) {
this[property+'Slider'].setValue(this[property].volume / VOLUME_MAX);
this._updateLabel(property);
if (property == '_output')
this.setIcon(this._volumeToIcon(this._output.volume));
},
_updateLabel: function(property) {
let label;
if (this[property].is_muted)
label = (property == '_output' ? _("Output: Muted") : _("Input: Muted"));
else
label = (property == '_output' ? _("Output: %3.0f%%") : _("Input: %3.0f%%")).format(this[property].volume / VOLUME_MAX * 100);
this[property+'Switch'].label.text = label;
}
};

View File

@ -31,6 +31,8 @@ StatusMenuButton.prototype = {
this.actor.set_child(box);
this._gdm = Gdm.UserManager.ref_default();
this._gdm.queue_load()
this._user = this._gdm.get_user(GLib.get_user_name());
this._presence = new GnomeSession.Presence();
@ -48,27 +50,31 @@ StatusMenuButton.prototype = {
this._presence.connect('StatusChanged', Lang.bind(this, this._updatePresenceIcon));
this._presence.getStatus(Lang.bind(this, this._updatePresenceIcon));
this._name = new St.Label({ text: this._user.get_real_name() });
this._name = new St.Label();
box.add(this._name, { y_align: St.Align.MIDDLE, y_fill: false });
this._userNameChangedId = this._user.connect('notify::display-name', Lang.bind(this, this._updateUserName));
this._userLoadedId = this._user.connect('notify::is-loaded', Lang.bind(this, this._updateUserName));
this._userChangedId = this._user.connect('changed', Lang.bind(this, this._updateUserName));
this._createSubMenu();
this._gdm.connect('users-loaded', Lang.bind(this, this._updateSwitchUser));
this._gdm.connect('notify::is-loaded', Lang.bind(this, this._updateSwitchUser));
this._gdm.connect('user-added', Lang.bind(this, this._updateSwitchUser));
this._gdm.connect('user-removed', Lang.bind(this, this._updateSwitchUser));
},
_onDestroy: function() {
this._user.disconnect(this._userNameChangedId);
this._user.disconnect(this._userLoadedId);
this._user.disconnect(this._userChangedId);
},
_updateUserName: function() {
if (this._user.is_loaded)
this._name.set_text(this._user.get_real_name());
else
this._name.set_text("");
},
_updateSwitchUser: function() {
let users = this._gdm.list_users();
if (users.length > 1)
if (this._gdm.can_switch ())
this._loginScreenItem.actor.show();
else
this._loginScreenItem.actor.hide();

View File

@ -14,6 +14,7 @@ js/ui/placeDisplay.js
js/ui/popupMenu.js
js/ui/runDialog.js
js/ui/statusMenu.js
js/ui/status/accessibility.js
js/ui/windowAttentionHandler.js
js/ui/workspacesView.js
src/gdmuser/gdm-user.c

View File

@ -8,8 +8,8 @@ msgstr ""
"Project-Id-Version: gnome-shell.master\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
"shell&component=general\n"
"POT-Creation-Date: 2010-10-04 19:52+0000\n"
"PO-Revision-Date: 2010-10-13 14:29+0200\n"
"POT-Creation-Date: 2010-10-18 08:59+0000\n"
"PO-Revision-Date: 2010-10-18 11:12+0200\n"
"Last-Translator: Jorge González <jorgegonz@svn.gnome.org>\n"
"Language-Team: Español <gnome-es-list@gnome.org>\n"
"MIME-Version: 1.0\n"
@ -284,7 +284,6 @@ msgstr ""
"la imagen del ratón."
#: ../data/org.gnome.accessibility.magnifier.gschema.xml.in.h:7
#| msgid "Enabled"
msgid "Enable lens mode"
msgstr "Activar el modo lente"
@ -504,58 +503,58 @@ msgid "Undo"
msgstr "Deshacer"
#. TODO - _quit() doesn't really work on apps in state STARTING yet
#: ../js/ui/panel.js:461
#: ../js/ui/panel.js:468
#, c-format
msgid "Quit %s"
msgstr "Salir de %s"
#: ../js/ui/panel.js:486
#: ../js/ui/panel.js:493
msgid "Preferences"
msgstr "Preferencias"
#. Translators: This is the time format with date used
#. in 24-hour mode.
#: ../js/ui/panel.js:572
#: ../js/ui/panel.js:579
msgid "%a %b %e, %R:%S"
msgstr "%a %e de %b, %R:%S"
#: ../js/ui/panel.js:573
#: ../js/ui/panel.js:580
msgid "%a %b %e, %R"
msgstr "%a %e de %b, %R"
#. Translators: This is the time format without date used
#. in 24-hour mode.
#: ../js/ui/panel.js:577
#: ../js/ui/panel.js:584
msgid "%a %R:%S"
msgstr "%a %R:%S"
#: ../js/ui/panel.js:578
#: ../js/ui/panel.js:585
msgid "%a %R"
msgstr "%a %R"
#. Translators: This is a time format with date used
#. for AM/PM.
#: ../js/ui/panel.js:585
#: ../js/ui/panel.js:592
msgid "%a %b %e, %l:%M:%S %p"
msgstr "%a %e de %b, %H:%M:%S"
#: ../js/ui/panel.js:586
#: ../js/ui/panel.js:593
msgid "%a %b %e, %l:%M %p"
msgstr "%a %e de %b, %H:%M"
#. Translators: This is a time format without date used
#. for AM/PM.
#: ../js/ui/panel.js:590
#: ../js/ui/panel.js:597
msgid "%a %l:%M:%S %p"
msgstr "%a %H:%M:%S"
#: ../js/ui/panel.js:591
#: ../js/ui/panel.js:598
msgid "%a %l:%M %p"
msgstr "%a %H:%M"
#. Button on the left side of the panel.
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
#: ../js/ui/panel.js:736
#: ../js/ui/panel.js:743
msgid "Activities"
msgstr "Actividades"
@ -590,43 +589,86 @@ msgstr "Introduzca un comando:"
msgid "Execution of '%s' failed:"
msgstr "Falló la ejecución de «%s»:"
#: ../js/ui/statusMenu.js:91
#: ../js/ui/statusMenu.js:97
msgid "Available"
msgstr "Disponible"
#: ../js/ui/statusMenu.js:95
#: ../js/ui/statusMenu.js:101
msgid "Busy"
msgstr "Ocupado"
#: ../js/ui/statusMenu.js:99
#: ../js/ui/statusMenu.js:105
msgid "Invisible"
msgstr "Invisible"
#: ../js/ui/statusMenu.js:106
#: ../js/ui/statusMenu.js:112
msgid "Account Information..."
msgstr "Información de la cuenta…"
#: ../js/ui/statusMenu.js:110
#| msgid "System Preferences..."
#: ../js/ui/statusMenu.js:116
msgid "System Settings..."
msgstr "Ajustes del sistema…"
#: ../js/ui/statusMenu.js:117
#: ../js/ui/statusMenu.js:123
msgid "Lock Screen"
msgstr "Bloquear la pantalla"
#: ../js/ui/statusMenu.js:121
#: ../js/ui/statusMenu.js:127
msgid "Switch User"
msgstr "Cambiar de usuario"
#: ../js/ui/statusMenu.js:126
#: ../js/ui/statusMenu.js:132
msgid "Log Out..."
msgstr "Salir…"
#: ../js/ui/statusMenu.js:130
#: ../js/ui/statusMenu.js:136
msgid "Shut Down..."
msgstr "Apagar…"
#: ../js/ui/status/accessibility.js:88
msgid "Screen Reader"
msgstr "Lector de pantalla"
#: ../js/ui/status/accessibility.js:91
msgid "Screen Keyboard"
msgstr "Teclado en pantalla"
#: ../js/ui/status/accessibility.js:94
msgid "Visual Alerts"
msgstr "Alertas visuales"
#: ../js/ui/status/accessibility.js:97
msgid "Sticky Keys"
msgstr "Teclas persistentes"
#: ../js/ui/status/accessibility.js:100
msgid "Slow Keys"
msgstr "Teclas lentas"
#: ../js/ui/status/accessibility.js:103
msgid "Bounce Keys"
msgstr "Rechazo de teclas"
#: ../js/ui/status/accessibility.js:106
msgid "Mouse Keys"
msgstr "Teclas del ratón"
#: ../js/ui/status/accessibility.js:110
msgid "Universal Access Settings"
msgstr "Preferencias del acceso universal"
#: ../js/ui/status/accessibility.js:163
msgid "High Contrast"
msgstr "Contraste alto"
#: ../js/ui/status/accessibility.js:202
msgid "Large Text"
msgstr "<b>Texto:</b>"
#: ../js/ui/status/accessibility.js:223
msgid "Zoom"
msgstr "Ampliación"
#: ../js/ui/windowAttentionHandler.js:43
#, c-format
msgid "%s has finished starting"

269
po/et.po
View File

@ -1,30 +1,30 @@
# GNOME Kesta eesti keele tõlge.
# Estonian translation of GNOME Shell.
#
# Copyright (C) 2010 The GNOME Project.
# Estonian translation for gnome-shell.
# Copyright (C) 2010 The Gnome Project
# This file is distributed under the same license as the gnome-shell package.
#
# Ivar Smolin <okul linux ee>, 2010.
# Mattias Põldaru <mahfiaz gmail com>, 2010.
#
msgid ""
msgstr ""
"Project-Id-Version: gnome-shell master\n"
"Report-Msgid-Bugs-To: http://bugzilla.gnome.org/enter_bug.cgi?product=gnome-"
"shell&component=general\n"
"POT-Creation-Date: 2010-09-10 02:04+0000\n"
"PO-Revision-Date: 2010-09-10 08:29+0300\n"
"Last-Translator: Ivar Smolin <okul@linux.ee>\n"
"Language-Team: Estonian <et@li.org>\n"
"POT-Creation-Date: 2010-10-16 19:24+0000\n"
"PO-Revision-Date: 2010-10-17 17:16+0300\n"
"Last-Translator: Mattias Põldaru <mahfiaz gmail com>\n"
"Language-Team: Estonian <gnome-et@linux.ee>\n"
"Language: et\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Poedit-Language: Estonian\n"
"X-Poedit-Country: Estonia\n"
msgid "GNOME Shell"
msgstr "GNOME Kest"
msgstr "GNOME kest"
msgid "Window management and application launching"
msgstr "Aknahaldus ja rakenduste käivitamine"
msgstr "Aknahaldur ja rakenduste käivitaja"
msgid "Clock"
msgstr "Kell"
@ -36,18 +36,21 @@ msgid ""
"Allows access to internal debugging and monitoring tools using the Alt-F2 "
"dialog."
msgstr ""
"Lubab ligipääsu sisemistele silumise ja monitoorimise tööriistadele Alt-F2 "
"dialoogi kaudu."
msgid "Custom format of the clock"
msgstr "Kella kohandatud vorming"
msgstr "Kellaaaja kohandatud vorming"
msgid "Enable internal tools useful for developers and testers from Alt-F2"
msgstr ""
"Arendajate ja testijate jaoks sisemiste tööriistade lubamine Alt-F2 alt"
msgid "File extension used for storing the screencast"
msgstr ""
msgstr "Faililaiend, mida kasutatakse ekraanivideo salvestamisel"
msgid "Framerate used for recording screencasts."
msgstr ""
msgstr "Ekraanivideo lindistamisel kasutatav kaadrikiirus."
msgid ""
"GNOME Shell extensions have a uuid property; this key lists extensions which "
@ -55,7 +58,7 @@ msgid ""
msgstr ""
msgid "History for command (Alt-F2) dialog"
msgstr ""
msgstr "Käsudialoogi (Alt-F2) ajalugu"
msgid "Hour format"
msgstr "Tundide vorming"
@ -64,17 +67,21 @@ msgid ""
"If true and format is either \"12-hour\" or \"24-hour\", display date in the "
"clock, in addition to time."
msgstr ""
"Kui tõene ja vorming on kas \"12-tundi\" või \"24-tundi\", kuvatakse "
"kellaaja kõrval ka kuupäeva."
msgid ""
"If true and format is either \"12-hour\" or \"24-hour\", display seconds in "
"time."
msgstr ""
"Kui tõene ja vorming on kas \"12-tundi\" või \"24-tundi\", kuvatakse "
"kellaaega koos sekunditega."
msgid "If true, display the ISO week date in the calendar."
msgstr ""
msgstr "Kui tõene, kuvatakse kalendris kuupäeva ISO nädalate järgi."
msgid "List of desktop file IDs for favorite applications"
msgstr ""
msgstr "Lemmikrakenduste töölauafailide ID-de loend"
msgid "Overview workspace view mode"
msgstr ""
@ -91,13 +98,13 @@ msgid ""
msgstr ""
msgid "Show date in clock"
msgstr "Kuupäeva näitamine koos kellaajaga"
msgstr "Kell näitab kuupäeva"
msgid "Show the week date in the calendar"
msgstr ""
msgstr "Kalendris näidatakse nädala kuupäeva"
msgid "Show time with seconds"
msgstr "Aja näitamine koos sekunditega"
msgstr "Kellaaega näidatakse sekunditega"
msgid ""
"The applications corresponding to these identifiers will be displayed in the "
@ -147,80 +154,190 @@ msgid ""
msgstr ""
msgid "Uuids of extensions to disable"
msgstr ""
msgstr "Keelatavate laienduste UUID-d"
msgid "Whether to collect stats about applications usage"
msgstr ""
msgid "Clip the crosshairs at the center"
msgstr "Niitristi keskel on auk"
msgid "Color of the crosshairs"
msgstr "Niitristi värvus"
msgid ""
"Determines the length of the vertical and horizontal lines that make up the "
"crosshairs."
msgstr ""
msgid ""
"Determines the position of the magnified mouse image within the magnified "
"view and how it reacts to system mouse movement. The values are - none: no "
"mouse tracking; - centered: the mouse image is displayed at the center of "
"the zoom region (which also represents the point under the system mouse) and "
"the magnified contents are scrolled as the system mouse moves; - "
"proportional: the position of the magnified mouse in the zoom region is "
"proportionally the same as the position of the system mouse on screen; - "
"push: when the magnified mouse intersects a boundary of the zoom region, the "
"contents are scrolled into view."
msgstr ""
msgid ""
"Determines the transparency of the crosshairs, from fully opaque to fully "
"transparent."
msgstr ""
"Määrab niitristi läbipaistvuse, alates täiesti läbipaistmatust kuni täiesti "
"läbipaistvani."
msgid ""
"Determines whether the crosshairs intersect the magnified mouse sprite, or "
"are clipped such that the ends of the horizontal and vertical lines surround "
"the mouse image."
msgstr ""
"Määrab, kas niitrist kattub suurendatud hiire pildiga või on keskelt ära "
"lõigatud nii, et jooned ümbritsevad hiirekursori pilti."
msgid "Enable lens mode"
msgstr "Läätsede režiimi lubamine"
msgid ""
"Enables/disables display of crosshairs centered on the magnified mouse "
"sprite."
msgstr "Lubab/keelab niitristi kuvamise suurendatud hiirekursori kohal."
msgid ""
"For centered mouse tracking, when the system pointer is at or near the edge "
"of the screen, the magnified contents continue to scroll such that the "
"screen edge moves into the magnified view."
msgstr ""
msgid "Length of the crosshairs"
msgstr "Niitristi pikkus"
msgid "Magnification factor"
msgstr "Suurendustegur"
msgid "Mouse Tracking Mode"
msgstr "Hiire jälitamise režiim"
msgid "Opacity of the crosshairs"
msgstr "Niitristi läbipaistvus"
msgid "Screen position"
msgstr "Ekraani asukoht"
msgid "Scroll magnified contents beyond the edges of the desktop"
msgstr "Suurendusklaas võib liikuda töölauapiiridest väljapoole"
msgid "Show or hide crosshairs"
msgstr "Niitristi kuvamine või peitmine"
msgid "Show or hide the magnifier"
msgstr "Suurendusklaasi kuvamine või peitmine"
msgid "Show or hide the magnifier and all of its zoom regions."
msgstr ""
"Suurendusklaasi ja selle kõigi suurenduspiirkondade kuvamine või peitmine."
msgid ""
"The color of the the vertical and horizontal lines that make up the "
"crosshairs."
msgstr "Niitristi püst- ja rõhtjoone värvus."
msgid ""
"The magnified view either fills the entire screen, or occupies the top-half, "
"bottom-half, left-half, or right-half of the screen."
msgstr ""
"Suurendatud vaade täidab kas kogu ekraani või täidab ülemise, alumise, "
"vasaku või parema ekraanipoole."
msgid ""
"The power of the magnification. A value of 1.0 means no magnification. A "
"value of 2.0 doubles the size."
msgstr "Suurendustegur. 1,0 tähendab originaalsuurust. 2,0 muudab kaks korda."
msgid "Thickness of the crosshairs"
msgstr "Niitristi paksus"
msgid ""
"Whether the magnified view should be centered over the location of the "
"system mouse and move with it."
msgstr ""
"Kas suurendatud vaate keskkoht peaks asetsema süsteemi hiire kohal ning "
"liikuma sellega kaasa."
msgid "Width of the vertical and horizontal lines that make up the crosshairs."
msgstr "Niitristi moodustavate püst- ja rõhtjoone laius"
msgid "Clock Format"
msgstr "Kella vorming"
msgstr "Kella formaat"
msgid "Clock Preferences"
msgstr "Kella eelistused"
msgid "Panel Display"
msgstr ""
msgstr "Paneelikuva"
msgid "Show seco_nds"
msgstr "_Sekundid on nähtaval"
msgstr "_Sekundeid näidatakse"
msgid "Show the _date"
msgstr "_Kuupäev on nähtaval"
msgstr "_Kuupäeva näidatakse"
msgid "_12 hour format"
msgstr "_12-tunnine vorming"
msgstr "_12 tunni vorming"
msgid "_24 hour format"
msgstr "_24-tunnine vorming"
msgstr "_24 tunni vorming"
#. **** Applications ****
msgid "APPLICATIONS"
msgstr "RAKENDUSED"
msgstr "Rakendused"
msgid "PREFERENCES"
msgstr "EELISTUSED"
msgstr "Eelistused"
msgid "New Window"
msgstr "Uus aken"
msgid "Remove from Favorites"
msgstr "Eemalda lemmikute hulgast"
msgstr "Eemalda lemmikutest"
msgid "Add to Favorites"
msgstr "Lisa lemmikute hulka"
msgstr "Lisa lemmikutesse"
msgid "Drag here to add favorites"
msgstr ""
msgstr "Lemmikute lisamiseks lohista need siia"
#, c-format
msgid "%s has been added to your favorites."
msgstr ""
msgstr "%s lisati lemmikutesse."
#, c-format
msgid "%s has been removed from your favorites."
msgstr ""
msgstr "%s eemaldati lemmikutest."
msgid "Find"
msgstr ""
msgstr "Otsi"
msgid "Searching..."
msgstr ""
msgstr "Otsimine..."
msgid "No matching results."
msgstr "Sobivaid vasteid ei leitud."
msgstr "Tulemused puuduvad."
#. **** Places ****
#. Translators: This is in the sense of locations for documents,
#. network locations, etc.
msgid "PLACES & DEVICES"
msgstr "ASUKOHAD JA SEADMED"
msgstr "Asukohad ja seadmed"
#. **** Documents ****
msgid "RECENT ITEMS"
msgstr "VIIMASED KIRJED"
msgstr "Hiljutised dokumendid"
msgid "No extensions installed"
msgstr "Laiendusi ei ole paigaldatud"
msgstr "Ühtegi laiendust pole paigaldatud"
msgid "Enabled"
msgstr "Lubatud"
@ -232,16 +349,16 @@ msgid "Error"
msgstr "Viga"
msgid "Out of date"
msgstr ""
msgstr "Pole värske"
msgid "View Source"
msgstr ""
msgstr "Kuva lähtekoodi"
msgid "Web Page"
msgstr "Veebileht"
msgid "Undo"
msgstr "Unusta"
msgstr "Võta tagasi"
#. TODO - _quit() doesn't really work on apps in state STARTING yet
#, c-format
@ -254,66 +371,64 @@ msgstr "Eelistused"
#. Translators: This is the time format with date used
#. in 24-hour mode.
msgid "%a %b %e, %R:%S"
msgstr "%a, %e. %b %R:%S"
msgstr "%a, %e. %b, %R:%S"
msgid "%a %b %e, %R"
msgstr "%a, %e. %b %R"
msgstr "%a, %e. %b, %R"
#. Translators: This is the time format without date used
#. in 24-hour mode.
msgid "%a %R:%S"
msgstr "%a %R:%S"
msgstr "%A %R:%S"
msgid "%a %R"
msgstr "%a %R"
msgstr "%A %R"
#. Translators: This is a time format with date used
#. for AM/PM.
msgid "%a %b %e, %l:%M:%S %p"
msgstr "%a, %e. %b %l:%M:%S %p"
msgstr "%a, %e. %b, %l:%M:%S %p"
msgid "%a %b %e, %l:%M %p"
msgstr "%a, %e. %b %l:%MS %p"
msgstr "%a, %e. %b, %l:%M %p"
#. Translators: This is a time format without date used
#. for AM/PM.
msgid "%a %l:%M:%S %p"
msgstr "%a %l:%M:%S %p"
msgstr "%A, %l:%M:%S %p"
msgid "%a %l:%M %p"
msgstr "%a %l:%M %p"
msgstr "%A, %l:%M %p"
#. Button on the left side of the panel.
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
msgid "Activities"
msgstr "Ülevaade"
msgstr "Tegevused"
#, c-format
msgid "Failed to unmount '%s'"
msgstr "Tõrge '%s' lahtihaakimisel"
msgstr "'%s' lahtihaakimine nurjus"
msgid "Retry"
msgstr "Proovi uuesti"
msgid "Connect to..."
msgstr ""
msgstr "Ühendumine..."
#. Translators: the "ON" and "OFF" strings are used in the
#. toggle switches in the status area menus, and must be SHORT.
#. If you don't have suitable short words, consider initials,
#. "0"/"1", "⚪"/"⚫", etc.
msgid "ON"
msgstr ""
msgid "OFF"
msgstr ""
#. Translators: this MUST be either "toggle-switch-us"
#. (for toggle switches containing the English words
#. "ON" and "OFF") or "toggle-switch-intl" (for toggle
#. switches containing "◯" and "|"). Other values will
#. simply result in invisible toggle switches.
msgid "toggle-switch-us"
msgstr "toggle-switch-intl"
msgid "Please enter a command:"
msgstr "Palun sisesta käsk:"
#, c-format
msgid "Execution of '%s' failed:"
msgstr ""
msgstr "'%s' käivitamine nurjus:"
msgid "Available"
msgstr "Saadaval"
@ -327,8 +442,8 @@ msgstr "Nähtamatu"
msgid "Account Information..."
msgstr "Konto andmed..."
msgid "System Preferences..."
msgstr "Süsteemi eelistused..."
msgid "System Settings..."
msgstr "Süsteemi sätted..."
msgid "Lock Screen"
msgstr "Lukusta ekraan"
@ -340,11 +455,11 @@ msgid "Log Out..."
msgstr "Logi välja..."
msgid "Shut Down..."
msgstr "Seiska..."
msgstr "Lülita välja..."
#, c-format
msgid "%s has finished starting"
msgstr "%s lõpetas käivitumise"
msgstr "%s läks käima"
#, c-format
msgid "'%s' is ready"
@ -352,13 +467,13 @@ msgstr "'%s' on valmis"
msgid ""
"Can't add a new workspace because maximum workspaces limit has been reached."
msgstr ""
msgstr "Pole võimalik uut tööala lisada, kuna tööalade piir on saavutatud."
msgid "Can't remove the first workspace."
msgstr ""
msgstr "Esimest tööala pole võimalik eemaldada."
msgid "Less than a minute ago"
msgstr "Vähem kui minut aega tagasi"
msgstr "Vähem kui minuti eest"
#, c-format
msgid "%d minute ago"
@ -369,14 +484,14 @@ msgstr[1] "%d minutit tagasi"
#, c-format
msgid "%d hour ago"
msgid_plural "%d hours ago"
msgstr[0] ""
msgstr[1] ""
msgstr[0] "%d tund tagasi"
msgstr[1] "%d tundi tagasi"
#, c-format
msgid "%d day ago"
msgid_plural "%d days ago"
msgstr[0] ""
msgstr[1] ""
msgstr[0] "%d päev tagasi"
msgstr[1] "%d päeva tagasi"
#, c-format
msgid "%d week ago"
@ -385,7 +500,7 @@ msgstr[0] "%d nädal tagasi"
msgstr[1] "%d nädalat tagasi"
msgid "Home Folder"
msgstr "Kodukataloog"
msgstr "Kodukaust"
#. Translators: this is the same string as the one found in
#. * nautilus

268
po/it.po
View File

@ -3,13 +3,14 @@
# This file is distributed under the same license as the gnome-shell package.
#
# Milo Casagrande <milo@ubuntu.com>, 2009, 2010.
# Luca Ferretti <elle.uca@infinito.it>, 2010.
msgid ""
msgstr ""
"Project-Id-Version: gnome-shell\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2010-09-02 21:30+0200\n"
"PO-Revision-Date: 2010-08-27 21:12+0200\n"
"Last-Translator: Milo Casagrande <milo@ubuntu.com>\n"
"POT-Creation-Date: 2010-10-18 10:54+0200\n"
"PO-Revision-Date: 2010-10-18 11:04+0200\n"
"Last-Translator: Luca Ferretti <elle.uca@infinito.it>\n"
"Language-Team: Italian <tp@lists.linux.it>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@ -225,6 +226,132 @@ msgid "Whether to collect stats about applications usage"
msgstr ""
"Indica se raccogliere statistiche riguardo l'utilizzo delle applicazioni"
#: ../data/org.gnome.accessibility.magnifier.gschema.xml.in.h:1
msgid "Clip the crosshairs at the center"
msgstr ""
#: ../data/org.gnome.accessibility.magnifier.gschema.xml.in.h:2
msgid "Color of the crosshairs"
msgstr ""
#: ../data/org.gnome.accessibility.magnifier.gschema.xml.in.h:3
msgid ""
"Determines the length of the vertical and horizontal lines that make up the "
"crosshairs."
msgstr ""
#: ../data/org.gnome.accessibility.magnifier.gschema.xml.in.h:4
msgid ""
"Determines the position of the magnified mouse image within the magnified "
"view and how it reacts to system mouse movement. The values are - none: no "
"mouse tracking; - centered: the mouse image is displayed at the center of "
"the zoom region (which also represents the point under the system mouse) and "
"the magnified contents are scrolled as the system mouse moves; - "
"proportional: the position of the magnified mouse in the zoom region is "
"proportionally the same as the position of the system mouse on screen; - "
"push: when the magnified mouse intersects a boundary of the zoom region, the "
"contents are scrolled into view."
msgstr ""
#: ../data/org.gnome.accessibility.magnifier.gschema.xml.in.h:5
msgid ""
"Determines the transparency of the crosshairs, from fully opaque to fully "
"transparent."
msgstr ""
#: ../data/org.gnome.accessibility.magnifier.gschema.xml.in.h:6
msgid ""
"Determines whether the crosshairs intersect the magnified mouse sprite, or "
"are clipped such that the ends of the horizontal and vertical lines surround "
"the mouse image."
msgstr ""
# (ndt) o abilitata?
#: ../data/org.gnome.accessibility.magnifier.gschema.xml.in.h:7
msgid "Enable lens mode"
msgstr ""
#: ../data/org.gnome.accessibility.magnifier.gschema.xml.in.h:8
msgid ""
"Enables/disables display of crosshairs centered on the magnified mouse "
"sprite."
msgstr ""
#: ../data/org.gnome.accessibility.magnifier.gschema.xml.in.h:9
msgid ""
"For centered mouse tracking, when the system pointer is at or near the edge "
"of the screen, the magnified contents continue to scroll such that the "
"screen edge moves into the magnified view."
msgstr ""
#: ../data/org.gnome.accessibility.magnifier.gschema.xml.in.h:10
msgid "Length of the crosshairs"
msgstr ""
#: ../data/org.gnome.accessibility.magnifier.gschema.xml.in.h:11
msgid "Magnification factor"
msgstr ""
#: ../data/org.gnome.accessibility.magnifier.gschema.xml.in.h:12
msgid "Mouse Tracking Mode"
msgstr ""
#: ../data/org.gnome.accessibility.magnifier.gschema.xml.in.h:13
msgid "Opacity of the crosshairs"
msgstr ""
#: ../data/org.gnome.accessibility.magnifier.gschema.xml.in.h:14
msgid "Screen position"
msgstr ""
#: ../data/org.gnome.accessibility.magnifier.gschema.xml.in.h:15
msgid "Scroll magnified contents beyond the edges of the desktop"
msgstr ""
#: ../data/org.gnome.accessibility.magnifier.gschema.xml.in.h:16
msgid "Show or hide crosshairs"
msgstr ""
#: ../data/org.gnome.accessibility.magnifier.gschema.xml.in.h:17
msgid "Show or hide the magnifier"
msgstr ""
#: ../data/org.gnome.accessibility.magnifier.gschema.xml.in.h:18
msgid "Show or hide the magnifier and all of its zoom regions."
msgstr ""
#: ../data/org.gnome.accessibility.magnifier.gschema.xml.in.h:19
msgid ""
"The color of the the vertical and horizontal lines that make up the "
"crosshairs."
msgstr ""
#: ../data/org.gnome.accessibility.magnifier.gschema.xml.in.h:20
msgid ""
"The magnified view either fills the entire screen, or occupies the top-half, "
"bottom-half, left-half, or right-half of the screen."
msgstr ""
#: ../data/org.gnome.accessibility.magnifier.gschema.xml.in.h:21
msgid ""
"The power of the magnification. A value of 1.0 means no magnification. A "
"value of 2.0 doubles the size."
msgstr ""
#: ../data/org.gnome.accessibility.magnifier.gschema.xml.in.h:22
msgid "Thickness of the crosshairs"
msgstr ""
#: ../data/org.gnome.accessibility.magnifier.gschema.xml.in.h:23
msgid ""
"Whether the magnified view should be centered over the location of the "
"system mouse and move with it."
msgstr ""
#: ../data/org.gnome.accessibility.magnifier.gschema.xml.in.h:24
msgid "Width of the vertical and horizontal lines that make up the crosshairs."
msgstr ""
#: ../data/clock-preferences.ui.h:1
msgid "Clock Format"
msgstr "Formato ora"
@ -254,27 +381,27 @@ msgid "_24 hour format"
msgstr "Formato _24 ore"
#. **** Applications ****
#: ../js/ui/appDisplay.js:384 ../js/ui/dash.js:778
#: ../js/ui/appDisplay.js:316 ../js/ui/dash.js:778
msgid "APPLICATIONS"
msgstr "Applicazioni"
#: ../js/ui/appDisplay.js:416
#: ../js/ui/appDisplay.js:348
msgid "PREFERENCES"
msgstr "Preferenze"
#: ../js/ui/appDisplay.js:721
#: ../js/ui/appDisplay.js:648
msgid "New Window"
msgstr "Nuova finestra"
#: ../js/ui/appDisplay.js:725
#: ../js/ui/appDisplay.js:652
msgid "Remove from Favorites"
msgstr "Rimuovi dai preferiti"
#: ../js/ui/appDisplay.js:726
#: ../js/ui/appDisplay.js:653
msgid "Add to Favorites"
msgstr "Aggiungi ai preferiti"
#: ../js/ui/appDisplay.js:1033
#: ../js/ui/appDisplay.js:830
msgid "Drag here to add favorites"
msgstr "Trascinare qui per aggiungere ai preferiti"
@ -349,59 +476,59 @@ msgid "Undo"
msgstr "Annulla"
#. TODO - _quit() doesn't really work on apps in state STARTING yet
#: ../js/ui/panel.js:473
#: ../js/ui/panel.js:468
#, c-format
msgid "Quit %s"
msgstr "Chiudi %s"
#: ../js/ui/panel.js:498
#: ../js/ui/panel.js:493
msgid "Preferences"
msgstr "Preferenze"
#. Translators: This is the time format with date used
#. in 24-hour mode.
#: ../js/ui/panel.js:584
#: ../js/ui/panel.js:579
msgid "%a %b %e, %R:%S"
msgstr "%a %e %b, %k.%M.%S"
# (ndt) proviamo col k, se non funge, sappiamo il perché...
#: ../js/ui/panel.js:585
#: ../js/ui/panel.js:580
msgid "%a %b %e, %R"
msgstr "%a %e %b, %k.%M"
#. Translators: This is the time format without date used
#. in 24-hour mode.
#: ../js/ui/panel.js:589
#: ../js/ui/panel.js:584
msgid "%a %R:%S"
msgstr "%a %k.%M.%S"
#: ../js/ui/panel.js:590
#: ../js/ui/panel.js:585
msgid "%a %R"
msgstr "%a %k.%M"
#. Translators: This is a time format with date used
#. for AM/PM.
#: ../js/ui/panel.js:597
#: ../js/ui/panel.js:592
msgid "%a %b %e, %l:%M:%S %p"
msgstr "%a %e %b, %l.%M.%S %P"
#: ../js/ui/panel.js:598
#: ../js/ui/panel.js:593
msgid "%a %b %e, %l:%M %p"
msgstr "%a %e %b, %l.%M %P"
#. Translators: This is a time format without date used
#. for AM/PM.
#: ../js/ui/panel.js:602
#: ../js/ui/panel.js:597
msgid "%a %l:%M:%S %p"
msgstr "%a %l.%M.%S %P"
#: ../js/ui/panel.js:603
#: ../js/ui/panel.js:598
msgid "%a %l:%M %p"
msgstr "%a %l.%M %P"
#. Button on the left side of the panel.
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
#: ../js/ui/panel.js:748
#: ../js/ui/panel.js:743
msgid "Activities"
msgstr "Attività"
@ -419,17 +546,14 @@ msgstr "Riprova"
msgid "Connect to..."
msgstr "Connetti a..."
#. Translators: the "ON" and "OFF" strings are used in the
#. toggle switches in the status area menus, and must be SHORT.
#. If you don't have suitable short words, consider initials,
#. "0"/"1", "⚪"/"⚫", etc.
#: ../js/ui/popupMenu.js:30 ../js/ui/popupMenu.js:40
msgid "ON"
msgstr "On"
#: ../js/ui/popupMenu.js:31 ../js/ui/popupMenu.js:45
msgid "OFF"
msgstr "Off"
#. Translators: this MUST be either "toggle-switch-us"
#. (for toggle switches containing the English words
#. "ON" and "OFF") or "toggle-switch-intl" (for toggle
#. switches containing "◯" and "|"). Other values will
#. simply result in invisible toggle switches.
#: ../js/ui/popupMenu.js:33
msgid "toggle-switch-us"
msgstr "toggle-switch-intl"
#: ../js/ui/runDialog.js:233
msgid "Please enter a command:"
@ -440,42 +564,86 @@ msgstr "Inserire un comando:"
msgid "Execution of '%s' failed:"
msgstr "Esecuzione di «%s» non riuscita:"
#: ../js/ui/statusMenu.js:91
#: ../js/ui/statusMenu.js:97
msgid "Available"
msgstr "Disponibile"
#: ../js/ui/statusMenu.js:95
#: ../js/ui/statusMenu.js:101
msgid "Busy"
msgstr "Non disponibile"
#: ../js/ui/statusMenu.js:99
#: ../js/ui/statusMenu.js:105
msgid "Invisible"
msgstr "Invisibile"
#: ../js/ui/statusMenu.js:106
#: ../js/ui/statusMenu.js:112
msgid "Account Information..."
msgstr "Informazioni account..."
#: ../js/ui/statusMenu.js:110
msgid "System Preferences..."
msgstr "Preferenze di sistema..."
#: ../js/ui/statusMenu.js:116
msgid "System Settings..."
msgstr "Impostazioni di sistema..."
#: ../js/ui/statusMenu.js:117
#: ../js/ui/statusMenu.js:123
msgid "Lock Screen"
msgstr "Blocca schermo"
#: ../js/ui/statusMenu.js:121
#: ../js/ui/statusMenu.js:127
msgid "Switch User"
msgstr "Cambia utente"
#: ../js/ui/statusMenu.js:126
#: ../js/ui/statusMenu.js:132
msgid "Log Out..."
msgstr "Termina sessione..."
#: ../js/ui/statusMenu.js:130
#: ../js/ui/statusMenu.js:136
msgid "Shut Down..."
msgstr "Arresta..."
#: ../js/ui/status/accessibility.js:88
msgid "Screen Reader"
msgstr "Lettore schermo"
#: ../js/ui/status/accessibility.js:91
msgid "Screen Keyboard"
msgstr "Tastiera a schermo"
#: ../js/ui/status/accessibility.js:94
msgid "Visual Alerts"
msgstr "Allerte visive"
#: ../js/ui/status/accessibility.js:97
msgid "Sticky Keys"
msgstr "Permanenza tasti"
#: ../js/ui/status/accessibility.js:100
msgid "Slow Keys"
msgstr "Rallentamento tasti"
#: ../js/ui/status/accessibility.js:103
msgid "Bounce Keys"
msgstr "Pressione ravvicinata tasti"
#: ../js/ui/status/accessibility.js:106
msgid "Mouse Keys"
msgstr "Mouse da tastiera"
#: ../js/ui/status/accessibility.js:110
msgid "Universal Access Settings"
msgstr "Impostazioni accesso universale"
#: ../js/ui/status/accessibility.js:163
msgid "High Contrast"
msgstr "Contrasto elevato"
#: ../js/ui/status/accessibility.js:202
msgid "Large Text"
msgstr "Caratteri grandi"
#: ../js/ui/status/accessibility.js:223
msgid "Zoom"
msgstr "Ingrandimento"
#: ../js/ui/windowAttentionHandler.js:43
#, c-format
msgid "%s has finished starting"
@ -499,32 +667,32 @@ msgstr ""
msgid "Can't remove the first workspace."
msgstr "Impossibile rimuovere il primo spazio di lavoro."
#: ../src/shell-global.c:1105
#: ../src/shell-global.c:1196
msgid "Less than a minute ago"
msgstr "Meno di un minuto fa"
#: ../src/shell-global.c:1109
#: ../src/shell-global.c:1200
#, c-format
msgid "%d minute ago"
msgid_plural "%d minutes ago"
msgstr[0] "%d minuto fa"
msgstr[1] "%d minuti fa"
#: ../src/shell-global.c:1114
#: ../src/shell-global.c:1205
#, c-format
msgid "%d hour ago"
msgid_plural "%d hours ago"
msgstr[0] "%d ora fa"
msgstr[1] "%d ore fa"
#: ../src/shell-global.c:1119
#: ../src/shell-global.c:1210
#, c-format
msgid "%d day ago"
msgid_plural "%d days ago"
msgstr[0] "%d giorno fa"
msgstr[1] "%d giorni fa"
#: ../src/shell-global.c:1124
#: ../src/shell-global.c:1215
#, c-format
msgid "%d week ago"
msgid_plural "%d weeks ago"
@ -555,3 +723,9 @@ msgstr "Cerca"
#, c-format
msgid "%1$s: %2$s"
msgstr "%1$s: %2$s"
#~ msgid "ON"
#~ msgstr "On"
#~ msgid "OFF"
#~ msgstr "Off"

View File

@ -1,15 +1,15 @@
# Norwegian bokmål translation of gnome-shell.
# Copyright (C) 2009 THE PACKAGE'S COPYRIGHT HOLDER
# This file is distributed under the same license as the gnome-shell package.
# Kjartan Maraas <kmaraas@broadpark.no>, 2009-2010.
# Kjartan Maraas <kmaraas@gnome.org>, 2009-2010.
#
msgid ""
msgstr ""
"Project-Id-Version: gnome-shell 2.31.x\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2010-10-06 16:05+0200\n"
"PO-Revision-Date: 2010-10-06 16:07+0200\n"
"Last-Translator: Kjartan Maraas <kmaraas@broadpark.no>\n"
"POT-Creation-Date: 2010-10-16 21:23+0200\n"
"PO-Revision-Date: 2010-10-16 21:24+0200\n"
"Last-Translator: Kjartan Maraas <kmaraas@gnome.org>\n"
"Language-Team: Norwegian bokmål <i18n-nb@lister.ping.uio.no>\n"
"Language: \n"
"MIME-Version: 1.0\n"
@ -37,9 +37,7 @@ msgstr "Tilpass klokken på panelet"
msgid ""
"Allows access to internal debugging and monitoring tools using the Alt-F2 "
"dialog."
msgstr ""
"Tillat tilgang til interne feilsøkings og overvåkingsverktøy ved å bruke Alt-"
"F2-dialogen."
msgstr "Tillat tilgang til interne feilsøkings og overvåkingsverktøy ved å bruke Alt-F2-dialogen."
#: ../data/org.gnome.shell.gschema.xml.in.h:2
msgid "Custom format of the clock"
@ -427,58 +425,58 @@ msgid "Undo"
msgstr "Angre"
#. TODO - _quit() doesn't really work on apps in state STARTING yet
#: ../js/ui/panel.js:461
#: ../js/ui/panel.js:468
#, c-format
msgid "Quit %s"
msgstr "Avslutt %s"
#: ../js/ui/panel.js:486
#: ../js/ui/panel.js:493
msgid "Preferences"
msgstr "Brukervalg"
#. Translators: This is the time format with date used
#. in 24-hour mode.
#: ../js/ui/panel.js:572
#: ../js/ui/panel.js:579
msgid "%a %b %e, %R:%S"
msgstr "%a %e %b, %R.%S"
#: ../js/ui/panel.js:573
#: ../js/ui/panel.js:580
msgid "%a %b %e, %R"
msgstr "%a %e %b, %R"
#. Translators: This is the time format without date used
#. in 24-hour mode.
#: ../js/ui/panel.js:577
#: ../js/ui/panel.js:584
msgid "%a %R:%S"
msgstr "%a %R.%S"
#: ../js/ui/panel.js:578
#: ../js/ui/panel.js:585
msgid "%a %R"
msgstr "%a %R"
#. Translators: This is a time format with date used
#. for AM/PM.
#: ../js/ui/panel.js:585
#: ../js/ui/panel.js:592
msgid "%a %b %e, %l:%M:%S %p"
msgstr "%a %e %b, %l.%M.%S %p"
#: ../js/ui/panel.js:586
#: ../js/ui/panel.js:593
msgid "%a %b %e, %l:%M %p"
msgstr "%a %e %b, %l.%M %p"
#. Translators: This is a time format without date used
#. for AM/PM.
#: ../js/ui/panel.js:590
#: ../js/ui/panel.js:597
msgid "%a %l:%M:%S %p"
msgstr "%a %l.%M.%S %p"
#: ../js/ui/panel.js:591
#: ../js/ui/panel.js:598
msgid "%a %l:%M %p"
msgstr "%a %l.%M %p"
#. Button on the left side of the panel.
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
#: ../js/ui/panel.js:736
#: ../js/ui/panel.js:743
msgid "Activities"
msgstr "Aktiviteter"
@ -513,39 +511,39 @@ msgstr "Oppgi en kommando:"
msgid "Execution of '%s' failed:"
msgstr "Kjøring av «%s» feilet:"
#: ../js/ui/statusMenu.js:91
#: ../js/ui/statusMenu.js:97
msgid "Available"
msgstr "Tilgjengelig"
#: ../js/ui/statusMenu.js:95
#: ../js/ui/statusMenu.js:101
msgid "Busy"
msgstr "Opptatt"
#: ../js/ui/statusMenu.js:99
#: ../js/ui/statusMenu.js:105
msgid "Invisible"
msgstr "Usynlig"
#: ../js/ui/statusMenu.js:106
#: ../js/ui/statusMenu.js:112
msgid "Account Information..."
msgstr "Kontoinformasjon..."
#: ../js/ui/statusMenu.js:110
#: ../js/ui/statusMenu.js:116
msgid "System Settings..."
msgstr "Innstillinger for systemet..."
#: ../js/ui/statusMenu.js:117
#: ../js/ui/statusMenu.js:123
msgid "Lock Screen"
msgstr "Lås skjerm"
#: ../js/ui/statusMenu.js:121
#: ../js/ui/statusMenu.js:127
msgid "Switch User"
msgstr "Bytt bruker"
#: ../js/ui/statusMenu.js:126
#: ../js/ui/statusMenu.js:132
msgid "Log Out..."
msgstr "Logg ut..."
#: ../js/ui/statusMenu.js:130
#: ../js/ui/statusMenu.js:136
msgid "Shut Down..."
msgstr "Avslutt..."

579
po/nl.po
View File

@ -3,14 +3,16 @@
# This file is distributed under the same license as the gnome-shell package.
#
# Sander Dijkhuis <sander.dijkhuis@gmail.com>, 2009, 2010.
# Reinout van Schouwen <reinouts@gnome.org>, 2010
msgid ""
msgstr ""
"Project-Id-Version: gnome-shell master\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2010-03-31 13:34+0200\n"
"PO-Revision-Date: 2010-04-02 22:18+0200\n"
"Last-Translator: Sander Dijkhuis <sander.dijkhuis@gmail.com>\n"
"POT-Creation-Date: 2010-10-19 23:19+0200\n"
"PO-Revision-Date: 2010-10-19 14:12+0100\n"
"Last-Translator: Reinout van Schouwen <reinouts@gnome.org>\n"
"Language-Team: Dutch <vertaling@vrijschrift.org>\n"
"Language: nl\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
@ -24,32 +26,369 @@ msgstr "Gnome Shell"
msgid "Window management and application launching"
msgstr "Vensterbeheer en toepassingen starten"
#: ../data/gnome-shell-clock-preferences.desktop.in.in.h:1
msgid "Clock"
msgstr "Klok"
#: ../data/gnome-shell-clock-preferences.desktop.in.in.h:2
msgid "Customize the panel clock"
msgstr "De paneelklok aanpassen"
#: ../data/org.gnome.shell.gschema.xml.in.h:1
msgid ""
"Allows access to internal debugging and monitoring tools using the Alt-F2 "
"dialog."
msgstr ""
"Geeft toegang tot interne debugging- en observatieprogramma's met behulp van "
"het Alt-F2-dialoogvenster."
#: ../data/org.gnome.shell.gschema.xml.in.h:2
msgid "Custom format of the clock"
msgstr "Aangepaste indeling van de klok"
#: ../data/org.gnome.shell.gschema.xml.in.h:3
msgid "Enable internal tools useful for developers and testers from Alt-F2"
msgstr ""
"Interne hulpprogramma's inschakelen die nuttig zijn voor gebruikers en "
"testers van Alt-F2"
#: ../data/org.gnome.shell.gschema.xml.in.h:4
msgid "File extension used for storing the screencast"
msgstr "Bestandsextensie voor het opslaan van de screencast"
#: ../data/org.gnome.shell.gschema.xml.in.h:5
msgid "Framerate used for recording screencasts."
msgstr "Framerate voor het opnemen van de screencasts."
#: ../data/org.gnome.shell.gschema.xml.in.h:6
msgid ""
"GNOME Shell extensions have a uuid property; this key lists extensions which "
"should not be loaded."
msgstr ""
"Gnome Shell-uitbreidingen hebben een uuid-eigenschap; deze sleutel toont "
"uitbreidingen die niet geladen mogen worden."
#: ../data/org.gnome.shell.gschema.xml.in.h:7
msgid "History for command (Alt-F2) dialog"
msgstr "Geschiedenis voor het opdracht-dialoogvenster (Alt-F2)"
#: ../data/org.gnome.shell.gschema.xml.in.h:8
msgid "Hour format"
msgstr "Uurindeling"
#: ../data/org.gnome.shell.gschema.xml.in.h:9
msgid ""
"If true and format is either \"12-hour\" or \"24-hour\", display date in the "
"clock, in addition to time."
msgstr ""
"Indien ingeschakeld en de indeling is ofwel 12-uur of 24-uur, behalve de "
"tijd ook de datum in de klok weergeven."
#: ../data/org.gnome.shell.gschema.xml.in.h:10
msgid ""
"If true and format is either \"12-hour\" or \"24-hour\", display seconds in "
"time."
msgstr ""
"Indien ingeschakeld en de indeling is ofwel 12-uur of 24-uur, seconden "
"in de klok weergeven."
#: ../data/org.gnome.shell.gschema.xml.in.h:11
msgid "If true, display the ISO week date in the calendar."
msgstr "Indien ingeschakeld worden weeknummers in de kalender getoond."
#: ../data/org.gnome.shell.gschema.xml.in.h:12
msgid "List of desktop file IDs for favorite applications"
msgstr "Lijst van desktopbestand-id's voor favoriete toepassingen"
#: ../data/org.gnome.shell.gschema.xml.in.h:13
msgid "Overview workspace view mode"
msgstr "Werkbladoverzichtsmodus"
#: ../data/org.gnome.shell.gschema.xml.in.h:14
msgid ""
"Sets the GStreamer pipeline used to encode recordings. It follows the syntax "
"used for gst-launch. The pipeline should have an unconnected sink pad where "
"the recorded video is recorded. It will normally have a unconnected source "
"pad; output from that pad will be written into the output file. However the "
"pipeline can also take care of its own output - this might be used to send "
"the output to an icecast server via shout2send or similar. When unset or set "
"to an empty value, the default pipeline will be used. This is currently "
"'videorate ! theoraenc ! oggmux' and records to Ogg Theora."
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.h:15
msgid "Show date in clock"
msgstr "Datum tonen in klok"
#: ../data/org.gnome.shell.gschema.xml.in.h:16
msgid "Show the week date in the calendar"
msgstr "Weeknummers tonen in kalender"
#: ../data/org.gnome.shell.gschema.xml.in.h:17
msgid "Show time with seconds"
msgstr "Tijd tonen inclusief seconden"
#: ../data/org.gnome.shell.gschema.xml.in.h:18
msgid ""
"The applications corresponding to these identifiers will be displayed in the "
"favorites area."
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.h:19
msgid ""
"The filename for recorded screencasts will be a unique filename based on the "
"current date, and use this extension. It should be changed when recording to "
"a different container format."
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.h:20
msgid ""
"The framerate of the resulting screencast recordered by GNOME Shell's "
"screencast recorder in frames-per-second."
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.h:21
msgid "The gstreamer pipeline used to encode the screencast"
msgstr "De gstreamer-pijplijn voor het coderen van de screencast"
#: ../data/org.gnome.shell.gschema.xml.in.h:22
msgid ""
"The selected workspace view mode in the overview. Supported values are "
"\"single\" and \"grid\"."
msgstr ""
"De geselecteerde werkbladmodus in het overzicht. Ondersteunde waarden zijn "
"single en grid."
#: ../data/org.gnome.shell.gschema.xml.in.h:23
msgid ""
"The shell normally monitors active applications in order to present the most "
"used ones (e.g. in launchers). While this data will be kept private, you may "
"want to disable this for privacy reasons. Please note that doing so won't "
"remove already saved data."
msgstr ""
#: ../data/org.gnome.shell.gschema.xml.in.h:24
msgid ""
"This key specifies the format used by the panel clock when the format key is "
"set to \"custom\". You can use conversion specifiers understood by strftime"
"() to obtain a specific format. See the strftime() manual for more "
"information."
msgstr ""
"Deze sleutel geeft aan welke weergave de paneelklok gebruikt wanneer de "
"weergavesleutel is ingsteld op custom. U kunt opmaakcodes voor de functie "
"strftime() gebruiken om een bepaalde weergave te verkrijgen. Zie de "
"handleiding van strftime() voor meer informatie."
#: ../data/org.gnome.shell.gschema.xml.in.h:25
msgid ""
"This key specifies the hour format used by the panel clock. Possible values "
"are \"12-hour\", \"24-hour\", \"unix\" and \"custom\". If set to \"unix\", "
"the clock will display time in seconds since Epoch, i.e. 1970-01-01. If set "
"to \"custom\", the clock will display time according to the format specified "
"in the custom_format key. Note that if set to either \"unix\" or \"custom\", "
"the show_date and show_seconds keys are ignored."
msgstr ""
"Deze sleutel geeft de uurindeling aan van de paneelklok. Mogelijke waarden "
"zijn 12-hour, 24-hour, unix en custom. Als ingesteld op unix geeft "
"de klok tijd weer in seconden sinds Epoch, oftewel 01-01-1970. Als ingesteld "
"op custom dan geeft de klok tijd weer aan de hand van de indeling die is "
"gespecificeerd in de sleutel custom_format. Merk op dat de sleutels "
"show_date en show_seconds worden genegeerd als de waarde staat op unix of "
"custom."
#: ../data/org.gnome.shell.gschema.xml.in.h:26
msgid "Uuids of extensions to disable"
msgstr "Uuid's van uit te schakelen uitbreidingen"
#: ../data/org.gnome.shell.gschema.xml.in.h:27
msgid "Whether to collect stats about applications usage"
msgstr "Of statistieken worden bijgehouden over toepassingsgebruik"
#: ../data/org.gnome.accessibility.magnifier.gschema.xml.in.h:1
msgid "Clip the crosshairs at the center"
msgstr ""
#: ../data/org.gnome.accessibility.magnifier.gschema.xml.in.h:2
#, fuzzy
msgid "Color of the crosshairs"
msgstr "Intersecties (kruisjes)"
#: ../data/org.gnome.accessibility.magnifier.gschema.xml.in.h:3
msgid ""
"Determines the length of the vertical and horizontal lines that make up the "
"crosshairs."
msgstr ""
#: ../data/org.gnome.accessibility.magnifier.gschema.xml.in.h:4
msgid ""
"Determines the position of the magnified mouse image within the magnified "
"view and how it reacts to system mouse movement. The values are - none: no "
"mouse tracking; - centered: the mouse image is displayed at the center of "
"the zoom region (which also represents the point under the system mouse) and "
"the magnified contents are scrolled as the system mouse moves; - "
"proportional: the position of the magnified mouse in the zoom region is "
"proportionally the same as the position of the system mouse on screen; - "
"push: when the magnified mouse intersects a boundary of the zoom region, the "
"contents are scrolled into view."
msgstr ""
#: ../data/org.gnome.accessibility.magnifier.gschema.xml.in.h:5
msgid ""
"Determines the transparency of the crosshairs, from fully opaque to fully "
"transparent."
msgstr ""
#: ../data/org.gnome.accessibility.magnifier.gschema.xml.in.h:6
msgid ""
"Determines whether the crosshairs intersect the magnified mouse sprite, or "
"are clipped such that the ends of the horizontal and vertical lines surround "
"the mouse image."
msgstr ""
#: ../data/org.gnome.accessibility.magnifier.gschema.xml.in.h:7
msgid "Enable lens mode"
msgstr "Lensmodus inschakelen"
#: ../data/org.gnome.accessibility.magnifier.gschema.xml.in.h:8
msgid ""
"Enables/disables display of crosshairs centered on the magnified mouse "
"sprite."
msgstr ""
#: ../data/org.gnome.accessibility.magnifier.gschema.xml.in.h:9
msgid ""
"For centered mouse tracking, when the system pointer is at or near the edge "
"of the screen, the magnified contents continue to scroll such that the "
"screen edge moves into the magnified view."
msgstr ""
#: ../data/org.gnome.accessibility.magnifier.gschema.xml.in.h:10
#, fuzzy
msgid "Length of the crosshairs"
msgstr "Intersecties (kruisjes)"
#: ../data/org.gnome.accessibility.magnifier.gschema.xml.in.h:11
msgid "Magnification factor"
msgstr "Vergrotingsfactor"
#: ../data/org.gnome.accessibility.magnifier.gschema.xml.in.h:12
msgid "Mouse Tracking Mode"
msgstr "Muisvolgmodus"
#: ../data/org.gnome.accessibility.magnifier.gschema.xml.in.h:13
#, fuzzy
msgid "Opacity of the crosshairs"
msgstr "Intersecties (kruisjes)"
#: ../data/org.gnome.accessibility.magnifier.gschema.xml.in.h:14
msgid "Screen position"
msgstr "Schermpositie"
#: ../data/org.gnome.accessibility.magnifier.gschema.xml.in.h:15
msgid "Scroll magnified contents beyond the edges of the desktop"
msgstr ""
#: ../data/org.gnome.accessibility.magnifier.gschema.xml.in.h:16
#, fuzzy
msgid "Show or hide crosshairs"
msgstr "De statusbalk tonen of verbergen"
#: ../data/org.gnome.accessibility.magnifier.gschema.xml.in.h:17
#, fuzzy
msgid "Show or hide the magnifier"
msgstr "De statusbalk tonen of verbergen"
#: ../data/org.gnome.accessibility.magnifier.gschema.xml.in.h:18
msgid "Show or hide the magnifier and all of its zoom regions."
msgstr ""
#: ../data/org.gnome.accessibility.magnifier.gschema.xml.in.h:19
msgid ""
"The color of the the vertical and horizontal lines that make up the "
"crosshairs."
msgstr ""
#: ../data/org.gnome.accessibility.magnifier.gschema.xml.in.h:20
msgid ""
"The magnified view either fills the entire screen, or occupies the top-half, "
"bottom-half, left-half, or right-half of the screen."
msgstr ""
#: ../data/org.gnome.accessibility.magnifier.gschema.xml.in.h:21
msgid ""
"The power of the magnification. A value of 1.0 means no magnification. A "
"value of 2.0 doubles the size."
msgstr ""
#: ../data/org.gnome.accessibility.magnifier.gschema.xml.in.h:22
#, fuzzy
msgid "Thickness of the crosshairs"
msgstr "Intersecties (kruisjes)"
#: ../data/org.gnome.accessibility.magnifier.gschema.xml.in.h:23
msgid ""
"Whether the magnified view should be centered over the location of the "
"system mouse and move with it."
msgstr ""
#: ../data/org.gnome.accessibility.magnifier.gschema.xml.in.h:24
msgid "Width of the vertical and horizontal lines that make up the crosshairs."
msgstr ""
#: ../data/clock-preferences.ui.h:1
msgid "Clock Format"
msgstr "Klokweergave"
#: ../data/clock-preferences.ui.h:2
msgid "Clock Preferences"
msgstr "Klok-voorkeuren"
#: ../data/clock-preferences.ui.h:3
msgid "Panel Display"
msgstr "Paneelweergave"
#: ../data/clock-preferences.ui.h:4
msgid "Show seco_nds"
msgstr "_Seconden tonen"
#: ../data/clock-preferences.ui.h:5
msgid "Show the _date"
msgstr "_Datum tonen"
#: ../data/clock-preferences.ui.h:6
msgid "_12 hour format"
msgstr "_12-uursklok"
#: ../data/clock-preferences.ui.h:7
msgid "_24 hour format"
msgstr "_24-uursklok"
#. **** Applications ****
#: ../js/ui/appDisplay.js:312 ../js/ui/dash.js:855
#: ../js/ui/appDisplay.js:316 ../js/ui/dash.js:778
msgid "APPLICATIONS"
msgstr "TOEPASSINGEN"
#: ../js/ui/appDisplay.js:344
#: ../js/ui/appDisplay.js:348
msgid "PREFERENCES"
msgstr "VOORKEUREN"
#: ../js/ui/appDisplay.js:734
#: ../js/ui/appDisplay.js:648
msgid "New Window"
msgstr "Nieuw venster"
#: ../js/ui/appDisplay.js:738
#: ../js/ui/appDisplay.js:652
msgid "Remove from Favorites"
msgstr "Uit favorieten verwijderen"
#: ../js/ui/appDisplay.js:739
#: ../js/ui/appDisplay.js:653
msgid "Add to Favorites"
msgstr "Aan favorieten toevoegen"
#: ../js/ui/appDisplay.js:1091
#: ../js/ui/appDisplay.js:830
msgid "Drag here to add favorites"
msgstr "Hierheen slepen om favorieten toe te voegen"
#: ../js/ui/appFavorites.js:89
#: ../js/ui/appFavorites.js:88
#, c-format
msgid "%s has been added to your favorites."
msgstr "%s is toegevoegd aan uw favorieten."
@ -59,189 +398,275 @@ msgstr "%s is toegevoegd aan uw favorieten."
msgid "%s has been removed from your favorites."
msgstr "%s is verwijderd uit uw favorieten."
#: ../js/ui/dash.js:194
#: ../js/ui/dash.js:142
msgid "Find"
msgstr "Zoeken"
#: ../js/ui/dash.js:510
#: ../js/ui/dash.js:473
msgid "Searching..."
msgstr "Zoeken…"
#: ../js/ui/dash.js:524
#: ../js/ui/dash.js:487
msgid "No matching results."
msgstr "Geen overeenkomende resultaten."
#. **** Places ****
#. Translators: This is in the sense of locations for documents,
#. network locations, etc.
#: ../js/ui/dash.js:874 ../js/ui/placeDisplay.js:543
#: ../js/ui/dash.js:797 ../js/ui/placeDisplay.js:554
msgid "PLACES & DEVICES"
msgstr "LOCATIES & APPARATEN"
#. **** Documents ****
#: ../js/ui/dash.js:881 ../js/ui/docDisplay.js:489
#: ../js/ui/dash.js:804 ../js/ui/docDisplay.js:494
msgid "RECENT ITEMS"
msgstr "RECENTE ITEMS"
#: ../js/ui/lookingGlass.js:363
#: ../js/ui/lookingGlass.js:552
msgid "No extensions installed"
msgstr "Geen uitbreidingen geïnstalleerd"
#: ../js/ui/lookingGlass.js:400
#: ../js/ui/lookingGlass.js:589
msgid "Enabled"
msgstr "Ingeschakeld"
#: ../js/ui/lookingGlass.js:402
#: ../js/ui/lookingGlass.js:591
msgid "Disabled"
msgstr "Uitgeschakeld"
#: ../js/ui/lookingGlass.js:404
#: ../js/ui/lookingGlass.js:593
msgid "Error"
msgstr "Fout"
#: ../js/ui/lookingGlass.js:406
#: ../js/ui/lookingGlass.js:595
msgid "Out of date"
msgstr "Gedateerd"
#: ../js/ui/lookingGlass.js:431
#: ../js/ui/lookingGlass.js:620
msgid "View Source"
msgstr "Broncode weergeven"
#: ../js/ui/lookingGlass.js:437
#: ../js/ui/lookingGlass.js:626
msgid "Web Page"
msgstr "Webpagina"
#: ../js/ui/overview.js:182
#: ../js/ui/overview.js:160
msgid "Undo"
msgstr "Ongedaan maken"
#. Button on the left side of the panel.
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
#: ../js/ui/panel.js:388
msgid "Activities"
msgstr "Activiteiten"
#. TODO - _quit() doesn't really work on apps in state STARTING yet
#: ../js/ui/panel.js:468
#, c-format
msgid "Quit %s"
msgstr "%s afsluiten"
#. Translators: This is the time format used in 24-hour mode.
#: ../js/ui/panel.js:619
#: ../js/ui/panel.js:493
msgid "Preferences"
msgstr "Voorkeuren"
#. Translators: This is the time format with date used
#. in 24-hour mode.
#: ../js/ui/panel.js:579
msgid "%a %b %e, %R:%S"
msgstr "%a %e %b, %R:%S"
#: ../js/ui/panel.js:580
msgid "%a %b %e, %R"
msgstr "%a %e %b, %R"
#. Translators: This is the time format without date used
#. in 24-hour mode.
#: ../js/ui/panel.js:584
msgid "%a %R:%S"
msgstr "%a %R:%S"
#: ../js/ui/panel.js:585
msgid "%a %R"
msgstr "%a %R"
#. Translators: This is a time format used for AM/PM.
#: ../js/ui/panel.js:622
msgid "%a %l:%M %p"
msgstr "%a %k:%M %p"
#. Translators: This is a time format with date used
#. for AM/PM.
#: ../js/ui/panel.js:592
msgid "%a %b %e, %l:%M:%S %p"
msgstr "%a %e %b, %l:%M:%S %p"
#: ../js/ui/placeDisplay.js:108
#: ../js/ui/panel.js:593
msgid "%a %b %e, %l:%M %p"
msgstr "%a %e %b, %l:%M %p"
#. Translators: This is a time format without date used
#. for AM/PM.
#: ../js/ui/panel.js:597
msgid "%a %l:%M:%S %p"
msgstr "%a %l:%M:%S %p"
#: ../js/ui/panel.js:598
msgid "%a %l:%M %p"
msgstr "%a %l:%M %p"
#. Button on the left side of the panel.
#. Translators: If there is no suitable word for "Activities" in your language, you can use the word for "Overview".
#: ../js/ui/panel.js:743
msgid "Activities"
msgstr "Activiteiten"
#: ../js/ui/placeDisplay.js:111
#, c-format
msgid "Failed to unmount '%s'"
msgstr "Ontkoppelen van %s mislukt"
#: ../js/ui/placeDisplay.js:111
#: ../js/ui/placeDisplay.js:114
msgid "Retry"
msgstr "Opnieuw"
#: ../js/ui/placeDisplay.js:156
#: ../js/ui/placeDisplay.js:159
msgid "Connect to..."
msgstr "Verbinding maken met…"
#: ../js/ui/runDialog.js:232
#. Translators: this MUST be either "toggle-switch-us"
#. (for toggle switches containing the English words
#. "ON" and "OFF") or "toggle-switch-intl" (for toggle
#. switches containing "◯" and "|"). Other values will
#. simply result in invisible toggle switches.
#: ../js/ui/popupMenu.js:31
msgid "toggle-switch-us"
msgstr "toggle-switch-intl"
#: ../js/ui/runDialog.js:233
msgid "Please enter a command:"
msgstr "Voer een opdracht in:"
#: ../js/ui/runDialog.js:376
#: ../js/ui/runDialog.js:378
#, c-format
msgid "Execution of '%s' failed:"
msgstr "Uitvoeren van %s mislukt:"
#: ../js/ui/statusMenu.js:107
#: ../js/ui/statusMenu.js:97
msgid "Available"
msgstr "Beschikbaar"
#: ../js/ui/statusMenu.js:112
#: ../js/ui/statusMenu.js:101
msgid "Busy"
msgstr "Bezig"
#: ../js/ui/statusMenu.js:117
#: ../js/ui/statusMenu.js:105
msgid "Invisible"
msgstr "Onzichtbaar"
#: ../js/ui/statusMenu.js:126
#: ../js/ui/statusMenu.js:112
msgid "Account Information..."
msgstr "Accountinformatie…"
#: ../js/ui/statusMenu.js:132
msgid "Sidebar"
msgstr "Zijbalk"
#: ../js/ui/statusMenu.js:116
msgid "System Settings..."
msgstr "Systeeminstellingen…"
#: ../js/ui/statusMenu.js:142
msgid "System Preferences..."
msgstr "Systeemvoorkeuren…"
#: ../js/ui/statusMenu.js:151
#: ../js/ui/statusMenu.js:123
msgid "Lock Screen"
msgstr "Scherm vergrendelen"
#: ../js/ui/statusMenu.js:156
#: ../js/ui/statusMenu.js:127
msgid "Switch User"
msgstr "Gebruiker wisselen"
#: ../js/ui/statusMenu.js:162
#: ../js/ui/statusMenu.js:132
msgid "Log Out..."
msgstr "Afmelden…"
#: ../js/ui/statusMenu.js:167
#: ../js/ui/statusMenu.js:136
msgid "Shut Down..."
msgstr "Afsluiten…"
#. Translators: This is a time format.
#: ../js/ui/widget.js:163
msgid "%H:%M"
msgstr "%H:%M"
#: ../js/ui/status/accessibility.js:88
msgid "Screen Reader"
msgstr "Schermlezer"
#: ../js/ui/widget.js:317
msgid "Applications"
msgstr "Toepassingen"
#: ../js/ui/status/accessibility.js:91
msgid "Screen Keyboard"
msgstr "Schermtoetsenbord"
#: ../js/ui/widget.js:339
msgid "Recent Documents"
msgstr "Recente documenten"
#: ../js/ui/status/accessibility.js:94
msgid "Visual Alerts"
msgstr "Visuele attenderingen"
#: ../js/ui/windowAttentionHandler.js:47
#: ../js/ui/status/accessibility.js:97
msgid "Sticky Keys"
msgstr "PlakToetsen"
#: ../js/ui/status/accessibility.js:100
msgid "Slow Keys"
msgstr "Trage Toetsen"
#: ../js/ui/status/accessibility.js:103
msgid "Bounce Keys"
msgstr "Springende toetsen"
#: ../js/ui/status/accessibility.js:106
msgid "Mouse Keys"
msgstr "MuisToetsen"
#: ../js/ui/status/accessibility.js:110
msgid "Universal Access Settings"
msgstr "Toegankelijkheidsinstellingen"
#: ../js/ui/status/accessibility.js:163
msgid "High Contrast"
msgstr "Hoog contrast"
#: ../js/ui/status/accessibility.js:202
msgid "Large Text"
msgstr "Grote tekst"
#: ../js/ui/status/accessibility.js:223
msgid "Zoom"
msgstr "Zoomen"
#: ../js/ui/windowAttentionHandler.js:43
#, c-format
msgid "%s has finished starting"
msgstr "%s is opgestart"
#: ../js/ui/windowAttentionHandler.js:49
#: ../js/ui/windowAttentionHandler.js:45
#, c-format
msgid "'%s' is ready"
msgstr "%s is klaar"
#: ../src/shell-global.c:967
#: ../js/ui/workspacesView.js:230
msgid ""
"Can't add a new workspace because maximum workspaces limit has been reached."
msgstr ""
"Kan geen nieuw werkblad toevoegen omdat maximum aantal werkbladen is bereikt."
#: ../js/ui/workspacesView.js:247
msgid "Can't remove the first workspace."
msgstr "Kan het eerste werkblad niet verwijderen"
#: ../src/shell-global.c:1196
msgid "Less than a minute ago"
msgstr "Minder dan een minuut geleden"
#: ../src/shell-global.c:971
#: ../src/shell-global.c:1200
#, c-format
msgid "%d minute ago"
msgid_plural "%d minutes ago"
msgstr[0] "%d minuut geleden"
msgstr[1] "%d minuten geleden"
#: ../src/shell-global.c:976
#: ../src/shell-global.c:1205
#, c-format
msgid "%d hour ago"
msgid_plural "%d hours ago"
msgstr[0] "%d uur geleden"
msgstr[1] "%d uur geleden"
#: ../src/shell-global.c:981
#: ../src/shell-global.c:1210
#, c-format
msgid "%d day ago"
msgid_plural "%d days ago"
msgstr[0] "%d dag geleden"
msgstr[1] "%d dagen geleden"
#: ../src/shell-global.c:986
#: ../src/shell-global.c:1215
#, c-format
msgid "%d week ago"
msgid_plural "%d weeks ago"
@ -271,3 +696,15 @@ msgstr "Zoeken"
#, c-format
msgid "%1$s: %2$s"
msgstr "%1$s: %2$s"
#~ msgid "Sidebar"
#~ msgstr "Zijbalk"
#~ msgid "%H:%M"
#~ msgstr "%H:%M"
#~ msgid "Applications"
#~ msgstr "Toepassingen"
#~ msgid "Recent Documents"
#~ msgstr "Recente documenten"

View File

@ -5,6 +5,7 @@ gdmuser_cflags = \
-DDATADIR=\""$(datadir)"\" \
-DG_DISABLE_DEPRECATED \
-DG_LOG_DOMAIN=\"GdmUser\" \
-DGDM_CACHE_DIR=\""$(localstatedir)/cache/gdm"\" \
$(GDMUSER_CFLAGS) \
$(NULL)

69
src/Makefile-gvc.am Normal file
View File

@ -0,0 +1,69 @@
noinst_LTLIBRARIES += libgvc.la
libgvc_la_CPPFLAGS = \
$(WARN_CFLAGS) \
$(GVC_CFLAGS) \
-I$(srcdir)/gvc/ \
-DWITH_INTROSPECTION \
-DG_LOG_DOMAIN="\"Gvc\""
libgvc_la_LIBADD = \
$(GVC_LIBS)
libgvc_la_LDFLAGS = -avoid-version
libgvc_la_gir_sources = \
gvc/gvc-mixer-stream.h \
gvc/gvc-mixer-stream.c \
gvc/gvc-channel-map.h \
gvc/gvc-channel-map.c \
gvc/gvc-mixer-card.c \
gvc/gvc-mixer-card.h \
gvc/gvc-mixer-sink.h \
gvc/gvc-mixer-sink.c \
gvc/gvc-mixer-source.h \
gvc/gvc-mixer-source.c \
gvc/gvc-mixer-sink-input.h \
gvc/gvc-mixer-sink-input.c \
gvc/gvc-mixer-source-output.h \
gvc/gvc-mixer-source-output.c \
gvc/gvc-mixer-event-role.h \
gvc/gvc-mixer-event-role.c \
gvc/gvc-mixer-control.h \
gvc/gvc-mixer-control.c \
gvc/gvc-pulseaudio-fake.h
libgvc_la_private_sources = \
gvc/gvc-mixer-stream-private.h \
gvc/gvc-channel-map-private.h \
gvc/gvc-mixer-card-private.h \
gvc/gvc-mixer-control-private.h \
gvc/gvc-pulseaudio-fake.h
libgvc_la_SOURCES = \
$(libgvc_la_gir_sources) \
$(libgvc_la_private_sources)
Gvc-1.0.gir: $(G_IR_SCANNER) libgvc.la Makefile
$(AM_V_GEN) $(G_IR_SCANNER) \
--namespace=Gvc \
--nsversion=1.0 \
--warn-all \
--quiet \
--libtool="$(LIBTOOL)" \
--add-include-path=$(builddir) \
--include=GObject-2.0 \
--library=libgvc.la \
--identifier-prefix=Gvc \
--symbol-prefix=gvc_ \
$(addprefix $(srcdir)/,$(libgvc_la_gir_sources)) \
$(INCLUDES) \
-I $(srcdir) \
-I $(srcdir)/gvc \
-DWITH_INTROSPECTION \
-o $@
CLEANFILES += Gvc-1.0.gir
Gvc-1.0.typelib: Gvc-1.0.gir
$(AM_V_GEN) $(G_IR_COMPILER) $< -o $@
CLEANFILES += Gvc-1.0.typelib

View File

@ -37,6 +37,7 @@ EXTRA_DIST += gnome-shell-clock-preferences.in
include Makefile-gdmuser.am
include Makefile-st.am
include Makefile-tray.am
include Makefile-gvc.am
gnome_shell_cflags = \
$(MUTTER_PLUGIN_CFLAGS) \
@ -190,11 +191,12 @@ libgnome_shell_la_LIBADD = \
$(LIBGNOMEUI_LIBS) \
libst-1.0.la \
libgdmuser-1.0.la \
libtray.la
libtray.la \
libgvc.la
libgnome_shell_la_CPPFLAGS = $(gnome_shell_cflags)
typelibdir = $(pkglibdir)
typelib_DATA = Shell-0.1.typelib St-1.0.typelib Gdm-1.0.typelib
typelib_DATA = Shell-0.1.typelib St-1.0.typelib Gdm-1.0.typelib Gvc-1.0.typelib
Shell-0.1.gir: $(mutter) $(G_IR_SCANNER) St-1.0.gir libgnome-shell.la Makefile
$(AM_V_GEN) $(G_IR_SCANNER) \

File diff suppressed because it is too large Load Diff

View File

@ -18,8 +18,8 @@
*
*/
#ifndef __GDM_USER_MANAGER_H
#define __GDM_USER_MANAGER_H
#ifndef __GDM_USER_MANAGER_H__
#define __GDM_USER_MANAGER_H__
#include <glib-object.h>
@ -35,34 +35,35 @@ G_BEGIN_DECLS
#define GDM_USER_MANAGER_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GDM_TYPE_USER_MANAGER, GdmUserManagerClass))
typedef struct GdmUserManagerPrivate GdmUserManagerPrivate;
typedef struct GdmUserManager GdmUserManager;
typedef struct GdmUserManagerClass GdmUserManagerClass;
typedef enum GdmUserManagerError GdmUserManagerError;
typedef struct
struct GdmUserManager
{
GObject parent;
GdmUserManagerPrivate *priv;
} GdmUserManager;
};
typedef struct
struct GdmUserManagerClass
{
GObjectClass parent_class;
void (* loading_users) (GdmUserManager *user_manager);
void (* users_loaded) (GdmUserManager *user_manager);
void (* user_added) (GdmUserManager *user_manager,
GdmUser *user);
void (* user_removed) (GdmUserManager *user_manager,
GdmUser *user);
void (* user_is_logged_in_changed) (GdmUserManager *user_manager,
GdmUser *user);
void (* user_login_frequency_changed) (GdmUserManager *user_manager,
void (* user_changed) (GdmUserManager *user_manager,
GdmUser *user);
} GdmUserManagerClass;
};
typedef enum
enum GdmUserManagerError
{
GDM_USER_MANAGER_ERROR_GENERAL,
GDM_USER_MANAGER_ERROR_KEY_NOT_FOUND
} GdmUserManagerError;
};
#define GDM_USER_MANAGER_ERROR gdm_user_manager_error_quark ()
@ -71,6 +72,7 @@ GType gdm_user_manager_get_type (void);
GdmUserManager * gdm_user_manager_ref_default (void);
void gdm_user_manager_queue_load (GdmUserManager *manager);
GSList * gdm_user_manager_list_users (GdmUserManager *manager);
GdmUser * gdm_user_manager_get_user (GdmUserManager *manager,
const char *username);
@ -80,6 +82,8 @@ GdmUser * gdm_user_manager_get_user_by_uid (GdmUserManager *mana
gboolean gdm_user_manager_activate_user_session (GdmUserManager *manager,
GdmUser *user);
gboolean gdm_user_manager_can_switch (GdmUserManager *manager);
gboolean gdm_user_manager_goto_login_session (GdmUserManager *manager);
G_END_DECLS

View File

@ -21,8 +21,8 @@
* Private interfaces to the GdmUser object
*/
#ifndef __GDM_USER_PRIVATE_H
#define __GDM_USER_PRIVATE_H
#ifndef __GDM_USER_PRIVATE_H_
#define __GDM_USER_PRIVATE_H_
#include <pwd.h>
@ -30,15 +30,20 @@
G_BEGIN_DECLS
void _gdm_user_update (GdmUser *user,
void _gdm_user_update_from_object_path (GdmUser *user,
const char *object_path);
void _gdm_user_update_from_pwent (GdmUser *user,
const struct passwd *pwent);
void _gdm_user_update_login_frequency (GdmUser *user,
guint64 login_frequency);
void _gdm_user_add_session (GdmUser *user,
const char *session_id);
void _gdm_user_remove_session (GdmUser *user,
const char *session_id);
void _gdm_user_icon_changed (GdmUser *user);
G_END_DECLS
#endif /* !__GDM_USER_PRIVATE_H */
#endif /* !__GDM_USER_PRIVATE__ */

File diff suppressed because it is too large Load Diff

View File

@ -22,8 +22,8 @@
* Facade object for user data, owned by GdmUserManager
*/
#ifndef __GDM_USER_H
#define __GDM_USER_H
#ifndef __GDM_USER_H__
#define __GDM_USER_H__
#include <sys/types.h>
#include <gtk/gtk.h>
@ -40,20 +40,24 @@ typedef struct _GdmUserClass GdmUserClass;
GType gdm_user_get_type (void) G_GNUC_CONST;
GdmUser *gdm_user_new_from_object_path (const char *path);
const char *gdm_user_get_object_path (GdmUser *user);
gulong gdm_user_get_uid (GdmUser *user);
G_CONST_RETURN char *gdm_user_get_user_name (GdmUser *user);
G_CONST_RETURN char *gdm_user_get_real_name (GdmUser *user);
G_CONST_RETURN char *gdm_user_get_home_directory (GdmUser *user);
G_CONST_RETURN char *gdm_user_get_shell (GdmUser *user);
const char *gdm_user_get_user_name (GdmUser *user);
const char *gdm_user_get_real_name (GdmUser *user);
guint gdm_user_get_num_sessions (GdmUser *user);
GList *gdm_user_get_sessions (GdmUser *user);
gboolean gdm_user_is_logged_in (GdmUser *user);
gulong gdm_user_get_login_frequency (GdmUser *user);
const char *gdm_user_get_icon_file (GdmUser *user);
const char *gdm_user_get_primary_session_id (GdmUser *user);
GdkPixbuf *gdm_user_render_icon (GdmUser *user,
gint icon_size);
gint gdm_user_collate (GdmUser *user1,
GdmUser *user2);
gboolean gdm_user_is_loaded (GdmUser *user);
G_END_DECLS

View File

@ -296,6 +296,15 @@ add_statistics (GnomeShellPlugin *shell_plugin)
NULL, NULL);
}
static void
gvc_muted_debug_log_handler (const char *log_domain,
GLogLevelFlags log_level,
const char *message,
gpointer data)
{
/* Intentionally empty to discard message */
}
static void
gnome_shell_plugin_start (MutterPlugin *plugin)
{
@ -355,6 +364,10 @@ gnome_shell_plugin_start (MutterPlugin *plugin)
shell_plugin->gjs_context = gjs_context_new_with_search_path(search_path);
g_strfreev(search_path);
/* Disable the gnome-volume-control debug */
g_log_set_handler ("Gvc", G_LOG_LEVEL_DEBUG,
gvc_muted_debug_log_handler, NULL);
/* Initialize the global object here. */
global = shell_global_get ();

View File

@ -0,0 +1,39 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
* Copyright (C) 2008 Red Hat, Inc.
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
#ifndef __GVC_CHANNEL_MAP_PRIVATE_H
#define __GVC_CHANNEL_MAP_PRIVATE_H
#include <glib-object.h>
#include <pulse/pulseaudio.h>
G_BEGIN_DECLS
GvcChannelMap * gvc_channel_map_new_from_pa_channel_map (const pa_channel_map *map);
const pa_channel_map * gvc_channel_map_get_pa_channel_map (const GvcChannelMap *map);
void gvc_channel_map_volume_changed (GvcChannelMap *map,
const pa_cvolume *cv,
gboolean set);
const pa_cvolume * gvc_channel_map_get_cvolume (const GvcChannelMap *map);
G_END_DECLS
#endif /* __GVC_CHANNEL_MAP_PRIVATE_H */

254
src/gvc/gvc-channel-map.c Normal file
View File

@ -0,0 +1,254 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
* Copyright (C) 2008 William Jon McCann
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <glib.h>
#include <glib/gi18n-lib.h>
#include <pulse/pulseaudio.h>
#include "gvc-channel-map.h"
#include "gvc-channel-map-private.h"
#define GVC_CHANNEL_MAP_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GVC_TYPE_CHANNEL_MAP, GvcChannelMapPrivate))
struct GvcChannelMapPrivate
{
pa_channel_map pa_map;
gboolean pa_volume_is_set;
pa_cvolume pa_volume;
gdouble extern_volume[NUM_TYPES]; /* volume, balance, fade, lfe */
gboolean can_balance;
gboolean can_fade;
};
enum {
VOLUME_CHANGED,
LAST_SIGNAL
};
static guint signals [LAST_SIGNAL] = { 0, };
static void gvc_channel_map_class_init (GvcChannelMapClass *klass);
static void gvc_channel_map_init (GvcChannelMap *channel_map);
static void gvc_channel_map_finalize (GObject *object);
G_DEFINE_TYPE (GvcChannelMap, gvc_channel_map, G_TYPE_OBJECT)
guint
gvc_channel_map_get_num_channels (const GvcChannelMap *map)
{
g_return_val_if_fail (GVC_IS_CHANNEL_MAP (map), 0);
if (!pa_channel_map_valid(&map->priv->pa_map))
return 0;
return map->priv->pa_map.channels;
}
const gdouble *
gvc_channel_map_get_volume (GvcChannelMap *map)
{
g_return_val_if_fail (GVC_IS_CHANNEL_MAP (map), NULL);
if (!pa_channel_map_valid(&map->priv->pa_map))
return NULL;
map->priv->extern_volume[VOLUME] = (gdouble) pa_cvolume_max (&map->priv->pa_volume);
if (gvc_channel_map_can_balance (map))
map->priv->extern_volume[BALANCE] = (gdouble) pa_cvolume_get_balance (&map->priv->pa_volume, &map->priv->pa_map);
else
map->priv->extern_volume[BALANCE] = 0;
if (gvc_channel_map_can_fade (map))
map->priv->extern_volume[FADE] = (gdouble) pa_cvolume_get_fade (&map->priv->pa_volume, &map->priv->pa_map);
else
map->priv->extern_volume[FADE] = 0;
if (gvc_channel_map_has_lfe (map))
map->priv->extern_volume[LFE] = (gdouble) pa_cvolume_get_position (&map->priv->pa_volume, &map->priv->pa_map, PA_CHANNEL_POSITION_LFE);
else
map->priv->extern_volume[LFE] = 0;
return map->priv->extern_volume;
}
gboolean
gvc_channel_map_can_balance (const GvcChannelMap *map)
{
g_return_val_if_fail (GVC_IS_CHANNEL_MAP (map), FALSE);
return map->priv->can_balance;
}
gboolean
gvc_channel_map_can_fade (const GvcChannelMap *map)
{
g_return_val_if_fail (GVC_IS_CHANNEL_MAP (map), FALSE);
return map->priv->can_fade;
}
const char *
gvc_channel_map_get_mapping (const GvcChannelMap *map)
{
g_return_val_if_fail (GVC_IS_CHANNEL_MAP (map), NULL);
if (!pa_channel_map_valid(&map->priv->pa_map))
return NULL;
return pa_channel_map_to_pretty_name (&map->priv->pa_map);
}
/**
* gvc_channel_map_has_position: (skip)
*
* @map:
* @position:
*
* Returns:
*/
gboolean
gvc_channel_map_has_position (const GvcChannelMap *map,
pa_channel_position_t position)
{
g_return_val_if_fail (GVC_IS_CHANNEL_MAP (map), FALSE);
return pa_channel_map_has_position (&(map->priv->pa_map), position);
}
const pa_channel_map *
gvc_channel_map_get_pa_channel_map (const GvcChannelMap *map)
{
g_return_val_if_fail (GVC_IS_CHANNEL_MAP (map), NULL);
if (!pa_channel_map_valid(&map->priv->pa_map))
return NULL;
return &map->priv->pa_map;
}
const pa_cvolume *
gvc_channel_map_get_cvolume (const GvcChannelMap *map)
{
g_return_val_if_fail (GVC_IS_CHANNEL_MAP (map), NULL);
if (!pa_channel_map_valid(&map->priv->pa_map))
return NULL;
return &map->priv->pa_volume;
}
static void
gvc_channel_map_class_init (GvcChannelMapClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->finalize = gvc_channel_map_finalize;
signals [VOLUME_CHANGED] =
g_signal_new ("volume-changed",
G_TYPE_FROM_CLASS (klass),
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (GvcChannelMapClass, volume_changed),
NULL, NULL,
g_cclosure_marshal_VOID__BOOLEAN,
G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
g_type_class_add_private (klass, sizeof (GvcChannelMapPrivate));
}
void
gvc_channel_map_volume_changed (GvcChannelMap *map,
const pa_cvolume *cv,
gboolean set)
{
g_return_if_fail (GVC_IS_CHANNEL_MAP (map));
g_return_if_fail (cv != NULL);
g_return_if_fail (pa_cvolume_compatible_with_channel_map(cv, &map->priv->pa_map));
if (pa_cvolume_equal(cv, &map->priv->pa_volume))
return;
map->priv->pa_volume = *cv;
if (map->priv->pa_volume_is_set == FALSE) {
map->priv->pa_volume_is_set = TRUE;
return;
}
g_signal_emit (map, signals[VOLUME_CHANGED], 0, set);
}
static void
gvc_channel_map_init (GvcChannelMap *map)
{
map->priv = GVC_CHANNEL_MAP_GET_PRIVATE (map);
map->priv->pa_volume_is_set = FALSE;
}
static void
gvc_channel_map_finalize (GObject *object)
{
GvcChannelMap *channel_map;
g_return_if_fail (object != NULL);
g_return_if_fail (GVC_IS_CHANNEL_MAP (object));
channel_map = GVC_CHANNEL_MAP (object);
g_return_if_fail (channel_map->priv != NULL);
G_OBJECT_CLASS (gvc_channel_map_parent_class)->finalize (object);
}
GvcChannelMap *
gvc_channel_map_new (void)
{
GObject *map;
map = g_object_new (GVC_TYPE_CHANNEL_MAP, NULL);
return GVC_CHANNEL_MAP (map);
}
static void
set_from_pa_map (GvcChannelMap *map,
const pa_channel_map *pa_map)
{
g_assert (pa_channel_map_valid(pa_map));
map->priv->can_balance = pa_channel_map_can_balance (pa_map);
map->priv->can_fade = pa_channel_map_can_fade (pa_map);
map->priv->pa_map = *pa_map;
pa_cvolume_set(&map->priv->pa_volume, pa_map->channels, PA_VOLUME_NORM);
}
GvcChannelMap *
gvc_channel_map_new_from_pa_channel_map (const pa_channel_map *pa_map)
{
GObject *map;
map = g_object_new (GVC_TYPE_CHANNEL_MAP, NULL);
set_from_pa_map (GVC_CHANNEL_MAP (map), pa_map);
return GVC_CHANNEL_MAP (map);
}

73
src/gvc/gvc-channel-map.h Normal file
View File

@ -0,0 +1,73 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
* Copyright (C) 2008 Red Hat, Inc.
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
#ifndef __GVC_CHANNEL_MAP_H
#define __GVC_CHANNEL_MAP_H
#include <glib-object.h>
#include <gvc-pulseaudio-fake.h>
G_BEGIN_DECLS
#define GVC_TYPE_CHANNEL_MAP (gvc_channel_map_get_type ())
#define GVC_CHANNEL_MAP(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GVC_TYPE_CHANNEL_MAP, GvcChannelMap))
#define GVC_CHANNEL_MAP_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GVC_TYPE_CHANNEL_MAP, GvcChannelMapClass))
#define GVC_IS_CHANNEL_MAP(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GVC_TYPE_CHANNEL_MAP))
#define GVC_IS_CHANNEL_MAP_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GVC_TYPE_CHANNEL_MAP))
#define GVC_CHANNEL_MAP_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GVC_TYPE_CHANNEL_MAP, GvcChannelMapClass))
typedef struct GvcChannelMapPrivate GvcChannelMapPrivate;
typedef struct
{
GObject parent;
GvcChannelMapPrivate *priv;
} GvcChannelMap;
typedef struct
{
GObjectClass parent_class;
void (*volume_changed) (GvcChannelMap *channel_map, gboolean set);
} GvcChannelMapClass;
enum {
VOLUME,
BALANCE,
FADE,
LFE,
NUM_TYPES
};
GType gvc_channel_map_get_type (void);
GvcChannelMap * gvc_channel_map_new (void);
guint gvc_channel_map_get_num_channels (const GvcChannelMap *map);
const gdouble * gvc_channel_map_get_volume (GvcChannelMap *map);
gboolean gvc_channel_map_can_balance (const GvcChannelMap *map);
gboolean gvc_channel_map_can_fade (const GvcChannelMap *map);
gboolean gvc_channel_map_has_position (const GvcChannelMap *map,
pa_channel_position_t position);
#define gvc_channel_map_has_lfe(x) gvc_channel_map_has_position (x, PA_CHANNEL_POSITION_LFE)
const char * gvc_channel_map_get_mapping (const GvcChannelMap *map);
G_END_DECLS
#endif /* __GVC_CHANNEL_MAP_H */

View File

@ -0,0 +1,35 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
* Copyright (C) 2008-2009 Red Hat, Inc.
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
#ifndef __GVC_MIXER_CARD_PRIVATE_H
#define __GVC_MIXER_CARD_PRIVATE_H
#include <pulse/pulseaudio.h>
#include "gvc-mixer-card.h"
G_BEGIN_DECLS
GvcMixerCard * gvc_mixer_card_new (pa_context *context,
guint index);
pa_context * gvc_mixer_card_get_pa_context (GvcMixerCard *card);
G_END_DECLS
#endif /* __GVC_MIXER_CARD_PRIVATE_H */

506
src/gvc/gvc-mixer-card.c Normal file
View File

@ -0,0 +1,506 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
* Copyright (C) 2008 William Jon McCann
* Copyright (C) 2009 Bastien Nocera
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <glib.h>
#include <glib/gi18n-lib.h>
#include <pulse/pulseaudio.h>
#include "gvc-mixer-card.h"
#include "gvc-mixer-card-private.h"
#define GVC_MIXER_CARD_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GVC_TYPE_MIXER_CARD, GvcMixerCardPrivate))
static guint32 card_serial = 1;
struct GvcMixerCardPrivate
{
pa_context *pa_context;
guint id;
guint index;
char *name;
char *icon_name;
char *profile;
char *target_profile;
char *human_profile;
GList *profiles;
pa_operation *profile_op;
};
enum
{
PROP_0,
PROP_ID,
PROP_PA_CONTEXT,
PROP_INDEX,
PROP_NAME,
PROP_ICON_NAME,
PROP_PROFILE,
PROP_HUMAN_PROFILE,
};
static void gvc_mixer_card_class_init (GvcMixerCardClass *klass);
static void gvc_mixer_card_init (GvcMixerCard *mixer_card);
static void gvc_mixer_card_finalize (GObject *object);
G_DEFINE_TYPE (GvcMixerCard, gvc_mixer_card, G_TYPE_OBJECT)
static guint32
get_next_card_serial (void)
{
guint32 serial;
serial = card_serial++;
if ((gint32)card_serial < 0) {
card_serial = 1;
}
return serial;
}
pa_context *
gvc_mixer_card_get_pa_context (GvcMixerCard *card)
{
g_return_val_if_fail (GVC_IS_MIXER_CARD (card), 0);
return card->priv->pa_context;
}
guint
gvc_mixer_card_get_index (GvcMixerCard *card)
{
g_return_val_if_fail (GVC_IS_MIXER_CARD (card), 0);
return card->priv->index;
}
guint
gvc_mixer_card_get_id (GvcMixerCard *card)
{
g_return_val_if_fail (GVC_IS_MIXER_CARD (card), 0);
return card->priv->id;
}
const char *
gvc_mixer_card_get_name (GvcMixerCard *card)
{
g_return_val_if_fail (GVC_IS_MIXER_CARD (card), NULL);
return card->priv->name;
}
gboolean
gvc_mixer_card_set_name (GvcMixerCard *card,
const char *name)
{
g_return_val_if_fail (GVC_IS_MIXER_CARD (card), FALSE);
g_free (card->priv->name);
card->priv->name = g_strdup (name);
g_object_notify (G_OBJECT (card), "name");
return TRUE;
}
const char *
gvc_mixer_card_get_icon_name (GvcMixerCard *card)
{
g_return_val_if_fail (GVC_IS_MIXER_CARD (card), NULL);
return card->priv->icon_name;
}
gboolean
gvc_mixer_card_set_icon_name (GvcMixerCard *card,
const char *icon_name)
{
g_return_val_if_fail (GVC_IS_MIXER_CARD (card), FALSE);
g_free (card->priv->icon_name);
card->priv->icon_name = g_strdup (icon_name);
g_object_notify (G_OBJECT (card), "icon-name");
return TRUE;
}
/**
* gvc_mixer_card_get_profile: (skip)
*
* @card:
*
* Returns:
*/
GvcMixerCardProfile *
gvc_mixer_card_get_profile (GvcMixerCard *card)
{
GList *l;
g_return_val_if_fail (GVC_IS_MIXER_CARD (card), NULL);
g_return_val_if_fail (card->priv->profiles != NULL, FALSE);
for (l = card->priv->profiles; l != NULL; l = l->next) {
GvcMixerCardProfile *p = l->data;
if (g_str_equal (card->priv->profile, p->profile)) {
return p;
}
}
g_assert_not_reached ();
return NULL;
}
gboolean
gvc_mixer_card_set_profile (GvcMixerCard *card,
const char *profile)
{
GList *l;
g_return_val_if_fail (GVC_IS_MIXER_CARD (card), FALSE);
g_return_val_if_fail (card->priv->profiles != NULL, FALSE);
g_free (card->priv->profile);
card->priv->profile = g_strdup (profile);
g_free (card->priv->human_profile);
card->priv->human_profile = NULL;
for (l = card->priv->profiles; l != NULL; l = l->next) {
GvcMixerCardProfile *p = l->data;
if (g_str_equal (card->priv->profile, p->profile)) {
card->priv->human_profile = g_strdup (p->human_profile);
break;
}
}
g_object_notify (G_OBJECT (card), "profile");
return TRUE;
}
static void
_pa_context_set_card_profile_by_index_cb (pa_context *context,
int success,
void *userdata)
{
GvcMixerCard *card = GVC_MIXER_CARD (userdata);
g_assert (card->priv->target_profile);
if (success > 0) {
gvc_mixer_card_set_profile (card, card->priv->target_profile);
} else {
g_debug ("Failed to switch profile on '%s' from '%s' to '%s'",
card->priv->name,
card->priv->profile,
card->priv->target_profile);
}
g_free (card->priv->target_profile);
card->priv->target_profile = NULL;
pa_operation_unref (card->priv->profile_op);
card->priv->profile_op = NULL;
}
gboolean
gvc_mixer_card_change_profile (GvcMixerCard *card,
const char *profile)
{
g_return_val_if_fail (GVC_IS_MIXER_CARD (card), FALSE);
g_return_val_if_fail (card->priv->profiles != NULL, FALSE);
/* Same profile, or already requested? */
if (g_strcmp0 (card->priv->profile, profile) == 0)
return TRUE;
if (g_strcmp0 (profile, card->priv->target_profile) == 0)
return TRUE;
if (card->priv->profile_op != NULL) {
pa_operation_cancel (card->priv->profile_op);
pa_operation_unref (card->priv->profile_op);
card->priv->profile_op = NULL;
}
if (card->priv->profile != NULL) {
g_free (card->priv->target_profile);
card->priv->target_profile = g_strdup (profile);
card->priv->profile_op = pa_context_set_card_profile_by_index (card->priv->pa_context,
card->priv->index,
card->priv->target_profile,
_pa_context_set_card_profile_by_index_cb,
card);
if (card->priv->profile_op == NULL) {
g_warning ("pa_context_set_card_profile_by_index() failed");
return FALSE;
}
} else {
g_assert (card->priv->human_profile == NULL);
card->priv->profile = g_strdup (profile);
}
return TRUE;
}
const GList *
gvc_mixer_card_get_profiles (GvcMixerCard *card)
{
g_return_val_if_fail (GVC_IS_MIXER_CARD (card), FALSE);
return card->priv->profiles;
}
static int
sort_profiles (GvcMixerCardProfile *a,
GvcMixerCardProfile *b)
{
if (a->priority == b->priority)
return 0;
if (a->priority > b->priority)
return 1;
return -1;
}
gboolean
gvc_mixer_card_set_profiles (GvcMixerCard *card,
GList *profiles)
{
g_return_val_if_fail (GVC_IS_MIXER_CARD (card), FALSE);
g_return_val_if_fail (card->priv->profiles == NULL, FALSE);
card->priv->profiles = g_list_sort (profiles, (GCompareFunc) sort_profiles);
return TRUE;
}
static void
gvc_mixer_card_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GvcMixerCard *self = GVC_MIXER_CARD (object);
switch (prop_id) {
case PROP_PA_CONTEXT:
self->priv->pa_context = g_value_get_pointer (value);
break;
case PROP_INDEX:
self->priv->index = g_value_get_ulong (value);
break;
case PROP_ID:
self->priv->id = g_value_get_ulong (value);
break;
case PROP_NAME:
gvc_mixer_card_set_name (self, g_value_get_string (value));
break;
case PROP_ICON_NAME:
gvc_mixer_card_set_icon_name (self, g_value_get_string (value));
break;
case PROP_PROFILE:
gvc_mixer_card_set_profile (self, g_value_get_string (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gvc_mixer_card_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GvcMixerCard *self = GVC_MIXER_CARD (object);
switch (prop_id) {
case PROP_PA_CONTEXT:
g_value_set_pointer (value, self->priv->pa_context);
break;
case PROP_INDEX:
g_value_set_ulong (value, self->priv->index);
break;
case PROP_ID:
g_value_set_ulong (value, self->priv->id);
break;
case PROP_NAME:
g_value_set_string (value, self->priv->name);
break;
case PROP_ICON_NAME:
g_value_set_string (value, self->priv->icon_name);
break;
case PROP_PROFILE:
g_value_set_string (value, self->priv->profile);
break;
case PROP_HUMAN_PROFILE:
g_value_set_string (value, self->priv->human_profile);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static GObject *
gvc_mixer_card_constructor (GType type,
guint n_construct_properties,
GObjectConstructParam *construct_params)
{
GObject *object;
GvcMixerCard *self;
object = G_OBJECT_CLASS (gvc_mixer_card_parent_class)->constructor (type, n_construct_properties, construct_params);
self = GVC_MIXER_CARD (object);
self->priv->id = get_next_card_serial ();
return object;
}
static void
gvc_mixer_card_class_init (GvcMixerCardClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->constructor = gvc_mixer_card_constructor;
gobject_class->finalize = gvc_mixer_card_finalize;
gobject_class->set_property = gvc_mixer_card_set_property;
gobject_class->get_property = gvc_mixer_card_get_property;
g_object_class_install_property (gobject_class,
PROP_INDEX,
g_param_spec_ulong ("index",
"Index",
"The index for this card",
0, G_MAXULONG, 0,
G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (gobject_class,
PROP_ID,
g_param_spec_ulong ("id",
"id",
"The id for this card",
0, G_MAXULONG, 0,
G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (gobject_class,
PROP_PA_CONTEXT,
g_param_spec_pointer ("pa-context",
"PulseAudio context",
"The PulseAudio context for this card",
G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (gobject_class,
PROP_NAME,
g_param_spec_string ("name",
"Name",
"Name to display for this card",
NULL,
G_PARAM_READWRITE|G_PARAM_CONSTRUCT));
g_object_class_install_property (gobject_class,
PROP_ICON_NAME,
g_param_spec_string ("icon-name",
"Icon Name",
"Name of icon to display for this card",
NULL,
G_PARAM_READWRITE|G_PARAM_CONSTRUCT));
g_object_class_install_property (gobject_class,
PROP_PROFILE,
g_param_spec_string ("profile",
"Profile",
"Name of current profile for this card",
NULL,
G_PARAM_READWRITE));
g_object_class_install_property (gobject_class,
PROP_HUMAN_PROFILE,
g_param_spec_string ("human-profile",
"Profile (Human readable)",
"Name of current profile for this card in human readable form",
NULL,
G_PARAM_READABLE));
g_type_class_add_private (klass, sizeof (GvcMixerCardPrivate));
}
static void
gvc_mixer_card_init (GvcMixerCard *card)
{
card->priv = GVC_MIXER_CARD_GET_PRIVATE (card);
}
GvcMixerCard *
gvc_mixer_card_new (pa_context *context,
guint index)
{
GObject *object;
object = g_object_new (GVC_TYPE_MIXER_CARD,
"index", index,
"pa-context", context,
NULL);
return GVC_MIXER_CARD (object);
}
static void
free_profile (GvcMixerCardProfile *p)
{
g_free (p->profile);
g_free (p->human_profile);
g_free (p->status);
g_free (p);
}
static void
gvc_mixer_card_finalize (GObject *object)
{
GvcMixerCard *mixer_card;
g_return_if_fail (object != NULL);
g_return_if_fail (GVC_IS_MIXER_CARD (object));
mixer_card = GVC_MIXER_CARD (object);
g_return_if_fail (mixer_card->priv != NULL);
g_free (mixer_card->priv->name);
mixer_card->priv->name = NULL;
g_free (mixer_card->priv->icon_name);
mixer_card->priv->icon_name = NULL;
g_free (mixer_card->priv->target_profile);
mixer_card->priv->target_profile = NULL;
g_free (mixer_card->priv->profile);
mixer_card->priv->profile = NULL;
g_free (mixer_card->priv->human_profile);
mixer_card->priv->human_profile = NULL;
g_list_foreach (mixer_card->priv->profiles, (GFunc) free_profile, NULL);
g_list_free (mixer_card->priv->profiles);
mixer_card->priv->profiles = NULL;
G_OBJECT_CLASS (gvc_mixer_card_parent_class)->finalize (object);
}

83
src/gvc/gvc-mixer-card.h Normal file
View File

@ -0,0 +1,83 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
* Copyright (C) 2008-2009 Red Hat, Inc.
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
#ifndef __GVC_MIXER_CARD_H
#define __GVC_MIXER_CARD_H
#include <glib-object.h>
G_BEGIN_DECLS
#define GVC_TYPE_MIXER_CARD (gvc_mixer_card_get_type ())
#define GVC_MIXER_CARD(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GVC_TYPE_MIXER_CARD, GvcMixerCard))
#define GVC_MIXER_CARD_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GVC_TYPE_MIXER_CARD, GvcMixerCardClass))
#define GVC_IS_MIXER_CARD(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GVC_TYPE_MIXER_CARD))
#define GVC_IS_MIXER_CARD_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GVC_TYPE_MIXER_CARD))
#define GVC_MIXER_CARD_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GVC_TYPE_MIXER_CARD, GvcMixerCardClass))
typedef struct GvcMixerCardPrivate GvcMixerCardPrivate;
typedef struct
{
GObject parent;
GvcMixerCardPrivate *priv;
} GvcMixerCard;
typedef struct
{
GObjectClass parent_class;
/* vtable */
} GvcMixerCardClass;
typedef struct
{
char *profile;
char *human_profile;
char *status;
guint priority;
guint n_sinks, n_sources;
} GvcMixerCardProfile;
GType gvc_mixer_card_get_type (void);
guint gvc_mixer_card_get_id (GvcMixerCard *card);
guint gvc_mixer_card_get_index (GvcMixerCard *card);
const char * gvc_mixer_card_get_name (GvcMixerCard *card);
const char * gvc_mixer_card_get_icon_name (GvcMixerCard *card);
GvcMixerCardProfile * gvc_mixer_card_get_profile (GvcMixerCard *card);
const GList * gvc_mixer_card_get_profiles (GvcMixerCard *card);
gboolean gvc_mixer_card_change_profile (GvcMixerCard *card,
const char *profile);
/* private */
gboolean gvc_mixer_card_set_name (GvcMixerCard *card,
const char *name);
gboolean gvc_mixer_card_set_icon_name (GvcMixerCard *card,
const char *name);
gboolean gvc_mixer_card_set_profile (GvcMixerCard *card,
const char *profile);
gboolean gvc_mixer_card_set_profiles (GvcMixerCard *card,
GList *profiles);
G_END_DECLS
#endif /* __GVC_MIXER_CARD_H */

View File

@ -0,0 +1,35 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
* Copyright (C) 2008 Red Hat, Inc.
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
#ifndef __GVC_MIXER_CONTROL_PRIVATE_H
#define __GVC_MIXER_CONTROL_PRIVATE_H
#include <glib-object.h>
#include <pulse/pulseaudio.h>
#include "gvc-mixer-stream.h"
#include "gvc-mixer-card.h"
G_BEGIN_DECLS
pa_context * gvc_mixer_control_get_pa_context (GvcMixerControl *control);
G_END_DECLS
#endif /* __GVC_MIXER_CONTROL_PRIVATE_H */

2232
src/gvc/gvc-mixer-control.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,96 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
* Copyright (C) 2008 Red Hat, Inc.
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
#ifndef __GVC_MIXER_CONTROL_H
#define __GVC_MIXER_CONTROL_H
#include <glib-object.h>
#include "gvc-mixer-stream.h"
#include "gvc-mixer-card.h"
G_BEGIN_DECLS
#define GVC_TYPE_MIXER_CONTROL (gvc_mixer_control_get_type ())
#define GVC_MIXER_CONTROL(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GVC_TYPE_MIXER_CONTROL, GvcMixerControl))
#define GVC_MIXER_CONTROL_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GVC_TYPE_MIXER_CONTROL, GvcMixerControlClass))
#define GVC_IS_MIXER_CONTROL(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GVC_TYPE_MIXER_CONTROL))
#define GVC_IS_MIXER_CONTROL_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GVC_TYPE_MIXER_CONTROL))
#define GVC_MIXER_CONTROL_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GVC_TYPE_MIXER_CONTROL, GvcMixerControlClass))
typedef struct GvcMixerControlPrivate GvcMixerControlPrivate;
typedef struct
{
GObject parent;
GvcMixerControlPrivate *priv;
} GvcMixerControl;
typedef struct
{
GObjectClass parent_class;
void (*connecting) (GvcMixerControl *control);
void (*ready) (GvcMixerControl *control);
void (*stream_added) (GvcMixerControl *control,
guint id);
void (*stream_removed) (GvcMixerControl *control,
guint id);
void (*card_added) (GvcMixerControl *control,
guint id);
void (*card_removed) (GvcMixerControl *control,
guint id);
void (*default_sink_changed) (GvcMixerControl *control,
guint id);
void (*default_source_changed) (GvcMixerControl *control,
guint id);
} GvcMixerControlClass;
GType gvc_mixer_control_get_type (void);
GvcMixerControl * gvc_mixer_control_new (const char *name);
gboolean gvc_mixer_control_open (GvcMixerControl *control);
gboolean gvc_mixer_control_close (GvcMixerControl *control);
gboolean gvc_mixer_control_is_ready (GvcMixerControl *control);
GSList * gvc_mixer_control_get_cards (GvcMixerControl *control);
GSList * gvc_mixer_control_get_streams (GvcMixerControl *control);
GSList * gvc_mixer_control_get_sinks (GvcMixerControl *control);
GSList * gvc_mixer_control_get_sources (GvcMixerControl *control);
GSList * gvc_mixer_control_get_sink_inputs (GvcMixerControl *control);
GSList * gvc_mixer_control_get_source_outputs (GvcMixerControl *control);
GvcMixerStream * gvc_mixer_control_lookup_stream_id (GvcMixerControl *control,
guint id);
GvcMixerCard * gvc_mixer_control_lookup_card_id (GvcMixerControl *control,
guint id);
GvcMixerStream * gvc_mixer_control_get_default_sink (GvcMixerControl *control);
GvcMixerStream * gvc_mixer_control_get_default_source (GvcMixerControl *control);
GvcMixerStream * gvc_mixer_control_get_event_sink_input (GvcMixerControl *control);
gboolean gvc_mixer_control_set_default_sink (GvcMixerControl *control,
GvcMixerStream *stream);
gboolean gvc_mixer_control_set_default_source (GvcMixerControl *control,
GvcMixerStream *stream);
G_END_DECLS
#endif /* __GVC_MIXER_CONTROL_H */

View File

@ -0,0 +1,250 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
* Copyright (C) 2008 William Jon McCann
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <glib.h>
#include <glib/gi18n-lib.h>
#include <pulse/pulseaudio.h>
#include <pulse/ext-stream-restore.h>
#include "gvc-mixer-event-role.h"
#include "gvc-mixer-stream-private.h"
#include "gvc-channel-map-private.h"
#define GVC_MIXER_EVENT_ROLE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GVC_TYPE_MIXER_EVENT_ROLE, GvcMixerEventRolePrivate))
struct GvcMixerEventRolePrivate
{
char *device;
};
enum
{
PROP_0,
PROP_DEVICE
};
static void gvc_mixer_event_role_class_init (GvcMixerEventRoleClass *klass);
static void gvc_mixer_event_role_init (GvcMixerEventRole *mixer_event_role);
static void gvc_mixer_event_role_finalize (GObject *object);
G_DEFINE_TYPE (GvcMixerEventRole, gvc_mixer_event_role, GVC_TYPE_MIXER_STREAM)
static gboolean
update_settings (GvcMixerEventRole *role,
gboolean is_muted,
gpointer *op)
{
pa_operation *o;
guint index;
const GvcChannelMap *map;
pa_context *context;
pa_ext_stream_restore_info info;
index = gvc_mixer_stream_get_index (GVC_MIXER_STREAM (role));
map = gvc_mixer_stream_get_channel_map (GVC_MIXER_STREAM(role));
info.volume = *gvc_channel_map_get_cvolume(map);
info.name = "sink-input-by-media-role:event";
info.channel_map = *gvc_channel_map_get_pa_channel_map(map);
info.device = role->priv->device;
info.mute = is_muted;
context = gvc_mixer_stream_get_pa_context (GVC_MIXER_STREAM (role));
o = pa_ext_stream_restore_write (context,
PA_UPDATE_REPLACE,
&info,
1,
TRUE,
NULL,
NULL);
if (o == NULL) {
g_warning ("pa_ext_stream_restore_write() failed");
return FALSE;
}
if (op != NULL)
*op = o;
return TRUE;
}
static gboolean
gvc_mixer_event_role_push_volume (GvcMixerStream *stream, gpointer *op)
{
return update_settings (GVC_MIXER_EVENT_ROLE (stream),
gvc_mixer_stream_get_is_muted (stream), op);
}
static gboolean
gvc_mixer_event_role_change_is_muted (GvcMixerStream *stream,
gboolean is_muted)
{
return update_settings (GVC_MIXER_EVENT_ROLE (stream),
is_muted, NULL);
}
static gboolean
gvc_mixer_event_role_set_device (GvcMixerEventRole *role,
const char *device)
{
g_return_val_if_fail (GVC_IS_MIXER_EVENT_ROLE (role), FALSE);
g_free (role->priv->device);
role->priv->device = g_strdup (device);
g_object_notify (G_OBJECT (role), "device");
return TRUE;
}
static void
gvc_mixer_event_role_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GvcMixerEventRole *self = GVC_MIXER_EVENT_ROLE (object);
switch (prop_id) {
case PROP_DEVICE:
gvc_mixer_event_role_set_device (self, g_value_get_string (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gvc_mixer_event_role_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GvcMixerEventRole *self = GVC_MIXER_EVENT_ROLE (object);
switch (prop_id) {
case PROP_DEVICE:
g_value_set_string (value, self->priv->device);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static GObject *
gvc_mixer_event_role_constructor (GType type,
guint n_construct_properties,
GObjectConstructParam *construct_params)
{
GObject *object;
GvcMixerEventRole *self;
object = G_OBJECT_CLASS (gvc_mixer_event_role_parent_class)->constructor (type, n_construct_properties, construct_params);
self = GVC_MIXER_EVENT_ROLE (object);
return object;
}
static void
gvc_mixer_event_role_class_init (GvcMixerEventRoleClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GvcMixerStreamClass *stream_class = GVC_MIXER_STREAM_CLASS (klass);
object_class->constructor = gvc_mixer_event_role_constructor;
object_class->finalize = gvc_mixer_event_role_finalize;
object_class->set_property = gvc_mixer_event_role_set_property;
object_class->get_property = gvc_mixer_event_role_get_property;
stream_class->push_volume = gvc_mixer_event_role_push_volume;
stream_class->change_is_muted = gvc_mixer_event_role_change_is_muted;
g_object_class_install_property (object_class,
PROP_DEVICE,
g_param_spec_string ("device",
"Device",
"Device",
NULL,
G_PARAM_READWRITE|G_PARAM_CONSTRUCT));
g_type_class_add_private (klass, sizeof (GvcMixerEventRolePrivate));
}
static void
gvc_mixer_event_role_init (GvcMixerEventRole *event_role)
{
event_role->priv = GVC_MIXER_EVENT_ROLE_GET_PRIVATE (event_role);
}
static void
gvc_mixer_event_role_finalize (GObject *object)
{
GvcMixerEventRole *mixer_event_role;
g_return_if_fail (object != NULL);
g_return_if_fail (GVC_IS_MIXER_EVENT_ROLE (object));
mixer_event_role = GVC_MIXER_EVENT_ROLE (object);
g_return_if_fail (mixer_event_role->priv != NULL);
g_free (mixer_event_role->priv->device);
G_OBJECT_CLASS (gvc_mixer_event_role_parent_class)->finalize (object);
}
/**
* gvc_mixer_event_role_new: (skip)
*
* @context:
* @index:
* @channel_map:
*
* Returns:
*/
GvcMixerStream *
gvc_mixer_event_role_new (pa_context *context,
const char *device,
GvcChannelMap *channel_map)
{
GObject *object;
object = g_object_new (GVC_TYPE_MIXER_EVENT_ROLE,
"pa-context", context,
"index", 0,
"device", device,
"channel-map", channel_map,
NULL);
return GVC_MIXER_STREAM (object);
}

View File

@ -0,0 +1,57 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
* Copyright (C) 2008 Red Hat, Inc.
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
#ifndef __GVC_MIXER_EVENT_ROLE_H
#define __GVC_MIXER_EVENT_ROLE_H
#include <glib-object.h>
#include "gvc-mixer-stream.h"
G_BEGIN_DECLS
#define GVC_TYPE_MIXER_EVENT_ROLE (gvc_mixer_event_role_get_type ())
#define GVC_MIXER_EVENT_ROLE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GVC_TYPE_MIXER_EVENT_ROLE, GvcMixerEventRole))
#define GVC_MIXER_EVENT_ROLE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GVC_TYPE_MIXER_EVENT_ROLE, GvcMixerEventRoleClass))
#define GVC_IS_MIXER_EVENT_ROLE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GVC_TYPE_MIXER_EVENT_ROLE))
#define GVC_IS_MIXER_EVENT_ROLE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GVC_TYPE_MIXER_EVENT_ROLE))
#define GVC_MIXER_EVENT_ROLE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GVC_TYPE_MIXER_EVENT_ROLE, GvcMixerEventRoleClass))
typedef struct GvcMixerEventRolePrivate GvcMixerEventRolePrivate;
typedef struct
{
GvcMixerStream parent;
GvcMixerEventRolePrivate *priv;
} GvcMixerEventRole;
typedef struct
{
GvcMixerStreamClass parent_class;
} GvcMixerEventRoleClass;
GType gvc_mixer_event_role_get_type (void);
GvcMixerStream * gvc_mixer_event_role_new (pa_context *context,
const char *device,
GvcChannelMap *channel_map);
G_END_DECLS
#endif /* __GVC_MIXER_EVENT_ROLE_H */

View File

@ -0,0 +1,199 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
* Copyright (C) 2008 William Jon McCann
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <glib.h>
#include <glib/gi18n-lib.h>
#include <pulse/pulseaudio.h>
#include "gvc-mixer-sink-input.h"
#include "gvc-mixer-stream-private.h"
#include "gvc-channel-map-private.h"
#define GVC_MIXER_SINK_INPUT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GVC_TYPE_MIXER_SINK_INPUT, GvcMixerSinkInputPrivate))
struct GvcMixerSinkInputPrivate
{
gpointer dummy;
};
static void gvc_mixer_sink_input_class_init (GvcMixerSinkInputClass *klass);
static void gvc_mixer_sink_input_init (GvcMixerSinkInput *mixer_sink_input);
static void gvc_mixer_sink_input_finalize (GObject *object);
static void gvc_mixer_sink_input_dispose (GObject *object);
G_DEFINE_TYPE (GvcMixerSinkInput, gvc_mixer_sink_input, GVC_TYPE_MIXER_STREAM)
static gboolean
gvc_mixer_sink_input_push_volume (GvcMixerStream *stream, gpointer *op)
{
pa_operation *o;
guint index;
const GvcChannelMap *map;
pa_context *context;
const pa_cvolume *cv;
guint num_channels;
index = gvc_mixer_stream_get_index (stream);
map = gvc_mixer_stream_get_channel_map (stream);
num_channels = gvc_channel_map_get_num_channels (map);
cv = gvc_channel_map_get_cvolume(map);
context = gvc_mixer_stream_get_pa_context (stream);
o = pa_context_set_sink_input_volume (context,
index,
cv,
NULL,
NULL);
if (o == NULL) {
g_warning ("pa_context_set_sink_input_volume() failed");
return FALSE;
}
*op = o;
return TRUE;
}
static gboolean
gvc_mixer_sink_input_change_is_muted (GvcMixerStream *stream,
gboolean is_muted)
{
pa_operation *o;
guint index;
pa_context *context;
index = gvc_mixer_stream_get_index (stream);
context = gvc_mixer_stream_get_pa_context (stream);
o = pa_context_set_sink_input_mute (context,
index,
is_muted,
NULL,
NULL);
if (o == NULL) {
g_warning ("pa_context_set_sink_input_mute_by_index() failed");
return FALSE;
}
pa_operation_unref(o);
return TRUE;
}
static GObject *
gvc_mixer_sink_input_constructor (GType type,
guint n_construct_properties,
GObjectConstructParam *construct_params)
{
GObject *object;
GvcMixerSinkInput *self;
object = G_OBJECT_CLASS (gvc_mixer_sink_input_parent_class)->constructor (type, n_construct_properties, construct_params);
self = GVC_MIXER_SINK_INPUT (object);
return object;
}
static void
gvc_mixer_sink_input_class_init (GvcMixerSinkInputClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GvcMixerStreamClass *stream_class = GVC_MIXER_STREAM_CLASS (klass);
object_class->constructor = gvc_mixer_sink_input_constructor;
object_class->dispose = gvc_mixer_sink_input_dispose;
object_class->finalize = gvc_mixer_sink_input_finalize;
stream_class->push_volume = gvc_mixer_sink_input_push_volume;
stream_class->change_is_muted = gvc_mixer_sink_input_change_is_muted;
g_type_class_add_private (klass, sizeof (GvcMixerSinkInputPrivate));
}
static void
gvc_mixer_sink_input_init (GvcMixerSinkInput *sink_input)
{
sink_input->priv = GVC_MIXER_SINK_INPUT_GET_PRIVATE (sink_input);
}
static void
gvc_mixer_sink_input_dispose (GObject *object)
{
GvcMixerSinkInput *mixer_sink_input;
g_return_if_fail (object != NULL);
g_return_if_fail (GVC_IS_MIXER_SINK_INPUT (object));
mixer_sink_input = GVC_MIXER_SINK_INPUT (object);
G_OBJECT_CLASS (gvc_mixer_sink_input_parent_class)->dispose (object);
}
static void
gvc_mixer_sink_input_finalize (GObject *object)
{
GvcMixerSinkInput *mixer_sink_input;
g_return_if_fail (object != NULL);
g_return_if_fail (GVC_IS_MIXER_SINK_INPUT (object));
mixer_sink_input = GVC_MIXER_SINK_INPUT (object);
g_return_if_fail (mixer_sink_input->priv != NULL);
G_OBJECT_CLASS (gvc_mixer_sink_input_parent_class)->finalize (object);
}
/**
* gvc_mixer_sink_input_new: (skip)
*
* @context:
* @index:
* @channel_map:
*
* Returns:
*/
GvcMixerStream *
gvc_mixer_sink_input_new (pa_context *context,
guint index,
GvcChannelMap *channel_map)
{
GObject *object;
object = g_object_new (GVC_TYPE_MIXER_SINK_INPUT,
"pa-context", context,
"index", index,
"channel-map", channel_map,
NULL);
return GVC_MIXER_STREAM (object);
}

View File

@ -0,0 +1,57 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
* Copyright (C) 2008 Red Hat, Inc.
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
#ifndef __GVC_MIXER_SINK_INPUT_H
#define __GVC_MIXER_SINK_INPUT_H
#include <glib-object.h>
#include "gvc-mixer-stream.h"
G_BEGIN_DECLS
#define GVC_TYPE_MIXER_SINK_INPUT (gvc_mixer_sink_input_get_type ())
#define GVC_MIXER_SINK_INPUT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GVC_TYPE_MIXER_SINK_INPUT, GvcMixerSinkInput))
#define GVC_MIXER_SINK_INPUT_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GVC_TYPE_MIXER_SINK_INPUT, GvcMixerSinkInputClass))
#define GVC_IS_MIXER_SINK_INPUT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GVC_TYPE_MIXER_SINK_INPUT))
#define GVC_IS_MIXER_SINK_INPUT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GVC_TYPE_MIXER_SINK_INPUT))
#define GVC_MIXER_SINK_INPUT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GVC_TYPE_MIXER_SINK_INPUT, GvcMixerSinkInputClass))
typedef struct GvcMixerSinkInputPrivate GvcMixerSinkInputPrivate;
typedef struct
{
GvcMixerStream parent;
GvcMixerSinkInputPrivate *priv;
} GvcMixerSinkInput;
typedef struct
{
GvcMixerStreamClass parent_class;
} GvcMixerSinkInputClass;
GType gvc_mixer_sink_input_get_type (void);
GvcMixerStream * gvc_mixer_sink_input_new (pa_context *context,
guint index,
GvcChannelMap *map);
G_END_DECLS
#endif /* __GVC_MIXER_SINK_INPUT_H */

231
src/gvc/gvc-mixer-sink.c Normal file
View File

@ -0,0 +1,231 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
* Copyright (C) 2008 William Jon McCann
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <glib.h>
#include <glib/gi18n-lib.h>
#include <pulse/pulseaudio.h>
#include "gvc-mixer-sink.h"
#include "gvc-mixer-stream-private.h"
#include "gvc-channel-map-private.h"
#define GVC_MIXER_SINK_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GVC_TYPE_MIXER_SINK, GvcMixerSinkPrivate))
struct GvcMixerSinkPrivate
{
gpointer dummy;
};
static void gvc_mixer_sink_class_init (GvcMixerSinkClass *klass);
static void gvc_mixer_sink_init (GvcMixerSink *mixer_sink);
static void gvc_mixer_sink_finalize (GObject *object);
static void gvc_mixer_sink_dispose (GObject *object);
G_DEFINE_TYPE (GvcMixerSink, gvc_mixer_sink, GVC_TYPE_MIXER_STREAM)
static gboolean
gvc_mixer_sink_push_volume (GvcMixerStream *stream, gpointer *op)
{
pa_operation *o;
guint index;
const GvcChannelMap *map;
pa_context *context;
const pa_cvolume *cv;
index = gvc_mixer_stream_get_index (stream);
map = gvc_mixer_stream_get_channel_map (stream);
/* set the volume */
cv = gvc_channel_map_get_cvolume(map);
context = gvc_mixer_stream_get_pa_context (stream);
o = pa_context_set_sink_volume_by_index (context,
index,
cv,
NULL,
NULL);
if (o == NULL) {
g_warning ("pa_context_set_sink_volume_by_index() failed: %s", pa_strerror(pa_context_errno(context)));
return FALSE;
}
*op = o;
return TRUE;
}
static gboolean
gvc_mixer_sink_change_is_muted (GvcMixerStream *stream,
gboolean is_muted)
{
pa_operation *o;
guint index;
pa_context *context;
index = gvc_mixer_stream_get_index (stream);
context = gvc_mixer_stream_get_pa_context (stream);
o = pa_context_set_sink_mute_by_index (context,
index,
is_muted,
NULL,
NULL);
if (o == NULL) {
g_warning ("pa_context_set_sink_mute_by_index() failed: %s", pa_strerror(pa_context_errno(context)));
return FALSE;
}
pa_operation_unref(o);
return TRUE;
}
static gboolean
gvc_mixer_sink_change_port (GvcMixerStream *stream,
const char *port)
{
#if PA_MICRO > 15
pa_operation *o;
guint index;
pa_context *context;
index = gvc_mixer_stream_get_index (stream);
context = gvc_mixer_stream_get_pa_context (stream);
o = pa_context_set_sink_port_by_index (context,
index,
port,
NULL,
NULL);
if (o == NULL) {
g_warning ("pa_context_set_sink_port_by_index() failed: %s", pa_strerror(pa_context_errno(context)));
return FALSE;
}
pa_operation_unref(o);
return TRUE;
#else
return FALSE;
#endif /* PA_MICRO > 15 */
}
static GObject *
gvc_mixer_sink_constructor (GType type,
guint n_construct_properties,
GObjectConstructParam *construct_params)
{
GObject *object;
GvcMixerSink *self;
object = G_OBJECT_CLASS (gvc_mixer_sink_parent_class)->constructor (type, n_construct_properties, construct_params);
self = GVC_MIXER_SINK (object);
return object;
}
static void
gvc_mixer_sink_class_init (GvcMixerSinkClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GvcMixerStreamClass *stream_class = GVC_MIXER_STREAM_CLASS (klass);
object_class->constructor = gvc_mixer_sink_constructor;
object_class->dispose = gvc_mixer_sink_dispose;
object_class->finalize = gvc_mixer_sink_finalize;
stream_class->push_volume = gvc_mixer_sink_push_volume;
stream_class->change_port = gvc_mixer_sink_change_port;
stream_class->change_is_muted = gvc_mixer_sink_change_is_muted;
g_type_class_add_private (klass, sizeof (GvcMixerSinkPrivate));
}
static void
gvc_mixer_sink_init (GvcMixerSink *sink)
{
sink->priv = GVC_MIXER_SINK_GET_PRIVATE (sink);
}
static void
gvc_mixer_sink_dispose (GObject *object)
{
GvcMixerSink *mixer_sink;
g_return_if_fail (object != NULL);
g_return_if_fail (GVC_IS_MIXER_SINK (object));
mixer_sink = GVC_MIXER_SINK (object);
G_OBJECT_CLASS (gvc_mixer_sink_parent_class)->dispose (object);
}
static void
gvc_mixer_sink_finalize (GObject *object)
{
GvcMixerSink *mixer_sink;
g_return_if_fail (object != NULL);
g_return_if_fail (GVC_IS_MIXER_SINK (object));
mixer_sink = GVC_MIXER_SINK (object);
g_return_if_fail (mixer_sink->priv != NULL);
G_OBJECT_CLASS (gvc_mixer_sink_parent_class)->finalize (object);
}
/**
* gvc_mixer_sink_new: (skip)
*
* @context:
* @index:
* @channel_map:
*
* Returns:
*/
GvcMixerStream *
gvc_mixer_sink_new (pa_context *context,
guint index,
GvcChannelMap *channel_map)
{
GObject *object;
object = g_object_new (GVC_TYPE_MIXER_SINK,
"pa-context", context,
"index", index,
"channel-map", channel_map,
NULL);
return GVC_MIXER_STREAM (object);
}

57
src/gvc/gvc-mixer-sink.h Normal file
View File

@ -0,0 +1,57 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
* Copyright (C) 2008 Red Hat, Inc.
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
#ifndef __GVC_MIXER_SINK_H
#define __GVC_MIXER_SINK_H
#include <glib-object.h>
#include "gvc-mixer-stream.h"
G_BEGIN_DECLS
#define GVC_TYPE_MIXER_SINK (gvc_mixer_sink_get_type ())
#define GVC_MIXER_SINK(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GVC_TYPE_MIXER_SINK, GvcMixerSink))
#define GVC_MIXER_SINK_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GVC_TYPE_MIXER_SINK, GvcMixerSinkClass))
#define GVC_IS_MIXER_SINK(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GVC_TYPE_MIXER_SINK))
#define GVC_IS_MIXER_SINK_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GVC_TYPE_MIXER_SINK))
#define GVC_MIXER_SINK_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GVC_TYPE_MIXER_SINK, GvcMixerSinkClass))
typedef struct GvcMixerSinkPrivate GvcMixerSinkPrivate;
typedef struct
{
GvcMixerStream parent;
GvcMixerSinkPrivate *priv;
} GvcMixerSink;
typedef struct
{
GvcMixerStreamClass parent_class;
} GvcMixerSinkClass;
GType gvc_mixer_sink_get_type (void);
GvcMixerStream * gvc_mixer_sink_new (pa_context *context,
guint index,
GvcChannelMap *map);
G_END_DECLS
#endif /* __GVC_MIXER_SINK_H */

View File

@ -0,0 +1,137 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
* Copyright (C) 2008 William Jon McCann
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <glib.h>
#include <glib/gi18n-lib.h>
#include <pulse/pulseaudio.h>
#include "gvc-mixer-source-output.h"
#define GVC_MIXER_SOURCE_OUTPUT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GVC_TYPE_MIXER_SOURCE_OUTPUT, GvcMixerSourceOutputPrivate))
struct GvcMixerSourceOutputPrivate
{
gpointer dummy;
};
static void gvc_mixer_source_output_class_init (GvcMixerSourceOutputClass *klass);
static void gvc_mixer_source_output_init (GvcMixerSourceOutput *mixer_source_output);
static void gvc_mixer_source_output_finalize (GObject *object);
G_DEFINE_TYPE (GvcMixerSourceOutput, gvc_mixer_source_output, GVC_TYPE_MIXER_STREAM)
static gboolean
gvc_mixer_source_output_push_volume (GvcMixerStream *stream, gpointer *op)
{
/* FIXME: */
*op = NULL;
return TRUE;
}
static gboolean
gvc_mixer_source_output_change_is_muted (GvcMixerStream *stream,
gboolean is_muted)
{
/* FIXME: */
return TRUE;
}
static GObject *
gvc_mixer_source_output_constructor (GType type,
guint n_construct_properties,
GObjectConstructParam *construct_params)
{
GObject *object;
GvcMixerSourceOutput *self;
object = G_OBJECT_CLASS (gvc_mixer_source_output_parent_class)->constructor (type, n_construct_properties, construct_params);
self = GVC_MIXER_SOURCE_OUTPUT (object);
return object;
}
static void
gvc_mixer_source_output_class_init (GvcMixerSourceOutputClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GvcMixerStreamClass *stream_class = GVC_MIXER_STREAM_CLASS (klass);
object_class->constructor = gvc_mixer_source_output_constructor;
object_class->finalize = gvc_mixer_source_output_finalize;
stream_class->push_volume = gvc_mixer_source_output_push_volume;
stream_class->change_is_muted = gvc_mixer_source_output_change_is_muted;
g_type_class_add_private (klass, sizeof (GvcMixerSourceOutputPrivate));
}
static void
gvc_mixer_source_output_init (GvcMixerSourceOutput *source_output)
{
source_output->priv = GVC_MIXER_SOURCE_OUTPUT_GET_PRIVATE (source_output);
}
static void
gvc_mixer_source_output_finalize (GObject *object)
{
GvcMixerSourceOutput *mixer_source_output;
g_return_if_fail (object != NULL);
g_return_if_fail (GVC_IS_MIXER_SOURCE_OUTPUT (object));
mixer_source_output = GVC_MIXER_SOURCE_OUTPUT (object);
g_return_if_fail (mixer_source_output->priv != NULL);
G_OBJECT_CLASS (gvc_mixer_source_output_parent_class)->finalize (object);
}
/**
* gvc_mixer_source_output_new: (skip)
*
* @context:
* @index:
* @channel_map:
*
* Returns:
*/
GvcMixerStream *
gvc_mixer_source_output_new (pa_context *context,
guint index,
GvcChannelMap *channel_map)
{
GObject *object;
object = g_object_new (GVC_TYPE_MIXER_SOURCE_OUTPUT,
"pa-context", context,
"index", index,
"channel-map", channel_map,
NULL);
return GVC_MIXER_STREAM (object);
}

View File

@ -0,0 +1,57 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
* Copyright (C) 2008 Red Hat, Inc.
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
#ifndef __GVC_MIXER_SOURCE_OUTPUT_H
#define __GVC_MIXER_SOURCE_OUTPUT_H
#include <glib-object.h>
#include "gvc-mixer-stream.h"
G_BEGIN_DECLS
#define GVC_TYPE_MIXER_SOURCE_OUTPUT (gvc_mixer_source_output_get_type ())
#define GVC_MIXER_SOURCE_OUTPUT(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GVC_TYPE_MIXER_SOURCE_OUTPUT, GvcMixerSourceOutput))
#define GVC_MIXER_SOURCE_OUTPUT_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GVC_TYPE_MIXER_SOURCE_OUTPUT, GvcMixerSourceOutputClass))
#define GVC_IS_MIXER_SOURCE_OUTPUT(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GVC_TYPE_MIXER_SOURCE_OUTPUT))
#define GVC_IS_MIXER_SOURCE_OUTPUT_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GVC_TYPE_MIXER_SOURCE_OUTPUT))
#define GVC_MIXER_SOURCE_OUTPUT_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GVC_TYPE_MIXER_SOURCE_OUTPUT, GvcMixerSourceOutputClass))
typedef struct GvcMixerSourceOutputPrivate GvcMixerSourceOutputPrivate;
typedef struct
{
GvcMixerStream parent;
GvcMixerSourceOutputPrivate *priv;
} GvcMixerSourceOutput;
typedef struct
{
GvcMixerStreamClass parent_class;
} GvcMixerSourceOutputClass;
GType gvc_mixer_source_output_get_type (void);
GvcMixerStream * gvc_mixer_source_output_new (pa_context *context,
guint index,
GvcChannelMap *map);
G_END_DECLS
#endif /* __GVC_MIXER_SOURCE_OUTPUT_H */

231
src/gvc/gvc-mixer-source.c Normal file
View File

@ -0,0 +1,231 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
* Copyright (C) 2008 William Jon McCann
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <glib.h>
#include <glib/gi18n-lib.h>
#include <pulse/pulseaudio.h>
#include "gvc-mixer-source.h"
#include "gvc-mixer-stream-private.h"
#include "gvc-channel-map-private.h"
#define GVC_MIXER_SOURCE_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GVC_TYPE_MIXER_SOURCE, GvcMixerSourcePrivate))
struct GvcMixerSourcePrivate
{
gpointer dummy;
};
static void gvc_mixer_source_class_init (GvcMixerSourceClass *klass);
static void gvc_mixer_source_init (GvcMixerSource *mixer_source);
static void gvc_mixer_source_finalize (GObject *object);
static void gvc_mixer_source_dispose (GObject *object);
G_DEFINE_TYPE (GvcMixerSource, gvc_mixer_source, GVC_TYPE_MIXER_STREAM)
static gboolean
gvc_mixer_source_push_volume (GvcMixerStream *stream, gpointer *op)
{
pa_operation *o;
guint index;
const GvcChannelMap *map;
pa_context *context;
const pa_cvolume *cv;
index = gvc_mixer_stream_get_index (stream);
map = gvc_mixer_stream_get_channel_map (stream);
/* set the volume */
cv = gvc_channel_map_get_cvolume (map);
context = gvc_mixer_stream_get_pa_context (stream);
o = pa_context_set_source_volume_by_index (context,
index,
cv,
NULL,
NULL);
if (o == NULL) {
g_warning ("pa_context_set_source_volume_by_index() failed: %s", pa_strerror(pa_context_errno(context)));
return FALSE;
}
*op = o;
return TRUE;
}
static gboolean
gvc_mixer_source_change_is_muted (GvcMixerStream *stream,
gboolean is_muted)
{
pa_operation *o;
guint index;
pa_context *context;
index = gvc_mixer_stream_get_index (stream);
context = gvc_mixer_stream_get_pa_context (stream);
o = pa_context_set_source_mute_by_index (context,
index,
is_muted,
NULL,
NULL);
if (o == NULL) {
g_warning ("pa_context_set_source_mute_by_index() failed: %s", pa_strerror(pa_context_errno(context)));
return FALSE;
}
pa_operation_unref(o);
return TRUE;
}
static gboolean
gvc_mixer_source_change_port (GvcMixerStream *stream,
const char *port)
{
#if PA_MICRO > 15
pa_operation *o;
guint index;
pa_context *context;
index = gvc_mixer_stream_get_index (stream);
context = gvc_mixer_stream_get_pa_context (stream);
o = pa_context_set_source_port_by_index (context,
index,
port,
NULL,
NULL);
if (o == NULL) {
g_warning ("pa_context_set_source_port_by_index() failed: %s", pa_strerror(pa_context_errno(context)));
return FALSE;
}
pa_operation_unref(o);
return TRUE;
#else
return FALSE;
#endif /* PA_MICRO > 15 */
}
static GObject *
gvc_mixer_source_constructor (GType type,
guint n_construct_properties,
GObjectConstructParam *construct_params)
{
GObject *object;
GvcMixerSource *self;
object = G_OBJECT_CLASS (gvc_mixer_source_parent_class)->constructor (type, n_construct_properties, construct_params);
self = GVC_MIXER_SOURCE (object);
return object;
}
static void
gvc_mixer_source_class_init (GvcMixerSourceClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GvcMixerStreamClass *stream_class = GVC_MIXER_STREAM_CLASS (klass);
object_class->constructor = gvc_mixer_source_constructor;
object_class->dispose = gvc_mixer_source_dispose;
object_class->finalize = gvc_mixer_source_finalize;
stream_class->push_volume = gvc_mixer_source_push_volume;
stream_class->change_is_muted = gvc_mixer_source_change_is_muted;
stream_class->change_port = gvc_mixer_source_change_port;
g_type_class_add_private (klass, sizeof (GvcMixerSourcePrivate));
}
static void
gvc_mixer_source_init (GvcMixerSource *source)
{
source->priv = GVC_MIXER_SOURCE_GET_PRIVATE (source);
}
static void
gvc_mixer_source_dispose (GObject *object)
{
GvcMixerSource *mixer_source;
g_return_if_fail (object != NULL);
g_return_if_fail (GVC_IS_MIXER_SOURCE (object));
mixer_source = GVC_MIXER_SOURCE (object);
G_OBJECT_CLASS (gvc_mixer_source_parent_class)->dispose (object);
}
static void
gvc_mixer_source_finalize (GObject *object)
{
GvcMixerSource *mixer_source;
g_return_if_fail (object != NULL);
g_return_if_fail (GVC_IS_MIXER_SOURCE (object));
mixer_source = GVC_MIXER_SOURCE (object);
g_return_if_fail (mixer_source->priv != NULL);
G_OBJECT_CLASS (gvc_mixer_source_parent_class)->finalize (object);
}
/**
* gvc_mixer_source_new: (skip)
*
* @context:
* @index:
* @channel_map:
*
* Returns:
*/
GvcMixerStream *
gvc_mixer_source_new (pa_context *context,
guint index,
GvcChannelMap *channel_map)
{
GObject *object;
object = g_object_new (GVC_TYPE_MIXER_SOURCE,
"pa-context", context,
"index", index,
"channel-map", channel_map,
NULL);
return GVC_MIXER_STREAM (object);
}

View File

@ -0,0 +1,57 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
* Copyright (C) 2008 Red Hat, Inc.
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
#ifndef __GVC_MIXER_SOURCE_H
#define __GVC_MIXER_SOURCE_H
#include <glib-object.h>
#include "gvc-mixer-stream.h"
G_BEGIN_DECLS
#define GVC_TYPE_MIXER_SOURCE (gvc_mixer_source_get_type ())
#define GVC_MIXER_SOURCE(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GVC_TYPE_MIXER_SOURCE, GvcMixerSource))
#define GVC_MIXER_SOURCE_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GVC_TYPE_MIXER_SOURCE, GvcMixerSourceClass))
#define GVC_IS_MIXER_SOURCE(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GVC_TYPE_MIXER_SOURCE))
#define GVC_IS_MIXER_SOURCE_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GVC_TYPE_MIXER_SOURCE))
#define GVC_MIXER_SOURCE_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GVC_TYPE_MIXER_SOURCE, GvcMixerSourceClass))
typedef struct GvcMixerSourcePrivate GvcMixerSourcePrivate;
typedef struct
{
GvcMixerStream parent;
GvcMixerSourcePrivate *priv;
} GvcMixerSource;
typedef struct
{
GvcMixerStreamClass parent_class;
} GvcMixerSourceClass;
GType gvc_mixer_source_get_type (void);
GvcMixerStream * gvc_mixer_source_new (pa_context *context,
guint index,
GvcChannelMap *map);
G_END_DECLS
#endif /* __GVC_MIXER_SOURCE_H */

View File

@ -0,0 +1,34 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
* Copyright (C) 2008 Red Hat, Inc.
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
#ifndef __GVC_MIXER_STREAM_PRIVATE_H
#define __GVC_MIXER_STREAM_PRIVATE_H
#include <glib-object.h>
#include "gvc-channel-map.h"
G_BEGIN_DECLS
pa_context * gvc_mixer_stream_get_pa_context (GvcMixerStream *stream);
G_END_DECLS
#endif /* __GVC_MIXER_STREAM_PRIVATE_H */

944
src/gvc/gvc-mixer-stream.c Normal file
View File

@ -0,0 +1,944 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
* Copyright (C) 2008 William Jon McCann
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
#include "config.h"
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <glib.h>
#include <glib/gi18n-lib.h>
#include <pulse/pulseaudio.h>
#include "gvc-mixer-stream.h"
#include "gvc-mixer-stream-private.h"
#include "gvc-channel-map-private.h"
#define GVC_MIXER_STREAM_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GVC_TYPE_MIXER_STREAM, GvcMixerStreamPrivate))
static guint32 stream_serial = 1;
struct GvcMixerStreamPrivate
{
pa_context *pa_context;
guint id;
guint index;
gint card_index;
GvcChannelMap *channel_map;
char *name;
char *description;
char *application_id;
char *icon_name;
gboolean is_muted;
gboolean can_decibel;
gboolean is_event_stream;
gboolean is_virtual;
pa_volume_t base_volume;
pa_operation *change_volume_op;
char *port;
char *human_port;
GList *ports;
};
enum
{
PROP_0,
PROP_ID,
PROP_PA_CONTEXT,
PROP_CHANNEL_MAP,
PROP_INDEX,
PROP_NAME,
PROP_DESCRIPTION,
PROP_APPLICATION_ID,
PROP_ICON_NAME,
PROP_VOLUME,
PROP_DECIBEL,
PROP_IS_MUTED,
PROP_CAN_DECIBEL,
PROP_IS_EVENT_STREAM,
PROP_IS_VIRTUAL,
PROP_CARD_INDEX,
PROP_PORT,
};
static void gvc_mixer_stream_class_init (GvcMixerStreamClass *klass);
static void gvc_mixer_stream_init (GvcMixerStream *mixer_stream);
static void gvc_mixer_stream_finalize (GObject *object);
G_DEFINE_ABSTRACT_TYPE (GvcMixerStream, gvc_mixer_stream, G_TYPE_OBJECT)
static guint32
get_next_stream_serial (void)
{
guint32 serial;
serial = stream_serial++;
if ((gint32)stream_serial < 0) {
stream_serial = 1;
}
return serial;
}
pa_context *
gvc_mixer_stream_get_pa_context (GvcMixerStream *stream)
{
g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), 0);
return stream->priv->pa_context;
}
guint
gvc_mixer_stream_get_index (GvcMixerStream *stream)
{
g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), 0);
return stream->priv->index;
}
guint
gvc_mixer_stream_get_id (GvcMixerStream *stream)
{
g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), 0);
return stream->priv->id;
}
const GvcChannelMap *
gvc_mixer_stream_get_channel_map (GvcMixerStream *stream)
{
g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), NULL);
return stream->priv->channel_map;
}
/**
* gvc_mixer_stream_get_volume:
*
* @stream:
*
* Returns: (type guint32) (transfer none):
*/
pa_volume_t
gvc_mixer_stream_get_volume (GvcMixerStream *stream)
{
g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), 0);
return (pa_volume_t) gvc_channel_map_get_volume(stream->priv->channel_map)[VOLUME];
}
gdouble
gvc_mixer_stream_get_decibel (GvcMixerStream *stream)
{
g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), 0);
return pa_sw_volume_to_dB(
(pa_volume_t) gvc_channel_map_get_volume(stream->priv->channel_map)[VOLUME]);
}
/**
* gvc_mixer_stream_set_volume:
*
* @stream:
* @volume: (type guint32):
*
* Returns:
*/
gboolean
gvc_mixer_stream_set_volume (GvcMixerStream *stream,
pa_volume_t volume)
{
pa_cvolume cv;
g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), FALSE);
cv = *gvc_channel_map_get_cvolume(stream->priv->channel_map);
pa_cvolume_scale(&cv, volume);
if (!pa_cvolume_equal(gvc_channel_map_get_cvolume(stream->priv->channel_map), &cv)) {
gvc_channel_map_volume_changed(stream->priv->channel_map, &cv, FALSE);
g_object_notify (G_OBJECT (stream), "volume");
return TRUE;
}
return FALSE;
}
gboolean
gvc_mixer_stream_set_decibel (GvcMixerStream *stream,
gdouble db)
{
pa_cvolume cv;
g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), FALSE);
cv = *gvc_channel_map_get_cvolume(stream->priv->channel_map);
pa_cvolume_scale(&cv, pa_sw_volume_from_dB(db));
if (!pa_cvolume_equal(gvc_channel_map_get_cvolume(stream->priv->channel_map), &cv)) {
gvc_channel_map_volume_changed(stream->priv->channel_map, &cv, FALSE);
g_object_notify (G_OBJECT (stream), "volume");
}
return TRUE;
}
gboolean
gvc_mixer_stream_get_is_muted (GvcMixerStream *stream)
{
g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), FALSE);
return stream->priv->is_muted;
}
gboolean
gvc_mixer_stream_get_can_decibel (GvcMixerStream *stream)
{
g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), FALSE);
return stream->priv->can_decibel;
}
gboolean
gvc_mixer_stream_set_is_muted (GvcMixerStream *stream,
gboolean is_muted)
{
g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), FALSE);
if (is_muted != stream->priv->is_muted) {
stream->priv->is_muted = is_muted;
g_object_notify (G_OBJECT (stream), "is-muted");
}
return TRUE;
}
gboolean
gvc_mixer_stream_set_can_decibel (GvcMixerStream *stream,
gboolean can_decibel)
{
g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), FALSE);
if (can_decibel != stream->priv->can_decibel) {
stream->priv->can_decibel = can_decibel;
g_object_notify (G_OBJECT (stream), "can-decibel");
}
return TRUE;
}
const char *
gvc_mixer_stream_get_name (GvcMixerStream *stream)
{
g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), NULL);
return stream->priv->name;
}
const char *
gvc_mixer_stream_get_description (GvcMixerStream *stream)
{
g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), NULL);
return stream->priv->description;
}
gboolean
gvc_mixer_stream_set_name (GvcMixerStream *stream,
const char *name)
{
g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), FALSE);
g_free (stream->priv->name);
stream->priv->name = g_strdup (name);
g_object_notify (G_OBJECT (stream), "name");
return TRUE;
}
gboolean
gvc_mixer_stream_set_description (GvcMixerStream *stream,
const char *description)
{
g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), FALSE);
g_free (stream->priv->description);
stream->priv->description = g_strdup (description);
g_object_notify (G_OBJECT (stream), "description");
return TRUE;
}
gboolean
gvc_mixer_stream_is_event_stream (GvcMixerStream *stream)
{
g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), FALSE);
return stream->priv->is_event_stream;
}
gboolean
gvc_mixer_stream_set_is_event_stream (GvcMixerStream *stream,
gboolean is_event_stream)
{
g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), FALSE);
stream->priv->is_event_stream = is_event_stream;
g_object_notify (G_OBJECT (stream), "is-event-stream");
return TRUE;
}
gboolean
gvc_mixer_stream_is_virtual (GvcMixerStream *stream)
{
g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), FALSE);
return stream->priv->is_virtual;
}
gboolean
gvc_mixer_stream_set_is_virtual (GvcMixerStream *stream,
gboolean is_virtual)
{
g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), FALSE);
stream->priv->is_virtual = is_virtual;
g_object_notify (G_OBJECT (stream), "is-virtual");
return TRUE;
}
const char *
gvc_mixer_stream_get_application_id (GvcMixerStream *stream)
{
g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), NULL);
return stream->priv->application_id;
}
gboolean
gvc_mixer_stream_set_application_id (GvcMixerStream *stream,
const char *application_id)
{
g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), FALSE);
g_free (stream->priv->application_id);
stream->priv->application_id = g_strdup (application_id);
g_object_notify (G_OBJECT (stream), "application-id");
return TRUE;
}
static void
on_channel_map_volume_changed (GvcChannelMap *channel_map,
gboolean set,
GvcMixerStream *stream)
{
if (set == TRUE)
gvc_mixer_stream_push_volume (stream);
g_object_notify (G_OBJECT (stream), "volume");
}
static gboolean
gvc_mixer_stream_set_channel_map (GvcMixerStream *stream,
GvcChannelMap *channel_map)
{
g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), FALSE);
if (channel_map != NULL) {
g_object_ref (channel_map);
}
if (stream->priv->channel_map != NULL) {
g_signal_handlers_disconnect_by_func (stream->priv->channel_map,
on_channel_map_volume_changed,
stream);
g_object_unref (stream->priv->channel_map);
}
stream->priv->channel_map = channel_map;
if (stream->priv->channel_map != NULL) {
g_signal_connect (stream->priv->channel_map,
"volume-changed",
G_CALLBACK (on_channel_map_volume_changed),
stream);
g_object_notify (G_OBJECT (stream), "channel-map");
}
return TRUE;
}
const char *
gvc_mixer_stream_get_icon_name (GvcMixerStream *stream)
{
g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), NULL);
return stream->priv->icon_name;
}
gboolean
gvc_mixer_stream_set_icon_name (GvcMixerStream *stream,
const char *icon_name)
{
g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), FALSE);
g_free (stream->priv->icon_name);
stream->priv->icon_name = g_strdup (icon_name);
g_object_notify (G_OBJECT (stream), "icon-name");
return TRUE;
}
/**
* gvc_mixer_stream_get_base_volume:
*
* @stream:
*
* Returns: (type guint32) (transfer none):
*/
pa_volume_t
gvc_mixer_stream_get_base_volume (GvcMixerStream *stream)
{
g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), 0);
return stream->priv->base_volume;
}
/**
* gvc_mixer_stream_set_base_volume:
*
* @stream:
* @base_volume: (type guint32):
*
* Returns:
*/
gboolean
gvc_mixer_stream_set_base_volume (GvcMixerStream *stream,
pa_volume_t base_volume)
{
g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), FALSE);
stream->priv->base_volume = base_volume;
return TRUE;
}
const GvcMixerStreamPort *
gvc_mixer_stream_get_port (GvcMixerStream *stream)
{
GList *l;
g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), NULL);
g_return_val_if_fail (stream->priv->ports != NULL, NULL);
for (l = stream->priv->ports; l != NULL; l = l->next) {
GvcMixerStreamPort *p = l->data;
if (g_strcmp0 (stream->priv->port, p->port) == 0) {
return p;
}
}
g_assert_not_reached ();
return NULL;
}
gboolean
gvc_mixer_stream_set_port (GvcMixerStream *stream,
const char *port)
{
GList *l;
g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), FALSE);
g_return_val_if_fail (stream->priv->ports != NULL, FALSE);
g_free (stream->priv->port);
stream->priv->port = g_strdup (port);
g_free (stream->priv->human_port);
stream->priv->human_port = NULL;
for (l = stream->priv->ports; l != NULL; l = l->next) {
GvcMixerStreamPort *p = l->data;
if (g_str_equal (stream->priv->port, p->port)) {
stream->priv->human_port = g_strdup (p->human_port);
break;
}
}
g_object_notify (G_OBJECT (stream), "port");
return TRUE;
}
gboolean
gvc_mixer_stream_change_port (GvcMixerStream *stream,
const char *port)
{
g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), FALSE);
return GVC_MIXER_STREAM_GET_CLASS (stream)->change_port (stream, port);
}
const GList *
gvc_mixer_stream_get_ports (GvcMixerStream *stream)
{
g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), FALSE);
return stream->priv->ports;
}
static int
sort_ports (GvcMixerStreamPort *a,
GvcMixerStreamPort *b)
{
if (a->priority == b->priority)
return 0;
if (a->priority > b->priority)
return 1;
return -1;
}
gboolean
gvc_mixer_stream_set_ports (GvcMixerStream *stream,
GList *ports)
{
g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), FALSE);
g_return_val_if_fail (stream->priv->ports == NULL, FALSE);
stream->priv->ports = g_list_sort (ports, (GCompareFunc) sort_ports);
return TRUE;
}
gint
gvc_mixer_stream_get_card_index (GvcMixerStream *stream)
{
g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), PA_INVALID_INDEX);
return stream->priv->card_index;
}
gboolean
gvc_mixer_stream_set_card_index (GvcMixerStream *stream,
gint card_index)
{
g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), FALSE);
stream->priv->card_index = card_index;
g_object_notify (G_OBJECT (stream), "card-index");
return TRUE;
}
static void
gvc_mixer_stream_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GvcMixerStream *self = GVC_MIXER_STREAM (object);
switch (prop_id) {
case PROP_PA_CONTEXT:
self->priv->pa_context = g_value_get_pointer (value);
break;
case PROP_INDEX:
self->priv->index = g_value_get_ulong (value);
break;
case PROP_ID:
self->priv->id = g_value_get_ulong (value);
break;
case PROP_CHANNEL_MAP:
gvc_mixer_stream_set_channel_map (self, g_value_get_object (value));
break;
case PROP_NAME:
gvc_mixer_stream_set_name (self, g_value_get_string (value));
break;
case PROP_DESCRIPTION:
gvc_mixer_stream_set_description (self, g_value_get_string (value));
break;
case PROP_APPLICATION_ID:
gvc_mixer_stream_set_application_id (self, g_value_get_string (value));
break;
case PROP_ICON_NAME:
gvc_mixer_stream_set_icon_name (self, g_value_get_string (value));
break;
case PROP_VOLUME:
gvc_mixer_stream_set_volume (self, g_value_get_ulong (value));
break;
case PROP_DECIBEL:
gvc_mixer_stream_set_decibel (self, g_value_get_double (value));
break;
case PROP_IS_MUTED:
gvc_mixer_stream_set_is_muted (self, g_value_get_boolean (value));
break;
case PROP_IS_EVENT_STREAM:
gvc_mixer_stream_set_is_event_stream (self, g_value_get_boolean (value));
break;
case PROP_IS_VIRTUAL:
gvc_mixer_stream_set_is_virtual (self, g_value_get_boolean (value));
break;
case PROP_CAN_DECIBEL:
gvc_mixer_stream_set_can_decibel (self, g_value_get_boolean (value));
break;
case PROP_PORT:
gvc_mixer_stream_set_port (self, g_value_get_string (value));
break;
case PROP_CARD_INDEX:
self->priv->card_index = g_value_get_long (value);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gvc_mixer_stream_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GvcMixerStream *self = GVC_MIXER_STREAM (object);
switch (prop_id) {
case PROP_PA_CONTEXT:
g_value_set_pointer (value, self->priv->pa_context);
break;
case PROP_INDEX:
g_value_set_ulong (value, self->priv->index);
break;
case PROP_ID:
g_value_set_ulong (value, self->priv->id);
break;
case PROP_CHANNEL_MAP:
g_value_set_object (value, self->priv->channel_map);
break;
case PROP_NAME:
g_value_set_string (value, self->priv->name);
break;
case PROP_DESCRIPTION:
g_value_set_string (value, self->priv->description);
break;
case PROP_APPLICATION_ID:
g_value_set_string (value, self->priv->application_id);
break;
case PROP_ICON_NAME:
g_value_set_string (value, self->priv->icon_name);
break;
case PROP_VOLUME:
g_value_set_ulong (value,
pa_cvolume_max(gvc_channel_map_get_cvolume(self->priv->channel_map)));
break;
case PROP_DECIBEL:
g_value_set_double (value,
pa_sw_volume_to_dB(pa_cvolume_max(gvc_channel_map_get_cvolume(self->priv->channel_map))));
break;
case PROP_IS_MUTED:
g_value_set_boolean (value, self->priv->is_muted);
break;
case PROP_IS_EVENT_STREAM:
g_value_set_boolean (value, self->priv->is_event_stream);
break;
case PROP_IS_VIRTUAL:
g_value_set_boolean (value, self->priv->is_virtual);
break;
case PROP_CAN_DECIBEL:
g_value_set_boolean (value, self->priv->can_decibel);
break;
case PROP_PORT:
g_value_set_string (value, self->priv->port);
break;
case PROP_CARD_INDEX:
g_value_set_long (value, self->priv->card_index);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static GObject *
gvc_mixer_stream_constructor (GType type,
guint n_construct_properties,
GObjectConstructParam *construct_params)
{
GObject *object;
GvcMixerStream *self;
object = G_OBJECT_CLASS (gvc_mixer_stream_parent_class)->constructor (type, n_construct_properties, construct_params);
self = GVC_MIXER_STREAM (object);
self->priv->id = get_next_stream_serial ();
return object;
}
static gboolean
gvc_mixer_stream_real_change_port (GvcMixerStream *stream,
const char *port)
{
return FALSE;
}
static gboolean
gvc_mixer_stream_real_push_volume (GvcMixerStream *stream, gpointer *op)
{
return FALSE;
}
static gboolean
gvc_mixer_stream_real_change_is_muted (GvcMixerStream *stream,
gboolean is_muted)
{
return FALSE;
}
gboolean
gvc_mixer_stream_push_volume (GvcMixerStream *stream)
{
pa_operation *op;
gboolean ret;
g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), FALSE);
if (stream->priv->is_event_stream != FALSE)
return TRUE;
g_debug ("Pushing new volume to stream '%s' (%s)",
stream->priv->description, stream->priv->name);
ret = GVC_MIXER_STREAM_GET_CLASS (stream)->push_volume (stream, (gpointer *) &op);
if (ret) {
if (stream->priv->change_volume_op != NULL)
pa_operation_unref (stream->priv->change_volume_op);
stream->priv->change_volume_op = op;
}
return ret;
}
gboolean
gvc_mixer_stream_change_is_muted (GvcMixerStream *stream,
gboolean is_muted)
{
gboolean ret;
g_return_val_if_fail (GVC_IS_MIXER_STREAM (stream), FALSE);
ret = GVC_MIXER_STREAM_GET_CLASS (stream)->change_is_muted (stream, is_muted);
return ret;
}
gboolean
gvc_mixer_stream_is_running (GvcMixerStream *stream)
{
if (stream->priv->change_volume_op == NULL)
return FALSE;
if ((pa_operation_get_state(stream->priv->change_volume_op) == PA_OPERATION_RUNNING))
return TRUE;
pa_operation_unref(stream->priv->change_volume_op);
stream->priv->change_volume_op = NULL;
return FALSE;
}
static void
gvc_mixer_stream_class_init (GvcMixerStreamClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
gobject_class->constructor = gvc_mixer_stream_constructor;
gobject_class->finalize = gvc_mixer_stream_finalize;
gobject_class->set_property = gvc_mixer_stream_set_property;
gobject_class->get_property = gvc_mixer_stream_get_property;
klass->push_volume = gvc_mixer_stream_real_push_volume;
klass->change_port = gvc_mixer_stream_real_change_port;
klass->change_is_muted = gvc_mixer_stream_real_change_is_muted;
g_object_class_install_property (gobject_class,
PROP_INDEX,
g_param_spec_ulong ("index",
"Index",
"The index for this stream",
0, G_MAXULONG, 0,
G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (gobject_class,
PROP_ID,
g_param_spec_ulong ("id",
"id",
"The id for this stream",
0, G_MAXULONG, 0,
G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (gobject_class,
PROP_CHANNEL_MAP,
g_param_spec_object ("channel-map",
"channel map",
"The channel map for this stream",
GVC_TYPE_CHANNEL_MAP,
G_PARAM_READWRITE|G_PARAM_CONSTRUCT));
g_object_class_install_property (gobject_class,
PROP_PA_CONTEXT,
g_param_spec_pointer ("pa-context",
"PulseAudio context",
"The PulseAudio context for this stream",
G_PARAM_READWRITE|G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (gobject_class,
PROP_VOLUME,
g_param_spec_ulong ("volume",
"Volume",
"The volume for this stream",
0, G_MAXULONG, 0,
G_PARAM_READWRITE));
g_object_class_install_property (gobject_class,
PROP_DECIBEL,
g_param_spec_double ("decibel",
"Decibel",
"The decibel level for this stream",
-G_MAXDOUBLE, G_MAXDOUBLE, 0,
G_PARAM_READWRITE|G_PARAM_CONSTRUCT));
g_object_class_install_property (gobject_class,
PROP_NAME,
g_param_spec_string ("name",
"Name",
"Name to display for this stream",
NULL,
G_PARAM_READWRITE|G_PARAM_CONSTRUCT));
g_object_class_install_property (gobject_class,
PROP_DESCRIPTION,
g_param_spec_string ("description",
"Description",
"Description to display for this stream",
NULL,
G_PARAM_READWRITE|G_PARAM_CONSTRUCT));
g_object_class_install_property (gobject_class,
PROP_APPLICATION_ID,
g_param_spec_string ("application-id",
"Application identifier",
"Application identifier for this stream",
NULL,
G_PARAM_READWRITE|G_PARAM_CONSTRUCT));
g_object_class_install_property (gobject_class,
PROP_ICON_NAME,
g_param_spec_string ("icon-name",
"Icon Name",
"Name of icon to display for this stream",
NULL,
G_PARAM_READWRITE|G_PARAM_CONSTRUCT));
g_object_class_install_property (gobject_class,
PROP_IS_MUTED,
g_param_spec_boolean ("is-muted",
"is muted",
"Whether stream is muted",
FALSE,
G_PARAM_READWRITE|G_PARAM_CONSTRUCT));
g_object_class_install_property (gobject_class,
PROP_CAN_DECIBEL,
g_param_spec_boolean ("can-decibel",
"can decibel",
"Whether stream volume can be converted to decibel units",
FALSE,
G_PARAM_READWRITE|G_PARAM_CONSTRUCT));
g_object_class_install_property (gobject_class,
PROP_IS_EVENT_STREAM,
g_param_spec_boolean ("is-event-stream",
"is event stream",
"Whether stream's role is to play an event",
FALSE,
G_PARAM_READWRITE|G_PARAM_CONSTRUCT));
g_object_class_install_property (gobject_class,
PROP_IS_VIRTUAL,
g_param_spec_boolean ("is-virtual",
"is virtual stream",
"Whether the stream is virtual",
FALSE,
G_PARAM_READWRITE|G_PARAM_CONSTRUCT));
g_object_class_install_property (gobject_class,
PROP_PORT,
g_param_spec_string ("port",
"Port",
"The name of the current port for this stream",
NULL,
G_PARAM_READWRITE));
g_object_class_install_property (gobject_class,
PROP_CARD_INDEX,
g_param_spec_long ("card-index",
"Card index",
"The index of the card for this stream",
PA_INVALID_INDEX, G_MAXLONG, PA_INVALID_INDEX,
G_PARAM_READWRITE|G_PARAM_CONSTRUCT));
g_type_class_add_private (klass, sizeof (GvcMixerStreamPrivate));
}
static void
gvc_mixer_stream_init (GvcMixerStream *stream)
{
stream->priv = GVC_MIXER_STREAM_GET_PRIVATE (stream);
}
static void
free_port (GvcMixerStreamPort *p)
{
g_free (p->port);
g_free (p->human_port);
g_free (p);
}
static void
gvc_mixer_stream_finalize (GObject *object)
{
GvcMixerStream *mixer_stream;
g_return_if_fail (object != NULL);
g_return_if_fail (GVC_IS_MIXER_STREAM (object));
mixer_stream = GVC_MIXER_STREAM (object);
g_return_if_fail (mixer_stream->priv != NULL);
g_object_unref (mixer_stream->priv->channel_map);
mixer_stream->priv->channel_map = NULL;
g_free (mixer_stream->priv->name);
mixer_stream->priv->name = NULL;
g_free (mixer_stream->priv->description);
mixer_stream->priv->description = NULL;
g_free (mixer_stream->priv->application_id);
mixer_stream->priv->application_id = NULL;
g_free (mixer_stream->priv->icon_name);
mixer_stream->priv->icon_name = NULL;
g_free (mixer_stream->priv->port);
mixer_stream->priv->port = NULL;
g_free (mixer_stream->priv->human_port);
mixer_stream->priv->human_port = NULL;
g_list_foreach (mixer_stream->priv->ports, (GFunc) free_port, NULL);
g_list_free (mixer_stream->priv->ports);
mixer_stream->priv->ports = NULL;
if (mixer_stream->priv->change_volume_op) {
pa_operation_unref(mixer_stream->priv->change_volume_op);
mixer_stream->priv->change_volume_op = NULL;
}
G_OBJECT_CLASS (gvc_mixer_stream_parent_class)->finalize (object);
}

125
src/gvc/gvc-mixer-stream.h Normal file
View File

@ -0,0 +1,125 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
* Copyright (C) 2008 Red Hat, Inc.
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
#ifndef __GVC_MIXER_STREAM_H
#define __GVC_MIXER_STREAM_H
#include <glib-object.h>
#include "gvc-pulseaudio-fake.h"
#include "gvc-channel-map.h"
G_BEGIN_DECLS
#define GVC_TYPE_MIXER_STREAM (gvc_mixer_stream_get_type ())
#define GVC_MIXER_STREAM(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), GVC_TYPE_MIXER_STREAM, GvcMixerStream))
#define GVC_MIXER_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), GVC_TYPE_MIXER_STREAM, GvcMixerStreamClass))
#define GVC_IS_MIXER_STREAM(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), GVC_TYPE_MIXER_STREAM))
#define GVC_IS_MIXER_STREAM_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), GVC_TYPE_MIXER_STREAM))
#define GVC_MIXER_STREAM_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), GVC_TYPE_MIXER_STREAM, GvcMixerStreamClass))
typedef struct GvcMixerStreamPrivate GvcMixerStreamPrivate;
typedef struct
{
GObject parent;
GvcMixerStreamPrivate *priv;
} GvcMixerStream;
typedef struct
{
GObjectClass parent_class;
/* vtable */
gboolean (*push_volume) (GvcMixerStream *stream,
gpointer *operation);
gboolean (*change_is_muted) (GvcMixerStream *stream,
gboolean is_muted);
gboolean (*change_port) (GvcMixerStream *stream,
const char *port);
} GvcMixerStreamClass;
typedef struct
{
char *port;
char *human_port;
guint priority;
} GvcMixerStreamPort;
GType gvc_mixer_stream_get_type (void);
guint gvc_mixer_stream_get_index (GvcMixerStream *stream);
guint gvc_mixer_stream_get_id (GvcMixerStream *stream);
const GvcChannelMap *gvc_mixer_stream_get_channel_map(GvcMixerStream *stream);
const GvcMixerStreamPort *gvc_mixer_stream_get_port (GvcMixerStream *stream);
const GList * gvc_mixer_stream_get_ports (GvcMixerStream *stream);
gboolean gvc_mixer_stream_change_port (GvcMixerStream *stream,
const char *port);
pa_volume_t gvc_mixer_stream_get_volume (GvcMixerStream *stream);
gdouble gvc_mixer_stream_get_decibel (GvcMixerStream *stream);
gboolean gvc_mixer_stream_push_volume (GvcMixerStream *stream);
pa_volume_t gvc_mixer_stream_get_base_volume (GvcMixerStream *stream);
gboolean gvc_mixer_stream_get_is_muted (GvcMixerStream *stream);
gboolean gvc_mixer_stream_get_can_decibel (GvcMixerStream *stream);
gboolean gvc_mixer_stream_change_is_muted (GvcMixerStream *stream,
gboolean is_muted);
gboolean gvc_mixer_stream_is_running (GvcMixerStream *stream);
const char * gvc_mixer_stream_get_name (GvcMixerStream *stream);
const char * gvc_mixer_stream_get_icon_name (GvcMixerStream *stream);
const char * gvc_mixer_stream_get_description (GvcMixerStream *stream);
const char * gvc_mixer_stream_get_application_id (GvcMixerStream *stream);
gboolean gvc_mixer_stream_is_event_stream (GvcMixerStream *stream);
gboolean gvc_mixer_stream_is_virtual (GvcMixerStream *stream);
gint gvc_mixer_stream_get_card_index (GvcMixerStream *stream);
/* private */
gboolean gvc_mixer_stream_set_volume (GvcMixerStream *stream,
pa_volume_t volume);
gboolean gvc_mixer_stream_set_decibel (GvcMixerStream *stream,
gdouble db);
gboolean gvc_mixer_stream_set_is_muted (GvcMixerStream *stream,
gboolean is_muted);
gboolean gvc_mixer_stream_set_can_decibel (GvcMixerStream *stream,
gboolean can_decibel);
gboolean gvc_mixer_stream_set_name (GvcMixerStream *stream,
const char *name);
gboolean gvc_mixer_stream_set_description (GvcMixerStream *stream,
const char *description);
gboolean gvc_mixer_stream_set_icon_name (GvcMixerStream *stream,
const char *name);
gboolean gvc_mixer_stream_set_is_event_stream (GvcMixerStream *stream,
gboolean is_event_stream);
gboolean gvc_mixer_stream_set_is_virtual (GvcMixerStream *stream,
gboolean is_event_stream);
gboolean gvc_mixer_stream_set_application_id (GvcMixerStream *stream,
const char *application_id);
gboolean gvc_mixer_stream_set_base_volume (GvcMixerStream *stream,
pa_volume_t base_volume);
gboolean gvc_mixer_stream_set_port (GvcMixerStream *stream,
const char *port);
gboolean gvc_mixer_stream_set_ports (GvcMixerStream *stream,
GList *ports);
gboolean gvc_mixer_stream_set_card_index (GvcMixerStream *stream,
gint card_index);
G_END_DECLS
#endif /* __GVC_MIXER_STREAM_H */

View File

@ -0,0 +1,34 @@
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*-
*
* Copyright (C) 2008 Red Hat, Inc.
*
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
*/
#ifndef __GVC_PULSEAUDIO_FAKE_H
#define __GVC_PULSEAUDIO_FAKE_H
#ifdef WITH_INTROSPECTION
#ifndef PA_API_VERSION
typedef int pa_channel_position_t;
typedef guint32 pa_volume_t;
typedef gpointer pa_context;
#endif /* PA_API_VERSION */
#endif /* WITH_INTROSPECTION */
#endif /* __GVC_PULSEAUDIO_FAKE_H */

View File

@ -24,6 +24,7 @@
#include <math.h>
#include <X11/extensions/Xfixes.h>
#include <gjs/gjs.h>
#include <canberra.h>
#ifdef HAVE_SYS_RESOURCE_H
#include <sys/resource.h>
#endif
@ -67,6 +68,9 @@ struct _ShellGlobal {
guint work_count;
GSList *leisure_closures;
guint leisure_function_id;
/* For sound notifications */
ca_context *sound_context;
};
enum {
@ -214,6 +218,10 @@ shell_global_init (ShellGlobal *global)
global->last_change_screen_width = 0;
global->last_change_screen_height = 0;
ca_context_create (&global->sound_context);
ca_context_change_props (global->sound_context, CA_PROP_APPLICATION_NAME, PACKAGE_NAME, CA_PROP_APPLICATION_ID, "org.gnome.Shell", NULL);
ca_context_open (global->sound_context);
}
static void
@ -1788,3 +1796,18 @@ shell_global_run_at_leisure (ShellGlobal *global,
if (global->work_count == 0)
schedule_leisure_functions (global);
}
/**
* shell_global_play_theme_sound:
* @global: the #ShellGlobal
* @name: the sound name
*
* Plays a simple sound picked according to Freedesktop sound theme.
* Really just a workaround for libcanberra not being introspected.
*/
void
shell_global_play_theme_sound (ShellGlobal *global,
const char *name)
{
ca_context_play (global->sound_context, 0, CA_PROP_EVENT_ID, name, NULL);
}

View File

@ -130,6 +130,9 @@ void shell_global_run_at_leisure (ShellGlobal *global,
gpointer user_data,
GDestroyNotify notify);
void shell_global_play_theme_sound (ShellGlobal *global,
const char *name);
G_END_DECLS
#endif /* __SHELL_GLOBAL_H__ */

View File

@ -115,6 +115,7 @@ st_drawing_area_paint (ClutterActor *self)
surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, width, height);
priv->context = cairo_create (surface);
priv->in_repaint = TRUE;
priv->needs_repaint = FALSE;
g_signal_emit ((GObject*)area, st_drawing_area_signals[REPAINT], 0);

View File

@ -320,6 +320,7 @@ st_theme_load_stylesheet (StTheme *theme,
return FALSE;
insert_stylesheet (theme, path, stylesheet);
cr_stylesheet_ref (stylesheet);
theme->custom_stylesheets = g_slist_prepend (theme->custom_stylesheets, stylesheet);
return TRUE;

View File

@ -58,7 +58,7 @@ fi
#
# Devel packages needed by gnome-shell and its deps:
# dbus-glib, GL, gnome-menus, gstreamer, libffi,
# libjasper, libjpeg, libpng, libtiff, libwnck,
# libjasper, libjpeg, libpng, libpulse, libtiff, libwnck,
# libxml2, ORBit2, python, readline,
# spidermonkey ({mozilla,firefox,xulrunner}-js), startup-notification
# xdamage, icon-naming-utils
@ -83,7 +83,7 @@ if test "x$system" = xUbuntu -o "x$system" = xDebian -o "x$system" = xLinuxMint
gvfs gvfs-backends icon-naming-utils \
libdbus-glib-1-dev libffi-dev libgnome-menu-dev libgnome-desktop-dev \
libjasper-dev libjpeg-dev libpng-dev libstartup-notification0-dev libtiff-dev \
libwnck-dev libgl1-mesa-dev liborbit2-dev libreadline5-dev libxml2-dev \
libwnck-dev libgl1-mesa-dev liborbit2-dev libpulse-dev libreadline5-dev libxml2-dev \
mesa-common-dev mesa-utils python-dev python-gconf python-gobject \
xulrunner-dev xserver-xephyr gnome-terminal libcroco3-dev \
libgstreamer0.10-dev gstreamer0.10-plugins-base gstreamer0.10-plugins-good \
@ -105,8 +105,8 @@ if test "x$system" = xFedora ; then
automake bison flex gettext git gnome-common gnome-doc-utils gvfs intltool
libtool pkgconfig dbus-glib-devel gnome-desktop-devel gnome-menus-devel
gnome-python2-gconf jasper-devel libffi-devel libjpeg-devel libpng-devel
libtiff-devel libwnck-devel mesa-libGL-devel ORBit2-devel python-devel
pygobject2 readline-devel xulrunner-devel libXdamage-devel libcroco-devel
libtiff-devel libwnck-devel mesa-libGL-devel ORBit2-devel pulseaudio-libs-devel
python-devel pygobject2 readline-devel xulrunner-devel libXdamage-devel libcroco-devel
libxml2-devel gstreamer-devel gstreamer-plugins-base gstreamer-plugins-good
glx-utils startup-notification-devel xorg-x11-server-Xephyr gnome-terminal zenity
icon-naming-utils
@ -132,7 +132,7 @@ if test "x$system" = xSUSE -o "x$system" = "xSUSE LINUX" ; then
curl \
bison flex gtk-doc gnome-common gnome-doc-utils-devel \
gnome-desktop-devel gnome-menus-devel icon-naming-utils \
libtiff-devel cups-devel libffi-devel \
libpulse-devel libtiff-devel cups-devel libffi-devel \
orbit2-devel libwnck-devel xorg-x11-proto-devel readline-devel \
mozilla-xulrunner191-devel libcroco-devel \
xorg-x11-devel xorg-x11 xorg-x11-server-extra \