diff -aur gtk-doc-1.11/gtkdoc-common.pl.in gtk-doc-patch/gtkdoc-common.pl.in
--- gtk-doc-1.11/gtkdoc-common.pl.in	2008-09-10 18:17:57.000000000 +0200
+++ gtk-doc-patch/gtkdoc-common.pl.in	2009-10-10 00:56:51.000000000 +0200
@@ -97,7 +97,7 @@
     my ($declaration, $is_object, $output_function_params, $typefunc, $namefunc) = @_;
 
     # For forward struct declarations just return an empty array.
-    if ($declaration =~ m/struct\s+\S+\s*;/msg) {
+    if ($declaration =~ m/(?:struct|union)\s+\S+\s*;/msg) {
       return ();
     }
 
@@ -105,7 +105,7 @@
 
     # For objects, assume private
     if ($is_object) {
-	$declaration =~ s!(struct\s+\w*\s*\{)
+	$declaration =~ s!((?:struct|union)\s+\w*\s*\{)
 	                  .*?
 			  (?:/\*\s*<\s*public\s*>\s*\*/|(?=\}))!$1!msgx;
     }
@@ -125,7 +125,7 @@
     }
 
     # Prime match after "struct {" declaration
-    if (!scalar($declaration =~ m/struct\s+\w*\s*\{/msg)) {
+    if (!scalar($declaration =~ m/(?:struct|union)\s+\w*\s*\{/msg)) {
 	die "Structure declaration '$declaration' does not begin with struct [NAME] {\n";
     }
 
diff -aur gtk-doc-1.11/gtkdoc-mkdb.in gtk-doc-patch/gtkdoc-mkdb.in
--- gtk-doc-1.11/gtkdoc-mkdb.in	2008-11-06 20:01:42.000000000 +0100
+++ gtk-doc-patch/gtkdoc-mkdb.in	2009-10-10 01:07:18.000000000 +0200
@@ -1435,7 +1435,7 @@
     my $id = &CreateValidSGMLID ($symbol);
     my $condition = &MakeConditionDescription ($symbol);
     my $synop = &MakeReturnField("union") . "<link linkend=\"$id\">$symbol</link>;\n";
-    my $desc = "<refsect2 id=\"$id\" role=\"union\"$condition>\n<title>union $symbol</title>\n";
+    my $desc = "<refsect2 id=\"$id\" role=\"union\"$condition>\n<title>$symbol</title>\n";
 
     $desc .= MakeIndexterms($symbol, $id);
 
diff -aur gtk-doc-1.11/gtkdoc-scan.in gtk-doc-patch/gtkdoc-scan.in
--- gtk-doc-1.11/gtkdoc-scan.in	2008-10-04 18:52:57.000000000 +0200
+++ gtk-doc-patch/gtkdoc-scan.in	2009-10-10 01:04:18.000000000 +0200
@@ -385,39 +385,41 @@
 		$in_declaration = "enum";
 
 
-	    # STRUCTS
+	    # STRUCTS AND UNIONS
 
-	    } elsif (m/^\s*typedef\s+struct\s+_(\w+)\s+\1\s*;/) {
+	    } elsif (m/^\s*typedef\s+(struct|union)\s+_(\w+)\s+\2\s*;/) {
 		# We've found a 'typedef struct _<name> <name>;'
 		# This could be an opaque data structure, so we output an
 		# empty declaration. If the structure is actually found that
 		# will override this.
-		#print "DEBUG: struct typedef: $1\n";
-		&AddSymbolToList (\$list, $1);
-		print DECL "<STRUCT>\n<NAME>$1</NAME>\n$deprecated</STRUCT>\n";
+		#print "DEBUG: struct typedef: $2\n";
+		my $structsym = uc $1;
+		&AddSymbolToList (\$list, $2);
+		print DECL "<$structsym>\n<NAME>$2</NAME>\n$deprecated</$structsym>\n";
 
-	    } elsif (m/^\s*struct\s+_(\w+)\s*;/) {
+	    } elsif (m/^\s*(?:struct|union)\s+_(\w+)\s*;/) {
 		# Skip private structs.
                 #print "DEBUG: private struct\n";
 
-	    } elsif (m/^\s*struct\s+(\w+)\s*;/) {
+	    } elsif (m/^\s*(struct|union)\s+(\w+)\s*;/) {
 	        # Do a similar thing for normal structs as for typedefs above.
 	        # But we output the declaration as well in this case, so we
 	        # can differentiate it from a typedef.
-	        #print "DEBUG: struct: $1\n";
-		&AddSymbolToList (\$list, $1);
-		print DECL "<STRUCT>\n<NAME>$1</NAME>\n$_$deprecated</STRUCT>\n";
+	        #print "DEBUG: struct: $2\n";
+		my $structsym = uc $1;
+		&AddSymbolToList (\$list, $2);
+		print DECL "<$structsym>\n<NAME>$2</NAME>\n$_$deprecated</$structsym>\n";
 
-	    } elsif (m/^\s*typedef\s+struct\s*\w*\s*{/) {
+	    } elsif (m/^\s*typedef\s+(struct|union)\s*\w*\s*{/) {
 		$symbol = "";
  		$decl = $_;
 		$level = 0;
-		$in_declaration = "struct";
+		$in_declaration = $1;
                 #print "DEBUG: struct\n";
 
 	    # OTHER TYPEDEFS
 
-	    } elsif (m/^\s*typedef\s+struct\s+\w+[\s\*]+(\w+)\s*;/) {
+	    } elsif (m/^\s*typedef\s+(?:struct|union)\s+\w+[\s\*]+(\w+)\s*;/) {
 		#print "DEBUG: Found struct* typedef: $_";
 		&AddSymbolToList (\$list, $1);
 		print DECL "<TYPEDEF>\n<NAME>$1</NAME>\n$deprecated$_</TYPEDEF>\n";
@@ -446,15 +448,15 @@
 
 	    # We assume that functions which start with '_' are private, so
 	    # we skip them.
-            #                                                                        $1                                                                                                                                 $2
-	    } elsif (m/^\s*(?:\b(?:extern|G_INLINE_FUNC|${IGNORE_DECORATORS})\b\s*)*((?:const\s+|G_CONST_RETURN\s+|unsigned\s+|struct\s+|enum\s+)*\w+(?:\**\s+\**(?:const|G_CONST_RETURN))?(?:\s+|\s*\*+))\s*\(\s*\*+\s*([A-Za-z]\w*)\s*\)\s*\(/o) {
+            #                                                                        $1                                                                                                                                          $2
+	    } elsif (m/^\s*(?:\b(?:extern|G_INLINE_FUNC|${IGNORE_DECORATORS})\b\s*)*((?:const\s+|G_CONST_RETURN\s+|unsigned\s+|struct\s+|union\s+|enum\s+)*\w+(?:\**\s+\**(?:const|G_CONST_RETURN))?(?:\s+|\s*\*+))\s*\(\s*\*+\s*([A-Za-z]\w*)\s*\)\s*\(/o) {
 		$ret_type = $1;
 		$symbol = $2;
 		$decl = $';
 		#print "DEBUG: FunctionPointer: $symbol, Returns: $ret_type\n";
 		$in_declaration = "function";
 
-	    } elsif (m/^\s*(?:\b(?:extern|G_INLINE_FUNC|${IGNORE_DECORATORS})\b\s*)*((?:const\s+|G_CONST_RETURN\s+|unsigned\s+|struct\s+|enum\s+)*\w+(?:\**\s+\**(?:const|G_CONST_RETURN))?(?:\s+|\s*\*+))\s*([A-Za-z]\w*)\s*\(/o) {
+	    } elsif (m/^\s*(?:\b(?:extern|G_INLINE_FUNC|${IGNORE_DECORATORS})\b\s*)*((?:const\s+|G_CONST_RETURN\s+|unsigned\s+|struct\s+|union\s+|enum\s+)*\w+(?:\**\s+\**(?:const|G_CONST_RETURN))?(?:\s+|\s*\*+))\s*([A-Za-z]\w*)\s*\(/o) {
 		$ret_type = $1;
 		$symbol = $2;
 		$decl = $';
@@ -471,7 +473,7 @@
 
 		if ($previous_line !~ m/^\s*G_INLINE_FUNC/
 		    && $previous_line !~ m/^\s*static\s+/) {
-		    if ($previous_line =~ m/^\s*(?:\b(?:extern|${IGNORE_DECORATORS})\b\s*)*((?:const\s+|G_CONST_RETURN\s+|unsigned\s+|struct\s+|enum\s+)?\w+)((?:\s*(?:\*+|\bconst\b|\bG_CONST_RETURN\b))*)\s*$/o) {
+		    if ($previous_line =~ m/^\s*(?:\b(?:extern|${IGNORE_DECORATORS})\b\s*)*((?:const\s+|G_CONST_RETURN\s+|unsigned\s+|struct\s+|union\s+|enum\s+)?\w+)((?:\s*(?:\*+|\bconst\b|\bG_CONST_RETURN\b))*)\s*$/o) {
 			$ret_type = $1;
 			if (defined ($2)) { $ret_type .= " $2"; }
 			#print "DEBUG: Function: $symbol, Returns: $ret_type\n";
@@ -490,7 +492,7 @@
 		    $in_declaration = "function";
 
 		} elsif ($previous_line =~ m/^\s*\w+\s*$/
-			 && $pre_previous_line =~ m/^\s*(?:\b(?:extern|G_INLINE_FUNC|${IGNORE_DECORATORS})\b\s*)*((?:const\s+|G_CONST_RETURN\s+|unsigned\s+|struct\s+|enum\s+)*\w+(?:\**\s+\**(?:const|G_CONST_RETURN))?(?:\s+|\s*\*+))\s*$/o) {
+			 && $pre_previous_line =~ m/^\s*(?:\b(?:extern|G_INLINE_FUNC|${IGNORE_DECORATORS})\b\s*)*((?:const\s+|G_CONST_RETURN\s+|unsigned\s+|struct\s+|union\s+|enum\s+)*\w+(?:\**\s+\**(?:const|G_CONST_RETURN))?(?:\s+|\s*\*+))\s*$/o) {
 			$ret_type = $1;
 			$ret_type =~ s/\s*\n//;
 			$in_declaration = "function";
@@ -524,11 +526,15 @@
 
 	    # UNIONS
 
-	    } elsif (s/^\s*union\s+_(\w+)/union $1/) {
+	    } elsif (m/^\s*union\s+_(\w+)\s*\*/) {
+		# Skip 'union _<union_name> *' (see above)
+	    } elsif (m/^\s*union\s+_(\w+)/) {
+		# We assume that 'union _<union_name>' is really union <union_name>.
 		$symbol = $1;
 		$decl = $_;
+		$level = 0;
 		$in_declaration = "union";
-                #print "DEBUG: Union: $symbol\n";
+                #print "DEBUG: Union(_): $symbol\n";
 	    }
 
 	} else {
@@ -587,7 +593,7 @@
 
 	# We try to handle nested stucts/unions, but unmatched brackets in
 	# comments will cause problems.
-	if ($in_declaration eq 'struct') {
+	if ($in_declaration eq 'struct' or $in_declaration eq 'union') {
 	    if ($level <= 1 && $decl =~ m/\}\s*(\w*);\s*$/) {
 		if ($symbol eq "") {
 		    $symbol = $1;
@@ -600,8 +606,9 @@
 		}
 		#print "Store struct: $symbol\n";
 		&AddSymbolToList (\$list, $symbol);
-
-		print DECL "<STRUCT>\n<NAME>$symbol</NAME>\n$deprecated$decl</STRUCT>\n";
+		
+		my $structsym = uc $in_declaration;
+		print DECL "<$structsym>\n<NAME>$symbol</NAME>\n$deprecated$decl</$structsym>\n";
 		$in_declaration = "";
 	    } else {
 		# We use tr to count the brackets in the line, and adjust
@@ -612,14 +619,6 @@
 	    }
 	}
 
-	if ($in_declaration eq 'union') {
-	    if ($decl =~ m/\}\s*;\s*$/) {
-		&AddSymbolToList (\$list, $symbol);
-		print DECL "<UNION>\n<NAME>$symbol</NAME>\n$deprecated$decl</UNION>\n";
-		$in_declaration = "";
-	    }
-	}
-
 	$pre_previous_line = $previous_line;
 	$previous_line = $_;
     }
