├── requirements-dev.txt
├── doc
├── mel.png
└── menu.png
├── requirements.txt
├── .gitignore
├── stdeb.cfg
├── inputdeviceindicator
├── resources
│ ├── input-device-indicator.desktop
│ └── input-device-indicator.svg
├── __main__.py
├── tests.py
├── main.py
├── indicator.py
├── about.py
├── mock.py
├── command.py
├── menu.py
└── info.py
├── Makefile
├── setup.py
├── README.md
└── LICENSE.txt
/requirements-dev.txt:
--------------------------------------------------------------------------------
1 | inelegant>=0.3.0
2 | pycodestyle>=2.6.0
3 | stdeb>=0.10.0
4 |
--------------------------------------------------------------------------------
/doc/mel.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brandizzi/input-device-indicator/HEAD/doc/mel.png
--------------------------------------------------------------------------------
/doc/menu.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/brandizzi/input-device-indicator/HEAD/doc/menu.png
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | pkg-resources==0.0.0
2 | pycairo==1.19.1
3 | PyGObject==3.36.1
4 | pycodestyle==2.6.0
5 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | __pycache__
2 | .*~
3 | *.orig
4 | *.py[co]
5 | build/
6 | deb_dist/
7 | dist/
8 | tmp/
9 | input-device-indicator*.tar.gz
10 | *.egg-info
11 | *.eggs
12 | *.bkp
13 | *.swp
14 |
--------------------------------------------------------------------------------
/stdeb.cfg:
--------------------------------------------------------------------------------
1 | [DEFAULT]
2 | Suite: bionic
3 | Depends: python3-gi python3-gi-cairo gir1.2-gtk-3.0 libgirepository1.0-dev gir1.2-appindicator3-0.1
4 | Build-Depends: dh-python
5 | Package3: input-device-indicator
6 |
--------------------------------------------------------------------------------
/inputdeviceindicator/resources/input-device-indicator.desktop:
--------------------------------------------------------------------------------
1 | [Desktop Entry]
2 | Version=0.0.1
3 | Type=Application
4 | Name=Input Device Indicator
5 | Comment=Enable and disables such as keyboards, mouses and trackpads.
6 | Exec=input-device-indicator
7 | Icon=/usr/share/icons/input-device-indicator.svg
8 | Terminal=false
9 | Categories=Utility;GTK;GNOME;
10 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | VERSION=$(shell python -c 'from inputdeviceindicator.info import VERSION; print(VERSION)' )
2 |
3 | install_local: bdist_deb
4 | sudo dpkg -i deb_dist/input-device-indicator*.deb
5 | sdist_dsc:
6 | python setup.py --command-packages=stdeb.command sdist_dsc
7 | bdist_deb:
8 | python setup.py --command-packages=stdeb.command bdist_deb
9 | clean:
10 | -rm input-device-indicator*.deb input-device-indicator*.tar.gz
11 | -rm -r dist deb_dist tmp *.egg-info
12 | publish: clean sdist_dsc
13 | mkdir -p tmp
14 | cd tmp ; \
15 | ls ../deb_dist/input-device-indicator_${VERSION}-1.dsc ; \
16 | dpkg-source -x ../deb_dist/input-device-indicator_${VERSION}-1.dsc ; \
17 | cd input-device-indicator-${VERSION} ; \
18 | debuild -S -sa ; \
19 | dput ppa:brandizzi/ppa ../input-device-indicator_${VERSION}-1_source.changes
20 |
--------------------------------------------------------------------------------
/inputdeviceindicator/__main__.py:
--------------------------------------------------------------------------------
1 | # Copyright © 2020 Adam Brandizzi
2 | #
3 | # This file is part of Input Device Indicator.
4 | #
5 | # Input Device Indicator is free software: you can redistribute it and/or
6 | # modify it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or (at your
8 | # option) any later version.
9 | #
10 | # Input Device Indicator is distributed in the hope that it will be useful, but
11 | # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 | # more details.
14 | #
15 | # You should have received a copy of the GNU General Public License along with
16 | # Input Device Indicator. If not, see
17 |
18 | from inputdeviceindicator.main import main
19 |
20 | if __name__ == '__main__':
21 | main()
22 |
--------------------------------------------------------------------------------
/inputdeviceindicator/tests.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # Copyright © 2020 Adam Brandizzi
3 | #
4 | # This file is part of Input Device Indicator.
5 | #
6 | # Input Device Indicator is free software: you can redistribute it and/or
7 | # modify it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or (at your
9 | # option) any later version.
10 | #
11 | # Input Device Indicator is distributed in the hope that it will be useful, but
12 | # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 | # more details.
15 | #
16 | # You should have received a copy of the GNU General Public License along with
17 | # Input Device Indicator. If not, see
18 | #
19 |
20 | from inelegant.finder import TestFinder
21 |
22 |
23 | load_tests = TestFinder(
24 | 'inputdeviceindicator.command',
25 | 'inputdeviceindicator.indicator',
26 | 'inputdeviceindicator.menu'
27 | ).load_tests
28 |
--------------------------------------------------------------------------------
/inputdeviceindicator/main.py:
--------------------------------------------------------------------------------
1 | # Copyright © 2020 Adam Brandizzi
2 | #
3 | # This file is part of Input Device Indicator.
4 | #
5 | # Input Device Indicator is free software: you can redistribute it and/or
6 | # modify it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or (at your
8 | # option) any later version.
9 | #
10 | # Input Device Indicator is distributed in the hope that it will be useful, but
11 | # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 | # more details.
14 | #
15 | # You should have received a copy of the GNU General Public License along with
16 | # Input Device Indicator. If not, see
17 |
18 | import gi
19 | gi.require_version('Gtk', '3.0') # noqa
20 | gi.require_version('AppIndicator3', '0.1') # noqa
21 |
22 | from gi.repository import Gtk as gtk
23 | from gi.repository import AppIndicator3 as appindicator
24 | from inputdeviceindicator.indicator import get_indicator
25 |
26 |
27 | def main():
28 | indicator = get_indicator()
29 | indicator.set_status(appindicator.IndicatorStatus.ACTIVE)
30 | gtk.main()
31 |
--------------------------------------------------------------------------------
/inputdeviceindicator/indicator.py:
--------------------------------------------------------------------------------
1 | # Copyright © 2020 Adam Brandizzi
2 | #
3 | # This file is part of Input Device Indicator.
4 | #
5 | # Input Device Indicator is free software: you can redistribute it and/or
6 | # modify it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or (at your
8 | # option) any later version.
9 | #
10 | # Input Device Indicator is distributed in the hope that it will be useful, but
11 | # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 | # more details.
14 | #
15 | # You should have received a copy of the GNU General Public License along with
16 | # Input Device Indicator. If not, see
17 |
18 | import gi
19 | gi.require_version('Gtk', '3.0') # noqa
20 | gi.require_version('AppIndicator3', '0.1') # noqa
21 |
22 | from gi.repository import Gtk as gtk
23 | from gi.repository import AppIndicator3 as appindicator
24 |
25 | from inputdeviceindicator.menu import get_menu
26 | from inputdeviceindicator.info import get_icon_path
27 |
28 |
29 | def get_indicator():
30 | return build_indicator(get_menu())
31 |
32 |
33 | def build_indicator(menu):
34 | indicator = appindicator.Indicator.new(
35 | 'input-device-indicator', get_icon_path(),
36 | appindicator.IndicatorCategory.SYSTEM_SERVICES
37 | )
38 | indicator.set_menu(menu)
39 | return indicator
40 |
--------------------------------------------------------------------------------
/inputdeviceindicator/about.py:
--------------------------------------------------------------------------------
1 | # Copyright © 2020 Adam Brandizzi
2 | #
3 | # This file is part of Input Device Indicator.
4 | #
5 | # Input Device Indicator is free software: you can redistribute it and/or
6 | # modify it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or (at your
8 | # option) any later version.
9 | #
10 | # Input Device Indicator is distributed in the hope that it will be useful, but
11 | # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 | # more details.
14 | #
15 | # You should have received a copy of the GNU General Public License along with
16 | # Input Device Indicator. If not, see
17 |
18 | import gi
19 | gi.require_version('Gtk', '3.0') # noqa
20 | gi.require_version('AppIndicator3', '0.1') # noqa
21 |
22 | from gi.repository import Gtk as gtk
23 | from gi.repository import GdkPixbuf as gdkpb
24 |
25 | from inputdeviceindicator.info import PROGRAM_NAME, VERSION, DESCRIPTION,\
26 | ICON_PATH, URL, AUTHOR, COPYRIGHT, EMAIL, LICENSE
27 |
28 |
29 | def get_about_dialog():
30 | dialog = gtk.AboutDialog()
31 | dialog.set_program_name(PROGRAM_NAME)
32 | dialog.set_version(VERSION)
33 | dialog.set_comments(DESCRIPTION)
34 | pixbuf = gdkpb.Pixbuf.new_from_file(ICON_PATH)
35 | dialog.set_logo(pixbuf)
36 | dialog.set_icon(pixbuf)
37 | dialog.set_website(URL)
38 | authors = [
39 | "{name} <{email}>".format(name=AUTHOR, email=EMAIL)
40 | ]
41 | dialog.set_authors(authors)
42 | dialog.set_copyright(COPYRIGHT)
43 | dialog.set_license(LICENSE)
44 | return dialog
45 |
--------------------------------------------------------------------------------
/inputdeviceindicator/mock.py:
--------------------------------------------------------------------------------
1 | # Copyright © 2020 Adam Brandizzi
2 | #
3 | # This file is part of Input Device Indicator.
4 | #
5 | # Input Device Indicator is free software: you can redistribute it and/or
6 | # modify it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or (at your
8 | # option) any later version.
9 | #
10 | # Input Device Indicator is distributed in the hope that it will be useful, but
11 | # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 | # more details.
14 | #
15 | # You should have received a copy of the GNU General Public License along with
16 | # Input Device Indicator. If not, see
17 |
18 | def noop(*args, **kwargs):
19 | pass
20 |
21 |
22 | class MockXInput:
23 |
24 | def __init__(self, devices=None):
25 | self.devices = devices if devices is not None else []
26 |
27 | def list(self):
28 | return self.devices
29 |
30 | def enable(self, device):
31 | print('Device {0} enabled'.format(device.name))
32 |
33 | def disable(self, device):
34 | print('Device {0} disabled'.format(device.name))
35 |
36 |
37 | class MockMenuCallbacks:
38 |
39 | def child_device_check_menu_item_toggled(self, check_menu_item):
40 | print(
41 | 'Device {0} toggled to {1}'.format(
42 | check_menu_item.device.name, check_menu_item.get_active()
43 | )
44 | )
45 |
46 | def refresh_menu_item_activate(self, menu_item, menu):
47 | print('Refresh menu item activated')
48 |
49 | def about_menu_item_activate(self, menu_item, menu):
50 | print('about menu item activated')
51 |
52 | def quit_menu_item_activate(self, menu_item):
53 | print('Quit menu item activated')
54 |
55 |
56 | class MockAboutDialog:
57 |
58 | def run(self):
59 | print('about dialog displayed')
60 |
61 | def hide(self):
62 | pass
63 |
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python
2 | # Copyright © 2020 Adam Brandizzi
3 | #
4 | # This file is part of Input Device Indicator.
5 | #
6 | # Input Device Indicator is free software: you can redistribute it and/or
7 | # modify it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or (at your
9 | # option) any later version.
10 | #
11 | # Input Device Indicator is distributed in the hope that it will be useful, but
12 | # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 | # more details.
15 | #
16 | # You should have received a copy of the GNU General Public License along with
17 | # Input Device Indicator. If not, see
18 | #
19 |
20 | from distutils.core import setup
21 | import setuptools
22 |
23 | from inputdeviceindicator.info import VERSION, DESCRIPTION, URL, AUTHOR, EMAIL
24 |
25 | setup(
26 | name="input-device-indicator",
27 | version=VERSION,
28 | author=AUTHOR,
29 | author_email=EMAIL,
30 | description=DESCRIPTION,
31 | license='GPLv3',
32 | url=URL,
33 | packages=['inputdeviceindicator'],
34 | package_data={
35 | 'inputdeviceindicator': ['resources/*']
36 | },
37 | entry_points={
38 | 'gui_scripts': [
39 | 'input-device-indicator=inputdeviceindicator.main:main'
40 | ]
41 | },
42 | test_suite='inputdeviceindicator.tests',
43 | test_loader='unittest:TestLoader',
44 | data_files=[
45 | (
46 | 'share/applications/',
47 | ['inputdeviceindicator/resources/input-device-indicator.desktop']
48 | ),
49 | (
50 | 'share/icons/',
51 | ['inputdeviceindicator/resources/input-device-indicator.svg']
52 | ),
53 | ],
54 | classifiers=[
55 | "Development Status :: 4 - Beta",
56 | "Environment :: X11 Applications :: Gnome",
57 | "Intended Audience :: End Users/Desktop",
58 | "License :: OSI Approved :: GNU General Public License v3 (GPLv3)",
59 | "Operating System :: POSIX",
60 | "Operating System :: Unix",
61 | "Topic :: Desktop Environment :: Gnome",
62 | ],
63 | )
64 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Input Device Indicator
2 |
3 | 
4 |
5 | This app is an indicator to help you disable/enable input devices (such as keyboards, mouses and trackpads).
6 |
7 | ## How to Use
8 |
9 | You just need to invoke `input-device-indicator`. (We do want to be able to
10 | invoke it from a menu item or a launcher when pressing Super but we did not
11 | manage to do it so far. Any help is welcome.)
12 |
13 | Once activated, there will be an icon (a cat on a keyboard) on your indicators.
14 | Click on it and a list of devices will appear. Just click on the one you want
15 | to disable or enable:
16 |
17 | 
18 |
19 | For those more used to technicalities, it can be useful to know this indicator
20 | is basically a wrapper around
21 | [`xinput`](https://www.x.org/archive/current/doc/man/man1/xinput.1.xhtml): the
22 | devices come from the output of `xinput list --long`, and we disable/enable
23 | them with `xinput disable`/`xinput enable`.
24 |
25 | ## Development Tips
26 |
27 | If you want to change Input Device Indicator's source code, once you cloned the
28 | repository, you will need to install the dependencies:
29 |
30 | $ pip install -r requirements.txt
31 | $ pip install -r requirements-dev.txt
32 |
33 | To test the package locally, you can leverage our Makefile by invoking the
34 | `install_local` target:
35 |
36 | $ make install_local
37 |
38 | To publish a release in the PPA, we use the `publish` target. Of course, you
39 | need to have the right permissions etc.
40 |
41 | $ make publish
42 |
43 | ## Why?
44 |
45 | Because of this:
46 |
47 | 
48 |
49 | ## Licensing
50 |
51 | ### Input Device Indicator
52 |
53 | ```
54 | Input Device Indicator is free software: you can redistribute it and/or modify
55 | it under the terms of the GNU General Public License as published by the Free
56 | Software Foundation, either version 3 of the License, or (at your option) any
57 | later version.
58 |
59 | Foobar is distributed in the hope that it will be useful,
60 | but WITHOUT ANY WARRANTY; without even the implied warranty of
61 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
62 | GNU General Public License for more details.
63 |
64 | You should have received a copy of the GNU General Public License
65 | along with Foobar. If not, see .
66 | ```
67 |
68 | ### Icons
69 |
70 | (The icon is a mashup of [this
71 | icon](https://commons.wikimedia.org/wiki/File:Noto_Emoji_Oreo_2328.svg) and
72 | [this
73 | icon](https://commons.wikimedia.org/wiki/File:Noto_Emoji_KitKat_1f408.svg)
74 | found on Wikimedia Commons, licensed under Apache License 2.0.)
75 |
76 | ```
77 | Copyright 2020 Adam Victor Brandizzi
78 |
79 | Licensed under the Apache License, Version 2.0 (the "License"); you may not use
80 | this file except in compliance with the License. You may obtain a copy of the
81 | License at
82 |
83 | http://www.apache.org/licenses/LICENSE-2.0
84 |
85 | Unless required by applicable law or agreed to in writing, software distributed
86 | under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
87 | CONDITIONS OF ANY KIND, either express or implied. See the License for the
88 | specific language governing permissions and limitations under the License.
89 | ```
90 |
--------------------------------------------------------------------------------
/inputdeviceindicator/command.py:
--------------------------------------------------------------------------------
1 | # Copyright © 2020 Adam Brandizzi
2 | #
3 | # This file is part of Input Device Indicator.
4 | #
5 | # Input Device Indicator is free software: you can redistribute it and/or
6 | # modify it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or (at your
8 | # option) any later version.
9 | #
10 | # Input Device Indicator is distributed in the hope that it will be useful, but
11 | # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 | # more details.
14 | #
15 | # You should have received a copy of the GNU General Public License along with
16 | # Input Device Indicator. If not, see
17 |
18 | import re
19 | import subprocess
20 |
21 |
22 | class XInput:
23 |
24 | def list(self):
25 | """
26 | Lists the devices as a forest of `Device` instances:
27 |
28 | >>> xi = XInput()
29 | >>> xi.list() # doctest: +ELLIPSIS
30 | [Device(..., ..., ..., [Device(...)]), Device(..., ..., ...)]
31 | """
32 | cp = subprocess.run(
33 | ['xinput', 'list', '--long'], stdout=subprocess.PIPE,
34 | stderr=subprocess.PIPE
35 | )
36 | return parse(cp.stdout.decode('utf-8'))
37 |
38 | def disable(self, device):
39 | """
40 | Given a specific device...
41 |
42 | >>> xi = XInput()
43 | >>> devices = xi.list()
44 | >>> device = devices[1].children[-1]
45 | >>> # For restoring later.
46 | >>> current_status = device.enabled
47 |
48 | ...`disable()` disables it:
49 |
50 | >>> xi.disable(device)
51 | >>> device = get_device_from_list_by_id(xi.list(), device.id)
52 | >>> device.enabled
53 | False
54 |
55 | To enable it again, you can use `enable()`:
56 |
57 | >>> xi.enable(device)
58 | >>> device = get_device_from_list_by_id(xi.list(), device.id)
59 | >>> device.enabled
60 | True
61 |
62 | >>> # If it was disabled before, let it this way.
63 | >>> if not current_status:
64 | ... xi.disable(device)
65 | """
66 | subprocess.run(['xinput', '--disable', str(device.id)])
67 |
68 | def enable(self, device):
69 | """
70 | Given a specific device...
71 |
72 | >>> xi = XInput()
73 | >>> devices = xi.list()
74 | >>> device = devices[1].children[-1]
75 | >>> # For restoring later.
76 | >>> current_status = device.enabled
77 | >>> xi.disable(device)
78 |
79 | ...`enable()` enables it:
80 |
81 | >>> xi.enable(device)
82 | >>> device = get_device_from_list_by_id(xi.list(), device.id)
83 | >>> device.enabled
84 | True
85 |
86 | >>> # If it was disabled before, let it this way.
87 | >>> if not current_status:
88 | ... xi.disable(device)
89 | """
90 | subprocess.run(['xinput', '--enable', str(device.id)])
91 |
92 |
93 | class Device:
94 | """
95 | The `Device` class represents a device listed by `xinput`. Each device
96 | should have an id, a name and the id of a parent device.
97 |
98 | >>> d = Device(
99 | ... id=1, name='abc', level='master', parent_id=4, type='keyboard'
100 | ... )
101 | >>> d
102 | Device(1, 'abc', 4, 'master', 'keyboard', True)
103 |
104 | You can also add a device as a child of another with ``add_child()``:
105 |
106 | >>> d.add_child(Device(2, 'def', 1, 'slave', 'keyboard'))
107 | >>> d
108 | Device(1, 'abc', 4, 'master', 'keyboard', True, [Device(2, 'def', 1, \
109 | 'slave', 'keyboard', True)])
110 | """
111 |
112 | def __init__(self, id, name, parent_id, level, type):
113 | self.id = id
114 | self.name = name
115 | self.parent_id = parent_id
116 | self.level = level
117 | self.type = type
118 | self.enabled = True
119 | self.children = []
120 |
121 | def __repr__(self):
122 | parameters = [
123 | self.id, self.name, self.parent_id, self.level, self.type,
124 | self.enabled
125 | ]
126 | if self.children:
127 | parameters.append(self.children)
128 | return 'Device({0})'.format(
129 | ', '.join(repr(p) for p in parameters)
130 | )
131 |
132 | def add_child(self, device):
133 | self.children.append(device)
134 |
135 |
136 | MAIN_LINE_REGEX = re.compile(
137 | r'''
138 | [~⎡⎜⎣]?(\s+↳)? \s+ # discarded
139 | (?P.*) \s+
140 | id=(?P\d+) \s+
141 | \[
142 | (
143 | (?Pmaster|slave) \s+
144 | (?P\w+) \s+
145 | \((?P\d+)\)
146 | |
147 | (?Pfloating) \s+
148 | (?Pmaster|slave)
149 | )
150 | \]
151 | ''',
152 | re.VERBOSE
153 | )
154 |
155 | SUBORDINATE_LINE_REGEX = re.compile(r'^\s+[^\s↳]')
156 |
157 |
158 | def parse(string):
159 | """
160 | As its name implies, `Parser` does parse `xinput` output.
161 |
162 | >>> parse('''
163 | ... ⎡ A id=2 [master pointer (3)]
164 | ... ⎜ ↳ A1 id=4 [slave pointer (2)]
165 | ... ⎣ B id=3 [master keyboard (2)]
166 | ... ↳ B1 id=5 [slave keyboard (3)]
167 | ... ~ C id=6 [floating slave]
168 | ... ''')
169 | [Device(2, 'A', 3, 'master', 'pointer', True, \
170 | [Device(4, 'A1', 2, 'slave', 'pointer', True)]), \
171 | Device(3, 'B', 2, 'master', 'keyboard', True, \
172 | [Device(5, 'B1', 3, 'slave', 'keyboard', True)]), \
173 | Device(6, 'C', None, 'slave', 'floating', True)]
174 |
175 | `parse()` does deal well with the long output:
176 |
177 | >>> parse('''
178 | ... ⎡ A id=2 [master pointer (3)]
179 | ... Reporting 1 classes:
180 | ... Class originated from: 7. Type: XIKeyClass
181 | ... Keycodes supported: 248
182 | ... ⎜ ↳ A1 id=4 [slave pointer (2)]
183 | ... Reporting 1 classes:
184 | ... Class originated from: 7. Type: XIKeyClass
185 | ... Keycodes supported: 248
186 | ... ⎣ B id=3 [master keyboard (2)]
187 | ... Reporting 1 classes:
188 | ... Class originated from: 7. Type: XIKeyClass
189 | ... ↳ B1 id=5 [slave keyboard (3)]
190 | ... Reporting 1 classes:
191 | ... Class originated from: 7. Type: XIKeyClass
192 | ... Keycodes supported: 248
193 | ... ~ C id=6 [floating slave]
194 | ... Reporting 1 classes:
195 | ... Class originated from: 7. Type: XIKeyClass
196 | ... Keycodes supported: 248
197 | ... ''')
198 | [Device(2, 'A', 3, 'master', 'pointer', True, \
199 | [Device(4, 'A1', 2, 'slave', 'pointer', True)]), \
200 | Device(3, 'B', 2, 'master', 'keyboard', True, \
201 | [Device(5, 'B1', 3, 'slave', 'keyboard', True)]), \
202 | Device(6, 'C', None, 'slave', 'floating', True)]
203 |
204 | If a device is disabled, so should be the object returned by `parse()`:
205 |
206 | >>> parse('''
207 | ... ⎡ A id=2 [master pointer (3)]
208 | ... This device is disabled
209 | ... Reporting 1 classes:
210 | ... Class originated from: 7. Type: XIKeyClass
211 | ... Keycodes supported: 248
212 | ... ⎣ B id=3 [master keyboard (2)]
213 | ... Reporting 1 classes:
214 | ... Class originated from: 7. Type: XIKeyClass ... ''')
215 | [Device(2, 'A', 3, 'master', 'pointer', False), \
216 | Device(3, 'B', 2, 'master', 'keyboard', True)]
217 | """
218 | device_list = []
219 | device_map = {}
220 | lines = string.split('\n')
221 | for line in lines:
222 | if not line or SUBORDINATE_LINE_REGEX.match(line):
223 | if 'This device is disabled' in line:
224 | device.enabled = False
225 | continue
226 | device = parse_line(line)
227 | device_map[device.id] = device
228 | if device.level == 'slave' and device.type != 'floating':
229 | device_map[device.parent_id].add_child(device)
230 | else:
231 | device_list.append(device)
232 | return device_list
233 |
234 |
235 | def parse_line(line):
236 | """
237 | `parse_line()` parses one line from the `xinput` output into a `Device`
238 | object:
239 |
240 | >>> parse_line('⎡ A id=2 [master pointer (3)]')
241 | Device(2, 'A', 3, 'master', 'pointer', True)
242 |
243 | It naturally should also handle floating devices:
244 |
245 | >>> parse_line('~ B1 id=5 [floating slave]')
246 | Device(5, 'B1', None, 'slave', 'floating', True)
247 | """
248 | m = MAIN_LINE_REGEX.search(line)
249 | if m is None:
250 | raise ValueError('Could not parse line {0}'.format(repr(line)))
251 | id = int(m.group('id'))
252 | name = m.group('name').strip()
253 | parent_id = int(m.group('parent_id')) if m.group('parent_id') else None
254 | level = m.group('level1') or m.group('level2')
255 | type = m.group('type1') or m.group('type2')
256 | return Device(id, name, parent_id, level, type)
257 |
258 |
259 | def get_device_from_list_by_id(devices, device_id):
260 | """
261 | Given a list/tree returned by `XInput.list()` and a device id, returns the
262 | device with the given id:
263 |
264 | >>> xi = XInput()
265 | >>> devices = xi.list()
266 | >>> devices[0] == get_device_from_list_by_id(devices, devices[0].id)
267 | True
268 |
269 | It should work even with children devices:
270 |
271 | >>> devices[0].children[-1] == get_device_from_list_by_id(
272 | ... devices,
273 | ... devices[0].children[-1].id
274 | ... )
275 | True
276 |
277 | (This function was made for tests but may work elsewhere.)
278 | """
279 | for parent_device in devices:
280 | if parent_device.id == device_id:
281 | return parent_device
282 | for child_device in parent_device.children:
283 | if child_device.id == device_id:
284 | return child_device
285 | return None
286 |
--------------------------------------------------------------------------------
/inputdeviceindicator/menu.py:
--------------------------------------------------------------------------------
1 | # Copyright © 2020 Adam Brandizzi
2 | #
3 | # This file is part of Input Device Indicator.
4 | #
5 | # Input Device Indicator is free software: you can redistribute it and/or
6 | # modify it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or (at your
8 | # option) any later version.
9 | #
10 | # Input Device Indicator is distributed in the hope that it will be useful, but
11 | # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 | # more details.
14 | #
15 | # You should have received a copy of the GNU General Public License along with
16 | # Input Device Indicator. If not, see
17 |
18 | import gi
19 | gi.require_version('Gtk', '3.0') # noqa
20 | gi.require_version('AppIndicator3', '0.1') # noqa
21 |
22 | from gi.repository import Gtk as gtk
23 |
24 | from inputdeviceindicator.command import XInput
25 | from inputdeviceindicator.about import get_about_dialog
26 |
27 |
28 | def get_menu():
29 | xinput = XInput()
30 | menu = gtk.Menu()
31 | about_dialog = get_about_dialog()
32 | menu_callbacks = MenuCallbacks(xinput, menu, about_dialog)
33 | build_menu(menu, xinput.list(), menu_callbacks)
34 | return menu
35 |
36 |
37 | def build_menu(menu, devices, callbacks):
38 | """
39 | Build a menu from a list of devices, connecting them to corresponding
40 | callbacks from `callbacks`.
41 |
42 | The menu should be created beforehand to be given to the function:
43 |
44 | >>> menu = gtk.Menu()
45 |
46 | Let's suppose we have the following devices, for example:
47 |
48 | >>> from inputdeviceindicator.command import parse
49 | >>> devices = parse('''
50 | ... ⎡ A id=2 [master pointer (3)]
51 | ... ⎜ ↳ A1 id=4 [slave pointer (2)]
52 | ... ⎣ B id=3 [master keyboard (2)]
53 | ... ↳ B1 id=5 [slave keyboard (3)]
54 | ... This device is disabled
55 | ... ''')
56 |
57 | ...then the menu should have an option for every one:
58 |
59 | >>> from inputdeviceindicator.mock import MockMenuCallbacks
60 | >>> build_menu(menu, devices, MockMenuCallbacks())
61 | >>> items = menu.get_children()
62 | >>> items[0].get_label()
63 | 'A'
64 | >>> items[1].get_label()
65 | 'A1'
66 | >>> items[2].get_label()
67 | 'B'
68 | >>> items[3].get_label()
69 | 'B1'
70 |
71 | An enabled device should be an active (checked) `gtk.CheckMenuItem`:
72 |
73 | >>> items[1].get_active()
74 | True
75 |
76 | A disabled device should then be an inactive (unchecked)
77 | `gtk.CheckMenuItem`:
78 |
79 | >>> items[3].get_active()
80 | False
81 |
82 | The child devices check menu items should have their `toggled` event
83 | connected to the method `child_device_check_menu_item_toggled` from
84 | `callbacks`:
85 |
86 | >>> items[3].set_active(True)
87 | Device B1 toggled to True
88 |
89 | The antepenultimate item from the menu is an option to refresh the device
90 | items...
91 |
92 | >>> items[-3].get_label()
93 | 'Refresh'
94 |
95 | ...the second to last option opens the "About" dialog...
96 |
97 | >>> items[-2].get_label()
98 | 'About'
99 |
100 | ...and the last item from the menu is an option to quit the application:
101 |
102 | >>> items[-1].get_label()
103 | 'Quit'
104 |
105 | It will be connected to the `quit_menu_item_activate` method from
106 | `callbacks`:
107 |
108 | >>> items[-1].emit('activate')
109 | Quit menu item activated
110 | """
111 | for c in menu.get_children():
112 | menu.remove(c)
113 |
114 | for d in devices:
115 | menu.append(gtk.MenuItem(label=d.name))
116 | for c in d.children:
117 | cdcmi = build_device_check_menu_item(
118 | c, callbacks.child_device_check_menu_item_toggled
119 | )
120 | menu.append(cdcmi)
121 |
122 | menu.append(gtk.SeparatorMenuItem())
123 |
124 | refresh_menu_item = gtk.MenuItem(label='Refresh')
125 | refresh_menu_item.connect(
126 | 'activate', callbacks.refresh_menu_item_activate
127 | )
128 | menu.append(refresh_menu_item)
129 |
130 | about_menu_item = gtk.MenuItem(label='About')
131 | about_menu_item.connect('activate', callbacks.about_menu_item_activate)
132 | menu.append(about_menu_item)
133 |
134 | quit_menu_item = gtk.MenuItem(label='Quit')
135 | quit_menu_item.connect('activate', callbacks.quit_menu_item_activate)
136 | menu.append(quit_menu_item)
137 |
138 | menu.show_all()
139 |
140 |
141 | def build_device_check_menu_item(device, callback):
142 | """
143 | Returns a `gtk.CheckMenuItem` representing the given child device, with the
144 | given callback connected to its `toggled` event..
145 |
146 | >>> from inputdeviceindicator.command import Device
147 | >>> from inputdeviceindicator.mock import noop
148 | >>> d = Device(1, 'abc', 4, 'slave', 'keyboard')
149 | >>> mi = build_device_check_menu_item(d, noop)
150 | >>> isinstance(mi, gtk.CheckMenuItem)
151 | True
152 |
153 | It should have the device's name as its title:
154 |
155 | >>> mi.get_label()
156 | 'abc'
157 |
158 | Also, the original device instance should be attached to the menu item:
159 |
160 | >>> mi.device == d
161 | True
162 |
163 | If the device is enabled, the item is active:
164 |
165 | >>> mi.get_active()
166 | True
167 |
168 | Otherwise, the item is inactive (unchecked):
169 |
170 | >>> d.enabled = False
171 | >>> mi = build_device_check_menu_item(d, noop)
172 | >>> mi.get_active()
173 | False
174 |
175 | The menu item should executed the given callback when the `toggled` event
176 | is called:
177 |
178 | >>> def callback(mi):
179 | ... print("menu item toggled to " + str(mi.get_active()))
180 | >>> mi = build_device_check_menu_item(d, callback)
181 | >>> mi.set_active(True)
182 | menu item toggled to True
183 | >>> mi.set_active(False)
184 | menu item toggled to False
185 | >>> mi.emit('toggled')
186 | menu item toggled to False
187 |
188 | If the function receives a parent device, it should fail:
189 |
190 | >>> build_device_check_menu_item(
191 | ... Device(1, 'abc', 4, 'master', 'keyboard'), noop
192 | ... )
193 | Traceback (most recent call last):
194 | ...
195 | AssertionError: build_device_check_menu_item() only accepts child devices.
196 |
197 | """
198 | assert device.level == \
199 | 'slave', "build_device_check_menu_item() only accepts child devices."
200 | menu_item = gtk.CheckMenuItem(label=device.name)
201 | menu_item.set_active(device.enabled)
202 | menu_item.device = device
203 | menu_item.connect('toggled', callback)
204 | return menu_item
205 |
206 |
207 | class MenuCallbacks:
208 |
209 | def __init__(self, xinput, menu, about_dialog):
210 | self.xinput = xinput
211 | self.menu = menu
212 | self.about_dialog = about_dialog
213 |
214 | def child_device_check_menu_item_toggled(self, check_menu_item):
215 | """
216 | Callback to enable or disable a device when its `gtk.CheckMenuItem` is
217 | clicked.
218 |
219 | It should receive a `XInput`-like object as argument:
220 |
221 | >>> from inputdeviceindicator.mock import MockXInput, MockAboutDialog
222 | >>> mcs = MenuCallbacks(
223 | ... MockXInput(), gtk.Menu(), MockAboutDialog()
224 | ... )
225 |
226 | When called with a menu item, it should try to toggle its state:
227 |
228 | >>> from inputdeviceindicator.command import Device
229 | >>> mi = build_device_check_menu_item(
230 | ... Device(1, 'abc', 4, 'slave', 'keyboard'), lambda _: None
231 | ... )
232 | >>> mi.set_active(False)
233 | >>> mcs.child_device_check_menu_item_toggled(mi)
234 | Device abc disabled
235 | >>> mi.set_active(True)
236 | >>> mcs.child_device_check_menu_item_toggled(mi)
237 | Device abc enabled
238 | """
239 | if check_menu_item.get_active():
240 | self.xinput.enable(check_menu_item.device)
241 | else:
242 | self.xinput.disable(check_menu_item.device)
243 |
244 | def about_menu_item_activate(self, menu_item):
245 | """
246 | Open the "About" dialog.
247 |
248 | >>> from inputdeviceindicator.mock import MockXInput, MockAboutDialog
249 | >>> callbacks = MenuCallbacks(
250 | ... MockXInput(), gtk.Menu(), MockAboutDialog()
251 | ... )
252 |
253 | It should display the dialog given to the constructor:
254 |
255 | >>> from inelegant.module import temp_var
256 | >>> callbacks.about_menu_item_activate(None)
257 | about dialog displayed
258 | """
259 | self.about_dialog.run()
260 | self.about_dialog.hide()
261 |
262 | def quit_menu_item_activate(self, menu_item):
263 | """
264 | Callback for quitting the application.
265 |
266 | >>> from inputdeviceindicator.mock import MockXInput, MockAboutDialog
267 | >>> callbacks = MenuCallbacks(
268 | ... MockXInput(), gtk.Menu(), MockAboutDialog()
269 | ... )
270 |
271 | It should do it by calling `gtk.main_quit()`:
272 |
273 | >>> from inelegant.module import temp_var
274 | >>> with temp_var(gtk, 'main_quit', lambda: print('quit called')):
275 | ... callbacks.quit_menu_item_activate(None)
276 | quit called
277 | """
278 | gtk.main_quit()
279 |
280 | def refresh_menu_item_activate(self, menu_item):
281 | """
282 | Refresh the menu by calling `xinput` again and regenerating all device
283 | items in the menu.
284 |
285 | Consider the following menu...
286 |
287 | >>> from inputdeviceindicator.command import parse
288 | >>> old_devices = parse('''
289 | ... ⎡ A id=2 [master pointer (3)]
290 | ... ⎜ ↳ A1 id=4 [slave pointer (2)]
291 | ... ⎣ B id=3 [master keyboard (2)]
292 | ... ↳ B1 id=5 [slave keyboard (3)]
293 | ... This device is disabled
294 | ... ''')
295 | >>> from inputdeviceindicator.mock import MockMenuCallbacks
296 | >>> callbacks = MockMenuCallbacks()
297 | >>> menu = gtk.Menu()
298 | >>> build_menu(menu, old_devices, callbacks)
299 |
300 | ...and the following `XInput`:
301 |
302 | >>> from inputdeviceindicator import mock
303 | >>> new_devices = parse('''
304 | ... ⎡ X id=10 [master pointer (9)]
305 | ... ⎜ ↳ X1 id=11 [slave pointer (10)]
306 | ... ⎣ Y id=12 [master keyboard (8)]
307 | ... ↳ Y1 id=13 [slave keyboard (12)]
308 | ... This device is disabled
309 | ... ''')
310 | >>> xinput = mock.MockXInput(new_devices)
311 |
312 | The menu will of course have the old options listed:
313 |
314 | >>> items = menu.get_children()
315 | >>> items[0].get_label()
316 | 'A'
317 | >>> items[1].get_label()
318 | 'A1'
319 | >>> items[2].get_label()
320 | 'B'
321 | >>> items[3].get_label()
322 | 'B1'
323 |
324 | Also, the antepenultimante item should be a "Refresh" option:
325 |
326 | >>> menu_item = items[-3]
327 | >>> menu_item.get_label()
328 | 'Refresh'
329 |
330 | Now, if we call `MenuCallbacks.refresh_menu_item_activate()` giving the
331 | menu item (and the xinput to `MenuCallback` constructor)...
332 |
333 | >>> from inputdeviceindicator.mock import MockXInput, MockAboutDialog
334 | >>> callbacks = MenuCallbacks(xinput, menu, MockAboutDialog())
335 | >>> callbacks.refresh_menu_item_activate(menu_item)
336 |
337 | ...the device menu items should be updated:
338 |
339 | >>> items = menu.get_children()
340 | >>> items[0].get_label()
341 | 'X'
342 | >>> items[1].get_label()
343 | 'X1'
344 | >>> items[2].get_label()
345 | 'Y'
346 | >>> items[3].get_label()
347 | 'Y1'
348 | >>> items[3].get_active()
349 | False
350 | """
351 | build_menu(self.menu, self.xinput.list(), self)
352 |
--------------------------------------------------------------------------------
/LICENSE.txt:
--------------------------------------------------------------------------------
1 | GNU GENERAL PUBLIC LICENSE
2 | Version 3, 29 June 2007
3 |
4 | Copyright (C) 2007 Free Software Foundation, Inc.
5 | Everyone is permitted to copy and distribute verbatim copies
6 | of this license document, but changing it is not allowed.
7 |
8 | Preamble
9 |
10 | The GNU General Public License is a free, copyleft license for
11 | software and other kinds of works.
12 |
13 | The licenses for most software and other practical works are designed
14 | to take away your freedom to share and change the works. By contrast,
15 | the GNU General Public License is intended to guarantee your freedom to
16 | share and change all versions of a program--to make sure it remains free
17 | software for all its users. We, the Free Software Foundation, use the
18 | GNU General Public License for most of our software; it applies also to
19 | any other work released this way by its authors. You can apply it to
20 | your programs, too.
21 |
22 | When we speak of free software, we are referring to freedom, not
23 | price. Our General Public Licenses are designed to make sure that you
24 | have the freedom to distribute copies of free software (and charge for
25 | them if you wish), that you receive source code or can get it if you
26 | want it, that you can change the software or use pieces of it in new
27 | free programs, and that you know you can do these things.
28 |
29 | To protect your rights, we need to prevent others from denying you
30 | these rights or asking you to surrender the rights. Therefore, you have
31 | certain responsibilities if you distribute copies of the software, or if
32 | you modify it: responsibilities to respect the freedom of others.
33 |
34 | For example, if you distribute copies of such a program, whether
35 | gratis or for a fee, you must pass on to the recipients the same
36 | freedoms that you received. You must make sure that they, too, receive
37 | or can get the source code. And you must show them these terms so they
38 | know their rights.
39 |
40 | Developers that use the GNU GPL protect your rights with two steps:
41 | (1) assert copyright on the software, and (2) offer you this License
42 | giving you legal permission to copy, distribute and/or modify it.
43 |
44 | For the developers' and authors' protection, the GPL clearly explains
45 | that there is no warranty for this free software. For both users' and
46 | authors' sake, the GPL requires that modified versions be marked as
47 | changed, so that their problems will not be attributed erroneously to
48 | authors of previous versions.
49 |
50 | Some devices are designed to deny users access to install or run
51 | modified versions of the software inside them, although the manufacturer
52 | can do so. This is fundamentally incompatible with the aim of
53 | protecting users' freedom to change the software. The systematic
54 | pattern of such abuse occurs in the area of products for individuals to
55 | use, which is precisely where it is most unacceptable. Therefore, we
56 | have designed this version of the GPL to prohibit the practice for those
57 | products. If such problems arise substantially in other domains, we
58 | stand ready to extend this provision to those domains in future versions
59 | of the GPL, as needed to protect the freedom of users.
60 |
61 | Finally, every program is threatened constantly by software patents.
62 | States should not allow patents to restrict development and use of
63 | software on general-purpose computers, but in those that do, we wish to
64 | avoid the special danger that patents applied to a free program could
65 | make it effectively proprietary. To prevent this, the GPL assures that
66 | patents cannot be used to render the program non-free.
67 |
68 | The precise terms and conditions for copying, distribution and
69 | modification follow.
70 |
71 | TERMS AND CONDITIONS
72 |
73 | 0. Definitions.
74 |
75 | "This License" refers to version 3 of the GNU General Public License.
76 |
77 | "Copyright" also means copyright-like laws that apply to other kinds of
78 | works, such as semiconductor masks.
79 |
80 | "The Program" refers to any copyrightable work licensed under this
81 | License. Each licensee is addressed as "you". "Licensees" and
82 | "recipients" may be individuals or organizations.
83 |
84 | To "modify" a work means to copy from or adapt all or part of the work
85 | in a fashion requiring copyright permission, other than the making of an
86 | exact copy. The resulting work is called a "modified version" of the
87 | earlier work or a work "based on" the earlier work.
88 |
89 | A "covered work" means either the unmodified Program or a work based
90 | on the Program.
91 |
92 | To "propagate" a work means to do anything with it that, without
93 | permission, would make you directly or secondarily liable for
94 | infringement under applicable copyright law, except executing it on a
95 | computer or modifying a private copy. Propagation includes copying,
96 | distribution (with or without modification), making available to the
97 | public, and in some countries other activities as well.
98 |
99 | To "convey" a work means any kind of propagation that enables other
100 | parties to make or receive copies. Mere interaction with a user through
101 | a computer network, with no transfer of a copy, is not conveying.
102 |
103 | An interactive user interface displays "Appropriate Legal Notices"
104 | to the extent that it includes a convenient and prominently visible
105 | feature that (1) displays an appropriate copyright notice, and (2)
106 | tells the user that there is no warranty for the work (except to the
107 | extent that warranties are provided), that licensees may convey the
108 | work under this License, and how to view a copy of this License. If
109 | the interface presents a list of user commands or options, such as a
110 | menu, a prominent item in the list meets this criterion.
111 |
112 | 1. Source Code.
113 |
114 | The "source code" for a work means the preferred form of the work
115 | for making modifications to it. "Object code" means any non-source
116 | form of a work.
117 |
118 | A "Standard Interface" means an interface that either is an official
119 | standard defined by a recognized standards body, or, in the case of
120 | interfaces specified for a particular programming language, one that
121 | is widely used among developers working in that language.
122 |
123 | The "System Libraries" of an executable work include anything, other
124 | than the work as a whole, that (a) is included in the normal form of
125 | packaging a Major Component, but which is not part of that Major
126 | Component, and (b) serves only to enable use of the work with that
127 | Major Component, or to implement a Standard Interface for which an
128 | implementation is available to the public in source code form. A
129 | "Major Component", in this context, means a major essential component
130 | (kernel, window system, and so on) of the specific operating system
131 | (if any) on which the executable work runs, or a compiler used to
132 | produce the work, or an object code interpreter used to run it.
133 |
134 | The "Corresponding Source" for a work in object code form means all
135 | the source code needed to generate, install, and (for an executable
136 | work) run the object code and to modify the work, including scripts to
137 | control those activities. However, it does not include the work's
138 | System Libraries, or general-purpose tools or generally available free
139 | programs which are used unmodified in performing those activities but
140 | which are not part of the work. For example, Corresponding Source
141 | includes interface definition files associated with source files for
142 | the work, and the source code for shared libraries and dynamically
143 | linked subprograms that the work is specifically designed to require,
144 | such as by intimate data communication or control flow between those
145 | subprograms and other parts of the work.
146 |
147 | The Corresponding Source need not include anything that users
148 | can regenerate automatically from other parts of the Corresponding
149 | Source.
150 |
151 | The Corresponding Source for a work in source code form is that
152 | same work.
153 |
154 | 2. Basic Permissions.
155 |
156 | All rights granted under this License are granted for the term of
157 | copyright on the Program, and are irrevocable provided the stated
158 | conditions are met. This License explicitly affirms your unlimited
159 | permission to run the unmodified Program. The output from running a
160 | covered work is covered by this License only if the output, given its
161 | content, constitutes a covered work. This License acknowledges your
162 | rights of fair use or other equivalent, as provided by copyright law.
163 |
164 | You may make, run and propagate covered works that you do not
165 | convey, without conditions so long as your license otherwise remains
166 | in force. You may convey covered works to others for the sole purpose
167 | of having them make modifications exclusively for you, or provide you
168 | with facilities for running those works, provided that you comply with
169 | the terms of this License in conveying all material for which you do
170 | not control copyright. Those thus making or running the covered works
171 | for you must do so exclusively on your behalf, under your direction
172 | and control, on terms that prohibit them from making any copies of
173 | your copyrighted material outside their relationship with you.
174 |
175 | Conveying under any other circumstances is permitted solely under
176 | the conditions stated below. Sublicensing is not allowed; section 10
177 | makes it unnecessary.
178 |
179 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
180 |
181 | No covered work shall be deemed part of an effective technological
182 | measure under any applicable law fulfilling obligations under article
183 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or
184 | similar laws prohibiting or restricting circumvention of such
185 | measures.
186 |
187 | When you convey a covered work, you waive any legal power to forbid
188 | circumvention of technological measures to the extent such circumvention
189 | is effected by exercising rights under this License with respect to
190 | the covered work, and you disclaim any intention to limit operation or
191 | modification of the work as a means of enforcing, against the work's
192 | users, your or third parties' legal rights to forbid circumvention of
193 | technological measures.
194 |
195 | 4. Conveying Verbatim Copies.
196 |
197 | You may convey verbatim copies of the Program's source code as you
198 | receive it, in any medium, provided that you conspicuously and
199 | appropriately publish on each copy an appropriate copyright notice;
200 | keep intact all notices stating that this License and any
201 | non-permissive terms added in accord with section 7 apply to the code;
202 | keep intact all notices of the absence of any warranty; and give all
203 | recipients a copy of this License along with the Program.
204 |
205 | You may charge any price or no price for each copy that you convey,
206 | and you may offer support or warranty protection for a fee.
207 |
208 | 5. Conveying Modified Source Versions.
209 |
210 | You may convey a work based on the Program, or the modifications to
211 | produce it from the Program, in the form of source code under the
212 | terms of section 4, provided that you also meet all of these conditions:
213 |
214 | a) The work must carry prominent notices stating that you modified
215 | it, and giving a relevant date.
216 |
217 | b) The work must carry prominent notices stating that it is
218 | released under this License and any conditions added under section
219 | 7. This requirement modifies the requirement in section 4 to
220 | "keep intact all notices".
221 |
222 | c) You must license the entire work, as a whole, under this
223 | License to anyone who comes into possession of a copy. This
224 | License will therefore apply, along with any applicable section 7
225 | additional terms, to the whole of the work, and all its parts,
226 | regardless of how they are packaged. This License gives no
227 | permission to license the work in any other way, but it does not
228 | invalidate such permission if you have separately received it.
229 |
230 | d) If the work has interactive user interfaces, each must display
231 | Appropriate Legal Notices; however, if the Program has interactive
232 | interfaces that do not display Appropriate Legal Notices, your
233 | work need not make them do so.
234 |
235 | A compilation of a covered work with other separate and independent
236 | works, which are not by their nature extensions of the covered work,
237 | and which are not combined with it such as to form a larger program,
238 | in or on a volume of a storage or distribution medium, is called an
239 | "aggregate" if the compilation and its resulting copyright are not
240 | used to limit the access or legal rights of the compilation's users
241 | beyond what the individual works permit. Inclusion of a covered work
242 | in an aggregate does not cause this License to apply to the other
243 | parts of the aggregate.
244 |
245 | 6. Conveying Non-Source Forms.
246 |
247 | You may convey a covered work in object code form under the terms
248 | of sections 4 and 5, provided that you also convey the
249 | machine-readable Corresponding Source under the terms of this License,
250 | in one of these ways:
251 |
252 | a) Convey the object code in, or embodied in, a physical product
253 | (including a physical distribution medium), accompanied by the
254 | Corresponding Source fixed on a durable physical medium
255 | customarily used for software interchange.
256 |
257 | b) Convey the object code in, or embodied in, a physical product
258 | (including a physical distribution medium), accompanied by a
259 | written offer, valid for at least three years and valid for as
260 | long as you offer spare parts or customer support for that product
261 | model, to give anyone who possesses the object code either (1) a
262 | copy of the Corresponding Source for all the software in the
263 | product that is covered by this License, on a durable physical
264 | medium customarily used for software interchange, for a price no
265 | more than your reasonable cost of physically performing this
266 | conveying of source, or (2) access to copy the
267 | Corresponding Source from a network server at no charge.
268 |
269 | c) Convey individual copies of the object code with a copy of the
270 | written offer to provide the Corresponding Source. This
271 | alternative is allowed only occasionally and noncommercially, and
272 | only if you received the object code with such an offer, in accord
273 | with subsection 6b.
274 |
275 | d) Convey the object code by offering access from a designated
276 | place (gratis or for a charge), and offer equivalent access to the
277 | Corresponding Source in the same way through the same place at no
278 | further charge. You need not require recipients to copy the
279 | Corresponding Source along with the object code. If the place to
280 | copy the object code is a network server, the Corresponding Source
281 | may be on a different server (operated by you or a third party)
282 | that supports equivalent copying facilities, provided you maintain
283 | clear directions next to the object code saying where to find the
284 | Corresponding Source. Regardless of what server hosts the
285 | Corresponding Source, you remain obligated to ensure that it is
286 | available for as long as needed to satisfy these requirements.
287 |
288 | e) Convey the object code using peer-to-peer transmission, provided
289 | you inform other peers where the object code and Corresponding
290 | Source of the work are being offered to the general public at no
291 | charge under subsection 6d.
292 |
293 | A separable portion of the object code, whose source code is excluded
294 | from the Corresponding Source as a System Library, need not be
295 | included in conveying the object code work.
296 |
297 | A "User Product" is either (1) a "consumer product", which means any
298 | tangible personal property which is normally used for personal, family,
299 | or household purposes, or (2) anything designed or sold for incorporation
300 | into a dwelling. In determining whether a product is a consumer product,
301 | doubtful cases shall be resolved in favor of coverage. For a particular
302 | product received by a particular user, "normally used" refers to a
303 | typical or common use of that class of product, regardless of the status
304 | of the particular user or of the way in which the particular user
305 | actually uses, or expects or is expected to use, the product. A product
306 | is a consumer product regardless of whether the product has substantial
307 | commercial, industrial or non-consumer uses, unless such uses represent
308 | the only significant mode of use of the product.
309 |
310 | "Installation Information" for a User Product means any methods,
311 | procedures, authorization keys, or other information required to install
312 | and execute modified versions of a covered work in that User Product from
313 | a modified version of its Corresponding Source. The information must
314 | suffice to ensure that the continued functioning of the modified object
315 | code is in no case prevented or interfered with solely because
316 | modification has been made.
317 |
318 | If you convey an object code work under this section in, or with, or
319 | specifically for use in, a User Product, and the conveying occurs as
320 | part of a transaction in which the right of possession and use of the
321 | User Product is transferred to the recipient in perpetuity or for a
322 | fixed term (regardless of how the transaction is characterized), the
323 | Corresponding Source conveyed under this section must be accompanied
324 | by the Installation Information. But this requirement does not apply
325 | if neither you nor any third party retains the ability to install
326 | modified object code on the User Product (for example, the work has
327 | been installed in ROM).
328 |
329 | The requirement to provide Installation Information does not include a
330 | requirement to continue to provide support service, warranty, or updates
331 | for a work that has been modified or installed by the recipient, or for
332 | the User Product in which it has been modified or installed. Access to a
333 | network may be denied when the modification itself materially and
334 | adversely affects the operation of the network or violates the rules and
335 | protocols for communication across the network.
336 |
337 | Corresponding Source conveyed, and Installation Information provided,
338 | in accord with this section must be in a format that is publicly
339 | documented (and with an implementation available to the public in
340 | source code form), and must require no special password or key for
341 | unpacking, reading or copying.
342 |
343 | 7. Additional Terms.
344 |
345 | "Additional permissions" are terms that supplement the terms of this
346 | License by making exceptions from one or more of its conditions.
347 | Additional permissions that are applicable to the entire Program shall
348 | be treated as though they were included in this License, to the extent
349 | that they are valid under applicable law. If additional permissions
350 | apply only to part of the Program, that part may be used separately
351 | under those permissions, but the entire Program remains governed by
352 | this License without regard to the additional permissions.
353 |
354 | When you convey a copy of a covered work, you may at your option
355 | remove any additional permissions from that copy, or from any part of
356 | it. (Additional permissions may be written to require their own
357 | removal in certain cases when you modify the work.) You may place
358 | additional permissions on material, added by you to a covered work,
359 | for which you have or can give appropriate copyright permission.
360 |
361 | Notwithstanding any other provision of this License, for material you
362 | add to a covered work, you may (if authorized by the copyright holders of
363 | that material) supplement the terms of this License with terms:
364 |
365 | a) Disclaiming warranty or limiting liability differently from the
366 | terms of sections 15 and 16 of this License; or
367 |
368 | b) Requiring preservation of specified reasonable legal notices or
369 | author attributions in that material or in the Appropriate Legal
370 | Notices displayed by works containing it; or
371 |
372 | c) Prohibiting misrepresentation of the origin of that material, or
373 | requiring that modified versions of such material be marked in
374 | reasonable ways as different from the original version; or
375 |
376 | d) Limiting the use for publicity purposes of names of licensors or
377 | authors of the material; or
378 |
379 | e) Declining to grant rights under trademark law for use of some
380 | trade names, trademarks, or service marks; or
381 |
382 | f) Requiring indemnification of licensors and authors of that
383 | material by anyone who conveys the material (or modified versions of
384 | it) with contractual assumptions of liability to the recipient, for
385 | any liability that these contractual assumptions directly impose on
386 | those licensors and authors.
387 |
388 | All other non-permissive additional terms are considered "further
389 | restrictions" within the meaning of section 10. If the Program as you
390 | received it, or any part of it, contains a notice stating that it is
391 | governed by this License along with a term that is a further
392 | restriction, you may remove that term. If a license document contains
393 | a further restriction but permits relicensing or conveying under this
394 | License, you may add to a covered work material governed by the terms
395 | of that license document, provided that the further restriction does
396 | not survive such relicensing or conveying.
397 |
398 | If you add terms to a covered work in accord with this section, you
399 | must place, in the relevant source files, a statement of the
400 | additional terms that apply to those files, or a notice indicating
401 | where to find the applicable terms.
402 |
403 | Additional terms, permissive or non-permissive, may be stated in the
404 | form of a separately written license, or stated as exceptions;
405 | the above requirements apply either way.
406 |
407 | 8. Termination.
408 |
409 | You may not propagate or modify a covered work except as expressly
410 | provided under this License. Any attempt otherwise to propagate or
411 | modify it is void, and will automatically terminate your rights under
412 | this License (including any patent licenses granted under the third
413 | paragraph of section 11).
414 |
415 | However, if you cease all violation of this License, then your
416 | license from a particular copyright holder is reinstated (a)
417 | provisionally, unless and until the copyright holder explicitly and
418 | finally terminates your license, and (b) permanently, if the copyright
419 | holder fails to notify you of the violation by some reasonable means
420 | prior to 60 days after the cessation.
421 |
422 | Moreover, your license from a particular copyright holder is
423 | reinstated permanently if the copyright holder notifies you of the
424 | violation by some reasonable means, this is the first time you have
425 | received notice of violation of this License (for any work) from that
426 | copyright holder, and you cure the violation prior to 30 days after
427 | your receipt of the notice.
428 |
429 | Termination of your rights under this section does not terminate the
430 | licenses of parties who have received copies or rights from you under
431 | this License. If your rights have been terminated and not permanently
432 | reinstated, you do not qualify to receive new licenses for the same
433 | material under section 10.
434 |
435 | 9. Acceptance Not Required for Having Copies.
436 |
437 | You are not required to accept this License in order to receive or
438 | run a copy of the Program. Ancillary propagation of a covered work
439 | occurring solely as a consequence of using peer-to-peer transmission
440 | to receive a copy likewise does not require acceptance. However,
441 | nothing other than this License grants you permission to propagate or
442 | modify any covered work. These actions infringe copyright if you do
443 | not accept this License. Therefore, by modifying or propagating a
444 | covered work, you indicate your acceptance of this License to do so.
445 |
446 | 10. Automatic Licensing of Downstream Recipients.
447 |
448 | Each time you convey a covered work, the recipient automatically
449 | receives a license from the original licensors, to run, modify and
450 | propagate that work, subject to this License. You are not responsible
451 | for enforcing compliance by third parties with this License.
452 |
453 | An "entity transaction" is a transaction transferring control of an
454 | organization, or substantially all assets of one, or subdividing an
455 | organization, or merging organizations. If propagation of a covered
456 | work results from an entity transaction, each party to that
457 | transaction who receives a copy of the work also receives whatever
458 | licenses to the work the party's predecessor in interest had or could
459 | give under the previous paragraph, plus a right to possession of the
460 | Corresponding Source of the work from the predecessor in interest, if
461 | the predecessor has it or can get it with reasonable efforts.
462 |
463 | You may not impose any further restrictions on the exercise of the
464 | rights granted or affirmed under this License. For example, you may
465 | not impose a license fee, royalty, or other charge for exercise of
466 | rights granted under this License, and you may not initiate litigation
467 | (including a cross-claim or counterclaim in a lawsuit) alleging that
468 | any patent claim is infringed by making, using, selling, offering for
469 | sale, or importing the Program or any portion of it.
470 |
471 | 11. Patents.
472 |
473 | A "contributor" is a copyright holder who authorizes use under this
474 | License of the Program or a work on which the Program is based. The
475 | work thus licensed is called the contributor's "contributor version".
476 |
477 | A contributor's "essential patent claims" are all patent claims
478 | owned or controlled by the contributor, whether already acquired or
479 | hereafter acquired, that would be infringed by some manner, permitted
480 | by this License, of making, using, or selling its contributor version,
481 | but do not include claims that would be infringed only as a
482 | consequence of further modification of the contributor version. For
483 | purposes of this definition, "control" includes the right to grant
484 | patent sublicenses in a manner consistent with the requirements of
485 | this License.
486 |
487 | Each contributor grants you a non-exclusive, worldwide, royalty-free
488 | patent license under the contributor's essential patent claims, to
489 | make, use, sell, offer for sale, import and otherwise run, modify and
490 | propagate the contents of its contributor version.
491 |
492 | In the following three paragraphs, a "patent license" is any express
493 | agreement or commitment, however denominated, not to enforce a patent
494 | (such as an express permission to practice a patent or covenant not to
495 | sue for patent infringement). To "grant" such a patent license to a
496 | party means to make such an agreement or commitment not to enforce a
497 | patent against the party.
498 |
499 | If you convey a covered work, knowingly relying on a patent license,
500 | and the Corresponding Source of the work is not available for anyone
501 | to copy, free of charge and under the terms of this License, through a
502 | publicly available network server or other readily accessible means,
503 | then you must either (1) cause the Corresponding Source to be so
504 | available, or (2) arrange to deprive yourself of the benefit of the
505 | patent license for this particular work, or (3) arrange, in a manner
506 | consistent with the requirements of this License, to extend the patent
507 | license to downstream recipients. "Knowingly relying" means you have
508 | actual knowledge that, but for the patent license, your conveying the
509 | covered work in a country, or your recipient's use of the covered work
510 | in a country, would infringe one or more identifiable patents in that
511 | country that you have reason to believe are valid.
512 |
513 | If, pursuant to or in connection with a single transaction or
514 | arrangement, you convey, or propagate by procuring conveyance of, a
515 | covered work, and grant a patent license to some of the parties
516 | receiving the covered work authorizing them to use, propagate, modify
517 | or convey a specific copy of the covered work, then the patent license
518 | you grant is automatically extended to all recipients of the covered
519 | work and works based on it.
520 |
521 | A patent license is "discriminatory" if it does not include within
522 | the scope of its coverage, prohibits the exercise of, or is
523 | conditioned on the non-exercise of one or more of the rights that are
524 | specifically granted under this License. You may not convey a covered
525 | work if you are a party to an arrangement with a third party that is
526 | in the business of distributing software, under which you make payment
527 | to the third party based on the extent of your activity of conveying
528 | the work, and under which the third party grants, to any of the
529 | parties who would receive the covered work from you, a discriminatory
530 | patent license (a) in connection with copies of the covered work
531 | conveyed by you (or copies made from those copies), or (b) primarily
532 | for and in connection with specific products or compilations that
533 | contain the covered work, unless you entered into that arrangement,
534 | or that patent license was granted, prior to 28 March 2007.
535 |
536 | Nothing in this License shall be construed as excluding or limiting
537 | any implied license or other defenses to infringement that may
538 | otherwise be available to you under applicable patent law.
539 |
540 | 12. No Surrender of Others' Freedom.
541 |
542 | If conditions are imposed on you (whether by court order, agreement or
543 | otherwise) that contradict the conditions of this License, they do not
544 | excuse you from the conditions of this License. If you cannot convey a
545 | covered work so as to satisfy simultaneously your obligations under this
546 | License and any other pertinent obligations, then as a consequence you may
547 | not convey it at all. For example, if you agree to terms that obligate you
548 | to collect a royalty for further conveying from those to whom you convey
549 | the Program, the only way you could satisfy both those terms and this
550 | License would be to refrain entirely from conveying the Program.
551 |
552 | 13. Use with the GNU Affero General Public License.
553 |
554 | Notwithstanding any other provision of this License, you have
555 | permission to link or combine any covered work with a work licensed
556 | under version 3 of the GNU Affero General Public License into a single
557 | combined work, and to convey the resulting work. The terms of this
558 | License will continue to apply to the part which is the covered work,
559 | but the special requirements of the GNU Affero General Public License,
560 | section 13, concerning interaction through a network will apply to the
561 | combination as such.
562 |
563 | 14. Revised Versions of this License.
564 |
565 | The Free Software Foundation may publish revised and/or new versions of
566 | the GNU General Public License from time to time. Such new versions will
567 | be similar in spirit to the present version, but may differ in detail to
568 | address new problems or concerns.
569 |
570 | Each version is given a distinguishing version number. If the
571 | Program specifies that a certain numbered version of the GNU General
572 | Public License "or any later version" applies to it, you have the
573 | option of following the terms and conditions either of that numbered
574 | version or of any later version published by the Free Software
575 | Foundation. If the Program does not specify a version number of the
576 | GNU General Public License, you may choose any version ever published
577 | by the Free Software Foundation.
578 |
579 | If the Program specifies that a proxy can decide which future
580 | versions of the GNU General Public License can be used, that proxy's
581 | public statement of acceptance of a version permanently authorizes you
582 | to choose that version for the Program.
583 |
584 | Later license versions may give you additional or different
585 | permissions. However, no additional obligations are imposed on any
586 | author or copyright holder as a result of your choosing to follow a
587 | later version.
588 |
589 | 15. Disclaimer of Warranty.
590 |
591 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
592 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
593 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
594 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
595 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
596 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
597 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
598 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
599 |
600 | 16. Limitation of Liability.
601 |
602 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
603 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
604 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
605 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
606 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
607 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
608 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
609 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
610 | SUCH DAMAGES.
611 |
612 | 17. Interpretation of Sections 15 and 16.
613 |
614 | If the disclaimer of warranty and limitation of liability provided
615 | above cannot be given local legal effect according to their terms,
616 | reviewing courts shall apply local law that most closely approximates
617 | an absolute waiver of all civil liability in connection with the
618 | Program, unless a warranty or assumption of liability accompanies a
619 | copy of the Program in return for a fee.
620 |
621 | END OF TERMS AND CONDITIONS
622 |
623 | How to Apply These Terms to Your New Programs
624 |
625 | If you develop a new program, and you want it to be of the greatest
626 | possible use to the public, the best way to achieve this is to make it
627 | free software which everyone can redistribute and change under these terms.
628 |
629 | To do so, attach the following notices to the program. It is safest
630 | to attach them to the start of each source file to most effectively
631 | state the exclusion of warranty; and each file should have at least
632 | the "copyright" line and a pointer to where the full notice is found.
633 |
634 |
635 | Copyright (C)
636 |
637 | This program is free software: you can redistribute it and/or modify
638 | it under the terms of the GNU General Public License as published by
639 | the Free Software Foundation, either version 3 of the License, or
640 | (at your option) any later version.
641 |
642 | This program is distributed in the hope that it will be useful,
643 | but WITHOUT ANY WARRANTY; without even the implied warranty of
644 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
645 | GNU General Public License for more details.
646 |
647 | You should have received a copy of the GNU General Public License
648 | along with this program. If not, see .
649 |
650 | Also add information on how to contact you by electronic and paper mail.
651 |
652 | If the program does terminal interaction, make it output a short
653 | notice like this when it starts in an interactive mode:
654 |
655 | Copyright (C)
656 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
657 | This is free software, and you are welcome to redistribute it
658 | under certain conditions; type `show c' for details.
659 |
660 | The hypothetical commands `show w' and `show c' should show the appropriate
661 | parts of the General Public License. Of course, your program's commands
662 | might be different; for a GUI interface, you would use an "about box".
663 |
664 | You should also get your employer (if you work as a programmer) or school,
665 | if any, to sign a "copyright disclaimer" for the program, if necessary.
666 | For more information on this, and how to apply and follow the GNU GPL, see
667 | .
668 |
669 | The GNU General Public License does not permit incorporating your program
670 | into proprietary programs. If your program is a subroutine library, you
671 | may consider it more useful to permit linking proprietary applications with
672 | the library. If this is what you want to do, use the GNU Lesser General
673 | Public License instead of this License. But first, please read
674 | .
675 |
--------------------------------------------------------------------------------
/inputdeviceindicator/info.py:
--------------------------------------------------------------------------------
1 | # Copyright © 2020 Adam Brandizzi
2 | #
3 | # This file is part of Input Device Indicator.
4 | #
5 | # Input Device Indicator is free software: you can redistribute it and/or
6 | # modify it under the terms of the GNU General Public License as published by
7 | # the Free Software Foundation, either version 3 of the License, or (at your
8 | # option) any later version.
9 | #
10 | # Input Device Indicator is distributed in the hope that it will be useful, but
11 | # WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 | # FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 | # more details.
14 | #
15 | # You should have received a copy of the GNU General Public License along with
16 | # Input Device Indicator. If not, see
17 |
18 |
19 | import os.path
20 |
21 |
22 | def get_icon_path():
23 | """
24 | Returns the path to the application icon. Naturally, the application icon
25 | file should exist:
26 |
27 | >>> os.path.exists(get_icon_path())
28 | True
29 | """
30 | return os.path.join(
31 | os.path.dirname(__file__), 'resources/input-device-indicator.svg'
32 | )
33 |
34 |
35 | PROGRAM_NAME = 'Input Device Indicator'
36 | VERSION = '0.1.1'
37 | ICON_PATH = get_icon_path()
38 | DESCRIPTION = 'Enable and disables input devices such as keyboards, mouses and trackpads.'
39 | URL = 'https://github.com/brandizzi/input-device-indicator'
40 | AUTHOR = 'Adam Brandizzi'
41 | COPYRIGHT = 'Copyright © 2020-present Adam Brandizzi'
42 | EMAIL = 'adam@brandizzi.com.br'
43 | LICENSE = """
44 | GNU GENERAL PUBLIC LICENSE
45 | Version 3, 29 June 2007
46 |
47 | Copyright (C) 2007 Free Software Foundation, Inc.
48 | Everyone is permitted to copy and distribute verbatim copies
49 | of this license document, but changing it is not allowed.
50 |
51 | Preamble
52 |
53 | The GNU General Public License is a free, copyleft license for
54 | software and other kinds of works.
55 |
56 | The licenses for most software and other practical works are designed
57 | to take away your freedom to share and change the works. By contrast,
58 | the GNU General Public License is intended to guarantee your freedom to
59 | share and change all versions of a program--to make sure it remains free
60 | software for all its users. We, the Free Software Foundation, use the
61 | GNU General Public License for most of our software; it applies also to
62 | any other work released this way by its authors. You can apply it to
63 | your programs, too.
64 |
65 | When we speak of free software, we are referring to freedom, not
66 | price. Our General Public Licenses are designed to make sure that you
67 | have the freedom to distribute copies of free software (and charge for
68 | them if you wish), that you receive source code or can get it if you
69 | want it, that you can change the software or use pieces of it in new
70 | free programs, and that you know you can do these things.
71 |
72 | To protect your rights, we need to prevent others from denying you
73 | these rights or asking you to surrender the rights. Therefore, you have
74 | certain responsibilities if you distribute copies of the software, or if
75 | you modify it: responsibilities to respect the freedom of others.
76 |
77 | For example, if you distribute copies of such a program, whether
78 | gratis or for a fee, you must pass on to the recipients the same
79 | freedoms that you received. You must make sure that they, too, receive
80 | or can get the source code. And you must show them these terms so they
81 | know their rights.
82 |
83 | Developers that use the GNU GPL protect your rights with two steps:
84 | (1) assert copyright on the software, and (2) offer you this License
85 | giving you legal permission to copy, distribute and/or modify it.
86 |
87 | For the developers' and authors' protection, the GPL clearly explains
88 | that there is no warranty for this free software. For both users' and
89 | authors' sake, the GPL requires that modified versions be marked as
90 | changed, so that their problems will not be attributed erroneously to
91 | authors of previous versions.
92 |
93 | Some devices are designed to deny users access to install or run
94 | modified versions of the software inside them, although the manufacturer
95 | can do so. This is fundamentally incompatible with the aim of
96 | protecting users' freedom to change the software. The systematic
97 | pattern of such abuse occurs in the area of products for individuals to
98 | use, which is precisely where it is most unacceptable. Therefore, we
99 | have designed this version of the GPL to prohibit the practice for those
100 | products. If such problems arise substantially in other domains, we
101 | stand ready to extend this provision to those domains in future versions
102 | of the GPL, as needed to protect the freedom of users.
103 |
104 | Finally, every program is threatened constantly by software patents.
105 | States should not allow patents to restrict development and use of
106 | software on general-purpose computers, but in those that do, we wish to
107 | avoid the special danger that patents applied to a free program could
108 | make it effectively proprietary. To prevent this, the GPL assures that
109 | patents cannot be used to render the program non-free.
110 |
111 | The precise terms and conditions for copying, distribution and
112 | modification follow.
113 |
114 | TERMS AND CONDITIONS
115 |
116 | 0. Definitions.
117 |
118 | "This License" refers to version 3 of the GNU General Public License.
119 |
120 | "Copyright" also means copyright-like laws that apply to other kinds of
121 | works, such as semiconductor masks.
122 |
123 | "The Program" refers to any copyrightable work licensed under this
124 | License. Each licensee is addressed as "you". "Licensees" and
125 | "recipients" may be individuals or organizations.
126 |
127 | To "modify" a work means to copy from or adapt all or part of the work
128 | in a fashion requiring copyright permission, other than the making of an
129 | exact copy. The resulting work is called a "modified version" of the
130 | earlier work or a work "based on" the earlier work.
131 |
132 | A "covered work" means either the unmodified Program or a work based
133 | on the Program.
134 |
135 | To "propagate" a work means to do anything with it that, without
136 | permission, would make you directly or secondarily liable for
137 | infringement under applicable copyright law, except executing it on a
138 | computer or modifying a private copy. Propagation includes copying,
139 | distribution (with or without modification), making available to the
140 | public, and in some countries other activities as well.
141 |
142 | To "convey" a work means any kind of propagation that enables other
143 | parties to make or receive copies. Mere interaction with a user through
144 | a computer network, with no transfer of a copy, is not conveying.
145 |
146 | An interactive user interface displays "Appropriate Legal Notices"
147 | to the extent that it includes a convenient and prominently visible
148 | feature that (1) displays an appropriate copyright notice, and (2)
149 | tells the user that there is no warranty for the work (except to the
150 | extent that warranties are provided), that licensees may convey the
151 | work under this License, and how to view a copy of this License. If
152 | the interface presents a list of user commands or options, such as a
153 | menu, a prominent item in the list meets this criterion.
154 |
155 | 1. Source Code.
156 |
157 | The "source code" for a work means the preferred form of the work
158 | for making modifications to it. "Object code" means any non-source
159 | form of a work.
160 |
161 | A "Standard Interface" means an interface that either is an official
162 | standard defined by a recognized standards body, or, in the case of
163 | interfaces specified for a particular programming language, one that
164 | is widely used among developers working in that language.
165 |
166 | The "System Libraries" of an executable work include anything, other
167 | than the work as a whole, that (a) is included in the normal form of
168 | packaging a Major Component, but which is not part of that Major
169 | Component, and (b) serves only to enable use of the work with that
170 | Major Component, or to implement a Standard Interface for which an
171 | implementation is available to the public in source code form. A
172 | "Major Component", in this context, means a major essential component
173 | (kernel, window system, and so on) of the specific operating system
174 | (if any) on which the executable work runs, or a compiler used to
175 | produce the work, or an object code interpreter used to run it.
176 |
177 | The "Corresponding Source" for a work in object code form means all
178 | the source code needed to generate, install, and (for an executable
179 | work) run the object code and to modify the work, including scripts to
180 | control those activities. However, it does not include the work's
181 | System Libraries, or general-purpose tools or generally available free
182 | programs which are used unmodified in performing those activities but
183 | which are not part of the work. For example, Corresponding Source
184 | includes interface definition files associated with source files for
185 | the work, and the source code for shared libraries and dynamically
186 | linked subprograms that the work is specifically designed to require,
187 | such as by intimate data communication or control flow between those
188 | subprograms and other parts of the work.
189 |
190 | The Corresponding Source need not include anything that users
191 | can regenerate automatically from other parts of the Corresponding
192 | Source.
193 |
194 | The Corresponding Source for a work in source code form is that
195 | same work.
196 |
197 | 2. Basic Permissions.
198 |
199 | All rights granted under this License are granted for the term of
200 | copyright on the Program, and are irrevocable provided the stated
201 | conditions are met. This License explicitly affirms your unlimited
202 | permission to run the unmodified Program. The output from running a
203 | covered work is covered by this License only if the output, given its
204 | content, constitutes a covered work. This License acknowledges your
205 | rights of fair use or other equivalent, as provided by copyright law.
206 |
207 | You may make, run and propagate covered works that you do not
208 | convey, without conditions so long as your license otherwise remains
209 | in force. You may convey covered works to others for the sole purpose
210 | of having them make modifications exclusively for you, or provide you
211 | with facilities for running those works, provided that you comply with
212 | the terms of this License in conveying all material for which you do
213 | not control copyright. Those thus making or running the covered works
214 | for you must do so exclusively on your behalf, under your direction
215 | and control, on terms that prohibit them from making any copies of
216 | your copyrighted material outside their relationship with you.
217 |
218 | Conveying under any other circumstances is permitted solely under
219 | the conditions stated below. Sublicensing is not allowed; section 10
220 | makes it unnecessary.
221 |
222 | 3. Protecting Users' Legal Rights From Anti-Circumvention Law.
223 |
224 | No covered work shall be deemed part of an effective technological
225 | measure under any applicable law fulfilling obligations under article
226 | 11 of the WIPO copyright treaty adopted on 20 December 1996, or
227 | similar laws prohibiting or restricting circumvention of such
228 | measures.
229 |
230 | When you convey a covered work, you waive any legal power to forbid
231 | circumvention of technological measures to the extent such circumvention
232 | is effected by exercising rights under this License with respect to
233 | the covered work, and you disclaim any intention to limit operation or
234 | modification of the work as a means of enforcing, against the work's
235 | users, your or third parties' legal rights to forbid circumvention of
236 | technological measures.
237 |
238 | 4. Conveying Verbatim Copies.
239 |
240 | You may convey verbatim copies of the Program's source code as you
241 | receive it, in any medium, provided that you conspicuously and
242 | appropriately publish on each copy an appropriate copyright notice;
243 | keep intact all notices stating that this License and any
244 | non-permissive terms added in accord with section 7 apply to the code;
245 | keep intact all notices of the absence of any warranty; and give all
246 | recipients a copy of this License along with the Program.
247 |
248 | You may charge any price or no price for each copy that you convey,
249 | and you may offer support or warranty protection for a fee.
250 |
251 | 5. Conveying Modified Source Versions.
252 |
253 | You may convey a work based on the Program, or the modifications to
254 | produce it from the Program, in the form of source code under the
255 | terms of section 4, provided that you also meet all of these conditions:
256 |
257 | a) The work must carry prominent notices stating that you modified
258 | it, and giving a relevant date.
259 |
260 | b) The work must carry prominent notices stating that it is
261 | released under this License and any conditions added under section
262 | 7. This requirement modifies the requirement in section 4 to
263 | "keep intact all notices".
264 |
265 | c) You must license the entire work, as a whole, under this
266 | License to anyone who comes into possession of a copy. This
267 | License will therefore apply, along with any applicable section 7
268 | additional terms, to the whole of the work, and all its parts,
269 | regardless of how they are packaged. This License gives no
270 | permission to license the work in any other way, but it does not
271 | invalidate such permission if you have separately received it.
272 |
273 | d) If the work has interactive user interfaces, each must display
274 | Appropriate Legal Notices; however, if the Program has interactive
275 | interfaces that do not display Appropriate Legal Notices, your
276 | work need not make them do so.
277 |
278 | A compilation of a covered work with other separate and independent
279 | works, which are not by their nature extensions of the covered work,
280 | and which are not combined with it such as to form a larger program,
281 | in or on a volume of a storage or distribution medium, is called an
282 | "aggregate" if the compilation and its resulting copyright are not
283 | used to limit the access or legal rights of the compilation's users
284 | beyond what the individual works permit. Inclusion of a covered work
285 | in an aggregate does not cause this License to apply to the other
286 | parts of the aggregate.
287 |
288 | 6. Conveying Non-Source Forms.
289 |
290 | You may convey a covered work in object code form under the terms
291 | of sections 4 and 5, provided that you also convey the
292 | machine-readable Corresponding Source under the terms of this License,
293 | in one of these ways:
294 |
295 | a) Convey the object code in, or embodied in, a physical product
296 | (including a physical distribution medium), accompanied by the
297 | Corresponding Source fixed on a durable physical medium
298 | customarily used for software interchange.
299 |
300 | b) Convey the object code in, or embodied in, a physical product
301 | (including a physical distribution medium), accompanied by a
302 | written offer, valid for at least three years and valid for as
303 | long as you offer spare parts or customer support for that product
304 | model, to give anyone who possesses the object code either (1) a
305 | copy of the Corresponding Source for all the software in the
306 | product that is covered by this License, on a durable physical
307 | medium customarily used for software interchange, for a price no
308 | more than your reasonable cost of physically performing this
309 | conveying of source, or (2) access to copy the
310 | Corresponding Source from a network server at no charge.
311 |
312 | c) Convey individual copies of the object code with a copy of the
313 | written offer to provide the Corresponding Source. This
314 | alternative is allowed only occasionally and noncommercially, and
315 | only if you received the object code with such an offer, in accord
316 | with subsection 6b.
317 |
318 | d) Convey the object code by offering access from a designated
319 | place (gratis or for a charge), and offer equivalent access to the
320 | Corresponding Source in the same way through the same place at no
321 | further charge. You need not require recipients to copy the
322 | Corresponding Source along with the object code. If the place to
323 | copy the object code is a network server, the Corresponding Source
324 | may be on a different server (operated by you or a third party)
325 | that supports equivalent copying facilities, provided you maintain
326 | clear directions next to the object code saying where to find the
327 | Corresponding Source. Regardless of what server hosts the
328 | Corresponding Source, you remain obligated to ensure that it is
329 | available for as long as needed to satisfy these requirements.
330 |
331 | e) Convey the object code using peer-to-peer transmission, provided
332 | you inform other peers where the object code and Corresponding
333 | Source of the work are being offered to the general public at no
334 | charge under subsection 6d.
335 |
336 | A separable portion of the object code, whose source code is excluded
337 | from the Corresponding Source as a System Library, need not be
338 | included in conveying the object code work.
339 |
340 | A "User Product" is either (1) a "consumer product", which means any
341 | tangible personal property which is normally used for personal, family,
342 | or household purposes, or (2) anything designed or sold for incorporation
343 | into a dwelling. In determining whether a product is a consumer product,
344 | doubtful cases shall be resolved in favor of coverage. For a particular
345 | product received by a particular user, "normally used" refers to a
346 | typical or common use of that class of product, regardless of the status
347 | of the particular user or of the way in which the particular user
348 | actually uses, or expects or is expected to use, the product. A product
349 | is a consumer product regardless of whether the product has substantial
350 | commercial, industrial or non-consumer uses, unless such uses represent
351 | the only significant mode of use of the product.
352 |
353 | "Installation Information" for a User Product means any methods,
354 | procedures, authorization keys, or other information required to install
355 | and execute modified versions of a covered work in that User Product from
356 | a modified version of its Corresponding Source. The information must
357 | suffice to ensure that the continued functioning of the modified object
358 | code is in no case prevented or interfered with solely because
359 | modification has been made.
360 |
361 | If you convey an object code work under this section in, or with, or
362 | specifically for use in, a User Product, and the conveying occurs as
363 | part of a transaction in which the right of possession and use of the
364 | User Product is transferred to the recipient in perpetuity or for a
365 | fixed term (regardless of how the transaction is characterized), the
366 | Corresponding Source conveyed under this section must be accompanied
367 | by the Installation Information. But this requirement does not apply
368 | if neither you nor any third party retains the ability to install
369 | modified object code on the User Product (for example, the work has
370 | been installed in ROM).
371 |
372 | The requirement to provide Installation Information does not include a
373 | requirement to continue to provide support service, warranty, or updates
374 | for a work that has been modified or installed by the recipient, or for
375 | the User Product in which it has been modified or installed. Access to a
376 | network may be denied when the modification itself materially and
377 | adversely affects the operation of the network or violates the rules and
378 | protocols for communication across the network.
379 |
380 | Corresponding Source conveyed, and Installation Information provided,
381 | in accord with this section must be in a format that is publicly
382 | documented (and with an implementation available to the public in
383 | source code form), and must require no special password or key for
384 | unpacking, reading or copying.
385 |
386 | 7. Additional Terms.
387 |
388 | "Additional permissions" are terms that supplement the terms of this
389 | License by making exceptions from one or more of its conditions.
390 | Additional permissions that are applicable to the entire Program shall
391 | be treated as though they were included in this License, to the extent
392 | that they are valid under applicable law. If additional permissions
393 | apply only to part of the Program, that part may be used separately
394 | under those permissions, but the entire Program remains governed by
395 | this License without regard to the additional permissions.
396 |
397 | When you convey a copy of a covered work, you may at your option
398 | remove any additional permissions from that copy, or from any part of
399 | it. (Additional permissions may be written to require their own
400 | removal in certain cases when you modify the work.) You may place
401 | additional permissions on material, added by you to a covered work,
402 | for which you have or can give appropriate copyright permission.
403 |
404 | Notwithstanding any other provision of this License, for material you
405 | add to a covered work, you may (if authorized by the copyright holders of
406 | that material) supplement the terms of this License with terms:
407 |
408 | a) Disclaiming warranty or limiting liability differently from the
409 | terms of sections 15 and 16 of this License; or
410 |
411 | b) Requiring preservation of specified reasonable legal notices or
412 | author attributions in that material or in the Appropriate Legal
413 | Notices displayed by works containing it; or
414 |
415 | c) Prohibiting misrepresentation of the origin of that material, or
416 | requiring that modified versions of such material be marked in
417 | reasonable ways as different from the original version; or
418 |
419 | d) Limiting the use for publicity purposes of names of licensors or
420 | authors of the material; or
421 |
422 | e) Declining to grant rights under trademark law for use of some
423 | trade names, trademarks, or service marks; or
424 |
425 | f) Requiring indemnification of licensors and authors of that
426 | material by anyone who conveys the material (or modified versions of
427 | it) with contractual assumptions of liability to the recipient, for
428 | any liability that these contractual assumptions directly impose on
429 | those licensors and authors.
430 |
431 | All other non-permissive additional terms are considered "further
432 | restrictions" within the meaning of section 10. If the Program as you
433 | received it, or any part of it, contains a notice stating that it is
434 | governed by this License along with a term that is a further
435 | restriction, you may remove that term. If a license document contains
436 | a further restriction but permits relicensing or conveying under this
437 | License, you may add to a covered work material governed by the terms
438 | of that license document, provided that the further restriction does
439 | not survive such relicensing or conveying.
440 |
441 | If you add terms to a covered work in accord with this section, you
442 | must place, in the relevant source files, a statement of the
443 | additional terms that apply to those files, or a notice indicating
444 | where to find the applicable terms.
445 |
446 | Additional terms, permissive or non-permissive, may be stated in the
447 | form of a separately written license, or stated as exceptions;
448 | the above requirements apply either way.
449 |
450 | 8. Termination.
451 |
452 | You may not propagate or modify a covered work except as expressly
453 | provided under this License. Any attempt otherwise to propagate or
454 | modify it is void, and will automatically terminate your rights under
455 | this License (including any patent licenses granted under the third
456 | paragraph of section 11).
457 |
458 | However, if you cease all violation of this License, then your
459 | license from a particular copyright holder is reinstated (a)
460 | provisionally, unless and until the copyright holder explicitly and
461 | finally terminates your license, and (b) permanently, if the copyright
462 | holder fails to notify you of the violation by some reasonable means
463 | prior to 60 days after the cessation.
464 |
465 | Moreover, your license from a particular copyright holder is
466 | reinstated permanently if the copyright holder notifies you of the
467 | violation by some reasonable means, this is the first time you have
468 | received notice of violation of this License (for any work) from that
469 | copyright holder, and you cure the violation prior to 30 days after
470 | your receipt of the notice.
471 |
472 | Termination of your rights under this section does not terminate the
473 | licenses of parties who have received copies or rights from you under
474 | this License. If your rights have been terminated and not permanently
475 | reinstated, you do not qualify to receive new licenses for the same
476 | material under section 10.
477 |
478 | 9. Acceptance Not Required for Having Copies.
479 |
480 | You are not required to accept this License in order to receive or
481 | run a copy of the Program. Ancillary propagation of a covered work
482 | occurring solely as a consequence of using peer-to-peer transmission
483 | to receive a copy likewise does not require acceptance. However,
484 | nothing other than this License grants you permission to propagate or
485 | modify any covered work. These actions infringe copyright if you do
486 | not accept this License. Therefore, by modifying or propagating a
487 | covered work, you indicate your acceptance of this License to do so.
488 |
489 | 10. Automatic Licensing of Downstream Recipients.
490 |
491 | Each time you convey a covered work, the recipient automatically
492 | receives a license from the original licensors, to run, modify and
493 | propagate that work, subject to this License. You are not responsible
494 | for enforcing compliance by third parties with this License.
495 |
496 | An "entity transaction" is a transaction transferring control of an
497 | organization, or substantially all assets of one, or subdividing an
498 | organization, or merging organizations. If propagation of a covered
499 | work results from an entity transaction, each party to that
500 | transaction who receives a copy of the work also receives whatever
501 | licenses to the work the party's predecessor in interest had or could
502 | give under the previous paragraph, plus a right to possession of the
503 | Corresponding Source of the work from the predecessor in interest, if
504 | the predecessor has it or can get it with reasonable efforts.
505 |
506 | You may not impose any further restrictions on the exercise of the
507 | rights granted or affirmed under this License. For example, you may
508 | not impose a license fee, royalty, or other charge for exercise of
509 | rights granted under this License, and you may not initiate litigation
510 | (including a cross-claim or counterclaim in a lawsuit) alleging that
511 | any patent claim is infringed by making, using, selling, offering for
512 | sale, or importing the Program or any portion of it.
513 |
514 | 11. Patents.
515 |
516 | A "contributor" is a copyright holder who authorizes use under this
517 | License of the Program or a work on which the Program is based. The
518 | work thus licensed is called the contributor's "contributor version".
519 |
520 | A contributor's "essential patent claims" are all patent claims
521 | owned or controlled by the contributor, whether already acquired or
522 | hereafter acquired, that would be infringed by some manner, permitted
523 | by this License, of making, using, or selling its contributor version,
524 | but do not include claims that would be infringed only as a
525 | consequence of further modification of the contributor version. For
526 | purposes of this definition, "control" includes the right to grant
527 | patent sublicenses in a manner consistent with the requirements of
528 | this License.
529 |
530 | Each contributor grants you a non-exclusive, worldwide, royalty-free
531 | patent license under the contributor's essential patent claims, to
532 | make, use, sell, offer for sale, import and otherwise run, modify and
533 | propagate the contents of its contributor version.
534 |
535 | In the following three paragraphs, a "patent license" is any express
536 | agreement or commitment, however denominated, not to enforce a patent
537 | (such as an express permission to practice a patent or covenant not to
538 | sue for patent infringement). To "grant" such a patent license to a
539 | party means to make such an agreement or commitment not to enforce a
540 | patent against the party.
541 |
542 | If you convey a covered work, knowingly relying on a patent license,
543 | and the Corresponding Source of the work is not available for anyone
544 | to copy, free of charge and under the terms of this License, through a
545 | publicly available network server or other readily accessible means,
546 | then you must either (1) cause the Corresponding Source to be so
547 | available, or (2) arrange to deprive yourself of the benefit of the
548 | patent license for this particular work, or (3) arrange, in a manner
549 | consistent with the requirements of this License, to extend the patent
550 | license to downstream recipients. "Knowingly relying" means you have
551 | actual knowledge that, but for the patent license, your conveying the
552 | covered work in a country, or your recipient's use of the covered work
553 | in a country, would infringe one or more identifiable patents in that
554 | country that you have reason to believe are valid.
555 |
556 | If, pursuant to or in connection with a single transaction or
557 | arrangement, you convey, or propagate by procuring conveyance of, a
558 | covered work, and grant a patent license to some of the parties
559 | receiving the covered work authorizing them to use, propagate, modify
560 | or convey a specific copy of the covered work, then the patent license
561 | you grant is automatically extended to all recipients of the covered
562 | work and works based on it.
563 |
564 | A patent license is "discriminatory" if it does not include within
565 | the scope of its coverage, prohibits the exercise of, or is
566 | conditioned on the non-exercise of one or more of the rights that are
567 | specifically granted under this License. You may not convey a covered
568 | work if you are a party to an arrangement with a third party that is
569 | in the business of distributing software, under which you make payment
570 | to the third party based on the extent of your activity of conveying
571 | the work, and under which the third party grants, to any of the
572 | parties who would receive the covered work from you, a discriminatory
573 | patent license (a) in connection with copies of the covered work
574 | conveyed by you (or copies made from those copies), or (b) primarily
575 | for and in connection with specific products or compilations that
576 | contain the covered work, unless you entered into that arrangement,
577 | or that patent license was granted, prior to 28 March 2007.
578 |
579 | Nothing in this License shall be construed as excluding or limiting
580 | any implied license or other defenses to infringement that may
581 | otherwise be available to you under applicable patent law.
582 |
583 | 12. No Surrender of Others' Freedom.
584 |
585 | If conditions are imposed on you (whether by court order, agreement or
586 | otherwise) that contradict the conditions of this License, they do not
587 | excuse you from the conditions of this License. If you cannot convey a
588 | covered work so as to satisfy simultaneously your obligations under this
589 | License and any other pertinent obligations, then as a consequence you may
590 | not convey it at all. For example, if you agree to terms that obligate you
591 | to collect a royalty for further conveying from those to whom you convey
592 | the Program, the only way you could satisfy both those terms and this
593 | License would be to refrain entirely from conveying the Program.
594 |
595 | 13. Use with the GNU Affero General Public License.
596 |
597 | Notwithstanding any other provision of this License, you have
598 | permission to link or combine any covered work with a work licensed
599 | under version 3 of the GNU Affero General Public License into a single
600 | combined work, and to convey the resulting work. The terms of this
601 | License will continue to apply to the part which is the covered work,
602 | but the special requirements of the GNU Affero General Public License,
603 | section 13, concerning interaction through a network will apply to the
604 | combination as such.
605 |
606 | 14. Revised Versions of this License.
607 |
608 | The Free Software Foundation may publish revised and/or new versions of
609 | the GNU General Public License from time to time. Such new versions will
610 | be similar in spirit to the present version, but may differ in detail to
611 | address new problems or concerns.
612 |
613 | Each version is given a distinguishing version number. If the
614 | Program specifies that a certain numbered version of the GNU General
615 | Public License "or any later version" applies to it, you have the
616 | option of following the terms and conditions either of that numbered
617 | version or of any later version published by the Free Software
618 | Foundation. If the Program does not specify a version number of the
619 | GNU General Public License, you may choose any version ever published
620 | by the Free Software Foundation.
621 |
622 | If the Program specifies that a proxy can decide which future
623 | versions of the GNU General Public License can be used, that proxy's
624 | public statement of acceptance of a version permanently authorizes you
625 | to choose that version for the Program.
626 |
627 | Later license versions may give you additional or different
628 | permissions. However, no additional obligations are imposed on any
629 | author or copyright holder as a result of your choosing to follow a
630 | later version.
631 |
632 | 15. Disclaimer of Warranty.
633 |
634 | THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
635 | APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
636 | HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
637 | OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
638 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
639 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
640 | IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
641 | ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
642 |
643 | 16. Limitation of Liability.
644 |
645 | IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
646 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
647 | THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
648 | GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
649 | USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
650 | DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
651 | PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
652 | EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
653 | SUCH DAMAGES.
654 |
655 | 17. Interpretation of Sections 15 and 16.
656 |
657 | If the disclaimer of warranty and limitation of liability provided
658 | above cannot be given local legal effect according to their terms,
659 | reviewing courts shall apply local law that most closely approximates
660 | an absolute waiver of all civil liability in connection with the
661 | Program, unless a warranty or assumption of liability accompanies a
662 | copy of the Program in return for a fee.
663 |
664 | END OF TERMS AND CONDITIONS
665 |
666 | How to Apply These Terms to Your New Programs
667 |
668 | If you develop a new program, and you want it to be of the greatest
669 | possible use to the public, the best way to achieve this is to make it
670 | free software which everyone can redistribute and change under these terms.
671 |
672 | To do so, attach the following notices to the program. It is safest
673 | to attach them to the start of each source file to most effectively
674 | state the exclusion of warranty; and each file should have at least
675 | the "copyright" line and a pointer to where the full notice is found.
676 |
677 |
678 | Copyright (C)
679 |
680 | This program is free software: you can redistribute it and/or modify
681 | it under the terms of the GNU General Public License as published by
682 | the Free Software Foundation, either version 3 of the License, or
683 | (at your option) any later version.
684 |
685 | This program is distributed in the hope that it will be useful,
686 | but WITHOUT ANY WARRANTY; without even the implied warranty of
687 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
688 | GNU General Public License for more details.
689 |
690 | You should have received a copy of the GNU General Public License
691 | along with this program. If not, see .
692 |
693 | Also add information on how to contact you by electronic and paper mail.
694 |
695 | If the program does terminal interaction, make it output a short
696 | notice like this when it starts in an interactive mode:
697 |
698 | Copyright (C)
699 | This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
700 | This is free software, and you are welcome to redistribute it
701 | under certain conditions; type `show c' for details.
702 |
703 | The hypothetical commands `show w' and `show c' should show the appropriate
704 | parts of the General Public License. Of course, your program's commands
705 | might be different; for a GUI interface, you would use an "about box".
706 |
707 | You should also get your employer (if you work as a programmer) or school,
708 | if any, to sign a "copyright disclaimer" for the program, if necessary.
709 | For more information on this, and how to apply and follow the GNU GPL, see
710 | .
711 |
712 | The GNU General Public License does not permit incorporating your program
713 | into proprietary programs. If your program is a subroutine library, you
714 | may consider it more useful to permit linking proprietary applications with
715 | the library. If this is what you want to do, use the GNU Lesser General
716 | Public License instead of this License. But first, please read
717 | .
718 | """
719 |
--------------------------------------------------------------------------------
/inputdeviceindicator/resources/input-device-indicator.svg:
--------------------------------------------------------------------------------
1 |
2 |
1404 |
--------------------------------------------------------------------------------