diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/ck-session.c | 223 | ||||
| -rwxr-xr-x | src/test-open-session-with-parameters | 5 | 
2 files changed, 205 insertions, 23 deletions
diff --git a/src/ck-session.c b/src/ck-session.c index d8f09f2..fc5b2b7 100644 --- a/src/ck-session.c +++ b/src/ck-session.c @@ -25,9 +25,12 @@  #include <fcntl.h>  #include <unistd.h>  #include <signal.h> +#include <errno.h> +#include <string.h>  #include <glib.h>  #include <glib/gi18n.h> +#include <glib/gstdio.h>  #include <glib-object.h>  #define DBUS_API_SUBJECT_TO_CHANGE  #include <dbus/dbus-glib.h> @@ -64,6 +67,8 @@ struct CkSessionPrivate          gboolean         idle_hint;          GTimeVal         idle_since_hint; +        guint            idle_timeout_id; +          DBusGConnection *connection;          DBusGProxy      *bus_proxy;  }; @@ -776,12 +781,119 @@ ck_session_get_property (GObject    *object,                  break;          }  } +#define IS_STR_SET(x) (x != NULL && x[0] != '\0') +static gboolean +session_is_text (CkSession *session) +{ +        gboolean ret; + +        ret = FALSE; + +        if (! IS_STR_SET (session->priv->x11_display_device) +            && ! IS_STR_SET (session->priv->x11_display) +            && IS_STR_SET (session->priv->display_device)) { +                ret = TRUE; +        } + +        ck_debug ("Identified session '%s' as %s", +                  session->priv->id, +                  ret ? "text" : "graphical"); + +        return ret; +} + +static void +maybe_update_idle_hint_from_access_time (CkSession *session, +                                         time_t     last_access) +{ +        time_t   now; +        time_t   idletime; +        gboolean is_idle; + +        time (&now); +        if (last_access > now) { +                last_access = now; +        } + +        idletime = now - last_access; + +        is_idle = (idletime > 60); +        ck_debug ("session idletime %ld", (glong)idletime); +        session_set_idle_hint_internal (session, is_idle); +} + +static gboolean +check_tty_idle (CkSession *session) +{ +        struct stat sb; + +        if (session->priv->display_device == NULL) { +                return FALSE; +        } + +        if (g_stat (session->priv->display_device, &sb) < 0) { +                ck_debug ("Unable to stat: %s: %s", session->priv->display_device, g_strerror (errno)); +                return FALSE; +        } + +        maybe_update_idle_hint_from_access_time (session, sb.st_atime); + +        return TRUE; +} + +static void +add_idle_hint_timeout (CkSession *session) +{ +        ck_debug ("Adding watch for text session idle"); +        /* yes this sucks - we'll add file monitoring when it is in glib */ +        if (session->priv->idle_timeout_id == 0) { +#if GLIB_CHECK_VERSION(2,14,0) +                session->priv->idle_timeout_id = g_timeout_add_seconds (30, +                                                                        (GSourceFunc)check_tty_idle, +                                                                        session); +#else +                session->priv->idle_timeout_id = g_timeout_add (30000, +                                                                (GSourceFunc)check_tty_idle, +                                                                session); +#endif +        } +} + +static void +remove_idle_hint_timeout (CkSession *session) +{ +        if (session->priv->idle_timeout_id > 0) { +                g_source_remove (session->priv->idle_timeout_id); +        } +} + +static GObject * +ck_session_constructor (GType                  type, +                        guint                  n_construct_properties, +                        GObjectConstructParam *construct_properties) +{ +        CkSession      *session; +        CkSessionClass *klass; + +        klass = CK_SESSION_CLASS (g_type_class_peek (CK_TYPE_SESSION)); + +        session = CK_SESSION (G_OBJECT_CLASS (ck_session_parent_class)->constructor (type, +                                                                                     n_construct_properties, +                                                                                     construct_properties)); +        if (session_is_text (session)) { +                /* FIXME: use file monitoring once it is in glib */ +                add_idle_hint_timeout (session); +        } + +        return G_OBJECT (session); +}  static void  ck_session_class_init (CkSessionClass *klass)  {          GObjectClass   *object_class = G_OBJECT_CLASS (klass); +        object_class->constructor = ck_session_constructor;          object_class->get_property = ck_session_get_property;          object_class->set_property = ck_session_set_property;          object_class->finalize = ck_session_finalize; @@ -850,7 +962,7 @@ ck_session_class_init (CkSessionClass *klass)                                                                 NULL,                                                                 NULL,                                                                 TRUE, -                                                               G_PARAM_READWRITE)); +                                                               G_PARAM_READWRITE | G_PARAM_CONSTRUCT));          g_object_class_install_property (object_class,                                           PROP_ID,                                           g_param_spec_string ("id", @@ -872,35 +984,35 @@ ck_session_class_init (CkSessionClass *klass)                                                                "session-type",                                                                "session type",                                                                NULL, -                                                              G_PARAM_READWRITE)); +                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT));          g_object_class_install_property (object_class,                                           PROP_X11_DISPLAY,                                           g_param_spec_string ("x11-display",                                                                "x11-display",                                                                "X11 Display",                                                                NULL, -                                                              G_PARAM_READWRITE)); +                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT));          g_object_class_install_property (object_class,                                           PROP_X11_DISPLAY_DEVICE,                                           g_param_spec_string ("x11-display-device",                                                                "x11-display-device",                                                                "X11 Display device",                                                                NULL, -                                                              G_PARAM_READWRITE)); +                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT));          g_object_class_install_property (object_class,                                           PROP_DISPLAY_DEVICE,                                           g_param_spec_string ("display-device",                                                                "display-device",                                                                "Display device",                                                                NULL, -                                                              G_PARAM_READWRITE)); +                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT));          g_object_class_install_property (object_class,                                           PROP_REMOTE_HOST_NAME,                                           g_param_spec_string ("remote-host-name",                                                                "remote-host-name",                                                                "Remote host name",                                                                NULL, -                                                              G_PARAM_READWRITE)); +                                                              G_PARAM_READWRITE | G_PARAM_CONSTRUCT));          g_object_class_install_property (object_class,                                           PROP_USER, @@ -910,7 +1022,7 @@ ck_session_class_init (CkSessionClass *klass)                                                              0,                                                              G_MAXINT,                                                              0, -                                                            G_PARAM_READWRITE)); +                                                            G_PARAM_READWRITE | G_PARAM_CONSTRUCT));          g_object_class_install_property (object_class,                                           PROP_ACTIVE,                                           g_param_spec_boolean ("idle-hint", @@ -945,6 +1057,8 @@ ck_session_finalize (GObject *object)          g_return_if_fail (session->priv != NULL); +        remove_idle_hint_timeout (session); +          g_free (session->priv->id);          g_free (session->priv->cookie);          g_free (session->priv->seat_id); @@ -985,39 +1099,104 @@ ck_session_new_with_parameters (const char      *ssid,                                  const char      *cookie,                                  const GPtrArray *parameters)  { -        GObject *object; -        gboolean res; -        int      i; +        GObject      *object; +        gboolean      res; +        int           i; +        GParameter   *params; +        guint         n_allocated_params; +        guint         n_params; +        GObjectClass *class; +        GType	      object_type; + +        object_type = CK_TYPE_SESSION; +        class = g_type_class_ref (object_type); + +        n_allocated_params = 2; +        if (parameters != NULL) { +                n_allocated_params += parameters->len; +        } -        object = g_object_new (CK_TYPE_SESSION, -                               "id", ssid, -                               "cookie", cookie, -                               NULL); +        params = g_new0 (GParameter, n_allocated_params); + +        n_params = 0; +        params[n_params].name = "id"; +        params[n_params].value.g_type = 0; +        g_value_init (¶ms[n_params].value, G_TYPE_STRING); +        g_value_set_string (¶ms[n_params].value, ssid); +        n_params++; + +        params[n_params].name = "cookie"; +        params[n_params].value.g_type = 0; +        g_value_init (¶ms[n_params].value, G_TYPE_STRING); +        g_value_set_string (¶ms[n_params].value, cookie); +        n_params++;          if (parameters != NULL) {                  for (i = 0; i < parameters->len; i++) { +                        gboolean    res;                          GValue      val_struct = { 0, };                          const char *prop_name;                          GValue     *prop_val; +                        GParamSpec *pspec;                          g_value_init (&val_struct, CK_TYPE_PARAMETER_STRUCT);                          g_value_set_static_boxed (&val_struct, g_ptr_array_index (parameters, i)); -                        dbus_g_type_struct_get (&val_struct, -                                                0, &prop_name, -                                                1, &prop_val, -                                                G_MAXUINT); +                        res = dbus_g_type_struct_get (&val_struct, +                                                      0, &prop_name, +                                                      1, &prop_val, +                                                      G_MAXUINT); +                        if (! res) { +                                ck_debug ("Unable to extract parameter input"); +                                continue; +                        } + +                        if (prop_name == NULL) { +                                ck_debug ("Skipping NULL parameter"); +                                continue; +                        } + +                        if (strcmp (prop_name, "id") == 0 +                            || strcmp (prop_name, "cookie") == 0) { +                                ck_debug ("Skipping restricted parameter: %s", prop_name); +                                continue; +                        } -                        if (g_object_class_find_property (G_OBJECT_GET_CLASS (object), prop_name)) { -                                g_object_set_property (object, prop_name, prop_val); -                        } else { +                        pspec = g_object_class_find_property (class, prop_name); +                        if (! pspec) {                                  ck_debug ("Skipping unknown parameter: %s", prop_name); +                                if (prop_val != NULL) { +                                        g_value_unset (prop_val); +                                } +                                continue;                          } -                        g_value_unset (prop_val); +                        if (!(pspec->flags & G_PARAM_WRITABLE)) { +                                ck_debug ("property '%s' is not writable", pspec->name); +                                continue; +                        } + +                        params[n_params].name = prop_name; +                        params[n_params].value.g_type = 0; +                        g_value_init (¶ms[n_params].value, G_PARAM_SPEC_VALUE_TYPE (pspec)); +                        res = g_value_transform (prop_val, ¶ms[n_params].value); +                        if (! res) { +                                ck_debug ("unable to transform property value for '%s'", pspec->name); +                                continue; +                        } + +                        n_params++;                  }          } +        object = g_object_newv (object_type, n_params, params); + +        while (n_params--) { +                g_value_unset (¶ms[n_params].value); +        } +        g_free (params); +        g_type_class_unref (class); +          res = register_session (CK_SESSION (object));          if (! res) {                  g_object_unref (object); diff --git a/src/test-open-session-with-parameters b/src/test-open-session-with-parameters index 9d026cb..e9e3358 100755 --- a/src/test-open-session-with-parameters +++ b/src/test-open-session-with-parameters @@ -17,9 +17,12 @@ manager = dbus.Interface (manager_obj, 'org.freedesktop.ConsoleKit.Manager')  params = dbus.Array ([], signature = "sv")  params.append (("user", dbus.Variant (730)))  params.append (("session-type", dbus.Variant ("gnome-session"))) -params.append (("x11-display", dbus.Variant (":0.0"))) +#params.append (("x11-display", dbus.Variant (":0.0")))  params.append (("display-device", dbus.Variant ("/dev/tty8")))  params.append (("is-local", dbus.Variant (True))) +params.append (("bogus-property", dbus.Variant ("Something bogus"))) +params.append (("cookie", dbus.Variant ("This should be ignored"))) +params.append (("id", dbus.Variant ("This should be ignored too")))  cookie = manager.OpenSessionWithParameters (params)  os.environ['XDG_SESSION_COOKIE'] = cookie  | 
