aboutsummaryrefslogtreecommitdiffstats
path: root/tools/process-x11-xcb.pl
diff options
context:
space:
mode:
authorJeff Morriss <jeff.morriss.ws@gmail.com>2013-11-24 01:32:20 +0000
committerJeff Morriss <jeff.morriss.ws@gmail.com>2013-11-24 01:32:20 +0000
commita434d9647ed9b724630552488048af4a31c97618 (patch)
tree73ac49c95f0b0ff76f5c3d1fc124d9cd404bbaff /tools/process-x11-xcb.pl
parent1db1b8e2bb6cd4ae1731205738eef9f572a03ead (diff)
Some patches from Peter Harris to make it possible to build the X11 dissector
again (and some various other improvements): Rebuild the dissector with the latest xcbproto and mesa. Subject: [PATCH 01/11] X11 dissector: Support CARD64 and INT64 types These types are used by the new Present extension. Subject: [PATCH 02/11] X11 dissector: Un-blacklist a few structures The xinput structs are used by the latest xcb/proto, and the xkb struct has been removed. Subject: [PATCH 03/11] X11 dissector: Add hack for xinput:ChangeProperty xinput:ChangeProperty should use switch/case, but only switch/bitcase is supported at the moment. Add (hopefully temporary) hack. Subject: [PATCH 04/11] X11 dissector: Use namespace for types In particular, the name of the xsync struct 'INT64' collides with a basic type of the same name. Subject: [PATCH 05/11] X11 dissector: Add support for "Generic" events All new extensions are using the new "Generic" events instead of traditional events, because there aren't enough traditional event numbers. Denoted by <event xge="true"> in xcb/proto. Subject: [PATCH 06/11] X11 dissector: Blacklist unused structures Subject: [PATCH 07/11] X11 dissector: Support multiple enumref in a bitcase XKB is weird. Subject: [PATCH 08/11] X11 dissector: Support sumof Subject: [PATCH 09/11] X11 dissector: Stop generating unused-but-set variables (This patch also reverts r53298/r53299.) svn path=/trunk/; revision=53531
Diffstat (limited to 'tools/process-x11-xcb.pl')
-rwxr-xr-xtools/process-x11-xcb.pl503
1 files changed, 371 insertions, 132 deletions
diff --git a/tools/process-x11-xcb.pl b/tools/process-x11-xcb.pl
index 38ac60a8d1..8b409f0103 100755
--- a/tools/process-x11-xcb.pl
+++ b/tools/process-x11-xcb.pl
@@ -51,9 +51,11 @@ my %basictype = (
CARD8 => { size => 1, encoding => 'byte_order', type => 'FT_UINT8', base => 'BASE_HEX_DEC', get => 'VALUE8', list => 'listOfByte', },
CARD16 => { size => 2, encoding => 'byte_order', type => 'FT_UINT16', base => 'BASE_HEX_DEC', get => 'VALUE16', list => 'listOfCard16', },
CARD32 => { size => 4, encoding => 'byte_order', type => 'FT_UINT32', base => 'BASE_HEX_DEC', get => 'VALUE32', list => 'listOfCard32', },
+ CARD64 => { size => 8, encoding => 'byte_order', type => 'FT_UINT64', base => 'BASE_HEX_DEC', get => 'VALUE64', list => 'listOfCard64', },
INT8 => { size => 1, encoding => 'byte_order', type => 'FT_INT8', base => 'BASE_DEC', get => 'VALUE8', list => 'listOfByte', },
INT16 => { size => 2, encoding => 'byte_order', type => 'FT_INT16', base => 'BASE_DEC', get => 'VALUE16', list => 'listOfInt16', },
INT32 => { size => 4, encoding => 'byte_order', type => 'FT_INT32', base => 'BASE_DEC', get => 'VALUE32', list => 'listOfInt32', },
+ INT64 => { size => 8, encoding => 'byte_order', type => 'FT_INT64', base => 'BASE_DEC', get => 'VALUE64', list => 'listOfInt64', },
float => { size => 4, encoding => 'byte_order', type => 'FT_FLOAT', base => 'BASE_NONE', get => 'FLOAT', list => 'listOfFloat', },
double => { size => 8, encoding => 'byte_order', type => 'FT_DOUBLE', base => 'BASE_NONE', get => 'DOUBLE', list => 'listOfDouble', },
BOOL => { size => 1, encoding => 'byte_order', type => 'FT_BOOLEAN',base => 'BASE_NONE', get => 'VALUE8', list => 'listOfByte', },
@@ -67,74 +69,88 @@ my %struct = # Not reset; contains structures already defined.
# extension (to avoid generating useless code).
(
# structures defined by xproto, but not used by any extension
- CHAR2B => 1,
- ARC => 1,
- FORMAT => 1,
- VISUALTYPE => 1,
- DEPTH => 1,
- SCREEN => 1,
- SetupRequest => 1,
- SetupFailed => 1,
- SetupAuthenticate => 1,
- Setup => 1,
- TIMECOORD => 1,
- FONTPROP => 1,
- CHARINFO => 1,
- SEGMENT => 1,
- COLORITEM => 1,
- RGB => 1,
- HOST => 1,
+ 'xproto:CHAR2B' => 1,
+ 'xproto:ARC' => 1,
+ 'xproto:FORMAT' => 1,
+ 'xproto:VISUALTYPE' => 1,
+ 'xproto:DEPTH' => 1,
+ 'xproto:SCREEN' => 1,
+ 'xproto:SetupRequest' => 1,
+ 'xproto:SetupFailed' => 1,
+ 'xproto:SetupAuthenticate' => 1,
+ 'xproto:Setup' => 1,
+ 'xproto:TIMECOORD' => 1,
+ 'xproto:FONTPROP' => 1,
+ 'xproto:CHARINFO' => 1,
+ 'xproto:SEGMENT' => 1,
+ 'xproto:COLORITEM' => 1,
+ 'xproto:RGB' => 1,
+ 'xproto:HOST' => 1,
+ 'xproto:POINT' => 1,
# structures defined by xinput, but never used (except by each other)(bug in xcb?)
- InputInfo => 1,
- KeyInfo => 1,
- ButtonInfo => 1,
- AxisInfo => 1,
- ValuatorInfo => 1,
- DeviceTimeCoord => 1,
- FeedbackState => 1,
- KbdFeedbackState => 1,
- PtrFeedbackState => 1,
- IntegerFeedbackState => 1,
- StringFeedbackState => 1,
- BellFeedbackState => 1,
- LedFeedbackState => 1,
- FeedbackCtl => 1,
- KbdFeedbackCtl => 1,
- PtrFeedbackCtl => 1,
- IntegerFeedbackCtl => 1,
- StringFeedbackCtl => 1,
- BellFeedbackCtl => 1,
- LedFeedbackCtl => 1,
- InputState => 1,
- KeyState => 1,
- ButtonState => 1,
- ValuatorState => 1,
- DeviceState => 1,
- DeviceResolutionState => 1,
- DeviceAbsCalibState => 1,
- DeviceAbsAreaState => 1,
- DeviceCoreState => 1,
- DeviceEnableState => 1,
- DeviceCtl => 1,
- DeviceResolutionCtl => 1,
- DeviceAbsCalibCtl => 1,
- DeviceAbsAreaCtrl => 1,
- DeviceCoreCtrl => 1,
- DeviceEnableCtrl => 1,
+ 'xinput:InputInfo' => 1,
+ 'xinput:KeyInfo' => 1,
+ 'xinput:ButtonInfo' => 1,
+ 'xinput:AxisInfo' => 1,
+ 'xinput:ValuatorInfo' => 1,
+ 'xinput:DeviceTimeCoord' => 1,
+ 'xinput:KbdFeedbackState' => 1,
+ 'xinput:PtrFeedbackState' => 1,
+ 'xinput:IntegerFeedbackState' => 1,
+ 'xinput:StringFeedbackState' => 1,
+ 'xinput:BellFeedbackState' => 1,
+ 'xinput:LedFeedbackState' => 1,
+ 'xinput:KbdFeedbackCtl' => 1,
+ 'xinput:PtrFeedbackCtl' => 1,
+ 'xinput:IntegerFeedbackCtl' => 1,
+ 'xinput:StringFeedbackCtl' => 1,
+ 'xinput:BellFeedbackCtl' => 1,
+ 'xinput:LedFeedbackCtl' => 1,
+ 'xinput:KeyState' => 1,
+ 'xinput:ButtonState' => 1,
+ 'xinput:ValuatorState' => 1,
+ 'xinput:DeviceResolutionState' => 1,
+ 'xinput:DeviceAbsCalibState' => 1,
+ 'xinput:DeviceAbsAreaState' => 1,
+ 'xinput:DeviceCoreState' => 1,
+ 'xinput:DeviceEnableState' => 1,
+ 'xinput:DeviceResolutionCtl' => 1,
+ 'xinput:DeviceAbsCalibCtl' => 1,
+ 'xinput:DeviceAbsAreaCtrl' => 1,
+ 'xinput:DeviceCoreCtrl' => 1,
+ 'xinput:DeviceEnableCtrl' => 1,
+ 'xinput:DeviceName' => 1,
+ 'xinput:AddMaster' => 1,
+ 'xinput:RemoveMaster' => 1,
+ 'xinput:AttachSlave' => 1,
+ 'xinput:DetachSlave' => 1,
+ 'xinput:ButtonClass' => 1,
+ 'xinput:KeyClass' => 1,
+ 'xinput:ScrollClass' => 1,
+ 'xinput:TouchClass' => 1,
+ 'xinput:ValuatorClass' => 1,
# structures defined by xv, but never used (bug in xcb?)
- Image => 1,
-
- # structures defined by xkb, but never used (bug in xcb?)
- CountedString8 => 1,
+ 'xv:Image' => 1,
+
+ # structures defined by xkb, but never used (except by each other)(bug in xcb?)
+ 'xkb:Key' => 1,
+ 'xkb:Outline' => 1,
+ 'xkb:Overlay' => 1,
+ 'xkb:OverlayKey' => 1,
+ 'xkb:OverlayRow' => 1,
+ 'xkb:Row' => 1,
+ 'xkb:Shape' => 1,
);
my %enum; # Not reset; contains enums already defined.
my %enum_name;
+my %type_name;
my $header;
my $extname;
my @incname;
my %request;
+my %genericevent;
my %event;
my %reply;
@@ -376,6 +392,10 @@ eot
if (defined($count) && !defined($variable_param)) {
print $impl " $list(tvb, offsetp, t, $regname, $count, byte_order);\n";
} else {
+ if (defined($count)) {
+ # Silence compiler until we support variable_param
+ say $impl " $count = $count; /* Avoid unreferenced warning */";
+ }
print $impl " $list(tvb, offsetp, t, $regname, (length - $length) / $gltype{$type}{'size'}, byte_order);\n";
}
}
@@ -444,6 +464,39 @@ sub get_unop($;$) {
}
}
+sub qualname {
+ my $name = shift;
+ $name = $incname[0].':'.$name unless $name =~ /:/;
+ return $name
+}
+
+sub get_simple_info {
+ my $name = shift;
+ my $info = $basictype{$name};
+ return $info if (defined $info);
+ $info = $simpletype{$name};
+ return $info if (defined $info);
+ if (defined($type_name{$name})) {
+ return $simpletype{$type_name{$name}};
+ }
+ return undef
+}
+
+sub get_struct_info {
+ my $name = shift;
+ my $info = $struct{$name};
+ return $info if (defined $info);
+ if (defined($type_name{$name})) {
+ return $struct{$type_name{$name}};
+ }
+ return undef
+}
+
+sub getinfo {
+ my $name = shift;
+ return get_simple_info($name) // get_struct_info($name);
+}
+
sub dump_enum_values($)
{
my $e = shift;
@@ -467,13 +520,56 @@ sub dump_enum_values($)
return $enumname;
}
-sub register_element($$$;$);
+# Find all references, so we can declare only the minimum necessary
+sub reference_elements($$);
+
+sub reference_elements($$)
+{
+ my $e = shift;
+ my $refref = shift;
+
+ given ($e->name()) {
+ when ('switch') {
+ my $lentype = $e->first_child();
+ if (defined $lentype) {
+ given ($lentype->name()) {
+ when ('fieldref') { $refref->{field}{$lentype->text()} = 1; }
+ when ('op') { get_op($lentype, $refref->{field}); }
+ }
+ }
+
+ my @elements = $e->children('bitcase');
+ for my $case (@elements) {
+ my @sub_elements = $case->children(qr/list|switch/);
+
+ foreach my $sub_e (@sub_elements) {
+ reference_elements($sub_e, $refref);
+ }
+ }
+ }
+ when ('list') {
+ my $lentype = $e->first_child();
+ if (defined $lentype) {
+ given ($lentype->name()) {
+ when ('fieldref') { $refref->{field}{$lentype->text()} = 1; }
+ when ('op') { get_op($lentype, $refref->{field}); }
+ when (['unop','popcount']) { get_unop($lentype, $refref->{field}); }
+ when ('sumof') { $refref->{sumof}{$lentype->att('ref')} = 1; }
+ }
+ } else {
+ $refref->{field}{'length'} = 1;
+ $refref->{'length'} = 1;
+ }
+ }
+ }
+}
-sub register_element($$$;$)
+sub register_element($$$$;$)
{
my $e = shift;
my $varpat = shift;
my $humanpat = shift;
+ my $refref = shift;
my $indent = shift // ' ' x 4;
given ($e->name()) {
@@ -485,12 +581,11 @@ sub register_element($$$;$)
my $fieldname = $e->att('name');
my $type = $e->att('type') or die ("Field $fieldname does not have a valid type\n");
- $type =~ s/^.*://;
my $regname = 'hf_x11_'.sprintf ($varpat, $fieldname);
my $humanname = 'x11.'.sprintf ($humanpat, $fieldname);
- my $info = $basictype{$type} // $simpletype{$type} // $struct{$type};
+ my $info = getinfo($type);
my $ft = $info->{'type'} // 'FT_NONE';
my $base = $info->{'base'} // 'BASE_NONE';
my $vals = 'NULL';
@@ -536,13 +631,19 @@ sub register_element($$$;$)
}
print $reg "{ &$regname, { \"$fieldname\", \"$humanname\", $ft, $base, $vals, 0, NULL, HFILL }},\n";
+ if ($refref->{sumof}{$fieldname}) {
+ print $impl $indent."int sumof_$fieldname = 0;\n";
+ }
+
if ($e->name() eq 'field') {
- if ($basictype{$type} or $simpletype{$type}) {
+ if ($refref->{field}{$fieldname} and get_simple_info($type)) {
# Pre-declare variable
if ($ft eq 'FT_FLOAT') {
print $impl $indent."gfloat f_$fieldname;\n";
} elsif ($ft eq 'FT_DOUBLE') {
print $impl $indent."gdouble f_$fieldname;\n";
+ } elsif ($ft eq 'FT_INT64' or $ft eq 'FT_UINT64') {
+ print $impl $indent."gint64 f_$fieldname;\n";
} else {
print $impl $indent."int f_$fieldname;\n";
}
@@ -550,14 +651,15 @@ sub register_element($$$;$)
}
}
-sub dissect_element($$$$;$$);
+sub dissect_element($$$$$;$$);
-sub dissect_element($$$$;$$)
+sub dissect_element($$$$$;$$)
{
my $e = shift;
my $varpat = shift;
my $humanpat = shift;
my $length = shift;
+ my $refref = shift;
my $adjustlength = shift;
my $indent = shift // ' ' x 4;
@@ -571,19 +673,24 @@ sub dissect_element($$$$;$$)
my $fieldname = $e->att('name');
my $regname = 'hf_x11_'.sprintf ($varpat, $fieldname);
my $type = $e->att('type');
- $type =~ s/^.*://;
- if ($basictype{$type} or $simpletype{$type}) {
- my $info = $basictype{$type} // $simpletype{$type};
+ if (get_simple_info($type)) {
+ my $info = get_simple_info($type);
my $size = $info->{'size'};
my $encoding = $info->{'encoding'};
my $get = $info->{'get'};
if ($e->att('enum') // $e->att('altenum')) {
my $fieldsize = $size * 8;
- say $impl $indent."f_$fieldname = field$fieldsize(tvb, offsetp, t, $regname, byte_order);";
+ print $impl $indent;
+ if ($refref->{field}{$fieldname}) {
+ print $impl "f_$fieldname = ";
+ }
+ say $impl "field$fieldsize(tvb, offsetp, t, $regname, byte_order);";
} elsif ($e->att('mask')) {
- say $impl $indent."f_$fieldname = $get(tvb, *offsetp);";
+ if ($refref->{field}{$fieldname}) {
+ say $impl $indent."f_$fieldname = $get(tvb, *offsetp);";
+ }
say $impl $indent."{";
say $impl $indent." proto_item *ti = proto_tree_add_item(t, $regname, tvb, *offsetp, $size, $encoding);";
say $impl $indent." proto_tree *bitmask_tree = proto_item_add_subtree(ti, ett_x11_rectangle);";
@@ -600,14 +707,16 @@ sub dissect_element($$$$;$$)
say $impl $indent."}";
say $impl $indent."*offsetp += $size;";
} else {
- print $impl $indent."f_$fieldname = $get(tvb, *offsetp);\n";
+ if ($refref->{field}{$fieldname}) {
+ say $impl $indent."f_$fieldname = $get(tvb, *offsetp);";
+ }
print $impl $indent."proto_tree_add_item(t, $regname, tvb, *offsetp, $size, $encoding);\n";
print $impl $indent."*offsetp += $size;\n";
}
$length += $size;
- } elsif ($struct{$type}) {
+ } elsif (get_struct_info($type)) {
# TODO: variable-lengths (when $info->{'size'} == 0 )
- my $info = $struct{$type};
+ my $info = get_struct_info($type);
$length += $info->{'size'};
print $impl $indent."struct_$info->{'name'}(tvb, offsetp, t, byte_order, 1);\n";
} else {
@@ -618,9 +727,8 @@ sub dissect_element($$$$;$$)
my $fieldname = $e->att('name');
my $regname = 'hf_x11_'.sprintf ($varpat, $fieldname);
my $type = $e->att('type');
- $type =~ s/^.*://;
- my $info = $basictype{$type} // $simpletype{$type} // $struct{$type};
+ my $info = getinfo($type);
my $lencalc = "(length - $length) / $info->{'size'}";
my $lentype = $e->first_child();
if (defined $lentype) {
@@ -629,14 +737,27 @@ sub dissect_element($$$$;$$)
when ('fieldref') { $lencalc = 'f_'.$lentype->text(); }
when ('op') { $lencalc = get_op($lentype); }
when (['unop','popcount']) { $lencalc = get_unop($lentype); }
+ when ('sumof') { $lencalc = 'sumof_'.$lentype->att('ref'); }
}
}
- if ($basictype{$type} or $simpletype{$type}) {
+ if (get_simple_info($type)) {
my $list = $info->{'list'};
- $regname .= ", $regname".'_item' if ($info->{'size'} > 1);
+ my $size = $info->{'size'};
+ $regname .= ", $regname".'_item' if ($size > 1);
+
+ if ($refref->{sumof}{$fieldname}) {
+ my $get = $info->{'get'};
+ say $impl $indent."{";
+ say $impl $indent." int i;";
+ say $impl $indent." for (i = 0; i < $lencalc; i++) {";
+ say $impl $indent." sumof_$fieldname += $get(tvb, *offsetp + i * $size);";
+ say $impl $indent." }";
+ say $impl $indent."}";
+ }
+
print $impl $indent."$list(tvb, offsetp, t, $regname, $lencalc, byte_order);\n";
- } elsif ($struct{$type}) {
+ } elsif (get_struct_info($type)) {
print $impl $indent."struct_$info->{'name'}(tvb, offsetp, t, byte_order, $lencalc);\n";
} else {
die ("Unrecognized type: $type\n");
@@ -654,29 +775,44 @@ sub dissect_element($$$$;$$)
my $switchon = get_ref($switchtype, {});
my @elements = $e->children('bitcase');
for my $case (@elements) {
- my $ref = $case->first_child('enumref');
- my $enum_ref = $ref->att('ref');
- my $field = $ref->text();
- my $bit = $enum{$enum_name{$enum_ref}}{rbit}{$field};
- if (! defined($bit)) {
- for my $foo (keys %{$enum{$enum_name{$enum_ref}}{rbit}}) { say "'$foo'"; }
- die ("Field '$field' not found in '$enum_ref'");
- }
- $bit = "(1 << $bit)";
- say $impl $indent."if (($switchon & $bit) != 0) {";
+ my @refs = $case->children('enumref');
+ my @bits;
+ my $fieldname;
+ foreach my $ref (@refs) {
+ my $enum_ref = $ref->att('ref');
+ my $field = $ref->text();
+ $fieldname //= $field; # Use first named field
+ my $bit = $enum{$enum_name{$enum_ref}}{rbit}{$field};
+ if (! defined($bit)) {
+ for my $foo (keys %{$enum{$enum_name{$enum_ref}}{rbit}}) { say "'$foo'"; }
+ die ("Field '$field' not found in '$enum_ref'");
+ }
+ push @bits , "(1 << $bit)";
+ }
+ if (scalar @bits == 1) {
+ say $impl $indent."if (($switchon & $bits[0]) != 0) {";
+ } else {
+ my $list = join '|', @bits;
+ say $impl $indent."if (($switchon & ($list)) != 0) {";
+ }
my $vp = $varpat;
my $hp = $humanpat;
- $vp =~ s/%s/${field}_%s/;
- $hp =~ s/%s/${field}.%s/;
+ $vp =~ s/%s/${fieldname}_%s/;
+ $hp =~ s/%s/${fieldname}.%s/;
my @sub_elements = $case->children(qr/pad|field|list|switch/);
+
+ my $subref = { field => {}, sumof => {} };
+ foreach my $sub_e (@sub_elements) {
+ reference_elements($sub_e, $subref);
+ }
foreach my $sub_e (@sub_elements) {
- register_element($sub_e, $vp, $hp, $indent . ' ');
+ register_element($sub_e, $vp, $hp, $subref, $indent . ' ');
}
foreach my $sub_e (@sub_elements) {
- $length = dissect_element($sub_e, $vp, $hp, $length, $adjustlength, $indent . ' ');
+ $length = dissect_element($sub_e, $vp, $hp, $length, $subref, $adjustlength, $indent . ' ');
}
say $impl $indent."}";
@@ -690,8 +826,10 @@ sub dissect_element($$$$;$$)
sub struct {
my ($t, $elt) = @_;
my $name = $elt->att('name');
+ my $qualname = qualname($name);
+ $type_name{$name} = $qualname;
- if (defined $struct{$name}) {
+ if (defined $struct{$qualname}) {
$t->purge;
return;
}
@@ -700,6 +838,9 @@ sub struct {
print(" - Struct $name\n");
+ $name = $qualname;
+ $name =~ s/:/_/;
+
my %refs;
my $size = 0;
my $dynamic = 0;
@@ -716,7 +857,7 @@ sub struct {
}
when ('list') {
my $type = $e->att('type');
- my $info = $basictype{$type} // $simpletype{$type} // $struct{$type};
+ my $info = getinfo($type);
my $count;
$needi = 1 if ($info->{'size'} == 0);
@@ -749,7 +890,7 @@ sub struct {
}
my $type = $e->att('type');
- my $info = $basictype{$type} // $simpletype{$type} // $struct{$type};
+ my $info = getinfo($type);
$size += $info->{'size'} * $count;
}
@@ -774,7 +915,7 @@ eot
$count = 1;
my $type = $e->att('type') // '';
- my $info = $basictype{$type} // $simpletype{$type} // $struct{$type};
+ my $info = getinfo($type);
given ($e->name()) {
when ('pad') {
@@ -805,7 +946,7 @@ eot
} else {
say $impl " for (i = 0; i < $sizemul; i++) {";
say $impl " off = (*offsetp) + size + $size;";
- say $impl " size += struct_size_$type(tvb, &off, byte_order);";
+ say $impl " size += struct_size_$info->{name}(tvb, &off, byte_order);";
say $impl ' }';
}
}
@@ -840,9 +981,13 @@ eot
my $varpat = 'struct_'.$name.'_%s';
my $humanpat = "struct.$name.%s";
+ my $refs = { field => {}, sumof => {} };
foreach my $e (@elements) {
- register_element($e, $varpat, $humanpat, "\t");
+ reference_elements($e, $refs);
+ }
+ foreach my $e (@elements) {
+ register_element($e, $varpat, $humanpat, $refs, "\t");
}
my $sizecalc = $size;
@@ -856,11 +1001,11 @@ eot
;
my $length = 0;
foreach my $e (@elements) {
- $length = dissect_element($e, $varpat, $humanpat, $length, 0, "\t");
+ $length = dissect_element($e, $varpat, $humanpat, $length, $refs, 0, "\t");
}
print $impl " }\n}\n";
- $struct{$name} = { size => $size, name => $name };
+ $struct{$qualname} = { size => $size, name => $name };
$t->purge;
}
@@ -871,8 +1016,10 @@ sub union {
# for now, punt.
my ($t, $elt) = @_;
my $name = $elt->att('name');
+ my $qualname = qualname($name);
+ $type_name{$name} = $qualname;
- if (defined $struct{$name}) {
+ if (defined $struct{$qualname}) {
$t->purge;
return;
}
@@ -882,10 +1029,13 @@ sub union {
print(" - Union $name\n");
+ $name = $qualname;
+ $name =~ s/:/_/;
+
# Find union size
foreach my $e (@elements) {
my $type = $e->att('type');
- my $info = $basictype{$type} // $simpletype{$type} // $struct{$type};
+ my $info = getinfo($type);
$info->{'size'} > 0 or die ("Error: Union containing variable sized struct $type\n");
push @sizes, $info->{'size'};
@@ -910,9 +1060,13 @@ eot
my $varpat = 'union_'.$name.'_%s';
my $humanpat = "union.$name.%s";
+ my $refs = { field => {}, sumof => {} };
foreach my $e (@elements) {
- register_element($e, $varpat, $humanpat, "\t");
+ reference_elements($e, $refs);
+ }
+ foreach my $e (@elements) {
+ register_element($e, $varpat, $humanpat, $refs, "\t");
}
print $impl <<eot
@@ -924,14 +1078,14 @@ eot
foreach my $e (@elements) {
say $impl ' *offsetp = base;';
- dissect_element($e, $varpat, $humanpat, 0, 0, "\t");
+ dissect_element($e, $varpat, $humanpat, 0, $refs, 0, "\t");
}
say $impl " base += $size;";
say $impl ' }';
say $impl ' *offsetp = base;';
say $impl '}';
- $struct{$name} = { size => $size, name => $name };
+ $struct{$qualname} = { size => $size, name => $name };
$t->purge;
}
@@ -968,6 +1122,24 @@ sub enum {
when ('value') {
$$value{$val} = $n;
$nextvalue = $val + 1;
+
+ # Ugly hack to support (temporary, hopefully) ugly
+ # hack in xinput:ChangeDeviceProperty
+ # Register certain values as bits also
+ given ($val) {
+ when (8) {
+ $$bit{'3'} = $n;
+ $$rbit{$n} = 3;
+ }
+ when (16) {
+ $$bit{'4'} = $n;
+ $$rbit{$n} = 4;
+ }
+ when (32) {
+ $$bit{'5'} = $n;
+ $$rbit{$n} = 5;
+ }
+ }
}
when ('bit') {
$$bit{$val} = $n;
@@ -1011,9 +1183,13 @@ eot
}
my $varpat = $header.'_'.$name.'_%s';
my $humanpat = "$header.$name.%s";
+ my $refs = { field => {}, sumof => {} };
foreach my $e (@elements) {
- register_element($e, $varpat, $humanpat);
+ reference_elements($e, $refs);
+ }
+ foreach my $e (@elements) {
+ register_element($e, $varpat, $humanpat, $refs);
}
foreach my $e (@elements) {
@@ -1021,7 +1197,7 @@ eot
# Special case: Use mesa-generated dissector for 'data'
print $impl " dispatch_glx_render(tvb, pinfo, offsetp, t, byte_order, (length - $length));\n";
} else {
- $length = dissect_element($e, $varpat, $humanpat, $length, 1);
+ $length = dissect_element($e, $varpat, $humanpat, $length, $refs, 1);
}
}
@@ -1042,10 +1218,17 @@ eot
} else {
say $impl "static void $header$name"."_Reply(tvbuff_t *tvb, packet_info *pinfo, int *offsetp, proto_tree *t, guint byte_order)\n{";
}
- say $impl ' int f_length, length, sequence_number;' if (@elements);
+ say $impl ' int sequence_number;' if (@elements);
+ my $refs = { field => {}, sumof => {} };
foreach my $e (@elements) {
- register_element($e, $varpat, $humanpat);
+ reference_elements($e, $refs);
+ }
+
+ say $impl ' int f_length;' if ($refs->{field}{'length'});
+ say $impl ' int length;' if ($refs->{length});
+ foreach my $e (@elements) {
+ register_element($e, $varpat, $humanpat, $refs);
}
say $impl '';
@@ -1056,7 +1239,7 @@ eot
my $first = 1;
my $length = 1;
foreach my $e (@elements) {
- $length = dissect_element($e, $varpat, $humanpat, $length);
+ $length = dissect_element($e, $varpat, $humanpat, $length, $refs);
if ($first) {
$first = 0;
say $impl ' sequence_number = VALUE16(tvb, *offsetp);';
@@ -1064,8 +1247,12 @@ eot
say $impl ' "sequencenumber: %d ('.$header.'-'.$name.')", sequence_number);';
say $impl ' *offsetp += 2;';
- say $impl ' f_length = VALUE32(tvb, *offsetp);';
- say $impl ' length = f_length * 4 + 32;';
+ if ($refs->{field}{length}) {
+ say $impl ' f_length = VALUE32(tvb, *offsetp);';
+ }
+ if ($refs->{length}) {
+ say $impl ' length = f_length * 4 + 32;';
+ }
say $impl ' proto_tree_add_item(t, hf_x11_replylength, tvb, *offsetp, 4, byte_order);';
say $impl ' *offsetp += 4;';
@@ -1081,7 +1268,9 @@ eot
sub defxid(@) {
my $name;
while ($name = shift) {
- $simpletype{$name} = { size => 4, encoding => 'byte_order', type => 'FT_UINT32', base => 'BASE_HEX', get => 'VALUE32', list => 'listOfCard32', };
+ my $qualname = qualname($name);
+ $simpletype{$qualname} = { size => 4, encoding => 'byte_order', type => 'FT_UINT32', base => 'BASE_HEX', get => 'VALUE32', list => 'listOfCard32', };
+ $type_name{$name} = $qualname;
}
}
@@ -1098,16 +1287,18 @@ sub typedef {
my ($t, $elt) = @_;
my $oldname = $elt->att('oldname');
my $newname = $elt->att('newname');
+ my $qualname = qualname($newname);
# Duplicate the type
- my $info = $basictype{$oldname} // $simpletype{$oldname};
+ my $info = get_simple_info($oldname);
if ($info) {
- $simpletype{$newname} = $info;
- } elsif ($struct{$oldname}) {
- $struct{$newname} = $struct{$oldname};
+ $simpletype{$qualname} = $info;
+ } elsif ($info = get_struct_info($oldname)) {
+ $struct{$qualname} = $info;
} else {
die ("$oldname not found while attempting to typedef $newname\n");
}
+ $type_name{$newname} = $qualname;
$t->purge;
}
@@ -1128,47 +1319,83 @@ sub event {
my ($t, $elt) = @_;
my $number = $elt->att('number');
+ $number or return;
+
my $name = $elt->att('name');
+ my $xge = $elt->att('xge');
- $event{$elt->att('number')} = $name;
+ if ($xge) {
+ $genericevent{$number} = $name;
+ } else {
+ $event{$number} = $name;
+ }
my $length = 1;
my @elements = $elt->children(qr/pad|field|list|switch/);
# Wireshark defines _U_ to mean "Unused" (compiler specific define)
if (!@elements) {
- print $impl <<eot
+ if ($xge) {
+ print $impl <<eot
+
+static void $header$name(tvbuff_t *tvb _U_, int length _U_, int *offsetp _U_, proto_tree *t _U_, guint byte_order _U_)
+{
+ } else {
+ print $impl <<eot
static void $header$name(tvbuff_t *tvb _U_, int *offsetp _U_, proto_tree *t _U_, guint byte_order _U_)
{
eot
;
+ }
} else {
- print $impl <<eot
+ if ($xge) {
+ $length = 10;
+ print $impl <<eot
+
+static void $header$name(tvbuff_t *tvb, int length _U_, int *offsetp, proto_tree *t, guint byte_order)
+{
+eot
+;
+ } else {
+ print $impl <<eot
static void $header$name(tvbuff_t *tvb, int *offsetp, proto_tree *t, guint byte_order)
{
eot
;
+ }
}
my $varpat = $header.'_'.$name.'_%s';
my $humanpat = "$header.$name.%s";
+ my $refs = { field => {}, sumof => {} };
foreach my $e (@elements) {
- register_element($e, $varpat, $humanpat);
+ reference_elements($e, $refs);
}
-
- my $first = 1;
foreach my $e (@elements) {
- $length = dissect_element($e, $varpat, $humanpat, $length);
- if ($first) {
- $first = 0;
- say $impl " CARD16(event_sequencenumber);";
- }
+ register_element($e, $varpat, $humanpat, $refs);
+ }
+
+ if ($xge) {
+ say $impl " proto_tree_add_uint_format(t, hf_x11_minor_opcode, tvb, *offsetp, 2, $number,";
+ say $impl " \"opcode: $name ($number)\");";
+ foreach my $e (@elements) {
+ $length = dissect_element($e, $varpat, $humanpat, $length, $refs);
+ }
+ } else {
+ my $first = 1;
+ foreach my $e (@elements) {
+ $length = dissect_element($e, $varpat, $humanpat, $length, $refs);
+ if ($first) {
+ $first = 0;
+ say $impl " CARD16(event_sequencenumber);";
+ }
+ }
}
- print $impl "}\n";
+ say $impl "}\n";
$t->purge;
}
@@ -1219,11 +1446,13 @@ sub xcb_start {
print("Extension $extname\n");
undef %request;
+ undef %genericevent;
undef %event;
undef %reply;
%simpletype = ();
%enum_name = ();
+ %type_name = ();
print $error "const char *$header"."_errors[] = {\n";
}
@@ -1235,6 +1464,7 @@ sub xcb {
my $lookup_name = $header . "_extension_minor";
my $error_name = $header . "_errors";
my $event_name = $header . "_events";
+ my $genevent_name = 'NULL';
my $reply_name = $header . "_replies";
print $decl "static int hf_x11_$lookup_name = -1;\n\n";
@@ -1253,6 +1483,18 @@ sub xcb {
say $impl ' { NULL, NULL }';
say $impl '};';
+ if (%genericevent) {
+ $genevent_name = $header.'_generic_events';
+ say $impl 'static const x11_generic_event_info '.$genevent_name.'[] = {';
+
+ for my $val (sort { $a <=> $b } keys %genericevent) {
+ say $impl sprintf("\t{ %3d, %s },", $val, $header.$genericevent{$val});
+ }
+ say $impl sprintf("\t{ %3d, NULL },", 0);
+ say $impl '};';
+ say $impl '';
+ }
+
print $impl "static x11_reply_info $reply_name"."[] = {\n";
foreach my $e (sort {$a <=> $b} keys %reply) {
print $impl " { $e, $header$reply{$e}_Reply },\n";
@@ -1289,7 +1531,7 @@ eot
static void register_$header(void)
{
- set_handler("$xextname", dispatch_$header, $error_name, $event_name, $reply_name);
+ set_handler("$xextname", dispatch_$header, $error_name, $event_name, $genevent_name, $reply_name);
}
eot
;
@@ -1383,9 +1625,6 @@ if (-e "$mesadir/gl_API.xml") {
or die ("Cannot open x11-glx-render-enum.h for writing\n");
add_generated_header($enum, 'mesa');
print $enum "static const value_string mesa_enum[] = {\n";
- print $impl "#if defined(__GNUC__)\n";
- print $impl '#pragma GCC diagnostic ignored "-Wunused-but-set-variable"'."\n";
- print $impl "#endif\n\n";
print $impl '#include "x11-glx-render-enum.h"'."\n\n";
print("Mesa glRender:\n");