2 * Routines for X11 dissection
3 * Copyright 2000, Christophe Tronche <ch.tronche@computer.org>
4 * Copyright 2003, Michael Shuldman
6 * Wireshark - Network traffic analyzer
7 * By Gerald Combs <gerald@wireshark.org>
8 * Copyright 1998 Gerald Combs
10 * SPDX-License-Identifier: GPL-2.0-or-later
13 /* TODO (in no particular order):
15 * - keep track of Atom creation by server to be able to display
16 * non-predefined atoms
17 * - Idem for keysym <-> keycode ???
19 * - Subtree the request ids (that is x11.create-window.window and
20 * x11.change-window.window should be distinct), and add hidden fields
21 * (so we still have x11.window).
22 * - add hidden fields so we can have x11.circulate-window in addition to
23 * x11.opcode == 13 (but you could match on x11.opcode == "CirculateWindow"
25 * - add hidden fields so we have x11.listOfStuff.length
26 * - use a faster scheme that linear list searching for the opcode.
27 * - correct display of Unicode chars.
28 * - Not everything is homogeneous, in particular the handling of items in
29 * list is a total mess.
32 /* By the way, I wrote a program to generate every request and test
33 * that stuff. If you're interested, you can get it at
34 * http://tronche.com/gui/x/
40 #include <epan/packet.h>
41 #include <epan/exceptions.h>
42 #include <epan/conversation.h>
43 #include <epan/expert.h>
44 #include <epan/show_exception.h>
45 #include <epan/prefs.h>
47 #include "packet-x11-keysymdef.h"
48 #include "packet-x11.h"
50 #include <wsutil/array.h>
51 #include <wsutil/bits_count_ones.h>
53 void proto_register_x11(void);
54 void proto_reg_handoff_x11(void);
56 static dissector_handle_t x11_handle
;
58 #define cVALS(x) (const value_string*)(x)
62 * Data structure associated with a conversation; keeps track of the
63 * request for which we're expecting a reply, the frame number of
64 * the initial connection request, and the byte order of the connection.
66 * An opcode of -3 means we haven't yet seen any requests yet.
67 * An opcode of -2 means we're not expecting a reply (unused).
68 * An opcode of -1 means we're waiting for a reply to the initial
70 * An opcode of 0 means the request was not seen (or unknown).
71 * Other values are the opcode of the request for which we're expecting
75 #define NOTHING_SEEN -3
76 #define NOTHING_EXPECTED -2
77 #define INITIAL_CONN -1
78 #define UNKNOWN_OPCODE 0
80 #define MAX_OPCODES (255 + 1) /* 255 + INITIAL_CONN */
81 #define LastExtensionError 255
82 #define LastExtensionEvent 127
84 #define BYTE_ORDER_UNKNOWN 0xFFFFFFFF
86 static const char *modifiers
[] = {
97 /* Keymasks. From <X11/X.h>. */
98 #define ShiftMask (1<<0)
99 #define LockMask (1<<1)
100 #define ControlMask (1<<2)
101 #define Mod1Mask (1<<3)
102 #define Mod2Mask (1<<4)
103 #define Mod3Mask (1<<5)
104 #define Mod4Mask (1<<6)
105 #define Mod5Mask (1<<7)
107 static const int modifiermask
[] = { ShiftMask
, LockMask
, ControlMask
,
108 Mod1Mask
, Mod2Mask
, Mod3Mask
, Mod4Mask
, Mod5Mask
};
111 #define NoSymbol 0L /* special KeySym */
113 typedef struct _x11_conv_data
{
114 wmem_map_t
*seqtable
; /* hashtable of sequencenumber <-> opcode. */
115 wmem_map_t
*valtable
; /* hashtable of sequencenumber <-> &opcode_vals */
116 /* major opcodes including extensions (NULL terminated) */
117 value_string opcode_vals
[MAX_OPCODES
+1];
118 /* error codes including extensions (NULL terminated) */
119 value_string errorcode_vals
[LastExtensionError
+ 2];
120 /* event codes including extensions (NULL terminated) */
121 value_string eventcode_vals
[LastExtensionEvent
+ 2];
122 wmem_map_t
*eventcode_funcs
; /* hashtable of eventcode <-> dissect_event() */
123 wmem_map_t
*reply_funcs
; /* hashtable of opcode <-> dissect_reply() */
125 int sequencenumber
; /* sequencenumber of current packet. */
126 uint32_t iconn_frame
; /* frame # of initial connection request */
127 uint32_t iconn_reply
; /* frame # of initial connection reply */
128 unsigned byte_order
; /* byte order of connection */
129 bool resync
; /* resynchronization of sequence number performed */
131 int *keycodemap
[256]; /* keycode to keysymvalue map. */
132 int keysyms_per_keycode
;
134 int *modifiermap
[array_length(modifiers
)];/* modifier to keycode.*/
135 int keycodes_per_modifier
;
140 } GetKeyboardMapping
;
144 static wmem_map_t
*extension_table
; /* hashtable of extension name <-> dispatch function */
145 static wmem_map_t
*event_table
; /* hashtable of extension name <-> event info list */
146 static wmem_map_t
*genevent_table
; /* hashtable of extension name <-> generic event info list */
147 static wmem_map_t
*error_table
; /* hashtable of extension name <-> error list */
148 static wmem_map_t
*reply_table
; /* hashtable of extension name <-> reply list */
150 /* Initialize the protocol and registered fields */
151 static int proto_x11
;
153 #include "x11-declarations.h"
155 /* Initialize the subtree pointers */
157 static int ett_x11_color_flags
;
158 static int ett_x11_list_of_arc
;
159 static int ett_x11_arc
;
160 static int ett_x11_list_of_atom
;
161 static int ett_x11_list_of_card32
;
162 static int ett_x11_list_of_float
;
163 static int ett_x11_list_of_double
;
164 static int ett_x11_list_of_color_item
;
165 static int ett_x11_color_item
;
166 static int ett_x11_list_of_keycode
;
167 static int ett_x11_list_of_keysyms
;
168 static int ett_x11_keysym
;
169 static int ett_x11_list_of_point
;
170 static int ett_x11_point
;
171 static int ett_x11_list_of_rectangle
;
172 static int ett_x11_rectangle
;
173 static int ett_x11_list_of_segment
;
174 static int ett_x11_segment
;
175 static int ett_x11_list_of_string8
;
176 static int ett_x11_list_of_text_item
;
177 static int ett_x11_text_item
;
178 static int ett_x11_gc_value_mask
; /* XXX - unused */
179 static int ett_x11_event_mask
; /* XXX - unused */
180 static int ett_x11_do_not_propagate_mask
; /* XXX - unused */
181 static int ett_x11_set_of_key_mask
;
182 static int ett_x11_pointer_event_mask
; /* XXX - unused */
183 static int ett_x11_window_value_mask
; /* XXX - unused */
184 static int ett_x11_configure_window_mask
; /* XXX - unused */
185 static int ett_x11_keyboard_value_mask
; /* XXX - unused */
186 static int ett_x11_same_screen_focus
;
187 static int ett_x11_event
;
188 static int ett_x11_list_of_pixmap_format
;
189 static int ett_x11_pixmap_format
;
190 static int ett_x11_list_of_screen
;
191 static int ett_x11_screen
;
192 static int ett_x11_list_of_depth_detail
;
193 static int ett_x11_depth_detail
;
194 static int ett_x11_list_of_visualtype
;
195 static int ett_x11_visualtype
;
197 static expert_field ei_x11_invalid_format
;
198 static expert_field ei_x11_request_length
;
199 static expert_field ei_x11_keycode_value_out_of_range
;
201 /* desegmentation of X11 messages */
202 static bool x11_desegment
= true;
204 #define DEFAULT_X11_PORT_RANGE "6000-6063"
207 * Round a length to a multiple of 4 bytes.
209 #define ROUND_LENGTH(n) ((((n) + 3)/4) * 4)
211 /************************************************************************
213 *** E N U M T A B L E S D E F I N I T I O N S ***
215 ************************************************************************/
217 static const value_string byte_order_vals
[] = {
218 { 'B', "Big-endian" },
219 { 'l', "Little-endian" },
223 static const value_string image_byte_order_vals
[] = {
229 static const value_string access_mode_vals
[] = {
235 static const value_string all_temporary_vals
[] = {
236 { 0, "AllTemporary" },
240 static const value_string alloc_vals
[] = {
246 static const value_string allow_events_mode_vals
[] = {
247 { 0, "AsyncPointer" },
248 { 1, "SyncPointer" },
249 { 2, "ReplayPointer" },
250 { 3, "AsyncKeyboard" },
251 { 4, "SyncKeyboard" },
252 { 5, "ReplayKeyboard" },
258 static const value_string arc_mode_vals
[] = {
264 static const char *atom_predefined_interpretation
[] = {
316 "UNDERLINE_POSITION",
317 "UNDERLINE_THICKNESS",
336 static const value_string auto_repeat_mode_vals
[] = {
343 static const value_string background_pixmap_vals
[] = {
345 { 1, "ParentRelative" },
349 static const value_string backing_store_vals
[] = {
356 static const value_string border_pixmap_vals
[] = {
357 { 0, "CopyFromParent" },
361 static const value_string button_vals
[] = {
362 { 0x8000, "AnyButton" },
366 static const value_string cap_style_vals
[] = {
374 static const value_string class_vals
[] = {
381 static const value_string close_down_mode_vals
[] = {
383 { 1, "RetainPermanent" },
384 { 2, "RetainTemporary" },
388 static const value_string colormap_state_vals
[] = {
389 { 0, "Uninstalled" },
394 static const value_string coordinate_mode_vals
[] = {
400 static const value_string destination_vals
[] = {
401 { 0, "PointerWindow" },
406 static const value_string direction_vals
[] = {
407 { 0, "RaiseLowest" },
408 { 1, "LowerHighest" },
412 static const value_string event_detail_vals
[] = {
417 { 4, "NonlinearVirtual" },
421 #define FAMILY_INTERNET 0
422 #define FAMILY_DECNET 1
423 #define FAMILY_CHAOS 2
425 static const value_string family_vals
[] = {
426 { FAMILY_INTERNET
, "Internet" },
427 { FAMILY_DECNET
, "DECnet" },
428 { FAMILY_CHAOS
, "Chaos" },
432 static const value_string fill_rule_vals
[] = {
438 static const value_string fill_style_vals
[] = {
442 { 3, "OpaqueStippled" },
446 static const value_string focus_detail_vals
[] = {
451 { 4, "NonlinearVirtual" },
453 { 6, "PointerRoot" },
458 static const value_string focus_mode_vals
[] = {
462 { 3, "WhileGrabbed" },
466 static const value_string focus_vals
[] = {
468 { 1, "PointerRoot" },
472 static const value_string function_vals
[] = {
477 { 4, "AndInverted" },
485 { 12, "CopyInverted" },
486 { 13, "OrInverted" },
492 static const value_string grab_mode_vals
[] = {
499 static const value_string grab_status_vals
[] = {
501 { 1, "AlreadyGrabbed" },
502 { 2, "InvalidTime" },
503 { 3, "NotViewable" },
508 static const value_string bit_gravity_vals
[] = {
523 static const value_string win_gravity_vals
[] = {
538 static const value_string image_format_vals
[] = {
545 static const value_string image_pixmap_format_vals
[] = {
551 static const value_string join_style_vals
[] = {
558 static const value_string key_vals
[] = {
563 #include "x11-keysym.h"
565 static const value_string line_style_vals
[] = {
572 static const value_string mode_vals
[] = {
579 static const value_string on_off_vals
[] = {
585 static const value_string place_vals
[] = {
591 static const value_string property_state_vals
[] = {
597 static const value_string visibility_state_vals
[] = {
599 { 1, "PartiallyObscured" },
600 { 2, "FullyObscured" },
604 static const value_string mapping_request_vals
[] = {
605 { 0, "MappingModifier" },
606 { 1, "MappingKeyboard" },
607 { 2, "MappingPointer" },
611 /* Requestcodes. From <X11/Xproto.h>. */
612 #define X_CreateWindow 1
613 #define X_ChangeWindowAttributes 2
614 #define X_GetWindowAttributes 3
615 #define X_DestroyWindow 4
616 #define X_DestroySubwindows 5
617 #define X_ChangeSaveSet 6
618 #define X_ReparentWindow 7
619 #define X_MapWindow 8
620 #define X_MapSubwindows 9
621 #define X_UnmapWindow 10
622 #define X_UnmapSubwindows 11
623 #define X_ConfigureWindow 12
624 #define X_CirculateWindow 13
625 #define X_GetGeometry 14
626 #define X_QueryTree 15
627 #define X_InternAtom 16
628 #define X_GetAtomName 17
629 #define X_ChangeProperty 18
630 #define X_DeleteProperty 19
631 #define X_GetProperty 20
632 #define X_ListProperties 21
633 #define X_SetSelectionOwner 22
634 #define X_GetSelectionOwner 23
635 #define X_ConvertSelection 24
636 #define X_SendEvent 25
637 #define X_GrabPointer 26
638 #define X_UngrabPointer 27
639 #define X_GrabButton 28
640 #define X_UngrabButton 29
641 #define X_ChangeActivePointerGrab 30
642 #define X_GrabKeyboard 31
643 #define X_UngrabKeyboard 32
645 #define X_UngrabKey 34
646 #define X_AllowEvents 35
647 #define X_GrabServer 36
648 #define X_UngrabServer 37
649 #define X_QueryPointer 38
650 #define X_GetMotionEvents 39
651 #define X_TranslateCoords 40
652 #define X_WarpPointer 41
653 #define X_SetInputFocus 42
654 #define X_GetInputFocus 43
655 #define X_QueryKeymap 44
656 #define X_OpenFont 45
657 #define X_CloseFont 46
658 #define X_QueryFont 47
659 #define X_QueryTextExtents 48
660 #define X_ListFonts 49
661 #define X_ListFontsWithInfo 50
662 #define X_SetFontPath 51
663 #define X_GetFontPath 52
664 #define X_CreatePixmap 53
665 #define X_FreePixmap 54
666 #define X_CreateGC 55
667 #define X_ChangeGC 56
669 #define X_SetDashes 58
670 #define X_SetClipRectangles 59
672 #define X_ClearArea 61
673 #define X_CopyArea 62
674 #define X_CopyPlane 63
675 #define X_PolyPoint 64
676 #define X_PolyLine 65
677 #define X_PolySegment 66
678 #define X_PolyRectangle 67
680 #define X_FillPoly 69
681 #define X_PolyFillRectangle 70
682 #define X_PolyFillArc 71
683 #define X_PutImage 72
684 #define X_GetImage 73
685 #define X_PolyText8 74
686 #define X_PolyText16 75
687 #define X_ImageText8 76
688 #define X_ImageText16 77
689 #define X_CreateColormap 78
690 #define X_FreeColormap 79
691 #define X_CopyColormapAndFree 80
692 #define X_InstallColormap 81
693 #define X_UninstallColormap 82
694 #define X_ListInstalledColormaps 83
695 #define X_AllocColor 84
696 #define X_AllocNamedColor 85
697 #define X_AllocColorCells 86
698 #define X_AllocColorPlanes 87
699 #define X_FreeColors 88
700 #define X_StoreColors 89
701 #define X_StoreNamedColor 90
702 #define X_QueryColors 91
703 #define X_LookupColor 92
704 #define X_CreateCursor 93
705 #define X_CreateGlyphCursor 94
706 #define X_FreeCursor 95
707 #define X_RecolorCursor 96
708 #define X_QueryBestSize 97
709 #define X_QueryExtension 98
710 #define X_ListExtensions 99
711 #define X_ChangeKeyboardMapping 100
712 #define X_GetKeyboardMapping 101
713 #define X_ChangeKeyboardControl 102
714 #define X_GetKeyboardControl 103
716 #define X_ChangePointerControl 105
717 #define X_GetPointerControl 106
718 #define X_SetScreenSaver 107
719 #define X_GetScreenSaver 108
720 #define X_ChangeHosts 109
721 #define X_ListHosts 110
722 #define X_SetAccessControl 111
723 #define X_SetCloseDownMode 112
724 #define X_KillClient 113
725 #define X_RotateProperties 114
726 #define X_ForceScreenSaver 115
727 #define X_SetPointerMapping 116
728 #define X_GetPointerMapping 117
729 #define X_SetModifierMapping 118
730 #define X_GetModifierMapping 119
731 #define X_NoOperation 127
732 #define X_FirstExtension 128
733 #define X_LastExtension 255
735 static const value_string opcode_vals
[] = {
736 { INITIAL_CONN
, "Initial connection request" },
737 { X_CreateWindow
, "CreateWindow" },
738 { X_ChangeWindowAttributes
, "ChangeWindowAttributes" },
739 { X_GetWindowAttributes
, "GetWindowAttributes" },
740 { X_DestroyWindow
, "DestroyWindow" },
741 { X_DestroySubwindows
, "DestroySubwindows" },
742 { X_ChangeSaveSet
, "ChangeSaveSet" },
743 { X_ReparentWindow
, "ReparentWindow" },
744 { X_MapWindow
, "MapWindow" },
745 { X_MapSubwindows
, "MapSubwindows" },
746 { X_UnmapWindow
, "UnmapWindow" },
747 { X_UnmapSubwindows
, "UnmapSubwindows" },
748 { X_ConfigureWindow
, "ConfigureWindow" },
749 { X_CirculateWindow
, "CirculateWindow" },
750 { X_GetGeometry
, "GetGeometry" },
751 { X_QueryTree
, "QueryTree" },
752 { X_InternAtom
, "InternAtom" },
753 { X_GetAtomName
, "GetAtomName" },
754 { X_ChangeProperty
, "ChangeProperty" },
755 { X_DeleteProperty
, "DeleteProperty" },
756 { X_GetProperty
, "GetProperty" },
757 { X_ListProperties
, "ListProperties" },
758 { X_SetSelectionOwner
, "SetSelectionOwner" },
759 { X_GetSelectionOwner
, "GetSelectionOwner" },
760 { X_ConvertSelection
, "ConvertSelection" },
761 { X_SendEvent
, "SendEvent" },
762 { X_GrabPointer
, "GrabPointer" },
763 { X_UngrabPointer
, "UngrabPointer" },
764 { X_GrabButton
, "GrabButton" },
765 { X_UngrabButton
, "UngrabButton" },
766 { X_ChangeActivePointerGrab
, "ChangeActivePointerGrab" },
767 { X_GrabKeyboard
, "GrabKeyboard" },
768 { X_UngrabKeyboard
, "UngrabKeyboard" },
769 { X_GrabKey
, "GrabKey" },
770 { X_UngrabKey
, "UngrabKey" },
771 { X_AllowEvents
, "AllowEvents" },
772 { X_GrabServer
, "GrabServer" },
773 { X_UngrabServer
, "UngrabServer" },
774 { X_QueryPointer
, "QueryPointer" },
775 { X_GetMotionEvents
, "GetMotionEvents" },
776 { X_TranslateCoords
, "TranslateCoordinates" },
777 { X_WarpPointer
, "WarpPointer" },
778 { X_SetInputFocus
, "SetInputFocus" },
779 { X_GetInputFocus
, "GetInputFocus" },
780 { X_QueryKeymap
, "QueryKeymap" },
781 { X_OpenFont
, "OpenFont" },
782 { X_CloseFont
, "CloseFont" },
783 { X_QueryFont
, "QueryFont" },
784 { X_QueryTextExtents
, "QueryTextExtents" },
785 { X_ListFonts
, "ListFonts" },
786 { X_ListFontsWithInfo
, "ListFontsWithInfo" },
787 { X_SetFontPath
, "SetFontPath" },
788 { X_GetFontPath
, "GetFontPath" },
789 { X_CreatePixmap
, "CreatePixmap" },
790 { X_FreePixmap
, "FreePixmap" },
791 { X_CreateGC
, "CreateGC" },
792 { X_ChangeGC
, "ChangeGC" },
793 { X_CopyGC
, "CopyGC" },
794 { X_SetDashes
, "SetDashes" },
795 { X_SetClipRectangles
, "SetClipRectangles" },
796 { X_FreeGC
, "FreeGC" },
797 { X_ClearArea
, "ClearArea" },
798 { X_CopyArea
, "CopyArea" },
799 { X_CopyPlane
, "CopyPlane" },
800 { X_PolyPoint
, "PolyPoint" },
801 { X_PolyLine
, "PolyLine" },
802 { X_PolySegment
, "PolySegment" },
803 { X_PolyRectangle
, "PolyRectangle" },
804 { X_PolyArc
, "PolyArc" },
805 { X_FillPoly
, "FillPoly" },
806 { X_PolyFillRectangle
, "PolyFillRectangle" },
807 { X_PolyFillArc
, "PolyFillArc" },
808 { X_PutImage
, "PutImage" },
809 { X_GetImage
, "GetImage" },
810 { X_PolyText8
, "PolyText8" },
811 { X_PolyText16
, "PolyText16" },
812 { X_ImageText8
, "ImageText8" },
813 { X_ImageText16
, "ImageText16" },
814 { X_CreateColormap
, "CreateColormap" },
815 { X_FreeColormap
, "FreeColormap" },
816 { X_CopyColormapAndFree
, "CopyColormapAndFree" },
817 { X_InstallColormap
, "InstallColormap" },
818 { X_UninstallColormap
, "UninstallColormap" },
819 { X_ListInstalledColormaps
, "ListInstalledColormaps" },
820 { X_AllocColor
, "AllocColor" },
821 { X_AllocNamedColor
, "AllocNamedColor" },
822 { X_AllocColorCells
, "AllocColorCells" },
823 { X_AllocColorPlanes
, "AllocColorPlanes" },
824 { X_FreeColors
, "FreeColors" },
825 { X_StoreColors
, "StoreColors" },
826 { X_StoreNamedColor
, "StoreNamedColor" },
827 { X_QueryColors
, "QueryColors" },
828 { X_LookupColor
, "LookupColor" },
829 { X_CreateCursor
, "CreateCursor" },
830 { X_CreateGlyphCursor
, "CreateGlyphCursor" },
831 { X_FreeCursor
, "FreeCursor" },
832 { X_RecolorCursor
, "RecolorCursor" },
833 { X_QueryBestSize
, "QueryBestSize" },
834 { X_QueryExtension
, "QueryExtension" },
835 { X_ListExtensions
, "ListExtensions" },
836 { X_ChangeKeyboardMapping
, "ChangeKeyboardMapping" },
837 { X_GetKeyboardMapping
, "GetKeyboardMapping" },
838 { X_ChangeKeyboardControl
, "ChangeKeyboardControl" },
839 { X_GetKeyboardControl
, "GetKeyboardControl" },
841 { X_ChangePointerControl
, "ChangePointerControl" },
842 { X_GetPointerControl
, "GetPointerControl" },
843 { X_SetScreenSaver
, "SetScreenSaver" },
844 { X_GetScreenSaver
, "GetScreenSaver" },
845 { X_ChangeHosts
, "ChangeHosts" },
846 { X_ListHosts
, "ListHosts" },
847 { X_SetAccessControl
, "SetAccessControl" },
848 { X_SetCloseDownMode
, "SetCloseDownMode" },
849 { X_KillClient
, "KillClient" },
850 { X_RotateProperties
, "RotateProperties" },
851 { X_ForceScreenSaver
, "ForceScreenSaver" },
852 { X_SetPointerMapping
, "SetPointerMapping" },
853 { X_GetPointerMapping
, "GetPointerMapping" },
854 { X_SetModifierMapping
, "SetModifierMapping" },
855 { X_GetModifierMapping
, "GetModifierMapping" },
856 { X_NoOperation
, "NoOperation" },
860 /* Eventscodes. From <X11/X.h>. */
863 #define ButtonPress 4
864 #define ButtonRelease 5
865 #define MotionNotify 6
866 #define EnterNotify 7
867 #define LeaveNotify 8
870 #define KeymapNotify 11
872 #define GraphicsExpose 13
874 #define VisibilityNotify 15
875 #define CreateNotify 16
876 #define DestroyNotify 17
877 #define UnmapNotify 18
879 #define MapRequest 20
880 #define ReparentNotify 21
881 #define ConfigureNotify 22
882 #define ConfigureRequest 23
883 #define GravityNotify 24
884 #define ResizeRequest 25
885 #define CirculateNotify 26
886 #define CirculateRequest 27
887 #define PropertyNotify 28
888 #define SelectionClear 29
889 #define SelectionRequest 30
890 #define SelectionNotify 31
891 #define ColormapNotify 32
892 #define ClientMessage 33
893 #define MappingNotify 34
894 #define GenericEvent 35
896 static const value_string eventcode_vals
[] = {
897 { KeyPress
, "KeyPress" },
898 { KeyRelease
, "KeyRelease" },
899 { ButtonPress
, "ButtonPress" },
900 { ButtonRelease
, "ButtonRelease" },
901 { MotionNotify
, "MotionNotify" },
902 { EnterNotify
, "EnterNotify" },
903 { LeaveNotify
, "LeaveNotify" },
904 { FocusIn
, "FocusIn" },
905 { FocusOut
, "FocusOut" },
906 { KeymapNotify
, "KeymapNotify" },
907 { Expose
, "Expose" },
908 { GraphicsExpose
, "GraphicsExpose" },
909 { NoExpose
, "NoExpose" },
910 { VisibilityNotify
, "VisibilityNotify" },
911 { CreateNotify
, "CreateNotify" },
912 { DestroyNotify
, "DestroyNotify" },
913 { UnmapNotify
, "UnmapNotify" },
914 { MapNotify
, "MapNotify" },
915 { MapRequest
, "MapRequest" },
916 { ReparentNotify
, "ReparentNotify" },
917 { ConfigureNotify
, "ConfigureNotify" },
918 { ConfigureRequest
, "ConfigureRequest" },
919 { GravityNotify
, "GravityNotify" },
920 { ResizeRequest
, "ResizeRequest" },
921 { CirculateNotify
, "CirculateNotify" },
922 { CirculateRequest
, "CirculateRequest" },
923 { PropertyNotify
, "PropertyNotify" },
924 { SelectionClear
, "SelectionClear" },
925 { SelectionRequest
, "SelectionRequest" },
926 { SelectionNotify
, "SelectionNotify" },
927 { ColormapNotify
, "ColormapNotify" },
928 { ClientMessage
, "ClientMessage" },
929 { MappingNotify
, "MappingNotify" },
930 { GenericEvent
, "GenericEvent" },
934 /* Errorcodes. From <X11/X.h> */
935 #define Success 0 /* everything's okay */
936 #define BadRequest 1 /* bad request code */
937 #define BadValue 2 /* int parameter out of range */
938 #define BadWindow 3 /* parameter not a Window */
939 #define BadPixmap 4 /* parameter not a Pixmap */
940 #define BadAtom 5 /* parameter not an Atom */
941 #define BadCursor 6 /* parameter not a Cursor */
942 #define BadFont 7 /* parameter not a Font */
943 #define BadMatch 8 /* parameter mismatch */
944 #define BadDrawable 9 /* parameter not a Pixmap or Window */
945 #define BadAccess 10 /* depending on context:
946 - key/button already grabbed
947 - attempt to free an illegal
949 - attempt to store into a read-only
951 - attempt to modify the access control
952 list from other than the local host.
954 #define BadAlloc 11 /* insufficient resources */
955 #define BadColormap 12 /* no such colormap */
956 #define BadGC 13 /* parameter not a GC */
957 #define BadIDChoice 14 /* choice not in range or already used */
958 #define BadName 15 /* font or color name doesn't exist */
959 #define BadLength 16 /* Request length incorrect */
960 #define BadImplementation 17 /* server is defective */
962 static const value_string errorcode_vals
[] = {
963 { Success
, "Success" },
964 { BadRequest
, "BadRequest" },
965 { BadValue
, "BadValue" },
966 { BadWindow
, "BadWindow" },
967 { BadPixmap
, "BadPixmap" },
968 { BadAtom
, "BadAtom" },
969 { BadCursor
, "BadCursor" },
970 { BadFont
, "BadFont" },
971 { BadMatch
, "BadMatch" },
972 { BadDrawable
, "BadDrawable" },
973 { BadAccess
, "BadAccess" },
974 { BadAlloc
, "BadAlloc" },
975 { BadColormap
, "BadColormap" },
977 { BadIDChoice
, "BadIDChoice" },
978 { BadName
, "BadName" },
979 { BadLength
, "BadLength" },
980 { BadImplementation
, "BadImplementation" },
984 static const value_string ordering_vals
[] = {
992 static const value_string plane_mask_vals
[] = {
993 { 0xFFFFFFFF, "AllPlanes" },
997 static const value_string pointer_keyboard_mode_vals
[] = {
998 { 0, "Synchronous" },
999 { 1, "Asynchronous" },
1003 static const value_string revert_to_vals
[] = {
1005 { 1, "PointerRoot" },
1010 static const value_string insert_delete_vals
[] = {
1016 static const value_string screen_saver_mode_vals
[] = {
1022 static const value_string shape_vals
[] = {
1029 static const value_string stack_mode_vals
[] = {
1038 static const value_string subwindow_mode_vals
[] = {
1039 { 0, "ClipByChildren" },
1040 { 1, "IncludeInferiors" },
1044 static const value_string window_class_vals
[] = {
1045 { 0, "CopyFromParent" },
1046 { 1, "InputOutput" },
1051 static const value_string yes_no_default_vals
[] = {
1058 static const value_string zero_is_any_property_type_vals
[] = {
1059 { 0, "AnyPropertyType" },
1063 static const value_string zero_is_none_vals
[] = {
1068 /************************************************************************
1070 *** F I E L D D E C O D I N G M A C R O S ***
1072 ************************************************************************/
1073 #define FIELD8(name) (field8(tvb, offsetp, t, hf_x11_##name, byte_order))
1074 #define FIELD16(name) (field16(tvb, offsetp, t, hf_x11_##name, byte_order))
1075 #define FIELD32(name) (field32(tvb, offsetp, t, hf_x11_##name, byte_order))
1077 #define FLAG(position, name) {\
1078 proto_tree_add_boolean(bitmask_tree, hf_x11_##position##_mask##_##name, tvb, bitmask_offset, bitmask_size, bitmask_value); }
1080 #define FLAG_IF_NONZERO(position, name) do {\
1081 if (bitmask_value & proto_registrar_get_nth(hf_x11_##position##_mask##_##name) -> bitmask) \
1082 proto_tree_add_boolean(bitmask_tree, hf_x11_##position##_mask##_##name, tvb, bitmask_offset, bitmask_size, bitmask_value); } while (0)
1084 #define ATOM(name) { atom(tvb, offsetp, t, hf_x11_##name, byte_order); }
1085 #define BOOL(name) (add_boolean(tvb, offsetp, t, hf_x11_##name))
1086 #define BUTTON(name) FIELD8(name)
1087 #define CARD8(name) FIELD8(name)
1088 #define CARD16(name) (FIELD16(name))
1089 #define CARD32(name) (FIELD32(name))
1090 #define COLOR_FLAGS(name) colorFlags(tvb, offsetp, t)
1091 #define COLORMAP(name) FIELD32(name)
1092 #define CURSOR(name) FIELD32(name)
1093 #define DRAWABLE(name) FIELD32(name)
1094 #define ENUM8(name) (FIELD8(name))
1095 #define ENUM16(name) (FIELD16(name))
1096 #define FONT(name) FIELD32(name)
1097 #define FONTABLE(name) FIELD32(name)
1098 #define GCONTEXT(name) FIELD32(name)
1099 #define INT8(name) FIELD8(name)
1100 #define INT16(name) FIELD16(name)
1101 #define INT32(name) FIELD32(name)
1102 #define KEYCODE(name) FIELD8(name)
1103 #define KEYCODE_DECODED(name, keycode, mask) do { \
1104 proto_tree_add_uint_format(t, hf_x11_##name, tvb, offset, 1, \
1105 keycode, "keycode: %d (%s)", \
1106 keycode, keycode2keysymString(state->keycodemap, \
1107 state->first_keycode, state->keysyms_per_keycode, \
1108 state->modifiermap, state->keycodes_per_modifier, \
1112 #define EVENT() do { \
1113 tvbuff_t *next_tvb; \
1114 unsigned char eventcode; \
1116 proto_tree *event_proto_tree; \
1117 next_tvb = tvb_new_subset_length_caplen(tvb, offset, next_offset - offset, \
1118 next_offset - offset); \
1119 eventcode = tvb_get_uint8(next_tvb, 0); \
1120 sent = (eventcode & 0x80) ? "Sent-" : ""; \
1121 event_proto_tree = proto_tree_add_subtree_format(t, next_tvb, \
1122 0, -1, ett_x11_event, NULL, \
1125 val_to_str(eventcode & 0x7F, \
1126 state->eventcode_vals, \
1127 "<Unknown eventcode %u>")); \
1128 decode_x11_event(next_tvb, eventcode, sent, event_proto_tree, \
1129 state, byte_order); \
1130 offset = next_offset; \
1133 #define LISTofARC(name) { listOfArc(tvb, offsetp, t, hf_x11_##name, (next_offset - *offsetp) / 12, byte_order); }
1134 #define LISTofATOM(name, length) { listOfAtom(tvb, offsetp, t, hf_x11_##name, (length) / 4, byte_order); }
1135 #define LISTofBYTE(name, length) { listOfByte(tvb, offsetp, t, hf_x11_##name, (length), byte_order); }
1136 #define LISTofCARD8(name, length) { listOfByte(tvb, offsetp, t, hf_x11_##name, (length), byte_order); }
1137 #define LISTofIPADDRESS(name, length) { listOfByte(tvb, offsetp, t, hf_x11_##name, (length), false); }
1138 #define LISTofCARD16(name, length) { listOfCard16(tvb, offsetp, t, hf_x11_##name, hf_x11_##name##_item, (length) / 2, byte_order); }
1139 #define LISTofCARD32(name, length) { listOfCard32(tvb, offsetp, t, hf_x11_##name, hf_x11_##name##_item, (length) / 4, byte_order); }
1140 #define LISTofCOLORITEM(name, length) { listOfColorItem(tvb, offsetp, t, hf_x11_##name, (length) / 12, byte_order); }
1141 #define LISTofKEYCODE(map, name, length) { listOfKeycode(tvb, offsetp, t, hf_x11_##name, map, (length), byte_order); }
1142 #define LISTofKEYSYM(name, map, keycode_first, keycode_count, \
1143 keysyms_per_keycode) {\
1144 listOfKeysyms(tvb, pinfo, offsetp, t, hf_x11_##name, hf_x11_##name##_item, map, (keycode_first), (keycode_count), (keysyms_per_keycode), byte_order); }
1145 #define LISTofPOINT(name, length) { listOfPoint(tvb, offsetp, t, hf_x11_##name, (length) / 4, byte_order); }
1146 #define LISTofRECTANGLE(name) { listOfRectangle(tvb, offsetp, t, hf_x11_##name, (next_offset - *offsetp) / 8, byte_order); }
1147 #define LISTofPIXMAPFORMAT(name, length) { listOfPixmapFormat(tvb, offsetp, t, hf_x11_##name, (length), byte_order); }
1148 #define LISTofSCREEN(name, length) { listOfScreen(tvb, offsetp, t, hf_x11_##name, (length), byte_order); }
1149 #define LISTofSEGMENT(name) { listOfSegment(tvb, offsetp, t, hf_x11_##name, (next_offset - *offsetp) / 8, byte_order); }
1150 #define LISTofSTRING8(name, length) { listOfString8(tvb, offsetp, t, hf_x11_##name, hf_x11_##name##_string, (length), byte_order); }
1151 #define LISTofTEXTITEM8(name) { listOfTextItem(tvb, offsetp, t, hf_x11_##name, false, next_offset, byte_order); }
1152 #define LISTofTEXTITEM16(name) { listOfTextItem(tvb, offsetp, t, hf_x11_##name, true, next_offset, byte_order); }
1153 #define OPCODE() { \
1154 opcode = tvb_get_uint8(tvb, *offsetp); \
1155 proto_tree_add_uint(t, hf_x11_opcode, tvb, *offsetp, \
1160 #define PIXMAP(name) { FIELD32(name); }
1161 #define REQUEST_LENGTH() (requestLength(tvb, offsetp, t, byte_order))
1162 #define SETofEVENT(name) { setOfEvent(tvb, offsetp, t, byte_order); }
1163 #define SETofDEVICEEVENT(name) { setOfDeviceEvent(tvb, offsetp, t, byte_order);}
1164 #define SETofKEYMASK(name) { setOfKeyButMask(tvb, offsetp, t, byte_order, 0); }
1165 #define SETofKEYBUTMASK(name) { setOfKeyButMask(tvb, offsetp, t, byte_order, 1); }
1166 #define SETofPOINTEREVENT(name) { setOfPointerEvent(tvb, offsetp, t, byte_order); }
1167 #define STRING8(name, length) { string8(tvb, offsetp, t, hf_x11_##name, length); }
1168 #define STRING16(name, length) { string16(tvb, offsetp, t, hf_x11_##name, hf_x11_##name##_bytes, length, byte_order); }
1169 #define TIMESTAMP(name){ timestamp(tvb, offsetp, t, hf_x11_##name, byte_order); }
1170 #define UNDECODED(x) { proto_tree_add_item(t, hf_x11_undecoded, tvb, *offsetp, x, ENC_NA); *offsetp += x; }
1171 #define PAD() { if (next_offset - *offsetp > 0) proto_tree_add_item(t, hf_x11_unused, tvb, *offsetp, next_offset - *offsetp, ENC_NA); *offsetp = next_offset; }
1172 #define WINDOW(name) { FIELD32(name); }
1174 #define VISUALID(name) { int32_t v = tvb_get_uint32(tvb, *offsetp, byte_order); \
1175 proto_tree_add_uint_format(t, hf_x11_##name, tvb, *offsetp, 4, v, "Visualid: 0x%08x%s", v, \
1176 v ? "" : " (CopyFromParent)"); *offsetp += 4; }
1177 #define REPLY(name) FIELD8(name);
1178 #define REPLYLENGTH(name) FIELD32(name);
1180 #define EVENTCONTENTS_COMMON() do { \
1182 WINDOW(rootwindow); \
1183 WINDOW(eventwindow); \
1184 WINDOW(childwindow); \
1189 setOfKeyButMask(tvb, offsetp, t, byte_order, 1); \
1192 #define SEQUENCENUMBER_REPLY(name) do { \
1195 seqno = tvb_get_uint16(tvb, *offsetp, byte_order); \
1196 proto_tree_add_uint_format(t, hf_x11_reply_##name, tvb, \
1197 *offsetp, 2, seqno, \
1198 "sequencenumber: %d (%s)", \
1200 val_to_str(opcode & 0xFF, state->opcode_vals, "<Unknown opcode %d>")); \
1204 #define REPLYCONTENTS_COMMON() do { \
1206 proto_tree_add_item(t, hf_x11_undecoded, tvb, *offsetp, \
1209 SEQUENCENUMBER_REPLY(sequencenumber); \
1210 REPLYLENGTH(replylength); \
1211 proto_tree_add_item(t, hf_x11_undecoded, tvb, *offsetp, \
1212 tvb_reported_length_remaining(tvb, *offsetp), ENC_NA); \
1213 *offsetp += tvb_reported_length_remaining(tvb, *offsetp); \
1217 #define HANDLE_REPLY(plen, length_remaining, str, func) do { \
1218 if (length_remaining < plen) { \
1219 if (x11_desegment && pinfo->can_desegment) { \
1220 pinfo->desegment_offset = offset; \
1221 pinfo->desegment_len = plen - length_remaining; \
1224 ; /* XXX yes, what then? Need to skip/join. */ \
1227 if (length_remaining > plen) \
1228 length_remaining = plen; \
1229 next_tvb = tvb_new_subset_length_caplen(tvb, offset, length_remaining, plen); \
1231 if (sep == NULL) { \
1232 col_set_str(pinfo->cinfo, COL_INFO, str); \
1237 func(next_tvb, pinfo, tree, sep, state, byte_order); \
1240 CATCH_NONFATAL_ERRORS { \
1241 show_exception(next_tvb, pinfo, tree, EXCEPT_CODE, GET_MESSAGE); \
1249 dissect_x11_initial_reply(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
1250 const char *sep
, x11_conv_data_t
*state
,
1251 unsigned byte_order
);
1254 dissect_x11_reply(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
1255 const char *sep
, x11_conv_data_t
*state
,
1256 unsigned byte_order
);
1259 dissect_x11_error(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
1260 const char *sep
, x11_conv_data_t
*state
,
1261 unsigned byte_order
);
1264 dissect_x11_event(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
1265 const char *sep
, x11_conv_data_t
*state
,
1266 unsigned byte_order
);
1269 decode_x11_event(tvbuff_t
*tvb
, unsigned char eventcode
, const char *sent
,
1270 proto_tree
*t
, x11_conv_data_t
*state
,
1271 unsigned byte_order
);
1273 static x11_conv_data_t
*
1274 x11_stateinit(conversation_t
*conversation
);
1277 keysymString(uint32_t v
);
1280 /************************************************************************
1282 *** D E C O D I N G F I E L D S ***
1284 ************************************************************************/
1286 static void atom(tvbuff_t
*tvb
, int *offsetp
, proto_tree
*t
, int hf
,
1287 unsigned byte_order
)
1289 const char *interpretation
= NULL
;
1291 uint32_t v
= tvb_get_uint32(tvb
, *offsetp
, byte_order
);
1292 if (v
>= 1 && v
< array_length(atom_predefined_interpretation
))
1293 interpretation
= atom_predefined_interpretation
[v
];
1295 interpretation
= "Not a predefined atom";
1297 header_field_info
*hfi
= proto_registrar_get_nth(hf
);
1299 interpretation
= try_val_to_str(v
, cVALS(hfi
-> strings
));
1301 if (!interpretation
) interpretation
= "error in Xlib client program ?";
1302 proto_tree_add_uint_format(t
, hf
, tvb
, *offsetp
, 4, v
, "%s: %u (%s)",
1303 proto_registrar_get_nth(hf
) -> name
, v
, interpretation
);
1307 static uint32_t add_boolean(tvbuff_t
*tvb
, int *offsetp
, proto_tree
*t
, int hf
)
1309 uint32_t v
= tvb_get_uint8(tvb
, *offsetp
);
1310 proto_tree_add_boolean(t
, hf
, tvb
, *offsetp
, 1, v
);
1315 static void colorFlags(tvbuff_t
*tvb
, int *offsetp
, proto_tree
*t
)
1317 unsigned do_red_green_blue
= tvb_get_uint8(tvb
, *offsetp
);
1321 if (do_red_green_blue
) {
1323 wmem_strbuf_t
*buffer
= wmem_strbuf_create(wmem_packet_scope());
1324 wmem_strbuf_append(buffer
, "flags: ");
1326 if (do_red_green_blue
& 0x1) {
1327 wmem_strbuf_append(buffer
, "DoRed");
1331 if (do_red_green_blue
& 0x2) {
1332 if (sep
) wmem_strbuf_append(buffer
, " | ");
1333 wmem_strbuf_append(buffer
, "DoGreen");
1337 if (do_red_green_blue
& 0x4) {
1338 if (sep
) wmem_strbuf_append(buffer
, " | ");
1339 wmem_strbuf_append(buffer
, "DoBlue");
1343 if (do_red_green_blue
& 0xf8) {
1344 if (sep
) wmem_strbuf_append(buffer
, " + trash");
1347 ti
= proto_tree_add_uint_format(t
, hf_x11_coloritem_flags
, tvb
, *offsetp
, 1, do_red_green_blue
,
1348 "%s", wmem_strbuf_get_str(buffer
));
1349 tt
= proto_item_add_subtree(ti
, ett_x11_color_flags
);
1350 if (do_red_green_blue
& 0x1)
1351 proto_tree_add_boolean(tt
, hf_x11_coloritem_flags_do_red
, tvb
, *offsetp
, 1,
1352 do_red_green_blue
& 0x1);
1353 if (do_red_green_blue
& 0x2)
1354 proto_tree_add_boolean(tt
, hf_x11_coloritem_flags_do_green
, tvb
, *offsetp
, 1,
1355 do_red_green_blue
& 0x2);
1356 if (do_red_green_blue
& 0x4)
1357 proto_tree_add_boolean(tt
, hf_x11_coloritem_flags_do_blue
, tvb
, *offsetp
, 1,
1358 do_red_green_blue
& 0x4);
1359 if (do_red_green_blue
& 0xf8)
1360 proto_tree_add_boolean(tt
, hf_x11_coloritem_flags_unused
, tvb
, *offsetp
, 1,
1361 do_red_green_blue
& 0xf8);
1363 proto_tree_add_uint_format(t
, hf_x11_coloritem_flags
, tvb
, *offsetp
, 1, do_red_green_blue
,
1368 static void listOfArc(tvbuff_t
*tvb
, int *offsetp
, proto_tree
*t
, int hf
,
1369 int length
, unsigned byte_order
)
1371 proto_item
*ti
= proto_tree_add_item(t
, hf
, tvb
, *offsetp
, length
* 8, byte_order
);
1372 proto_tree
*tt
= proto_item_add_subtree(ti
, ett_x11_list_of_arc
);
1374 int16_t x
= tvb_get_uint16(tvb
, *offsetp
, byte_order
);
1375 int16_t y
= tvb_get_uint16(tvb
, *offsetp
+ 2, byte_order
);
1376 uint16_t width
= tvb_get_uint16(tvb
, *offsetp
+ 4, byte_order
);
1377 uint16_t height
= tvb_get_uint16(tvb
, *offsetp
+ 6, byte_order
);
1378 int16_t angle1
= tvb_get_uint16(tvb
, *offsetp
+ 8, byte_order
);
1379 int16_t angle2
= tvb_get_uint16(tvb
, *offsetp
+ 10, byte_order
);
1381 proto_item
*tti
= proto_tree_add_none_format(tt
, hf_x11_arc
, tvb
, *offsetp
, 12,
1382 "arc: %dx%d+%d+%d, angle %d -> %d (%f degrees -> %f degrees)",
1383 width
, height
, x
, y
, angle1
, angle2
,
1384 angle1
/ 64.0, angle2
/ 64.0);
1385 proto_tree
*ttt
= proto_item_add_subtree(tti
, ett_x11_arc
);
1386 proto_tree_add_int(ttt
, hf_x11_arc_x
, tvb
, *offsetp
, 2, x
);
1388 proto_tree_add_int(ttt
, hf_x11_arc_y
, tvb
, *offsetp
, 2, y
);
1390 proto_tree_add_uint(ttt
, hf_x11_arc_width
, tvb
, *offsetp
, 2, y
);
1392 proto_tree_add_uint(ttt
, hf_x11_arc_height
, tvb
, *offsetp
, 2, y
);
1394 proto_tree_add_int(ttt
, hf_x11_arc_angle1
, tvb
, *offsetp
, 2, y
);
1396 proto_tree_add_int(ttt
, hf_x11_arc_angle2
, tvb
, *offsetp
, 2, y
);
1401 static void listOfAtom(tvbuff_t
*tvb
, int *offsetp
, proto_tree
*t
, int hf
,
1402 int length
, unsigned byte_order
)
1404 proto_item
*ti
= proto_tree_add_item(t
, hf
, tvb
, *offsetp
, length
* 4, byte_order
);
1405 proto_tree
*tt
= proto_item_add_subtree(ti
, ett_x11_list_of_atom
);
1407 atom(tvb
, offsetp
, tt
, hf_x11_properties_item
, byte_order
);
1410 static void listOfByte(tvbuff_t
*tvb
, int *offsetp
, proto_tree
*t
, int hf
,
1411 int length
, unsigned byte_order
)
1413 if (length
<= 0) length
= 1;
1414 proto_tree_add_item(t
, hf
, tvb
, *offsetp
, length
, byte_order
);
1418 static void listOfCard16(tvbuff_t
*tvb
, int *offsetp
, proto_tree
*t
, int hf
,
1419 int hf_item
, int length
, unsigned byte_order
)
1421 proto_item
*ti
= proto_tree_add_item(t
, hf
, tvb
, *offsetp
, length
* 2, byte_order
);
1422 proto_tree
*tt
= proto_item_add_subtree(ti
, ett_x11_list_of_card32
);
1424 proto_tree_add_item(tt
, hf_item
, tvb
, *offsetp
, 2, byte_order
);
1429 static void listOfInt16(tvbuff_t
*tvb
, int *offsetp
, proto_tree
*t
, int hf
,
1430 int hf_item
, int length
, unsigned byte_order
)
1432 proto_item
*ti
= proto_tree_add_item(t
, hf
, tvb
, *offsetp
, length
* 2, byte_order
);
1433 proto_tree
*tt
= proto_item_add_subtree(ti
, ett_x11_list_of_card32
);
1435 proto_tree_add_item(tt
, hf_item
, tvb
, *offsetp
, 2, byte_order
);
1440 static void listOfCard32(tvbuff_t
*tvb
, int *offsetp
, proto_tree
*t
, int hf
,
1441 int hf_item
, int length
, unsigned byte_order
)
1443 proto_item
*ti
= proto_tree_add_item(t
, hf
, tvb
, *offsetp
, length
* 4, byte_order
);
1444 proto_tree
*tt
= proto_item_add_subtree(ti
, ett_x11_list_of_card32
);
1446 proto_tree_add_item(tt
, hf_item
, tvb
, *offsetp
, 4, byte_order
);
1451 static void listOfInt32(tvbuff_t
*tvb
, int *offsetp
, proto_tree
*t
, int hf
,
1452 int hf_item
, int length
, unsigned byte_order
)
1454 proto_item
*ti
= proto_tree_add_item(t
, hf
, tvb
, *offsetp
, length
* 4, byte_order
);
1455 proto_tree
*tt
= proto_item_add_subtree(ti
, ett_x11_list_of_card32
);
1457 proto_tree_add_item(tt
, hf_item
, tvb
, *offsetp
, 4, byte_order
);
1462 static void listOfCard64(tvbuff_t
*tvb
, int *offsetp
, proto_tree
*t
, int hf
,
1463 int hf_item
, int length
, unsigned byte_order
)
1465 proto_item
*ti
= proto_tree_add_item(t
, hf
, tvb
, *offsetp
, length
* 8, byte_order
);
1466 proto_tree
*tt
= proto_item_add_subtree(ti
, ett_x11_list_of_card32
);
1468 proto_tree_add_item(tt
, hf_item
, tvb
, *offsetp
, 8, byte_order
);
1473 #if 0 /* Not yet used by any extension */
1474 static void listOfInt64(tvbuff_t
*tvb
, int *offsetp
, proto_tree
*t
, int hf
,
1475 int hf_item
, int length
, unsigned byte_order
)
1477 proto_item
*ti
= proto_tree_add_item(t
, hf
, tvb
, *offsetp
, length
* 8, byte_order
);
1478 proto_tree
*tt
= proto_item_add_subtree(ti
, ett_x11_list_of_card32
);
1480 proto_tree_add_item(tt
, hf_item
, tvb
, *offsetp
, 8, byte_order
);
1486 static void listOfFloat(tvbuff_t
*tvb
, int *offsetp
, proto_tree
*t
, int hf
,
1487 int hf_item
, int length
, unsigned byte_order
)
1489 proto_item
*ti
= proto_tree_add_item(t
, hf
, tvb
, *offsetp
, length
* 4, byte_order
);
1490 proto_tree
*tt
= proto_item_add_subtree(ti
, ett_x11_list_of_float
);
1492 proto_tree_add_item(tt
, hf_item
, tvb
, *offsetp
, 4, byte_order
);
1497 static void listOfDouble(tvbuff_t
*tvb
, int *offsetp
, proto_tree
*t
, int hf
,
1498 int hf_item
, int length
, unsigned byte_order
)
1500 proto_item
*ti
= proto_tree_add_item(t
, hf
, tvb
, *offsetp
, length
* 8, byte_order
);
1501 proto_tree
*tt
= proto_item_add_subtree(ti
, ett_x11_list_of_double
);
1503 proto_tree_add_item(tt
, hf_item
, tvb
, *offsetp
, 8, byte_order
);
1508 static void listOfColorItem(tvbuff_t
*tvb
, int *offsetp
, proto_tree
*t
, int hf
,
1509 int length
, unsigned byte_order
)
1511 proto_item
*ti
= proto_tree_add_item(t
, hf
, tvb
, *offsetp
, length
* 8, byte_order
);
1512 proto_tree
*tt
= proto_item_add_subtree(ti
, ett_x11_list_of_color_item
);
1516 unsigned do_red_green_blue
;
1517 uint16_t red
, green
, blue
;
1518 wmem_strbuf_t
*buffer
;
1521 buffer
=wmem_strbuf_create(wmem_packet_scope());
1522 wmem_strbuf_append(buffer
, "colorItem ");
1523 red
= tvb_get_uint16(tvb
, *offsetp
+ 4, byte_order
);
1524 green
= tvb_get_uint16(tvb
, *offsetp
+ 6, byte_order
);
1525 blue
= tvb_get_uint16(tvb
, *offsetp
+ 8, byte_order
);
1526 do_red_green_blue
= tvb_get_uint8(tvb
, *offsetp
+ 10);
1529 if (do_red_green_blue
& 0x1) {
1530 wmem_strbuf_append_printf(buffer
, "red = %d", red
);
1533 if (do_red_green_blue
& 0x2) {
1534 wmem_strbuf_append_printf(buffer
, "%sgreen = %d", sep
, green
);
1537 if (do_red_green_blue
& 0x4)
1538 wmem_strbuf_append_printf(buffer
, "%sblue = %d", sep
, blue
);
1540 tti
= proto_tree_add_none_format(tt
, hf_x11_coloritem
, tvb
, *offsetp
, 12, "%s", wmem_strbuf_get_str(buffer
));
1541 ttt
= proto_item_add_subtree(tti
, ett_x11_color_item
);
1542 proto_tree_add_item(ttt
, hf_x11_coloritem_pixel
, tvb
, *offsetp
, 4, byte_order
);
1544 proto_tree_add_item(ttt
, hf_x11_coloritem_red
, tvb
, *offsetp
, 2, byte_order
);
1546 proto_tree_add_item(ttt
, hf_x11_coloritem_green
, tvb
, *offsetp
, 2, byte_order
);
1548 proto_tree_add_item(ttt
, hf_x11_coloritem_blue
, tvb
, *offsetp
, 2, byte_order
);
1550 colorFlags(tvb
, offsetp
, ttt
);
1551 proto_tree_add_item(ttt
, hf_x11_coloritem_unused
, tvb
, *offsetp
, 1, byte_order
);
1556 #if 0 /* XXX: Use of GTree no longer needed; use value_string_ext */
1557 static int compareGuint32(const void *a
, const void *b
)
1559 return GPOINTER_TO_INT(b
) - GPOINTER_TO_INT(a
);
1564 XConvertCase(register int sym
, int *lower
, int *upper
)
1569 case 0: /* Latin 1 */
1570 if ((sym
>= XK_A
) && (sym
<= XK_Z
))
1571 *lower
+= (XK_a
- XK_A
);
1572 else if ((sym
>= XK_a
) && (sym
<= XK_z
))
1573 *upper
-= (XK_a
- XK_A
);
1574 else if ((sym
>= XK_Agrave
) && (sym
<= XK_Odiaeresis
))
1575 *lower
+= (XK_agrave
- XK_Agrave
);
1576 else if ((sym
>= XK_agrave
) && (sym
<= XK_odiaeresis
))
1577 *upper
-= (XK_agrave
- XK_Agrave
);
1578 else if ((sym
>= XK_Ooblique
) && (sym
<= XK_Thorn
))
1579 *lower
+= (XK_oslash
- XK_Ooblique
);
1580 else if ((sym
>= XK_oslash
) && (sym
<= XK_thorn
))
1581 *upper
-= (XK_oslash
- XK_Ooblique
);
1583 case 1: /* Latin 2 */
1584 /* Assume the KeySym is a legal value (ignore discontinuities) */
1585 if (sym
== XK_Aogonek
)
1586 *lower
= XK_aogonek
;
1587 else if (sym
>= XK_Lstroke
&& sym
<= XK_Sacute
)
1588 *lower
+= (XK_lstroke
- XK_Lstroke
);
1589 else if (sym
>= XK_Scaron
&& sym
<= XK_Zacute
)
1590 *lower
+= (XK_scaron
- XK_Scaron
);
1591 else if (sym
>= XK_Zcaron
&& sym
<= XK_Zabovedot
)
1592 *lower
+= (XK_zcaron
- XK_Zcaron
);
1593 else if (sym
== XK_aogonek
)
1594 *upper
= XK_Aogonek
;
1595 else if (sym
>= XK_lstroke
&& sym
<= XK_sacute
)
1596 *upper
-= (XK_lstroke
- XK_Lstroke
);
1597 else if (sym
>= XK_scaron
&& sym
<= XK_zacute
)
1598 *upper
-= (XK_scaron
- XK_Scaron
);
1599 else if (sym
>= XK_zcaron
&& sym
<= XK_zabovedot
)
1600 *upper
-= (XK_zcaron
- XK_Zcaron
);
1601 else if (sym
>= XK_Racute
&& sym
<= XK_Tcedilla
)
1602 *lower
+= (XK_racute
- XK_Racute
);
1603 else if (sym
>= XK_racute
&& sym
<= XK_tcedilla
)
1604 *upper
-= (XK_racute
- XK_Racute
);
1606 case 2: /* Latin 3 */
1607 /* Assume the KeySym is a legal value (ignore discontinuities) */
1608 if (sym
>= XK_Hstroke
&& sym
<= XK_Hcircumflex
)
1609 *lower
+= (XK_hstroke
- XK_Hstroke
);
1610 else if (sym
>= XK_Gbreve
&& sym
<= XK_Jcircumflex
)
1611 *lower
+= (XK_gbreve
- XK_Gbreve
);
1612 else if (sym
>= XK_hstroke
&& sym
<= XK_hcircumflex
)
1613 *upper
-= (XK_hstroke
- XK_Hstroke
);
1614 else if (sym
>= XK_gbreve
&& sym
<= XK_jcircumflex
)
1615 *upper
-= (XK_gbreve
- XK_Gbreve
);
1616 else if (sym
>= XK_Cabovedot
&& sym
<= XK_Scircumflex
)
1617 *lower
+= (XK_cabovedot
- XK_Cabovedot
);
1618 else if (sym
>= XK_cabovedot
&& sym
<= XK_scircumflex
)
1619 *upper
-= (XK_cabovedot
- XK_Cabovedot
);
1621 case 3: /* Latin 4 */
1622 /* Assume the KeySym is a legal value (ignore discontinuities) */
1623 if (sym
>= XK_Rcedilla
&& sym
<= XK_Tslash
)
1624 *lower
+= (XK_rcedilla
- XK_Rcedilla
);
1625 else if (sym
>= XK_rcedilla
&& sym
<= XK_tslash
)
1626 *upper
-= (XK_rcedilla
- XK_Rcedilla
);
1627 else if (sym
== XK_ENG
)
1629 else if (sym
== XK_eng
)
1631 else if (sym
>= XK_Amacron
&& sym
<= XK_Umacron
)
1632 *lower
+= (XK_amacron
- XK_Amacron
);
1633 else if (sym
>= XK_amacron
&& sym
<= XK_umacron
)
1634 *upper
-= (XK_amacron
- XK_Amacron
);
1636 case 6: /* Cyrillic */
1637 /* Assume the KeySym is a legal value (ignore discontinuities) */
1638 if (sym
>= XK_Serbian_DJE
&& sym
<= XK_Serbian_DZE
)
1639 *lower
-= (XK_Serbian_DJE
- XK_Serbian_dje
);
1640 else if (sym
>= XK_Serbian_dje
&& sym
<= XK_Serbian_dze
)
1641 *upper
+= (XK_Serbian_DJE
- XK_Serbian_dje
);
1642 else if (sym
>= XK_Cyrillic_YU
&& sym
<= XK_Cyrillic_HARDSIGN
)
1643 *lower
-= (XK_Cyrillic_YU
- XK_Cyrillic_yu
);
1644 else if (sym
>= XK_Cyrillic_yu
&& sym
<= XK_Cyrillic_hardsign
)
1645 *upper
+= (XK_Cyrillic_YU
- XK_Cyrillic_yu
);
1648 /* Assume the KeySym is a legal value (ignore discontinuities) */
1649 if (sym
>= XK_Greek_ALPHAaccent
&& sym
<= XK_Greek_OMEGAaccent
)
1650 *lower
+= (XK_Greek_alphaaccent
- XK_Greek_ALPHAaccent
);
1651 else if (sym
>= XK_Greek_alphaaccent
&& sym
<= XK_Greek_omegaaccent
&&
1652 sym
!= XK_Greek_iotaaccentdieresis
&&
1653 sym
!= XK_Greek_upsilonaccentdieresis
)
1654 *upper
-= (XK_Greek_alphaaccent
- XK_Greek_ALPHAaccent
);
1655 else if (sym
>= XK_Greek_ALPHA
&& sym
<= XK_Greek_OMEGA
)
1656 *lower
+= (XK_Greek_alpha
- XK_Greek_ALPHA
);
1657 else if (sym
>= XK_Greek_alpha
&& sym
<= XK_Greek_omega
&&
1658 sym
!= XK_Greek_finalsmallsigma
)
1659 *upper
-= (XK_Greek_alpha
- XK_Greek_ALPHA
);
1665 keycode2keysymString(int *keycodemap
[256], int first_keycode
,
1666 int keysyms_per_keycode
,
1667 int *modifiermap
[array_length(modifiers
)],
1668 int keycodes_per_modifier
,
1669 uint32_t keycode
, uint32_t bitmask
)
1672 int groupmodkc
, numlockkc
, numlockmod
, groupmod
;
1673 int lockmod_is_capslock
= 0, lockmod_is_shiftlock
= 0;
1674 int lockmod_is_nosymbol
= 1;
1675 int modifier
, kc
, keysym
;
1677 if ((syms
= keycodemap
[keycode
]) == NULL
)
1680 for (kc
= first_keycode
, groupmodkc
= numlockkc
= -1; kc
< 256; ++kc
)
1681 for (keysym
= 0; keysym
< keysyms_per_keycode
; ++keysym
) {
1682 if (keycodemap
[kc
] == NULL
)
1684 switch (keycodemap
[kc
][keysym
]) {
1694 lockmod_is_capslock
= kc
;
1698 lockmod_is_shiftlock
= kc
;
1705 * If we have not seen the modifiermap we don't know what the
1706 * keycode translates to, but we do know it's one of the keys
1707 * in syms (give or take a case-conversion), so we could in
1708 * theory list them all.
1710 if (modifiermap
[array_length(modifiers
) - 1] == NULL
) /* all or none */
1713 /* find out what the numlockmodifer and groupmodifier is. */
1714 for (modifier
= 0, numlockmod
= groupmod
= -1;
1715 modifier
< (int)array_length(modifiers
) && numlockmod
== -1;
1717 for (kc
= 0; kc
< keycodes_per_modifier
; ++kc
)
1718 if (modifiermap
[modifier
][kc
] == numlockkc
)
1719 numlockmod
= modifier
;
1720 else if (modifiermap
[modifier
][kc
] == groupmodkc
)
1721 groupmod
= modifier
;
1724 * ... and what the lockmodifier is interpreted as.
1725 * (X11v4r6 ref, keyboard and pointers section.)
1727 for (kc
= 0; kc
< keycodes_per_modifier
; ++kc
)
1728 if (modifiermap
[1][kc
] == lockmod_is_capslock
) {
1729 lockmod_is_shiftlock
= lockmod_is_nosymbol
= 0;
1732 else if (modifiermap
[0][kc
] == lockmod_is_shiftlock
) {
1733 lockmod_is_capslock
= lockmod_is_nosymbol
= 0;
1739 * This is (how I understand) the X11v4R6 protocol description given
1740 * in A. Nye's book. It is quite different from the
1741 * code in _XTranslateKey() in the file
1742 * "$XConsortium: KeyBind.c /main/55 1996/02/02 14:08:55 kaleb $"
1743 * as shipped with XFree, and doesn't work correctly, nor do I see
1744 * how it could (e.g. the case of lower/uppercase-letters).
1745 * -- Michael Shuldman
1748 if (numlockmod
>= 0 && (bitmask
& modifiermask
[numlockmod
])
1749 && ((syms
[1] >= 0xff80
1750 && syms
[1] <= 0xffbd)
1751 || (syms
[1] >= 0x11000000
1752 && syms
[1] <= 0x1100ffff))) {
1753 if ((bitmask
& ShiftMask
) || lockmod_is_shiftlock
)
1754 return keysymString(syms
[groupmod
+ 0]);
1756 if (syms
[groupmod
+ 1] == NoSymbol
)
1757 return keysymString(syms
[groupmod
+ 0]);
1759 return keysymString(syms
[groupmod
+ 1]);
1761 else if (!(bitmask
& ShiftMask
) && !(bitmask
& LockMask
))
1762 return keysymString(syms
[groupmod
+ 0]);
1763 else if (!(bitmask
& ShiftMask
)
1764 && ((bitmask
& LockMask
) && lockmod_is_capslock
))
1765 if (islower(syms
[groupmod
+ 0]))
1766 /* return toupper(keysymString(syms[groupmod + 0])); */
1767 return "Uppercase"; /* XXX */
1769 return keysymString(syms
[groupmod
+ 0]);
1771 else if ((bitmask
& ShiftMask
)
1772 && ((bitmask
& LockMask
) && lockmod_is_capslock
))
1773 if (islower(syms
[groupmod
+ 1]))
1774 /* return toupper(keysymString(syms[groupmod + 1])); */
1775 return "Uppercase"; /* XXX */
1777 return keysymString(syms
[groupmod
+ 1]);
1779 else if ((bitmask
& ShiftMask
)
1780 || ((bitmask
& LockMask
) && lockmod_is_shiftlock
))
1781 return keysymString(syms
[groupmod
+ 1]);
1782 #else /* _XTranslateKey() based code. */
1784 while (keysyms_per_keycode
> 2
1785 && keycodemap
[keysyms_per_keycode
- 1] == NoSymbol
)
1786 --keysyms_per_keycode
;
1787 if (keysyms_per_keycode
> 2
1788 && (groupmod
>= 0 && (modifiermask
[groupmod
] & bitmask
))) {
1790 keysyms_per_keycode
-= 2;
1793 if (numlockmod
>= 0 && (bitmask
& modifiermask
[numlockmod
])
1794 && keysyms_per_keycode
> 1
1795 && ((syms
[1] >= 0xff80 && syms
[1] <= 0xffbd)
1796 || (syms
[1] >= 0x11000000 && syms
[1] <= 0x1100ffff))) {
1797 if ((bitmask
& ShiftMask
)
1798 || (bitmask
& LockMask
&& lockmod_is_shiftlock
))
1803 else if (!(bitmask
& ShiftMask
)
1804 && (!(bitmask
& LockMask
) || lockmod_is_nosymbol
)) {
1805 if (keysyms_per_keycode
== 1
1806 || (keysyms_per_keycode
> 1 && syms
[1] == NoSymbol
)) {
1809 XConvertCase(syms
[0], &keysym
, &usym
);
1814 else if (!(bitmask
& LockMask
) || !lockmod_is_capslock
) {
1817 if (keysyms_per_keycode
== 1
1818 || (keysyms_per_keycode
> 1 && (usym
= syms
[1]) == NoSymbol
))
1819 XConvertCase(syms
[0], &lsym
, &usym
);
1825 if (keysyms_per_keycode
== 1
1826 || (keysyms_per_keycode
> 1 && syms
[1] == NoSymbol
))
1829 XConvertCase(keysym
, &lsym
, &usym
);
1831 if (!(bitmask
& ShiftMask
) && keysym
!= syms
[0]
1832 && ((keysym
!= usym
) || (lsym
== usym
)))
1833 XConvertCase(syms
[0], &lsym
, &usym
);
1837 if (keysym
== XK_VoidSymbol
)
1840 return wmem_strdup_printf(wmem_packet_scope(), "%d, \"%s\"", keysym
, keysymString(keysym
));
1844 static const char *keysymString(uint32_t v
)
1846 #if 0 /* XXX: Use of GTree no longer needed; use value_string_ext */
1847 static GTree
*keysymTable
= NULL
;
1852 /* This table is so big that we built it only if necessary */
1853 const value_string
*p
= x11_keysym_vals_source
;
1854 keysymTable
= g_tree_new(compareGuint32
);
1855 for(; p
-> strptr
; p
++)
1856 g_tree_insert(keysymTable
, GINT_TO_POINTER(p
-> value
), (void *) (p
-> strptr
) );
1858 res
= g_tree_lookup(keysymTable
, GINT_TO_POINTER(v
));
1859 return res
? res
: "<Unknown>";
1862 return val_to_str_ext_const(v
, &x11_keysym_vals_source_ext
, "<Unknown>");
1866 static void listOfKeycode(tvbuff_t
*tvb
, int *offsetp
, proto_tree
*t
, int hf
,
1867 int *modifiermap
[], int keycodes_per_modifier
,
1868 unsigned byte_order _U_
)
1870 proto_item
*ti
= proto_tree_add_item(t
, hf
, tvb
, *offsetp
,
1871 (int)array_length(modifiers
) * keycodes_per_modifier
, ENC_NA
);
1872 proto_tree
*tt
= proto_item_add_subtree(ti
, ett_x11_list_of_keycode
);
1875 for (m
= 0; m
< array_length(modifiers
);
1876 ++m
, *offsetp
+= keycodes_per_modifier
) {
1880 tikc
= proto_tree_add_bytes_format(tt
, hf_x11_keycodes_item
, tvb
,
1881 *offsetp
, keycodes_per_modifier
, NULL
, "item: ");
1882 modifiermap
[m
] = (int *)
1883 wmem_alloc(wmem_file_scope(), sizeof(*modifiermap
[m
]) * keycodes_per_modifier
);
1884 for(i
= 0; i
< keycodes_per_modifier
; ++i
) {
1885 unsigned char c
= tvb_get_uint8(tvb
, (*offsetp
) + i
);
1888 proto_item_append_text(tikc
, " %s=%d", modifiers
[m
], c
);
1890 modifiermap
[m
][i
] = c
;
1895 static void listOfKeysyms(tvbuff_t
*tvb
, packet_info
*pinfo
, int *offsetp
, proto_tree
*t
, int hf
,
1896 int hf_item
, int *keycodemap
[256],
1897 int keycode_first
, int keycode_count
,
1898 int keysyms_per_keycode
, unsigned byte_order
)
1900 proto_item
*ti
= proto_tree_add_item(t
, hf
, tvb
, *offsetp
, keycode_count
* keysyms_per_keycode
* 4, byte_order
);
1901 proto_tree
*tt
= proto_item_add_subtree(ti
, ett_x11_list_of_keysyms
);
1906 DISSECTOR_ASSERT(keycode_first
>= 0);
1907 DISSECTOR_ASSERT(keycode_count
>= 0);
1909 for (keycode
= keycode_first
; keycode_count
> 0;
1910 ++keycode
, --keycode_count
) {
1911 tti
= proto_tree_add_none_format(tt
, hf_item
, tvb
, *offsetp
,
1912 4 * keysyms_per_keycode
, "keysyms (keycode %d):", keycode
);
1913 if (keycode
>= 256) {
1914 expert_add_info_format(pinfo
, tti
, &ei_x11_keycode_value_out_of_range
,
1915 "keycode value %d is out of range", keycode
);
1916 *offsetp
+= 4 * keysyms_per_keycode
;
1920 ttt
= proto_item_add_subtree(tti
, ett_x11_keysym
);
1922 tvb_ensure_bytes_exist(tvb
, *offsetp
, 4 * keysyms_per_keycode
);
1924 = (int *)wmem_alloc(wmem_file_scope(), sizeof(*keycodemap
[keycode
]) * keysyms_per_keycode
);
1926 for(i
= 0; i
< keysyms_per_keycode
; ++i
) {
1927 /* keysymvalue = byte3 * 256 + byte4. */
1928 uint32_t v
= tvb_get_uint32(tvb
, *offsetp
, byte_order
);
1930 proto_item_append_text(tti
, " %s", keysymString(v
));
1931 proto_tree_add_uint_format(ttt
, hf_x11_keysyms_item_keysym
,
1932 tvb
, *offsetp
, 4, v
,
1933 "keysym (keycode %d): 0x%08x (%s)",
1934 keycode
, v
, keysymString(v
));
1936 keycodemap
[keycode
][i
] = v
;
1940 for (i
= 1; i
< keysyms_per_keycode
; ++i
)
1941 if (keycodemap
[keycode
][i
] != NoSymbol
)
1944 if (i
== keysyms_per_keycode
) {
1945 /* all but (possibly) first were NoSymbol. */
1946 if (keysyms_per_keycode
== 4) {
1947 keycodemap
[keycode
][1] = NoSymbol
;
1948 keycodemap
[keycode
][2] = keycodemap
[keycode
][0];
1949 keycodemap
[keycode
][3] = NoSymbol
;
1955 for (i
= 2; i
< keysyms_per_keycode
; ++i
)
1956 if (keycodemap
[keycode
][i
] != NoSymbol
)
1958 if (i
== keysyms_per_keycode
) {
1959 /* all but (possibly) first two were NoSymbol. */
1960 if (keysyms_per_keycode
== 4) {
1961 keycodemap
[keycode
][2] = keycodemap
[keycode
][0];
1962 keycodemap
[keycode
][3] = keycodemap
[keycode
][1];
1970 static void listOfPoint(tvbuff_t
*tvb
, int *offsetp
, proto_tree
*t
, int hf
,
1971 int length
, unsigned byte_order
)
1973 proto_item
*ti
= proto_tree_add_item(t
, hf
, tvb
, *offsetp
, length
* 4, byte_order
);
1974 proto_tree
*tt
= proto_item_add_subtree(ti
, ett_x11_list_of_point
);
1980 x
= tvb_get_uint16(tvb
, *offsetp
, byte_order
);
1981 y
= tvb_get_uint16(tvb
, *offsetp
+ 2, byte_order
);
1983 tti
= proto_tree_add_none_format(tt
, hf_x11_point
, tvb
, *offsetp
, 4, "point: (%d,%d)", x
, y
);
1984 ttt
= proto_item_add_subtree(tti
, ett_x11_point
);
1985 proto_tree_add_int(ttt
, hf_x11_point_x
, tvb
, *offsetp
, 2, x
);
1987 proto_tree_add_int(ttt
, hf_x11_point_y
, tvb
, *offsetp
, 2, y
);
1992 static void listOfRectangle(tvbuff_t
*tvb
, int *offsetp
, proto_tree
*t
, int hf
,
1993 int length
, unsigned byte_order
)
1995 proto_item
*ti
= proto_tree_add_item(t
, hf
, tvb
, *offsetp
, length
* 8, byte_order
);
1996 proto_tree
*tt
= proto_item_add_subtree(ti
, ett_x11_list_of_rectangle
);
1999 unsigned width
, height
;
2003 x
= tvb_get_uint16(tvb
, *offsetp
, byte_order
);
2004 y
= tvb_get_uint16(tvb
, *offsetp
+ 2, byte_order
);
2005 width
= tvb_get_uint16(tvb
, *offsetp
+ 4, byte_order
);
2006 height
= tvb_get_uint16(tvb
, *offsetp
+ 6, byte_order
);
2008 tti
= proto_tree_add_none_format(tt
, hf_x11_rectangle
, tvb
, *offsetp
, 8,
2009 "rectangle: %dx%d+%d+%d", width
, height
, x
, y
);
2010 ttt
= proto_item_add_subtree(tti
, ett_x11_rectangle
);
2011 proto_tree_add_int(ttt
, hf_x11_rectangle_x
, tvb
, *offsetp
, 2, x
);
2013 proto_tree_add_int(ttt
, hf_x11_rectangle_y
, tvb
, *offsetp
, 2, y
);
2015 proto_tree_add_uint(ttt
, hf_x11_rectangle_width
, tvb
, *offsetp
, 2, width
);
2017 proto_tree_add_uint(ttt
, hf_x11_rectangle_height
, tvb
, *offsetp
, 2, height
);
2022 static void listOfSegment(tvbuff_t
*tvb
, int *offsetp
, proto_tree
*t
, int hf
,
2023 int length
, unsigned byte_order
)
2025 proto_item
*ti
= proto_tree_add_item(t
, hf
, tvb
, *offsetp
, length
* 8, byte_order
);
2026 proto_tree
*tt
= proto_item_add_subtree(ti
, ett_x11_list_of_segment
);
2028 int16_t x1
, y1
, x2
, y2
;
2032 x1
= tvb_get_uint16(tvb
, *offsetp
, byte_order
);
2033 y1
= tvb_get_uint16(tvb
, *offsetp
+ 2, byte_order
);
2034 x2
= tvb_get_uint16(tvb
, *offsetp
+ 4, byte_order
);
2035 y2
= tvb_get_uint16(tvb
, *offsetp
+ 6, byte_order
);
2037 tti
= proto_tree_add_none_format(tt
, hf_x11_segment
, tvb
, *offsetp
, 8,
2038 "segment: (%d,%d)-(%d,%d)", x1
, y1
, x2
, y2
);
2039 ttt
= proto_item_add_subtree(tti
, ett_x11_segment
);
2040 proto_tree_add_item(ttt
, hf_x11_segment_x1
, tvb
, *offsetp
, 2, byte_order
);
2042 proto_tree_add_item(ttt
, hf_x11_segment_y1
, tvb
, *offsetp
, 2, byte_order
);
2044 proto_tree_add_item(ttt
, hf_x11_segment_x2
, tvb
, *offsetp
, 2, byte_order
);
2046 proto_tree_add_item(ttt
, hf_x11_segment_y2
, tvb
, *offsetp
, 2, byte_order
);
2051 static void listOfVisualTypes(tvbuff_t
*tvb
, int *offsetp
, proto_tree
*t
, int hf
,
2052 int length
, unsigned byte_order
)
2054 proto_item
*ti
= proto_tree_add_item(t
, hf
, tvb
, *offsetp
, length
* 24, byte_order
);
2055 proto_tree
*tt
= proto_item_add_subtree(ti
, ett_x11_list_of_visualtype
);
2060 tti
= proto_tree_add_none_format(tt
, hf_x11_visualtype
, tvb
, *offsetp
, 24,
2062 ttt
= proto_item_add_subtree(tti
, ett_x11_visualtype
);
2063 proto_tree_add_item(ttt
, hf_x11_visualtype_visualid
, tvb
, *offsetp
, 4, byte_order
);
2065 proto_tree_add_item(ttt
, hf_x11_visualtype_class
, tvb
, *offsetp
, 1, byte_order
);
2067 proto_tree_add_item(ttt
, hf_x11_visualtype_bits_per_rgb_value
, tvb
, *offsetp
, 1, byte_order
);
2069 proto_tree_add_item(ttt
, hf_x11_visualtype_colormap_entries
, tvb
, *offsetp
, 2, byte_order
);
2071 proto_tree_add_item(ttt
, hf_x11_visualtype_red_mask
, tvb
, *offsetp
, 4, byte_order
);
2073 proto_tree_add_item(ttt
, hf_x11_visualtype_green_mask
, tvb
, *offsetp
, 4, byte_order
);
2075 proto_tree_add_item(ttt
, hf_x11_visualtype_blue_mask
, tvb
, *offsetp
, 4, byte_order
);
2077 proto_tree_add_item(ttt
, hf_x11_unused
, tvb
, *offsetp
, 4, byte_order
);
2081 static void listOfDepth(tvbuff_t
*tvb
, int *offsetp
, proto_tree
*t
, int hf
,
2082 int length
, unsigned byte_order
)
2084 uint16_t number_of_visualtypes
;
2088 ti
= proto_tree_add_item(t
, hf
, tvb
, *offsetp
, -1, byte_order
);
2089 tt
= proto_item_add_subtree(ti
, ett_x11_list_of_depth_detail
);
2093 number_of_visualtypes
= tvb_get_uint16(tvb
, *offsetp
+ 2, byte_order
);
2095 tti
= proto_tree_add_none_format(tt
, hf_x11_depth_detail
, tvb
, *offsetp
, 8 + 24 * number_of_visualtypes
,
2097 ttt
= proto_item_add_subtree(tti
, ett_x11_screen
);
2098 proto_tree_add_item(ttt
, hf_x11_depth_detail_depth
, tvb
, *offsetp
, 1, byte_order
);
2100 proto_tree_add_item(ttt
, hf_x11_unused
, tvb
, *offsetp
, 1, byte_order
);
2102 proto_tree_add_item(ttt
, hf_x11_depth_detail_visualtypes_numbers
, tvb
, *offsetp
, 2, byte_order
);
2104 proto_tree_add_item(ttt
, hf_x11_unused
, tvb
, *offsetp
, 4, byte_order
);
2106 if (number_of_visualtypes
> 0)
2107 listOfVisualTypes(tvb
, offsetp
, ttt
, hf_x11_visualtype
, number_of_visualtypes
, byte_order
);
2111 static void listOfScreen(tvbuff_t
*tvb
, int *offsetp
, proto_tree
*t
, int hf
,
2112 int length
, unsigned byte_order
)
2114 proto_item
*ti
= proto_tree_add_item(t
, hf
, tvb
, *offsetp
, -1, byte_order
);
2115 proto_tree
*tt
= proto_item_add_subtree(ti
, ett_x11_list_of_screen
);
2117 uint8_t number_of_depths
, root_depth
;
2118 uint16_t width_in_pixels
, height_in_pixels
;
2119 uint32_t screen_root
;
2123 screen_root
= tvb_get_uint32(tvb
, *offsetp
, byte_order
);
2124 width_in_pixels
= tvb_get_uint16(tvb
, *offsetp
+ 20, byte_order
);
2125 height_in_pixels
= tvb_get_uint16(tvb
, *offsetp
+ 22, byte_order
);
2126 root_depth
= tvb_get_uint8(tvb
, *offsetp
+ 38);
2127 tti
= proto_tree_add_none_format(tt
, hf_x11_screen
, tvb
, *offsetp
, 0,
2128 "screen (%08x: %d x %d x %d)", screen_root
,
2129 width_in_pixels
, height_in_pixels
, root_depth
);
2130 ttt
= proto_item_add_subtree(tti
, ett_x11_screen
);
2131 proto_tree_add_item(ttt
, hf_x11_screen_root
, tvb
, *offsetp
, 4, byte_order
);
2133 proto_tree_add_item(ttt
, hf_x11_screen_default_colormap
, tvb
, *offsetp
, 4, byte_order
);
2135 proto_tree_add_item(ttt
, hf_x11_screen_white_pixel
, tvb
, *offsetp
, 4, byte_order
);
2137 proto_tree_add_item(ttt
, hf_x11_screen_black_pixel
, tvb
, *offsetp
, 4, byte_order
);
2139 proto_tree_add_item(ttt
, hf_x11_screen_current_input_masks
, tvb
, *offsetp
, 4, byte_order
);
2141 proto_tree_add_item(ttt
, hf_x11_screen_width_in_pixels
, tvb
, *offsetp
, 2, byte_order
);
2143 proto_tree_add_item(ttt
, hf_x11_screen_height_in_pixels
, tvb
, *offsetp
, 2, byte_order
);
2145 proto_tree_add_item(ttt
, hf_x11_screen_width_in_millimeters
, tvb
, *offsetp
, 2, byte_order
);
2147 proto_tree_add_item(ttt
, hf_x11_screen_height_in_millimeters
, tvb
, *offsetp
, 2, byte_order
);
2149 proto_tree_add_item(ttt
, hf_x11_screen_min_installed_maps
, tvb
, *offsetp
, 2, byte_order
);
2151 proto_tree_add_item(ttt
, hf_x11_screen_max_installed_maps
, tvb
, *offsetp
, 2, byte_order
);
2153 proto_tree_add_item(ttt
, hf_x11_screen_root_visual
, tvb
, *offsetp
, 4, byte_order
);
2155 proto_tree_add_item(ttt
, hf_x11_screen_backing_stores
, tvb
, *offsetp
, 1, byte_order
);
2157 proto_tree_add_item(ttt
, hf_x11_screen_save_unders
, tvb
, *offsetp
, 1, byte_order
);
2159 proto_tree_add_item(ttt
, hf_x11_screen_root_depth
, tvb
, *offsetp
, 1, byte_order
);
2161 number_of_depths
= tvb_get_uint8(tvb
, *offsetp
);
2162 proto_tree_add_item(ttt
, hf_x11_screen_allowed_depths_len
, tvb
, *offsetp
, 1, byte_order
);
2164 listOfDepth(tvb
, offsetp
, ttt
, hf_x11_depth_detail
, number_of_depths
, byte_order
);
2167 static void listOfPixmapFormat(tvbuff_t
*tvb
, int *offsetp
, proto_tree
*t
, int hf
,
2168 int length
, unsigned byte_order
)
2170 proto_item
*ti
= proto_tree_add_item(t
, hf
, tvb
, *offsetp
, length
* 8, byte_order
);
2171 proto_tree
*tt
= proto_item_add_subtree(ti
, ett_x11_list_of_pixmap_format
);
2176 tti
= proto_tree_add_none_format(tt
, hf_x11_pixmap_format
, tvb
, *offsetp
, 8,
2178 ttt
= proto_item_add_subtree(tti
, ett_x11_pixmap_format
);
2179 proto_tree_add_item(ttt
, hf_x11_pixmap_format_depth
, tvb
, *offsetp
, 1, byte_order
);
2181 proto_tree_add_item(ttt
, hf_x11_pixmap_format_bits_per_pixel
, tvb
, *offsetp
, 1, byte_order
);
2183 proto_tree_add_item(ttt
, hf_x11_pixmap_format_scanline_pad
, tvb
, *offsetp
, 1, byte_order
);
2185 proto_tree_add_item(ttt
, hf_x11_unused
, tvb
, *offsetp
, 5, byte_order
);
2190 static void listOfString8(tvbuff_t
*tvb
, int *offsetp
, proto_tree
*t
, int hf
,
2191 int hf_item
, int length
, unsigned byte_order
)
2198 /* Compute total length */
2200 int scanning_offset
= *offsetp
; /* Scanning pointer */
2201 for(i
= length
; i
; i
--) {
2203 l
= tvb_get_uint8(tvb
, scanning_offset
);
2204 scanning_offset
+= 1 + l
;
2207 ti
= proto_tree_add_item(t
, hf
, tvb
, *offsetp
, scanning_offset
- *offsetp
, byte_order
);
2208 tt
= proto_item_add_subtree(ti
, ett_x11_list_of_string8
);
2211 unsigned l
= tvb_get_uint8(tvb
, *offsetp
);
2212 s
= tvb_get_string_enc(wmem_packet_scope(), tvb
, *offsetp
+ 1, l
, ENC_ASCII
);
2213 proto_tree_add_string_format(tt
, hf_item
, tvb
, *offsetp
, l
+ 1, s
, "\"%s\"", s
);
2218 static int stringIsActuallyAn8BitString(tvbuff_t
*tvb
, int offset
, unsigned length
)
2220 for(; length
> 0; offset
+= 2, length
--) {
2221 if (tvb_get_uint8(tvb
, offset
))
2227 /* XXX - assumes that the string encoding is ASCII; even if 0x00 through
2228 0x7F are ASCII, 0x80 through 0xFF might not be, and even 0x00 through
2229 0x7F aren't necessarily ASCII. */
2230 static char *tvb_get_ascii_string16(tvbuff_t
*tvb
, int offset
, unsigned length
)
2235 str
= wmem_strbuf_new_sized(wmem_packet_scope(), length
+ 1);
2239 ch
= tvb_get_uint8(tvb
, offset
);
2241 wmem_strbuf_append_c(str
, ch
);
2243 wmem_strbuf_append_unichar_repl(str
);
2246 return wmem_strbuf_finalize(str
);
2249 static void listOfTextItem(tvbuff_t
*tvb
, int *offsetp
, proto_tree
*t
, int hf
,
2250 int sizeIs16
, int next_offset
, unsigned byte_order
)
2257 /* Compute total length */
2259 int scanning_offset
= *offsetp
; /* Scanning pointer */
2260 int n
= 0; /* Number of items */
2262 while(scanning_offset
< next_offset
) {
2263 int l
; /* Length of an individual item */
2264 l
= tvb_get_uint8(tvb
, scanning_offset
);
2268 scanning_offset
+= l
== 255 ? 4 : l
+ (sizeIs16
? l
: 0) + 1;
2271 ti
= proto_tree_add_item(t
, hf
, tvb
, *offsetp
, scanning_offset
- *offsetp
, byte_order
);
2272 tt
= proto_item_add_subtree(ti
, ett_x11_list_of_text_item
);
2275 unsigned l
= tvb_get_uint8(tvb
, *offsetp
);
2276 if (l
== 255) { /* Item is a font */
2277 fid
= tvb_get_ntohl(tvb
, *offsetp
+ 1);
2278 proto_tree_add_uint(tt
, hf_x11_textitem_font
, tvb
, *offsetp
, 5, fid
);
2280 } else { /* Item is a string */
2283 int8_t delta
= tvb_get_uint8(tvb
, *offsetp
+ 1);
2285 if (stringIsActuallyAn8BitString(tvb
, *offsetp
+ 2, l
)) {
2286 s
= tvb_get_ascii_string16(tvb
, *offsetp
+ 2, l
);
2287 tti
= proto_tree_add_none_format(tt
, hf_x11_textitem_string
, tvb
, *offsetp
, l
*2 + 2,
2288 "textitem (string): delta = %d, \"%s\"",
2290 ttt
= proto_item_add_subtree(tti
, ett_x11_text_item
);
2291 proto_tree_add_item(ttt
, hf_x11_textitem_string_delta
, tvb
, *offsetp
+ 1, 1, byte_order
);
2292 proto_tree_add_string_format_value(ttt
, hf_x11_textitem_string_string16
, tvb
,
2293 *offsetp
+ 2, l
, s
, "\"%s\"", s
);
2295 tti
= proto_tree_add_none_format(tt
, hf_x11_textitem_string
, tvb
, *offsetp
, l
*2 + 2,
2296 "textitem (string): delta = %d, %s",
2298 tvb_bytes_to_str(wmem_packet_scope(), tvb
, *offsetp
+ 2, l
*2));
2299 ttt
= proto_item_add_subtree(tti
, ett_x11_text_item
);
2300 proto_tree_add_item(ttt
, hf_x11_textitem_string_delta
, tvb
, *offsetp
+ 1, 1, byte_order
);
2301 proto_tree_add_item(ttt
, hf_x11_textitem_string_string16_bytes
, tvb
, *offsetp
+ 2, l
*2, byte_order
);
2303 *offsetp
+= l
*2 + 2;
2305 s
= tvb_get_string_enc(wmem_packet_scope(), tvb
, *offsetp
+ 2, l
, ENC_ASCII
);
2306 tti
= proto_tree_add_none_format(tt
, hf_x11_textitem_string
, tvb
, *offsetp
, l
+ 2,
2307 "textitem (string): delta = %d, \"%s\"",
2309 ttt
= proto_item_add_subtree(tti
, ett_x11_text_item
);
2310 proto_tree_add_item(ttt
, hf_x11_textitem_string_delta
, tvb
, *offsetp
+ 1, 1, byte_order
);
2311 proto_tree_add_string_format(ttt
, hf_x11_textitem_string_string8
, tvb
,
2312 *offsetp
+ 2, l
, s
, "\"%s\"", s
);
2319 static uint32_t field8(tvbuff_t
*tvb
, int *offsetp
, proto_tree
*t
, int hf
,
2320 unsigned byte_order
)
2322 uint32_t v
= tvb_get_uint8(tvb
, *offsetp
);
2323 header_field_info
*hfi
= proto_registrar_get_nth(hf
);
2324 const char *enumValue
= NULL
;
2327 enumValue
= try_val_to_str(v
, cVALS(hfi
-> strings
));
2329 proto_tree_add_uint_format(t
, hf
, tvb
, *offsetp
, 1, v
,
2330 hfi
-> display
== BASE_DEC
? "%s: %u (%s)" : "%s: 0x%02x (%s)",
2331 hfi
-> name
, v
, enumValue
);
2333 proto_tree_add_item(t
, hf
, tvb
, *offsetp
, 1, byte_order
);
2338 static uint32_t field16(tvbuff_t
*tvb
, int *offsetp
, proto_tree
*t
, int hf
,
2339 unsigned byte_order
)
2341 uint32_t v
= tvb_get_uint16(tvb
, *offsetp
, byte_order
);
2342 header_field_info
*hfi
= proto_registrar_get_nth(hf
);
2343 const char *enumValue
= NULL
;
2346 enumValue
= try_val_to_str(v
, cVALS(hfi
-> strings
));
2348 proto_tree_add_uint_format(t
, hf
, tvb
, *offsetp
, 2, v
,
2349 hfi
-> display
== BASE_DEC
? "%s: %u (%s)" : "%s: 0x%02x (%s)",
2350 hfi
-> name
, v
, enumValue
);
2352 proto_tree_add_item(t
, hf
, tvb
, *offsetp
, 2, byte_order
);
2357 static uint32_t field32(tvbuff_t
*tvb
, int *offsetp
, proto_tree
*t
, int hf
,
2358 unsigned byte_order
)
2360 uint32_t v
= tvb_get_uint32(tvb
, *offsetp
, byte_order
);
2361 header_field_info
*hfi
= proto_registrar_get_nth(hf
);
2362 const char *enumValue
= NULL
;
2363 const char *nameAsChar
= hfi
-> name
;
2366 enumValue
= try_val_to_str(v
, cVALS(hfi
-> strings
));
2368 proto_tree_add_uint_format(t
, hf
, tvb
, *offsetp
, 4, v
,
2369 hfi
-> display
== BASE_DEC
? "%s: %u (%s)" : "%s: 0x%08x (%s)",
2370 nameAsChar
, v
, enumValue
);
2372 proto_tree_add_uint_format(t
, hf
, tvb
, *offsetp
, 4, v
,
2373 hfi
-> display
== BASE_DEC
? "%s: %u" : "%s: 0x%08x",
2379 static int * const gc_mask_attributes
[] = {
2380 &hf_x11_gc_value_mask_function
,
2381 &hf_x11_gc_value_mask_plane_mask
,
2382 &hf_x11_gc_value_mask_foreground
,
2383 &hf_x11_gc_value_mask_background
,
2384 &hf_x11_gc_value_mask_line_width
,
2385 &hf_x11_gc_value_mask_line_style
,
2386 &hf_x11_gc_value_mask_cap_style
,
2387 &hf_x11_gc_value_mask_join_style
,
2388 &hf_x11_gc_value_mask_fill_style
,
2389 &hf_x11_gc_value_mask_fill_rule
,
2390 &hf_x11_gc_value_mask_tile
,
2391 &hf_x11_gc_value_mask_stipple
,
2392 &hf_x11_gc_value_mask_tile_stipple_x_origin
,
2393 &hf_x11_gc_value_mask_tile_stipple_y_origin
,
2394 &hf_x11_gc_value_mask_font
,
2395 &hf_x11_gc_value_mask_subwindow_mode
,
2396 &hf_x11_gc_value_mask_graphics_exposures
,
2397 &hf_x11_gc_value_mask_clip_x_origin
,
2398 &hf_x11_gc_value_mask_clip_y_origin
,
2399 &hf_x11_gc_value_mask_clip_mask
,
2400 &hf_x11_gc_value_mask_dash_offset
,
2401 &hf_x11_gc_value_mask_gc_dashes
,
2402 &hf_x11_gc_value_mask_arc_mode
,
2406 static void gcAttributes(tvbuff_t
*tvb
, int *offsetp
, proto_tree
*t
,
2407 unsigned byte_order
)
2410 bitmask
= tvb_get_uint32(tvb
, *offsetp
, byte_order
);
2411 proto_tree_add_bitmask(t
, tvb
, *offsetp
, hf_x11_gc_value_mask
, ett_x11_gc_value_mask
, gc_mask_attributes
, byte_order
);
2414 if (bitmask
& 0x00000001) {
2415 proto_tree_add_item(t
, hf_x11_function
, tvb
, *offsetp
, 1, byte_order
);
2417 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 3, ENC_NA
);
2420 if (bitmask
& 0x00000002) {
2421 proto_tree_add_item(t
, hf_x11_plane_mask
, tvb
, *offsetp
, 4, byte_order
);
2424 if (bitmask
& 0x00000004) {
2425 proto_tree_add_item(t
, hf_x11_foreground
, tvb
, *offsetp
, 4, byte_order
);
2428 if (bitmask
& 0x00000008) {
2429 proto_tree_add_item(t
, hf_x11_background
, tvb
, *offsetp
, 4, byte_order
);
2432 if (bitmask
& 0x00000010) {
2433 proto_tree_add_item(t
, hf_x11_line_width
, tvb
, *offsetp
, 2, byte_order
);
2435 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 2, ENC_NA
);
2438 if (bitmask
& 0x00000020) {
2439 proto_tree_add_item(t
, hf_x11_line_style
, tvb
, *offsetp
, 1, byte_order
);
2441 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 3, ENC_NA
);
2444 if (bitmask
& 0x00000040) {
2445 proto_tree_add_item(t
, hf_x11_cap_style
, tvb
, *offsetp
, 1, byte_order
);
2447 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 3, ENC_NA
);
2450 if (bitmask
& 0x00000080) {
2451 proto_tree_add_item(t
, hf_x11_join_style
, tvb
, *offsetp
, 1, byte_order
);
2453 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 3, ENC_NA
);
2456 if (bitmask
& 0x00000100) {
2457 proto_tree_add_item(t
, hf_x11_fill_style
, tvb
, *offsetp
, 1, byte_order
);
2459 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 3, ENC_NA
);
2462 if (bitmask
& 0x00000200) {
2463 proto_tree_add_item(t
, hf_x11_fill_rule
, tvb
, *offsetp
, 1, byte_order
);
2465 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 3, ENC_NA
);
2468 if (bitmask
& 0x00000400) {
2469 proto_tree_add_item(t
, hf_x11_tile
, tvb
, *offsetp
, 4, byte_order
);
2472 if (bitmask
& 0x00000800) {
2473 proto_tree_add_item(t
, hf_x11_stipple
, tvb
, *offsetp
, 4, byte_order
);
2476 if (bitmask
& 0x00001000) {
2477 proto_tree_add_item(t
, hf_x11_tile_stipple_x_origin
, tvb
, *offsetp
, 2, byte_order
);
2479 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 2, ENC_NA
);
2482 if (bitmask
& 0x00002000) {
2483 proto_tree_add_item(t
, hf_x11_tile_stipple_y_origin
, tvb
, *offsetp
, 2, byte_order
);
2485 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 2, ENC_NA
);
2488 if (bitmask
& 0x00004000) {
2489 proto_tree_add_item(t
, hf_x11_font
, tvb
, *offsetp
, 4, byte_order
);
2492 if (bitmask
& 0x00008000) {
2493 proto_tree_add_item(t
, hf_x11_subwindow_mode
, tvb
, *offsetp
, 1, byte_order
);
2495 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 3, ENC_NA
);
2498 if (bitmask
& 0x00010000) {
2499 proto_tree_add_item(t
, hf_x11_graphics_exposures
, tvb
, *offsetp
, 1, byte_order
);
2501 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 3, ENC_NA
);
2504 if (bitmask
& 0x00020000) {
2505 proto_tree_add_item(t
, hf_x11_clip_x_origin
, tvb
, *offsetp
, 2, byte_order
);
2507 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 2, ENC_NA
);
2510 if (bitmask
& 0x00040000) {
2511 proto_tree_add_item(t
, hf_x11_clip_y_origin
, tvb
, *offsetp
, 2, byte_order
);
2513 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 2, ENC_NA
);
2516 if (bitmask
& 0x00080000) {
2517 proto_tree_add_item(t
, hf_x11_clip_mask
, tvb
, *offsetp
, 4, byte_order
);
2520 if (bitmask
& 0x00100000) {
2521 proto_tree_add_item(t
, hf_x11_dash_offset
, tvb
, *offsetp
, 2, byte_order
);
2523 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 2, ENC_NA
);
2526 if (bitmask
& 0x00200000) {
2527 proto_tree_add_item(t
, hf_x11_gc_dashes
, tvb
, *offsetp
, 1, byte_order
);
2529 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 3, ENC_NA
);
2532 if (bitmask
& 0x00400000) {
2533 proto_tree_add_item(t
, hf_x11_arc_mode
, tvb
, *offsetp
, 1, byte_order
);
2535 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 3, ENC_NA
);
2540 static void gcMask(tvbuff_t
*tvb
, int *offsetp
, proto_tree
*t
,
2541 unsigned byte_order
)
2543 proto_tree_add_bitmask(t
, tvb
, *offsetp
, hf_x11_gc_value_mask
, ett_x11_gc_value_mask
, gc_mask_attributes
, byte_order
);
2547 static uint32_t requestLength(tvbuff_t
*tvb
, int *offsetp
, proto_tree
*t
,
2548 unsigned byte_order
)
2551 proto_item
*ti
= proto_tree_add_item_ret_uint(t
, hf_x11_request_length
, tvb
, *offsetp
, 2, byte_order
, &res
);
2554 proto_item_append_text(ti
, " (extended length flag)");
2555 proto_tree_add_item_ret_uint(t
, hf_x11_request_length
, tvb
, *offsetp
, 4, byte_order
, &res
);
2561 static void setOfEvent(tvbuff_t
*tvb
, int *offsetp
, proto_tree
*t
,
2562 unsigned byte_order
)
2564 static int * const events
[] = {
2565 &hf_x11_event_mask_KeyPress
,
2566 &hf_x11_event_mask_KeyRelease
,
2567 &hf_x11_event_mask_ButtonPress
,
2568 &hf_x11_event_mask_ButtonRelease
,
2569 &hf_x11_event_mask_EnterWindow
,
2570 &hf_x11_event_mask_LeaveWindow
,
2571 &hf_x11_event_mask_PointerMotion
,
2572 &hf_x11_event_mask_PointerMotionHint
,
2573 &hf_x11_event_mask_Button1Motion
,
2574 &hf_x11_event_mask_Button2Motion
,
2575 &hf_x11_event_mask_Button3Motion
,
2576 &hf_x11_event_mask_Button4Motion
,
2577 &hf_x11_event_mask_Button5Motion
,
2578 &hf_x11_event_mask_ButtonMotion
,
2579 &hf_x11_event_mask_KeymapState
,
2580 &hf_x11_event_mask_Exposure
,
2581 &hf_x11_event_mask_VisibilityChange
,
2582 &hf_x11_event_mask_StructureNotify
,
2583 &hf_x11_event_mask_ResizeRedirect
,
2584 &hf_x11_event_mask_SubstructureNotify
,
2585 &hf_x11_event_mask_SubstructureRedirect
,
2586 &hf_x11_event_mask_FocusChange
,
2587 &hf_x11_event_mask_PropertyChange
,
2588 &hf_x11_event_mask_ColormapChange
,
2589 &hf_x11_event_mask_OwnerGrabButton
,
2593 proto_tree_add_bitmask(t
, tvb
, *offsetp
, hf_x11_event_mask
, ett_x11_event_mask
, events
, byte_order
);
2597 static void setOfDeviceEvent(tvbuff_t
*tvb
, int *offsetp
, proto_tree
*t
,
2598 unsigned byte_order
)
2600 static int * const do_not_propagate_events
[] = {
2601 &hf_x11_do_not_propagate_mask_KeyPress
,
2602 &hf_x11_do_not_propagate_mask_KeyRelease
,
2603 &hf_x11_do_not_propagate_mask_ButtonPress
,
2604 &hf_x11_do_not_propagate_mask_ButtonRelease
,
2605 &hf_x11_do_not_propagate_mask_PointerMotion
,
2606 &hf_x11_do_not_propagate_mask_Button1Motion
,
2607 &hf_x11_do_not_propagate_mask_Button2Motion
,
2608 &hf_x11_do_not_propagate_mask_Button3Motion
,
2609 &hf_x11_do_not_propagate_mask_Button4Motion
,
2610 &hf_x11_do_not_propagate_mask_Button5Motion
,
2611 &hf_x11_do_not_propagate_mask_ButtonMotion
,
2615 proto_tree_add_bitmask(t
, tvb
, *offsetp
, hf_x11_do_not_propagate_mask
, ett_x11_do_not_propagate_mask
, do_not_propagate_events
, byte_order
);
2620 static void setOfKeyButMask(tvbuff_t
*tvb
, int *offsetp
, proto_tree
*t
,
2621 unsigned byte_order
, bool butmask
)
2624 uint32_t bitmask_value
;
2627 proto_tree
*bitmask_tree
;
2629 bitmask_value
= tvb_get_uint16(tvb
, *offsetp
, byte_order
);
2630 bitmask_offset
= *offsetp
;
2633 if (!butmask
&& bitmask_value
== 0x8000)
2634 proto_tree_add_uint_format(t
, hf_x11_modifiers_mask_AnyModifier
, tvb
, *offsetp
, 2, 0x8000,
2635 "modifiers-masks: 0x8000 (AnyModifier)");
2637 ti
= proto_tree_add_uint(t
, hf_x11_modifiers_mask
, tvb
, *offsetp
, 2,
2639 bitmask_tree
= proto_item_add_subtree(ti
, ett_x11_set_of_key_mask
);
2640 FLAG(modifiers
, Shift
);
2641 FLAG(modifiers
, Lock
);
2642 FLAG(modifiers
, Control
);
2643 FLAG(modifiers
, Mod1
);
2644 FLAG(modifiers
, Mod2
);
2645 FLAG(modifiers
, Mod3
);
2646 FLAG(modifiers
, Mod4
);
2647 FLAG(modifiers
, Mod5
);
2650 FLAG(modifiers
, Button1
);
2651 FLAG(modifiers
, Button2
);
2652 FLAG(modifiers
, Button3
);
2653 FLAG(modifiers
, Button4
);
2654 FLAG(modifiers
, Button5
);
2658 FLAG_IF_NONZERO(keybut
, erroneous_bits
);
2660 FLAG_IF_NONZERO(modifiers
, erroneous_bits
);
2665 static void setOfPointerEvent(tvbuff_t
*tvb
, int *offsetp
, proto_tree
*t
,
2666 unsigned byte_order
)
2668 static int * const pointer_events
[] = {
2669 &hf_x11_pointer_event_mask_ButtonRelease
,
2670 &hf_x11_pointer_event_mask_EnterWindow
,
2671 &hf_x11_pointer_event_mask_LeaveWindow
,
2672 &hf_x11_pointer_event_mask_PointerMotion
,
2673 &hf_x11_pointer_event_mask_PointerMotionHint
,
2674 &hf_x11_pointer_event_mask_Button1Motion
,
2675 &hf_x11_pointer_event_mask_Button2Motion
,
2676 &hf_x11_pointer_event_mask_Button3Motion
,
2677 &hf_x11_pointer_event_mask_Button4Motion
,
2678 &hf_x11_pointer_event_mask_Button5Motion
,
2679 &hf_x11_pointer_event_mask_ButtonMotion
,
2680 &hf_x11_pointer_event_mask_KeymapState
,
2684 proto_tree_add_bitmask(t
, tvb
, *offsetp
, hf_x11_pointer_event_mask
, ett_x11_pointer_event_mask
, pointer_events
, byte_order
);
2688 static void string8(tvbuff_t
*tvb
, int *offsetp
, proto_tree
*t
,
2689 int hf
, unsigned length
)
2691 proto_tree_add_item(t
, hf
, tvb
, *offsetp
, length
, ENC_NA
|ENC_ASCII
);
2695 /* The length supplied is the length of the string in CHAR2Bs (half the number of bytes) */
2697 static void string16(tvbuff_t
*tvb
, int *offsetp
, proto_tree
*t
, int hf
,
2698 int hf_bytes
, unsigned length
, unsigned byte_order
)
2700 unsigned l
= length
*2; /* byte count */
2703 if (stringIsActuallyAn8BitString(tvb
, *offsetp
, length
)) {
2704 s
= tvb_get_ascii_string16(tvb
, *offsetp
, length
);
2705 proto_tree_add_string_format_value(t
, hf
, tvb
, *offsetp
, l
, s
, "\"%s\"", s
);
2707 proto_tree_add_item(t
, hf_bytes
, tvb
, *offsetp
, l
, byte_order
);
2712 static void timestamp(tvbuff_t
*tvb
, int *offsetp
, proto_tree
*t
, int hf
,
2713 unsigned byte_order
)
2715 uint32_t v
= tvb_get_uint32(tvb
, *offsetp
, byte_order
);
2718 proto_tree_add_uint_format(t
, hf
, tvb
, *offsetp
, 4, 0, "%s: 0 (CurrentTime)",
2719 proto_registrar_get_nth(hf
) -> name
);
2721 proto_tree_add_uint(t
, hf
, tvb
, *offsetp
, 4, v
);
2725 static void windowAttributes(tvbuff_t
*tvb
, int *offsetp
, proto_tree
*t
,
2726 unsigned byte_order
)
2729 static int * const window_attributes_flags
[] = {
2730 &hf_x11_window_value_mask_background_pixmap
,
2731 &hf_x11_window_value_mask_background_pixel
,
2732 &hf_x11_window_value_mask_border_pixmap
,
2733 &hf_x11_window_value_mask_border_pixel
,
2734 &hf_x11_window_value_mask_bit_gravity
,
2735 &hf_x11_window_value_mask_win_gravity
,
2736 &hf_x11_window_value_mask_backing_store
,
2737 &hf_x11_window_value_mask_backing_planes
,
2738 &hf_x11_window_value_mask_backing_pixel
,
2739 &hf_x11_window_value_mask_override_redirect
,
2740 &hf_x11_window_value_mask_save_under
,
2741 &hf_x11_window_value_mask_event_mask
,
2742 &hf_x11_window_value_mask_do_not_propagate_mask
,
2743 &hf_x11_window_value_mask_colormap
,
2744 &hf_x11_window_value_mask_cursor
,
2748 bitmask
= tvb_get_uint32(tvb
, *offsetp
, byte_order
);
2749 proto_tree_add_bitmask(t
, tvb
, *offsetp
, hf_x11_window_value_mask
, ett_x11_window_value_mask
, window_attributes_flags
, byte_order
);
2752 if (bitmask
& 0x00000001) {
2753 proto_tree_add_item(t
, hf_x11_background_pixmap
, tvb
, *offsetp
, 4, byte_order
);
2756 if (bitmask
& 0x00000002) {
2757 proto_tree_add_item(t
, hf_x11_background_pixel
, tvb
, *offsetp
, 4, byte_order
);
2760 if (bitmask
& 0x00000004) {
2761 proto_tree_add_item(t
, hf_x11_border_pixmap
, tvb
, *offsetp
, 4, byte_order
);
2764 if (bitmask
& 0x00000008) {
2765 proto_tree_add_item(t
, hf_x11_border_pixel
, tvb
, *offsetp
, 4, byte_order
);
2768 if (bitmask
& 0x00000010) {
2769 proto_tree_add_item(t
, hf_x11_bit_gravity
, tvb
, *offsetp
, 1, byte_order
);
2771 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 3, ENC_NA
);
2774 if (bitmask
& 0x00000020) {
2775 proto_tree_add_item(t
, hf_x11_win_gravity
, tvb
, *offsetp
, 1, byte_order
);
2777 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 3, ENC_NA
);
2780 if (bitmask
& 0x00000040) {
2781 proto_tree_add_item(t
, hf_x11_backing_store
, tvb
, *offsetp
, 1, byte_order
);
2783 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 3, ENC_NA
);
2786 if (bitmask
& 0x00000080) {
2787 proto_tree_add_item(t
, hf_x11_backing_planes
, tvb
, *offsetp
, 4, byte_order
);
2790 if (bitmask
& 0x00000100) {
2791 proto_tree_add_item(t
, hf_x11_backing_pixel
, tvb
, *offsetp
, 4, byte_order
);
2794 if (bitmask
& 0x00000200) {
2795 proto_tree_add_item(t
, hf_x11_override_redirect
, tvb
, *offsetp
, 1, byte_order
);
2797 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 3, ENC_NA
);
2800 if (bitmask
& 0x00000400) {
2801 proto_tree_add_item(t
, hf_x11_save_under
, tvb
, *offsetp
, 1, byte_order
);
2803 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 3, ENC_NA
);
2806 if (bitmask
& 0x00000800) {
2807 setOfEvent(tvb
, offsetp
, t
, byte_order
);
2809 if (bitmask
& 0x00001000) {
2810 setOfDeviceEvent(tvb
, offsetp
, t
, byte_order
);
2812 if (bitmask
& 0x00002000) {
2813 proto_tree_add_item(t
, hf_x11_colormap
, tvb
, *offsetp
, 4, byte_order
);
2816 if (bitmask
& 0x00004000) {
2817 proto_tree_add_item(t
, hf_x11_cursor
, tvb
, *offsetp
, 4, byte_order
);
2822 /************************************************************************
2824 *** G U E S S I N G T H E B Y T E O R D E R I N G ***
2826 ************************************************************************/
2828 /* If we can't guess, we return ENC_LITTLE_ENDIAN, cause
2829 I'm developing on a Linux box :-). The (non-)guess isn't cached
2830 however, so we may have more luck next time. I'm quite conservative
2831 in my assertions, cause once it's cached, it stays in cache, and
2832 we may be fooled up by a packet starting with the end of a request
2833 started in a previous packet...
2836 static int numberOfBitSetTable
[] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
2838 static int numberOfBitSet(tvbuff_t
*tvb
, int offset
, int maskLength
)
2841 while(maskLength
--) {
2842 int c
= tvb_get_uint8(tvb
, offset
);
2844 res
+= numberOfBitSetTable
[c
& 0xf] + numberOfBitSetTable
[c
>> 4];
2849 static int listOfStringLengthConsistent(tvbuff_t
*tvb
, int offset
, int length
, int listLength
)
2851 if (listLength
> length
) return false;
2852 while(listLength
--) {
2854 if (!tvb_bytes_exist(tvb
, offset
, 1)) return true;
2855 l
= tvb_get_uint8(tvb
, offset
);
2858 if (l
> length
) return false;
2859 if (!tvb_bytes_exist(tvb
, offset
, l
)) return true;
2863 if (length
> 3) return false;
2867 static int rounded4(int n
)
2869 int remainder
= n
% 4;
2871 if (remainder
) res
++;
2875 /* We assume the order to be consistent, until proven wrong. */
2877 static bool consistentWithOrder(int length
, tvbuff_t
*tvb
, int offset
, int encoding
)
2879 switch(tvb_get_uint8(tvb
, offset
)) {
2880 case X_CreateWindow
:
2881 return !tvb_bytes_exist(tvb
, offset
, 32) || length
== 8 + numberOfBitSet(tvb
, offset
+ 7 * 4, 4);
2883 case X_ChangeWindowAttributes
:
2885 return !tvb_bytes_exist(tvb
, offset
, 12) || length
== 3 + numberOfBitSet(tvb
, offset
+ 8, 4);
2887 case X_GetWindowAttributes
:
2888 case X_DestroyWindow
:
2889 case X_DestroySubwindows
:
2890 case X_ChangeSaveSet
:
2892 case X_MapSubwindows
:
2894 case X_UnmapSubwindows
:
2895 case X_CirculateWindow
:
2899 case X_ListProperties
:
2900 case X_GetSelectionOwner
:
2901 case X_UngrabPointer
:
2902 case X_UngrabKeyboard
:
2904 case X_QueryPointer
:
2909 case X_FreeColormap
:
2910 case X_InstallColormap
:
2911 case X_UninstallColormap
:
2912 case X_ListInstalledColormaps
:
2914 case X_GetKeyboardMapping
:
2918 case X_ReparentWindow
:
2919 case X_SetSelectionOwner
:
2920 case X_ChangeActivePointerGrab
:
2921 case X_GrabKeyboard
:
2923 case X_GetMotionEvents
:
2924 case X_TranslateCoords
:
2925 case X_CreatePixmap
:
2928 case X_CreateColormap
:
2930 case X_AllocColorPlanes
:
2933 case X_ConfigureWindow
:
2934 return !tvb_bytes_exist(tvb
, offset
, 10) || length
== 3 + numberOfBitSet(tvb
, offset
+ 8, 2);
2937 case X_QueryExtension
:
2938 return !tvb_bytes_exist(tvb
, offset
, 6) || length
== 2 + rounded4(tvb_get_uint16(tvb
, offset
+ 4, encoding
));
2940 case X_ChangeProperty
:
2942 int multiplier
, type
;
2943 if (!tvb_bytes_exist(tvb
, offset
, 17)) return true;
2944 type
= tvb_get_uint8(tvb
, 16);
2945 if (type
!= 8 && type
!= 16 && type
!= 32) return false;
2946 multiplier
= type
== 8 ? 1 : type
== 16 ? 2 : 4;
2947 if (!tvb_bytes_exist(tvb
, offset
, 24)) return true;
2948 return length
== 6 + rounded4(tvb_get_uint32(tvb
, offset
+ 20, encoding
) * multiplier
);
2951 case X_DeleteProperty
:
2952 case X_UngrabButton
:
2954 case X_SetInputFocus
:
2955 case X_CopyColormapAndFree
:
2956 case X_AllocColorCells
:
2957 case X_QueryBestSize
:
2958 case X_ChangePointerControl
:
2959 case X_SetScreenSaver
:
2963 case X_ConvertSelection
:
2970 return length
== 11;
2973 case X_UngrabServer
:
2974 case X_GetInputFocus
:
2977 case X_ListExtensions
:
2978 case X_GetKeyboardControl
:
2980 case X_GetPointerControl
:
2981 case X_GetScreenSaver
:
2983 case X_SetAccessControl
:
2984 case X_SetCloseDownMode
:
2985 case X_ForceScreenSaver
:
2986 case X_GetPointerMapping
:
2987 case X_GetModifierMapping
:
2991 case X_AllocNamedColor
:
2993 return !tvb_bytes_exist(tvb
, offset
, 10) || length
== 3 + rounded4(tvb_get_uint16(tvb
, offset
+ 8, encoding
));
2995 case X_QueryTextExtents
:
2999 case X_ListFontsWithInfo
:
3001 return !tvb_bytes_exist(tvb
, offset
, 8) || length
== 2 + rounded4(tvb_get_uint16(tvb
, offset
+ 6, encoding
));
3004 if (length
< 2) return false;
3005 if (!tvb_bytes_exist(tvb
, offset
, 8)) return true;
3006 return listOfStringLengthConsistent(tvb
, offset
+ 8, (length
- 2) * 4, tvb_get_uint16(tvb
, offset
+ 4, encoding
));
3009 return !tvb_bytes_exist(tvb
, offset
, 16) || length
== 4 + numberOfBitSet(tvb
, offset
+ 12, 4);
3012 return !tvb_bytes_exist(tvb
, offset
, 12) || length
== 3 + rounded4(tvb_get_uint16(tvb
, offset
+ 10, encoding
));
3014 case X_SetClipRectangles
:
3016 case X_PolyRectangle
:
3017 case X_PolyFillRectangle
:
3018 return length
>= 3 && (length
- 3) % 2 == 0;
3024 case X_CreateCursor
:
3025 case X_CreateGlyphCursor
:
3035 return length
>= 3 && (length
- 3) % 3 == 0;
3045 case X_RecolorCursor
:
3049 if (length
< 4) return false;
3050 return true; /* We don't perform many controls on this one */
3053 if (length
< 4) return false;
3054 return true; /* We don't perform many controls on this one */
3060 return length
> 2 && (length
- 2) % 3 == 0;
3062 case X_StoreNamedColor
:
3063 return !tvb_bytes_exist(tvb
, offset
, 14) || length
== 4 + rounded4(tvb_get_uint16(tvb
, offset
+ 12, encoding
));
3068 case X_ChangeKeyboardMapping
:
3069 return !tvb_bytes_exist(tvb
, offset
, 6) || length
== 2 + tvb_get_uint8(tvb
, 1) * tvb_get_uint8(tvb
, 5);
3071 case X_ChangeKeyboardControl
:
3072 return !tvb_bytes_exist(tvb
, offset
, 6) || length
== 2 + numberOfBitSet(tvb
, offset
+ 4, 2);
3074 case X_RotateProperties
:
3075 return !tvb_bytes_exist(tvb
, offset
, 10) || length
== 3 + tvb_get_uint16(tvb
, offset
+ 8, encoding
);
3077 case X_SetPointerMapping
:
3078 return length
== 1 + rounded4(tvb_get_uint8(tvb
, 1));
3080 case X_SetModifierMapping
:
3081 return length
== 1 + tvb_get_uint8(tvb
, 1) * 2;
3091 /* -1 means doesn't match, +1 means match, 0 means don't know */
3093 static int x_endian_match(tvbuff_t
*tvb
, int encoding
)
3095 int offset
, nextoffset
;
3098 for(offset
= 0; tvb_bytes_exist(tvb
, offset
, 4); offset
= nextoffset
) {
3100 length
= tvb_get_uint16(tvb
, offset
+ 2, encoding
);
3103 nextoffset
= offset
+ length
* 4;
3104 if (!consistentWithOrder(length
, tvb
, offset
, encoding
))
3112 guess_byte_ordering(tvbuff_t
*tvb
, packet_info
*pinfo
,
3113 x11_conv_data_t
*state
)
3115 /* With X the client gives the byte ordering for the protocol,
3116 and the port on the server tells us we're speaking X. */
3121 if (state
->byte_order
== ENC_BIG_ENDIAN
)
3122 return ENC_BIG_ENDIAN
; /* known to be big-endian */
3123 else if (state
->byte_order
== ENC_LITTLE_ENDIAN
)
3124 return ENC_LITTLE_ENDIAN
; /* known to be little-endian */
3126 if (pinfo
->srcport
== pinfo
->match_uint
) {
3128 * This is a reply or event; we don't try to guess the
3129 * byte order on it for now.
3131 return ENC_LITTLE_ENDIAN
;
3134 le
= x_endian_match(tvb
, ENC_LITTLE_ENDIAN
);
3135 be
= x_endian_match(tvb
, ENC_BIG_ENDIAN
);
3138 /* We have no reason to believe it's little- rather than
3139 big-endian, so we guess the shortest length is the
3142 if (!tvb_bytes_exist(tvb
, 0, 4))
3143 /* Not even a way to get the length. We're biased
3144 toward little endianness here (essentially the
3145 x86 world right now). Decoding won't go very far
3148 decision
= ENC_LITTLE_ENDIAN
;
3150 if (tvb_get_letohs(tvb
, 2) <= tvb_get_ntohs(tvb
, 2))
3151 decision
= ENC_LITTLE_ENDIAN
;
3153 decision
= ENC_BIG_ENDIAN
;
3157 decision
= ENC_LITTLE_ENDIAN
;
3159 decision
= ENC_BIG_ENDIAN
;
3162 if ((le
< 0 && be
> 0) || (le
> 0 && be
< 0)) {
3164 * Remember the decision.
3166 state
->byte_order
= decision
;
3172 /************************************************************************
3174 *** D E C O D I N G O N E P A C K E T ***
3176 ************************************************************************/
3179 * Decode an initial connection request.
3181 static void dissect_x11_initial_conn(tvbuff_t
*tvb
, packet_info
*pinfo
,
3182 proto_tree
*tree
, x11_conv_data_t
*state
, unsigned byte_order
)
3185 int *offsetp
= &offset
;
3188 uint16_t auth_proto_name_length
, auth_proto_data_length
;
3191 ti
= proto_tree_add_item(tree
, proto_x11
, tvb
, 0, -1, ENC_NA
);
3192 proto_item_append_text(ti
, ", Request, Initial connection request");
3193 t
= proto_item_add_subtree(ti
, ett_x11
);
3196 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
3198 CARD16(protocol_major_version
);
3199 CARD16(protocol_minor_version
);
3200 auth_proto_name_length
= CARD16(authorization_protocol_name_length
);
3201 auth_proto_data_length
= CARD16(authorization_protocol_data_length
);
3202 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 2, ENC_NA
);
3205 if (auth_proto_name_length
!= 0) {
3206 STRING8(authorization_protocol_name
, auth_proto_name_length
);
3207 offset
= ROUND_LENGTH(offset
);
3210 if (auth_proto_data_length
!= 0) {
3211 STRING8(authorization_protocol_data
, auth_proto_data_length
);
3212 offset
= ROUND_LENGTH(offset
);
3215 if ((left
= tvb_reported_length_remaining(tvb
, offset
)) > 0)
3216 proto_tree_add_item(t
, hf_x11_undecoded
, tvb
, offset
, left
,
3220 * This is the initial connection request...
3222 state
->iconn_frame
= pinfo
->num
;
3225 * ...and we're expecting a reply to it.
3227 state
->sequencenumber
= 0;
3228 wmem_map_insert(state
->seqtable
, GINT_TO_POINTER(state
->sequencenumber
),
3229 (int *)INITIAL_CONN
);
3232 static void dissect_x11_initial_reply(tvbuff_t
*tvb
, packet_info
*pinfo
,
3233 proto_tree
*tree
, const char _U_
*sep
, x11_conv_data_t
*state
,
3234 unsigned byte_order
)
3236 int offset
= 0, *offsetp
= &offset
, left
;
3237 unsigned char success
;
3238 int length_of_vendor
;
3239 int length_of_reason
;
3240 int number_of_formats_in_pixmap_formats
;
3241 int number_of_screens_in_roots
;
3246 ti
= proto_tree_add_item(tree
, proto_x11
, tvb
, 0, -1, ENC_NA
);
3247 proto_item_append_text(ti
, ", Reply, Initial connection reply");
3248 t
= proto_item_add_subtree(ti
, ett_x11
);
3250 state
->iconn_reply
= pinfo
->num
;
3251 success
= INT8(success
);
3253 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
3255 length_of_reason
= 0;
3258 length_of_reason
= INT8(length_of_reason
);
3261 INT16(protocol_major_version
);
3262 INT16(protocol_minor_version
);
3265 INT32(release_number
);
3266 INT32(resource_id_base
);
3267 INT32(resource_id_mask
);
3268 INT32(motion_buffer_size
);
3269 length_of_vendor
= INT16(length_of_vendor
);
3270 INT16(maximum_request_length
);
3271 number_of_screens_in_roots
= INT8(number_of_screens_in_roots
);
3272 number_of_formats_in_pixmap_formats
= INT8(number_of_formats_in_pixmap_formats
);
3273 INT8(image_byte_order
);
3274 INT8(bitmap_format_bit_order
);
3275 INT8(bitmap_format_scanline_unit
);
3276 INT8(bitmap_format_scanline_pad
);
3279 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 4, ENC_NA
);
3281 STRING8(vendor
, length_of_vendor
);
3282 unused
= (4 - (length_of_vendor
% 4)) % 4;
3284 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, unused
, ENC_NA
);
3287 LISTofPIXMAPFORMAT(pixmap_format
, number_of_formats_in_pixmap_formats
);
3288 LISTofSCREEN(screen
, number_of_screens_in_roots
);
3290 STRING8(reason
, length_of_reason
);
3293 if ((left
= tvb_reported_length_remaining(tvb
, offset
)) > 0)
3298 typedef struct x11_reply_info
{
3299 const uint8_t minor
;
3300 void (*dissect
)(tvbuff_t
*tvb
, packet_info
*pinfo
, int *offsetp
, proto_tree
*t
, unsigned byte_order
);
3303 typedef struct event_info
{
3305 void (*dissect
)(tvbuff_t
*tvb
, int *offsetp
, proto_tree
*t
, unsigned byte_order
);
3308 typedef struct x11_generic_event_info
{
3309 const uint16_t minor
;
3310 void (*dissect
)(tvbuff_t
*tvb
, int length
, int *offsetp
, proto_tree
*t
, unsigned byte_order
);
3311 } x11_generic_event_info
;
3313 static void set_handler(const char *name
, void (*func
)(tvbuff_t
*tvb
, packet_info
*pinfo
, int *offsetp
, proto_tree
*t
, unsigned byte_order
),
3314 const char * const *errors
,
3315 const x11_event_info
*event_info
,
3316 const x11_generic_event_info
*genevent_info
,
3317 const x11_reply_info
*reply_info
)
3319 wmem_map_insert(extension_table
, (void *)name
, (void *)func
);
3320 wmem_map_insert(error_table
, (void *)name
, (void *)errors
);
3321 wmem_map_insert(event_table
, (void *)name
, (void *)event_info
);
3323 wmem_map_insert(genevent_table
, (void *)name
, (void *)genevent_info
);
3324 wmem_map_insert(reply_table
, (void *)name
, (void *)reply_info
);
3327 #include "x11-extension-errors.h"
3328 #include "x11-extension-implementation.h"
3330 static void tryExtension(int opcode
, tvbuff_t
*tvb
, packet_info
*pinfo
, int *offsetp
, proto_tree
*t
,
3331 x11_conv_data_t
*state
, unsigned byte_order
)
3333 const char *extension
;
3334 void (*func
)(tvbuff_t
*tvb
, packet_info
*pinfo
, int *offsetp
, proto_tree
*t
, unsigned byte_order
);
3336 extension
= try_val_to_str(opcode
, state
->opcode_vals
);
3340 func
= (void (*)(tvbuff_t
*, packet_info
*, int *, proto_tree
*, unsigned))wmem_map_lookup(extension_table
, extension
);
3342 func(tvb
, pinfo
, offsetp
, t
, byte_order
);
3345 static void tryExtensionReply(int opcode
, tvbuff_t
*tvb
, packet_info
*pinfo
, int *offsetp
, proto_tree
*t
,
3346 x11_conv_data_t
*state
, unsigned byte_order
)
3348 void (*func
)(tvbuff_t
*tvb
, packet_info
*pinfo
, int *offsetp
, proto_tree
*t
, unsigned byte_order
);
3350 func
= (void (*)(tvbuff_t
*, packet_info
*, int *, proto_tree
*, unsigned))wmem_map_lookup(state
->reply_funcs
, GINT_TO_POINTER(opcode
));
3352 func(tvb
, pinfo
, offsetp
, t
, byte_order
);
3354 REPLYCONTENTS_COMMON();
3357 static void tryExtensionEvent(int event
, tvbuff_t
*tvb
, int *offsetp
, proto_tree
*t
,
3358 x11_conv_data_t
*state
, unsigned byte_order
)
3360 void (*func
)(tvbuff_t
*tvb
, int *offsetp
, proto_tree
*t
, unsigned byte_order
);
3362 func
= (void (*)(tvbuff_t
*, int *, proto_tree
*, unsigned))wmem_map_lookup(state
->eventcode_funcs
, GINT_TO_POINTER(event
));
3364 func(tvb
, offsetp
, t
, byte_order
);
3367 static void tryGenericExtensionEvent(tvbuff_t
*tvb
, int *offsetp
, proto_tree
*t
,
3368 x11_conv_data_t
*state
, unsigned byte_order
)
3370 const char *extname
;
3371 int extension
, length
;
3373 extension
= tvb_get_uint8(tvb
, *offsetp
);
3375 extname
= try_val_to_str(extension
, state
->opcode_vals
);
3378 proto_tree_add_uint_format(t
, hf_x11_extension
, tvb
, *offsetp
, 1, extension
, "extension: %d (%s)", extension
, extname
);
3380 proto_tree_add_uint(t
, hf_x11_extension
, tvb
, *offsetp
, 1, extension
);
3383 CARD16(event_sequencenumber
);
3385 length
= REPLYLENGTH(eventlength
);
3386 length
= length
* 4 + 32;
3390 x11_generic_event_info
*info
;
3391 info
= (x11_generic_event_info
*)wmem_map_lookup(genevent_table
, extname
);
3396 int opcode
= tvb_get_uint16(tvb
, *offsetp
, byte_order
);
3398 for (i
= 0; info
[i
].dissect
!= NULL
; i
++) {
3399 if (info
[i
].minor
== opcode
) {
3401 info
[i
].dissect(tvb
, length
, offsetp
, t
, byte_order
);
3407 CARD16(minor_opcode
);
3410 static void register_extension(x11_conv_data_t
*state
, value_string
*vals_p
,
3411 int major_opcode
, unsigned int first_event
, unsigned int first_error
)
3413 const char * const *error_string
;
3414 x11_event_info
*event_info
;
3415 x11_reply_info
*reply_info
;
3418 vals_p
->value
= major_opcode
;
3420 error_string
= (const char * const *)wmem_map_lookup(error_table
, vals_p
->strptr
);
3421 while (error_string
&& *error_string
&& first_error
<= LastExtensionError
) {
3422 /* store string of extension error */
3423 for (i
= 0; i
<= LastExtensionError
; i
++) {
3424 if (state
->errorcode_vals
[i
].strptr
== NULL
) {
3425 state
->errorcode_vals
[i
].value
= first_error
;
3426 state
->errorcode_vals
[i
].strptr
= *error_string
;
3428 } else if (state
->errorcode_vals
[i
].value
== first_error
) {
3429 /* TODO: Warn about extensions stepping on each other */
3430 state
->errorcode_vals
[i
].strptr
= *error_string
;
3438 event_info
= (x11_event_info
*)wmem_map_lookup(event_table
, vals_p
->strptr
);
3439 while (event_info
&& event_info
->name
&& first_event
<= LastExtensionEvent
) {
3440 /* store string of extension event */
3441 for (i
= 0; i
<= LastExtensionEvent
; i
++) {
3442 if (state
->eventcode_vals
[i
].strptr
== NULL
) {
3443 state
->eventcode_vals
[i
].value
= first_event
;
3444 state
->eventcode_vals
[i
].strptr
= event_info
->name
;
3446 } else if (state
->eventcode_vals
[i
].value
== first_event
) {
3447 /* TODO: Warn about extensions stepping on each other */
3448 state
->eventcode_vals
[i
].strptr
= event_info
->name
;
3453 /* store event decode function */
3454 wmem_map_insert(state
->eventcode_funcs
, GINT_TO_POINTER(first_event
), (void *)event_info
->dissect
);
3460 reply_info
= (x11_reply_info
*)wmem_map_lookup(reply_table
, vals_p
->strptr
);
3462 for (i
= 0; reply_info
[i
].dissect
; i
++)
3463 wmem_map_insert(state
->reply_funcs
,
3464 GINT_TO_POINTER(major_opcode
| (reply_info
[i
].minor
<< 8)),
3465 (void *)reply_info
[i
].dissect
);
3469 static void dissect_x11_request(tvbuff_t
*tvb
, packet_info
*pinfo
,
3470 proto_tree
*tree
, const char *sep
, x11_conv_data_t
*state
,
3471 unsigned byte_order
)
3474 int *offsetp
= &offset
;
3475 int query_ext_offset
;
3479 int length
, opcode
, i
;
3480 uint8_t v8
, v8_2
, v8_3
;
3486 query_ext_offset
= 2; /* "opcode" and "unused" */
3488 length
= tvb_get_uint16(tvb
, query_ext_offset
, byte_order
) * 4;
3489 query_ext_offset
+= 2;
3492 /* BIG-REQUESTS extension */
3493 length
= tvb_get_uint32(tvb
, query_ext_offset
, byte_order
);
3494 if ((int64_t)length
* 4 > INT32_MAX
)
3497 query_ext_offset
+= 4;
3501 /* Bogus message length? */
3505 next_offset
= offset
+ length
;
3507 ti
= proto_tree_add_item(tree
, proto_x11
, tvb
, 0, -1, ENC_NA
);
3508 t
= proto_item_add_subtree(ti
, ett_x11
);
3510 if (!pinfo
->fd
->visited
)
3511 ++state
->sequencenumber
;
3515 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "%s %s", sep
,
3516 val_to_str(opcode
, state
->opcode_vals
,
3517 "<Unknown opcode %d>"));
3519 proto_item_append_text(ti
, ", Request, opcode: %d (%s)",
3520 opcode
, val_to_str(opcode
, state
->opcode_vals
,
3521 "<Unknown opcode %d>"));
3524 * Does this request expect a reply?
3528 case X_QueryExtension
:
3530 /* necessary processing even if tree == NULL */
3532 v16
= tvb_get_uint16(tvb
, query_ext_offset
, byte_order
);
3533 query_ext_offset
+= 2;
3534 /* Some unused bytes */
3535 query_ext_offset
+= 2;
3536 name
= tvb_get_string_enc(wmem_file_scope(), tvb
, query_ext_offset
, v16
, ENC_ASCII
);
3538 /* store string of extension, opcode will be set at reply */
3540 while(i
< MAX_OPCODES
) {
3541 if (state
->opcode_vals
[i
].strptr
== NULL
) {
3542 state
->opcode_vals
[i
].strptr
= name
;
3543 state
->opcode_vals
[i
].value
= -1;
3544 wmem_map_insert(state
->valtable
,
3545 GINT_TO_POINTER(state
->sequencenumber
),
3546 (int *)&state
->opcode_vals
[i
]);
3548 } else if (strcmp(state
->opcode_vals
[i
].strptr
,
3550 wmem_map_insert(state
->valtable
,
3551 GINT_TO_POINTER(state
->sequencenumber
),
3552 (int *)&state
->opcode_vals
[i
]);
3558 /* QueryExtension expects a reply, fall through */
3561 case X_AllocColorCells
:
3562 case X_AllocColorPlanes
:
3563 case X_AllocNamedColor
:
3568 case X_GetInputFocus
:
3569 case X_GetKeyboardControl
:
3570 case X_GetKeyboardMapping
:
3571 case X_GetModifierMapping
:
3572 case X_GetMotionEvents
:
3573 case X_GetPointerControl
:
3574 case X_GetPointerMapping
:
3576 case X_GetScreenSaver
:
3577 case X_GetSelectionOwner
:
3578 case X_GetWindowAttributes
:
3579 case X_GrabKeyboard
:
3582 case X_ListExtensions
:
3584 case X_ListFontsWithInfo
:
3586 case X_ListInstalledColormaps
:
3587 case X_ListProperties
:
3589 case X_QueryBestSize
:
3593 case X_QueryPointer
:
3594 case X_QueryTextExtents
:
3596 case X_SetModifierMapping
:
3597 case X_SetPointerMapping
:
3598 case X_TranslateCoords
:
3600 * Those requests expect a reply.
3602 wmem_map_insert(state
->seqtable
,
3603 GINT_TO_POINTER(state
->sequencenumber
),
3604 GINT_TO_POINTER(opcode
));
3610 * With Extension, we don't know, so assume there could be one
3612 if (opcode
>= X_FirstExtension
&& opcode
<= X_LastExtension
) {
3614 minor
= tvb_get_uint8(tvb
, 1);
3616 wmem_map_insert(state
->seqtable
,
3617 GINT_TO_POINTER(state
->sequencenumber
),
3618 GINT_TO_POINTER(opcode
| (minor
<< 8)));
3622 * No reply is expected from any other request.
3632 case X_CreateWindow
:
3634 requestLength(tvb
, offsetp
, t
, byte_order
);
3641 CARD16(border_width
);
3642 ENUM16(window_class
);
3644 windowAttributes(tvb
, offsetp
, t
, byte_order
);
3647 case X_ChangeWindowAttributes
:
3648 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
3650 requestLength(tvb
, offsetp
, t
, byte_order
);
3652 windowAttributes(tvb
, offsetp
, t
, byte_order
);
3655 case X_GetWindowAttributes
:
3656 case X_DestroyWindow
:
3657 case X_DestroySubwindows
:
3658 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
3660 requestLength(tvb
, offsetp
, t
, byte_order
);
3664 case X_ChangeSaveSet
:
3665 ENUM8(save_set_mode
);
3666 requestLength(tvb
, offsetp
, t
, byte_order
);
3670 case X_ReparentWindow
:
3671 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
3673 requestLength(tvb
, offsetp
, t
, byte_order
);
3681 case X_MapSubwindows
:
3683 case X_UnmapSubwindows
:
3684 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
3686 requestLength(tvb
, offsetp
, t
, byte_order
);
3690 case X_ConfigureWindow
:
3693 static int * const configure_window_mask_flags
[] = {
3694 &hf_x11_configure_window_mask_x
,
3695 &hf_x11_configure_window_mask_y
,
3696 &hf_x11_configure_window_mask_width
,
3697 &hf_x11_configure_window_mask_height
,
3698 &hf_x11_configure_window_mask_border_width
,
3699 &hf_x11_configure_window_mask_sibling
,
3700 &hf_x11_configure_window_mask_stack_mode
,
3704 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
3706 requestLength(tvb
, offsetp
, t
, byte_order
);
3707 proto_tree_add_item(t
, hf_x11_window
, tvb
, *offsetp
, 4, byte_order
);
3709 bitmask16
= tvb_get_uint16(tvb
, *offsetp
, byte_order
);
3710 proto_tree_add_bitmask(t
, tvb
, *offsetp
, hf_x11_configure_window_mask
, ett_x11_configure_window_mask
, configure_window_mask_flags
, byte_order
);
3712 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 2, ENC_NA
);
3714 if (bitmask16
& 0x0001) {
3715 proto_tree_add_item(t
, hf_x11_x
, tvb
, *offsetp
, 2, byte_order
);
3717 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 2, ENC_NA
);
3720 if (bitmask16
& 0x0002) {
3721 proto_tree_add_item(t
, hf_x11_y
, tvb
, *offsetp
, 2, byte_order
);
3723 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 2, ENC_NA
);
3726 if (bitmask16
& 0x0004) {
3727 proto_tree_add_item(t
, hf_x11_width
, tvb
, *offsetp
, 2, byte_order
);
3729 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 2, ENC_NA
);
3732 if (bitmask16
& 0x0008) {
3733 proto_tree_add_item(t
, hf_x11_height
, tvb
, *offsetp
, 2, byte_order
);
3735 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 2, ENC_NA
);
3738 if (bitmask16
& 0x0010) {
3739 proto_tree_add_item(t
, hf_x11_border_width
, tvb
, *offsetp
, 2, byte_order
);
3741 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 2, ENC_NA
);
3744 if (bitmask16
& 0x0020) {
3745 proto_tree_add_item(t
, hf_x11_sibling
, tvb
, *offsetp
, 4, byte_order
);
3748 if (bitmask16
& 0x0040) {
3749 proto_tree_add_item(t
, hf_x11_stack_mode
, tvb
, *offsetp
, 1, byte_order
);
3751 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 3, ENC_NA
);
3754 if (next_offset
- *offsetp
> 0) {
3755 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, next_offset
- *offsetp
, ENC_NA
);
3756 *offsetp
= next_offset
;
3761 case X_CirculateWindow
:
3763 requestLength(tvb
, offsetp
, t
, byte_order
);
3769 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
3771 requestLength(tvb
, offsetp
, t
, byte_order
);
3776 BOOL(only_if_exists
);
3777 requestLength(tvb
, offsetp
, t
, byte_order
);
3778 v16
= FIELD16(name_length
);
3779 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 2, ENC_NA
);
3786 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
3788 requestLength(tvb
, offsetp
, t
, byte_order
);
3792 case X_ChangeProperty
:
3794 requestLength(tvb
, offsetp
, t
, byte_order
);
3799 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 3, ENC_NA
);
3801 v32
= CARD32(data_length
);
3805 LISTofBYTE(data
, v32
);
3809 LISTofCARD16(data16
, v32
* 2);
3813 LISTofCARD32(data32
, v32
* 4);
3816 expert_add_info(pinfo
, ti
, &ei_x11_invalid_format
);
3822 case X_DeleteProperty
:
3823 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
3825 requestLength(tvb
, offsetp
, t
, byte_order
);
3832 requestLength(tvb
, offsetp
, t
, byte_order
);
3835 ATOM(get_property_type
);
3836 CARD32(long_offset
);
3837 CARD32(long_length
);
3840 case X_ListProperties
:
3841 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
3843 requestLength(tvb
, offsetp
, t
, byte_order
);
3847 case X_SetSelectionOwner
:
3848 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
3850 requestLength(tvb
, offsetp
, t
, byte_order
);
3856 case X_GetSelectionOwner
:
3857 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
3859 requestLength(tvb
, offsetp
, t
, byte_order
);
3863 case X_ConvertSelection
:
3864 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
3866 requestLength(tvb
, offsetp
, t
, byte_order
);
3876 requestLength(tvb
, offsetp
, t
, byte_order
);
3877 WINDOW(destination
);
3878 SETofEVENT(event_mask
);
3884 requestLength(tvb
, offsetp
, t
, byte_order
);
3885 WINDOW(grab_window
);
3886 SETofPOINTEREVENT(pointer_event_mask
);
3887 ENUM8(pointer_mode
);
3888 ENUM8(keyboard_mode
);
3894 case X_UngrabPointer
:
3895 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
3897 requestLength(tvb
, offsetp
, t
, byte_order
);
3903 requestLength(tvb
, offsetp
, t
, byte_order
);
3904 WINDOW(grab_window
);
3905 SETofPOINTEREVENT(event_mask
);
3906 ENUM8(pointer_mode
);
3907 ENUM8(keyboard_mode
);
3911 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
3913 SETofKEYMASK(modifiers
);
3916 case X_UngrabButton
:
3918 requestLength(tvb
, offsetp
, t
, byte_order
);
3919 WINDOW(grab_window
);
3920 SETofKEYMASK(modifiers
);
3921 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 2, ENC_NA
);
3925 case X_ChangeActivePointerGrab
:
3926 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
3928 requestLength(tvb
, offsetp
, t
, byte_order
);
3931 SETofPOINTEREVENT(event_mask
);
3932 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 2, ENC_NA
);
3936 case X_GrabKeyboard
:
3938 requestLength(tvb
, offsetp
, t
, byte_order
);
3939 WINDOW(grab_window
);
3941 ENUM8(pointer_mode
);
3942 ENUM8(keyboard_mode
);
3943 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 2, ENC_NA
);
3947 case X_UngrabKeyboard
:
3948 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
3950 requestLength(tvb
, offsetp
, t
, byte_order
);
3956 requestLength(tvb
, offsetp
, t
, byte_order
);
3957 WINDOW(grab_window
);
3958 SETofKEYMASK(modifiers
);
3960 ENUM8(pointer_mode
);
3961 ENUM8(keyboard_mode
);
3962 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 3, ENC_NA
);
3968 requestLength(tvb
, offsetp
, t
, byte_order
);
3969 WINDOW(grab_window
);
3970 SETofKEYMASK(modifiers
);
3971 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 2, ENC_NA
);
3976 ENUM8(allow_events_mode
);
3977 requestLength(tvb
, offsetp
, t
, byte_order
);
3982 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
3984 requestLength(tvb
, offsetp
, t
, byte_order
);
3987 case X_UngrabServer
:
3988 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
3990 requestLength(tvb
, offsetp
, t
, byte_order
);
3993 case X_QueryPointer
:
3994 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
3996 requestLength(tvb
, offsetp
, t
, byte_order
);
4000 case X_GetMotionEvents
:
4001 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
4003 requestLength(tvb
, offsetp
, t
, byte_order
);
4009 case X_TranslateCoords
:
4010 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
4012 requestLength(tvb
, offsetp
, t
, byte_order
);
4020 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
4022 requestLength(tvb
, offsetp
, t
, byte_order
);
4023 WINDOW(warp_pointer_src_window
);
4024 WINDOW(warp_pointer_dst_window
);
4033 case X_SetInputFocus
:
4035 requestLength(tvb
, offsetp
, t
, byte_order
);
4040 case X_GetInputFocus
:
4041 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
4043 requestLength(tvb
, offsetp
, t
, byte_order
);
4047 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
4049 requestLength(tvb
, offsetp
, t
, byte_order
);
4053 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
4055 requestLength(tvb
, offsetp
, t
, byte_order
);
4057 v16
= FIELD16(name_length
);
4058 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 2, ENC_NA
);
4065 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
4067 requestLength(tvb
, offsetp
, t
, byte_order
);
4072 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
4074 requestLength(tvb
, offsetp
, t
, byte_order
);
4078 case X_QueryTextExtents
:
4079 v8
= BOOL(odd_length
);
4080 requestLength(tvb
, offsetp
, t
, byte_order
);
4082 STRING16(string16
, (next_offset
- offset
- (v8
? 2 : 0)) / 2);
4087 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
4089 requestLength(tvb
, offsetp
, t
, byte_order
);
4091 v16
= FIELD16(pattern_length
);
4092 STRING8(pattern
, v16
);
4096 case X_ListFontsWithInfo
:
4097 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
4099 requestLength(tvb
, offsetp
, t
, byte_order
);
4101 v16
= FIELD16(pattern_length
);
4102 STRING8(pattern
, v16
);
4107 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
4109 requestLength(tvb
, offsetp
, t
, byte_order
);
4110 v16
= CARD16(str_number_in_path
);
4111 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 2, ENC_NA
);
4113 LISTofSTRING8(path
, v16
);
4118 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
4120 requestLength(tvb
, offsetp
, t
, byte_order
);
4123 case X_CreatePixmap
:
4125 requestLength(tvb
, offsetp
, t
, byte_order
);
4133 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
4135 requestLength(tvb
, offsetp
, t
, byte_order
);
4140 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
4142 requestLength(tvb
, offsetp
, t
, byte_order
);
4145 gcAttributes(tvb
, offsetp
, t
, byte_order
);
4149 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
4151 requestLength(tvb
, offsetp
, t
, byte_order
);
4153 gcAttributes(tvb
, offsetp
, t
, byte_order
);
4157 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
4159 requestLength(tvb
, offsetp
, t
, byte_order
);
4162 gcMask(tvb
, offsetp
, t
, byte_order
);
4166 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
4168 requestLength(tvb
, offsetp
, t
, byte_order
);
4170 CARD16(dash_offset
);
4171 v16
= FIELD16(dashes_length
);
4172 LISTofCARD8(dashes
, v16
);
4176 case X_SetClipRectangles
:
4178 requestLength(tvb
, offsetp
, t
, byte_order
);
4180 INT16(clip_x_origin
);
4181 INT16(clip_y_origin
);
4182 LISTofRECTANGLE(rectangles
);
4186 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
4188 requestLength(tvb
, offsetp
, t
, byte_order
);
4194 requestLength(tvb
, offsetp
, t
, byte_order
);
4203 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
4205 requestLength(tvb
, offsetp
, t
, byte_order
);
4206 DRAWABLE(src_drawable
);
4207 DRAWABLE(dst_drawable
);
4218 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
4220 requestLength(tvb
, offsetp
, t
, byte_order
);
4221 DRAWABLE(src_drawable
);
4222 DRAWABLE(dst_drawable
);
4234 ENUM8(coordinate_mode
);
4235 v16
= requestLength(tvb
, offsetp
, t
, byte_order
);
4238 LISTofPOINT(points
, v16
- 12);
4242 ENUM8(coordinate_mode
);
4243 v16
= requestLength(tvb
, offsetp
, t
, byte_order
);
4246 LISTofPOINT(points
, v16
- 12);
4250 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
4252 requestLength(tvb
, offsetp
, t
, byte_order
);
4255 LISTofSEGMENT(segments
);
4258 case X_PolyRectangle
:
4259 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
4261 requestLength(tvb
, offsetp
, t
, byte_order
);
4264 LISTofRECTANGLE(rectangles
);
4268 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
4270 requestLength(tvb
, offsetp
, t
, byte_order
);
4277 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
4279 v16
= requestLength(tvb
, offsetp
, t
, byte_order
);
4283 ENUM8(coordinate_mode
);
4284 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 2, ENC_NA
);
4286 LISTofPOINT(points
, v16
- 16);
4289 case X_PolyFillRectangle
:
4290 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
4292 requestLength(tvb
, offsetp
, t
, byte_order
);
4295 LISTofRECTANGLE(rectangles
);
4299 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
4301 requestLength(tvb
, offsetp
, t
, byte_order
);
4308 ENUM8(image_format
);
4309 v16
= requestLength(tvb
, offsetp
, t
, byte_order
);
4318 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 2, ENC_NA
);
4320 LISTofBYTE(data
, v16
- 24);
4325 ENUM8(image_pixmap_format
);
4326 requestLength(tvb
, offsetp
, t
, byte_order
);
4336 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
4338 requestLength(tvb
, offsetp
, t
, byte_order
);
4343 LISTofTEXTITEM8(items
);
4348 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
4350 requestLength(tvb
, offsetp
, t
, byte_order
);
4355 LISTofTEXTITEM16(items
);
4360 v8
= FIELD8(string_length
);
4361 requestLength(tvb
, offsetp
, t
, byte_order
);
4366 STRING8(string
, v8
);
4371 v8
= FIELD8(string_length
);
4372 requestLength(tvb
, offsetp
, t
, byte_order
);
4377 STRING16(string16
, v8
);
4381 case X_CreateColormap
:
4383 requestLength(tvb
, offsetp
, t
, byte_order
);
4389 case X_FreeColormap
:
4390 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
4392 requestLength(tvb
, offsetp
, t
, byte_order
);
4396 case X_CopyColormapAndFree
:
4397 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
4399 requestLength(tvb
, offsetp
, t
, byte_order
);
4404 case X_InstallColormap
:
4405 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
4407 requestLength(tvb
, offsetp
, t
, byte_order
);
4411 case X_UninstallColormap
:
4412 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
4414 requestLength(tvb
, offsetp
, t
, byte_order
);
4418 case X_ListInstalledColormaps
:
4419 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
4421 requestLength(tvb
, offsetp
, t
, byte_order
);
4426 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
4428 requestLength(tvb
, offsetp
, t
, byte_order
);
4433 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 2, ENC_NA
);
4437 case X_AllocNamedColor
:
4438 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
4440 requestLength(tvb
, offsetp
, t
, byte_order
);
4442 v16
= FIELD16(name_length
);
4443 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 2, ENC_NA
);
4449 case X_AllocColorCells
:
4451 requestLength(tvb
, offsetp
, t
, byte_order
);
4457 case X_AllocColorPlanes
:
4459 requestLength(tvb
, offsetp
, t
, byte_order
);
4468 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
4470 v16
= requestLength(tvb
, offsetp
, t
, byte_order
);
4473 LISTofCARD32(pixels
, v16
- 12);
4477 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
4479 v16
= requestLength(tvb
, offsetp
, t
, byte_order
);
4481 LISTofCOLORITEM(color_items
, v16
- 8);
4484 case X_StoreNamedColor
:
4486 requestLength(tvb
, offsetp
, t
, byte_order
);
4489 v16
= FIELD16(name_length
);
4490 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 2, ENC_NA
);
4497 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
4499 v16
= requestLength(tvb
, offsetp
, t
, byte_order
);
4501 LISTofCARD32(pixels
, v16
- 8);
4505 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
4507 requestLength(tvb
, offsetp
, t
, byte_order
);
4509 v16
= FIELD16(name_length
);
4510 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 2, ENC_NA
);
4516 case X_CreateCursor
:
4517 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
4519 requestLength(tvb
, offsetp
, t
, byte_order
);
4521 PIXMAP(source_pixmap
);
4533 case X_CreateGlyphCursor
:
4534 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
4536 requestLength(tvb
, offsetp
, t
, byte_order
);
4540 CARD16(source_char
);
4551 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
4553 requestLength(tvb
, offsetp
, t
, byte_order
);
4557 case X_RecolorCursor
:
4558 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
4560 requestLength(tvb
, offsetp
, t
, byte_order
);
4570 case X_QueryBestSize
:
4572 requestLength(tvb
, offsetp
, t
, byte_order
);
4578 case X_QueryExtension
:
4579 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
4581 requestLength(tvb
, offsetp
, t
, byte_order
);
4582 v16
= FIELD16(name_length
);
4583 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 2, ENC_NA
);
4589 case X_ListExtensions
:
4590 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
4592 requestLength(tvb
, offsetp
, t
, byte_order
);
4595 case X_ChangeKeyboardMapping
:
4596 v8
= FIELD8(keycode_count
);
4597 requestLength(tvb
, offsetp
, t
, byte_order
);
4598 v8_2
= KEYCODE(first_keycode
);
4599 v8_3
= FIELD8(keysyms_per_keycode
);
4600 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 2, ENC_NA
);
4602 LISTofKEYSYM(keysyms
, state
->keycodemap
, v8_2
, v8
, v8_3
);
4605 case X_GetKeyboardMapping
:
4606 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
4608 requestLength(tvb
, offsetp
, t
, byte_order
);
4609 state
->request
.GetKeyboardMapping
.first_keycode
4610 = KEYCODE(first_keycode
);
4612 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 2, ENC_NA
);
4616 case X_ChangeKeyboardControl
:
4619 static int * const keyboard_value_flags
[] = {
4620 &hf_x11_keyboard_value_mask_key_click_percent
,
4621 &hf_x11_keyboard_value_mask_bell_percent
,
4622 &hf_x11_keyboard_value_mask_bell_pitch
,
4623 &hf_x11_keyboard_value_mask_bell_duration
,
4624 &hf_x11_keyboard_value_mask_led
,
4625 &hf_x11_keyboard_value_mask_led_mode
,
4626 &hf_x11_keyboard_value_mask_keyboard_key
,
4627 &hf_x11_keyboard_value_mask_auto_repeat_mode
,
4631 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
4633 requestLength(tvb
, offsetp
, t
, byte_order
);
4634 bitmask32
= tvb_get_uint32(tvb
, *offsetp
, byte_order
);
4635 proto_tree_add_bitmask(t
, tvb
, *offsetp
, hf_x11_keyboard_value_mask
, ett_x11_keyboard_value_mask
, keyboard_value_flags
, byte_order
);
4637 if (bitmask32
& 0x00000001) {
4638 proto_tree_add_item(t
, hf_x11_key_click_percent
, tvb
, *offsetp
, 1, byte_order
);
4640 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 3, ENC_NA
);
4643 if (bitmask32
& 0x00000002) {
4644 proto_tree_add_item(t
, hf_x11_bell_percent
, tvb
, *offsetp
, 1, byte_order
);
4646 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 3, ENC_NA
);
4649 if (bitmask32
& 0x00000004) {
4650 proto_tree_add_item(t
, hf_x11_bell_pitch
, tvb
, *offsetp
, 2, byte_order
);
4652 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 2, ENC_NA
);
4655 if (bitmask32
& 0x00000008) {
4656 proto_tree_add_item(t
, hf_x11_bell_duration
, tvb
, *offsetp
, 2, byte_order
);
4658 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 2, ENC_NA
);
4661 if (bitmask32
& 0x00000010) {
4662 proto_tree_add_item(t
, hf_x11_led
, tvb
, *offsetp
, 2, byte_order
);
4664 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 2, ENC_NA
);
4667 if (bitmask32
& 0x00000020) {
4668 proto_tree_add_item(t
, hf_x11_led_mode
, tvb
, *offsetp
, 1, byte_order
);
4670 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 3, ENC_NA
);
4673 if (bitmask32
& 0x00000040) {
4674 proto_tree_add_item(t
, hf_x11_keyboard_key
, tvb
, *offsetp
, 1, byte_order
);
4676 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 3, ENC_NA
);
4679 if (bitmask32
& 0x00000080) {
4680 proto_tree_add_item(t
, hf_x11_auto_repeat_mode
, tvb
, *offsetp
, 1, byte_order
);
4682 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 3, ENC_NA
);
4688 case X_GetKeyboardControl
:
4689 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
4691 requestLength(tvb
, offsetp
, t
, byte_order
);
4696 requestLength(tvb
, offsetp
, t
, byte_order
);
4699 case X_ChangePointerControl
:
4700 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
4702 requestLength(tvb
, offsetp
, t
, byte_order
);
4703 INT16(acceleration_numerator
);
4704 INT16(acceleration_denominator
);
4706 BOOL(do_acceleration
);
4710 case X_GetPointerControl
:
4711 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
4713 requestLength(tvb
, offsetp
, t
, byte_order
);
4716 case X_SetScreenSaver
:
4717 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
4719 requestLength(tvb
, offsetp
, t
, byte_order
);
4722 ENUM8(prefer_blanking
);
4723 ENUM8(allow_exposures
);
4724 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 2, ENC_NA
);
4728 case X_GetScreenSaver
:
4729 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
4731 requestLength(tvb
, offsetp
, t
, byte_order
);
4735 ENUM8(change_host_mode
);
4736 requestLength(tvb
, offsetp
, t
, byte_order
);
4738 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
4740 v16
= CARD16(address_length
);
4741 if (v8
== FAMILY_INTERNET
&& v16
== 4) {
4744 * XXX - what about IPv6? Is that a family of
4745 * FAMILY_INTERNET (0) with a length of 16?
4747 LISTofIPADDRESS(ip_address
, v16
);
4749 LISTofCARD8(address
, v16
);
4753 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
4755 requestLength(tvb
, offsetp
, t
, byte_order
);
4758 case X_SetAccessControl
:
4760 requestLength(tvb
, offsetp
, t
, byte_order
);
4763 case X_SetCloseDownMode
:
4764 ENUM8(close_down_mode
);
4765 requestLength(tvb
, offsetp
, t
, byte_order
);
4769 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
4771 requestLength(tvb
, offsetp
, t
, byte_order
);
4775 case X_RotateProperties
:
4776 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
4778 v16
= requestLength(tvb
, offsetp
, t
, byte_order
);
4780 CARD16(property_number
);
4782 LISTofATOM(properties
, (v16
- 12));
4785 case X_ForceScreenSaver
:
4786 ENUM8(screen_saver_mode
);
4787 requestLength(tvb
, offsetp
, t
, byte_order
);
4790 case X_SetPointerMapping
:
4791 v8
= FIELD8(map_length
);
4792 requestLength(tvb
, offsetp
, t
, byte_order
);
4793 LISTofCARD8(map
, v8
);
4797 case X_GetPointerMapping
:
4798 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
4800 requestLength(tvb
, offsetp
, t
, byte_order
);
4803 case X_SetModifierMapping
:
4804 v8
= FIELD8(keycodes_per_modifier
);
4805 requestLength(tvb
, offsetp
, t
, byte_order
);
4806 LISTofKEYCODE(state
->modifiermap
, keycodes
, v8
);
4809 case X_GetModifierMapping
:
4810 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
4812 requestLength(tvb
, offsetp
, t
, byte_order
);
4816 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
4818 requestLength(tvb
, offsetp
, t
, byte_order
);
4821 tryExtension(opcode
, tvb
, pinfo
, offsetp
, t
, state
, byte_order
);
4825 if ((left
= tvb_reported_length_remaining(tvb
, offset
)) > 0)
4829 static void dissect_x11_requests(tvbuff_t
*tvb
, packet_info
*pinfo
,
4832 volatile int offset
= 0;
4833 int length_remaining
;
4834 volatile unsigned byte_order
;
4838 volatile bool is_initial_creq
;
4839 uint16_t auth_proto_len
, auth_data_len
;
4840 const char *volatile sep
= NULL
;
4841 conversation_t
*conversation
;
4842 x11_conv_data_t
*volatile state
;
4844 tvbuff_t
*volatile next_tvb
;
4846 while ((length_remaining
= tvb_reported_length_remaining(tvb
, offset
)) > 0) {
4849 * Can we do reassembly?
4851 if (x11_desegment
&& pinfo
->can_desegment
) {
4853 * Yes - is the X11 request header split across
4854 * segment boundaries?
4856 if (length_remaining
< 4) {
4858 * Yes. Tell the TCP dissector where the data
4859 * for this message starts in the data it handed
4860 * us and that we need "some more data." Don't tell
4861 * it exactly how many bytes we need because if/when
4862 * we ask for even more (after the header) that will
4865 pinfo
->desegment_offset
= offset
;
4866 pinfo
->desegment_len
= DESEGMENT_ONE_MORE_SEGMENT
;
4872 * Get the state for this conversation; create the conversation
4873 * if we don't have one, and create the state if we don't have
4876 conversation
= find_or_create_conversation(pinfo
);
4879 * Is there state attached to this conversation?
4881 if ((state
= (x11_conv_data_t
*)conversation_get_proto_data(conversation
, proto_x11
))
4883 state
= x11_stateinit(conversation
);
4886 * Guess the byte order if we don't already know it.
4888 byte_order
= guess_byte_ordering(tvb
, pinfo
, state
);
4891 * Get the opcode and length of the putative X11 request.
4893 opcode
= tvb_get_uint8(tvb
, 0);
4894 plen
= tvb_get_uint16(tvb
, offset
+ 2, byte_order
);
4898 * A length field of 0 indicates that the BIG-REQUESTS
4899 * extension is used: The next four bytes are the real length.
4901 plen
= tvb_get_uint32(tvb
, offset
+ 4, byte_order
);
4906 * This can't be less then 0, as it includes the header length.
4907 * A different choice of byte order wouldn't have
4911 ti
= proto_tree_add_item(tree
, proto_x11
, tvb
, offset
, -1, ENC_NA
);
4912 expert_add_info_format(pinfo
, ti
, &ei_x11_request_length
, "Bogus request length (%d)", plen
);
4916 if (state
->iconn_frame
== pinfo
->num
||
4917 (wmem_map_lookup(state
->seqtable
,
4918 GINT_TO_POINTER(state
->sequencenumber
)) == (int *)NOTHING_SEEN
&&
4919 (opcode
== 'B' || opcode
== 'l') &&
4920 (plen
== 11 || plen
== 2816))) {
4924 * we saw this on the first pass and this is
4928 * we haven't already seen any requests, the first
4929 * byte of the message is 'B' or 'l', and the 16-bit
4930 * integer 2 bytes into the data stream is either 11
4931 * or a byte-swapped 11.
4933 * This means it's probably an initial connection
4934 * request, not a message.
4936 * 'B' is decimal 66, which is the opcode for a
4937 * PolySegment request; unfortunately, 11 is a valid
4938 * length for a PolySegment request request, so we
4939 * might mis-identify that request. (Are there any
4940 * other checks we can do?)
4942 * 'l' is decimal 108, which is the opcode for a
4943 * GetScreenSaver request; the only valid length
4944 * for that request is 1.
4946 is_initial_creq
= true;
4949 * We now know the byte order. Override the guess.
4951 if (state
->byte_order
== BYTE_ORDER_UNKNOWN
) {
4952 if (opcode
== 'B') {
4956 byte_order
= state
->byte_order
= ENC_BIG_ENDIAN
;
4961 byte_order
= state
->byte_order
= ENC_LITTLE_ENDIAN
;
4966 * Can we do reassembly?
4968 if (x11_desegment
&& pinfo
->can_desegment
) {
4970 * Yes - is the fixed-length portion of the
4971 * initial connection header split across
4972 * segment boundaries?
4974 if (length_remaining
< 10) {
4976 * Yes. Tell the TCP dissector where the
4977 * data for this message starts in the data
4978 * it handed us and that we need "some more
4979 * data." Don't tell it exactly how many bytes
4980 * we need because if/when we ask for even more
4981 * (after the header) that will break reassembly.
4983 pinfo
->desegment_offset
= offset
;
4984 pinfo
->desegment_len
= DESEGMENT_ONE_MORE_SEGMENT
;
4990 * Get the lengths of the authorization protocol and
4991 * the authorization data.
4993 auth_proto_len
= tvb_get_uint16(tvb
, offset
+ 6, byte_order
);
4994 auth_data_len
= tvb_get_uint16(tvb
, offset
+ 8, byte_order
);
4995 plen
= 12 + ROUND_LENGTH(auth_proto_len
) +
4996 ROUND_LENGTH(auth_data_len
);
4998 volatile int64_t tmp
= (int64_t)plen
* 4;
5000 * This is probably an ordinary request.
5002 is_initial_creq
= false;
5005 * The length of a request is in 4-byte words.
5007 if (tmp
> INT32_MAX
) {
5008 ti
= proto_tree_add_item(tree
, proto_x11
, tvb
, offset
, -1, ENC_NA
);
5009 expert_add_info_format(pinfo
, ti
, &ei_x11_request_length
, "Bogus request length (%"PRId64
")", tmp
);
5016 * Can we do reassembly?
5018 if (x11_desegment
&& pinfo
->can_desegment
) {
5020 * Yes - is the X11 request split across segment
5023 if (length_remaining
< plen
) {
5025 * Yes. Tell the TCP dissector where the data
5026 * for this message starts in the data it handed
5027 * us, and how many more bytes we need, and return.
5029 pinfo
->desegment_offset
= offset
;
5030 pinfo
->desegment_len
= plen
- length_remaining
;
5036 * Construct a tvbuff containing the amount of the payload
5037 * we have available. Make its reported length the
5038 * amount of data in the X11 request.
5040 * XXX - if reassembly isn't enabled. the subdissector
5041 * will throw a BoundsError exception, rather than a
5042 * ReportedBoundsError exception. We really want a tvbuff
5043 * where the length is "length", the reported length is "plen",
5044 * and the "if the snapshot length were infinite" length is the
5045 * minimum of the reported length of the tvbuff handed to us
5046 * and "plen", with a new type of exception thrown if the offset
5047 * is within the reported length but beyond that third length,
5048 * with that exception getting the "Unreassembled Packet" error.
5050 length
= length_remaining
;
5053 next_tvb
= tvb_new_subset_length_caplen(tvb
, offset
, length
, plen
);
5056 * Set the column appropriately.
5058 if (is_initial_creq
) {
5059 col_set_str(pinfo
->cinfo
, COL_INFO
, "Initial connection request");
5063 * We haven't set the column yet; set it.
5065 col_set_str(pinfo
->cinfo
, COL_INFO
, "Requests");
5068 * Initialize the separator.
5075 * Dissect the X11 request.
5077 * Catch the ReportedBoundsError exception; if this
5078 * particular message happens to get a ReportedBoundsError
5079 * exception, that doesn't mean that we should stop
5080 * dissecting X11 requests within this frame or chunk of
5083 * If it gets a BoundsError, we can stop, as there's nothing
5084 * more to see, so we just re-throw it.
5087 if (is_initial_creq
) {
5088 dissect_x11_initial_conn(next_tvb
, pinfo
, tree
,
5091 dissect_x11_request(next_tvb
, pinfo
, tree
, sep
,
5095 CATCH_NONFATAL_ERRORS
{
5096 show_exception(tvb
, pinfo
, tree
, EXCEPT_CODE
, GET_MESSAGE
);
5101 * Skip the X11 message.
5109 static x11_conv_data_t
*
5110 x11_stateinit(conversation_t
*conversation
)
5112 x11_conv_data_t
*state
;
5113 static x11_conv_data_t stateinit
;
5116 state
= wmem_new(wmem_file_scope(), x11_conv_data_t
);
5119 /* initialise opcodes */
5120 for (i
= 0; opcode_vals
[i
].strptr
!= NULL
; i
++) {
5121 state
->opcode_vals
[i
].value
= opcode_vals
[i
].value
;
5122 state
->opcode_vals
[i
].strptr
= opcode_vals
[i
].strptr
;
5124 for (; i
<= MAX_OPCODES
; i
++) {
5125 state
->opcode_vals
[i
].value
= 0;
5126 state
->opcode_vals
[i
].strptr
= NULL
;
5129 /* initialise errorcodes */
5130 for (i
= 0; errorcode_vals
[i
].strptr
!= NULL
; i
++) {
5131 state
->errorcode_vals
[i
].value
= errorcode_vals
[i
].value
;
5132 state
->errorcode_vals
[i
].strptr
= errorcode_vals
[i
].strptr
;
5134 for (; i
<= LastExtensionError
+ 1; i
++) {
5135 state
->errorcode_vals
[i
].value
= 0;
5136 state
->errorcode_vals
[i
].strptr
= NULL
;
5139 /* initialise eventcodes */
5140 for (i
= 0; eventcode_vals
[i
].strptr
!= NULL
; i
++) {
5141 state
->eventcode_vals
[i
].value
= eventcode_vals
[i
].value
;
5142 state
->eventcode_vals
[i
].strptr
= eventcode_vals
[i
].strptr
;
5144 for (; i
<= LastExtensionEvent
+ 1; i
++) {
5145 state
->eventcode_vals
[i
].value
= 0;
5146 state
->eventcode_vals
[i
].strptr
= NULL
;
5148 state
->eventcode_funcs
= wmem_map_new(wmem_file_scope(), g_direct_hash
, g_direct_equal
);
5149 state
->reply_funcs
= wmem_map_new(wmem_file_scope(), g_direct_hash
, g_direct_equal
);
5151 state
->seqtable
= wmem_map_new(wmem_file_scope(), g_direct_hash
, g_direct_equal
);
5152 state
->valtable
= wmem_map_new(wmem_file_scope(), g_direct_hash
, g_direct_equal
);
5153 wmem_map_insert(state
->seqtable
, (int *)0, (int *)NOTHING_SEEN
);
5154 state
->byte_order
= BYTE_ORDER_UNKNOWN
; /* don't know yet*/
5155 conversation_add_proto_data(conversation
, proto_x11
, state
);
5161 dissect_x11_replies(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
)
5163 /* Set up structures we will need to add the protocol subtree and manage it */
5164 volatile int offset
, plen
;
5165 tvbuff_t
*volatile next_tvb
;
5166 conversation_t
*conversation
;
5167 x11_conv_data_t
*volatile state
;
5168 volatile unsigned byte_order
;
5169 int length_remaining
;
5170 const char *volatile sep
= NULL
;
5174 * Get the state for this conversation; create the conversation
5175 * if we don't have one, and create the state if we don't have
5178 conversation
= find_or_create_conversation(pinfo
);
5181 * Is there state attached to this conversation?
5183 if ((state
= (x11_conv_data_t
*)conversation_get_proto_data(conversation
, proto_x11
))
5186 * No - create a state structure and attach it.
5188 state
= x11_stateinit(conversation
);
5192 * Guess the byte order if we don't already know it.
5194 byte_order
= guess_byte_ordering(tvb
, pinfo
, state
);
5197 while ((length_remaining
= tvb_reported_length_remaining(tvb
, offset
)) > 0) {
5199 * Can we do reassembly?
5201 if (x11_desegment
&& pinfo
->can_desegment
) {
5203 * Yes - is the X11 Reply or GenericEvent header split across
5204 * segment boundaries?
5206 if (length_remaining
< 8) {
5208 * Yes. Tell the TCP dissector where the data
5209 * for this message starts in the data it handed
5210 * us and that we need "some more data." Don't tell
5211 * it exactly how many bytes we need because if/when
5212 * we ask for even more (after the header) that will
5215 pinfo
->desegment_offset
= offset
;
5216 pinfo
->desegment_len
= DESEGMENT_ONE_MORE_SEGMENT
;
5222 * Find out what kind of a reply it is.
5223 * There are four possible:
5224 * - reply to initial connection
5225 * - errorreply (a request generated an error)
5226 * - requestreply (reply to a request)
5227 * - event (some event occurred)
5229 if (wmem_map_lookup(state
->seqtable
,
5230 GINT_TO_POINTER(state
->sequencenumber
)) == (int *)INITIAL_CONN
5231 || (state
->iconn_reply
== pinfo
->num
)) {
5233 * Either the connection is in the "initial
5234 * connection" state, or this frame is known
5235 * to have the initial connection reply.
5236 * That means this is the initial connection
5239 plen
= 8 + tvb_get_uint16(tvb
, offset
+ 6, byte_order
) * 4;
5241 HANDLE_REPLY(plen
, length_remaining
,
5242 "Initial connection reply",
5243 dissect_x11_initial_reply
);
5246 * This isn't an initial connection reply
5247 * (XXX - unless we missed the initial
5248 * connection request). Look at the first
5249 * byte to determine what it is; errors
5250 * start with a byte of 0, replies start
5251 * with a byte of 1, events start with
5252 * a byte with of 2 or greater.
5254 switch (tvb_get_uint8(tvb
, offset
)) {
5258 HANDLE_REPLY(plen
, length_remaining
,
5259 "Error", dissect_x11_error
);
5264 /* To avoid an "assert w/side-effect" warning,
5265 * use a non-volatile temp variable instead. */
5268 /* replylength is in units of four. */
5269 tmp_plen
= plen
= 32 + tvb_get_uint32(tvb
, offset
+ 4, byte_order
) * 4;
5270 /* If tmp_plen < 32, we got an overflow;
5271 * the reply length is too long. */
5272 THROW_ON(tmp_plen
< 32, ReportedBoundsError
);
5273 HANDLE_REPLY(plen
, length_remaining
,
5274 "Reply", dissect_x11_reply
);
5280 /* An Event, but with a length field like a Reply. */
5282 /* To avoid an "assert w/side-effect" warning,
5283 * use a non-volatile temp variable instead. */
5286 /* GenericEvent's length is also in units of four. */
5287 tmp_plen
= plen
= 32 + tvb_get_uint32(tvb
, offset
+ 4, byte_order
) * 4;
5288 /* If tmp_plen < 32, we got an overflow;
5289 * the event length is too long. */
5290 THROW_ON(tmp_plen
< 32, ReportedBoundsError
);
5291 HANDLE_REPLY(plen
, length_remaining
,
5292 "Event", dissect_x11_event
);
5299 HANDLE_REPLY(plen
, length_remaining
,
5300 "Event", dissect_x11_event
);
5312 dissect_x11_reply(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
5313 const char *sep
, x11_conv_data_t
*state
,
5314 unsigned byte_order
)
5316 int offset
= 0, *offsetp
= &offset
, length
, left
, opcode
;
5317 int major_opcode
, sequence_number
, first_error
, first_event
;
5318 value_string
*vals_p
;
5322 ti
= proto_tree_add_item(tree
, proto_x11
, tvb
, 0, -1, ENC_NA
);
5323 t
= proto_item_add_subtree(ti
, ett_x11
);
5327 * XXX - this doesn't work correctly if either
5329 * 1) the request sequence number wraps in the lower 16
5332 * 2) we don't see the initial connection request and the
5333 * resynchronization of sequence number fails and thus
5334 * don't have the right sequence numbers
5336 * 3) we don't have all the packets in the capture and
5337 * get out of sequence.
5339 * We might, instead, want to assume that a reply is a reply to
5340 * the most recent not-already-replied-to request in the same
5341 * connection. That also might mismatch replies to requests if
5342 * packets are lost, but there's nothing you can do to fix that.
5345 sequence_number
= tvb_get_uint16(tvb
, offset
+ 2, byte_order
);
5346 opcode
= GPOINTER_TO_INT(wmem_map_lookup(state
->seqtable
,
5347 GINT_TO_POINTER(sequence_number
)));
5349 if (state
->iconn_frame
== 0 && state
->resync
== false) {
5352 * We don't see the initial connection request and no
5353 * resynchronization has been performed yet (first reply),
5354 * set the current sequence number to the one of the
5355 * current reply (this is only performed once).
5357 state
->sequencenumber
= sequence_number
;
5358 state
->resync
= true;
5361 if (opcode
== UNKNOWN_OPCODE
) {
5362 col_append_fstr(pinfo
->cinfo
, COL_INFO
,
5363 "%s to unknown request", sep
);
5364 proto_item_append_text(ti
, ", Reply to unknown request");
5366 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "%s %s",
5368 val_to_str(opcode
& 0xFF, state
->opcode_vals
,
5369 "<Unknown opcode %d>"));
5372 proto_item_append_text(ti
, ", Reply, opcode: %d.%d (%s)",
5373 opcode
& 0xFF, opcode
>> 8, val_to_str(opcode
& 0xFF,
5375 "<Unknown opcode %d>"));
5377 proto_item_append_text(ti
, ", Reply, opcode: %d (%s)",
5378 opcode
, val_to_str(opcode
,
5380 "<Unknown opcode %d>"));
5386 * Replies that need special processing outside tree
5389 case X_QueryExtension
:
5392 * if extension is present and request is known:
5393 * store opcode of extension in value_string of
5396 if (!tvb_get_uint8(tvb
, offset
+ 8)) {
5401 vals_p
= (value_string
*)wmem_map_lookup(state
->valtable
,
5402 GINT_TO_POINTER(sequence_number
));
5403 if (vals_p
!= NULL
) {
5404 major_opcode
= tvb_get_uint8(tvb
, offset
+ 9);
5405 first_event
= tvb_get_uint8(tvb
, offset
+ 10);
5406 first_error
= tvb_get_uint8(tvb
, offset
+ 11);
5408 register_extension(state
, vals_p
, major_opcode
, first_event
, first_error
);
5409 wmem_map_remove(state
->valtable
,
5410 GINT_TO_POINTER(sequence_number
));
5423 * Requests that expect a reply.
5426 case X_GetWindowAttributes
:
5427 REPLYCONTENTS_COMMON();
5433 SEQUENCENUMBER_REPLY(sequencenumber
);
5434 REPLYLENGTH(replylength
);
5440 CARD16(border_width
);
5441 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 10, ENC_NA
);
5446 REPLYCONTENTS_COMMON();
5451 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
5453 SEQUENCENUMBER_REPLY(sequencenumber
);
5454 REPLYLENGTH(replylength
);
5456 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 20, ENC_NA
);
5461 REPLYCONTENTS_COMMON();
5467 SEQUENCENUMBER_REPLY(sequencenumber
);
5468 REPLYLENGTH(replylength
);
5469 ATOM(get_property_type
);
5470 CARD32(bytes_after
);
5471 CARD32(valuelength
);
5472 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 12, ENC_NA
);
5476 case X_ListProperties
:
5478 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
5480 SEQUENCENUMBER_REPLY(sequencenumber
);
5481 REPLYLENGTH(replylength
);
5482 length
= CARD16(property_number
);
5483 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 22, ENC_NA
);
5485 LISTofATOM(properties
, length
*4);
5488 case X_GetSelectionOwner
:
5490 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
5492 SEQUENCENUMBER_REPLY(sequencenumber
);
5493 REPLYLENGTH(replylength
);
5495 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 20, ENC_NA
);
5500 case X_GrabKeyboard
:
5503 SEQUENCENUMBER_REPLY(sequencenumber
);
5504 REPLYLENGTH(replylength
);
5505 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 24, ENC_NA
);
5509 case X_QueryPointer
:
5512 SEQUENCENUMBER_REPLY(sequencenumber
);
5513 REPLYLENGTH(replylength
);
5515 WINDOW(childwindow
);
5520 SETofKEYBUTMASK(mask
);
5521 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 6, ENC_NA
);
5525 case X_GetMotionEvents
:
5526 REPLYCONTENTS_COMMON();
5529 case X_TranslateCoords
:
5532 SEQUENCENUMBER_REPLY(sequencenumber
);
5533 REPLYLENGTH(replylength
);
5534 WINDOW(childwindow
);
5537 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 16, ENC_NA
);
5541 case X_GetInputFocus
:
5544 SEQUENCENUMBER_REPLY(sequencenumber
);
5545 REPLYLENGTH(replylength
);
5547 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 20, ENC_NA
);
5553 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
5555 SEQUENCENUMBER_REPLY(sequencenumber
);
5556 REPLYLENGTH(replylength
);
5557 LISTofCARD8(keys
, 32);
5561 case X_QueryTextExtents
:
5564 case X_ListInstalledColormaps
:
5565 REPLYCONTENTS_COMMON();
5570 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
5572 SEQUENCENUMBER_REPLY(sequencenumber
);
5573 REPLYLENGTH(replylength
);
5577 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 2, ENC_NA
);
5580 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 12, ENC_NA
);
5585 REPLYCONTENTS_COMMON();
5590 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
5592 SEQUENCENUMBER_REPLY(sequencenumber
);
5593 REPLYLENGTH(replylength
);
5595 CARD16(exact_green
);
5598 CARD16(visual_green
);
5599 CARD16(visual_blue
);
5600 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 12, ENC_NA
);
5604 case X_QueryBestSize
:
5606 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
5608 SEQUENCENUMBER_REPLY(sequencenumber
);
5609 REPLYLENGTH(replylength
);
5612 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 20, ENC_NA
);
5616 case X_QueryExtension
:
5618 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
5620 SEQUENCENUMBER_REPLY(sequencenumber
);
5621 REPLYLENGTH(replylength
);
5623 CARD8(major_opcode
);
5626 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 20, ENC_NA
);
5630 case X_ListExtensions
:
5631 REPLYCONTENTS_COMMON();
5634 case X_GetKeyboardMapping
:
5635 state
->first_keycode
=
5636 state
->request
.GetKeyboardMapping
.first_keycode
;
5638 state
->keysyms_per_keycode
=
5639 FIELD8(keysyms_per_keycode
);
5640 SEQUENCENUMBER_REPLY(sequencenumber
);
5641 length
= REPLYLENGTH(replylength
);
5642 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 24, ENC_NA
);
5644 LISTofKEYSYM(keysyms
, state
->keycodemap
,
5645 state
->request
.GetKeyboardMapping
.first_keycode
,
5646 /* XXX - length / state->keysyms_per_keycode can raise a division by zero,
5647 * don't know if this is the *right* way to fix it ... */
5648 state
->keysyms_per_keycode
? length
/ state
->keysyms_per_keycode
: 0,
5649 state
->keysyms_per_keycode
);
5652 case X_GetKeyboardControl
:
5653 REPLYCONTENTS_COMMON();
5656 case X_GetPointerControl
:
5658 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
5660 SEQUENCENUMBER_REPLY(sequencenumber
);
5661 REPLYLENGTH(replylength
);
5662 CARD16(acceleration_numerator
);
5663 CARD16(acceleration_denominator
);
5665 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 18, ENC_NA
);
5669 case X_GetScreenSaver
:
5671 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
5673 SEQUENCENUMBER_REPLY(sequencenumber
);
5674 REPLYLENGTH(replylength
);
5677 ENUM8(prefer_blanking
);
5678 ENUM8(allow_exposures
);
5679 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 18, ENC_NA
);
5684 case X_SetPointerMapping
:
5685 case X_GetPointerMapping
:
5686 case X_SetModifierMapping
:
5687 REPLYCONTENTS_COMMON();
5690 case X_GetModifierMapping
:
5692 state
->keycodes_per_modifier
=
5693 FIELD8(keycodes_per_modifier
);
5694 SEQUENCENUMBER_REPLY(sequencenumber
);
5695 REPLYLENGTH(replylength
);
5696 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 24, ENC_NA
);
5698 LISTofKEYCODE(state
->modifiermap
, keycodes
,
5699 state
->keycodes_per_modifier
);
5702 case UNKNOWN_OPCODE
:
5703 REPLYCONTENTS_COMMON();
5707 tryExtensionReply(opcode
, tvb
, pinfo
, offsetp
, t
, state
, byte_order
);
5710 if ((left
= tvb_reported_length_remaining(tvb
, offset
)) > 0)
5715 same_screen_focus(tvbuff_t
*tvb
, int *offsetp
, proto_tree
*t
)
5718 uint32_t bitmask_value
;
5721 proto_tree
*bitmask_tree
;
5723 bitmask_value
= tvb_get_uint8(tvb
, *offsetp
);
5724 bitmask_offset
= *offsetp
;
5727 ti
= proto_tree_add_uint(t
, hf_x11_same_screen_focus_mask
, tvb
, *offsetp
, 1,
5729 bitmask_tree
= proto_item_add_subtree(ti
, ett_x11_same_screen_focus
);
5730 FLAG(same_screen_focus
, focus
);
5731 FLAG(same_screen_focus
, same_screen
);
5737 dissect_x11_event(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
5738 const char *sep
, x11_conv_data_t
*state
,
5739 unsigned byte_order
)
5741 unsigned char eventcode
;
5746 ti
= proto_tree_add_item(tree
, proto_x11
, tvb
, 0, -1, ENC_NA
);
5747 t
= proto_item_add_subtree(ti
, ett_x11
);
5749 eventcode
= tvb_get_uint8(tvb
, 0);
5750 sent
= (eventcode
& 0x80) ? "Sent-" : "";
5752 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "%s %s%s",
5754 val_to_str(eventcode
& 0x7F, state
->eventcode_vals
,
5755 "<Unknown eventcode %u>"));
5757 proto_item_append_text(ti
, ", Event, eventcode: %d (%s%s)",
5759 val_to_str(eventcode
& 0x7F, state
->eventcode_vals
,
5760 "<Unknown eventcode %u>"));
5765 decode_x11_event(tvb
, eventcode
, sent
, t
, state
, byte_order
);
5771 decode_x11_event(tvbuff_t
*tvb
, unsigned char eventcode
, const char *sent
,
5772 proto_tree
*t
, x11_conv_data_t
*state
,
5773 unsigned byte_order
)
5775 int offset
= 0, *offsetp
= &offset
, left
;
5777 proto_tree_add_uint_format(t
, hf_x11_eventcode
, tvb
, offset
, 1,
5779 "eventcode: %d (%s%s)",
5781 val_to_str(eventcode
& 0x7F, state
->eventcode_vals
,
5782 "<Unknown eventcode %u>"));
5785 switch (eventcode
& 0x7F) {
5790 /* need to do some prefetching here ... */
5791 code
= tvb_get_uint8(tvb
, offset
);
5792 mask
= tvb_get_uint16(tvb
, 28, byte_order
);
5794 KEYCODE_DECODED(keycode
, code
, mask
);
5795 CARD16(event_sequencenumber
);
5796 EVENTCONTENTS_COMMON();
5798 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
5805 BUTTON(eventbutton
);
5806 CARD16(event_sequencenumber
);
5807 EVENTCONTENTS_COMMON();
5809 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
5815 CARD16(event_sequencenumber
);
5816 EVENTCONTENTS_COMMON();
5818 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
5824 ENUM8(event_detail
);
5825 CARD16(event_sequencenumber
);
5826 EVENTCONTENTS_COMMON();
5828 same_screen_focus(tvb
, offsetp
, t
);
5833 ENUM8(focus_detail
);
5834 CARD16(event_sequencenumber
);
5835 WINDOW(eventwindow
);
5837 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 23, ENC_NA
);
5845 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
5847 CARD16(event_sequencenumber
);
5848 WINDOW(eventwindow
);
5854 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 14, ENC_NA
);
5858 case GraphicsExpose
:
5859 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
5861 CARD16(event_sequencenumber
);
5867 CARD16(minor_opcode
);
5869 CARD8(major_opcode
);
5870 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 11, ENC_NA
);
5875 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
5877 CARD16(event_sequencenumber
);
5879 CARD16(minor_opcode
);
5880 CARD8(major_opcode
);
5881 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 21, ENC_NA
);
5885 case VisibilityNotify
:
5886 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
5888 CARD16(event_sequencenumber
);
5889 WINDOW(eventwindow
);
5890 ENUM8(visibility_state
);
5891 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 23, ENC_NA
);
5896 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
5898 CARD16(event_sequencenumber
);
5900 WINDOW(eventwindow
);
5905 CARD16(border_width
);
5906 BOOL(override_redirect
);
5907 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 9, ENC_NA
);
5912 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
5914 CARD16(event_sequencenumber
);
5915 WINDOW(eventwindow
);
5917 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 20, ENC_NA
);
5922 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
5924 CARD16(event_sequencenumber
);
5925 WINDOW(eventwindow
);
5927 BOOL(from_configure
);
5928 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 19, ENC_NA
);
5933 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
5935 CARD16(event_sequencenumber
);
5936 WINDOW(eventwindow
);
5938 BOOL(override_redirect
);
5939 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 19, ENC_NA
);
5944 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
5946 CARD16(event_sequencenumber
);
5948 WINDOW(eventwindow
);
5949 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 20, ENC_NA
);
5953 case ReparentNotify
:
5954 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
5956 CARD16(event_sequencenumber
);
5957 WINDOW(eventwindow
);
5962 BOOL(override_redirect
);
5963 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 11, ENC_NA
);
5967 case ConfigureNotify
:
5968 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
5970 CARD16(event_sequencenumber
);
5971 WINDOW(eventwindow
);
5973 WINDOW(above_sibling
);
5978 CARD16(border_width
);
5979 BOOL(override_redirect
);
5980 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 5, ENC_NA
);
5984 case ConfigureRequest
:
5988 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
5990 CARD16(event_sequencenumber
);
5991 WINDOW(eventwindow
);
5995 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 16, ENC_NA
);
6000 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
6002 CARD16(event_sequencenumber
);
6003 WINDOW(eventwindow
);
6006 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 20, ENC_NA
);
6010 case CirculateNotify
:
6011 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
6013 CARD16(event_sequencenumber
);
6014 WINDOW(eventwindow
);
6016 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 4, ENC_NA
);
6019 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 15, ENC_NA
);
6023 case CirculateRequest
:
6024 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
6026 CARD16(event_sequencenumber
);
6028 WINDOW(eventwindow
);
6029 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 4, ENC_NA
);
6032 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 15, ENC_NA
);
6036 case PropertyNotify
:
6037 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
6039 CARD16(event_sequencenumber
);
6040 WINDOW(eventwindow
);
6043 ENUM8(property_state
);
6044 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 15, ENC_NA
);
6048 case SelectionClear
:
6049 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
6051 CARD16(event_sequencenumber
);
6055 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 16, ENC_NA
);
6059 case SelectionRequest
:
6060 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
6062 CARD16(event_sequencenumber
);
6069 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 4, ENC_NA
);
6073 case SelectionNotify
:
6074 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
6076 CARD16(event_sequencenumber
);
6082 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 8, ENC_NA
);
6086 case ColormapNotify
:
6087 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
6089 CARD16(event_sequencenumber
);
6090 WINDOW(eventwindow
);
6093 ENUM8(colormap_state
);
6094 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 18, ENC_NA
);
6100 CARD16(event_sequencenumber
);
6101 WINDOW(eventwindow
);
6103 LISTofBYTE(data
, 20);
6107 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 1, ENC_NA
);
6109 CARD16(event_sequencenumber
);
6110 ENUM8(mapping_request
);
6111 CARD8(first_keycode
);
6113 proto_tree_add_item(t
, hf_x11_unused
, tvb
, *offsetp
, 25, ENC_NA
);
6118 tryGenericExtensionEvent(tvb
, offsetp
, t
, state
, byte_order
);
6122 tryExtensionEvent(eventcode
& 0x7F, tvb
, offsetp
, t
, state
, byte_order
);
6126 if ((left
= tvb_reported_length_remaining(tvb
, offset
)) > 0)
6131 dissect_x11_error(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
,
6132 const char *sep
, x11_conv_data_t
*state _U_
,
6133 unsigned byte_order
)
6135 int offset
= 0, *offsetp
= &offset
, left
;
6136 unsigned char errorcode
;
6140 ti
= proto_tree_add_item(tree
, proto_x11
, tvb
, 0, -1, ENC_NA
);
6141 t
= proto_item_add_subtree(ti
, ett_x11
);
6145 errorcode
= tvb_get_uint8(tvb
, offset
);
6146 col_append_fstr(pinfo
->cinfo
, COL_INFO
, "%s %s",
6147 sep
, val_to_str(errorcode
, state
->errorcode_vals
, "<Unknown errorcode %u>"));
6149 proto_tree_add_uint_format(t
, hf_x11_errorcode
, tvb
, offset
, 1,
6151 "errorcode: %d (%s)",
6153 val_to_str(errorcode
, state
->errorcode_vals
,
6154 "<Unknown errorcode %u>"));
6157 proto_item_append_text(ti
, ", Error, errorcode: %d (%s)",
6158 errorcode
, val_to_str(errorcode
, state
->errorcode_vals
,
6159 "<Unknown errorcode %u>"));
6164 CARD16(error_sequencenumber
);
6166 switch (errorcode
) {
6168 CARD32(error_badvalue
);
6178 CARD32(error_badresourceid
);
6185 CARD16(minor_opcode
);
6186 CARD8(major_opcode
);
6188 if ((left
= tvb_reported_length_remaining(tvb
, offset
)) > 0)
6194 /************************************************************************
6196 *** I N I T I A L I Z A T I O N A N D M A I N ***
6198 ************************************************************************/
6201 dissect_x11(tvbuff_t
*tvb
, packet_info
*pinfo
, proto_tree
*tree
, void* data _U_
)
6203 col_set_str(pinfo
->cinfo
, COL_PROTOCOL
, "X11");
6205 if (pinfo
->match_uint
== pinfo
->srcport
)
6206 dissect_x11_replies(tvb
, pinfo
, tree
);
6208 dissect_x11_requests(tvb
, pinfo
, tree
);
6210 return tvb_captured_length(tvb
);
6213 /* Register the protocol with Wireshark */
6214 void proto_register_x11(void)
6217 /* Setup list of header fields */
6218 static hf_register_info hf
[] = {
6219 #include "x11-register-info.h"
6222 /* Setup protocol subtree array */
6223 static int *ett
[] = {
6225 &ett_x11_color_flags
,
6226 &ett_x11_list_of_arc
,
6228 &ett_x11_list_of_atom
,
6229 &ett_x11_list_of_card32
,
6230 &ett_x11_list_of_float
,
6231 &ett_x11_list_of_double
,
6232 &ett_x11_list_of_color_item
,
6233 &ett_x11_color_item
,
6234 &ett_x11_list_of_keycode
,
6235 &ett_x11_list_of_keysyms
,
6237 &ett_x11_list_of_point
,
6239 &ett_x11_list_of_rectangle
,
6241 &ett_x11_list_of_segment
,
6243 &ett_x11_list_of_string8
,
6244 &ett_x11_list_of_text_item
,
6246 &ett_x11_gc_value_mask
,
6247 &ett_x11_event_mask
,
6248 &ett_x11_do_not_propagate_mask
,
6249 &ett_x11_set_of_key_mask
,
6250 &ett_x11_pointer_event_mask
,
6251 &ett_x11_window_value_mask
,
6252 &ett_x11_configure_window_mask
,
6253 &ett_x11_keyboard_value_mask
,
6254 &ett_x11_same_screen_focus
,
6256 &ett_x11_list_of_pixmap_format
,
6257 &ett_x11_pixmap_format
,
6258 &ett_x11_list_of_screen
,
6260 &ett_x11_list_of_depth_detail
,
6261 &ett_x11_depth_detail
,
6262 &ett_x11_list_of_visualtype
,
6263 &ett_x11_visualtype
,
6266 static ei_register_info ei
[] = {
6267 { &ei_x11_invalid_format
, { "x11.invalid_format", PI_PROTOCOL
, PI_WARN
, "Invalid Format", EXPFILL
}},
6268 { &ei_x11_request_length
, { "x11.request-length.invalid", PI_PROTOCOL
, PI_WARN
, "Invalid Length", EXPFILL
}},
6269 { &ei_x11_keycode_value_out_of_range
, { "x11.keycode_value_out_of_range", PI_PROTOCOL
, PI_WARN
, "keycode value is out of range", EXPFILL
}},
6272 module_t
*x11_module
;
6273 expert_module_t
* expert_x11
;
6275 /* Register the protocol name and description */
6276 proto_x11
= proto_register_protocol("X11", "X11", "x11");
6277 x11_handle
= register_dissector("x11", dissect_x11
, proto_x11
);
6279 /* Required function calls to register the header fields and subtrees used */
6280 proto_register_field_array(proto_x11
, hf
, array_length(hf
));
6281 proto_register_subtree_array(ett
, array_length(ett
));
6282 expert_x11
= expert_register_protocol(proto_x11
);
6283 expert_register_field_array(expert_x11
, ei
, array_length(ei
));
6285 extension_table
= wmem_map_new(wmem_epan_scope(), wmem_str_hash
, g_str_equal
);
6286 error_table
= wmem_map_new(wmem_epan_scope(), wmem_str_hash
, g_str_equal
);
6287 event_table
= wmem_map_new(wmem_epan_scope(), wmem_str_hash
, g_str_equal
);
6288 genevent_table
= wmem_map_new(wmem_epan_scope(), wmem_str_hash
, g_str_equal
);
6289 reply_table
= wmem_map_new(wmem_epan_scope(), wmem_str_hash
, g_str_equal
);
6290 register_x11_extensions();
6292 x11_module
= prefs_register_protocol(proto_x11
, NULL
);
6293 prefs_register_bool_preference(x11_module
, "desegment",
6294 "Reassemble X11 messages spanning multiple TCP segments",
6295 "Whether the X11 dissector should reassemble messages spanning multiple TCP segments. "
6296 "To use this option, you must also enable \"Allow subdissectors to reassemble TCP streams\" in the TCP protocol settings.",
6301 proto_reg_handoff_x11(void)
6303 dissector_add_uint_range_with_preference("tcp.port", DEFAULT_X11_PORT_RANGE
, x11_handle
);
6312 * indent-tabs-mode: nil
6315 * ex: set shiftwidth=6 tabstop=8 expandtab:
6316 * :indentSize=6:tabSize=8:noTabs=true: