[Xfce4-commits] [panel-plugins/xfce4-pulseaudio-plugin] 01/01: Add XF86AudioMicMute key support

noreply at xfce.org noreply at xfce.org
Sat May 20 14:34:37 CEST 2017


This is an automated email from the git hooks/post-receive script.

a   n   d   r   z   e   j   r       p   u   s   h   e   d       a       c   o   m   m   i   t       t   o       b   r   a   n   c   h       m   a   s   t   e   r   
   in repository panel-plugins/xfce4-pulseaudio-plugin.

commit f7024b6c7a6c954ede32cd147a1dd93d7220a133
Author: Viktor Odintsev <zakhams at gmail.com>
Date:   Sat May 13 07:02:30 2017 +0300

    Add XF86AudioMicMute key support
---
 icons/scalable/status/Makefile.am                  |   6 +-
 .../microphone-sensitivity-high-symbolic.svg       |  45 +++++++
 .../status/microphone-sensitivity-low-symbolic.svg |  45 +++++++
 .../microphone-sensitivity-medium-symbolic.svg     |  45 +++++++
 .../microphone-sensitivity-muted-symbolic.svg      |  45 +++++++
 panel-plugin/pulseaudio-notify.c                   |  81 +++++++++---
 panel-plugin/pulseaudio-plugin.c                   |  19 ++-
 panel-plugin/pulseaudio-volume.c                   | 144 ++++++++++++++++++++-
 panel-plugin/pulseaudio-volume.h                   |  31 +++--
 9 files changed, 420 insertions(+), 41 deletions(-)

diff --git a/icons/scalable/status/Makefile.am b/icons/scalable/status/Makefile.am
index ad4dcc8..603878e 100644
--- a/icons/scalable/status/Makefile.am
+++ b/icons/scalable/status/Makefile.am
@@ -5,7 +5,11 @@ icons_DATA =								\
     audio-volume-high-symbolic.svg          \
     audio-volume-low-symbolic.svg           \
     audio-volume-medium-symbolic.svg        \
-    audio-volume-muted-symbolic.svg
+    audio-volume-muted-symbolic.svg         \
+    microphone-sensitivity-high-symbolic.svg          \
+    microphone-sensitivity-low-symbolic.svg           \
+    microphone-sensitivity-medium-symbolic.svg        \
+    microphone-sensitivity-muted-symbolic.svg
 
 EXTRA_DIST =								\
 	$(icons_DATA)
diff --git a/icons/scalable/status/microphone-sensitivity-high-symbolic.svg b/icons/scalable/status/microphone-sensitivity-high-symbolic.svg
new file mode 100644
index 0000000..b5578ea
--- /dev/null
+++ b/icons/scalable/status/microphone-sensitivity-high-symbolic.svg
@@ -0,0 +1,45 @@
+<?xml version='1.0' encoding='UTF-8' standalone='no'?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg xmlns:cc='http://creativecommons.org/ns#' xmlns:dc='http://purl.org/dc/elements/1.1/' sodipodi:docname='microphone-sensitivity-high-symbolic.svg' height='16.001951' id='svg7384' xmlns:inkscape='http://www.inkscape.org/namespaces/inkscape' xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#' xmlns:sodipodi='http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd' xmlns:svg='http://www.w3.org/2000/svg' inkscape:version='0.48.4 r9939' version='1.1' width='16' xmlns='http://www.w3.org/2000/svg'>
+  <metadata id='metadata90'>
+    <rdf:RDF>
+      <cc:Work rdf:about=''>
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type rdf:resource='http://purl.org/dc/dcmitype/StillImage'/>
+        <dc:title>Gnome Symbolic Icon Theme</dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview inkscape:bbox-nodes='false' inkscape:bbox-paths='true' bordercolor='#666666' borderopacity='1' inkscape:current-layer='layer9' inkscape:cx='91.284009' inkscape:cy='-441.90835' gridtolerance='10' inkscape:guide-bbox='true' guidetolerance='10' id='namedview88' inkscape:object-nodes='false' inkscape:object-paths='false' objecttolerance='10' pagecolor='#3a3b39' inkscape:pageopacity='1' inkscape:pageshadow='2' showborder='false' showgrid='false' showguides='true' inkscap [...]
+    <inkscape:grid empspacing='2' enabled='true' id='grid4866' originx='60.0002px' originy='-19.998049px' snapvisiblegridlinesonly='true' spacingx='1px' spacingy='1px' type='xygrid' visible='true'/>
+    <inkscape:grid color='#000000' empcolor='#000000' empopacity='0' empspacing='4' enabled='true' id='grid5968' opacity='0.1254902' originx='60.0002px' originy='-19.998049px' snapvisiblegridlinesonly='true' spacingx='0.5px' spacingy='0.5px' type='xygrid' visible='true'/>
+  </sodipodi:namedview>
+  <title id='title9167'>Gnome Symbolic Icon Theme</title>
+  <defs id='defs7386'>
+    <clipPath clipPathUnits='userSpaceOnUse' id='clipPath6810-7-87'>
+      <rect height='11' id='rect6812-2-4' style='color:#bebebe;fill:none;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible' width='14' x='21' y='281'/>
+    </clipPath>
+  </defs>
+  <g inkscape:groupmode='layer' id='layer9' inkscape:label='status' style='display:inline' transform='translate(-181,-197)'>
+    
+    <rect height='10.012877' id='rect12327' rx='2.5' ry='2.5' style='color:#bebebe;fill:#bebebe;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible' width='5' x='184' y='197.98712'/>
+    <path clip-path='url(#clipPath6810-7-87)' inkscape:connector-curvature='0' d='m 27.96875,273.625 c -2.502477,0 -4.53125,2.02877 -4.53125,4.53125 l 0,5.8125 c 0,2.50248 2.028773,4.53125 4.53125,4.53125 2.502477,0 4.53125,-2.02877 4.53125,-4.53125 l 0,-5.8125 c 0,-2.50248 -2.028773,-4.53125 -4.53125,-4.53125 z m 0,1 c 1.964148,0 3.53125,1.5671 3.53125,3.53125 l 0,5.8125 c 0,1.96415 -1.567102,3.53125 -3.53125,3.53125 -1.964148,0 -3.53125,-1.5671 -3.53125,-3.53125 l 0,-5.8125 c 0,-1.9641 [...]
+    <path sodipodi:cx='23' sodipodi:cy='361' d='m 24,361 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z' id='path12331' sodipodi:rx='1' sodipodi:ry='1' style='color:#bebebe;fill:#bebebe;fill-opacity:1;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible' transform='matrix(0.5,0,0,0.5,171,22)' sodipodi:type='arc'/>
+    <path sodipodi:cx='23' sodipodi:cy='361' d='m 24,361 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z' id='path12333' sodipodi:rx='1' sodipodi:ry='1' style='color:#bebebe;fill:#bebebe;fill-opacity:1;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible' transform='matrix(0.5,0,0,0.5,179,22)' sodipodi:type='arc'/>
+    <path inkscape:connector-curvature='0' d='m 182.875,211 a 1.0019512,1.0019512 0 1 0 0.125,2 l 7.03125,0 a 1.0001,1.0001 0 1 0 0,-2 L 183,211 a 1.0001,1.0001 0 0 0 -0.125,0 z' id='path12335' style='font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-ancho [...]
+    <rect height='1' id='rect12337' style='color:#bebebe;fill:#bebebe;fill-opacity:1;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible' width='9' x='182' y='212'/>
+    <rect height='4' id='rect12339' style='color:#bebebe;fill:#bebebe;fill-opacity:1;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible' width='3' x='185' y='209'/>
+    <path sodipodi:cx='-188' sodipodi:cy='184.0625' d='m -186.0625,184.0625 a 1.9375,1.9375 0 1 1 -3.875,0 1.9375,1.9375 0 1 1 3.875,0 z' id='path12343' sodipodi:rx='1.9375' sodipodi:ry='1.9375' style='color:#000000;fill:#bebebe;fill-opacity:1;stroke:none;stroke-width:1.2784189;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate' transform='matrix(1.0322581,0,0,1.0322551,388.06472,20.00054)' sodipodi:type='arc'/>
+    <path sodipodi:cx='-188' sodipodi:cy='184.0625' d='m -186.0625,184.0625 a 1.9375,1.9375 0 1 1 -3.875,0 1.9375,1.9375 0 1 1 3.875,0 z' id='path12345' sodipodi:rx='1.9375' sodipodi:ry='1.9375' style='color:#000000;fill:#bebebe;fill-opacity:1;stroke:none;stroke-width:1.2784189;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate' transform='matrix(1.0322581,0,0,1.0322551,388.06472,15.00054)' sodipodi:type='arc'/>
+    <path sodipodi:cx='-188' sodipodi:cy='184.0625' d='m -186.0625,184.0625 a 1.9375,1.9375 0 1 1 -3.875,0 1.9375,1.9375 0 1 1 3.875,0 z' id='path12347' sodipodi:rx='1.9375' sodipodi:ry='1.9375' style='color:#000000;fill:#bebebe;fill-opacity:1;stroke:none;stroke-width:1.2784189;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate' transform='matrix(1.0322581,0,0,1.0322551,388.06472,10.00054)' sodipodi:type='arc'/>
+  </g>
+  <g inkscape:groupmode='layer' id='layer10' inkscape:label='devices' style='display:inline' transform='translate(-181,-197)'/>
+  <g inkscape:groupmode='layer' id='layer11' inkscape:label='apps' transform='translate(-181,-197)'/>
+  <g inkscape:groupmode='layer' id='layer13' inkscape:label='places' style='display:inline' transform='translate(-181,-197)'/>
+  <g inkscape:groupmode='layer' id='layer14' inkscape:label='mimetypes' transform='translate(-181,-197)'/>
+  <g inkscape:groupmode='layer' id='layer15' inkscape:label='emblems' style='display:inline' transform='translate(-181,-197)'/>
+  <g inkscape:groupmode='layer' id='g71291' inkscape:label='emotes' style='display:inline' transform='translate(-181,-197)'/>
+  <g inkscape:groupmode='layer' id='g4953' inkscape:label='categories' style='display:inline' transform='translate(-181,-197)'/>
+  <g inkscape:groupmode='layer' id='layer12' inkscape:label='actions' style='display:inline' transform='translate(-181,-197)'/>
+</svg>
diff --git a/icons/scalable/status/microphone-sensitivity-low-symbolic.svg b/icons/scalable/status/microphone-sensitivity-low-symbolic.svg
new file mode 100644
index 0000000..612d4d0
--- /dev/null
+++ b/icons/scalable/status/microphone-sensitivity-low-symbolic.svg
@@ -0,0 +1,45 @@
+<?xml version='1.0' encoding='UTF-8' standalone='no'?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg xmlns:cc='http://creativecommons.org/ns#' xmlns:dc='http://purl.org/dc/elements/1.1/' sodipodi:docname='microphone-sensitivity-low-symbolic.svg' height='16.001099' id='svg7384' xmlns:inkscape='http://www.inkscape.org/namespaces/inkscape' xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#' xmlns:sodipodi='http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd' xmlns:svg='http://www.w3.org/2000/svg' inkscape:version='0.48.4 r9939' version='1.1' width='16' xmlns='http://www.w3.org/2000/svg'>
+  <metadata id='metadata90'>
+    <rdf:RDF>
+      <cc:Work rdf:about=''>
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type rdf:resource='http://purl.org/dc/dcmitype/StillImage'/>
+        <dc:title>Gnome Symbolic Icon Theme</dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview inkscape:bbox-nodes='false' inkscape:bbox-paths='true' bordercolor='#666666' borderopacity='1' inkscape:current-layer='layer9' inkscape:cx='131.28401' inkscape:cy='-441.9092' gridtolerance='10' inkscape:guide-bbox='true' guidetolerance='10' id='namedview88' inkscape:object-nodes='false' inkscape:object-paths='false' objecttolerance='10' pagecolor='#3a3b39' inkscape:pageopacity='1' inkscape:pageshadow='2' showborder='false' showgrid='false' showguides='true' inkscape [...]
+    <inkscape:grid empspacing='2' enabled='true' id='grid4866' originx='100.0002px' originy='-19.998902px' snapvisiblegridlinesonly='true' spacingx='1px' spacingy='1px' type='xygrid' visible='true'/>
+    <inkscape:grid color='#000000' empcolor='#000000' empopacity='0' empspacing='4' enabled='true' id='grid5968' opacity='0.1254902' originx='100.0002px' originy='-19.998902px' snapvisiblegridlinesonly='true' spacingx='0.5px' spacingy='0.5px' type='xygrid' visible='true'/>
+  </sodipodi:namedview>
+  <title id='title9167'>Gnome Symbolic Icon Theme</title>
+  <defs id='defs7386'>
+    <clipPath clipPathUnits='userSpaceOnUse' id='clipPath6810-7-87'>
+      <rect height='11' id='rect6812-2-4' style='color:#bebebe;fill:none;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible' width='14' x='21' y='281'/>
+    </clipPath>
+  </defs>
+  <g inkscape:groupmode='layer' id='layer9' inkscape:label='status' style='display:inline' transform='translate(-141,-197)'>
+    <path inkscape:connector-curvature='0' d='m 154.0002,198 c -1.10457,0 -2,0.89543 -2,2 0,1.10457 0.89543,2 2,2 1.10457,0 2,-0.89543 2,-2 0,-1.10457 -0.89543,-2 -2,-2 z m 0,1 c 0.55228,0 1,0.44771 1,1 0,0.55228 -0.44772,1 -1,1 -0.55229,0 -1,-0.44772 -1,-1 0,-0.55229 0.44771,-1 1,-1 z' id='path8179' style='opacity:0.5;color:#000000;fill:#bebebe;fill-opacity:1;stroke:none;stroke-width:1.2784189;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate'/>
+    
+    <rect height='10' id='rect12259' rx='2.4999001' ry='2.5' style='color:#bebebe;fill:#bebebe;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible' width='4.9998002' x='144.0002' y='198'/>
+    <path clip-path='url(#clipPath6810-7-87)' inkscape:connector-curvature='0' d='m 27.96875,273.625 c -2.502477,0 -4.53125,2.02877 -4.53125,4.53125 l 0,5.8125 c 0,2.50248 2.028773,4.53125 4.53125,4.53125 2.502477,0 4.53125,-2.02877 4.53125,-4.53125 l 0,-5.8125 c 0,-2.50248 -2.028773,-4.53125 -4.53125,-4.53125 z m 0,1 c 1.964148,0 3.53125,1.5671 3.53125,3.53125 l 0,5.8125 c 0,1.96415 -1.567102,3.53125 -3.53125,3.53125 -1.964148,0 -3.53125,-1.5671 -3.53125,-3.53125 l 0,-5.8125 c 0,-1.9641 [...]
+    <path sodipodi:cx='23' sodipodi:cy='361' d='m 24,361 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z' id='path12263' sodipodi:rx='1' sodipodi:ry='1' style='color:#bebebe;fill:#bebebe;fill-opacity:1;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible' transform='matrix(0.5,0,0,0.5,131,22)' sodipodi:type='arc'/>
+    <path sodipodi:cx='23' sodipodi:cy='361' d='m 24,361 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z' id='path12265' sodipodi:rx='1' sodipodi:ry='1' style='color:#bebebe;fill:#bebebe;fill-opacity:1;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible' transform='matrix(0.5,0,0,0.5,139,22)' sodipodi:type='arc'/>
+    <path inkscape:connector-curvature='0' d='M 142.90625,211 A 1.001098,1.001098 0 1 0 143,213 l 7,0 a 1.0001,1.0001 0 1 0 0,-2 l -7,0 a 1.0001,1.0001 0 0 0 -0.0937,0 z' id='path12267' style='font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start; [...]
+    <rect height='1' id='rect12269' style='color:#bebebe;fill:#bebebe;fill-opacity:1;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible' width='9' x='142' y='212'/>
+    <rect height='4' id='rect12271' style='color:#bebebe;fill:#bebebe;fill-opacity:1;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible' width='3' x='145' y='209'/>
+    <path sodipodi:cx='-188' sodipodi:cy='184.0625' d='m -186.0625,184.0625 a 1.9375,1.9375 0 1 1 -3.875,0 1.9375,1.9375 0 1 1 3.875,0 z' id='path12275' sodipodi:rx='1.9375' sodipodi:ry='1.9375' style='color:#000000;fill:#bebebe;fill-opacity:1;stroke:none;stroke-width:1.2784189;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate' transform='matrix(1.0322581,0,0,1.0322551,348.06472,20.000543)' sodipodi:type='arc'/>
+    <path inkscape:connector-curvature='0' d='m 154.0002,203 c -1.10457,0 -2,0.89543 -2,2 0,1.10457 0.89543,2 2,2 1.10457,0 2,-0.89543 2,-2 0,-1.10457 -0.89543,-2 -2,-2 z m 0,1 c 0.55228,0 1,0.44771 1,1 0,0.55228 -0.44772,1 -1,1 -0.55228,0 -1,-0.44772 -1,-1 0,-0.55229 0.44772,-1 1,-1 z' id='path8174' style='opacity:0.5;color:#000000;fill:#bebebe;fill-opacity:1;stroke:none;stroke-width:1.2784189;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate'/>
+  </g>
+  <g inkscape:groupmode='layer' id='layer10' inkscape:label='devices' style='display:inline' transform='translate(-141,-197)'/>
+  <g inkscape:groupmode='layer' id='layer11' inkscape:label='apps' transform='translate(-141,-197)'/>
+  <g inkscape:groupmode='layer' id='layer13' inkscape:label='places' style='display:inline' transform='translate(-141,-197)'/>
+  <g inkscape:groupmode='layer' id='layer14' inkscape:label='mimetypes' transform='translate(-141,-197)'/>
+  <g inkscape:groupmode='layer' id='layer15' inkscape:label='emblems' style='display:inline' transform='translate(-141,-197)'/>
+  <g inkscape:groupmode='layer' id='g71291' inkscape:label='emotes' style='display:inline' transform='translate(-141,-197)'/>
+  <g inkscape:groupmode='layer' id='g4953' inkscape:label='categories' style='display:inline' transform='translate(-141,-197)'/>
+  <g inkscape:groupmode='layer' id='layer12' inkscape:label='actions' style='display:inline' transform='translate(-141,-197)'/>
+</svg>
diff --git a/icons/scalable/status/microphone-sensitivity-medium-symbolic.svg b/icons/scalable/status/microphone-sensitivity-medium-symbolic.svg
new file mode 100644
index 0000000..9a47107
--- /dev/null
+++ b/icons/scalable/status/microphone-sensitivity-medium-symbolic.svg
@@ -0,0 +1,45 @@
+<?xml version='1.0' encoding='UTF-8' standalone='no'?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg xmlns:cc='http://creativecommons.org/ns#' xmlns:dc='http://purl.org/dc/elements/1.1/' sodipodi:docname='microphone-sensitivity-medium-symbolic.svg' height='16.001099' id='svg7384' xmlns:inkscape='http://www.inkscape.org/namespaces/inkscape' xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#' xmlns:sodipodi='http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd' xmlns:svg='http://www.w3.org/2000/svg' inkscape:version='0.48.4 r9939' version='1.1' width='16' xmlns='http://www.w3.org/2 [...]
+  <metadata id='metadata90'>
+    <rdf:RDF>
+      <cc:Work rdf:about=''>
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type rdf:resource='http://purl.org/dc/dcmitype/StillImage'/>
+        <dc:title>Gnome Symbolic Icon Theme</dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview inkscape:bbox-nodes='false' inkscape:bbox-paths='true' bordercolor='#666666' borderopacity='1' inkscape:current-layer='layer9' inkscape:cx='111.28401' inkscape:cy='-441.9092' gridtolerance='10' inkscape:guide-bbox='true' guidetolerance='10' id='namedview88' inkscape:object-nodes='false' inkscape:object-paths='false' objecttolerance='10' pagecolor='#3a3b39' inkscape:pageopacity='1' inkscape:pageshadow='2' showborder='false' showgrid='false' showguides='true' inkscape [...]
+    <inkscape:grid empspacing='2' enabled='true' id='grid4866' originx='80.0002px' originy='-19.998902px' snapvisiblegridlinesonly='true' spacingx='1px' spacingy='1px' type='xygrid' visible='true'/>
+    <inkscape:grid color='#000000' empcolor='#000000' empopacity='0' empspacing='4' enabled='true' id='grid5968' opacity='0.1254902' originx='80.0002px' originy='-19.998902px' snapvisiblegridlinesonly='true' spacingx='0.5px' spacingy='0.5px' type='xygrid' visible='true'/>
+  </sodipodi:namedview>
+  <title id='title9167'>Gnome Symbolic Icon Theme</title>
+  <defs id='defs7386'>
+    <clipPath clipPathUnits='userSpaceOnUse' id='clipPath6810-7-87'>
+      <rect height='11' id='rect6812-2-4' style='color:#bebebe;fill:none;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible' width='14' x='21' y='281'/>
+    </clipPath>
+  </defs>
+  <g inkscape:groupmode='layer' id='layer9' inkscape:label='status' style='display:inline' transform='translate(-161,-197)'>
+    <path inkscape:connector-curvature='0' d='m 174.0002,198 c -1.10457,0 -2,0.89543 -2,2 0,1.10457 0.89543,2 2,2 1.10457,0 2,-0.89543 2,-2 0,-1.10457 -0.89543,-2 -2,-2 z m 0,1 c 0.55228,0 1,0.44771 1,1 0,0.55228 -0.44772,1 -1,1 -0.55228,0 -1,-0.44772 -1,-1 0,-0.55229 0.44772,-1 1,-1 z' id='path8169' style='opacity:0.5;color:#000000;fill:#bebebe;fill-opacity:1;stroke:none;stroke-width:1.2784189;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate'/>
+    
+    <rect height='10.012877' id='rect12283' rx='2.5' ry='2.5' style='color:#bebebe;fill:#bebebe;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible' width='5' x='164' y='197.98712'/>
+    <path clip-path='url(#clipPath6810-7-87)' inkscape:connector-curvature='0' d='m 27.96875,273.625 c -2.502477,0 -4.53125,2.02877 -4.53125,4.53125 l 0,5.8125 c 0,2.50248 2.028773,4.53125 4.53125,4.53125 2.502477,0 4.53125,-2.02877 4.53125,-4.53125 l 0,-5.8125 c 0,-2.50248 -2.028773,-4.53125 -4.53125,-4.53125 z m 0,1 c 1.964148,0 3.53125,1.5671 3.53125,3.53125 l 0,5.8125 c 0,1.96415 -1.567102,3.53125 -3.53125,3.53125 -1.964148,0 -3.53125,-1.5671 -3.53125,-3.53125 l 0,-5.8125 c 0,-1.9641 [...]
+    <path sodipodi:cx='23' sodipodi:cy='361' d='m 24,361 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z' id='path12287' sodipodi:rx='1' sodipodi:ry='1' style='color:#bebebe;fill:#bebebe;fill-opacity:1;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible' transform='matrix(0.5,0,0,0.5,151,22)' sodipodi:type='arc'/>
+    <path sodipodi:cx='23' sodipodi:cy='361' d='m 24,361 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z' id='path12289' sodipodi:rx='1' sodipodi:ry='1' style='color:#bebebe;fill:#bebebe;fill-opacity:1;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible' transform='matrix(0.5,0,0,0.5,159,22)' sodipodi:type='arc'/>
+    <path inkscape:connector-curvature='0' d='M 162.90625,211 A 1.001098,1.001098 0 1 0 163,213 l 7,0 a 1.0001,1.0001 0 1 0 0,-2 l -7,0 a 1.0001,1.0001 0 0 0 -0.0937,0 z' id='path12291' style='font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start; [...]
+    <rect height='1' id='rect12293' style='color:#bebebe;fill:#bebebe;fill-opacity:1;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible' width='9' x='162' y='212'/>
+    <rect height='4' id='rect12295' style='color:#bebebe;fill:#bebebe;fill-opacity:1;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible' width='3' x='165' y='209'/>
+    <path sodipodi:cx='-188' sodipodi:cy='184.0625' d='m -186.0625,184.0625 a 1.9375,1.9375 0 1 1 -3.875,0 1.9375,1.9375 0 1 1 3.875,0 z' id='path12275-1' sodipodi:rx='1.9375' sodipodi:ry='1.9375' style='color:#000000;fill:#bebebe;fill-opacity:1;stroke:none;stroke-width:1.2784189;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate' transform='matrix(1.0322581,0,0,1.0322551,368.06472,20.00054)' sodipodi:type='arc'/>
+    <path sodipodi:cx='-188' sodipodi:cy='184.0625' d='m -186.0625,184.0625 a 1.9375,1.9375 0 1 1 -3.875,0 1.9375,1.9375 0 1 1 3.875,0 z' id='path12321' sodipodi:rx='1.9375' sodipodi:ry='1.9375' style='color:#000000;fill:#bebebe;fill-opacity:1;stroke:none;stroke-width:1.2784189;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate' transform='matrix(1.0322581,0,0,1.0322551,368.06472,15.00054)' sodipodi:type='arc'/>
+  </g>
+  <g inkscape:groupmode='layer' id='layer10' inkscape:label='devices' style='display:inline' transform='translate(-161,-197)'/>
+  <g inkscape:groupmode='layer' id='layer11' inkscape:label='apps' transform='translate(-161,-197)'/>
+  <g inkscape:groupmode='layer' id='layer13' inkscape:label='places' style='display:inline' transform='translate(-161,-197)'/>
+  <g inkscape:groupmode='layer' id='layer14' inkscape:label='mimetypes' transform='translate(-161,-197)'/>
+  <g inkscape:groupmode='layer' id='layer15' inkscape:label='emblems' style='display:inline' transform='translate(-161,-197)'/>
+  <g inkscape:groupmode='layer' id='g71291' inkscape:label='emotes' style='display:inline' transform='translate(-161,-197)'/>
+  <g inkscape:groupmode='layer' id='g4953' inkscape:label='categories' style='display:inline' transform='translate(-161,-197)'/>
+  <g inkscape:groupmode='layer' id='layer12' inkscape:label='actions' style='display:inline' transform='translate(-161,-197)'/>
+</svg>
diff --git a/icons/scalable/status/microphone-sensitivity-muted-symbolic.svg b/icons/scalable/status/microphone-sensitivity-muted-symbolic.svg
new file mode 100644
index 0000000..1914ed3
--- /dev/null
+++ b/icons/scalable/status/microphone-sensitivity-muted-symbolic.svg
@@ -0,0 +1,45 @@
+<?xml version='1.0' encoding='UTF-8' standalone='no'?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg xmlns:cc='http://creativecommons.org/ns#' xmlns:dc='http://purl.org/dc/elements/1.1/' sodipodi:docname='microphone-sensitivity-muted-symbolic.svg' height='16.001099' id='svg7384' xmlns:inkscape='http://www.inkscape.org/namespaces/inkscape' xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#' xmlns:sodipodi='http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd' xmlns:svg='http://www.w3.org/2000/svg' inkscape:version='0.48.4 r9939' version='1.1' width='16.0002' xmlns='http://www.w3.o [...]
+  <metadata id='metadata90'>
+    <rdf:RDF>
+      <cc:Work rdf:about=''>
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type rdf:resource='http://purl.org/dc/dcmitype/StillImage'/>
+        <dc:title>Gnome Symbolic Icon Theme</dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <sodipodi:namedview inkscape:bbox-nodes='false' inkscape:bbox-paths='true' bordercolor='#666666' borderopacity='1' inkscape:current-layer='layer9' inkscape:cx='151.28401' inkscape:cy='-441.9092' gridtolerance='10' inkscape:guide-bbox='true' guidetolerance='10' id='namedview88' inkscape:object-nodes='false' inkscape:object-paths='false' objecttolerance='10' pagecolor='#3a3b39' inkscape:pageopacity='1' inkscape:pageshadow='2' showborder='false' showgrid='false' showguides='true' inkscape [...]
+    <inkscape:grid empspacing='2' enabled='true' id='grid4866' originx='120.0002px' originy='-19.998902px' snapvisiblegridlinesonly='true' spacingx='1px' spacingy='1px' type='xygrid' visible='true'/>
+    <inkscape:grid color='#000000' empcolor='#000000' empopacity='0' empspacing='4' enabled='true' id='grid5968' opacity='0.1254902' originx='120.0002px' originy='-19.998902px' snapvisiblegridlinesonly='true' spacingx='0.5px' spacingy='0.5px' type='xygrid' visible='true'/>
+  </sodipodi:namedview>
+  <title id='title9167'>Gnome Symbolic Icon Theme</title>
+  <defs id='defs7386'>
+    <clipPath clipPathUnits='userSpaceOnUse' id='clipPath6810-7-87'>
+      <rect height='11' id='rect6812-2-4' style='color:#bebebe;fill:none;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none;stroke-dashoffset:0;marker:none;visibility:visible;display:inline;overflow:visible' width='14' x='21' y='281'/>
+    </clipPath>
+  </defs>
+  <g inkscape:groupmode='layer' id='layer9' inkscape:label='status' style='display:inline' transform='translate(-121,-197)'>
+    
+    <rect height='10.012877' id='rect12235' rx='2.5' ry='2.5' style='color:#bebebe;fill:#bebebe;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible' width='5' x='124' y='197.98712'/>
+    <path clip-path='url(#clipPath6810-7-87)' inkscape:connector-curvature='0' d='m 27.96875,273.625 c -2.502477,0 -4.53125,2.02877 -4.53125,4.53125 l 0,5.8125 c 0,2.50248 2.028773,4.53125 4.53125,4.53125 2.502477,0 4.53125,-2.02877 4.53125,-4.53125 l 0,-5.8125 c 0,-2.50248 -2.028773,-4.53125 -4.53125,-4.53125 z m 0,1 c 1.964148,0 3.53125,1.5671 3.53125,3.53125 l 0,5.8125 c 0,1.96415 -1.567102,3.53125 -3.53125,3.53125 -1.964148,0 -3.53125,-1.5671 -3.53125,-3.53125 l 0,-5.8125 c 0,-1.9641 [...]
+    <path sodipodi:cx='23' sodipodi:cy='361' d='m 24,361 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z' id='path12239' sodipodi:rx='1' sodipodi:ry='1' style='color:#bebebe;fill:#bebebe;fill-opacity:1;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible' transform='matrix(0.5,0,0,0.5,111,22)' sodipodi:type='arc'/>
+    <path sodipodi:cx='23' sodipodi:cy='361' d='m 24,361 a 1,1 0 1 1 -2,0 1,1 0 1 1 2,0 z' id='path12241' sodipodi:rx='1' sodipodi:ry='1' style='color:#bebebe;fill:#bebebe;fill-opacity:1;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible' transform='matrix(0.5,0,0,0.5,119,22)' sodipodi:type='arc'/>
+    <path inkscape:connector-curvature='0' d='M 122.90625,211 A 1.001098,1.001098 0 1 0 123,213 l 7,0 a 1.0001,1.0001 0 1 0 0,-2 l -7,0 a 1.0001,1.0001 0 0 0 -0.0937,0 z' id='path12243' style='font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start; [...]
+    <rect height='1' id='rect12245' style='color:#bebebe;fill:#bebebe;fill-opacity:1;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible' width='9.0002003' x='122' y='212'/>
+    <rect height='4' id='rect12247' style='color:#bebebe;fill:#bebebe;fill-opacity:1;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible' width='3' x='125' y='209'/>
+    <path inkscape:connector-curvature='0' d='m 134.0002,197.99193 c -1.09865,0 -2.00806,0.90942 -2.00806,2.00807 0,1.09865 0.90941,2.00806 2.00806,2.00806 1.09865,0 2.00806,-0.90941 2.00806,-2.00806 0,-1.09865 -0.90941,-2.00807 -2.00806,-2.00807 z m 0,1.01613 c 0.55821,0 0.99193,0.43373 0.99193,0.99194 0,0.55821 -0.43372,0.99193 -0.99193,0.99193 -0.55821,0 -0.99193,-0.43372 -0.99193,-0.99193 0,-0.55821 0.43372,-0.99194 0.99193,-0.99194 z' id='path12249' style='font-size:medium;font-styl [...]
+    <path inkscape:connector-curvature='0' d='m 134.00019,202.99193 c -1.09865,0 -2.00806,0.90941 -2.00806,2.00806 0,1.09865 0.90941,2.00807 2.00806,2.00807 1.09865,0 2.00807,-0.90942 2.00807,-2.00807 0,-1.09865 -0.90942,-2.00806 -2.00807,-2.00806 z m 0,1.01613 c 0.55821,0 0.99194,0.43373 0.99194,0.99193 0,0.55821 -0.43373,0.99194 -0.99194,0.99194 -0.55821,0 -0.99193,-0.43373 -0.99193,-0.99194 0,-0.5582 0.43372,-0.99193 0.99193,-0.99193 z' id='path12253' style='font-size:medium;font-styl [...]
+    <path inkscape:connector-curvature='0' d='m 132.0002,208 1.375,0 1.125,1.09375 1.09375,-1.09375 1.40625,0 0,1.46875 -1.09375,1.0625 1.09375,1.0625 0,1.40625 -1.4375,0 -1.0625,-1.0625 -1.0625,1.0625 -1.4375,0 0,-1.40625 1.0625,-1.0625 -1.0625,-1.0625 0,-1.46875 z' id='path3761-2-3-5-4-8-9-8-0-9-0-4' sodipodi:nodetypes='ccccccccccccccccc' style='color:#bebebe;fill:#bebebe;fill-opacity:1;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible'/>
+  </g>
+  <g inkscape:groupmode='layer' id='layer10' inkscape:label='devices' style='display:inline' transform='translate(-121,-197)'/>
+  <g inkscape:groupmode='layer' id='layer11' inkscape:label='apps' transform='translate(-121,-197)'/>
+  <g inkscape:groupmode='layer' id='layer13' inkscape:label='places' style='display:inline' transform='translate(-121,-197)'/>
+  <g inkscape:groupmode='layer' id='layer14' inkscape:label='mimetypes' transform='translate(-121,-197)'/>
+  <g inkscape:groupmode='layer' id='layer15' inkscape:label='emblems' style='display:inline' transform='translate(-121,-197)'/>
+  <g inkscape:groupmode='layer' id='g71291' inkscape:label='emotes' style='display:inline' transform='translate(-121,-197)'/>
+  <g inkscape:groupmode='layer' id='g4953' inkscape:label='categories' style='display:inline' transform='translate(-121,-197)'/>
+  <g inkscape:groupmode='layer' id='layer12' inkscape:label='actions' style='display:inline' transform='translate(-121,-197)'/>
+</svg>
diff --git a/panel-plugin/pulseaudio-notify.c b/panel-plugin/pulseaudio-notify.c
index efc6f27..d4caad3 100644
--- a/panel-plugin/pulseaudio-notify.c
+++ b/panel-plugin/pulseaudio-notify.c
@@ -59,6 +59,16 @@ static const char *icons[] = {
 };
 
 
+/* Icons for different mic volume levels */
+static const char *icons_mic[] = {
+  "microphone-sensitivity-muted-symbolic",
+  "microphone-sensitivity-low-symbolic",
+  "microphone-sensitivity-medium-symbolic",
+  "microphone-sensitivity-high-symbolic",
+  NULL
+};
+
+
 static void                 pulseaudio_notify_finalize        (GObject            *object);
 
 
@@ -72,8 +82,10 @@ struct _PulseaudioNotify
 
   gboolean              gauge_notifications;
   NotifyNotification   *notification;
+  NotifyNotification   *notification_mic;
 
   gulong                volume_changed_id;
+  gulong                volume_mic_changed_id;
 };
 
 struct _PulseaudioNotifyClass
@@ -105,7 +117,9 @@ pulseaudio_notify_init (PulseaudioNotify *notify)
 
   notify->gauge_notifications = TRUE;
   notify->notification = NULL;
+  notify->notification_mic = NULL;
   notify->volume_changed_id = 0;
+  notify->volume_mic_changed_id = 0;
 
   //g_set_application_name ("Xfce volume control");
   notify_init ("Xfce volume control");
@@ -124,6 +138,8 @@ pulseaudio_notify_init (PulseaudioNotify *notify)
     }
   notify->notification = notify_notification_new ("xfce4-pulseaudio-plugin", NULL, NULL);
   notify_notification_set_timeout (notify->notification, 2000);
