1# utils.py -- utility functions source
2# This file is part of Redshift.
3
4# Redshift is free software: you can redistribute it and/or modify
5# it under the terms of the GNU General Public License as published by
6# the Free Software Foundation, either version 3 of the License, or
7# (at your option) any later version.
8
9# Redshift is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12# GNU General Public License for more details.
13
14# You should have received a copy of the GNU General Public License
15# along with Redshift.  If not, see <http://www.gnu.org/licenses/>.
16
17# Copyright (c) 2010  Francesco Marella <francesco.marella@gmail.com>
18# Copyright (c) 2011  Jon Lund Steffensen <jonlst@gmail.com>
19
20import ctypes
21import os
22import sys
23
24try:
25    from xdg import BaseDirectory
26    from xdg import DesktopEntry
27    has_xdg = True
28except ImportError:
29    has_xdg = False
30
31
32REDSHIFT_DESKTOP = 'redshift-gtk.desktop'
33
34# Keys to set when enabling/disabling autostart.
35# Only first one is checked on "get".
36AUTOSTART_KEYS = (('Hidden', ('true', 'false')),
37                  ('X-GNOME-Autostart-enabled', ('false', 'true')))
38
39
40def open_autostart_file():
41    autostart_dir = BaseDirectory.save_config_path("autostart")
42    autostart_file = os.path.join(autostart_dir, REDSHIFT_DESKTOP)
43
44    if not os.path.exists(autostart_file):
45        desktop_files = list(
46            BaseDirectory.load_data_paths(
47                "applications", REDSHIFT_DESKTOP))
48
49        if not desktop_files:
50            raise IOError("Installed redshift desktop file not found!")
51
52        desktop_file_path = desktop_files[0]
53
54        # Read installed file
55        dfile = DesktopEntry.DesktopEntry(desktop_file_path)
56        for key, values in AUTOSTART_KEYS:
57            dfile.set(key, values[False])
58        dfile.write(filename=autostart_file)
59    else:
60        dfile = DesktopEntry.DesktopEntry(autostart_file)
61
62    return dfile, autostart_file
63
64
65def supports_autostart():
66    return has_xdg
67
68
69def get_autostart():
70    if not has_xdg:
71        return False
72
73    dfile, path = open_autostart_file()
74    check_key, check_values = AUTOSTART_KEYS[0]
75    return dfile.get(check_key) == check_values[True]
76
77
78def set_autostart(active):
79    if not has_xdg:
80        return
81
82    dfile, path = open_autostart_file()
83    for key, values in AUTOSTART_KEYS:
84        dfile.set(key, values[active])
85    dfile.write(filename=path)
86
87
88def setproctitle(title):
89    """Set process title."""
90    title_bytes = title.encode(sys.getdefaultencoding(), 'replace')
91    buf = ctypes.create_string_buffer(title_bytes)
92    if 'linux' in sys.platform:
93        try:
94            libc = ctypes.cdll.LoadLibrary("libc.so.6")
95        except OSError:
96            return
97        try:
98            libc.prctl(15, buf, 0, 0, 0)
99        except AttributeError:
100            return  # Strange libc, just skip this
101    elif 'bsd' in sys.platform:
102        try:
103            libc = ctypes.cdll.LoadLibrary("libc.so.7")
104        except OSError:
105            return
106        try:
107            libc.setproctitle(ctypes.create_string_buffer(b"-%s"), buf)
108        except AttributeError:
109            return
110