diff options
author | Jeff Morriss <jeff.morriss.ws@gmail.com> | 2013-11-24 01:32:20 +0000 |
---|---|---|
committer | Jeff Morriss <jeff.morriss.ws@gmail.com> | 2013-11-24 01:32:20 +0000 |
commit | a434d9647ed9b724630552488048af4a31c97618 (patch) | |
tree | 73ac49c95f0b0ff76f5c3d1fc124d9cd404bbaff /tools/process-x11-xcb.pl | |
parent | 1db1b8e2bb6cd4ae1731205738eef9f572a03ead (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-x | tools/process-x11-xcb.pl | 503 |
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"); |