diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 3 | ||||
-rw-r--r-- | src/cairo-utils.vala | 75 | ||||
-rw-r--r-- | src/fixes.vapi | 16 | ||||
-rw-r--r-- | src/idle-monitor.vala | 216 | ||||
-rw-r--r-- | src/menubar.vala | 1 | ||||
-rw-r--r-- | src/prompt-box.vala | 3 | ||||
-rw-r--r-- | src/settings-daemon.vala | 4 | ||||
-rw-r--r-- | src/xsync.vapi | 103 |
8 files changed, 323 insertions, 98 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 062c7c9..39bef81 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -7,6 +7,7 @@ arctica_greeter_SOURCES = \ config.vapi \ fixes.vapi \ indicator.vapi \ + xsync.vapi \ animate-timer.vala \ background.vala \ cached-image.vala \ @@ -20,6 +21,7 @@ arctica_greeter_SOURCES = \ fading-label.vala \ flat-button.vala \ greeter-list.vala \ + idle-monitor.vala \ list-stack.vala \ main-window.vala \ menu.vala \ @@ -40,7 +42,6 @@ logo_generator_SOURCES = logo-generator.vala arctica_greeter_CFLAGS = \ $(ARCTICA_GREETER_CFLAGS) \ -w \ - -DGNOME_DESKTOP_USE_UNSTABLE_API \ -DGETTEXT_PACKAGE=\"$(GETTEXT_PACKAGE)\" \ -DLOCALEDIR=\""$(localedir)"\" \ -DVERSION=\"$(VERSION)\" \ diff --git a/src/cairo-utils.vala b/src/cairo-utils.vala index a30a580..1bf0d85 100644 --- a/src/cairo-utils.vala +++ b/src/cairo-utils.vala @@ -38,81 +38,6 @@ public void rounded_rectangle (Cairo.Context c, double x, double y, c.rel_curve_to (0, -kappa, radius - kappa, -radius, radius, -radius); } -class GaussianBlur -{ - /* Gaussian Blur, based on Mirco Mueller work on notify-osd */ - - public static void surface (Cairo.ImageSurface surface, uint radius, double sigma = 0.0f) - { - if (surface.get_format () != Cairo.Format.ARGB32) - { - warning ("Impossible to blur a non ARGB32-formatted ImageSurface"); - return; - } - - surface.flush (); - - double radiusf = Math.fabs (radius) + 1.0f; - - if (sigma == 0.0f) - sigma = Math.sqrt (-(radiusf * radiusf) / (2.0f * Math.log (1.0f / 255.0f))); - - int w = surface.get_width (); - int h = surface.get_height (); - int s = surface.get_stride (); - - // create pixman image for cairo image surface - unowned uchar[] p = surface.get_data (); - var src = new Pixman.Image.bits (Pixman.Format.A8R8G8B8, w, h, p, s); - - // attach gaussian kernel to pixman image - var params = create_gaussian_blur_kernel ((int) radius, sigma); - src.set_filter (Pixman.Filter.CONVOLUTION, params); - - // render blured image to new pixman image - Pixman.Image.composite (Pixman.Operation.SRC, src, null, src, - 0, 0, 0, 0, 0, 0, (uint16) w, (uint16) h); - - surface.mark_dirty (); - } - - private static Pixman.Fixed[] create_gaussian_blur_kernel (int radius, double sigma) - { - double scale2 = 2.0f * sigma * sigma; - double scale1 = 1.0f / (Math.PI * scale2); - int size = 2 * radius + 1; - int n_params = size * size; - double sum = 0; - - var tmp = new double[n_params]; - - // caluclate gaussian kernel in floating point format - for (int i = 0, x = -radius; x <= radius; ++x) - { - for (int y = -radius; y <= radius; ++y, ++i) - { - double u = x * x; - double v = y * y; - - tmp[i] = scale1 * Math.exp (-(u+v)/scale2); - - sum += tmp[i]; - } - } - - // normalize gaussian kernel and convert to fixed point format - var params = new Pixman.Fixed[n_params + 2]; - - params[0] = Pixman.Fixed.int (size); - params[1] = Pixman.Fixed.int (size); - - for (int i = 2; i < params.length; ++i) - params[i] = Pixman.Fixed.double (tmp[i] / sum); - - return params; - } -} - class ExponentialBlur { /* Exponential Blur, based on the Nux version */ diff --git a/src/fixes.vapi b/src/fixes.vapi index 8d08370..3cbae7a 100644 --- a/src/fixes.vapi +++ b/src/fixes.vapi @@ -34,22 +34,6 @@ namespace Gtk } } -namespace Gnome -{ - [CCode (cheader_filename = "libgnome-desktop/gnome-idle-monitor.h")] - public class IdleMonitor : GLib.Object - { - public IdleMonitor (); - public IdleMonitor.for_device (Gdk.Device device); - public uint add_idle_watch (uint64 interval_msec, IdleMonitorWatchFunc callback, GLib.DestroyNotify? notify = null); - public uint add_user_active_watch (IdleMonitorWatchFunc callback, GLib.DestroyNotify? notify = null); - public void remove_watch (uint id); - public int64 get_idletime (); - } - - public delegate void IdleMonitorWatchFunc (IdleMonitor monitor, uint id); -} - // Note, fixed in 1.10.0 namespace LightDM { diff --git a/src/idle-monitor.vala b/src/idle-monitor.vala new file mode 100644 index 0000000..b3a423e --- /dev/null +++ b/src/idle-monitor.vala @@ -0,0 +1,216 @@ +public delegate void IdleMonitorWatchFunc (IdleMonitor monitor, uint id); + +public class IdleMonitor +{ + private unowned X.Display display; + private HashTable<uint, IdleMonitorWatch> watches; + private HashTable<uint32, uint32> alarms; + private int sync_event_base; + private X.ID counter; + private X.ID user_active_alarm; + private int serial = 0; + + public IdleMonitor () + { + watches = new HashTable<uint, IdleMonitorWatch> (null, null); + alarms = new HashTable<uint32, uint32> (null, null); + init_xsync (); + } + + ~IdleMonitor () + { + foreach (var watch in watches.get_values ()) + remove_watch (watch.id); + if (user_active_alarm != X.None) + X.Sync.DestroyAlarm (display, user_active_alarm); + + /* Note this is a bit weird, since we need to pass null as the window by Vala treats this as a method */ + Gdk.Window w = null; + w.remove_filter (xevent_filter); + } + + public uint add_idle_watch (uint64 interval_msec, IdleMonitorWatchFunc callback) + { + var watch = make_watch (xsync_alarm_set (X.Sync.TestType.PositiveTransition, interval_msec, true), callback); + alarms.add ((uint32) watch.xalarm); + return watch.id; + } + + public uint add_user_active_watch (IdleMonitorWatchFunc callback) + { + set_alarm_enabled (display, user_active_alarm, true); + var watch = make_watch (user_active_alarm, callback); + return watch.id; + } + + public void remove_watch (uint id) + { + var watch = watches.lookup (id); + watches.remove (id); + if (watch.xalarm != user_active_alarm) + X.Sync.DestroyAlarm (display, watch.xalarm); + } + + private void init_xsync () + { + var d = Gdk.Display.get_default (); + if (!(d is Gdk.X11.Display)) + { + warning ("Only support idle monitor under X"); + return; + } + display = (d as Gdk.X11.Display).get_xdisplay (); + + int sync_error_base; + var res = X.Sync.QueryExtension (display, out sync_event_base, out sync_error_base); + if (res == 0) + { + warning ("IdleMonitor: Sync extension not present"); + return; + } + + int major, minor; + res = X.Sync.Initialize (display, out major, out minor); + if (res == 0) + { + warning ("IdleMonitor: Unable to initialize Sync extension"); + return; + } + + counter = find_idletime_counter (); + /* IDLETIME counter not found? */ + if (counter == X.None) + return; + + user_active_alarm = xsync_alarm_set (X.Sync.TestType.NegativeTransition, 1, false); + + /* Note this is a bit weird, since we need to pass null as the window by Vala treats this as a method */ + Gdk.Window w = null; + w.add_filter (xevent_filter); + } + + private Gdk.FilterReturn xevent_filter (Gdk.XEvent xevent, Gdk.Event event) + { + var ev = (X.Event*) xevent; + if (ev.xany.type != sync_event_base + X.Sync.AlarmNotify) + return Gdk.FilterReturn.CONTINUE; + + var alarm_event = (X.Sync.AlarmNotifyEvent*) xevent; + handle_alarm_notify_event (alarm_event); + + return Gdk.FilterReturn.CONTINUE; + } + + private IdleMonitorWatch make_watch (X.ID xalarm, IdleMonitorWatchFunc callback) + { + var watch = new IdleMonitorWatch (); + watch.id = get_next_watch_serial (); + watch.callback = callback; + watch.xalarm = xalarm; + + watches.insert (watch.id, watch); + + return watch; + } + + private X.ID xsync_alarm_set (X.Sync.TestType test_type, uint64 interval, bool want_events) + { + var attr = X.Sync.AlarmAttributes (); + X.Sync.Value delta; + X.Sync.IntToValue (out delta, 0); + attr.trigger.counter = counter; + attr.trigger.value_type = X.Sync.ValueType.Absolute; + attr.delta = delta; + attr.events = want_events; + X.Sync.IntsToValue (out attr.trigger.wait_value, (uint) interval, (int) (interval >> 32)); + attr.trigger.test_type = test_type; + + return X.Sync.CreateAlarm (display, X.Sync.CA.Counter | X.Sync.CA.ValueType | X.Sync.CA.TestType | X.Sync.CA.Value | X.Sync.CA.Delta | X.Sync.CA.Events, attr); + } + + private void ensure_alarm_rescheduled (X.Display dpy, X.ID alarm) + { + /* Some versions of Xorg have an issue where alarms aren't + * always rescheduled. Calling X.Sync.ChangeAlarm, even + * without any attributes, will reschedule the alarm. */ + var attr = X.Sync.AlarmAttributes (); + X.Sync.ChangeAlarm (dpy, alarm, 0, attr); + } + + private void set_alarm_enabled (X.Display dpy, X.ID alarm, bool enabled) + { + var attr = X.Sync.AlarmAttributes (); + attr.events = enabled; + X.Sync.ChangeAlarm (dpy, alarm, X.Sync.CA.Events, attr); + } + + private void handle_alarm_notify_event (X.Sync.AlarmNotifyEvent* alarm_event) + { + if (alarm_event.state != X.Sync.AlarmState.Active) + return; + + var alarm = alarm_event.alarm; + var has_alarm = false; + + if (alarm == user_active_alarm) + { + set_alarm_enabled (display, alarm, false); + has_alarm = true; + } + else if (alarms.contains ((uint32) alarm)) + { + ensure_alarm_rescheduled (display, alarm); + has_alarm = true; + } + + if (has_alarm) + { + foreach (var watch in watches.get_values ()) + fire_watch (watch, alarm); + } + } + + private void fire_watch (IdleMonitorWatch watch, X.ID alarm) + { + if (watch.xalarm != alarm) + return; + + if (watch.callback != null) + watch.callback (this, watch.id); + + if (watch.xalarm == user_active_alarm) + remove_watch (watch.id); + } + + private X.ID find_idletime_counter () + { + X.ID counter = X.None; + + int ncounters; + var counters = X.Sync.ListSystemCounters (display, out ncounters); + for (var i = 0; i < ncounters; i++) + { + if (counters[i].name != null && strcmp (counters[i].name, "IDLETIME") == 0) + { + counter = counters[i].counter; + break; + } + } + X.Sync.FreeSystemCounterList (counters); + + return counter; + } + + private uint32 get_next_watch_serial () + { + AtomicInt.inc (ref serial); + return serial; + } +} + +public class IdleMonitorWatch +{ + public uint id; + public IdleMonitorWatchFunc callback; + public X.ID xalarm; +} diff --git a/src/menubar.vala b/src/menubar.vala index 2af4f2d..8a507a4 100644 --- a/src/menubar.vala +++ b/src/menubar.vala @@ -230,7 +230,6 @@ public class MenuBar : Gtk.MenuBar high_contrast_item.set_active (UGSettings.get_boolean (UGSettings.KEY_HIGH_CONTRAST)); var item = new Gtk.CheckMenuItem.with_label (_("Screen Reader")); item.toggled.connect (screen_reader_toggled_cb); - item.add_accelerator ("activate", accel_group, Gdk.Key.s, Gdk.ModifierType.CONTROL_MASK, Gtk.AccelFlags.VISIBLE); item.add_accelerator ("activate", accel_group, Gdk.Key.s, Gdk.ModifierType.SUPER_MASK | Gdk.ModifierType.MOD1_MASK, Gtk.AccelFlags.VISIBLE); item.show (); submenu.append (item); diff --git a/src/prompt-box.vala b/src/prompt-box.vala index 075a6ba..50c46d1 100644 --- a/src/prompt-box.vala +++ b/src/prompt-box.vala @@ -283,9 +283,6 @@ public class PromptBox : FadableBox base.get_preferred_height (out min, out nat); min = round_to_grid (min + GreeterList.BORDER * 2) - GreeterList.BORDER * 2; nat = round_to_grid (nat + GreeterList.BORDER * 2) - GreeterList.BORDER * 2; - - if (position <= -1 || position >= 1) - min = nat = grid_size; } public void set_zone (Gtk.Widget zone) diff --git a/src/settings-daemon.vala b/src/settings-daemon.vala index 6839df2..56d4fae 100644 --- a/src/settings-daemon.vala +++ b/src/settings-daemon.vala @@ -174,13 +174,13 @@ public class ScreenSaverInterface : Object { public signal void active_changed (bool value); - private Gnome.IdleMonitor idle_monitor; + private IdleMonitor idle_monitor; private bool _active = false; private uint idle_watch = 0; public ScreenSaverInterface () { - idle_monitor = new Gnome.IdleMonitor (); + idle_monitor = new IdleMonitor (); _set_active (false); } diff --git a/src/xsync.vapi b/src/xsync.vapi new file mode 100644 index 0000000..6e6bfff --- /dev/null +++ b/src/xsync.vapi @@ -0,0 +1,103 @@ +namespace X +{ + [CCode (cprefix = "", cheader_filename = "X11/extensions/sync.h")] + namespace Sync + { + [CCode (cname = "XSyncQueryExtension")] + public X.Status QueryExtension (X.Display display, out int event_base, out int error_base); + [CCode (cname = "XSyncInitialize")] + public X.Status Initialize (X.Display display, out int major_version, out int minor_version); + [CCode (cname = "XSyncListSystemCounters")] + public SystemCounter* ListSystemCounters (X.Display display, out int n_counters); + [CCode (cname = "XSyncFreeSystemCounterList")] + public void FreeSystemCounterList (SystemCounter* counters); + [CCode (cname = "XSyncQueryCounter")] + public X.Status QueryCounter (X.Display display, X.ID counter, out Value value); + [CCode (cname = "XSyncCreateAlarm")] + public X.ID CreateAlarm (X.Display display, CA values_mask, AlarmAttributes values); + [CCode (cname = "XSyncDestroyAlarm")] + public X.Status DestroyAlarm (X.Display display, X.ID alarm); + [CCode (cname = "XSyncQueryAlarm")] + public X.Status QueryAlarm (X.Display display, X.ID alarm, out AlarmAttributes values); + [CCode (cname = "XSyncChangeAlarm")] + public X.Status ChangeAlarm (X.Display display, X.ID alarm, CA values_mask, AlarmAttributes values); + [CCode (cname = "XSyncSetPriority")] + public X.Status SetPriority (X.Display display, X.ID alarm, int priority); + [CCode (cname = "XSyncGetPriority")] + public X.Status GetPriority (X.Display display, X.ID alarm, out int priority); + [CCode (cname = "XSyncIntToValue")] + public void IntToValue (out Value value, int v); + [CCode (cname = "XSyncIntsToValue")] + public void IntsToValue (out Value value, uint l, int h); + [CCode (cname = "XSyncValueGreaterThan")] + public bool ValueGreaterThan (Value a, Value b); + [CCode (cprefix = "XSyncCA")] + public enum CA + { + Counter, + ValueType, + Value, + TestType, + Delta, + Events + } + [CCode (cname = "XSyncSystemCounter", has_type_id = false)] + public struct SystemCounter + { + public string name; + public X.ID counter; + } + [CCode (cname = "XSyncAlarmNotify")] + public int AlarmNotify; + [CCode (cname = "XSyncAlarmNotifyEvent", has_type_id = false)] + public struct AlarmNotifyEvent + { + public X.ID alarm; + public AlarmState state; + } + [CCode (cname = "XSyncAlarmState", cprefix = "XSyncAlarm")] + public enum AlarmState + { + Active, + Inactive, + Destroyed + } + [CCode (cname = "XSyncAlarmAttributes", has_type_id = false)] + public struct AlarmAttributes + { + public Trigger trigger; + public Value delta; + public bool events; + public AlarmState state; + } + [CCode (cname = "XSyncTrigger", has_type_id = false)] + public struct Trigger + { + public X.ID counter; + public ValueType value_type; + public Value wait_value; + public TestType test_type; + } + [CCode (cname = "XSyncValueType", cprefix = "XSync")] + public enum ValueType + { + Absolute, + Relative + } + [CCode (cname = "XSyncValue", has_type_id = false)] + [SimpleType] + public struct Value + { + public int hi; + public uint lo; + } + [CCode (cname = "XSyncTestType", cprefix = "XSync")] + public enum TestType + { + PositiveTransition, + NegativeTransition, + PositiveComparison, + NegativeComparison + } + } +} |