aboutsummarylogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Göbel2015-09-26 18:57:59 +0200
committerStefan Göbel2015-09-26 18:57:59 +0200
commitd7c5d84fa3706e962007ed6c26c6ae5a8fdf3b30 (patch)
tree65c30a027e96f5f729e2347849e53bc2d72ccca8
downloadaur-d7c5d84fa3706e962007ed6c26c6ae5a8fdf3b30.tar.gz
Initial commit
-rw-r--r--.SRCINFO37
-rw-r--r--01-mss-fix-args.diff19
-rw-r--r--02-mws-inline.diff11
-rw-r--r--03-mws-fix-args.diff29
-rw-r--r--04-mws-sleep-arg.diff73
-rw-r--r--PKGBUILD69
-rw-r--r--README4
-rw-r--r--README.icons26
-rwxr-xr-xmouse-wrapscreen-tray149
-rw-r--r--mouse-wrapscreen-tray.desktop12
-rw-r--r--running.svg54
-rw-r--r--stopped.svg54
12 files changed, 537 insertions, 0 deletions
diff --git a/.SRCINFO b/.SRCINFO
new file mode 100644
index 000000000000..8691c68fe504
--- /dev/null
+++ b/.SRCINFO
@@ -0,0 +1,37 @@
+pkgbase = dualscreen-mouse-utils
+ pkgdesc = Utilities for use with old-school dual head setups.
+ pkgver = 0.5
+ pkgrel = 1
+ url = http://de.mcbf.net/david/dualscreenmouseutils/
+ arch = i686
+ arch = x86_64
+ license = GPL2
+ license = GPL3
+ license = LGPL3
+ license = CCPL:by-nc-sa
+ depends = libx11
+ optdepends = python-pyqt5: for mouse-wrapscreen-tray (system tray icon)
+ optdepends = python-psutil: for mouse-wrapscreen-tray (system tray icon)
+ source = http://dsp.mcbf.net/releases/dualscreen-mouse-utils-0.5.tar.gz
+ source = 01-mss-fix-args.diff
+ source = 02-mws-inline.diff
+ source = 03-mws-fix-args.diff
+ source = 04-mws-sleep-arg.diff
+ source = mouse-wrapscreen-tray
+ source = mouse-wrapscreen-tray.desktop
+ source = README.icons
+ source = running.svg
+ source = stopped.svg
+ md5sums = b68a43c9041cbb8dc373553ccef93070
+ md5sums = dc203cc98b15bdaf7453c21e76e87a41
+ md5sums = eb95a8830324f0d2d3249f6802b7e666
+ md5sums = 0294b640ae8daf006c209fb14954c282
+ md5sums = e5ebb5eef015695ee3d533bd5de24180
+ md5sums = b2ba6403fa7dfbe2b1a7f4f945030e7d
+ md5sums = 5b2ebb17e8bc7c833d0c772d2d986bc3
+ md5sums = 5f1b6249af6ad454f950d27ff1dcc533
+ md5sums = 4bca9dc0dcf3fdbbff094b8f83cdee08
+ md5sums = a7b6529cdbd3010c40818c204458b734
+
+pkgname = dualscreen-mouse-utils
+
diff --git a/01-mss-fix-args.diff b/01-mss-fix-args.diff
new file mode 100644
index 000000000000..66571a623f58
--- /dev/null
+++ b/01-mss-fix-args.diff
@@ -0,0 +1,19 @@
+--- mouse-switchscreen.c 2009-05-18 06:42:54.000000000 +0200
++++ mouse-switchscreen.c 2015-09-17 16:34:38.140015233 +0200
+@@ -140,6 +140,7 @@
+ "\t-V, --version Print version and exit\n"
+ "\t-v, --verbose Print some information about what is being done\n"
+ "\t-h, --help Print this help text and exit\n"
++ "\t-s, --screen=# Number of the screen to switch to\n"
+ "\t-f, --focus-button=# Simulate a press and release of the given mouse button.\n"
+ "\t\tIntended to allow the program to focus on the new screen once the mouse has been moved.\n"
+ "\t\tValid focus buttons are positive integers.\n"
+@@ -163,7 +164,7 @@
+ char c;
+ verbose = 0;
+
+- while ((c = getopt_long(argc, argv, "f:hvVs", long_options, NULL)) != -1)
++ while ((c = getopt_long(argc, argv, "f:hvVs:", long_options, NULL)) != -1)
+ {
+ switch (c)
+ {
diff --git a/02-mws-inline.diff b/02-mws-inline.diff
new file mode 100644
index 000000000000..9b075c93b03d
--- /dev/null
+++ b/02-mws-inline.diff
@@ -0,0 +1,11 @@
+--- mouse-wrapscreen.c 2015-09-13 16:15:51.696161977 +0200
++++ mouse-wrapscreen.c 2015-09-13 16:15:59.864140353 +0200
+@@ -67,7 +67,7 @@
+ #define VERSION "0.5"
+ #define DEFAULT_RESISTANCE 15
+
+-inline int
++static inline int
+ getOtherScreen (int screen)
+ {
+ return 1 - screen;
diff --git a/03-mws-fix-args.diff b/03-mws-fix-args.diff
new file mode 100644
index 000000000000..8e879ae8454d
--- /dev/null
+++ b/03-mws-fix-args.diff
@@ -0,0 +1,29 @@
+--- mouse-wrapscreen.c 2009-05-18 06:42:54.000000000 +0200
++++ mouse-wrapscreen.c 2015-09-17 16:10:29.917729010 +0200
+@@ -75,7 +75,7 @@
+
+ static struct option const long_options[] = {
+ {"help", 0, NULL, 'h'},
+- {"resistance", no_argument, NULL, 'r'},
++ {"resistance", required_argument, NULL, 'r'},
+ {"version", no_argument, NULL, 'V'},
+ {"verbose", no_argument, NULL, 'v'},
+ {"left", no_argument, NULL, 'l'},
+@@ -118,7 +118,7 @@
+ int left = 1;
+ int right = 1;
+
+- while ((c = getopt_long (argc, argv, "r:hvlib", long_options, NULL)) != -1) {
++ while ((c = getopt_long (argc, argv, "r:hvVlib", long_options, NULL)) != -1) {
+ switch (c) {
+ case 'h':
+ usage (argv);
+@@ -130,7 +130,7 @@
+ break;
+ case 'r':
+ resistance = atoi (optarg);
+- if (resistance <= 1) {
++ if (resistance < 1) {
+ fprintf (stderr, PRINT_PREFIX "Edge resistance must be greater or equal to one\n");
+ usage (argv);
+ return 1;
diff --git a/04-mws-sleep-arg.diff b/04-mws-sleep-arg.diff
new file mode 100644
index 000000000000..900f6d818436
--- /dev/null
+++ b/04-mws-sleep-arg.diff
@@ -0,0 +1,73 @@
+--- mouse-wrapscreen.c 2015-09-17 16:57:57.563217953 +0200
++++ mouse-wrapscreen.c 2015-09-17 16:58:08.797179507 +0200
+@@ -66,6 +66,7 @@
+ #define PRINT_PREFIX PROG_NAME ": "
+ #define VERSION "0.5"
+ #define DEFAULT_RESISTANCE 15
++#define DEFAULT_SLEEP 1000
+
+ static inline int
+ getOtherScreen (int screen)
+@@ -81,6 +82,7 @@
+ {"left", no_argument, NULL, 'l'},
+ {"right", no_argument, NULL, 'i'},
+ {"both", no_argument, NULL, 'b'},
++ {"sleep", required_argument, NULL, 's'},
+ {NULL, 0, NULL, 0}
+ };
+
+@@ -92,6 +94,8 @@
+ " -r, --resistance=R Mouse pointer has an edge resistance of R when cross-,\n"
+ " ing from one screen to the other (%d is the default,\n"
+ " 1 will make the mouse pass over right away)\n"
++ " -s, --sleep=S Sleep that many microseconds between position checks.\n"
++ " The default value is %d.\n"
+ " -v, --verbose Print some information about what is being done\n"
+ " Can be specified twice for even more outputd\n"
+ " -h, --help Print this help text and exit\n"
+@@ -101,7 +105,7 @@
+ " -l, --left Screen 1 is left of screen 0\n"
+ " -i, --right Screen 1 is rigt of screen 0\n"
+ " -b, --both Pass cursor on both the left and the right edge\n"
+- " (default)\n", argv[0], DEFAULT_RESISTANCE);
++ " (default)\n", argv[0], DEFAULT_RESISTANCE, DEFAULT_SLEEP);
+ }
+
+ int
+@@ -117,8 +121,9 @@
+ int verbose = 0;
+ int left = 1;
+ int right = 1;
++ int sleep_us = DEFAULT_SLEEP;
+
+- while ((c = getopt_long (argc, argv, "r:hvVlib", long_options, NULL)) != -1) {
++ while ((c = getopt_long (argc, argv, "r:s:hvVlib", long_options, NULL)) != -1) {
+ switch (c) {
+ case 'h':
+ usage (argv);
+@@ -136,6 +141,14 @@
+ return 1;
+ }
+ break;
++ case 's':
++ sleep_us = atoi (optarg);
++ if (sleep_us < 1) {
++ fprintf (stderr, PRINT_PREFIX "Sleep value must be greater or equal to one\n");
++ usage (argv);
++ return 1;
++ }
++ break;
+ case 'v':
+ verbose++;
+ break;
+@@ -278,8 +291,8 @@
+ modif = 0;
+ }
+
+- //sleeps for 1ms
+- usleep (1000);
++ // sleeps for 1ms (default) or as specified on the command line:
++ usleep (sleep_us);
+
+ // reset gets triggered when we see an unrelated event
+ if (reset)
diff --git a/PKGBUILD b/PKGBUILD
new file mode 100644
index 000000000000..2fe96265d3f5
--- /dev/null
+++ b/PKGBUILD
@@ -0,0 +1,69 @@
+# Maintainer: Stefan Göbel <aur —at— subtype —dot— de>
+
+pkgname='dualscreen-mouse-utils'
+pkgver='0.5'
+pkgrel='1'
+pkgdesc='Utilities for use with old-school dual head setups.'
+arch=('i686' 'x86_64')
+url='http://de.mcbf.net/david/dualscreenmouseutils/'
+license=('GPL2' 'GPL3' 'LGPL3' 'CCPL:by-nc-sa')
+depends=('libx11')
+optdepends=(
+ 'python-pyqt5: for mouse-wrapscreen-tray (system tray icon)'
+ 'python-psutil: for mouse-wrapscreen-tray (system tray icon)'
+)
+source=(
+ "http://dsp.mcbf.net/releases/$pkgname-$pkgver.tar.gz"
+ '01-mss-fix-args.diff'
+ '02-mws-inline.diff'
+ '03-mws-fix-args.diff'
+ '04-mws-sleep-arg.diff'
+ 'mouse-wrapscreen-tray'
+ 'mouse-wrapscreen-tray.desktop'
+ 'README.icons'
+ 'running.svg'
+ 'stopped.svg'
+)
+md5sums=(
+ 'b68a43c9041cbb8dc373553ccef93070'
+ 'dc203cc98b15bdaf7453c21e76e87a41'
+ 'eb95a8830324f0d2d3249f6802b7e666'
+ '0294b640ae8daf006c209fb14954c282'
+ 'e5ebb5eef015695ee3d533bd5de24180'
+ 'b2ba6403fa7dfbe2b1a7f4f945030e7d'
+ '5b2ebb17e8bc7c833d0c772d2d986bc3'
+ '5f1b6249af6ad454f950d27ff1dcc533'
+ '4bca9dc0dcf3fdbbff094b8f83cdee08'
+ 'a7b6529cdbd3010c40818c204458b734'
+)
+
+prepare() {
+ cd "$pkgname-$pkgver"
+ for diff in ../*.diff ; do
+ patch -uN -i "$diff" || return 1
+ done
+}
+
+build() {
+ cd "$pkgname-$pkgver"
+ CPPFLAGS="$CFLAGS -O2" make
+}
+
+package() {
+
+ install -d "$pkgdir"/usr/{bin,share/{dualscreen-mouse-utils,applications}}/
+
+ install -m 0755 mouse-wrapscreen-tray "$pkgdir/usr/bin/mouse-wrapscreen-tray"
+ install -m 0644 mouse-wrapscreen-tray.desktop "$pkgdir/usr/share/applications/"
+ install -m 0644 README.icons "$pkgdir/usr/share/dualscreen-mouse-utils/"
+ install -m 0644 {running,stopped}.svg "$pkgdir/usr/share/dualscreen-mouse-utils/"
+
+ cd "$pkgname-$pkgver"
+
+ install -m 0755 -s mouse-{switch,wrap}screen "$pkgdir/usr/bin/"
+ install -m 0755 mouse-wrapscreen.sh "$pkgdir/usr/share/dualscreen-mouse-utils/"
+ install -m 0644 README "$pkgdir/usr/share/dualscreen-mouse-utils/"
+
+}
+
+#:indentSize=3:tabSize=3:noTabs=true:mode=shellscript:maxLineLen=93: \ No newline at end of file
diff --git a/README b/README
new file mode 100644
index 000000000000..d42cbd35fdbe
--- /dev/null
+++ b/README
@@ -0,0 +1,4 @@
+This repository contains the PKGBUILD to create the «dualscreen-mouse-utils»
+package for Arch Linux.
+
+See https://aur.archlinux.org/packages/dualscreen-mouse-utils/. \ No newline at end of file
diff --git a/README.icons b/README.icons
new file mode 100644
index 000000000000..ed3fc4073e50
--- /dev/null
+++ b/README.icons
@@ -0,0 +1,26 @@
+The SVG images located in this folder ("running.svg" and "stopped.svg")
+are based on "input-mouse-symbolic.svg", included in the Adwaita icon
+theme by the GNOME Project <http://www.gnome.org>.
+
+See <https://git.gnome.org/browse/adwaita-icon-theme/tree/COPYING>.
+
+The following license terms apply:
+
+ This work is licenced under the terms of either the GNU LGPL v3 or
+ Creative Commons Attribution-Share Alike 3.0 United States License.
+
+ To view a copy of the CC-BY-SA licence, visit
+
+ <http://creativecommons.org/licenses/by-sa/3.0/>
+
+ or send a letter to
+
+ Creative Commons,
+ 171 Second Street,
+ Suite 300,
+ San Francisco,
+ California 94105,
+ USA.
+
+On Arch Linux these licenses can be found in /usr/share/licenses/common/
+if the «licenses» package is installed. \ No newline at end of file
diff --git a/mouse-wrapscreen-tray b/mouse-wrapscreen-tray
new file mode 100755
index 000000000000..4251c5e8c0f4
--- /dev/null
+++ b/mouse-wrapscreen-tray
@@ -0,0 +1,149 @@
+#!/usr/bin/env python
+
+# Coypright 2015 Stefan Göbel.
+#
+# 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
+# 3 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, see <http://www.gnu.org/licenses/>.
+
+#############################################################################################
+
+from PyQt5.QtCore import QTimer
+from PyQt5.QtGui import QIcon
+from PyQt5.QtWidgets import QAction, QApplication, QMenu, QSystemTrayIcon
+
+import ctypes, os, psutil, shlex, signal, subprocess, sys
+
+#############################################################################################
+#
+# This script can be configured using the following environment variables:
+#
+# DSMUMWST_CNF_RUNNING
+# DSMUMWST_CNF_STOPPED
+#
+# Full paths to the images used in the system tray if the process is running or stopped,
+# respectively. All image formats supported by QIcon may be used. The default paths are
+# /usr/share/dualscreen-mouse-utils/running.svg and …/stopped.svg.
+#
+# DSMUMWST_CNF_COMMAND
+#
+# The command to execute to start the process. Either a full path or located somewhere in
+# $PATH. Command line parameters may be included, the command will be split on whitespace
+# using shlex.split() (shell-style escapes and quoting is supported, see shlex.split()).
+# The default is "mouse-wrapscreen".
+#
+# DSMUMWST_CNF_PROCESS
+#
+# The process name to look for when checking if the process is running. Usually, but not
+# always, the name of the executable. The default is "mouse-wrapscreen".
+#
+# DSMUMWST_CNF_OWNNAME
+#
+# This name will be set for the script's own process, it replaces the generic "python"
+# name. The name must be unique. When $DSMUMWST_CNF_COMMAND is started or stopped the
+# name will be used to located other running instances of this script and signal them to
+# update their icons. Names longer than 15 bytes will be truncated! The default name is
+# "dsmumwstray".
+#
+# DSMUMWST_CNF_DELAYMS
+#
+# Signal handlers will not be run when Qt is doing nothing, waiting for events. A timer
+# will be created to generate an event every $DSMUMWST_CNF_DEALYMS milliseconds. Updates
+# of the tray icons of other running instances will take up to this time. The default is
+# "500" (half a second). This value may be set to "0" to disable the timer.
+#
+# Note that there is no error checking!
+#
+# Sending a SIGUSR1 signal to this script will change the status icon to the "running" icon,
+# SIGUSR2 will change the icon to the "stopped" icon.
+
+running = os.getenv ("DSMUMWST_CNF_RUNNING", "/usr/share/dualscreen-mouse-utils/running.svg")
+stopped = os.getenv ("DSMUMWST_CNF_STOPPED", "/usr/share/dualscreen-mouse-utils/stopped.svg")
+command = os.getenv ("DSMUMWST_CNF_COMMAND", "mouse-wrapscreen")
+pr_name = os.getenv ("DSMUMWST_CNF_PROCESS", "mouse-wrapscreen")
+pr_tray = os.getenv ("DSMUMWST_CNF_OWNNAME", "dsmumwstray")
+wait_ms = os.getenv ("DSMUMWST_CNF_DELAYMS", "500")
+
+#############################################################################################
+
+def setProcessName (name):
+ PR_SET_NAME = 15 # From prctl.h.
+ libc = ctypes.cdll.LoadLibrary ('libc.so.6')
+ buffer = ctypes.create_string_buffer (len (name) + 1)
+ buffer.value = name
+ libc.prctl (PR_SET_NAME, ctypes.byref (buffer), 0, 0, 0)
+
+def isRunning (name):
+ for process in psutil.process_iter ():
+ if process.name () == name:
+ return process
+ return None
+
+pid = os.getpid ()
+def notify (signum):
+ for process in psutil.process_iter ():
+ if process.name () == pr_tray:
+ if process.pid != pid:
+ process.send_signal (signum)
+
+class SystemTrayIcon (QSystemTrayIcon):
+
+ icon_running = QIcon (running)
+ icon_stopped = QIcon (stopped)
+
+ class Menu (QMenu):
+ def __init__ (self, parent = None):
+ super (SystemTrayIcon.Menu, self).__init__ ("Menu", parent)
+ exitAction = QAction (QIcon.fromTheme ("application-exit"), "&Exit", self)
+ exitAction.triggered.connect (lambda: QApplication.exit (0))
+ self.addAction (exitAction)
+
+ def __init__(self, parent = None):
+ super (SystemTrayIcon, self).__init__ (parent)
+ self.setContextMenu (SystemTrayIcon.Menu ())
+ self.activated.connect (self.onActivated)
+ if isRunning (pr_name):
+ self.setIcon (self.icon_running)
+ else:
+ self.setIcon (self.icon_stopped)
+ self.show ()
+
+ def onActivated (self, reason):
+ if reason == QSystemTrayIcon.Trigger:
+ process = isRunning (pr_name)
+ if process:
+ process.terminate ()
+ process.wait ()
+ self.setIcon (self.icon_stopped)
+ notify (signal.SIGUSR2)
+ else:
+ subprocess.Popen (shlex.split (command))
+ self.setIcon (self.icon_running)
+ notify (signal.SIGUSR1)
+
+ def updateIcon (self, signum, frame):
+ if signum == signal.SIGUSR1:
+ self.setIcon (self.icon_running)
+ elif signum == signal.SIGUSR2:
+ self.setIcon (self.icon_stopped)
+
+if __name__ == "__main__":
+ setProcessName (pr_tray.encode ())
+ app = QApplication ([])
+ if int (wait_ms) > 0:
+ timer = QTimer ()
+ timer.start (int (wait_ms))
+ timer.timeout.connect (lambda: None)
+ tray = SystemTrayIcon ()
+ signal.signal (signal.SIGUSR1, tray.updateIcon)
+ signal.signal (signal.SIGUSR2, tray.updateIcon)
+ sys.exit (app.exec_ ())
+
+# :indentSize=3:tabSize=3:noTabs=true:mode=python:maxLineLen=93: \ No newline at end of file
diff --git a/mouse-wrapscreen-tray.desktop b/mouse-wrapscreen-tray.desktop
new file mode 100644
index 000000000000..cb289e181887
--- /dev/null
+++ b/mouse-wrapscreen-tray.desktop
@@ -0,0 +1,12 @@
+[Desktop Entry]
+Version=1.0
+Type=Application
+Name=Mouse Wrap Screen
+Comment=Toggle the mouse-wrapscreen tool from the system tray.
+Exec=mouse-wrapscreen-tray
+TryExec=mouse-wrapscreen-tray
+Icon=input-mouse
+Terminal=false
+Categories=Utility;Qt;HardwareSettings;DesktopSettings;
+Keywords=mouse;system;tray;wrap;dual;screen;
+StartupNotify=false \ No newline at end of file
diff --git a/running.svg b/running.svg
new file mode 100644
index 000000000000..b03648c028f5
--- /dev/null
+++ b/running.svg
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ sodipodi:docname="running.svg"
+ height="16.009148"
+ id="svg7384"
+ inkscape:version="0.91 r13725"
+ version="1.1"
+ width="16">
+ <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" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:groupmode="layer"
+ id="layer10"
+ inkscape:label="devices"
+ transform="translate(-341.0002,-446.99085)">
+ <path
+ style="fill:#00ff00;fill-opacity:1;stroke:none"
+ d="m 344.6967,451.79833 c -0.85142,-0.003 -1.54026,0.69949 -1.54443,1.57804 0.0165,0.68037 0.0202,1.3773 0.0137,2.07387 l 2.67019,0.014 0.0173,-3.65956 -1.15689,-0.005 z"
+ id="path3534"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#bebebe;fill-opacity:1;stroke:none"
+ d="m 346.897,451.80903 -0.0173,3.65958 2.6703,0.014 c 0.0137,-0.69932 0.0274,-1.40105 0.0335,-2.07361 0.003,-0.87854 -0.6779,-1.58929 -1.52936,-1.59361 l -1.15718,-0.005 z"
+ id="path3532"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#bebebe;fill-opacity:1;stroke:none"
+ d="m 343.16196,456.45309 c -0.0103,0.7601 -0.0338,1.37145 -0.0343,2.07112 -0.008,1.83815 1.41839,3.32526 3.19986,3.3343 1.78145,0.009 3.22268,-1.46352 3.23144,-3.30171 -0.0323,-0.76462 -0.042,-1.37872 -0.0343,-2.10371 z"
+ id="rect7357"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 347.78918,448.14826 c -0.41524,0.0453 -0.80796,0.20237 -1.14252,0.45701 -0.44608,0.33952 -0.74264,0.87276 -0.74264,1.54241 -0.004,0.24145 0.21554,0.46352 0.45701,0.46352 0.24146,0 0.46043,-0.22207 0.45701,-0.46352 0,-0.41049 0.15688,-0.64337 0.39988,-0.82833 0.243,-0.18496 0.60669,-0.27442 0.97115,-0.25707 0.36445,0.0174 0.71684,0.14084 0.97114,0.37132 0.2543,0.23048 0.42845,0.53425 0.42845,1.02827 0,1.97913 1.33796,3.20738 2.74206,3.17051 0.78305,-0.0206 1.54309,-0.43595 2.05654,-1.19965 l -0.51414,-0.91402 c -0.34309,0.83697 -0.97603,1.18403 -1.57097,1.19965 -0.87788,0.023 -1.79947,-0.66701 -1.79947,-2.25649 0,-0.72387 -0.30786,-1.31973 -0.74264,-1.71378 -0.43478,-0.39405 -0.98809,-0.57344 -1.54241,-0.59983 -0.13858,-0.006 -0.29004,-0.0151 -0.42845,0 z m 6.34101,1.79943 c -3e-4,0.01 -3e-4,0.019 0,0.0285 0,0.0416 8.1e-4,0.0738 0,0.11425 l 0.71408,1.25678 c 0.0104,-0.0373 0.019,-0.0761 0.0285,-0.11425 z m 0,0.34276 c -0.005,0.0969 -0.0184,0.19547 -0.0285,0.28563 l 0.65695,1.11396 c 0.0214,-0.0571 0.0379,-0.11181 0.0571,-0.17138 z m -0.0571,0.45701 c -0.0126,0.0822 -0.0406,0.15227 -0.0571,0.2285 l 0.59982,1.02828 c 0.0268,-0.0557 0.0611,-0.11297 0.0856,-0.17138 z m -0.0856,0.39988 c -0.0217,0.0813 -0.0597,0.15446 -0.0856,0.22851 l 0.5427,0.94258 c 0.0367,-0.0595 0.0804,-0.10804 0.11425,-0.17138 z"
+ id="path7413"
+ sodipodi:nodetypes="sscscscssccccsscsccccccccccccccccccccc"
+ style="fill:#bebebe;fill-opacity:1;stroke:none;stroke-width:1;marker:none;enable-background:accumulate" />
+ </g>
+</svg>
diff --git a/stopped.svg b/stopped.svg
new file mode 100644
index 000000000000..f0c851d12ef7
--- /dev/null
+++ b/stopped.svg
@@ -0,0 +1,54 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://creativecommons.org/ns#"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ sodipodi:docname="stopped.svg"
+ height="16.009148"
+ id="svg7384"
+ inkscape:version="0.91 r13725"
+ version="1.1"
+ width="16">
+ <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" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:groupmode="layer"
+ id="layer10"
+ inkscape:label="devices"
+ transform="translate(-341.0002,-446.99085)">
+ <path
+ style="fill:#bebebe;fill-opacity:1;stroke:none"
+ d="m 344.6967,451.79447 c -0.85142,-0.003 -1.54026,0.69949 -1.54443,1.57804 0.0165,0.68037 0.0202,1.3773 0.0137,2.07387 l 2.67019,0.014 0.0173,-3.65956 -1.15689,-0.005 z"
+ id="path3534"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#ff0000;fill-opacity:1;stroke:none"
+ d="m 346.897,451.80517 -0.0173,3.65958 2.6703,0.014 c 0.0137,-0.69932 0.0274,-1.40105 0.0335,-2.07361 0.003,-0.87854 -0.6779,-1.58929 -1.52936,-1.59361 l -1.15718,-0.005 z"
+ id="path3532"
+ inkscape:connector-curvature="0" />
+ <path
+ style="fill:#bebebe;fill-opacity:1;stroke:none"
+ d="m 343.16196,456.44923 c -0.0103,0.7601 -0.0338,1.37145 -0.0343,2.07112 -0.008,1.83815 1.41839,3.32526 3.19986,3.3343 1.78145,0.009 3.22268,-1.46352 3.23144,-3.30171 -0.0323,-0.76462 -0.042,-1.37872 -0.0343,-2.10371 z"
+ id="rect7357"
+ inkscape:connector-curvature="0" />
+ <path
+ inkscape:connector-curvature="0"
+ d="m 347.78918,448.1444 c -0.41524,0.0453 -0.80796,0.20237 -1.14252,0.45701 -0.44608,0.33952 -0.74264,0.87276 -0.74264,1.54241 -0.004,0.24145 0.21554,0.46352 0.45701,0.46352 0.24146,0 0.46043,-0.22207 0.45701,-0.46352 0,-0.41049 0.15688,-0.64337 0.39988,-0.82833 0.243,-0.18496 0.60669,-0.27442 0.97115,-0.25707 0.36445,0.0174 0.71684,0.14084 0.97114,0.37132 0.2543,0.23048 0.42845,0.53425 0.42845,1.02827 0,1.97913 1.33796,3.20738 2.74206,3.17051 0.78305,-0.0206 1.54309,-0.43595 2.05654,-1.19965 l -0.51414,-0.91402 c -0.34309,0.83697 -0.97603,1.18403 -1.57097,1.19965 -0.87788,0.023 -1.79947,-0.66701 -1.79947,-2.25649 0,-0.72387 -0.30786,-1.31973 -0.74264,-1.71378 -0.43478,-0.39405 -0.98809,-0.57344 -1.54241,-0.59983 -0.13858,-0.006 -0.29004,-0.0151 -0.42845,0 z m 6.34101,1.79943 c -3e-4,0.01 -3e-4,0.019 0,0.0285 0,0.0416 8.1e-4,0.0738 0,0.11425 l 0.71408,1.25678 c 0.0104,-0.0373 0.019,-0.0761 0.0285,-0.11425 z m 0,0.34276 c -0.005,0.0969 -0.0184,0.19547 -0.0285,0.28563 l 0.65695,1.11396 c 0.0214,-0.0571 0.0379,-0.11181 0.0571,-0.17138 z m -0.0571,0.45701 c -0.0126,0.0822 -0.0406,0.15227 -0.0571,0.2285 l 0.59982,1.02828 c 0.0268,-0.0557 0.0611,-0.11297 0.0856,-0.17138 z m -0.0856,0.39988 c -0.0217,0.0813 -0.0597,0.15446 -0.0856,0.22851 l 0.5427,0.94258 c 0.0367,-0.0595 0.0804,-0.10804 0.11425,-0.17138 z"
+ id="path7413"
+ sodipodi:nodetypes="sscscscssccccsscsccccccccccccccccccccc"
+ style="fill:#bebebe;fill-opacity:1;stroke:none;stroke-width:1;marker:none;enable-background:accumulate" />
+ </g>
+</svg>