+  notify->notification_mic = notify_notification_new ("xfce4-pulseaudio-plugin", NULL, NULL);
+  notify_notification_set_timeout (notify->notification_mic, 2000);
 }
 
 
@@ -137,6 +153,8 @@ pulseaudio_notify_finalize (GObject *object)
 
   g_object_unref (G_OBJECT (notify->notification));
   notify->notification = NULL;
+  g_object_unref (G_OBJECT (notify->notification_mic));
+  notify->notification_mic = NULL;
   notify_uninit ();
 
   (*G_OBJECT_CLASS (pulseaudio_notify_parent_class)->finalize) (object);
@@ -145,15 +163,17 @@ pulseaudio_notify_finalize (GObject *object)
 
 
 static void
-pulseaudio_notify_notify (PulseaudioNotify *notify)
+pulseaudio_notify_notify (PulseaudioNotify *notify, gboolean mic)
 {
-  GError      *error = NULL;
-  gdouble      volume;
-  gint         volume_i;
-  gboolean     muted;
-  gboolean     connected;
-  gchar       *title = NULL;
-  const gchar *icon = NULL;
+  GError             *error = NULL;
+  NotifyNotification *notification;
+  gdouble             volume;
+  gint                volume_i;
+  gboolean            muted;
+  gboolean            connected;
+  gchar              *title = NULL;
+  const char        **icons_array;
+  const gchar        *icon = NULL;
 
   g_return_if_fail (IS_PULSEAUDIO_NOTIFY (notify));
   g_return_if_fail (IS_PULSEAUDIO_VOLUME (notify->volume));
@@ -162,8 +182,11 @@ pulseaudio_notify_notify (PulseaudioNotify *notify)
       pulseaudio_button_get_menu (notify->button) != NULL)
     return;
 
