Index: vapigen/valavapigen.vala
===================================================================
--- vapigen/valavapigen.vala	(révision 2450)
+++ vapigen/valavapigen.vala	(copie de travail)
@@ -189,6 +189,10 @@
 			return quit ();
 		}
 		
+		if (library == null && girparser.package_name != null) {
+			library = girparser.package_name;
+		}
+		
 		if (library != null) {
 			// interface writer ignores external packages
 			foreach (SourceFile file in context.get_source_files ()) {
Index: vapigen/valagirparser.vala
===================================================================
--- vapigen/valagirparser.vala	(révision 2450)
+++ vapigen/valagirparser.vala	(copie de travail)
@@ -31,6 +31,13 @@
 
 	CodeContext context;
 	Namespace glib_ns;
+	string _package_name;
+	public string package_name {
+		get {
+			return _package_name;
+		}
+	}
+	string[] c_header_filenames;
 
 	SourceFile current_source_file;
 	SourceLocation begin;
@@ -38,6 +45,9 @@
 	MarkupTokenType current_token;
 
 	HashMap<string,string> attributes_map = new HashMap<string,string> (str_hash, str_equal);
+	
+	HashMap<string,ArrayList<Method>> class_vmethods = new HashMap<string,ArrayList<Method>> (str_hash, str_equal);
+	HashMap<string,ArrayList<Method>> iface_vmethods = new HashMap<string,ArrayList<Method>> (str_hash, str_equal);
 
 	/**
 	 * Parses all .gir source files in the specified code
@@ -134,6 +144,10 @@
 				}
 			} else if (reader.name == "include") {
 				parse_include ();
+			} else if (reader.name == "package") {
+				parse_package ();
+			} else if (reader.name == "c:include") {
+				parse_c_include ();
 			} else {
 				// error
 				Report.error (get_current_src (), "unknown child element `%s' in `repository'".printf (reader.name));
@@ -149,6 +163,20 @@
 		end_element ("include");
 	}
 
+	void parse_package () {
+		start_element ("package");
+		_package_name = reader.get_attribute ("name");
+		next ();
+		end_element ("package");
+	}
+
+	void parse_c_include () {
+		start_element ("c:include");
+		c_header_filenames += reader.get_attribute ("name");
+		next ();
+		end_element ("c:include");
+	}
+
 	Namespace? parse_namespace () {
 		start_element ("namespace");
 
@@ -164,10 +192,9 @@
 				ns.source_reference = get_current_src ();
 			}
 		}
-
-		string cheader = get_attribute (ns.name, "c:header-filename");
-		if (cheader != null) {
-			ns.set_cheader_filename (cheader);
+		
+		foreach (string c_header in c_header_filenames) {
+			ns.add_cheader_filename (c_header);
 		}
 		next ();
 		while (current_token == MarkupTokenType.START_ELEMENT) {
@@ -191,7 +218,7 @@
 			} else if (reader.name == "glib:boxed") {
 				parse_boxed ();
 			} else if (reader.name == "union") {
-				parse_union ();
+				sym = parse_union ();
 			} else if (reader.name == "constant") {
 				sym = parse_constant ();
 			} else {
@@ -220,6 +247,9 @@
 			current_source_file.add_node (sym);
 		}
 		end_element ("namespace");
+		
+		postprocess_class_vmethods(ns);
+		postprocess_iface_vmethods(ns);
 
 		if (!new_namespace) {
 			ns = null;
@@ -319,7 +349,7 @@
 		next ();
 		var type = parse_type ();
 		if (transfer == "full") {
-			type.value_owned = true;
+			type.value_owned = false;
 		}
 		end_element ("return-value");
 		return type;
@@ -456,17 +486,43 @@
 	Struct parse_record () {
 		start_element ("record");
 		var st = new Struct (reader.get_attribute ("name"), get_current_src ());
+		
+		string glib_is_class_struct_for = reader.get_attribute ("glib:is-class-struct-for");
+		string iface_name = reader.get_attribute ("name");
+		string glib_is_iface_struct_for =
+			(iface_name != null && iface_name.has_suffix("Iface"))
+				? iface_name.substring(0, iface_name.length - 5)
+				: null;
+		
 		st.access = SymbolAccessibility.PUBLIC;
 		next ();
 		while (current_token == MarkupTokenType.START_ELEMENT) {
 			if (reader.name == "field") {
 				st.add_field (parse_field ());
 			} else if (reader.name == "callback") {
-				parse_callback ();
+				if (glib_is_class_struct_for != null) {
+					ArrayList<Method> vmethods = class_vmethods.get (glib_is_class_struct_for);
+					if (vmethods == null) {
+						vmethods = new ArrayList<Method> ();
+						class_vmethods.set (glib_is_class_struct_for, vmethods);
+					}
+					vmethods.add (parse_method ("callback"));
+				} else if (glib_is_iface_struct_for != null) {
+					ArrayList<Method> vmethods = iface_vmethods.get (glib_is_iface_struct_for);
+					if (vmethods == null) {
+						vmethods = new ArrayList<Method> ();
+						iface_vmethods.set (glib_is_iface_struct_for, vmethods);
+					}
+					vmethods.add (parse_method ("callback"));
+				} else {
+					parse_callback ();
+				}
 			} else if (reader.name == "constructor") {
 				parse_constructor ();
 			} else if (reader.name == "method") {
 				st.add_method (parse_method ("method"));
+			} else if (reader.name == "function") {
+				st.add_method (parse_method ("function"));
 			} else {
 				// error
 				Report.error (get_current_src (), "unknown child element `%s' in `record'".printf (reader.name));
@@ -579,6 +635,27 @@
 		end_element ("class");
 		return cl;
 	}
+	
+	void postprocess_class_vmethods (Namespace ns) {
+		foreach (string class_name in class_vmethods.get_keys ()) {
+			Class cl = (Class) ns.scope.lookup (class_name);
+			ArrayList<Method> vmethods = class_vmethods.get (class_name);
+			foreach (Method m in vmethods) {
+				var symbol = cl.scope.lookup (m.name);
+				if (symbol == null) {
+					continue;
+				} else if (symbol is Method)  {
+					var meth = (Method) symbol;
+					meth.is_virtual = true;
+				} else if (symbol is Signal) {
+					var sig = (Signal) symbol;
+					sig.is_virtual = true;
+				} else {
+					Report.error (get_current_src (), "unknown member type `%s' in `%s'".printf (m.name, cl.name));
+				}
+			}
+		}
+	}
 
 	Interface parse_interface () {
 		start_element ("interface");
@@ -605,6 +682,8 @@
 				iface.add_property (parse_property ());
 			} else if (reader.name == "callback") {
 				vmethods.add (parse_method ("callback"));
+			} else if (reader.name == "function") {
+				methods.add (parse_method ("function"));
 			} else if (reader.name == "method") {
 				methods.add (parse_method ("method"));
 			} else if (reader.name == "glib:signal") {
@@ -647,6 +726,27 @@
 		end_element ("interface");
 		return iface;
 	}
+	
+	void postprocess_iface_vmethods (Namespace ns) {
+		foreach (string iface_name in iface_vmethods.get_keys ()) {
+			Interface iface = (Interface) ns.scope.lookup (iface_name);
+			ArrayList<Method> vmethods = iface_vmethods.get (iface_name);
+			foreach (Method m in vmethods) {
+				var symbol = iface.scope.lookup (m.name);
+				if (symbol == null) {
+					continue;
+				} else if (symbol is Method)  {
+					var meth = (Method) symbol;
+					meth.is_abstract = true;
+				} else if (symbol is Signal) {
+					var sig = (Signal) symbol;
+					sig.is_virtual = true;
+				} else {
+					Report.error (get_current_src (), "unknown member type `%s' in `%s'".printf (m.name, iface.name));
+				}
+			}
+		}
+	}
 
 	Field parse_field () {
 		start_element ("field");
@@ -664,7 +764,7 @@
 		string name = string.joinv ("_", reader.get_attribute ("name").split ("-"));
 		string readable = reader.get_attribute ("readable");
 		string writable = reader.get_attribute ("writable");
-		string construct_ = reader.get_attribute ("construct");
+		string construct_only = reader.get_attribute ("construct-only");
 		next ();
 		var type = parse_type ();
 		var prop = new Property (name, type, null, null, get_current_src ());
@@ -672,8 +772,8 @@
 		if (readable != "0") {
 			prop.get_accessor = new PropertyAccessor (true, false, false, prop.property_type.copy (), null, null);
 		}
-		if (writable == "1" || construct_ == "1") {
-			prop.set_accessor = new PropertyAccessor (false, (writable == "1"), (construct_ == "1"), prop.property_type.copy (), null, null);
+		if (writable == "1" || construct_only == "1") {
+			prop.set_accessor = new PropertyAccessor (false, (construct_only != "1") && (writable == "1"), (construct_only == "1"), prop.property_type.copy (), null, null);
 		}
 		end_element ("property");
 		return prop;
Index: vala/valacodewriter.vala
===================================================================
--- vala/valacodewriter.vala	(révision 2450)
+++ vala/valacodewriter.vala	(copie de travail)
@@ -663,7 +663,7 @@
 		}
 
 		if (is_weak (f.field_type)) {
-			write_string ("weak ");
+			write_string ("unowned ");
 		}
 
 		write_type (f.field_type);
Index: vala/valanamespace.vala
===================================================================
--- vala/valanamespace.vala	(révision 2450)
+++ vala/valanamespace.vala	(copie de travail)
@@ -512,6 +512,15 @@
 		cheader_filenames.add (cheader_filename);
 	}
 	
+	/**
+	 * Adds a C header filename of this namespace.
+	 *
+	 * @param cheader_filename header filename
+	 */
+	public void add_cheader_filename (string cheader_filename) {
+		cheader_filenames.add (cheader_filename);
+	}
+	
 	private void process_ccode_attribute (Attribute a) {
 		if (a.has_argument ("cprefix")) {
 			foreach (string name in a.get_string ("cprefix").split (","))
