3 # Script to convert xcbproto and mesa protocol files for
4 # X11 dissector. Creates header files containing code to
5 # dissect X11 extensions.
7 # Copyright 2008, 2009, 2013 Open Text Corporation <pharris[AT]opentext.com>
11 # Wireshark - Network traffic analyzer
12 # By Gerald Combs <gerald@wireshark.org>
13 # Copyright 1998 Gerald Combs
15 # This program is free software; you can redistribute it and/or
16 # modify it under the terms of the GNU General Public License
17 # as published by the Free Software Foundation; either version 2
18 # of the License, or (at your option) any later version.
20 # This program is distributed in the hope that it will be useful,
21 # but WITHOUT ANY WARRANTY; without even the implied warranty of
22 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 # GNU General Public License for more details.
25 # You should have received a copy of the GNU General Public License
26 # along with this program; if not, write to the Free Software
27 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
31 # - support constructs that are legal in XCB, but don't appear to be used
38 # given/when is going to be removed (and/or dramatically altered)
39 # in 5.20. Patches welcome.
40 # Patches even more welcome if they rewrite this whole thing in a
41 # language with a proper compatibility document, such as
42 # http://golang.org/doc/go1compat
43 no if $] >= 5.018, warnings => "experimental::smartmatch";
51 my @reslist = grep {!/xproto\.xml$/} glob File::Spec->catfile('xcbproto', 'src', '*.xml');
55 char => { size => 1, encoding => 'ENC_ASCII|ENC_NA', type => 'FT_STRING', base => 'BASE_NONE', get => 'VALUE8', list => 'listOfByte', },
56 void => { size => 1, encoding => 'ENC_NA', type => 'FT_BYTES', base => 'BASE_NONE', get => 'VALUE8', list => 'listOfByte', },
57 BYTE => { size => 1, encoding => 'ENC_NA', type => 'FT_BYTES', base => 'BASE_NONE', get => 'VALUE8', list => 'listOfByte', },
58 CARD8 => { size => 1, encoding => 'byte_order', type => 'FT_UINT8', base => 'BASE_HEX_DEC', get => 'VALUE8', list => 'listOfByte', },
59 CARD16 => { size => 2, encoding => 'byte_order', type => 'FT_UINT16', base => 'BASE_HEX_DEC', get => 'VALUE16', list => 'listOfCard16', },
60 CARD32 => { size => 4, encoding => 'byte_order', type => 'FT_UINT32', base => 'BASE_HEX_DEC', get => 'VALUE32', list => 'listOfCard32', },
61 CARD64 => { size => 8, encoding => 'byte_order', type => 'FT_UINT64', base => 'BASE_HEX_DEC', get => 'VALUE64', list => 'listOfCard64', },
62 INT8 => { size => 1, encoding => 'byte_order', type => 'FT_INT8', base => 'BASE_DEC', get => 'VALUE8', list => 'listOfByte', },
63 INT16 => { size => 2, encoding => 'byte_order', type => 'FT_INT16', base => 'BASE_DEC', get => 'VALUE16', list => 'listOfInt16', },
64 INT32 => { size => 4, encoding => 'byte_order', type => 'FT_INT32', base => 'BASE_DEC', get => 'VALUE32', list => 'listOfInt32', },
65 INT64 => { size => 8, encoding => 'byte_order', type => 'FT_INT64', base => 'BASE_DEC', get => 'VALUE64', list => 'listOfInt64', },
66 float => { size => 4, encoding => 'byte_order', type => 'FT_FLOAT', base => 'BASE_NONE', get => 'FLOAT', list => 'listOfFloat', },
67 double => { size => 8, encoding => 'byte_order', type => 'FT_DOUBLE', base => 'BASE_NONE', get => 'DOUBLE', list => 'listOfDouble', },
68 BOOL => { size => 1, encoding => 'byte_order', type => 'FT_BOOLEAN',base => 'BASE_NONE', get => 'VALUE8', list => 'listOfByte', },
71 my %simpletype; # Reset at the beginning of each extension
72 my %gltype; # No need to reset, since it's only used once
74 my %struct = # Not reset; contains structures already defined.
75 # Also contains this black-list of structures never used by any
76 # extension (to avoid generating useless code).
78 # structures defined by xproto, but not used by any extension
82 'xproto:VISUALTYPE' => 1,
85 'xproto:SetupRequest' => 1,
86 'xproto:SetupFailed' => 1,
87 'xproto:SetupAuthenticate' => 1,
89 'xproto:TIMECOORD' => 1,
90 'xproto:FONTPROP' => 1,
91 'xproto:CHARINFO' => 1,
92 'xproto:SEGMENT' => 1,
93 'xproto:COLORITEM' => 1,
98 # structures defined by xinput, but never used (except by each other)(bug in xcb?)
99 'xinput:InputInfo' => 1,
100 'xinput:KeyInfo' => 1,
101 'xinput:ButtonInfo' => 1,
102 'xinput:AxisInfo' => 1,
103 'xinput:ValuatorInfo' => 1,
104 'xinput:DeviceTimeCoord' => 1,
105 'xinput:KbdFeedbackState' => 1,
106 'xinput:PtrFeedbackState' => 1,
107 'xinput:IntegerFeedbackState' => 1,
108 'xinput:StringFeedbackState' => 1,
109 'xinput:BellFeedbackState' => 1,
110 'xinput:LedFeedbackState' => 1,
111 'xinput:KbdFeedbackCtl' => 1,
112 'xinput:PtrFeedbackCtl' => 1,
113 'xinput:IntegerFeedbackCtl' => 1,
114 'xinput:StringFeedbackCtl' => 1,
115 'xinput:BellFeedbackCtl' => 1,
116 'xinput:LedFeedbackCtl' => 1,
117 'xinput:KeyState' => 1,
118 'xinput:ButtonState' => 1,
119 'xinput:ValuatorState' => 1,
120 'xinput:DeviceResolutionState' => 1,
121 'xinput:DeviceAbsCalibState' => 1,
122 'xinput:DeviceAbsAreaState' => 1,
123 'xinput:DeviceCoreState' => 1,
124 'xinput:DeviceEnableState' => 1,
125 'xinput:DeviceResolutionCtl' => 1,
126 'xinput:DeviceAbsCalibCtl' => 1,
127 'xinput:DeviceAbsAreaCtrl' => 1,
128 'xinput:DeviceCoreCtrl' => 1,
129 'xinput:DeviceEnableCtrl' => 1,
130 'xinput:DeviceName' => 1,
131 'xinput:AddMaster' => 1,
132 'xinput:RemoveMaster' => 1,
133 'xinput:AttachSlave' => 1,
134 'xinput:DetachSlave' => 1,
135 'xinput:ButtonClass' => 1,
136 'xinput:KeyClass' => 1,
137 'xinput:ScrollClass' => 1,
138 'xinput:TouchClass' => 1,
139 'xinput:ValuatorClass' => 1,
141 # structures defined by xv, but never used (bug in xcb?)
144 # structures defined by xkb, but never used (except by each other)(bug in xcb?)
148 'xkb:OverlayKey' => 1,
149 'xkb:OverlayRow' => 1,
153 my %enum; # Not reset; contains enums already defined.
170 # glRender sub-op output files
173 # Mesa API definitions keep moving
174 my @mesas = ('mesa/src/mapi/glapi/gen', # 2010-04-26
175 'mesa/src/mesa/glapi/gen', # 2010-02-22
176 'mesa/src/mesa/glapi'); # 2004-05-18
177 my $mesadir = (grep { -d } @mesas)[0];
179 sub mesa_category_start {
181 my $name = $elt->att('name');
183 if ($name =~ /^\d\.\d$/) {
184 $comment = "version $name";
186 $comment = "extension $name";
189 print $enum "/* OpenGL $comment */\n";
190 print(" - $comment\n");
200 my $name = $elt->att('name');
201 my $value = $elt->att('value');
203 print $enum " { $value, \"$name\" },\n" if (length($value) > 3 && length($value) < 10);
210 my $name = $elt->att('name');
211 my $size = $elt->att('size');
212 my $float = $elt->att('float');
213 my $unsigned = $elt->att('unsigned');
218 if($name eq 'enum') {
219 # enum does not have a direct X equivalent
220 $gltype{'GLenum'} = { size => 4, encoding => 'byte_order', type => 'FT_UINT32', base => 'BASE_HEX',
221 get => 'VALUE32', list => 'listOfCard32',
222 val => 'VALS(mesa_enum)', };
227 if (defined($float) && $float eq 'true') {
229 $base = 'double' if ($size == 8);
232 if (defined($unsigned) && $unsigned eq 'true') {
235 $base .= ($size * 8);
237 $base = 'BOOL' if ($name eq 'bool');
238 $base = 'BYTE' if ($name eq 'void');
241 $gltype{$name} = $basictype{$base};
244 sub registered_name($$)
249 return "hf_x11_$header"."_$name"."_$field";
254 # rop == glRender sub-op
255 # sop == GLX minor opcode
256 my $glx = $elt->first_child('glx');
257 unless(defined $glx) { $t->purge; return; }
259 my $rop = $glx->att('rop');
260 unless (defined $rop) { $t->purge; return; }
262 # Ideally, we want the main name, not the alias name.
263 # Practically, we'd have to scan the file twice to find
264 # the functions that we want to skip.
265 my $alias = $elt->att('alias');
266 if (defined $alias) { $t->purge; return; }
268 my $name = $elt->att('name');
269 $request{$rop} = $name;
274 my @elements = $elt->children('param');
276 # Wireshark defines _U_ to mean "Unused" (compiler specific define)
279 static void mesa_$name(tvbuff_t *tvb _U_, int *offsetp _U_, proto_tree *t _U_, guint byte_order _U_, int length _U_)
285 static void mesa_$name(tvbuff_t *tvb, int *offsetp, proto_tree *t, guint byte_order, int length _U_)
292 foreach my $e (@elements) {
293 # Detect count && variable_param
294 my $count = $e->att('count');
295 my $variable_param = $e->att('variable_param');
296 if (defined $count and defined $variable_param) {
297 $type_param{$variable_param} = 1;
300 foreach my $e (@elements) {
301 # Register field with wireshark
303 my $type = $e->att('type');
304 $type =~ s/^const //;
306 $list = 1 if ($type =~ /\*$/);
309 my $fieldname = $e->att('name');
310 my $regname = registered_name($name, $fieldname);
312 my $info = $gltype{$type};
313 my $ft = $info->{'type'};
314 my $base = $info->{'base'};
315 my $val = $info->{'val'} // 'NULL';
316 my $count = $e->att('count');
317 my $variable_param = $e->att('variable_param');
319 if ($list and $count and $variable_param) {
320 print $decl "static int ${regname} = -1;\n";
321 print $reg "{ &$regname, { \"$fieldname\", \"x11.glx.render.$name.$fieldname\", FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }},\n";
322 print $decl "static int ${regname}_signed = -1;\n";
323 print $reg "{ &${regname}_signed, { \"$fieldname\", \"x11.glx.render.$name.$fieldname\", FT_INT8, BASE_DEC, NULL, 0, NULL, HFILL }},\n";
324 print $decl "static int ${regname}_unsigned = -1;\n";
325 print $reg "{ &${regname}_unsigned, { \"$fieldname\", \"x11.glx.render.$name.$fieldname\", FT_UINT8, BASE_DEC, NULL, 0, NULL, HFILL }},\n";
326 print $decl "static int ${regname}_item_card16 = -1;\n";
327 print $reg "{ &${regname}_item_card16, { \"$fieldname\", \"x11.glx.render.$name.$fieldname\", FT_UINT16, BASE_DEC, NULL, 0, NULL, HFILL }},\n";
328 print $decl "static int ${regname}_item_int16 = -1;\n";
329 print $reg "{ &${regname}_item_int16, { \"$fieldname\", \"x11.glx.render.$name.$fieldname\", FT_INT16, BASE_DEC, NULL, 0, NULL, HFILL }},\n";
330 print $decl "static int ${regname}_item_card32 = -1;\n";
331 print $reg "{ &${regname}_item_card32, { \"$fieldname\", \"x11.glx.render.$name.$fieldname\", FT_UINT32, BASE_DEC, NULL, 0, NULL, HFILL }},\n";
332 print $decl "static int ${regname}_item_int32 = -1;\n";
333 print $reg "{ &${regname}_item_int32, { \"$fieldname\", \"x11.glx.render.$name.$fieldname\", FT_INT32, BASE_DEC, NULL, 0, NULL, HFILL }},\n";
334 print $decl "static int ${regname}_item_float = -1;\n";
335 print $reg "{ &${regname}_item_float, { \"$fieldname\", \"x11.glx.render.$name.$fieldname\", FT_FLOAT, BASE_NONE, NULL, 0, NULL, HFILL }},\n";
337 print $decl "static int $regname = -1;\n";
338 if ($list and $info->{'size'} > 1) {
339 print $reg "{ &$regname, { \"$fieldname\", \"x11.glx.render.$name.$fieldname\", FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }},\n";
341 print $decl "static int $regname = -1;\n";
343 print $reg "{ &$regname, { \"$fieldname\", \"x11.glx.render.$name.$fieldname\", $ft, $base, $val, 0, NULL, HFILL }},\n";
345 if ($e->att('counter') or $type_param{$fieldname}) {
346 print $impl " int $fieldname;\n";
351 if ($e->att('img_format')) {
353 foreach my $wholename (('swap bytes', 'lsb first')) {
355 my $varname = $wholename;
357 my $regname = registered_name($name, $varname);
358 print $decl "static int $regname = -1;\n";
359 print $reg "{ &$regname, { \"$wholename\", \"x11.glx.render.$name.$varname\", FT_BOOLEAN, BASE_NONE, NULL, 0, NULL, HFILL }},\n";
361 foreach my $wholename (('row length', 'skip rows', 'skip pixels', 'alignment')) {
363 my $varname = $wholename;
365 my $regname = registered_name($name, $varname);
366 print $decl "static int $regname = -1;\n";
367 print $reg "{ &$regname, { \"$wholename\", \"x11.glx.render.$name.$varname\", FT_UINT32, BASE_HEX_DEC, NULL, 0, NULL, HFILL }},\n";
373 # The image requests have a few implicit elements first:
375 foreach my $wholename (('swap bytes', 'lsb first')) {
377 my $varname = $wholename;
379 my $regname = registered_name($name, $varname);
380 print $impl " proto_tree_add_item(t, $regname, tvb, *offsetp, 1, byte_order);\n";
381 print $impl " *offsetp += 1;\n";
384 print $impl " UNUSED(2);\n";
386 foreach my $wholename (('row length', 'skip rows', 'skip pixels', 'alignment')) {
388 my $varname = $wholename;
390 my $regname = registered_name($name, $varname);
391 print $impl " proto_tree_add_item(t, $regname, tvb, *offsetp, 4, byte_order);\n";
392 print $impl " *offsetp += 4;\n";
397 foreach my $e (@elements) {
398 my $type = $e->att('type');
399 $type =~ s/^const //;
401 $list = 1 if ($type =~ /\*$/);
404 my $fieldname = $e->att('name');
405 my $regname = registered_name($name, $fieldname);
407 my $info = $gltype{$type};
408 my $ft = $info->{'type'};
409 my $base = $info->{'base'};
412 my $size = $info->{'size'};
413 my $encoding = $info->{'encoding'};
414 my $get = $info->{'get'};
416 if ($e->att('counter') or $type_param{$fieldname}) {
417 print $impl " $fieldname = $get(tvb, *offsetp);\n";
419 print $impl " proto_tree_add_item(t, $regname, tvb, *offsetp, $size, $encoding);\n";
420 print $impl " *offsetp += $size;\n";
423 my $list = $info->{'list'};
424 my $count = $e->att('count');
425 my $variable_param = $e->att('variable_param');
427 if (defined($count) && !defined($variable_param)) {
428 $regname .= ", $regname".'_item' if ($info->{'size'} > 1);
429 print $impl " $list(tvb, offsetp, t, $regname, $count, byte_order);\n";
431 if (defined($count)) {
432 # Currently, only CallLists has both a count and a variable_param
433 # The XML contains a size description of all the possibilities
434 # for CallLists, but not a type description. Implement by hand,
435 # with the caveat that more types may need to be added in the
437 say $impl " switch($variable_param) {";
438 say $impl " case 0x1400: /* BYTE */";
439 say $impl " listOfByte(tvb, offsetp, t, ${regname}_signed, $count, byte_order);";
440 say $impl " UNUSED(length - $length - $count);";
442 say $impl " case 0x1401: /* UNSIGNED_BYTE */";
443 say $impl " listOfByte(tvb, offsetp, t, ${regname}_unsigned, $count, byte_order);";
444 say $impl " UNUSED(length - $length - $count);";
446 say $impl " case 0x1402: /* SHORT */";
447 say $impl " listOfInt16(tvb, offsetp, t, $regname, ${regname}_item_int16, $count, byte_order);";
448 say $impl " UNUSED(length - $length - 2 * $count);";
450 say $impl " case 0x1403: /* UNSIGNED_SHORT */";
451 say $impl " listOfCard16(tvb, offsetp, t, $regname, ${regname}_item_card16, $count, byte_order);";
452 say $impl " UNUSED(length - $length - 2 * $count);";
454 say $impl " case 0x1404: /* INT */";
455 say $impl " listOfInt32(tvb, offsetp, t, $regname, ${regname}_item_int32, $count, byte_order);";
457 say $impl " case 0x1405: /* UNSIGNED_INT */";
458 say $impl " listOfCard32(tvb, offsetp, t, $regname, ${regname}_item_card32, $count, byte_order);";
460 say $impl " case 0x1406: /* FLOAT */";
461 say $impl " listOfFloat(tvb, offsetp, t, $regname, ${regname}_item_float, $count, byte_order);";
463 say $impl " case 0x1407: /* 2_BYTES */";
464 say $impl " listOfCard16(tvb, offsetp, t, $regname, ${regname}_item_card16, $count, ENC_BIG_ENDIAN);";
465 say $impl " UNUSED(length - $length - 2 * $count);";
467 say $impl " case 0x1408: /* 3_BYTES */";
468 say $impl " UNDECODED(3 * $count);";
469 say $impl " UNUSED(length - $length - 3 * $count);";
471 say $impl " case 0x1409: /* 4_BYTES */";
472 say $impl " listOfCard32(tvb, offsetp, t, $regname, ${regname}_item_card32, $count, ENC_BIG_ENDIAN);";
474 say $impl " case 0x140B: /* HALF_FLOAT */";
475 say $impl " UNDECODED(2 * $count);";
476 say $impl " UNUSED(length - $length - 2 * $count);";
478 say $impl " default: /* Unknown */";
479 say $impl " UNDECODED(length - $length);";
483 $regname .= ", $regname".'_item' if ($info->{'size'} > 1);
484 print $impl " $list(tvb, offsetp, t, $regname, (length - $length) / $gltype{$type}{'size'}, byte_order);\n";
503 given($elt->name()) {
509 when ('value') { $rv = $elt->text(); }
510 when ('op') { $rv = get_op($elt, $refref); }
511 when (['unop','popcount']) { $rv = get_unop($elt, $refref); }
512 default { die "Invalid op fragment: $_" }
519 my $refref = shift // {};
521 my @elements = $op->children(qr/fieldref|value|op|unop|popcount/);
522 (@elements == 2) or die ("Wrong number of children for 'op'\n");
526 $left = get_ref($elements[0], $refref);
527 $right = get_ref($elements[1], $refref);
529 return "($left " . $op->att('op') . " $right)";
534 my $refref = shift // {};
536 my @elements = $op->children(qr/fieldref|value|op|unop|popcount/);
537 (@elements == 1) or die ("Wrong number of children for 'unop'\n");
540 $left = get_ref($elements[0], $refref);
542 given ($op->name()) {
544 return '(' . $op->att('op') . "$left)";
547 return "popcount($left)";
549 default { die "Invalid unop element $op->name()\n"; }
555 $name = $incname[0].':'.$name unless $name =~ /:/;
559 sub get_simple_info {
561 my $info = $basictype{$name};
562 return $info if (defined $info);
563 $info = $simpletype{$name};
564 return $info if (defined $info);
565 if (defined($type_name{$name})) {
566 return $simpletype{$type_name{$name}};
571 sub get_struct_info {
573 my $info = $struct{$name};
574 return $info if (defined $info);
575 if (defined($type_name{$name})) {
576 return $struct{$type_name{$name}};
583 return get_simple_info($name) // get_struct_info($name);
586 sub dump_enum_values($)
590 defined($enum{$e}) or die("Enum $e not found");
592 my $enumname = "x11_enum_$e";
593 return $enumname if (defined $enum{$e}{done});
595 say $enum 'static const value_string '.$enumname.'[] = {';
597 my $value = $enum{$e}{value};
598 for my $val (sort { $a <=> $b } keys %$value) {
599 say $enum sprintf("\t{ %3d, \"%s\" },", $val, $$value{$val});
601 say $enum sprintf("\t{ %3d, NULL },", 0);
609 # Find all references, so we can declare only the minimum necessary
610 sub reference_elements($$);
612 sub reference_elements($$)
619 my $lentype = $e->first_child();
620 if (defined $lentype) {
621 given ($lentype->name()) {
622 when ('fieldref') { $refref->{field}{$lentype->text()} = 1; }
623 when ('op') { get_op($lentype, $refref->{field}); }
627 my @elements = $e->children('bitcase');
628 for my $case (@elements) {
629 my @sub_elements = $case->children(qr/list|switch/);
631 foreach my $sub_e (@sub_elements) {
632 reference_elements($sub_e, $refref);
637 my $lentype = $e->first_child();
638 if (defined $lentype) {
639 given ($lentype->name()) {
640 when ('fieldref') { $refref->{field}{$lentype->text()} = 1; }
641 when ('op') { get_op($lentype, $refref->{field}); }
642 when (['unop','popcount']) { get_unop($lentype, $refref->{field}); }
643 when ('sumof') { $refref->{sumof}{$lentype->att('ref')} = 1; }
646 $refref->{field}{'length'} = 1;
647 $refref->{'length'} = 1;
653 sub register_element($$$$;$)
657 my $humanpat = shift;
659 my $indent = shift // ' ' x 4;
662 when ('pad') { return; } # Pad has no variables
663 when ('switch') { return; } # Switch defines varaibles in a tighter scope to avoid collisions
666 # Register field with wireshark
668 my $fieldname = $e->att('name');
669 my $type = $e->att('type') or die ("Field $fieldname does not have a valid type\n");
671 my $regname = 'hf_x11_'.sprintf ($varpat, $fieldname);
672 my $humanname = 'x11.'.sprintf ($humanpat, $fieldname);
674 my $info = getinfo($type);
675 my $ft = $info->{'type'} // 'FT_NONE';
676 my $base = $info->{'base'} // 'BASE_NONE';
679 my $enum = $e->att('enum') // $e->att('altenum');
681 my $enumname = dump_enum_values($enum_name{$enum});
682 $vals = "VALS($enumname)";
684 # Wireshark does not allow FT_BYTES, FT_BOOLEAN, or BASE_NONE to have an enum
685 $ft =~ s/FT_BYTES/FT_UINT8/;
686 $ft =~ s/FT_BOOLEAN/FT_UINT8/;
687 $base =~ s/BASE_NONE/BASE_DEC/;
690 $enum = $e->att('mask');
692 # Create subtree items:
693 defined($enum{$enum_name{$enum}}) or die("Enum $enum not found");
695 # Wireshark does not allow FT_BYTES or BASE_NONE to have an enum
696 $ft =~ s/FT_BYTES/FT_UINT8/;
697 $base =~ s/BASE_NONE/BASE_DEC/;
699 my $bitsize = $info->{'size'} * 8;
701 my $bit = $enum{$enum_name{$enum}}{bit};
702 for my $val (sort { $a <=> $b } keys %$bit) {
703 my $itemname = $$bit{$val};
704 my $item = $regname . '_mask_' . $itemname;
705 my $itemhuman = $humanname . '.' . $itemname;
706 my $bitshift = "1 << $val";
708 say $decl "static int $item = -1;";
709 say $reg "{ &$item, { \"$itemname\", \"$itemhuman\", FT_BOOLEAN, $bitsize, NULL, $bitshift, NULL, HFILL }},";
713 print $decl "static int $regname = -1;\n";
714 if ($e->name() eq 'list' and $info->{'size'} > 1) {
715 print $reg "{ &$regname, { \"$fieldname\", \"$humanname\", FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }},\n";
717 print $decl "static int $regname = -1;\n";
719 print $reg "{ &$regname, { \"$fieldname\", \"$humanname\", $ft, $base, $vals, 0, NULL, HFILL }},\n";
721 if ($refref->{sumof}{$fieldname}) {
722 print $impl $indent."int sumof_$fieldname = 0;\n";
725 if ($e->name() eq 'field') {
726 if ($refref->{field}{$fieldname} and get_simple_info($type)) {
727 # Pre-declare variable
728 if ($ft eq 'FT_FLOAT') {
729 print $impl $indent."gfloat f_$fieldname;\n";
730 } elsif ($ft eq 'FT_DOUBLE') {
731 print $impl $indent."gdouble f_$fieldname;\n";
732 } elsif ($ft eq 'FT_INT64' or $ft eq 'FT_UINT64') {
733 print $impl $indent."gint64 f_$fieldname;\n";
735 print $impl $indent."int f_$fieldname;\n";
741 sub dissect_element($$$$$;$$);
743 sub dissect_element($$$$$;$$)
747 my $humanpat = shift;
750 my $adjustlength = shift;
751 my $indent = shift // ' ' x 4;
755 my $bytes = $e->att('bytes');
756 print $impl $indent."UNUSED($bytes);\n";
760 my $fieldname = $e->att('name');
761 my $regname = 'hf_x11_'.sprintf ($varpat, $fieldname);
762 my $type = $e->att('type');
764 if (get_simple_info($type)) {
765 my $info = get_simple_info($type);
766 my $size = $info->{'size'};
767 my $encoding = $info->{'encoding'};
768 my $get = $info->{'get'};
770 if ($e->att('enum') // $e->att('altenum')) {
771 my $fieldsize = $size * 8;
773 if ($refref->{field}{$fieldname}) {
774 print $impl "f_$fieldname = ";
776 say $impl "field$fieldsize(tvb, offsetp, t, $regname, byte_order);";
777 } elsif ($e->att('mask')) {
778 if ($refref->{field}{$fieldname}) {
779 say $impl $indent."f_$fieldname = $get(tvb, *offsetp);";
781 say $impl $indent."{";
782 say $impl $indent." proto_item *ti = proto_tree_add_item(t, $regname, tvb, *offsetp, $size, $encoding);";
783 say $impl $indent." proto_tree *bitmask_tree = proto_item_add_subtree(ti, ett_x11_rectangle);";
785 my $bytesize = $info->{'size'};
786 my $byteencoding = $info->{'encoding'};
787 my $bit = $enum{$enum_name{$e->att('mask')}}{bit};
788 for my $val (sort { $a <=> $b } keys %$bit) {
789 my $item = $regname . '_mask_' . $$bit{$val};
791 say $impl "$indent proto_tree_add_item(bitmask_tree, $item, tvb, *offsetp, $bytesize, $byteencoding);";
794 say $impl $indent."}";
795 say $impl $indent."*offsetp += $size;";
797 if ($refref->{field}{$fieldname}) {
798 say $impl $indent."f_$fieldname = $get(tvb, *offsetp);";
800 print $impl $indent."proto_tree_add_item(t, $regname, tvb, *offsetp, $size, $encoding);\n";
801 print $impl $indent."*offsetp += $size;\n";
804 } elsif (get_struct_info($type)) {
805 # TODO: variable-lengths (when $info->{'size'} == 0 )
806 my $info = get_struct_info($type);
807 $length += $info->{'size'};
808 print $impl $indent."struct_$info->{'name'}(tvb, offsetp, t, byte_order, 1);\n";
810 die ("Unrecognized type: $type\n");
814 my $fieldname = $e->att('name');
815 my $regname = 'hf_x11_'.sprintf ($varpat, $fieldname);
816 my $type = $e->att('type');
818 my $info = getinfo($type);
819 my $lencalc = "(length - $length) / $info->{'size'}";
820 my $lentype = $e->first_child();
821 if (defined $lentype) {
822 given ($lentype->name()) {
823 when ('value') { $lencalc = $lentype->text(); }
824 when ('fieldref') { $lencalc = 'f_'.$lentype->text(); }
825 when ('op') { $lencalc = get_op($lentype); }
826 when (['unop','popcount']) { $lencalc = get_unop($lentype); }
827 when ('sumof') { $lencalc = 'sumof_'.$lentype->att('ref'); }
831 if (get_simple_info($type)) {
832 my $list = $info->{'list'};
833 my $size = $info->{'size'};
834 $regname .= ", $regname".'_item' if ($size > 1);
836 if ($refref->{sumof}{$fieldname}) {
837 my $get = $info->{'get'};
838 say $impl $indent."{";
839 say $impl $indent." int i;";
840 say $impl $indent." for (i = 0; i < $lencalc; i++) {";
841 say $impl $indent." sumof_$fieldname += $get(tvb, *offsetp + i * $size);";
842 say $impl $indent." }";
843 say $impl $indent."}";
846 print $impl $indent."$list(tvb, offsetp, t, $regname, $lencalc, byte_order);\n";
847 } elsif (get_struct_info($type)) {
848 print $impl $indent."struct_$info->{'name'}(tvb, offsetp, t, byte_order, $lencalc);\n";
850 die ("Unrecognized type: $type\n");
853 if ($adjustlength && defined($lentype)) {
854 # Some requests end with a list of unspecified length
855 # Adjust the length field here so that the next $lencalc will be accurate
856 say $impl $indent."length -= $lencalc * $info->{'size'};";
860 my $switchtype = $e->first_child() or die("Switch element not defined");
862 my $switchon = get_ref($switchtype, {});
863 my @elements = $e->children('bitcase');
864 for my $case (@elements) {
865 my @refs = $case->children('enumref');
868 foreach my $ref (@refs) {
869 my $enum_ref = $ref->att('ref');
870 my $field = $ref->text();
871 $fieldname //= $field; # Use first named field
872 my $bit = $enum{$enum_name{$enum_ref}}{rbit}{$field};
873 if (! defined($bit)) {
874 for my $foo (keys %{$enum{$enum_name{$enum_ref}}{rbit}}) { say "'$foo'"; }
875 die ("Field '$field' not found in '$enum_ref'");
877 push @bits , "(1 << $bit)";
879 if (scalar @bits == 1) {
880 say $impl $indent."if (($switchon & $bits[0]) != 0) {";
882 my $list = join '|', @bits;
883 say $impl $indent."if (($switchon & ($list)) != 0) {";
889 $vp =~ s/%s/${fieldname}_%s/;
890 $hp =~ s/%s/${fieldname}.%s/;
892 my @sub_elements = $case->children(qr/pad|field|list|switch/);
894 my $subref = { field => {}, sumof => {} };
895 foreach my $sub_e (@sub_elements) {
896 reference_elements($sub_e, $subref);
898 foreach my $sub_e (@sub_elements) {
899 register_element($sub_e, $vp, $hp, $subref, $indent . ' ');
901 foreach my $sub_e (@sub_elements) {
902 $length = dissect_element($sub_e, $vp, $hp, $length, $subref, $adjustlength, $indent . ' ');
905 say $impl $indent."}";
908 default { die "Unknown field type: $_\n"; }
915 my $name = $elt->att('name');
916 my $qualname = qualname($name);
917 $type_name{$name} = $qualname;
919 if (defined $struct{$qualname}) {
924 my @elements = $elt->children(qr/pad|field|list|switch/);
926 print(" - Struct $name\n");
936 foreach my $e (@elements) {
941 my $bytes = $e->att('bytes');
946 my $type = $e->att('type');
947 my $info = getinfo($type);
950 $needi = 1 if ($info->{'size'} == 0);
952 my $value = $e->first_child();
953 given($value->name()) {
955 $refs{$value->text()} = 1;
960 get_op($value, \%refs);
964 when (['unop','popcount']) {
965 get_unop($value, \%refs);
970 $count = $value->text();
972 default { die("Invalid list size $_\n"); }
976 default { die("unrecognized field $_\n"); }
979 my $type = $e->att('type');
980 my $info = getinfo($type);
982 $size += $info->{'size'} * $count;
989 static int struct_size_$name(tvbuff_t *tvb, int *offsetp, guint byte_order _U_)
994 say $impl ' int i, off;' if ($needi);
996 foreach my $ref (sort keys %refs) {
997 say $impl " int f_$ref;";
1000 foreach my $e (@elements) {
1004 my $type = $e->att('type') // '';
1005 my $info = getinfo($type);
1007 given ($e->name()) {
1009 my $bytes = $e->att('bytes');
1013 my $len = $e->first_child();
1014 my $infosize = $info->{'size'};
1017 given ($len->name()) {
1018 when ('op') { $sizemul = get_op($len, \%refs); }
1019 when (['unop','popcount']) { $sizemul = get_unop($len, \%refs); }
1020 when ('fieldref') { $sizemul = 'f_'.$len->text(); }
1023 $size += $infosize * $len->text();
1025 $sizemul = $len->text();
1028 default { die "Invalid list size: $_\n"; }
1030 if (defined $sizemul) {
1032 say $impl " size += $sizemul * $infosize;";
1034 say $impl " for (i = 0; i < $sizemul; i++) {";
1035 say $impl " off = (*offsetp) + size + $size;";
1036 say $impl " size += struct_size_$info->{name}(tvb, &off, byte_order);";
1042 my $fname = $e->att('name');
1043 if (defined($refs{$fname})) {
1044 say $impl " f_$fname = $info->{'get'}(tvb, *offsetp + size + $size);";
1046 $size += $info->{'size'};
1050 say $impl " return size + $size;";
1052 $size = 0; # 0 means "dynamic calcuation required"
1055 print $decl "static int hf_x11_struct_$name = -1;\n";
1056 print $reg "{ &hf_x11_struct_$name, { \"$name\", \"x11.struct.$name\", FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }},\n";
1060 static void struct_$name(tvbuff_t *tvb, int *offsetp, proto_tree *root, guint byte_order _U_, int count)
1063 for (i = 0; i < count; i++) {
1069 my $varpat = 'struct_'.$name.'_%s';
1070 my $humanpat = "struct.$name.%s";
1071 my $refs = { field => {}, sumof => {} };
1073 foreach my $e (@elements) {
1074 reference_elements($e, $refs);
1076 foreach my $e (@elements) {
1077 register_element($e, $varpat, $humanpat, $refs, "\t");
1080 my $sizecalc = $size;
1081 $size or $sizecalc = "struct_size_$name(tvb, offsetp, byte_order)";
1085 item = proto_tree_add_item(root, hf_x11_struct_$name, tvb, *offsetp, $sizecalc, ENC_NA);
1086 t = proto_item_add_subtree(item, ett_x11_rectangle);
1090 foreach my $e (@elements) {
1091 $length = dissect_element($e, $varpat, $humanpat, $length, $refs, 0, "\t");
1094 print $impl " }\n}\n";
1095 $struct{$qualname} = { size => $size, name => $name };
1100 # TODO proper dissection
1102 # Right now, the only extension to use a union is randr.
1105 my $name = $elt->att('name');
1106 my $qualname = qualname($name);
1107 $type_name{$name} = $qualname;
1109 if (defined $struct{$qualname}) {
1114 my @elements = $elt->children(qr/field/);
1117 print(" - Union $name\n");
1123 foreach my $e (@elements) {
1124 my $type = $e->att('type');
1125 my $info = getinfo($type);
1127 $info->{'size'} > 0 or die ("Error: Union containing variable sized struct $type\n");
1128 push @sizes, $info->{'size'};
1130 @sizes = sort {$b <=> $a} @sizes;
1131 my $size = $sizes[0];
1133 print $decl "static int hf_x11_union_$name = -1;\n";
1134 print $reg "{ &hf_x11_union_$name, { \"$name\", \"x11.union.$name\", FT_NONE, BASE_NONE, NULL, 0, NULL, HFILL }},\n";
1138 static void struct_$name(tvbuff_t *tvb, int *offsetp, proto_tree *root, guint byte_order, int count)
1141 int base = *offsetp;
1142 for (i = 0; i < count; i++) {
1148 my $varpat = 'union_'.$name.'_%s';
1149 my $humanpat = "union.$name.%s";
1150 my $refs = { field => {}, sumof => {} };
1152 foreach my $e (@elements) {
1153 reference_elements($e, $refs);
1155 foreach my $e (@elements) {
1156 register_element($e, $varpat, $humanpat, $refs, "\t");
1160 item = proto_tree_add_item(root, hf_x11_union_$name, tvb, base, $size, ENC_NA);
1161 t = proto_item_add_subtree(item, ett_x11_rectangle);
1166 foreach my $e (@elements) {
1167 say $impl ' *offsetp = base;';
1168 dissect_element($e, $varpat, $humanpat, 0, $refs, 0, "\t");
1170 say $impl " base += $size;";
1172 say $impl ' *offsetp = base;';
1175 $struct{$qualname} = { size => $size, name => $name };
1181 my $name = $elt->att('name');
1182 my $fullname = $incname[0].'_'.$name;
1184 $enum_name{$name} = $fullname;
1185 $enum_name{$incname[0].':'.$name} = $fullname;
1187 if (defined $enum{$fullname}) {
1192 my @elements = $elt->children('item');
1194 print(" - Enum $name\n");
1199 $enum{$fullname} = { value => $value, bit => $bit, rbit => $rbit };
1203 foreach my $e (@elements) {
1204 my $n = $e->att('name');
1205 my $valtype = $e->first_child(qr/value|bit/);
1206 if (defined $valtype) {
1207 my $val = int($valtype->text());
1208 given ($valtype->name()) {
1211 $nextvalue = $val + 1;
1213 # Ugly hack to support (temporary, hopefully) ugly
1214 # hack in xinput:ChangeDeviceProperty
1215 # Register certain values as bits also
1237 $$value{$nextvalue} = $n;
1247 my $name = $elt->att('name');
1249 print(" - Request $name\n");
1250 $request{$elt->att('opcode')} = $name;
1253 my @elements = $elt->children(qr/pad|field|list|switch/);
1255 # Wireshark defines _U_ to mean "Unused" (compiler specific define)
1259 static void $header$name(tvbuff_t *tvb _U_, packet_info *pinfo _U_, int *offsetp _U_, proto_tree *t _U_, guint byte_order _U_, int length _U_)
1266 static void $header$name(tvbuff_t *tvb, packet_info *pinfo _U_, int *offsetp, proto_tree *t, guint byte_order, int length _U_)
1271 my $varpat = $header.'_'.$name.'_%s';
1272 my $humanpat = "$header.$name.%s";
1273 my $refs = { field => {}, sumof => {} };
1275 foreach my $e (@elements) {
1276 reference_elements($e, $refs);
1278 foreach my $e (@elements) {
1279 register_element($e, $varpat, $humanpat, $refs);
1282 foreach my $e (@elements) {
1283 if ($e->name() eq 'list' && $name eq 'Render' && $e->att('name') eq 'data' && -e "$mesadir/gl_API.xml") {
1284 # Special case: Use mesa-generated dissector for 'data'
1285 print $impl " dispatch_glx_render(tvb, pinfo, offsetp, t, byte_order, (length - $length));\n";
1287 $length = dissect_element($e, $varpat, $humanpat, $length, $refs, 1);
1293 my $reply = $elt->first_child('reply');
1295 $reply{$elt->att('opcode')} = $name;
1297 $varpat = $header.'_'.$name.'_reply_%s';
1298 $humanpat = "$header.$name.reply.%s";
1300 @elements = $reply->children(qr/pad|field|list|switch/);
1302 # Wireshark defines _U_ to mean "Unused" (compiler specific define)
1304 say $impl "static void $header$name"."_Reply(tvbuff_t *tvb _U_, packet_info *pinfo, int *offsetp _U_, proto_tree *t _U_, guint byte_order _U_)\n{";
1306 say $impl "static void $header$name"."_Reply(tvbuff_t *tvb, packet_info *pinfo, int *offsetp, proto_tree *t, guint byte_order)\n{";
1308 say $impl ' int sequence_number;' if (@elements);
1310 my $refs = { field => {}, sumof => {} };
1311 foreach my $e (@elements) {
1312 reference_elements($e, $refs);
1315 say $impl ' int f_length;' if ($refs->{field}{'length'});
1316 say $impl ' int length;' if ($refs->{length});
1317 foreach my $e (@elements) {
1318 register_element($e, $varpat, $humanpat, $refs);
1322 say $impl ' col_append_fstr(pinfo->cinfo, COL_INFO, "-'.$name.'");';
1324 say $impl ' REPLY(reply);';
1328 foreach my $e (@elements) {
1329 $length = dissect_element($e, $varpat, $humanpat, $length, $refs);
1332 say $impl ' sequence_number = VALUE16(tvb, *offsetp);';
1333 say $impl ' proto_tree_add_uint_format(t, hf_x11_reply_sequencenumber, tvb, *offsetp, 2, sequence_number,';
1334 say $impl ' "sequencenumber: %d ('.$header.'-'.$name.')", sequence_number);';
1335 say $impl ' *offsetp += 2;';
1337 if ($refs->{field}{length}) {
1338 say $impl ' f_length = VALUE32(tvb, *offsetp);';
1340 if ($refs->{length}) {
1341 say $impl ' length = f_length * 4 + 32;';
1343 say $impl ' proto_tree_add_item(t, hf_x11_replylength, tvb, *offsetp, 4, byte_order);';
1344 say $impl ' *offsetp += 4;';
1357 while ($name = shift) {
1358 my $qualname = qualname($name);
1359 $simpletype{$qualname} = { size => 4, encoding => 'byte_order', type => 'FT_UINT32', base => 'BASE_HEX', get => 'VALUE32', list => 'listOfCard32', };
1360 $type_name{$name} = $qualname;
1366 my $name = $elt->att('name');
1375 my $oldname = $elt->att('oldname');
1376 my $newname = $elt->att('newname');
1377 my $qualname = qualname($newname);
1379 # Duplicate the type
1380 my $info = get_simple_info($oldname);
1382 $simpletype{$qualname} = $info;
1383 } elsif ($info = get_struct_info($oldname)) {
1384 $struct{$qualname} = $info;
1386 die ("$oldname not found while attempting to typedef $newname\n");
1388 $type_name{$newname} = $qualname;
1396 my $number = $elt->att('number');
1398 my $name = $elt->att('name');
1399 print $error " \"$header-$name\",\n";
1408 my $number = $elt->att('number');
1411 my $name = $elt->att('name');
1412 my $xge = $elt->att('xge');
1415 $genericevent{$number} = $name;
1417 $event{$number} = $name;
1421 my @elements = $elt->children(qr/pad|field|list|switch/);
1423 # Wireshark defines _U_ to mean "Unused" (compiler specific define)
1428 static void $header$name(tvbuff_t *tvb _U_, int length _U_, int *offsetp _U_, proto_tree *t _U_, guint byte_order _U_)
1433 static void $header$name(tvbuff_t *tvb _U_, int *offsetp _U_, proto_tree *t _U_, guint byte_order _U_)
1443 static void $header$name(tvbuff_t *tvb, int length _U_, int *offsetp, proto_tree *t, guint byte_order)
1450 static void $header$name(tvbuff_t *tvb, int *offsetp, proto_tree *t, guint byte_order)
1457 my $varpat = $header.'_'.$name.'_%s';
1458 my $humanpat = "$header.$name.%s";
1459 my $refs = { field => {}, sumof => {} };
1461 foreach my $e (@elements) {
1462 reference_elements($e, $refs);
1464 foreach my $e (@elements) {
1465 register_element($e, $varpat, $humanpat, $refs);
1469 say $impl " proto_tree_add_uint_format(t, hf_x11_minor_opcode, tvb, *offsetp, 2, $number,";
1470 say $impl " \"opcode: $name ($number)\");";
1471 foreach my $e (@elements) {
1472 $length = dissect_element($e, $varpat, $humanpat, $length, $refs);
1476 foreach my $e (@elements) {
1477 $length = dissect_element($e, $varpat, $humanpat, $length, $refs);
1480 say $impl " CARD16(event_sequencenumber);";
1492 my $header = $elt->att('header');
1493 unshift @incname, $header;
1503 my $include = $elt->text();
1505 print " - Import $include\n";
1506 my $xml = XML::Twig->new(
1507 start_tag_handlers => {
1508 'xcb' => \&include_start,
1511 'import' => \&include,
1512 'struct' => \&struct,
1513 'xidtype' => \&xidtype,
1514 'xidunion' => \&xidtype,
1515 'typedef' => \&typedef,
1518 end_tag_handlers => {
1519 'xcb' => \&include_end,
1521 $xml->parsefile("xcbproto/src/$include.xml") or die ("Cannot open $include.xml\n");
1529 $header = $elt->att('header');
1530 $extname = ($elt->att('extension-name') or $header);
1531 unshift @incname, $header;
1533 print("Extension $extname\n");
1536 undef %genericevent;
1544 print $error "const char *$header"."_errors[] = {\n";
1550 my $xextname = $elt->att('extension-xname');
1551 my $lookup_name = $header . "_extension_minor";
1552 my $error_name = $header . "_errors";
1553 my $event_name = $header . "_events";
1554 my $genevent_name = 'NULL';
1555 my $reply_name = $header . "_replies";
1557 print $decl "static int hf_x11_$lookup_name = -1;\n\n";
1559 print $impl "static const value_string $lookup_name"."[] = {\n";
1560 foreach my $req (sort {$a <=> $b} keys %request) {
1561 print $impl " { $req, \"$request{$req}\" },\n";
1563 print $impl " { 0, NULL }\n";
1566 say $impl "const x11_event_info $event_name".'[] = {';
1567 foreach my $e (sort {$a <=> $b} keys %event) {
1568 say $impl " { \"$header-$event{$e}\", $header$event{$e} },";
1570 say $impl ' { NULL, NULL }';
1573 if (%genericevent) {
1574 $genevent_name = $header.'_generic_events';
1575 say $impl 'static const x11_generic_event_info '.$genevent_name.'[] = {';
1577 for my $val (sort { $a <=> $b } keys %genericevent) {
1578 say $impl sprintf("\t{ %3d, %s },", $val, $header.$genericevent{$val});
1580 say $impl sprintf("\t{ %3d, NULL },", 0);
1585 print $impl "static x11_reply_info $reply_name"."[] = {\n";
1586 foreach my $e (sort {$a <=> $b} keys %reply) {
1587 print $impl " { $e, $header$reply{$e}_Reply },\n";
1589 print $impl " { 0, NULL }\n";
1592 print $reg "{ &hf_x11_$lookup_name, { \"extension-minor\", \"x11.extension-minor\", FT_UINT8, BASE_DEC, VALS($lookup_name), 0, \"minor opcode\", HFILL }},\n\n";
1596 static void dispatch_$header(tvbuff_t *tvb, packet_info *pinfo, int *offsetp, proto_tree *t, guint byte_order)
1599 minor = CARD8($lookup_name);
1600 length = REQUEST_LENGTH();
1602 col_append_fstr(pinfo->cinfo, COL_INFO, "-%s",
1603 val_to_str(minor, $lookup_name,
1604 "<Unknown opcode %d>"));
1609 foreach my $req (sort {$a <=> $b} keys %request) {
1610 print $impl " case $req:\n";
1611 print $impl "\t$header$request{$req}(tvb, pinfo, offsetp, t, byte_order, length);\n";
1612 print $impl "\tbreak;\n";
1614 say $impl " /* No need for a default case here, since Unknown is printed above,";
1615 say $impl " and UNDECODED() is taken care of by dissect_x11_request */";
1616 print $impl " }\n}\n";
1619 static void register_$header(void)
1621 set_handler("$xextname", dispatch_$header, $error_name, $event_name, $genevent_name, $reply_name);
1626 print $error " NULL\n};\n\n";
1628 push @register, $header;
1632 #my $git = `which git`;
1634 #-x $git or return 'unknown';
1637 # this will generate an error on stderr if git isn't in our $PATH
1638 # but that's OK. The version is still set to 'unknown' in that case
1639 # and at least the operator could see it.
1640 my $ver = `git --git-dir=$lib/.git describe --tags`;
1646 sub add_generated_header {
1647 my ($out, $using) = @_;
1648 my $ver = find_version($using);
1651 /* Do not modify this file. */
1652 /* It was automatically generated by $0
1653 using $using version $ver */
1656 # Since this file is checked in, add its SVN revision
1657 print $out "/* \$"."Id"."\$ */\n\n";
1662 * Copyright 2008, 2009, 2013 Open Text Corporation <pharris[AT]opentext.com>
1664 * Wireshark - Network traffic analyzer
1665 * By Gerald Combs <gerald[AT]wireshark.org>
1666 * Copyright 1998 Gerald Combs
1668 * This program is free software; you can redistribute it and/or modify
1669 * it under the terms of the GNU General Public License as published by
1670 * the Free Software Foundation; either version 2 of the License, or
1671 * (at your option) any later version.
1673 * This program is distributed in the hope that it will be useful,
1674 * but WITHOUT ANY WARRANTY; without even the implied warranty of
1675 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1676 * GNU General Public License for more details.
1678 * You should have received a copy of the GNU General Public License along
1679 * with this program; if not, write to the Free Software Foundation, Inc.,
1680 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
1687 # initialize core X11 protocol
1688 # Do this in the Makefile now
1689 #system('./process-x11-fields.pl < x11-fields');
1691 # Extension implementation
1692 $impl = new IO::File '> x11-extension-implementation.h'
1693 or die ("Cannot open x11-extension-implementation.h for writing\n");
1694 $error = new IO::File '> x11-extension-errors.h'
1695 or die ("Cannot open x11-extension-errors.h for writing\n");
1697 add_generated_header($impl, 'xcbproto');
1698 add_generated_header($error, 'xcbproto');
1700 # Open the files generated by process-x11-fields.pl for appending
1701 $reg = new IO::File '>> x11-register-info.h'
1702 or die ("Cannot open x11-register-info.h for appending\n");
1703 $decl = new IO::File '>> x11-declarations.h'
1704 or die ("Cannot open x11-declarations.h for appending\n");
1706 print $reg "\n/* Generated by $0 below this line */\n";
1707 print $decl "\n/* Generated by $0 below this line */\n";
1710 if (-e "$mesadir/gl_API.xml") {
1711 $enum = new IO::File '> x11-glx-render-enum.h'
1712 or die ("Cannot open x11-glx-render-enum.h for writing\n");
1713 add_generated_header($enum, 'mesa');
1714 print $enum "static const value_string mesa_enum[] = {\n";
1715 print $impl '#include "x11-glx-render-enum.h"'."\n\n";
1717 print("Mesa glRender:\n");
1718 $header = "glx_render";
1720 my $xml = XML::Twig->new(
1721 start_tag_handlers => {
1722 'category' => \&mesa_category_start,
1725 'category' => \&mesa_category,
1726 'enum' => \&mesa_enum,
1727 'type' => \&mesa_type,
1728 'function' => \&mesa_function,
1730 $xml->parsefile("$mesadir/gl_API.xml") or die ("Cannot open gl_API\n");
1732 print $enum " { 0, NULL }\n";
1736 print $decl "static int hf_x11_glx_render_op_name = -1;\n\n";
1738 print $impl "static const value_string glx_render_op_name"."[] = {\n";
1739 foreach my $req (sort {$a <=> $b} keys %request) {
1740 print $impl " { $req, \"gl$request{$req}\" },\n";
1742 print $impl " { 0, NULL }\n";
1745 print $reg "{ &hf_x11_glx_render_op_name, { \"render op\", \"x11.glx.render.op\", FT_UINT16, BASE_DEC, VALS(glx_render_op_name), 0, NULL, HFILL }},\n\n";
1747 # Uses ett_x11_list_of_rectangle, since I am unable to see how the subtree type matters.
1750 static void dispatch_glx_render(tvbuff_t *tvb, packet_info *pinfo, int *offsetp, proto_tree *t, guint byte_order, int length)
1752 while (length >= 4) {
1758 len = VALUE16(tvb, *offsetp);
1760 op = VALUE16(tvb, *offsetp + 2);
1761 ti = proto_tree_add_uint(t, hf_x11_glx_render_op_name, tvb, *offsetp, len, op);
1763 tt = proto_item_add_subtree(ti, ett_x11_list_of_rectangle);
1765 ti = proto_tree_add_item(tt, hf_x11_request_length, tvb, *offsetp, 2, byte_order);
1767 proto_tree_add_item(tt, hf_x11_glx_render_op_name, tvb, *offsetp, 2, byte_order);
1771 expert_add_info(pinfo, ti, &ei_x11_request_length);
1772 /* Eat the rest of the packet, mark it undecoded */
1778 next = *offsetp + len;
1783 foreach my $req (sort {$a <=> $b} keys %request) {
1784 print $impl "\tcase $req:\n";
1785 print $impl "\t mesa_$request{$req}(tvb, offsetp, tt, byte_order, len);\n";
1786 print $impl "\t break;\n";
1788 print $impl "\tdefault:\n";
1789 print $impl "\t proto_tree_add_item(tt, hf_x11_undecoded, tvb, *offsetp, len, ENC_NA);\n";
1790 print $impl "\t *offsetp += len;\n";
1792 print $impl "\t}\n";
1793 print $impl "\tif (*offsetp < next) {\n";
1794 print $impl "\t proto_tree_add_item(tt, hf_x11_unused, tvb, *offsetp, next - *offsetp, ENC_NA);\n";
1795 print $impl "\t *offsetp = next;\n";
1796 print $impl "\t}\n";
1797 print $impl "\tlength -= (len + 4);\n";
1798 print $impl " }\n}\n";
1801 $enum = new IO::File '> x11-enum.h'
1802 or die ("Cannot open x11-enum.h for writing\n");
1803 add_generated_header($enum, 'xcbproto');
1804 print $impl '#include "x11-enum.h"'."\n\n";
1807 foreach my $ext (@reslist) {
1808 my $xml = XML::Twig->new(
1809 start_tag_handlers => {
1810 'xcb' => \&xcb_start,
1814 'import' => \&include,
1815 'request' => \&request,
1816 'struct' => \&struct,
1818 'xidtype' => \&xidtype,
1819 'xidunion' => \&xidtype,
1820 'typedef' => \&typedef,
1822 'errorcopy' => \&error,
1826 $xml->parsefile($ext) or die ("Cannot open $ext\n");
1829 print $impl "static void register_x11_extensions(void)\n{\n";
1830 foreach my $reg (@register) {
1831 print $impl " register_$reg();\n";