[gnome-initial-setup/shell/4765: 37/362] Add FBE factory mode dialog



commit b4ab9b4a42465870d7d5afd8c732df2d597d2e82
Author: Juan A. Suarez Romero <jasuarez igalia com>
Date:   Tue May 20 16:40:45 2014 +0200

    Add FBE factory mode dialog
    
    Dialog that can be accessed from the very first screen in the FBE,
    though Ctrl+F combination.
    
    This dialog shows software version and the product serial (both as text
    and as a barcode). It allows directly to power off the device.
    
    [endlessm/eos-shell#2437]

 configure.ac                                       |   14 ++
 .../pages/language/gis-language-page.c             |  223 +++++++++++++++++++-
 .../pages/language/gis-language-page.ui            |  122 +++++++++++-
 3 files changed, 355 insertions(+), 4 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 47794c2..e64b417 100644
--- a/configure.ac
+++ b/configure.ac
@@ -63,6 +63,20 @@ if test "x$GEOCLUE_DBUS_INTERFACE_XML" = "x"; then
 fi
 AC_SUBST(GEOCLUE_DBUS_INTERFACE_XML)
 
+# Zint barcode
+AC_CHECK_LIB(zint, ZBarcode_Render,
+        [have_libzint=yes], [have_libzint=no])
+if test "x$have_libzint" = "xno" ; then
+   AC_MSG_ERROR([*** libzint not found ***])
+fi
+LIBZINT_CFLAGS=""
+LIBZINT_LIBS="-lzint"
+AC_SUBST(LIBZINT_CFLAGS)
+AC_SUBST(LIBZINT_LIBS)
+
+INITIAL_SETUP_CFLAGS="$INITIAL_SETUP_CFLAGS $LIBZINT_CFLAGS"
+INITIAL_SETUP_LIBS="$INITIAL_SETUP_LIBS $LIBZINT_LIBS"
+
 AC_ARG_ENABLE(ibus,
         AS_HELP_STRING([--disable-ibus],
                        [Disable IBus support]),
diff --git a/gnome-initial-setup/pages/language/gis-language-page.c 
b/gnome-initial-setup/pages/language/gis-language-page.c
index cf6bf2f..e2bd628 100644
--- a/gnome-initial-setup/pages/language/gis-language-page.c
+++ b/gnome-initial-setup/pages/language/gis-language-page.c
@@ -28,6 +28,9 @@
 
 #define PAGE_ID "language"
 
+#define OSRELEASE_FILE      "/etc/os-release"
+#define SERIAL_VERSION_FILE "/sys/devices/virtual/dmi/id/product_serial"
+
 #include "config.h"
 #include "language-resources.h"
 #include "cc-language-chooser.h"
@@ -37,6 +40,7 @@
 #include <polkit/polkit.h>
 #include <locale.h>
 #include <gtk/gtk.h>
+#include <zint.h>
 
 struct _GisLanguagePagePrivate
 {
@@ -46,6 +50,8 @@ struct _GisLanguagePagePrivate
   const gchar *new_locale_id;
 
   GCancellable *cancellable;
+
+  GtkAccelGroup *accel_group;
 };
 typedef struct _GisLanguagePagePrivate GisLanguagePagePrivate;
 
@@ -199,12 +205,210 @@ ensure_localed_proxy (GisLanguagePage *page)
   }
 }
 