-  volume = pulseaudio_volume_get_volume (notify->volume);
-  muted = pulseaudio_volume_get_muted (notify->volume);
+  notification = mic ? notify->notification_mic : notify->notification;
+  icons_array = mic ? icons_mic : icons;
+
+  volume = (mic ? pulseaudio_volume_get_volume_mic : pulseaudio_volume_get_volume) (notify->volume);
+  muted = (mic ? pulseaudio_volume_get_muted_mic : pulseaudio_volume_get_muted) (notify->volume);
   connected = pulseaudio_volume_get_connected (notify->volume);
   volume_i = (gint) round (volume * 100);
 
@@ -178,35 +201,35 @@ pulseaudio_notify_notify (PulseaudioNotify *notify)
     title = g_strdup_printf ( _("Volume %d%c"), volume_i, '%');
 
   if (!connected)
-    icon = icons[V_MUTED];
+    icon = icons_array[V_MUTED];
   else if (muted)
-    icon = icons[V_MUTED];
+    icon = icons_array[V_MUTED];
   else if (volume <= 0.0)
-    icon = icons[V_MUTED];
+    icon = icons_array[V_MUTED];
   else if (volume <= 0.3)
-    icon = icons[V_LOW];
+    icon = icons_array[V_LOW];
   else if (volume <= 0.7)
