Merge lp:~noskcaj/ubuntu/wily/redshift/merge2 into lp:ubuntu/wily/redshift

Proposed by Jackson Doak
Status: Merged
Approved by: Michael Terry
Approved revision: 22
Merge reported by: Michael Terry
Merged at revision: not available
Proposed branch: lp:~noskcaj/ubuntu/wily/redshift/merge2
Merge into: lp:ubuntu/wily/redshift
Diff against target: 1046 lines (+108/-795)
16 files modified
.pc/applied-patches (+0/-2)
.pc/remove_autostart.patch/src/redshift-gtk/statusicon.py (+0/-520)
.pc/retry-geoclue.patch/src/location-geoclue.c (+0/-217)
debian/README.Debian (+0/-24)
debian/changelog (+36/-0)
debian/control (+1/-1)
debian/gbp.conf (+2/-0)
debian/patches/add-desktop-file.patch (+34/-0)
debian/patches/retry-geoclue.patch (+8/-6)
debian/patches/series (+1/-1)
debian/redshift-gtk.docs (+0/-1)
debian/redshift-gtk.install (+2/-1)
debian/redshift.install (+1/-0)
debian/rules (+3/-2)
src/location-geoclue.c (+8/-20)
src/redshift-gtk/statusicon.py (+12/-0)
To merge this branch: bzr merge lp:~noskcaj/ubuntu/wily/redshift/merge2
Reviewer Review Type Date Requested Status
Michael Terry Approve
Review via email: mp+274448@code.launchpad.net

Description of the change

Merge from debian. package is currently broken in wily, this merge is required for it to work as intended

To post a comment you must log in.
Revision history for this message
Michael Terry (mterry) wrote :

Looks good, thanks! Uploaded to wily.

review: Approve
Revision history for this message
Michael Terry (mterry) wrote :