- static void
+static gchar *
+create_serial_barcode (const gchar *serial)
+{
+  gchar *savefile;
+  struct zint_symbol *barcode;
+
+  savefile = g_build_filename (g_get_user_cache_dir (), "product_serial.png", NULL);
+
+  barcode = ZBarcode_Create();
+  strncpy ((char *) barcode->outfile, savefile, 4096);
+  if (ZBarcode_Encode_and_Print (barcode, (gchar *) serial, 0, 0)) {
+    g_warning ("Error while generating barcode: %s", barcode->errtxt);
+  }
+  ZBarcode_Delete (barcode);
+
+  return savefile;
+}
+
+static gchar *
+get_serial_version (void)
+{
+  GError *error = NULL;
+  gchar *serial = NULL;
+
+  g_file_get_contents (SERIAL_VERSION_FILE, &serial, NULL, &error);
+
+  if (error) {
+    g_warning ("Error when reading " SERIAL_VERSION_FILE ": %s", error->message);
+    g_error_free (error);
+    return NULL;
+  }
+
+  return serial;
+}
+
+static gchar *
+get_software_version (void)
+{
+  GDataInputStream *datastream;
+  GError *error = NULL;
+  GFile *osrelease_file = NULL;
+  GFileInputStream *filestream;
+  GString *software_version;
+  gchar *line;
+  gchar *name = NULL;
+  gchar *version = NULL;
+  gchar *version_string = NULL;
+
+  osrelease_file = g_file_new_for_path (OSRELEASE_FILE);
+  filestream = g_file_read (osrelease_file, NULL, &error);
+  if (error) {
+    goto bailout;
+  }
+
+  datastream = g_data_input_stream_new (G_INPUT_STREAM (filestream));
+
+  while ((!name || !version) &&
+         (line = g_data_input_stream_read_line (datastream, NULL, NULL, &error))) {
+    if (g_str_has_prefix (line, "NAME=")) {
+      name = line;
+    } else if (g_str_has_prefix (line, "VERSION=")) {
+      version = line;
+    } else {
+      g_free (line);
+    }
+  }
+
+  if (error) {
+    goto bailout;
+  }
+
+  software_version = g_string_new ("");
+
+  if (name) {
+    g_string_append (software_version, name + strlen ("NAME=\""));
+    g_string_erase (software_version, software_version->len - 1, 1);
+  }
+
+  if (version) {
+    if (name) {
+      g_string_append_c (software_version, ' ');
+    }
+    g_string_append (software_version, version + strlen ("VERSION=\""));
+    g_string_erase (software_version, software_version->len - 1, 1);
+  }
+
+  version_string = g_string_free (software_version, FALSE);
+
+ bailout:
+  g_free (name);
+  g_free (version);
+
+  if (error) {
+    g_warning ("Error reading " OSRELEASE_FILE ": %s", error->message);
+    g_error_free (error);
+  }
+
+  g_clear_object (&datastream);
+  g_clear_object (&filestream);
+  g_clear_object (&osrelease_file);
+
+  if (version_string) {
+    return version_string;
+  } else {
+    return g_strdup ("");
+  }
+}
+
+static void
+system_poweroff (gpointer data)
+{
+  GDBusConnection *bus;
+  GError *error = NULL;
+  GPermission *permission;
+
+  permission = polkit_permission_new_sync ("org.freedesktop.login1.power-off", NULL, NULL, &error);
+  if (error) {
+    g_warning ("Failed getting permission to power off: %s", error->message);
+    g_error_free (error);
+    return;
+  }
+
+  if (!g_permission_get_allowed (permission)) {
+    g_warning ("Not allowed to power off");
+    g_object_unref (permission);
+    return;
+  }
+
+  g_object_unref (permission);
+
+  bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, &error);
+  if (error) {
+    g_warning ("Failed to get system bus: %s", error->message);
+    g_error_free (error);
+    return;
+  }
+
+  g_dbus_connection_call (bus,
+                          "org.freedesktop.login1",
+                          "/org/freedesktop/login1",
+                          "org.freedesktop.login1.Manager",
+                          "PowerOff",
+                          g_variant_new ("(b)", FALSE),
+                          NULL, 0, G_MAXINT, NULL, NULL, NULL);
+
+  g_object_unref (bus);
+}
+
+static void
+show_factory_dialog (GisLanguagePage *page)
+{
+  GtkButton *poweroff_button;
+  GtkDialog *factory_dialog;
+  GtkImage *serial_image;
+  GtkLabel *serial_label;
+  GtkLabel *version_label;
+  gchar *barcode;
+  gchar *serial;
+  gchar *version;
+
+  factory_dialog = OBJ (GtkDialog *, "factory-dialog");
+  version_label = OBJ (GtkLabel *, "software-version");
+  serial_label = OBJ (GtkLabel *, "serial-text");
+  serial_image = OBJ (GtkImage *, "serial-barcode");
+  poweroff_button = OBJ (GtkButton *, "poweroff-button");
+
+  version = get_software_version ();
+  gtk_label_set_text (version_label, version);
+
+  serial = get_serial_version ();
+  if (serial) {
+    gtk_label_set_text (serial_label, serial);
+
+    barcode = create_serial_barcode (serial);
+    gtk_image_set_from_file (serial_image, barcode);
+  } else {
+    gtk_widget_set_visible (serial_label, FALSE);
+    gtk_widget_set_visible (serial_image, FALSE);
+  }
+
+  g_signal_connect_swapped (poweroff_button, "clicked",
+                            G_CALLBACK (system_poweroff), NULL);
+
+  gtk_window_set_transient_for (GTK_WINDOW (factory_dialog),
+                                GTK_WINDOW (gtk_widget_get_toplevel (GTK_WIDGET (page))));
+  gtk_window_set_modal (GTK_WINDOW (factory_dialog), TRUE);
+  gtk_window_present (GTK_WINDOW (factory_dialog));
+
+  if (serial) {
+    g_remove (barcode);
+    g_free (barcode);
+    g_free (serial);
+  }
+
+  g_free (version);
+}
+
+static void
 gis_language_page_constructed (GObject *object)
 {
   GisLanguagePage *page = GIS_LANGUAGE_PAGE (object);
   GisLanguagePagePrivate *priv = gis_language_page_get_instance_private (page);
   GisDriver *driver = GIS_PAGE (page)->driver;
+  GClosure *closure;
   const gchar *lang_override;
 
   g_type_ensure (CC_TYPE_LANGUAGE_CHOOSER);
@@ -233,6 +437,12 @@ gis_language_page_constructed (GObject *object)
   /* Propagate initial language setting to localed/AccountsService */
   set_language (page);
 
+  /* Use ctrl+f to show factory dialog */
+  priv->accel_group = gtk_accel_group_new ();
+  closure = g_cclosure_new_swap (G_CALLBACK (show_factory_dialog), page, NULL);
+  gtk_accel_group_connect (priv->accel_group, GDK_KEY_f, GDK_CONTROL_MASK, 0, closure);
+  g_closure_unref (closure);
+
   gis_page_set_complete (GIS_PAGE (page), TRUE);
   gtk_widget_show (GTK_WIDGET (page));
 }
@@ -252,6 +462,16 @@ gis_language_page_dispose (GObject *object)
   g_clear_object (&priv->permission);
   g_clear_object (&priv->localed);
   g_clear_object (&priv->cancellable);
+  g_clear_object (&priv->accel_group);
+}
+
+static GtkAccelGroup *
+gis_language_page_get_accel_group (GisPage *page)
+{
+  GisLanguagePage *language_page = GIS_LANGUAGE_PAGE (page);
+  GisLanguagePagePrivate *priv = gis_language_page_get_instance_private (language_page);
+
+  return priv->accel_group;
 }
 
 static void
@@ -262,6 +482,7 @@ gis_language_page_class_init (GisLanguagePageClass *klass)
 
   page_class->page_id = PAGE_ID;
   page_class->locale_changed = gis_language_page_locale_changed;
+  page_class->get_accel_group = gis_language_page_get_accel_group;
   object_class->constructed = gis_language_page_constructed;
   object_class->dispose = gis_language_page_dispose;
 }
diff --git a/gnome-initial-setup/pages/language/gis-language-page.ui 
b/gnome-initial-setup/pages/language/gis-language-page.ui
index 2951464..6d77cd5 100644
--- a/gnome-initial-setup/pages/language/gis-language-page.ui
+++ b/gnome-initial-setup/pages/language/gis-language-page.ui
@@ -1,16 +1,132 @@
-<?xml version="1.0"?>
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- Generated with glade 3.16.1 -->
 <interface>
   <requires lib="gtk+" version="3.0"/>
+  <object class="GtkDialog" id="factory-dialog">
+    <property name="can_focus">False</property>
+    <property name="type_hint">dialog</property>
+    <child internal-child="vbox">
+      <object class="GtkBox" id="dialog-vbox1">
+        <property name="can_focus">False</property>
+        <property name="orientation">vertical</property>
+        <property name="spacing">2</property>
+        <child internal-child="action_area">
+          <object class="GtkButtonBox" id="dialog-action_area1">
+            <property name="can_focus">False</property>
+            <property name="layout_style">end</property>
+            <child>
+              <object class="GtkButton" id="poweroff-button">
+                <property name="visible">True</property>
+                <property name="can_focus">True</property>
+                <property name="has_focus">True</property>
+                <property name="has_default">True</property>
+                <property name="receives_default">True</property>
+                <child>
+                  <object class="GtkLabel" id="label1">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="label" translatable="yes">Power Off</property>
+                    <attributes>
+                      <attribute name="font-desc" value="&lt;Enter Value&gt; 16"/>
+                      <attribute name="weight" value="bold"/>
+                    </attributes>
+                  </object>
+                </child>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="fill">True</property>
+            <property name="pack_type">end</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkBox" id="box1">
+            <property name="visible">True</property>
+            <property name="can_focus">False</property>
+            <property name="margin_left">16</property>
+            <property name="margin_right">16</property>
+            <property name="margin_top">16</property>
+            <property name="orientation">vertical</property>
+            <property name="spacing">10</property>
+            <child>
+              <object class="GtkLabel" id="software-version">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label">Endless 1.x.y</property>
+                <attributes>
+                  <attribute name="font-desc" value="&lt;Enter Value&gt; 32"/>
+                  <attribute name="weight" value="bold"/>
+                </attributes>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkImage" id="serial-barcode">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="stock">gtk-missing-image</property>
+              </object>
+              <packing>
+                <property name="expand">True</property>
+                <property name="fill">True</property>
+                <property name="padding">16</property>
+                <property name="position">1</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkLabel" id="serial-text">
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="label" translatable="yes">label</property>
+                <attributes>
+                  <attribute name="font-desc" value="&lt;Enter Value&gt; 26"/>
+                  <attribute name="weight" value="bold"/>
+                </attributes>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">True</property>
+                <property name="position">2</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">True</property>
+            <property name="fill">True</property>
+            <property name="position">1</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+  </object>
   <object class="GtkBox" id="language-page">
     <property name="name">language-page</property>
     <property name="visible">True</property>
+    <property name="can_focus">False</property>
+    <property name="margin_left">80</property>
+    <property name="margin_right">80</property>
     <property name="orientation">vertical</property>
-    <property name="margin-left">80</property>
-    <property name="margin-right">80</property>
     <child>
       <object class="CcLanguageChooser" id="language-chooser">
         <property name="visible">True</property>
       </object>
+      <packing>
+        <property name="expand">False</property>
+        <property name="fill">True</property>
+        <property name="position">0</property>
+      </packing>
     </child>
   </object>
 </interface>


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]