-    icon = icons[V_MEDIUM];
+    icon = icons_array[V_MEDIUM];
   else
-    icon = icons[V_HIGH];
+    icon = icons_array[V_HIGH];
 
 
-  notify_notification_update (notify->notification,
+  notify_notification_update (notification,
                               title,
                               NULL,
                               icon);
   g_free (title);
 
   if (notify->gauge_notifications) {
-    notify_notification_set_hint_int32 (notify->notification,
+    notify_notification_set_hint_int32 (notification,
                                         "value",
                                         volume_i);
-    notify_notification_set_hint_string (notify->notification,
+    notify_notification_set_hint_string (notification,
                                          "x-canonical-private-synchronous",
                                          "");
   }
 
-  if (!notify_notification_show (notify->notification, &error))
+  if (!notify_notification_show (notification, &error))
     {
       g_warning ("Error while sending notification : %s\n", error->message);
       g_error_free (error);
@@ -223,7 +246,20 @@ pulseaudio_notify_volume_changed (PulseaudioNotify  *notify,
   g_return_if_fail (IS_PULSEAUDIO_NOTIFY (notify));
 
   if (should_notify)
-    pulseaudio_notify_notify (notify);
+    pulseaudio_notify_notify (notify, FALSE);
+}
+
+
+
+static void
+pulseaudio_notify_volume_mic_changed (PulseaudioNotify  *notify,
+                                      gboolean           should_notify,
+                                      PulseaudioVolume  *volume)
+{
+  g_return_if_fail (IS_PULSEAUDIO_NOTIFY (notify));
+
+  if (should_notify)
+    pulseaudio_notify_notify (notify, TRUE);
 }
 
 
@@ -247,6 +283,9 @@ pulseaudio_notify_new (PulseaudioConfig *config,
   notify->volume_changed_id =
     g_signal_connect_swapped (G_OBJECT (notify->volume), "volume-changed",
                               G_CALLBACK (pulseaudio_notify_volume_changed), notify);
+  notify->volume_changed_id =
+    g_signal_connect_swapped (G_OBJECT (notify->volume), "volume-mic-changed",
+                              G_CALLBACK (pulseaudio_notify_volume_mic_changed), notify);
 
   return notify;
 }
diff --git a/panel-plugin/pulseaudio-plugin.c b/panel-plugin/pulseaudio-plugin.c
index 7e80050..ff2c254 100644
--- a/panel-plugin/pulseaudio-plugin.c
+++ b/panel-plugin/pulseaudio-plugin.c
@@ -54,6 +54,7 @@
 #define PULSEAUDIO_PLUGIN_RAISE_VOLUME_KEY  "XF86AudioRaiseVolume"
 #define PULSEAUDIO_PLUGIN_LOWER_VOLUME_KEY  "XF86AudioLowerVolume"
 #define PULSEAUDIO_PLUGIN_MUTE_KEY          "XF86AudioMute"
+#define PULSEAUDIO_PLUGIN_MIC_MUTE_KEY      "XF86AudioMicMute"
 #endif
 
 
@@ -76,6 +77,8 @@ static void             pulseaudio_plugin_volume_key_pressed               (cons
                                                                             void                  *user_data);
 static void             pulseaudio_plugin_mute_pressed                     (const char            *keystring,
                                                                             void                  *user_data);
+static void             pulseaudio_plugin_mic_mute_pressed                 (const char            *keystring,
+                                                                            void                  *user_data);
 #endif
 
 struct _PulseaudioPluginClass
@@ -277,7 +280,8 @@ pulseaudio_plugin_bind_keys (PulseaudioPlugin      *pulseaudio_plugin)
 
   success = (keybinder_bind (PULSEAUDIO_PLUGIN_LOWER_VOLUME_KEY, pulseaudio_plugin_volume_key_pressed, pulseaudio_plugin) &&
              keybinder_bind (PULSEAUDIO_PLUGIN_RAISE_VOLUME_KEY, pulseaudio_plugin_volume_key_pressed, pulseaudio_plugin) &&
-             keybinder_bind (PULSEAUDIO_PLUGIN_MUTE_KEY, pulseaudio_plugin_mute_pressed, pulseaudio_plugin));
+             keybinder_bind (PULSEAUDIO_PLUGIN_MUTE_KEY, pulseaudio_plugin_mute_pressed, pulseaudio_plugin) &&
+             keybinder_bind (PULSEAUDIO_PLUGIN_MIC_MUTE_KEY, pulseaudio_plugin_mic_mute_pressed, pulseaudio_plugin));
 
   if (!success)
     g_warning ("Could not have grabbed volume control keys. Is another volume control application (xfce4-volumed) running?");
@@ -295,6 +299,7 @@ pulseaudio_plugin_unbind_keys (PulseaudioPlugin      *pulseaudio_plugin)
   keybinder_unbind (PULSEAUDIO_PLUGIN_LOWER_VOLUME_KEY, pulseaudio_plugin_volume_key_pressed);
   keybinder_unbind (PULSEAUDIO_PLUGIN_RAISE_VOLUME_KEY, pulseaudio_plugin_volume_key_pressed);
   keybinder_unbind (PULSEAUDIO_PLUGIN_MUTE_KEY, pulseaudio_plugin_mute_pressed);
+  keybinder_unbind (PULSEAUDIO_PLUGIN_MIC_MUTE_KEY, pulseaudio_plugin_mic_mute_pressed);
 }
 
 
@@ -325,6 +330,18 @@ pulseaudio_plugin_mute_pressed (const char            *keystring,
 
   pulseaudio_volume_toggle_muted (pulseaudio_plugin->volume);
 }
+
+
+static void
+pulseaudio_plugin_mic_mute_pressed (const char            *keystring,
+                                    void                  *user_data)
+{
+  PulseaudioPlugin *pulseaudio_plugin = PULSEAUDIO_PLUGIN (user_data);
+
+  pulseaudio_debug ("%s pressed", keystring);
+
+  pulseaudio_volume_toggle_muted_mic (pulseaudio_plugin->volume);
+}
 #endif
 
 
diff --git a/panel-plugin/pulseaudio-volume.c b/panel-plugin/pulseaudio-volume.c
index d0fa246..ac8624b 100644
--- a/panel-plugin/pulseaudio-volume.c
+++ b/panel-plugin/pulseaudio-volume.c
@@ -76,6 +76,7 @@ struct _PulseaudioVolumeClass
 enum
 {
   VOLUME_CHANGED,
+  VOLUME_MIC_CHANGED,
   LAST_SIGNAL
 };
 
@@ -102,6 +103,14 @@ pulseaudio_volume_class_init (PulseaudioVolumeClass *klass)
                   g_cclosure_marshal_VOID__BOOLEAN,
                   G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
 
+  pulseaudio_volume_signals[VOLUME_MIC_CHANGED] =
+    g_signal_new (g_intern_static_string ("volume-mic-changed"),
+                  G_TYPE_FROM_CLASS (gobject_class),
+                  G_SIGNAL_RUN_LAST,
+                  0, NULL, NULL,
+                  g_cclosure_marshal_VOID__BOOLEAN,
+                  G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
+
 }
 
 
@@ -112,6 +121,8 @@ pulseaudio_volume_init (PulseaudioVolume *volume)
   volume->connected = FALSE;
   volume->volume = 0.0;
   volume->muted = FALSE;
+  volume->volume_mic = 0.0;
+  volume->muted_mic = FALSE;
   volume->reconnect_timer_id = 0;
 
   volume->pa_mainloop = pa_glib_mainloop_new (NULL);
@@ -171,6 +182,41 @@ pulseaudio_volume_sink_info_cb (pa_context         *context,
 
 
 
+
+static void
+pulseaudio_volume_source_info_cb (pa_context           *context,
+                                  const pa_source_info *i,
+                                  int                   eol,
+                                  void                 *userdata)
+{
+  gboolean  muted_mic;
+  gdouble   vol_mic;
+
+  PulseaudioVolume *volume = PULSEAUDIO_VOLUME (userdata);
+  if (i == NULL) return;
+  pulseaudio_debug ("source info: %s, %s", i->name, i->description);
+
+  muted_mic = !!(i->mute);
+  vol_mic = pulseaudio_volume_v2d (volume, i->volume.values[0]);
+
+  if (volume->muted_mic != muted_mic)
+    {
+      pulseaudio_debug ("Updated Mute Mic: %d -> %d", volume->muted_mic, muted_mic);
+      volume->muted_mic = muted_mic;
+      g_signal_emit (G_OBJECT (volume), pulseaudio_volume_signals [VOLUME_MIC_CHANGED], 0, FALSE);
+    }
+
+  if (ABS (volume->volume_mic - vol_mic) > 2e-3)
+    {
+      pulseaudio_debug ("Updated Volume Mic: %04.3f -> %04.3f", volume->volume_mic, vol_mic);
+      volume->volume_mic = vol_mic;
+      g_signal_emit (G_OBJECT (volume), pulseaudio_volume_signals [VOLUME_MIC_CHANGED], 0, FALSE);
+    }
+  pulseaudio_debug ("volume mic: %d, muted mic: %d", vol_mic, muted_mic);
+}
+
+
+
 static void
 pulseaudio_volume_server_info_cb (pa_context           *context,
                                   const pa_server_info *i,
@@ -181,14 +227,15 @@ pulseaudio_volume_server_info_cb (pa_context           *context,
 
   pulseaudio_debug ("server: %s@%s, v.%s", i->user_name, i->server_name, i->server_version);
   pa_context_get_sink_info_by_name (context, i->default_sink_name, pulseaudio_volume_sink_info_cb, volume);
+  pa_context_get_source_info_by_name (context, i->default_source_name, pulseaudio_volume_source_info_cb, volume);
 }
 
 
 
 
 static void
-pulseaudio_volume_sink_check (PulseaudioVolume *volume,
-                              pa_context       *context)
+pulseaudio_volume_sink_source_check (PulseaudioVolume *volume,
+                                     pa_context       *context)
 {
   g_return_if_fail (IS_PULSEAUDIO_VOLUME (volume));
 
@@ -209,11 +256,12 @@ pulseaudio_volume_subscribe_cb (pa_context                   *context,
   switch (t & PA_SUBSCRIPTION_EVENT_FACILITY_MASK)
     {
     case PA_SUBSCRIPTION_EVENT_SINK          :
-      pulseaudio_volume_sink_check (volume, context);
+      pulseaudio_volume_sink_source_check (volume, context);
       pulseaudio_debug ("received sink event");
       break;
 
     case PA_SUBSCRIPTION_EVENT_SOURCE        :
+      pulseaudio_volume_sink_source_check (volume, context);
       pulseaudio_debug ("received source event");
       break;
 
@@ -222,7 +270,7 @@ pulseaudio_volume_subscribe_cb (pa_context                   *context,
       break;
 
     case PA_SUBSCRIPTION_EVENT_SERVER        :
-      pulseaudio_volume_sink_check (volume, context);
+      pulseaudio_volume_sink_source_check (volume, context);
       pulseaudio_debug ("received server event");
       break;
 
@@ -249,9 +297,10 @@ pulseaudio_volume_context_state_cb (pa_context *context,
 
       pulseaudio_debug ("PulseAudio connection established");
       volume->connected = TRUE;
-      // Check current sink volume manually. PA sink events usually not emitted.
-      pulseaudio_volume_sink_check (volume, context);
+      // Check current sink and source volume manually. PA sink events usually not emitted.
+      pulseaudio_volume_sink_source_check (volume, context);
       g_signal_emit (G_OBJECT (volume), pulseaudio_volume_signals [VOLUME_CHANGED], 0, FALSE);
+      g_signal_emit (G_OBJECT (volume), pulseaudio_volume_signals [VOLUME_MIC_CHANGED], 0, FALSE);
       break;
 
     case PA_CONTEXT_FAILED       :
@@ -261,7 +310,10 @@ pulseaudio_volume_context_state_cb (pa_context *context,
       volume->connected = FALSE;
       volume->volume = 0.0;
       volume->muted = FALSE;
+      volume->volume_mic = 0.0;
+      volume->muted_mic = FALSE;
       g_signal_emit (G_OBJECT (volume), pulseaudio_volume_signals [VOLUME_CHANGED], 0, FALSE);
+      g_signal_emit (G_OBJECT (volume), pulseaudio_volume_signals [VOLUME_MIC_CHANGED], 0, FALSE);
       if (volume->reconnect_timer_id == 0)
         volume->reconnect_timer_id = g_timeout_add_seconds
           (5, pulseaudio_volume_reconnect_timeout, volume);
@@ -406,6 +458,8 @@ pulseaudio_volume_sink_volume_changed (pa_context *context,
     g_signal_emit (G_OBJECT (volume), pulseaudio_volume_signals [VOLUME_CHANGED], 0, TRUE);
 }
 
+
+
 /* mute setting callbacks */
 /* pa_sink_info_cb_t */
 static void
@@ -450,6 +504,74 @@ pulseaudio_volume_toggle_muted (PulseaudioVolume *volume)
 
 
 
+gboolean
+pulseaudio_volume_get_muted_mic (PulseaudioVolume *volume)
+{
+  g_return_val_if_fail (IS_PULSEAUDIO_VOLUME (volume), FALSE);
+
+  return volume->muted_mic;
+}
+
+
+
+/* final callback for mic volume/mute changes */
+/* pa_context_success_cb_t */
+static void
+pulseaudio_volume_source_volume_changed (pa_context *context,
+                                         int         success,
+                                         void       *userdata)
+{
+  PulseaudioVolume *volume = PULSEAUDIO_VOLUME (userdata);
+
+  if (success)
+    g_signal_emit (G_OBJECT (volume), pulseaudio_volume_signals [VOLUME_MIC_CHANGED], 0, TRUE);
+}
+
+
+
+/* mute setting callbacks */
+/* pa_source_info_cb_t */
+static void
+pulseaudio_volume_set_muted_mic_cb1 (pa_context           *context,
+                                     const pa_source_info *i,
+                                     int                   eol,
+                                     void                 *userdata)
+{
+  PulseaudioVolume *volume = PULSEAUDIO_VOLUME (userdata);
+  if (i == NULL) return;
+
+  pa_context_set_source_mute_by_index (context, i->index, volume->muted_mic, pulseaudio_volume_source_volume_changed, volume);
+}
+
+
+
+void
+pulseaudio_volume_set_muted_mic (PulseaudioVolume *volume,
+                                 gboolean          muted_mic)
+{
+  g_return_if_fail (IS_PULSEAUDIO_VOLUME (volume));
+  g_return_if_fail (volume->pa_context != NULL);
+  g_return_if_fail (pa_context_get_state (volume->pa_context) == PA_CONTEXT_READY);
+
+  if (volume->muted_mic != muted_mic)
+    {
+      volume->muted_mic = muted_mic;
+      pa_context_get_source_info_list (volume->pa_context, pulseaudio_volume_set_muted_mic_cb1, volume);
+    }
+}
+
+
+
+void
+pulseaudio_volume_toggle_muted_mic (PulseaudioVolume *volume)
+{
+  g_return_if_fail (IS_PULSEAUDIO_VOLUME (volume));
+
+  pulseaudio_volume_set_muted_mic (volume, !volume->muted_mic);
+}
+
+
+
 gdouble
 pulseaudio_volume_get_volume (PulseaudioVolume *volume)
 {
@@ -516,6 +638,16 @@ pulseaudio_volume_set_volume (PulseaudioVolume *volume,
 
 
 
+gdouble
+pulseaudio_volume_get_volume_mic (PulseaudioVolume *volume)
+{
+  g_return_val_if_fail (IS_PULSEAUDIO_VOLUME (volume), 0.0);
+
+  return volume->volume_mic;
+}
+
+
+
 PulseaudioVolume *
 pulseaudio_volume_new (PulseaudioConfig *config)
 {
diff --git a/panel-plugin/pulseaudio-volume.h b/panel-plugin/pulseaudio-volume.h
index 3c6397e..d8799b0 100644
--- a/panel-plugin/pulseaudio-volume.h
+++ b/panel-plugin/pulseaudio-volume.h
@@ -30,23 +30,30 @@ G_BEGIN_DECLS
 #define IS_PULSEAUDIO_VOLUME_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass),  TYPE_PULSEAUDIO_VOLUME))
 #define PULSEAUDIO_VOLUME_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj),  TYPE_PULSEAUDIO_VOLUME, PulseaudioVolumeClass))
 
-typedef struct          _PulseaudioVolume                 PulseaudioVolume;
-typedef struct          _PulseaudioVolumeClass            PulseaudioVolumeClass;
+typedef struct          _PulseaudioVolume                         PulseaudioVolume;
+typedef struct          _PulseaudioVolumeClass                    PulseaudioVolumeClass;
 
-GType                   pulseaudio_volume_get_type        (void) G_GNUC_CONST;
+GType                   pulseaudio_volume_get_type                (void) G_GNUC_CONST;
 
-PulseaudioVolume       *pulseaudio_volume_new             (PulseaudioConfig *config);
+PulseaudioVolume       *pulseaudio_volume_new                     (PulseaudioConfig *config);
 
-gboolean                pulseaudio_volume_get_connected   (PulseaudioVolume *volume);
+gboolean                pulseaudio_volume_get_connected           (PulseaudioVolume *volume);
 
-gdouble                 pulseaudio_volume_get_volume      (PulseaudioVolume *volume);
-void                    pulseaudio_volume_set_volume      (PulseaudioVolume *volume,
-                                                           gdouble           vol);
+gdouble                 pulseaudio_volume_get_volume              (PulseaudioVolume *volume);
+void                    pulseaudio_volume_set_volume              (PulseaudioVolume *volume,
+                                                                   gdouble           vol);
 
-gboolean                pulseaudio_volume_get_muted       (PulseaudioVolume *volume);
-void                    pulseaudio_volume_set_muted       (PulseaudioVolume *volume,
-                                                           gboolean          muted);
-void                    pulseaudio_volume_toggle_muted    (PulseaudioVolume *volume);
+gboolean                pulseaudio_volume_get_muted               (PulseaudioVolume *volume);
+void                    pulseaudio_volume_set_muted               (PulseaudioVolume *volume,
+                                                                   gboolean          muted);
+void                    pulseaudio_volume_toggle_muted            (PulseaudioVolume *volume);
+
+gdouble                 pulseaudio_volume_get_volume_mic          (PulseaudioVolume *volume);
+
+gboolean                pulseaudio_volume_get_muted_mic           (PulseaudioVolume *volume);
+void                    pulseaudio_volume_set_muted_mic           (PulseaudioVolume *volume,
+                                                                   gboolean          mic_muted);
+void                    pulseaudio_volume_toggle_muted_mic        (PulseaudioVolume *volume);
 
 G_END_DECLS
 

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the Xfce4-commits mailing list