[gnome-boxes] UI for specifying product key for Windows XP & 2003



commit 2a8c93728aacd9eb617f7c1f5f58ee4a57a12948
Author: Zeeshan Ali (Khattak) <zeeshanak gnome org>
Date:   Mon Dec 12 21:52:59 2011 +0200

    UI for specifying product key for Windows XP & 2003
    
    Product keys are not required by recent Windows (Vista, 7 and 2008).
    
    https://bugzilla.gnome.org/show_bug.cgi?id=666030

 data/gtk-style.css            |    4 ++
 data/win2k3.sif               |    2 +-
 data/winxp.sif                |    2 +-
 src/unattended-installer.vala |   46 +++++++++++---------
 src/winxp-installer.vala      |   92 +++++++++++++++++++++++++++++++++++++++++
 vapi/upstream/gtk+-3.0.vapi   |   60 ++++++++++++++++++--------
 6 files changed, 165 insertions(+), 41 deletions(-)
---
diff --git a/data/gtk-style.css b/data/gtk-style.css
index ba358bf..5286f2e 100644
--- a/data/gtk-style.css
+++ b/data/gtk-style.css
@@ -78,6 +78,10 @@
     background-image: none;
 }
 
+.boxes-product-key-entry {
+    font-family: monospace;
+}
+
 .osd {
     background-image: none;
     background-color: alpha(#000, 0.0);
diff --git a/data/win2k3.sif b/data/win2k3.sif
index 3a7e864..ff50a69 100644
--- a/data/win2k3.sif
+++ b/data/win2k3.sif
@@ -23,7 +23,7 @@
     OemSkipWelcome=1
 
 [UserData]
-    ProductKey=
+    ProductKey=BOXES_PRODUCT_KEY
     FullName="BOXES_USERNAME"
     OrgName=""
     ComputerName=BOXES_HOSTNAME
diff --git a/data/winxp.sif b/data/winxp.sif
index 3a7e864..ff50a69 100644
--- a/data/winxp.sif
+++ b/data/winxp.sif
@@ -23,7 +23,7 @@
     OemSkipWelcome=1
 
 [UserData]
-    ProductKey=
+    ProductKey=BOXES_PRODUCT_KEY
     FullName="BOXES_USERNAME"
     OrgName=""
     ComputerName=BOXES_HOSTNAME
diff --git a/src/unattended-installer.vala b/src/unattended-installer.vala
index ffaff3f..adc2f05 100644
--- a/src/unattended-installer.vala
+++ b/src/unattended-installer.vala
@@ -34,6 +34,7 @@ private abstract class Boxes.UnattendedInstaller: InstallerMedia {
 
     private bool created_floppy;
 
+    protected Gtk.Table setup_table;
     protected Gtk.Label setup_label;
     protected Gtk.HBox setup_hbox;
     protected Gtk.Switch express_toggle;
@@ -125,22 +126,22 @@ private abstract class Boxes.UnattendedInstaller: InstallerMedia {
         setup_hbox.valign = Gtk.Align.START;
         setup_hbox.margin = 24;
 
-        var table = new Gtk.Table (3, 3, false);
-        setup_hbox.pack_start (table, false, false);
-        table.column_spacing = 10;
-        table.row_spacing = 10;
+        setup_table = new Gtk.Table (3, 3, false);
+        setup_hbox.pack_start (setup_table, false, false);
+        setup_table.column_spacing = 10;
+        setup_table.row_spacing = 10;
 
         // First row
         var label = new Gtk.Label (_("Express Install"));
         label.halign = Gtk.Align.END;
         label.valign = Gtk.Align.CENTER;
-        table.attach_defaults (label, 1, 2, 0, 1);
+        setup_table.attach_defaults (label, 1, 2, 0, 1);
 
         express_toggle = new Gtk.Switch ();
         express_toggle.active = !os_media.live;
         express_toggle.halign = Gtk.Align.START;
         express_toggle.valign = Gtk.Align.CENTER;
-        table.attach_defaults (express_toggle, 2, 3, 0, 1);
+        setup_table.attach_defaults (express_toggle, 2, 3, 0, 1);
 
         // 2nd row (while user avatar spans over 2 rows)
         var avatar_file = "/var/lib/AccountsService/icons/" + Environment.get_user_name ();
@@ -151,23 +152,23 @@ private abstract class Boxes.UnattendedInstaller: InstallerMedia {
         else
             avatar = new Gtk.Image.from_icon_name ("avatar-default", 0);
         avatar.pixel_size = 128;
-        table.attach_defaults (avatar, 0, 1, 1, 3);
+        setup_table.attach_defaults (avatar, 0, 1, 1, 3);
 
         label = new Gtk.Label (_("Username"));
         label.halign = Gtk.Align.END;
         label.valign = Gtk.Align.CENTER;
-        table.attach_defaults (label, 1, 2, 1, 2);
+        setup_table.attach_defaults (label, 1, 2, 1, 2);
         username_entry = new Gtk.Entry ();
         username_entry.text = Environment.get_user_name ();
         username_entry.halign = Gtk.Align.START;
         username_entry.valign = Gtk.Align.CENTER;
-        table.attach_defaults (username_entry, 2, 3, 1, 2);
+        setup_table.attach_defaults (username_entry, 2, 3, 1, 2);
 
         // 3rd row
         label = new Gtk.Label (_("Password"));
         label.halign = Gtk.Align.END;
         label.valign = Gtk.Align.CENTER;
-        table.attach_defaults (label, 1, 2, 2, 3);
+        setup_table.attach_defaults (label, 1, 2, 2, 3);
         password_entry = new Gtk.Entry ();
         password_entry.visibility = false;
         password_entry.visible = true;
@@ -176,14 +177,14 @@ private abstract class Boxes.UnattendedInstaller: InstallerMedia {
         password_entry.valign = Gtk.Align.CENTER;
         var button = new Gtk.Button.with_mnemonic (_("_Add Password"));
         button.valign = Gtk.Align.CENTER;
-        table.attach_defaults (button, 2, 3, 2, 3);
+        setup_table.attach_defaults (button, 2, 3, 2, 3);
         button.clicked.connect (() => {
-            table.remove (button);
-            table.attach_defaults (password_entry, 2, 3, 2, 3);
+            setup_table.remove (button);
+            setup_table.attach_defaults (password_entry, 2, 3, 2, 3);
             password_entry.is_focus = true;
         });
 
-        foreach (var child in table.get_children ())
+        foreach (var child in setup_table.get_children ())
             if (child != express_toggle)
                 express_toggle.bind_property ("active", child, "sensitive", 0);
     }
@@ -199,6 +200,16 @@ private abstract class Boxes.UnattendedInstaller: InstallerMedia {
         debug ("Removed '%s'.", floppy_path);
     }
 
+    protected virtual string fill_unattended_data (string data) throws RegexError {
+        var str = username_regex.replace (data, data.length, 0, username_entry.text);
+        str = password_regex.replace (str, str.length, 0, password_entry.text);
+        str = timezone_regex.replace (str, str.length, 0, timezone);
+        str = kbd_regex.replace (str, str.length, 0, kbd);
+        str = lang_regex.replace (str, str.length, 0, lang);
+
+        return str;
+    }
+
     protected virtual async void prepare_direct_boot (Cancellable? cancellable) throws GLib.Error {}
 
     protected async void exec (string[] argv, Cancellable? cancellable) throws GLib.Error {
@@ -276,12 +287,7 @@ private abstract class Boxes.UnattendedInstaller: InstallerMedia {
         size_t bytes_read;
         while ((bytes_read = yield input_stream.read_async (buffer, Priority.DEFAULT, cancellable)) > 0) {
             var str = ((string) buffer).substring (0, (long) bytes_read);
-
-            str = username_regex.replace (str, str.length, 0, username_entry.text);
-            str = password_regex.replace (str, str.length, 0, password_entry.text);
-            str = timezone_regex.replace (str, str.length, 0, timezone);
-            str = kbd_regex.replace (str, str.length, 0, kbd);
-            str = lang_regex.replace (str, str.length, 0, lang);
+            str = fill_unattended_data (str);
 
             yield output_stream.write_async (str.data, Priority.DEFAULT, cancellable);
         }
diff --git a/src/winxp-installer.vala b/src/winxp-installer.vala
index 37220e2..64f4eba 100644
--- a/src/winxp-installer.vala
+++ b/src/winxp-installer.vala
@@ -2,8 +2,100 @@
 
 // Automated installer media for Windows XP, 2000 and 2003
 private class Boxes.WinXPInstaller: UnattendedInstaller {
+    private const uint[] allowed_dash_positions = { 5, 11, 17, 23 };
+
+    private static Regex key_regex;
+
+    private Gtk.Entry key_entry;
+
+    private ulong key_inserted_id; // ID of key_entry.insert_text signal handler
+
+    static construct {
+        try {
+            key_regex = new Regex ("BOXES_PRODUCT_KEY");
+        } catch (RegexError error) {
+            // This just can't fail
+            assert_not_reached ();
+        }
+    }
+
     public WinXPInstaller.copy (InstallerMedia media) throws GLib.Error {
         var unattended_source = get_unattended_dir (media.os.short_id + ".sif");
         base.copy (media, unattended_source, "Winnt.sif");
     }
+
+    protected override void setup_ui () {
+        base.setup_ui ();
+
+        setup_table.resize (setup_table.n_rows + 1, setup_table.n_columns);
+
+        var hbox = new Gtk.HBox (false, 10);
+        hbox.margin_top = 12;
+
+        // Microsoft Windows product key
+        var label = new Gtk.Label (_("Product Key"));
+        label.halign = Gtk.Align.START;
+        hbox.pack_start (label, true, true, 0);
+
+        var notebook = new Gtk.Notebook ();
+        notebook.show_tabs = false;
+        notebook.show_border = false;
+        var button = new Gtk.Button.with_mnemonic (_("_Add Product Key"));
+        notebook.append_page (button);
+        key_entry = new Gtk.Entry ();
+        key_entry.width_chars = 29;
+        key_entry.max_length = 29;
+        key_entry.get_style_context ().add_class ("boxes-product-key-entry");
+        notebook.append_page (key_entry);
+
+        button.clicked.connect (() => {
+            notebook.next_page ();
+            key_entry.is_focus = true;
+        });
+
+        hbox.pack_start (notebook, true, true, 0);
+        setup_table.attach_defaults (hbox, 0, setup_table.n_columns, setup_table.n_rows - 1, setup_table.n_rows);
+
+        express_toggle.bind_property ("active", hbox, "sensitive", 0);
+
+        key_inserted_id = key_entry.insert_text.connect (on_key_text_inserted);
+    }
+
+    protected override string fill_unattended_data (string data) throws RegexError {
+        var str = base.fill_unattended_data (data);
+
+        return key_regex.replace (str, str.length, 0, key_entry.text);
+    }
+
+    private void on_key_text_inserted (string text, int text_length, ref int position) {
+        var result = "";
+
+        uint i = 0;
+        foreach (var character  in ((char[]) text.data)) {
+            var char_position = i + position;
+
+            if (character != '-') {
+                if (!character.isalnum ())
+                    continue;
+
+                if (char_position in allowed_dash_positions) {
+                    // Insert dash in the right place for our dear user
+                    result += "-";
+                    i++;
+                }
+            } else if (!(char_position in allowed_dash_positions))
+                continue;
+
+            result += character.to_string ();
+            i++;
+        }
+
+        if (result != "") {
+            SignalHandler.block (key_entry, key_inserted_id);
+            key_entry.insert_text (result.up (), result.length, ref position);
+            SignalHandler.unblock (key_entry, key_inserted_id);
+        }
+
+        Signal.stop_emission_by_name (key_entry, "insert-text");
+    }
 }
diff --git a/vapi/upstream/gtk+-3.0.vapi b/vapi/upstream/gtk+-3.0.vapi
index c6cfca8..e48398c 100644
--- a/vapi/upstream/gtk+-3.0.vapi
+++ b/vapi/upstream/gtk+-3.0.vapi
@@ -1,4 +1,4 @@
-/* gtk+-3.0.vapi generated by lt-vapigen, do not modify. */
+/* gtk+-3.0.vapi generated by vapigen, do not modify. */
 
 [CCode (gir_namespace = "Gtk", gir_version = "3.0")]
 namespace Gtk {
@@ -632,11 +632,6 @@ namespace Gtk {
 	}
 	[CCode (cheader_filename = "gtk/gtk.h")]
 	[Compact]
-	public class BindingArg {
-		public GLib.Type arg_type;
-	}
-	[CCode (cheader_filename = "gtk/gtk.h")]
-	[Compact]
 	public class BindingEntry {
 		public weak Gtk.BindingSet binding_set;
 		public uint destroyed;
@@ -647,9 +642,9 @@ namespace Gtk {
 		public Gdk.ModifierType modifiers;
 		public weak Gtk.BindingEntry set_next;
 		public weak Gtk.BindingSignal signals;
-		public static void add_signal (Gtk.BindingSet binding_set, uint keyval, Gdk.ModifierType modifiers, string signal_name, uint n_args);
+		public static void add_signal (Gtk.BindingSet binding_set, uint keyval, Gdk.ModifierType modifiers, string signal_name, uint n_args, ...);
 		public static GLib.TokenType add_signal_from_string (Gtk.BindingSet binding_set, string signal_desc);
-		public static void add_signall (Gtk.BindingSet binding_set, uint keyval, Gdk.ModifierType modifiers, string signal_name, GLib.SList<Gtk.BindingArg> binding_args);
+		public static void add_signall (Gtk.BindingSet binding_set, uint keyval, Gdk.ModifierType modifiers, string signal_name, GLib.SList<Gtk.BindingArg?> binding_args);
 		public static void remove (Gtk.BindingSet binding_set, uint keyval, Gdk.ModifierType modifiers);
 		public static void skip (Gtk.BindingSet binding_set, uint keyval, Gdk.ModifierType modifiers);
 	}
@@ -671,7 +666,8 @@ namespace Gtk {
 	[CCode (cheader_filename = "gtk/gtk.h")]
 	[Compact]
 	public class BindingSignal {
-		public weak Gtk.BindingArg args;
+		[CCode (array_length_cname = "n_args")]
+		public weak Gtk.BindingArg[] args;
 		public uint n_args;
 		public weak Gtk.BindingSignal next;
 		public weak string signal_name;
@@ -2994,13 +2990,13 @@ namespace Gtk {
 	[CCode (cheader_filename = "gtk/gtkx.h")]
 	public class Plug : Gtk.Window, Atk.Implementor, Gtk.Buildable {
 		[CCode (has_construct_function = false, type = "GtkWidget*")]
-		public Plug (X.Window socket_id);
-		public void @construct (X.Window socket_id);
-		public void construct_for_display (Gdk.Display display, X.Window socket_id);
+		public Plug (Gtk.Window socket_id);
+		public void @construct (Gtk.Window socket_id);
+		public void construct_for_display (Gdk.Display display, Gtk.Window socket_id);
 		[CCode (has_construct_function = false, type = "GtkWidget*")]
-		public Plug.for_display (Gdk.Display display, X.Window socket_id);
+		public Plug.for_display (Gdk.Display display, Gtk.Window socket_id);
 		public bool get_embedded ();
-		public X.Window get_id ();
+		public unowned Gtk.Window get_id ();
 		public unowned Gdk.Window get_socket_window ();
 		public bool embedded { get; }
 		public Gdk.Window socket_window { get; }
@@ -3492,7 +3488,7 @@ namespace Gtk {
 	[CCode (cheader_filename = "gtk/gtk.h")]
 	public class Scale : Gtk.Range, Atk.Implementor, Gtk.Buildable, Gtk.Orientable {
 		[CCode (has_construct_function = false, type = "GtkWidget*")]
-		public Scale (Gtk.Orientation orientation, Gtk.Adjustment adjustment);
+		public Scale (Gtk.Orientation orientation, Gtk.Adjustment? adjustment);
 		public void add_mark (double value, Gtk.PositionType position, string? markup);
 		public void clear_marks ();
 		public int get_digits ();
@@ -3798,8 +3794,8 @@ namespace Gtk {
 	public class Socket : Gtk.Container, Atk.Implementor, Gtk.Buildable {
 		[CCode (has_construct_function = false, type = "GtkWidget*")]
 		public Socket ();
-		public void add_id (X.Window window);
-		public X.Window get_id ();
+		public void add_id (Gtk.Window window);
+		public unowned Gtk.Window get_id ();
 		public unowned Gdk.Window get_plug_window ();
 		public virtual signal void plug_added ();
 		public virtual signal bool plug_removed ();
@@ -4096,7 +4092,7 @@ namespace Gtk {
 		public void render_focus (Cairo.Context cr, double x, double y, double width, double height);
 		[CCode (cname = "gtk_render_frame")]
 		public void render_frame (Cairo.Context cr, double x, double y, double width, double height);
-		[CCode (cname = "gtk_render_frame_gab")]
+		[CCode (cname = "gtk_render_frame_gap")]
 		public void render_frame_gap (Cairo.Context cr, double x, double y, double width, double height, Gtk.PositionType gap_side, double xy0_gap, double xy1_gap);
 		[CCode (cname = "gtk_render_handle")]
 		public void render_handle (Cairo.Context cr, double x, double y, double width, double height);
@@ -5991,7 +5987,7 @@ namespace Gtk {
 		[HasEmitter]
 		public signal void delete_text (int start_pos, int end_pos);
 		[HasEmitter]
-		public signal void insert_text (string new_text, int new_text_length, void* position);
+		public signal void insert_text (string new_text, int new_text_length, ref int position);
 	}
 	[CCode (cheader_filename = "gtk/gtk.h")]
 	public interface FileChooser : Gtk.Widget {
@@ -6250,6 +6246,16 @@ namespace Gtk {
 		public int height;
 	}
 	[CCode (cheader_filename = "gtk/gtk.h")]
+	public struct BindingArg {
+		[CCode (cname = "d.long_data")]
+		public long long_data;
+		[CCode (cname = "d.double_data")]
+		public double double_data;
+		[CCode (cname = "d.string_data")]
+		public weak string string_data;
+		public GLib.Type arg_type;
+	}
+	[CCode (cheader_filename = "gtk/gtk.h")]
 	public struct Border {
 		public int16 left;
 		public int16 right;
@@ -8200,36 +8206,52 @@ namespace Gtk {
 	[CCode (cheader_filename = "gtk/gtk.h")]
 	public static void rc_set_default_files (string filenames);
 	[CCode (cheader_filename = "gtk/gtk.h")]
+	[Deprecated (replacement = "StyleContext.render_activity", since = "vala-0.16")]
 	public static void render_activity (Gtk.StyleContext context, Cairo.Context cr, double x, double y, double width, double height);
 	[CCode (cheader_filename = "gtk/gtk.h")]
+	[Deprecated (replacement = "StyleContext.render_arrow", since = "vala-0.16")]
 	public static void render_arrow (Gtk.StyleContext context, Cairo.Context cr, double angle, double x, double y, double size);
 	[CCode (cheader_filename = "gtk/gtk.h")]
+	[Deprecated (replacement = "StyleContext.render_background", since = "vala-0.16")]
 	public static void render_background (Gtk.StyleContext context, Cairo.Context cr, double x, double y, double width, double height);
 	[CCode (cheader_filename = "gtk/gtk.h")]
+	[Deprecated (replacement = "StyleContext.render_check", since = "vala-0.16")]
 	public static void render_check (Gtk.StyleContext context, Cairo.Context cr, double x, double y, double width, double height);
 	[CCode (cheader_filename = "gtk/gtk.h")]
+	[Deprecated (replacement = "StyleContext.render_expander", since = "vala-0.16")]
 	public static void render_expander (Gtk.StyleContext context, Cairo.Context cr, double x, double y, double width, double height);
 	[CCode (cheader_filename = "gtk/gtk.h")]
+	[Deprecated (replacement = "StyleContext.render_extension", since = "vala-0.16")]
 	public static void render_extension (Gtk.StyleContext context, Cairo.Context cr, double x, double y, double width, double height, Gtk.PositionType gap_side);
 	[CCode (cheader_filename = "gtk/gtk.h")]
+	[Deprecated (replacement = "StyleContext.render_focus", since = "vala-0.16")]
 	public static void render_focus (Gtk.StyleContext context, Cairo.Context cr, double x, double y, double width, double height);
 	[CCode (cheader_filename = "gtk/gtk.h")]
+	[Deprecated (replacement = "StyleContext.render_frame", since = "vala-0.16")]
 	public static void render_frame (Gtk.StyleContext context, Cairo.Context cr, double x, double y, double width, double height);
 	[CCode (cheader_filename = "gtk/gtk.h")]
+	[Deprecated (replacement = "StyleContext.render_frame_gap", since = "vala-0.16")]
 	public static void render_frame_gap (Gtk.StyleContext context, Cairo.Context cr, double x, double y, double width, double height, Gtk.PositionType gap_side, double xy0_gap, double xy1_gap);
 	[CCode (cheader_filename = "gtk/gtk.h")]
+	[Deprecated (replacement = "StyleContext.render_handle", since = "vala-0.16")]
 	public static void render_handle (Gtk.StyleContext context, Cairo.Context cr, double x, double y, double width, double height);
 	[CCode (cheader_filename = "gtk/gtk.h")]
+	[Deprecated (replacement = "StyleContext.render_icon", since = "vala-0.16")]
 	public static void render_icon (Gtk.StyleContext context, Cairo.Context cr, Gdk.Pixbuf pixbuf, double x, double y);
 	[CCode (cheader_filename = "gtk/gtk.h")]
+	[Deprecated (replacement = "StyleContext.render_icon_pixbuf", since = "vala-0.16")]
 	public static unowned Gdk.Pixbuf render_icon_pixbuf (Gtk.StyleContext context, Gtk.IconSource source, Gtk.IconSize size);
 	[CCode (cheader_filename = "gtk/gtk.h")]
+	[Deprecated (replacement = "StyleContext.render_layout", since = "vala-0.16")]
 	public static void render_layout (Gtk.StyleContext context, Cairo.Context cr, double x, double y, Pango.Layout layout);
 	[CCode (cheader_filename = "gtk/gtk.h")]
+	[Deprecated (replacement = "StyleContext.render_line", since = "vala-0.16")]
 	public static void render_line (Gtk.StyleContext context, Cairo.Context cr, double x0, double y0, double x1, double y1);
 	[CCode (cheader_filename = "gtk/gtk.h")]
+	[Deprecated (replacement = "StyleContext.render_option", since = "vala-0.16")]
 	public static void render_option (Gtk.StyleContext context, Cairo.Context cr, double x, double y, double width, double height);
 	[CCode (cheader_filename = "gtk/gtk.h")]
+	[Deprecated (replacement = "StyleContext.render_slider", since = "vala-0.16")]
 	public static void render_slider (Gtk.StyleContext context, Cairo.Context cr, double x, double y, double width, double height, Gtk.Orientation orientation);
 	[CCode (cheader_filename = "gtk/gtk.h")]
 	public static void rgb_to_hsv (double r, double g, double b, double h, double s, double v);



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