Only change was I also fixed the typo in the changelog (rues to rules)

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== removed file '.pc/applied-patches'
--- .pc/applied-patches 2014-11-01 17:06:15 +0000
+++ .pc/applied-patches 1970-01-01 00:00:00 +0000
@@ -1,2 +0,0 @@
1remove_autostart.patch
2retry-geoclue.patch
30
=== removed directory '.pc/remove_autostart.patch'
=== removed directory '.pc/remove_autostart.patch/src'
=== removed directory '.pc/remove_autostart.patch/src/redshift-gtk'
=== removed file '.pc/remove_autostart.patch/src/redshift-gtk/statusicon.py'
--- .pc/remove_autostart.patch/src/redshift-gtk/statusicon.py 2015-05-24 16:48:08 +0000
+++ .pc/remove_autostart.patch/src/redshift-gtk/statusicon.py 1970-01-01 00:00:00 +0000
@@ -1,520 +0,0 @@
1# statusicon.py -- GUI status icon 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) 2013-2014 Jon Lund Steffensen <jonlst@gmail.com>
18
19
20'''GUI status icon for Redshift.
21
22The run method will try to start an appindicator for Redshift. If the
23appindicator module isn't present it will fall back to a GTK status icon.
24'''
25
26import sys, os
27import fcntl
28import signal
29import re
30import gettext
31
32from gi.repository import Gtk, GLib, GObject
33
34try:
35 from gi.repository import AppIndicator3 as appindicator
36except ImportError:
37 appindicator = None
38
39from . import defs
40from . import utils
41
42_ = gettext.gettext
43
44
45class RedshiftController(GObject.GObject):
46 '''A GObject wrapper around the child process'''
47
48 __gsignals__ = {
49 'inhibit-changed': (GObject.SIGNAL_RUN_FIRST, None, (bool,)),
50 'temperature-changed': (GObject.SIGNAL_RUN_FIRST, None, (int,)),
51 'period-changed': (GObject.SIGNAL_RUN_FIRST, None, (str,)),
52 'location-changed': (GObject.SIGNAL_RUN_FIRST, None, (float, float)),
53 'error-occured': (GObject.SIGNAL_RUN_FIRST, None, (str,))
54 }
55
56 def __init__(self, args):
57 '''Initialize controller and start child process
58
59 The parameter args is a list of command line arguments to pass on to
60 the child process. The "-v" argument is automatically added.'''
61
62 GObject.GObject.__init__(self)
63
64 # Initialize state variables
65 self._inhibited = False
66 self._temperature = 0
67 self._period = 'Unknown'
68 self._location = (0.0, 0.0)
69
70 # Start redshift with arguments
71 args.insert(0, os.path.join(defs.BINDIR, 'redshift'))
72 if '-v' not in args:
73 args.insert(1, '-v')
74
75 # Start child process with C locale so we can parse the output
76 env = os.environ.copy()
77 env['LANG'] = env['LANGUAGE'] = env['LC_ALL'] = env['LC_MESSAGES'] = 'C'
78 self._process = GLib.spawn_async(args, envp=['{}={}'.format(k,v) for k, v in env.items()],
79 flags=GLib.SPAWN_DO_NOT_REAP_CHILD,
80 standard_output=True, standard_error=True)
81
82 # Wrap remaining contructor in try..except to avoid that the child
83 # process is not closed properly.
84 try:
85 # Handle child input
86 # The buffer is encapsulated in a class so we
87 # can pass an instance to the child callback.
88 class InputBuffer(object):
89 buf = ''
90
91 self._input_buffer = InputBuffer()
92 self._error_buffer = InputBuffer()
93 self._errors = ''
94
95 # Set non blocking
96 fcntl.fcntl(self._process[2], fcntl.F_SETFL,
97 fcntl.fcntl(self._process[2], fcntl.F_GETFL) | os.O_NONBLOCK)
98
99 # Add watch on child process
100 GLib.child_watch_add(GLib.PRIORITY_DEFAULT, self._process[0], self._child_cb)
101 GLib.io_add_watch(self._process[2], GLib.PRIORITY_DEFAULT, GLib.IO_IN,
102 self._child_data_cb, (True, self._input_buffer))
103 GLib.io_add_watch(self._process[3], GLib.PRIORITY_DEFAULT, GLib.IO_IN,
104 self._child_data_cb, (False, self._error_buffer))
105
106 # Signal handler to relay USR1 signal to redshift process
107 def relay_signal_handler(signal):
108 os.kill(self._process[0], signal)
109 return True
110
111 GLib.unix_signal_add(GLib.PRIORITY_DEFAULT, signal.SIGUSR1,
112 relay_signal_handler, signal.SIGUSR1)
113 except:
114 self.termwait()
115 raise
116
117 @property
118 def inhibited(self):
119 '''Current inhibition state'''
120 return self._inhibited
121
122 @property
123 def temperature(self):
124 '''Current screen temperature'''
125 return self._temperature
126
127 @property
128 def period(self):
129 '''Current period of day'''
130 return self._period
131
132 @property
133 def location(self):
134 '''Current location'''
135 return self._location
136
137 def set_inhibit(self, inhibit):
138 '''Set inhibition state'''
139 if inhibit != self._inhibited:
140 self._child_toggle_inhibit()
141
142 def _child_toggle_inhibit(self):
143 '''Sends a request to the child process to toggle state'''
144 os.kill(self._process[0], signal.SIGUSR1)
145
146 def _child_cb(self, pid, status, data=None):
147 '''Called when the child process exists'''
148
149 # Empty stdout and stderr
150 for f in (self._process[2], self._process[3]):
151 while True:
152 buf = os.read(f, 256).decode('utf-8')
153 if buf == '':
154 break
155 if f == self._process[3]: # stderr
156 self._errors += buf
157
158 # Check exit status of child
159 report_errors = False
160 try:
161 GLib.spawn_check_exit_status(status)
162 Gtk.main_quit()
163 except GLib.GError:
164 report_errors = True
165
166 if report_errors:
167 self.emit('error-occured', self._errors)
168
169 def _child_key_change_cb(self, key, value):
170 '''Called when the child process reports a change of internal state'''
171
172 def parse_coord(s):
173 '''Parse coordinate like `42.0 N` or `91.5 W`'''
174 v, d = s.split(' ')
175 return float(v) * (1 if d in 'NE' else -1)
176
177 if key == 'Status':
178 new_inhibited = value != 'Enabled'
179 if new_inhibited != self._inhibited:
180 self._inhibited = new_inhibited
181 self.emit('inhibit-changed', new_inhibited)
182 elif key == 'Color temperature':
183 new_temperature = int(value.rstrip('K'), 10)
184 if new_temperature != self._temperature:
185 self._temperature = new_temperature
186 self.emit('temperature-changed', new_temperature)
187 elif key == 'Period':
188 new_period = value
189 if new_period != self._period:
190 self._period = new_period
191 self.emit('period-changed', new_period)
192 elif key == 'Location':
193 new_location = tuple(parse_coord(x) for x in value.split(', '))
194 if new_location != self._location:
195 self._location = new_location
196 self.emit('location-changed', *new_location)
197
198 def _child_stdout_line_cb(self, line):
199 '''Called when the child process outputs a line to stdout'''
200 if line:
201 m = re.match(r'([\w ]+): (.+)', line)
202 if m:
203 key = m.group(1)
204 value = m.group(2)
205 self._child_key_change_cb(key, value)
206
207 def _child_data_cb(self, f, cond, data):
208 '''Called when the child process has new data on stdout/stderr'''
209
210 stdout, ib = data
211 ib.buf += os.read(f, 256).decode('utf-8')
212
213 # Split input at line break
214 while True:
215 first, sep, last = ib.buf.partition('\n')
216 if sep == '':
217 break
218 ib.buf = last
219 if stdout:
220 self._child_stdout_line_cb(first)
221 else:
222 self._errors += first + '\n'
223
224 return True
225
226 def termwait(self):
227 '''Send SIGINT and wait for the child process to quit'''
228 try:
229 os.kill(self._process[0], signal.SIGINT)
230 os.waitpid(self._process[0], 0)
231 except ProcessLookupError:
232 # Process has apparently already disappeared
233 pass
234
235
236class RedshiftStatusIcon(object):
237 '''The status icon tracking the RedshiftController'''
238
239 def __init__(self, controller):
240 '''Creates a new instance of the status icon'''
241
242 self._controller = controller
243
244 if appindicator:
245 # Create indicator
246 self.indicator = appindicator.Indicator.new('redshift',
247 'redshift-status-on',
248 appindicator.IndicatorCategory.APPLICATION_STATUS)
249 self.indicator.set_status(appindicator.IndicatorStatus.ACTIVE)
250 else:
251 # Create status icon
252 self.status_icon = Gtk.StatusIcon()
253 self.status_icon.set_from_icon_name('redshift-status-on')
254 self.status_icon.set_tooltip_text('Redshift')
255
256 # Create popup menu
257 self.status_menu = Gtk.Menu()
258
259 # Add toggle action
260 self.toggle_item = Gtk.CheckMenuItem.new_with_label(_('Enabled'))
261 self.toggle_item.connect('activate', self.toggle_item_cb)
262 self.status_menu.append(self.toggle_item)
263
264 # Add suspend menu
265 suspend_menu_item = Gtk.MenuItem.new_with_label(_('Suspend for'))
266 suspend_menu = Gtk.Menu()
267 for minutes, label in [(30, _('30 minutes')),
268 (60, _('1 hour')),
269 (120, _('2 hours'))]:
270 suspend_item = Gtk.MenuItem.new_with_label(label)
271 suspend_item.connect('activate', self.suspend_cb, minutes)
272 suspend_menu.append(suspend_item)
273 suspend_menu_item.set_submenu(suspend_menu)
274 self.status_menu.append(suspend_menu_item)
275
276 # Add autostart option
277 autostart_item = Gtk.CheckMenuItem.new_with_label(_('Autostart'))
278 try:
279 autostart_item.set_active(utils.get_autostart())
280 except IOError as strerror:
281 print(strerror)
282 autostart_item.set_property('sensitive', False)
283 else:
284 autostart_item.connect('toggled', self.autostart_cb)
285 finally:
286 self.status_menu.append(autostart_item)
287
288 # Add info action
289 info_item = Gtk.MenuItem.new_with_label(_('Info'))
290 info_item.connect('activate', self.show_info_cb)
291 self.status_menu.append(info_item)
292
293 # Add quit action
294 quit_item = Gtk.ImageMenuItem.new_with_label(_('Quit'))
295 quit_item.connect('activate', self.destroy_cb)
296 self.status_menu.append(quit_item)
297
298 # Create info dialog
299 self.info_dialog = Gtk.Dialog()
300 self.info_dialog.set_title(_('Info'))
301 self.info_dialog.add_button(_('Close'), Gtk.ButtonsType.CLOSE)
302 self.info_dialog.set_resizable(False)
303 self.info_dialog.set_property('border-width', 6)
304
305 self.status_label = Gtk.Label()
306 self.status_label.set_alignment(0.0, 0.5)
307 self.status_label.set_padding(6, 6)
308 self.info_dialog.get_content_area().pack_start(self.status_label, True, True, 0)
309 self.status_label.show()
310
311 self.location_label = Gtk.Label()
312 self.location_label.set_alignment(0.0, 0.5)
313 self.location_label.set_padding(6, 6)
314 self.info_dialog.get_content_area().pack_start(self.location_label, True, True, 0)
315 self.location_label.show()
316
317 self.temperature_label = Gtk.Label()
318 self.temperature_label.set_alignment(0.0, 0.5)
319 self.temperature_label.set_padding(6, 6)
320 self.info_dialog.get_content_area().pack_start(self.temperature_label, True, True, 0)
321 self.temperature_label.show()
322
323 self.period_label = Gtk.Label()
324 self.period_label.set_alignment(0.0, 0.5)
325 self.period_label.set_padding(6, 6)
326 self.info_dialog.get_content_area().pack_start(self.period_label, True, True, 0)
327 self.period_label.show()
328
329 self.info_dialog.connect('response', self.response_info_cb)
330
331 # Setup signals to property changes
332 self._controller.connect('inhibit-changed', self.inhibit_change_cb)
333 self._controller.connect('period-changed', self.period_change_cb)
334 self._controller.connect('temperature-changed', self.temperature_change_cb)
335 self._controller.connect('location-changed', self.location_change_cb)
336 self._controller.connect('error-occured', self.error_occured_cb)
337
338 # Set info box text
339 self.change_inhibited(self._controller.inhibited)
340 self.change_period(self._controller.period)
341 self.change_temperature(self._controller.temperature)
342 self.change_location(self._controller.location)
343
344 if appindicator:
345 self.status_menu.show_all()
346
347 # Set the menu
348 self.indicator.set_menu(self.status_menu)
349 else:
350 # Connect signals for status icon and show
351 self.status_icon.connect('activate', self.toggle_cb)
352 self.status_icon.connect('popup-menu', self.popup_menu_cb)
353 self.status_icon.set_visible(True)
354
355 # Initialize suspend timer
356 self.suspend_timer = None
357
358 def remove_suspend_timer(self):
359 '''Disable any previously set suspend timer'''
360 if self.suspend_timer is not None:
361 GLib.source_remove(self.suspend_timer)
362 self.suspend_timer = None
363
364 def suspend_cb(self, item, minutes):
365 '''Callback that handles activation of a suspend timer
366
367 The minutes parameter is the number of minutes to suspend. Even if redshift
368 is not disabled when called, it will still set a suspend timer and
369 reactive redshift when the timer is up.'''
370
371 # Inhibit
372 self._controller.set_inhibit(True)
373
374 # If "suspend" is clicked while redshift is disabled, we reenable
375 # it after the last selected timespan is over.
376 self.remove_suspend_timer()
377
378 # If redshift was already disabled we reenable it nonetheless.
379 self.suspend_timer = GLib.timeout_add_seconds(minutes * 60, self.reenable_cb)
380
381 def reenable_cb(self):
382 '''Callback to reenable redshift when a suspend timer expires'''
383 self._controller.set_inhibit(False)
384
385 def popup_menu_cb(self, widget, button, time, data=None):
386 '''Callback when the popup menu on the status icon has to open'''
387 self.status_menu.show_all()
388 self.status_menu.popup(None, None, Gtk.StatusIcon.position_menu,
389 self.status_icon, button, time)
390
391 def toggle_cb(self, widget, data=None):
392 '''Callback when a request to toggle redshift was made'''
393 self.remove_suspend_timer()
394 self._controller.set_inhibit(not self._controller.inhibited)
395
396 def toggle_item_cb(self, widget, data=None):
397 '''Callback then a request to toggle redshift was made from a toggle item
398
399 This ensures that the state of redshift is synchronised with
400 the toggle state of the widget (e.g. Gtk.CheckMenuItem).'''
401
402 active = not self._controller.inhibited
403 if active != widget.get_active():
404 self.remove_suspend_timer()
405 self._controller.set_inhibit(not self._controller.inhibited)
406
407 # Info dialog callbacks
408 def show_info_cb(self, widget, data=None):
409 '''Callback when the info dialog should be presented'''
410 self.info_dialog.show()
411
412 def response_info_cb(self, widget, data=None):
413 '''Callback when a button in the info dialog was activated'''
414 self.info_dialog.hide()
415
416 def update_status_icon(self):
417 '''Update the status icon according to the internally recorded state
418
419 This should be called whenever the internally recorded state
420 might have changed.'''
421
422 # Update status icon
423 if appindicator:
424 if not self._controller.inhibited:
425 self.indicator.set_icon('redshift-status-on')
426 else:
427 self.indicator.set_icon('redshift-status-off')
428 else:
429 if not self._controller.inhibited:
430 self.status_icon.set_from_icon_name('redshift-status-on')
431 else:
432 self.status_icon.set_from_icon_name('redshift-status-off')
433
434 # State update functions
435 def inhibit_change_cb(self, controller, inhibit):
436 '''Callback when controller changes inhibition status'''
437 self.change_inhibited(inhibit)
438
439 def period_change_cb(self, controller, period):
440 '''Callback when controller changes period'''
441 self.change_period(period)
442
443 def temperature_change_cb(self, controller, temperature):
444 '''Callback when controller changes temperature'''
445 self.change_temperature(temperature)
446
447 def location_change_cb(self, controller, lat, lon):
448 '''Callback when controlled changes location'''
449 self.change_location((lat, lon))
450
451 def error_occured_cb(self, controller, error):
452 '''Callback when an error occurs in the controller'''
453 error_dialog = Gtk.MessageDialog(None, Gtk.DialogFlags.MODAL, Gtk.MessageType.ERROR,
454 Gtk.ButtonsType.CLOSE, '')
455 error_dialog.set_markup('<b>Failed to run Redshift</b>\n<i>' + error + '</i>')
456 error_dialog.run()
457
458 # Quit when the model dialog is closed
459 sys.exit(-1)
460
461 # Update interface
462 def change_inhibited(self, inhibited):
463 '''Change interface to new inhibition status'''
464 self.update_status_icon()
465 self.toggle_item.set_active(not inhibited)
466 self.status_label.set_markup(_('<b>Status:</b> {}').format(_('Disabled') if inhibited else _('Enabled')))
467
468 def change_temperature(self, temperature):
469 '''Change interface to new temperature'''
470 self.temperature_label.set_markup('<b>{}:</b> {}K'.format(_('Color temperature'), temperature))
471
472 def change_period(self, period):
473 '''Change interface to new period'''
474 self.period_label.set_markup('<b>{}:</b> {}'.format(_('Period'), period))
475
476 def change_location(self, location):
477 '''Change interface to new location'''
478 self.location_label.set_markup('<b>{}:</b> {}, {}'.format(_('Location'), *location))
479
480
481 def autostart_cb(self, widget, data=None):
482 '''Callback when a request to toggle autostart is made'''
483 utils.set_autostart(widget.get_active())
484
485 def destroy_cb(self, widget, data=None):
486 '''Callback when a request to quit the application is made'''
487 if not appindicator:
488 self.status_icon.set_visible(False)
489 Gtk.main_quit()
490 return False
491
492
493def sigterm_handler(data=None):
494 sys.exit(0)
495
496
497def run():
498 utils.setproctitle('redshift-gtk')
499
500 # Install TERM signal handler
501 GLib.unix_signal_add(GLib.PRIORITY_DEFAULT, signal.SIGTERM,
502 sigterm_handler, None)
503 GLib.unix_signal_add(GLib.PRIORITY_DEFAULT, signal.SIGINT,
504 sigterm_handler, None)
505
506 # Internationalisation
507 gettext.bindtextdomain('redshift', defs.LOCALEDIR)
508 gettext.textdomain('redshift')
509
510 # Create redshift child process controller
511 c = RedshiftController(sys.argv[1:])
512 try:
513 # Create status icon
514 s = RedshiftStatusIcon(c)
515
516 # Run main loop
517 Gtk.main()
518 finally:
519 # Always make sure that the child process is closed
520 c.termwait()
5210
=== removed directory '.pc/retry-geoclue.patch'
=== removed directory '.pc/retry-geoclue.patch/src'
=== removed file '.pc/retry-geoclue.patch/src/location-geoclue.c'
--- .pc/retry-geoclue.patch/src/location-geoclue.c 2015-06-28 09:25:43 +0000
+++ .pc/retry-geoclue.patch/src/location-geoclue.c 1970-01-01 00:00:00 +0000
@@ -1,217 +0,0 @@
1/* location-geoclue.c -- Geoclue location provider 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 Mathieu Trudel-Lapierre <mathieu-tl@ubuntu.com>
18*/
19
20#include <stdio.h>
21#include <stdlib.h>
22#include <string.h>
23
24#include <geoclue/geoclue-master.h>
25#include <geoclue/geoclue-position.h>
26
27#include <glib.h>
28#include <glib-object.h>
29
30#include "location-geoclue.h"
31
32#ifdef ENABLE_NLS
33# include <libintl.h>
34# define _(s) gettext(s)
35#else
36# define _(s) s
37#endif
38
39#define DEFAULT_PROVIDER "org.freedesktop.Geoclue.Providers.UbuntuGeoIP"
40#define DEFAULT_PROVIDER_PATH "/org/freedesktop/Geoclue/Providers/UbuntuGeoIP"
41
42int
43location_geoclue_init(location_geoclue_state_t *state)
44{
45#if !GLIB_CHECK_VERSION(2, 35, 0)
46 g_type_init();
47#endif
48
49 state->position = NULL;
50 state->provider = NULL;
51 state->provider_path = NULL;
52
53 return 0;
54}
55
56int
57location_geoclue_start(location_geoclue_state_t *state)
58{
59 if (state->provider && state->provider_path) {
60 state->position = geoclue_position_new(state->provider,
61 state->provider_path);
62 } else {
63 if (getenv("DISPLAY") == NULL || *getenv("DISPLAY") == '\0') {
64 /* TODO This (hack) should be removed when GeoClue has been patched. */
65 putenv("DISPLAY=:0");
66 }
67 GError *error = NULL;
68 GeoclueMaster *master = geoclue_master_get_default();
69 GeoclueMasterClient *client = geoclue_master_create_client(master,
70 NULL, &error);
71 g_object_unref(master);
72
73 if (client == NULL) {
74 if (error != NULL) {
75 g_printerr(_("Unable to obtain master client: %s\n"),
76 error->message);
77 g_error_free(error);
78 } else {
79 g_printerr(_("Unable to obtain master client\n"));
80 }
81 return -1;
82 }
83
84 if (!geoclue_master_client_set_requirements(client,
85 GEOCLUE_ACCURACY_LEVEL_REGION,
86 0, FALSE,
87 GEOCLUE_RESOURCE_NETWORK,
88 &error)) {
89 if (error != NULL) {
90 g_printerr(_("Can't set requirements for master: %s\n"),
91 error->message);
92 g_error_free(error);
93 } else {
94 g_printerr(_("Can't set requirements for master\n"));
95 }
96 g_object_unref(client);
97
98 return -1;
99 }
100
101 state->position = geoclue_master_client_create_position(client, NULL);
102
103 g_object_unref(client);
104 }
105
106 gchar *name = NULL;
107
108 if (geoclue_provider_get_provider_info(GEOCLUE_PROVIDER(state->position),
109 &name, NULL, NULL)) {
110 fprintf(stdout, _("Started Geoclue provider `%s'.\n"), name);
111 g_free(name);
112 } else {
113 fputs(_("Could not find a usable Geoclue provider.\n"), stderr);
114 fputs(_("Try setting name and path to specify which to use.\n"), stderr);
115 return -1;
116 }
117
118 return 0;
119}
120
121void
122location_geoclue_free(location_geoclue_state_t *state)
123{
124 if (state->position != NULL) g_object_unref(state->position);
125 if (state->provider != NULL) free(state->provider);
126 if (state->provider_path != NULL) free(state->provider_path);
127}
128
129void
130location_geoclue_print_help(FILE *f)
131{
132 fputs(_("Use the location as discovered by a Geoclue provider.\n"), f);
133 fputs("\n", f);
134
135 /* TRANSLATORS: Geoclue help output
136 left column must not be translated */
137 fputs(_(" name=N\tName of Geoclue provider (or `default')\n"
138 " path=N\tPath of Geoclue provider (or `default')\n"), f);
139 fputs("\n", f);
140 fprintf(f, _("NOTE: currently Redshift doesn't recheck %s once started,\n"
141 "which means it has to be restarted to take notice after travel.\n"),
142 "GeoClue");
143 fputs("\n", f);
144}
145
146int
147location_geoclue_set_option(location_geoclue_state_t *state,
148 const char *key, const char *value)
149{
150 const char *provider = NULL;
151 const char *path = NULL;
152
153 /* Parse string value */
154 if (strcasecmp(key, "name") == 0) {
155 if (strcasecmp(value, "default") == 0) {
156 provider = DEFAULT_PROVIDER;
157 } else {
158 provider = value;
159 }
160
161 state->provider = strdup(provider);
162 if (state->provider == NULL) {
163 perror("strdup");
164 return -1;
165 }
166 } else if (strcasecmp(key, "path") == 0) {
167 if (value != NULL && strcasecmp(value, "default") == 0) {
168 path = DEFAULT_PROVIDER_PATH;
169 } else {
170 path = value;
171 }
172
173 state->provider_path = strdup(path);
174 if (state->provider_path == NULL) {
175 perror("strdup");
176 return -1;
177 }
178 } else {
179 fprintf(stderr, _("Unknown method parameter: `%s'.\n"), key);
180 return -1;
181 }
182
183 return 0;
184}
185
186int
187location_geoclue_get_location(location_geoclue_state_t *state,
188 float *lat, float *lon)
189{
190 GeocluePositionFields fields;
191 GError *error = NULL;
192 double latitude = 0, longitude = 0;
193
194 fields = geoclue_position_get_position(state->position, NULL,
195 &latitude, &longitude, NULL,
196 NULL, &error);
197 if (error) {
198 g_printerr(_("Could not get location: %s.\n"), error->message);
199 g_error_free(error);
200 return -1;
201 }
202
203 if (fields & GEOCLUE_POSITION_FIELDS_LATITUDE &&
204 fields & GEOCLUE_POSITION_FIELDS_LONGITUDE) {
205 fprintf(stdout, _("According to the geoclue provider"
206 " we're at: %.2f, %.2f\n"),
207 latitude, longitude);
208 } else {
209 g_warning(_("Provider does not have a valid location available."));
210 return -1;
211 }
212
213 *lat = latitude;
214 *lon = longitude;
215
216 return 0;
217}
2180
=== removed file 'debian/README.Debian'
--- debian/README.Debian 2015-05-26 14:55:19 +0000
+++ debian/README.Debian 1970-01-01 00:00:00 +0000
@@ -1,24 +0,0 @@
1Geoclue 2
2---------
3
4Starting with version 1.10, redshift has support for Geoclue 2.
5By default, geoclue will not allow access to redshift.
6
7To make geoclue accept requests from redshift, add the following to
8/etc/geoclue/geoclue.conf
9
10[redshift]
11allowed=true
12system=false
13users=
14
15
16Autostart of gtk-redshift
17-------------------------
18
19Autostart was removed from Debian package because of violation of 'Desktop Application
20Autostart Specification' (see bug #619699). If you want gtk-redshift autostarted please
21configure this in your specific desktop environment (e.g. by placing
22/usr/share/applications/gtk-redshift.desktop in
23$HOME/$XDG_CONFIG_HOME/autostart/
24(usually defaults to $HOME/.config/autostart).
250
=== modified file 'debian/changelog'
--- debian/changelog 2015-06-28 09:25:43 +0000
+++ debian/changelog 2015-10-14 19:20:52 +0000
@@ -1,3 +1,39 @@
1redshift (1.10-5ubuntu1) wily; urgency=medium
2
3 * Merge from Debian. (LP: #1485153) Remaining changes:
4 - debian/rues: Add --enable-ubuntu
5 - debian/patches/retry-geoclue.patch: Retry geoclue a few times so
6 redshift does not explode at startup.
7
8 -- Jackson Doak <noskcaj@ubuntu.com> Thu, 15 Oct 2015 06:10:29 +1100
9
10redshift (1.10-5) unstable; urgency=medium
11
12 * [8a88246] Add some changes from Laurent Bigonville
13 * [ca45b49] Drop README.Debian
14 * [4b34f2c] Add header to quilt patch
15 * [9e854c4] Add debian/gbp.conf
16
17 -- Ritesh Raj Sarraf <rrs@debian.org> Thu, 27 Aug 2015 17:05:00 +0530
18
19redshift (1.10-4) unstable; urgency=medium
20
21 * [c3cdd0e] Drop patch remove_autostart.patch (Closes: #791598)
22 * [47e94ba] Ship appdata file in redshift-gtk.
23 Thanks to Laurent Bigonville (Closes: #791600)
24 * [3a6b76d] Fix reference to correct name.
25 Thanks to Torquil Macdonal Sorensen (Closes: #795502)
26 * [26605bd] Add redshift.desktop file entry. Needed for GeoClue activation.
27 Thanks to Laurent Bigonville (Closes: #789883)
28 * [536ef7e] Add dh-autoreconf to build. Drop autotools_dev from build.
29 Call intltoolize to update po/ files
30 * [4983734] Ship redshift.desktop file
31 * [a1397f2] Add configure flag for systemd user unit dir
32 * [fb6fb18] Add redshift-gtk.desktop file that got dropped off mistakenly
33 in the redshift.desktop patch
34
35 -- Ritesh Raj Sarraf <rrs@debian.org> Sat, 15 Aug 2015 16:46:00 +0200
36
1redshift (1.10-3ubuntu1) wily; urgency=medium37redshift (1.10-3ubuntu1) wily; urgency=medium
238
3 * Merge from Debian. Remaining changes:39 * Merge from Debian. Remaining changes:
440
=== modified file 'debian/control'
--- debian/control 2015-06-28 09:25:43 +0000
+++ debian/control 2015-10-14 19:20:52 +0000
@@ -4,7 +4,7 @@
4Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>4Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
5XSBC-Original-Maintainer: Ritesh Raj Sarraf <rrs@debian.org>5XSBC-Original-Maintainer: Ritesh Raj Sarraf <rrs@debian.org>
6Uploaders: Franziska Lichtblau <rhalina@old-forest.org>6Uploaders: Franziska Lichtblau <rhalina@old-forest.org>
7Build-Depends: debhelper (>= 9), autotools-dev (>= 20100122.1~), pkg-config (>= 0.25), dpkg-dev (>= 1.16.1~), libxcb-randr0-dev, libxxf86vm-dev, libgconf2-dev, python3, libxext-dev, libgeoclue-dev, libdrm-dev, intltool, dh-python7Build-Depends: debhelper (>= 9), autotools-dev (>= 20100122.1~), pkg-config (>= 0.25), dpkg-dev (>= 1.16.1~), libxcb-randr0-dev, libxxf86vm-dev, libgconf2-dev, python3, libxext-dev, libdrm-dev, intltool, dh-python, dh-autoreconf
8X-Python3-Version: >= 3.28X-Python3-Version: >= 3.2
9Standards-Version: 3.9.3 9Standards-Version: 3.9.3
10Vcs-Git: git://anonscm.debian.org/users/rhalina-guest/redshift.git10Vcs-Git: git://anonscm.debian.org/users/rhalina-guest/redshift.git
1111
=== added file 'debian/gbp.conf'
--- debian/gbp.conf 1970-01-01 00:00:00 +0000
+++ debian/gbp.conf 2015-10-14 19:20:52 +0000
@@ -0,0 +1,2 @@
1[DEFAULT]
2pristine-tar = True
03
=== added file 'debian/patches/add-desktop-file.patch'
--- debian/patches/add-desktop-file.patch 1970-01-01 00:00:00 +0000
+++ debian/patches/add-desktop-file.patch 2015-10-14 19:20:52 +0000
@@ -0,0 +1,34 @@
1Add .desktop file until next release, when we can then drop it
2--- a/Makefile.am
3+++ b/Makefile.am
4@@ -28,6 +28,7 @@
5 data/icons/ubuntu-mono-light/scalable/apps/redshift-status-off.svg
6
7 DESKTOP_IN_FILES = \
8+ data/applications/redshift.desktop.in \
9 data/applications/redshift-gtk.desktop.in
10
11 SYSTEMD_USER_UNIT_IN_FILES = \
12--- /dev/null
13+++ b/data/applications/redshift.desktop.in
14@@ -0,0 +1,10 @@
15+[Desktop Entry]
16+Version=1.0
17+_Name=Redshift
18+_GenericName=Color temperature adjustment
19+_Comment=Color temperature adjustment tool
20+Exec=redshift
21+Icon=redshift
22+Terminal=true
23+Type=Application
24+NoDisplay=true
25--- a/po/POTFILES.in
26+++ b/po/POTFILES.in
27@@ -1,6 +1,7 @@
28 # List of source files containing translatable strings
29
30 data/appdata/redshift-gtk.appdata.xml.in
31+data/applications/redshift.desktop.in
32 data/applications/redshift-gtk.desktop.in
33
34 src/redshift.c
035
=== modified file 'debian/patches/retry-geoclue.patch'
--- debian/patches/retry-geoclue.patch 2014-11-01 17:06:15 +0000
+++ debian/patches/retry-geoclue.patch 2015-10-14 19:20:52 +0000
@@ -2,11 +2,13 @@
2Author: Clint Byrum <clint@ubuntu.com>2Author: Clint Byrum <clint@ubuntu.com>
3Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/redshift/+bug/8689043Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/redshift/+bug/868904
44
5Index: redshift/src/location-geoclue.c5---
6===================================================================6 src/location-geoclue.c | 28 ++++++++++++++++++++--------
7--- redshift.orig/src/location-geoclue.c 2012-03-02 17:45:30.000000000 -08007 1 file changed, 20 insertions(+), 8 deletions(-)
8+++ redshift/src/location-geoclue.c 2012-03-02 19:06:32.854211600 -08008
9@@ -19,6 +19,7 @@9--- a/src/location-geoclue.c
10+++ b/src/location-geoclue.c
11@@ -20,6 +20,7 @@
10 #include <stdio.h>12 #include <stdio.h>
11 #include <stdlib.h>13 #include <stdlib.h>
12 #include <string.h>14 #include <string.h>
@@ -14,7 +16,7 @@
14 16
15 #include <geoclue/geoclue-master.h>17 #include <geoclue/geoclue-master.h>
16 #include <geoclue/geoclue-position.h>18 #include <geoclue/geoclue-position.h>
17@@ -160,17 +161,28 @@19@@ -191,17 +192,28 @@ location_geoclue_get_location(location_g
18 GError *error = NULL;20 GError *error = NULL;
19 double latitude = 0, longitude = 0;21 double latitude = 0, longitude = 0;
20 22
2123
=== modified file 'debian/patches/series'
--- debian/patches/series 2014-11-01 17:06:15 +0000
+++ debian/patches/series 2015-10-14 19:20:52 +0000
@@ -1,2 +1,2 @@
1remove_autostart.patch1add-desktop-file.patch
2retry-geoclue.patch2retry-geoclue.patch
33
=== modified file 'debian/redshift-gtk.docs'
--- debian/redshift-gtk.docs 2015-06-28 09:25:43 +0000
+++ debian/redshift-gtk.docs 2015-10-14 19:20:52 +0000
@@ -1,2 +1,1 @@
1README1README
2debian/README.Debian
32
=== modified file 'debian/redshift-gtk.install'
--- debian/redshift-gtk.install 2015-06-28 09:25:43 +0000
+++ debian/redshift-gtk.install 2015-10-14 19:20:52 +0000
@@ -1,4 +1,5 @@
1usr/bin/redshift-gtk1usr/bin/redshift-gtk
2usr/lib/python*2usr/lib/python*
3usr/share/icons3usr/share/icons
4usr/share/applications/4usr/share/appdata/redshift-gtk.appdata.xml
5usr/share/applications/redshift-gtk.desktop
56
=== modified file 'debian/redshift.install'
--- debian/redshift.install 2010-02-18 09:58:46 +0000
+++ debian/redshift.install 2015-10-14 19:20:52 +0000
@@ -1,2 +1,3 @@
1usr/bin/redshift1usr/bin/redshift
2usr/share/locale2usr/share/locale
3usr/share/applications/redshift.desktop
34
=== modified file 'debian/rules'
--- debian/rules 2015-06-28 09:25:43 +0000
+++ debian/rules 2015-10-14 19:20:52 +0000
@@ -6,10 +6,11 @@
6include /usr/share/dpkg/buildflags.mk6include /usr/share/dpkg/buildflags.mk
77
8%:8%:
9 dh $@ --with autotools_dev,python39 dh $@ --with python3,autoreconf
1010
11override_dh_auto_configure:11override_dh_auto_configure:
12 dh_auto_configure -- --enable-randr --enable-vidmode --enable-geoclue2 --disable-geoclue --enable-ubuntu12 intltoolize --force
13 dh_auto_configure -- --enable-randr --enable-vidmode --enable-geoclue2 --disable-geoclue --with-systemduserunitdir=/usr/lib/systemd/user/ --enable-ubuntu
1314
14override_dh_installchangelogs:15override_dh_installchangelogs:
15 dh_installchangelogs NEWS16 dh_installchangelogs NEWS
1617
=== modified file 'src/location-geoclue.c'
--- src/location-geoclue.c 2015-06-28 09:25:43 +0000
+++ src/location-geoclue.c 2015-10-14 19:20:52 +0000
@@ -20,7 +20,6 @@
20#include <stdio.h>20#include <stdio.h>
21#include <stdlib.h>21#include <stdlib.h>
22#include <string.h>22#include <string.h>
23#include <unistd.h>
2423
25#include <geoclue/geoclue-master.h>24#include <geoclue/geoclue-master.h>
26#include <geoclue/geoclue-position.h>25#include <geoclue/geoclue-position.h>
@@ -192,28 +191,17 @@
192 GError *error = NULL;191 GError *error = NULL;
193 double latitude = 0, longitude = 0;192 double latitude = 0, longitude = 0;
194193
195 /* Retry 3 times because this seems to timeout quite a bit */194 fields = geoclue_position_get_position(state->position, NULL,
196 int retries = 4;195 &latitude, &longitude, NULL,
197 while(--retries) {196 NULL, &error);
198 fields = geoclue_position_get_position(state->position, NULL,197 if (error) {
199 &latitude, &longitude, NULL,198 g_printerr(_("Could not get location: %s.\n"), error->message);
200 NULL, &error);199 g_error_free(error);
201 if (error) {200 return -1;
202 g_printerr(_("Could not get location (%d retries left): %s.\n"), retries, error->message);
203 g_error_free(error);
204 return -1;
205 }
206 if (fields & GEOCLUE_POSITION_FIELDS_LATITUDE &&
207 fields & GEOCLUE_POSITION_FIELDS_LONGITUDE) {
208 break;
209 }
210 g_warning(_("Could not get location, %d retries left.\n"), retries);
211 /* Sleep for a while to let */
212 usleep(1000000);
213 }201 }
214 202
215 if (fields & GEOCLUE_POSITION_FIELDS_LATITUDE &&203 if (fields & GEOCLUE_POSITION_FIELDS_LATITUDE &&
216 fields & GEOCLUE_POSITION_FIELDS_LONGITUDE) {204 fields & GEOCLUE_POSITION_FIELDS_LONGITUDE) {
217 fprintf(stdout, _("According to the geoclue provider"205 fprintf(stdout, _("According to the geoclue provider"
218 " we're at: %.2f, %.2f\n"),206 " we're at: %.2f, %.2f\n"),
219 latitude, longitude);207 latitude, longitude);
220208
=== modified file 'src/redshift-gtk/statusicon.py'
--- src/redshift-gtk/statusicon.py 2015-06-28 09:25:43 +0000
+++ src/redshift-gtk/statusicon.py 2015-10-14 19:20:52 +0000
@@ -273,6 +273,18 @@
273 suspend_menu_item.set_submenu(suspend_menu)273 suspend_menu_item.set_submenu(suspend_menu)
274 self.status_menu.append(suspend_menu_item)274 self.status_menu.append(suspend_menu_item)
275275
276 # Add autostart option
277 autostart_item = Gtk.CheckMenuItem.new_with_label(_('Autostart'))
278 try:
279 autostart_item.set_active(utils.get_autostart())
280 except IOError as strerror:
281 print(strerror)
282 autostart_item.set_property('sensitive', False)
283 else:
284 autostart_item.connect('toggled', self.autostart_cb)
285 finally:
286 self.status_menu.append(autostart_item)
287
276 # Add info action288 # Add info action
277 info_item = Gtk.MenuItem.new_with_label(_('Info'))289 info_item = Gtk.MenuItem.new_with_label(_('Info'))
278 info_item.connect('activate', self.show_info_cb)290 info_item.connect('activate', self.show_info_cb)

Subscribers

People subscribed via source and target branches

to all changes: