* Copyright 2000, Christophe Tronche <ch.tronche@computer.org>
* Copyright 2003, Michael Shuldman
*
- * $Id: packet-x11.c,v 1.48 2004/01/02 12:52:45 obiot Exp $
+ * $Id: packet-x11.c,v 1.59 2004/06/23 21:43:02 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@ethereal.com>
* the initial connection request, and the byte order of the connection.
*
* An opcode of -3 means we haven't yet seen any requests yet.
- * An opcode of -2 means we're not expecting a reply.
- * An opcode of -1 means means we're waiting for a reply to the initial
+ * An opcode of -2 means we're not expecting a reply (unused).
+ * An opcode of -1 means we're waiting for a reply to the initial
* connection request.
+ * An opcode of 0 means the request was not seen (or unknown).
* Other values are the opcode of the request for which we're expecting
* a reply.
*
#define NOTHING_SEEN -3
#define NOTHING_EXPECTED -2
#define INITIAL_CONN -1
+#define UNKNOWN_OPCODE 0
+
+#define MAX_OPCODES (255 + 1) /* 255 + INITIAL_CONN */
#define BYTE_ORDER_BE 0
#define BYTE_ORDER_LE 1
#define NoSymbol 0L /* special KeySym */
typedef struct {
- GHashTable *seqtable; /* hashtable of sequncenumber <-> opcode. */
+ GHashTable *seqtable; /* hashtable of sequencenumber <-> opcode. */
+ GHashTable *valtable;/* hashtable of sequencenumber <-> &opcode_vals */
+ /* major opcodes including extensions (NULL terminated) */
+ value_string opcode_vals[MAX_OPCODES+1];
int sequencenumber; /* sequencenumber of current packet. */
guint32 iconn_frame; /* frame # of initial connection request */
guint32 iconn_reply; /* frame # of initial connection reply */
int byte_order; /* byte order of connection */
+ gboolean resync; /* resynchronization of sequence number performed */
int *keycodemap[256]; /* keycode to keysymvalue map. */
int keysyms_per_keycode;
int first_keycode;
- int *modifiermap[array_length(modifiers)];/* modifier to keycode. */
+ int *modifiermap[array_length(modifiers)];/* modifier to keycode.*/
int keycodes_per_modifier;
union {
static gint ett_x11_list_of_string8 = -1;
static gint ett_x11_list_of_text_item = -1;
static gint ett_x11_text_item = -1;
-static gint ett_x11_gc_value_mask = -1;
-static gint ett_x11_event_mask = -1;
-static gint ett_x11_do_not_propagate_mask = -1;
+static gint ett_x11_gc_value_mask = -1; /* XXX - unused */
+static gint ett_x11_event_mask = -1; /* XXX - unused */
+static gint ett_x11_do_not_propagate_mask = -1; /* XXX - unused */
static gint ett_x11_set_of_key_mask = -1;
-static gint ett_x11_pointer_event_mask = -1;
-static gint ett_x11_window_value_mask = -1;
-static gint ett_x11_configure_window_mask = -1;
-static gint ett_x11_keyboard_value_mask = -1;
+static gint ett_x11_pointer_event_mask = -1; /* XXX - unused */
+static gint ett_x11_window_value_mask = -1; /* XXX - unused */
+static gint ett_x11_configure_window_mask = -1; /* XXX - unused */
+static gint ett_x11_keyboard_value_mask = -1; /* XXX - unused */
+static gint ett_x11_same_screen_focus = -1;
/* desegmentation of X11 messages */
static gboolean x11_desegment = TRUE;
{ 0, NULL }
};
+static const value_string colormap_state_vals[] = {
+ { 0, "Uninstalled" },
+ { 1, "Installed" },
+ { 0, NULL }
+};
+
static const value_string coordinate_mode_vals[] = {
{ 0, "Origin" },
{ 1, "Previous" },
{ 0, NULL }
};
+static const value_string destination_vals[] = {
+ { 0, "PointerWindow" },
+ { 1, "InputFocus" },
+ { 0, NULL }
+};
+
static const value_string direction_vals[] = {
{ 0, "RaiseLowest" },
{ 1, "LowerHighest" },
{ 0, NULL }
};
+static const value_string event_detail_vals[] = {
+ { 0, "Ancestor" },
+ { 1, "Virtual" },
+ { 2, "Inferior" },
+ { 3, "Nonlinear" },
+ { 4, "NonlinearVirtual" },
+ { 0, NULL }
+};
+
#define FAMILY_INTERNET 0
#define FAMILY_DECNET 1
#define FAMILY_CHAOS 2
{ 0, NULL }
};
+static const value_string focus_detail_vals[] = {
+ { 0, "Ancestor" },
+ { 1, "Virtual" },
+ { 2, "Inferior" },
+ { 3, "Nonlinear" },
+ { 4, "NonlinearVirtual" },
+ { 5, "Pointer" },
+ { 6, "PointerRoot" },
+ { 7, "None" },
+ { 0, NULL }
+};
+
+static const value_string focus_mode_vals[] = {
+ { 0, "Normal" },
+ { 1, "Grab" },
+ { 2, "Ungrab" },
+ { 3, "WhileGrabbed" },
+ { 0, NULL }
+};
+
static const value_string focus_vals[] = {
{ 0, "None" },
{ 1, "PointerRoot" },
{ 0, NULL }
};
+static const value_string grab_mode_vals[] = {
+ { 0, "Normal" },
+ { 1, "Grab" },
+ { 2, "Ungrab" },
+ { 0, NULL }
+};
+
+static const value_string grab_status_vals[] = {
+ { 0, "Success" },
+ { 1, "AlreadyGrabbed" },
+ { 2, "InvalidTime" },
+ { 3, "NotViewable" },
+ { 4, "Frozen" },
+ { 0, NULL }
+};
+
static const value_string gravity_vals[] = {
{ 1, "NorthWest" },
{ 2, "North" },
{ 0, NULL }
};
+static const value_string place_vals[] = {
+ { 0, "Top" },
+ { 1, "Bottom" },
+ { 0, NULL }
+};
+
+static const value_string property_state_vals[] = {
+ { 0, "NewValue" },
+ { 1, "Deleted" },
+ { 0, NULL }
+};
+
+static const value_string visibility_state_vals[] = {
+ { 0, "Unobscured" },
+ { 1, "PartiallyObscured" },
+ { 2, "FullyObscured" },
+ { 0, NULL }
+};
+
/* Requestcodes. From <X11/Xproto.h>. */
#define X_CreateWindow 1
#define X_ChangeWindowAttributes 2
#define X_SetModifierMapping 118
#define X_GetModifierMapping 119
#define X_NoOperation 127
+#define X_FirstExtension 128
+#define X_LastExtension 255
static const value_string opcode_vals[] = {
{ INITIAL_CONN, "Initial connection request" },
{ X_SetSelectionOwner, "SetSelectionOwner" },
{ X_GetSelectionOwner, "GetSelectionOwner" },
{ X_ConvertSelection, "ConvertSelection" },
- /* { X_SendEvent, "SendEvent" }, */
+ { X_SendEvent, "SendEvent" },
{ X_GrabPointer, "GrabPointer" },
{ X_UngrabPointer, "UngrabPointer" },
{ X_GrabButton, "GrabButton" },
#define ColormapNotify 32
#define ClientMessage 33
#define MappingNotify 34
+#define FirstExtensionEvent 64
+#define LastExtensionEvent 127
static const value_string eventcode_vals[] = {
{ KeyPress, "KeyPress" },
#define CURSOR(name) FIELD32(name)
#define DRAWABLE(name) FIELD32(name)
#define ENUM8(name) (FIELD8(name))
-#define ENUM16(name) FIELD16(name)
+#define ENUM16(name) (FIELD16(name))
#define FONT(name) FIELD32(name)
#define FONTABLE(name) FIELD32(name)
#define GCONTEXT(name) FIELD32(name)
#define SETofEVENT(name) { setOfEvent(tvb, offsetp, t, little_endian); }
#define SETofDEVICEEVENT(name) { setOfDeviceEvent(tvb, offsetp, t, little_endian);}
#define SETofKEYMASK(name) { setOfKeyButMask(tvb, offsetp, t, little_endian, 0); }
+#define SETofKEYBUTMASK(name) { setOfKeyButMask(tvb, offsetp, t, little_endian, 1); }
#define SETofPOINTEREVENT(name) { setOfPointerEvent(tvb, offsetp, t, little_endian); }
#define STRING8(name, length) { string8(tvb, offsetp, t, hf_x11_##name, length); }
#define STRING16(name, length) { string16(tvb, offsetp, t, hf_x11_##name, hf_x11_##name##_bytes, length, little_endian); }
*offsetp, sizeof(seqno), seqno, \
"sequencenumber: %d (%s)", \
(int)seqno, \
- val_to_str(opcode, opcode_vals, "<Unknown opcode %d>")); \
+ val_to_str(opcode, state->opcode_vals, "<Unknown opcode %d>")); \
*offsetp += sizeof(seqno); \
} while (0)
static void
dissect_x11_initial_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
- const char *sep, x11_conv_data_t *volatile state, gboolean
- little_endian);
+ const char *sep, x11_conv_data_t *volatile state,
+ gboolean little_endian);
static void
dissect_x11_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
- const char *sep, x11_conv_data_t *volatile state, gboolean
- little_endian);
+ const char *volatile sep, x11_conv_data_t *volatile state,
+ gboolean little_endian);
static void
dissect_x11_error(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
- const char *sep, x11_conv_data_t *volatile state,
+ const char *volatile sep, x11_conv_data_t *volatile state,
gboolean little_endian);
static void
dissect_x11_event(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
- const char *sep, x11_conv_data_t *volatile state,
+ const char *volatile sep, x11_conv_data_t *volatile state,
gboolean little_endian);
static void
return GPOINTER_TO_INT(b) - GPOINTER_TO_INT(a);
}
+static void
+XConvertCase(register int sym, int *lower, int *upper)
+{
+ *lower = sym;
+ *upper = sym;
+ switch(sym >> 8) {
+ case 0: /* Latin 1 */
+ if ((sym >= XK_A) && (sym <= XK_Z))
+ *lower += (XK_a - XK_A);
+ else if ((sym >= XK_a) && (sym <= XK_z))
+ *upper -= (XK_a - XK_A);
+ else if ((sym >= XK_Agrave) && (sym <= XK_Odiaeresis))
+ *lower += (XK_agrave - XK_Agrave);
+ else if ((sym >= XK_agrave) && (sym <= XK_odiaeresis))
+ *upper -= (XK_agrave - XK_Agrave);
+ else if ((sym >= XK_Ooblique) && (sym <= XK_Thorn))
+ *lower += (XK_oslash - XK_Ooblique);
+ else if ((sym >= XK_oslash) && (sym <= XK_thorn))
+ *upper -= (XK_oslash - XK_Ooblique);
+ break;
+ case 1: /* Latin 2 */
+ /* Assume the KeySym is a legal value (ignore discontinuities) */
+ if (sym == XK_Aogonek)
+ *lower = XK_aogonek;
+ else if (sym >= XK_Lstroke && sym <= XK_Sacute)
+ *lower += (XK_lstroke - XK_Lstroke);
+ else if (sym >= XK_Scaron && sym <= XK_Zacute)
+ *lower += (XK_scaron - XK_Scaron);
+ else if (sym >= XK_Zcaron && sym <= XK_Zabovedot)
+ *lower += (XK_zcaron - XK_Zcaron);
+ else if (sym == XK_aogonek)
+ *upper = XK_Aogonek;
+ else if (sym >= XK_lstroke && sym <= XK_sacute)
+ *upper -= (XK_lstroke - XK_Lstroke);
+ else if (sym >= XK_scaron && sym <= XK_zacute)
+ *upper -= (XK_scaron - XK_Scaron);
+ else if (sym >= XK_zcaron && sym <= XK_zabovedot)
+ *upper -= (XK_zcaron - XK_Zcaron);
+ else if (sym >= XK_Racute && sym <= XK_Tcedilla)
+ *lower += (XK_racute - XK_Racute);
+ else if (sym >= XK_racute && sym <= XK_tcedilla)
+ *upper -= (XK_racute - XK_Racute);
+ break;
+ case 2: /* Latin 3 */
+ /* Assume the KeySym is a legal value (ignore discontinuities) */
+ if (sym >= XK_Hstroke && sym <= XK_Hcircumflex)
+ *lower += (XK_hstroke - XK_Hstroke);
+ else if (sym >= XK_Gbreve && sym <= XK_Jcircumflex)
+ *lower += (XK_gbreve - XK_Gbreve);
+ else if (sym >= XK_hstroke && sym <= XK_hcircumflex)
+ *upper -= (XK_hstroke - XK_Hstroke);
+ else if (sym >= XK_gbreve && sym <= XK_jcircumflex)
+ *upper -= (XK_gbreve - XK_Gbreve);
+ else if (sym >= XK_Cabovedot && sym <= XK_Scircumflex)
+ *lower += (XK_cabovedot - XK_Cabovedot);
+ else if (sym >= XK_cabovedot && sym <= XK_scircumflex)
+ *upper -= (XK_cabovedot - XK_Cabovedot);
+ break;
+ case 3: /* Latin 4 */
+ /* Assume the KeySym is a legal value (ignore discontinuities) */
+ if (sym >= XK_Rcedilla && sym <= XK_Tslash)
+ *lower += (XK_rcedilla - XK_Rcedilla);
+ else if (sym >= XK_rcedilla && sym <= XK_tslash)
+ *upper -= (XK_rcedilla - XK_Rcedilla);
+ else if (sym == XK_ENG)
+ *lower = XK_eng;
+ else if (sym == XK_eng)
+ *upper = XK_ENG;
+ else if (sym >= XK_Amacron && sym <= XK_Umacron)
+ *lower += (XK_amacron - XK_Amacron);
+ else if (sym >= XK_amacron && sym <= XK_umacron)
+ *upper -= (XK_amacron - XK_Amacron);
+ break;
+ case 6: /* Cyrillic */
+ /* Assume the KeySym is a legal value (ignore discontinuities) */
+ if (sym >= XK_Serbian_DJE && sym <= XK_Serbian_DZE)
+ *lower -= (XK_Serbian_DJE - XK_Serbian_dje);
+ else if (sym >= XK_Serbian_dje && sym <= XK_Serbian_dze)
+ *upper += (XK_Serbian_DJE - XK_Serbian_dje);
+ else if (sym >= XK_Cyrillic_YU && sym <= XK_Cyrillic_HARDSIGN)
+ *lower -= (XK_Cyrillic_YU - XK_Cyrillic_yu);
+ else if (sym >= XK_Cyrillic_yu && sym <= XK_Cyrillic_hardsign)
+ *upper += (XK_Cyrillic_YU - XK_Cyrillic_yu);
+ break;
+ case 7: /* Greek */
+ /* Assume the KeySym is a legal value (ignore discontinuities) */
+ if (sym >= XK_Greek_ALPHAaccent && sym <= XK_Greek_OMEGAaccent)
+ *lower += (XK_Greek_alphaaccent - XK_Greek_ALPHAaccent);
+ else if (sym >= XK_Greek_alphaaccent && sym <= XK_Greek_omegaaccent &&
+ sym != XK_Greek_iotaaccentdieresis &&
+ sym != XK_Greek_upsilonaccentdieresis)
+ *upper -= (XK_Greek_alphaaccent - XK_Greek_ALPHAaccent);
+ else if (sym >= XK_Greek_ALPHA && sym <= XK_Greek_OMEGA)
+ *lower += (XK_Greek_alpha - XK_Greek_ALPHA);
+ else if (sym >= XK_Greek_alpha && sym <= XK_Greek_omega &&
+ sym != XK_Greek_finalsmallsigma)
+ *upper -= (XK_Greek_alpha - XK_Greek_ALPHA);
+ break;
+ }
+}
+
static const char *
keycode2keysymString(int *keycodemap[256], int first_keycode,
int keysyms_per_keycode,
return "<Unknown>";
for (kc = first_keycode, groupmodkc = numlockkc = -1; kc < 256; ++kc)
- for (keysym = 0; keysym < keysyms_per_keycode; ++keysym)
+ for (keysym = 0; keysym < keysyms_per_keycode; ++keysym) {
+ if (keycodemap[kc] == NULL)
+ return "<Unknown>";
switch (keycodemap[kc][keysym]) {
case 0xff7e:
groupmodkc = kc;
lockmod_is_shiftlock = kc;
break;
}
+ }
/*
/* find out what the numlockmodifer and groupmodifier is. */
for (modifier = 0, numlockmod = groupmod = -1;
- modifier < (int)array_length(modifiers) && numlockmod == -1;
- ++modifier)
+ modifier < (int)array_length(modifiers) && numlockmod == -1;
+ ++modifier)
for (kc = 0; kc < keycodes_per_modifier; ++kc)
if (modifiermap[modifier][kc] == numlockkc)
numlockmod = modifier;
*/
if (numlockmod >= 0 && (bitmask & modifiermask[numlockmod])
- && ((keycodemap[keycode][1] >= 0xff80
- && keycodemap[keycode][1] <= 0xffbd)
- || (keycodemap[keycode][1] >= 0x11000000
- && keycodemap[keycode][1] <= 0x1100ffff))) {
+ && ((syms[1] >= 0xff80
+ && syms[1] <= 0xffbd)
+ || (syms[1] >= 0x11000000
+ && syms[1] <= 0x1100ffff))) {
if ((bitmask & ShiftMask) || lockmod_is_shiftlock)
- return keysymString(keycodemap[keycode][groupmod + 0]);
+ return keysymString(syms[groupmod + 0]);
else
- if (keycodemap[keycode][groupmod + 1] == NoSymbol)
- return keysymString(keycodemap[keycode]
- [groupmod + 0]);
+ if (syms[groupmod + 1] == NoSymbol)
+ return keysymString(syms[groupmod + 0]);
else
- return keysymString(keycodemap[keycode]
- [groupmod + 1]);
+ return keysymString(syms[groupmod + 1]);
}
else if (!(bitmask & ShiftMask) && !(bitmask & LockMask))
- return keysymString(keycodemap[keycode][groupmod + 0]);
+ return keysymString(syms[groupmod + 0]);
else if (!(bitmask & ShiftMask)
- && ((bitmask & LockMask) && lockmod_is_capslock))
- if (islower(keycodemap[keycode][groupmod + 0]))
-/* return toupper(keysymString(keycodemap[keycode][groupmod + 0])); */
+ && ((bitmask & LockMask) && lockmod_is_capslock))
+ if (islower(syms[groupmod + 0]))
+/* return toupper(keysymString(syms[groupmod + 0])); */
return "Uppercase"; /* XXX */
else
- return keysymString(keycodemap[keycode][groupmod + 0]);
+ return keysymString(syms[groupmod + 0]);
else if ((bitmask & ShiftMask)
- && ((bitmask & LockMask) && lockmod_is_capslock))
- if (islower(keycodemap[keycode][groupmod + 1]))
-/* return toupper(keysymString(keycodemap[keycode][groupmod + 1])); */
+ && ((bitmask & LockMask) && lockmod_is_capslock))
+ if (islower(syms[groupmod + 1]))
+/* return toupper(keysymString(syms[groupmod + 1])); */
return "Uppercase"; /* XXX */
else
- return keysymString(keycodemap[keycode][groupmod + 1]);
+ return keysymString(syms[groupmod + 1]);
else if ((bitmask & ShiftMask)
- || ((bitmask & LockMask) && lockmod_is_shiftlock))
- return keysymString(keycodemap[keycode][groupmod + 1]);
+ || ((bitmask & LockMask) && lockmod_is_shiftlock))
+ return keysymString(syms[groupmod + 1]);
#else /* _XTranslateKey() based code. */
while (keysyms_per_keycode > 2
- && keycodemap[keysyms_per_keycode - 1] == NoSymbol)
+ && keycodemap[keysyms_per_keycode - 1] == NoSymbol)
--keysyms_per_keycode;
if (keysyms_per_keycode > 2
- && (groupmod >= 0 && (modifiermask[groupmod] & bitmask))) {
+ && (groupmod >= 0 && (modifiermask[groupmod] & bitmask))) {
syms += 2;
keysyms_per_keycode -= 2;
}
if (numlockmod >= 0 && (bitmask & modifiermask[numlockmod])
- && keysyms_per_keycode > 1 && ((syms[1] >= 0xff80 && syms[1] <= 0xffbd)
- || (syms[1] >= 0x11000000 && syms[1] <= 0x1100ffff))) {
+ && keysyms_per_keycode > 1
+ && ((syms[1] >= 0xff80 && syms[1] <= 0xffbd)
+ || (syms[1] >= 0x11000000 && syms[1] <= 0x1100ffff))) {
if ((bitmask & ShiftMask)
- || (bitmask & LockMask && lockmod_is_shiftlock))
+ || (bitmask & LockMask && lockmod_is_shiftlock))
keysym = syms[0];
else
keysym = syms[1];
}
else if (!(bitmask & ShiftMask)
- && (!(bitmask & LockMask) || lockmod_is_nosymbol)) {
+ && (!(bitmask & LockMask) || lockmod_is_nosymbol)) {
if (keysyms_per_keycode == 1
- || (keysyms_per_keycode > 1 && syms[1] == NoSymbol)) {
+ || (keysyms_per_keycode > 1 && syms[1] == NoSymbol)) {
int usym;
XConvertCase(syms[0], &keysym, &usym);
int lsym, usym;
if (keysyms_per_keycode == 1
- || (keysyms_per_keycode > 1 && (usym = syms[1]) == NoSymbol))
+ || (keysyms_per_keycode > 1 && (usym = syms[1]) == NoSymbol))
XConvertCase(syms[0], &lsym, &usym);
keysym = usym;
}
int lsym, usym;
if (keysyms_per_keycode == 1
- || (keysyms_per_keycode > 1 && syms[1] == NoSymbol))
+ || (keysyms_per_keycode > 1 && syms[1] == NoSymbol))
keysym = syms[0];
XConvertCase(keysym, &lsym, &usym);
size_t m;
for (m = 0; m < array_length(modifiers);
- ++m, *offsetp += keycodes_per_modifier) {
+ ++m, *offsetp += keycodes_per_modifier) {
+ const guint8 *p;
char *bp = buffer;
int i;
- modifiermap[m] = g_malloc(keycodes_per_modifier);
+ p = tvb_get_ptr(tvb, *offsetp, keycodes_per_modifier);
+ modifiermap[m] =
+ g_malloc(sizeof(*modifiermap[m]) * keycodes_per_modifier);
for(i = 0; i < keycodes_per_modifier; ++i) {
- guchar c = tvb_get_guint8(tvb, *offsetp + i);
+ guchar c = p[i];
if (c)
bp += sprintf(bp, " %s=%d", modifiers[m], c);
}
proto_tree_add_bytes_format(tt, hf_x11_keycodes_item, tvb,
- *offsetp, keycodes_per_modifier,
- tvb_get_ptr(tvb, *offsetp, keycodes_per_modifier),
- "item: %s", buffer);
+ *offsetp, keycodes_per_modifier, p,
+ "item: %s", buffer);
}
}
for (keycode = keycode_first; keycode_count > 0;
- ++keycode, --keycode_count) {
+ ++keycode, --keycode_count) {
tti = proto_tree_add_none_format(tt, hf_item, tvb, *offsetp,
keysyms_per_keycode * 4, "keysyms (keycode %d):", keycode);
ttt = proto_item_add_subtree(tti, ett_x11_keysym);
+ tvb_ensure_bytes_exist(tvb, *offsetp, 4 * keysyms_per_keycode);
keycodemap[keycode]
- = g_malloc(sizeof(*keycodemap[keycode]) * keysyms_per_keycode);
+ = g_malloc(sizeof(*keycodemap[keycode]) * keysyms_per_keycode);
for(i = 0; i < keysyms_per_keycode; ++i) {
/* keysymvalue = byte3 * 256 + byte4. */
proto_item_append_text(tti, " %s", keysymString(v));
proto_tree_add_uint_format(ttt, hf_x11_keysyms_item_keysym,
- tvb, *offsetp, 4, v,
- "keysym (keycode %d): 0x%08x (%s)",
- keycode, v, keysymString(v));
+ tvb, *offsetp, 4, v,
+ "keysym (keycode %d): 0x%08x (%s)",
+ keycode, v, keysymString(v));
keycodemap[keycode][i] = v;
*offsetp += 4;
*offsetp += 2;
}
-
static void setOfPointerEvent(tvbuff_t *tvb, int *offsetp, proto_tree *t,
gboolean little_endian)
{
static void string8(tvbuff_t *tvb, int *offsetp, proto_tree *t,
int hf, unsigned length)
{
- char *s = g_malloc(length + 1);
+ const guint8 *p;
+ char *s;
- /*
- * In case we throw an exception, clean up whatever stuff we've
- * allocated (if any).
- */
- CLEANUP_PUSH(g_free, s);
-
- stringCopy(s, tvb_get_ptr(tvb, *offsetp, length), length);
+ p = tvb_get_ptr(tvb, *offsetp, length);
+ s = g_malloc(length + 1);
+ stringCopy(s, p, length);
proto_tree_add_string(t, hf, tvb, *offsetp, length, s);
-
- /*
- * Call the cleanup handler to free the string and pop the handler.
- */
- CLEANUP_CALL_AND_POP;
-
+ g_free(s);
*offsetp += length;
}
*/
state->sequencenumber = 0;
g_hash_table_insert(state->seqtable, (int *)state->sequencenumber,
- (int *)INITIAL_CONN);
+ (int *)INITIAL_CONN);
}
static void dissect_x11_initial_reply(tvbuff_t *tvb, packet_info *pinfo,
- proto_tree *tree, const char _U_ *sep, x11_conv_data_t *state,
+ proto_tree *tree, const char _U_ *sep, x11_conv_data_t *volatile state,
gboolean little_endian)
{
int offset = 0, *offsetp = &offset, left;
unsigned char success;
int length_of_vendor;
+ int length_of_reason;
proto_item *ti;
proto_tree *t;
state->iconn_reply = pinfo->fd->num;
success = INT8(success);
- if (success == 0) {
- UNDECODED(1);
+ if (success) {
+ UNUSED(1);
+ length_of_reason = 0;
}
else {
- UNUSED(1);
+ length_of_reason = INT8(length_of_reason);
}
INT16(protocol_major_version);
INT16(protocol_minor_version);
INT16(replylength);
- INT32(release_number);
- INT32(resource_id_base);
- INT32(resource_id_mask);
- INT32(motion_buffer_size);
- length_of_vendor = INT16(length_of_vendor);
- INT16(maximum_request_length);
- INT8(number_of_screens_in_roots);
- INT8(number_of_formats_in_pixmap_formats);
- INT8(image_byte_order);
- INT8(bitmap_format_bit_order);
- INT8(bitmap_format_scanline_unit);
- INT8(bitmap_format_scanline_pad);
- INT8(min_keycode);
- INT8(max_keycode);
- UNUSED(4);
- STRING8(vendor, length_of_vendor);
+ if (success) {
+ INT32(release_number);
+ INT32(resource_id_base);
+ INT32(resource_id_mask);
+ INT32(motion_buffer_size);
+ length_of_vendor = INT16(length_of_vendor);
+ INT16(maximum_request_length);
+ INT8(number_of_screens_in_roots);
+ INT8(number_of_formats_in_pixmap_formats);
+ INT8(image_byte_order);
+ INT8(bitmap_format_bit_order);
+ INT8(bitmap_format_scanline_unit);
+ INT8(bitmap_format_scanline_pad);
+ INT8(min_keycode);
+ INT8(max_keycode);
+ UNUSED(4);
+ STRING8(vendor, length_of_vendor);
+ } else {
+ STRING8(reason, length_of_reason);
+ }
if ((left = tvb_reported_length_remaining(tvb, offset)) > 0)
UNDECODED(left);
int next_offset;
proto_item *ti;
proto_tree *t;
- int length, opcode;
+ int length, opcode, i;
guint8 v8, v8_2, v8_3;
guint16 v16;
guint32 v32;
gint left;
- char *str;
+ gchar *name;
length = VALUE16(tvb, 2) * 4;
if (check_col(pinfo->cinfo, COL_INFO))
col_append_fstr(pinfo->cinfo, COL_INFO, "%s %s", sep,
- val_to_str(opcode, opcode_vals, "<Unknown opcode %d>"));
-
- str = g_strdup_printf(", Request, opcode: %d (%s)",
- opcode, val_to_str(opcode, opcode_vals,
- "<Unknown opcode %d>"));
+ val_to_str(opcode, state->opcode_vals,
+ "<Unknown opcode %d>"));
- proto_item_append_text(ti, str);
- g_free(str);
+ proto_item_append_text(ti, ", Request, opcode: %d (%s)",
+ opcode, val_to_str(opcode, state->opcode_vals,
+ "<Unknown opcode %d>"));
/*
* Does this request expect a reply?
*/
switch(opcode) {
+
+ case X_QueryExtension:
+
+ /* necessary processing even if tree == NULL */
+
+ v16 = VALUE16(tvb, 4);
+ name = g_malloc(v16 + 1);
+ stringCopy(name, tvb_get_ptr(tvb, 8, v16), v16);
+
+ /* store string of extension, opcode will be set at reply */
+ i = 0;
+ while(i < MAX_OPCODES) {
+ if (state->opcode_vals[i].strptr == NULL) {
+ state->opcode_vals[i].strptr = name;
+ g_hash_table_insert(state->valtable,
+ (int *)state->sequencenumber,
+ (int *)&state->opcode_vals[i]);
+ break;
+ } else if (strcmp(state->opcode_vals[i].strptr,
+ name) == 0) {
+ g_hash_table_insert(state->valtable,
+ (int *)state->sequencenumber,
+ (int *)&state->opcode_vals[i]);
+ break;
+ }
+ i++;
+ }
+
+ /* QueryExtension expects a reply, fall through */
+
case X_AllocColor:
case X_AllocColorCells:
case X_AllocColorPlanes:
case X_LookupColor:
case X_QueryBestSize:
case X_QueryColors:
- case X_QueryExtension:
case X_QueryFont:
case X_QueryKeymap:
case X_QueryPointer:
/*
* Those requests expect a reply.
*/
-
g_hash_table_insert(state->seqtable,
- (int *)state->sequencenumber, (int *)opcode);
+ (int *)state->sequencenumber,
+ (int *)opcode);
break;
default:
+ /*
+ * With Extension, we don't know, so assume there could be one
+ */
+ if (opcode >= X_FirstExtension && opcode <= X_LastExtension) {
+ g_hash_table_insert(state->seqtable,
+ (int *)state->sequencenumber,
+ (int *)opcode);
+ }
+
/*
* No reply is expected from any other request.
*/
TIMESTAMP(time);
break;
+ case X_SendEvent:
+ BOOL(propagate);
+ REQUEST_LENGTH();
+ WINDOW(destination);
+ SETofEVENT(event_mask);
+ UNDECODED(32);
+ break;
+
case X_GrabPointer:
BOOL(owner_events);
REQUEST_LENGTH();
int length;
tvbuff_t *next_tvb;
- while ((length_remaining = tvb_reported_length_remaining(tvb, offset))
- > 0) {
+ while (tvb_reported_length_remaining(tvb, offset) != 0) {
+ /*
+ * We use "tvb_ensure_length_remaining()" to make sure there
+ * actually *is* data remaining.
+ *
+ * This means we're guaranteed that "length_remaining" is
+ * positive.
+ */
+ length_remaining = tvb_ensure_length_remaining(tvb, offset);
+
/*
* Can we do reassembly?
*/
static void
x11_stateinit(x11_conv_data_t **state, conversation_t *conversation)
{
-
- /*
- * No - create a state structure and attach it.
- */
static x11_conv_data_t stateinit;
+ int i = 0;
*state = g_mem_chunk_alloc(x11_state_chunk);
**state = stateinit;
+ /* initialise opcodes */
+ while (1) {
+ if (opcode_vals[i].strptr == NULL) break;
+ (*state)->opcode_vals[i].value = opcode_vals[i].value;
+ (*state)->opcode_vals[i].strptr = opcode_vals[i].strptr;
+ i++;
+ }
+ while (i <= MAX_OPCODES) {
+ (*state)->opcode_vals[i].value = 0;
+ (*state)->opcode_vals[i].strptr = NULL;
+ i++;
+ }
+
(*state)->seqtable = g_hash_table_new(g_direct_hash, g_direct_equal);
+ (*state)->valtable = g_hash_table_new(g_direct_hash, g_direct_equal);
g_hash_table_insert((*state)->seqtable, (int *)0, (int *)NOTHING_SEEN);
(*state)->byte_order = BYTE_ORDER_UNKNOWN; /* don't know yet*/
conversation_add_proto_data(conversation, proto_x11, *state);
* Is there state attached to this conversation?
*/
if ((state = conversation_get_proto_data(conversation, proto_x11))
- == NULL)
+ == NULL) {
+ /*
+ * No - create a state structure and attach it.
+ */
x11_stateinit(&state, conversation);
+ }
/*
* Guess the byte order if we don't already know it.
little_endian = guess_byte_ordering(tvb, pinfo, state);
offset = 0;
- while ((length_remaining = tvb_reported_length_remaining(tvb, offset))
- > 0) {
+ while (tvb_reported_length_remaining(tvb, offset) != 0) {
+ /*
+ * We use "tvb_ensure_length_remaining()" to make sure there
+ * actually *is* data remaining.
+ *
+ * This means we're guaranteed that "length_remaining" is
+ * positive.
+ */
+ length_remaining = tvb_ensure_length_remaining(tvb, offset);
+
/*
* Can we do reassembly?
*/
/*
* Find out what kind of a reply it is.
- * There are three possible:
+ * There are four possible:
+ * - reply to initial connection
* - errorreply (a request generated an error)
* - requestreply (reply to a request)
- * - eventreply (some event occured)
+ * - event (some event occured)
*/
+ if (g_hash_table_lookup(state->seqtable,
+ (int *)state->sequencenumber) == (int *)INITIAL_CONN
+ || (state->iconn_reply == pinfo->fd->num)) {
+ /*
+ * Either the connection is in the "initial
+ * connection" state, or this frame is known
+ * to have the initial connection reply.
+ * That means this is the initial connection
+ * reply.
+ */
+ plen = 8 + VALUE16(tvb, offset + 6) * 4;
+
+ HANDLE_REPLY(plen, length_remaining,
+ "Initial connection reply",
+ dissect_x11_initial_reply);
+ } else {
+ /*
+ * This isn't an initial connection reply
+ * (XXX - unless we missed the initial
+ * connection request). Look at the first
+ * byte to determine what it is; errors
+ * start with a byte of 0, replies start
+ * with a byte of 1, events start with
+ * a byte with of 2 or greater.
+ */
+ switch (tvb_get_guint8(tvb, offset)) {
- switch (tvb_get_guint8(tvb, offset)) {
- case 0:
- plen = 32;
- HANDLE_REPLY(plen, length_remaining,
- "Error", dissect_x11_error);
+ case 0:
+ plen = 32;
+ HANDLE_REPLY(plen, length_remaining,
+ "Error", dissect_x11_error);
break;
case 1:
/* replylength is in units of four. */
- if (g_hash_table_lookup(state->seqtable,
- (int *)state->sequencenumber)
- == (int *)INITIAL_CONN
- || (state->iconn_reply == pinfo->fd->num)) {
- /*
- * ref. by A. Nye. says all
- * replies are 32 + "additional bytes".
- * Initial serverreply seems to be
- * the exception, it's 8 + "additional
- * bytes".
- */
- plen = 8 + VALUE16(tvb, offset + 6) * 4;
-
- HANDLE_REPLY(plen, length_remaining,
- "Initial connection reply",
- dissect_x11_initial_reply);
- }
- else {
- plen
- = 32 + VALUE32(tvb, offset + 4) * 4;
-
- HANDLE_REPLY(plen, length_remaining,
- "Reply", dissect_x11_reply);
- }
+ plen = 32 + VALUE32(tvb, offset + 4) * 4;
+
+ HANDLE_REPLY(plen, length_remaining,
+ "Reply", dissect_x11_reply);
break;
default:
+ /* Event */
plen = 32;
HANDLE_REPLY(plen, length_remaining,
- "Event", dissect_x11_event);
+ "Event", dissect_x11_event);
break;
- }
+ }
+ }
offset += plen;
}
gboolean little_endian)
{
int offset = 0, *offsetp = &offset, length, left, opcode;
+ int major_opcode, sequence_number;
+ value_string *vals_p;
proto_item *ti;
proto_tree *t;
- char *str;
ti = proto_tree_add_item(tree, proto_x11, tvb, 0,
tvb_reported_length_remaining(tvb, offset),
t = proto_item_add_subtree(ti, ett_x11);
+ /*
+ * XXX - this doesn't work correctly if either
+ *
+ * 1) the request sequence number wraps in the lower 16
+ * bits;
+ *
+ * 2) we don't see the initial connection request and the
+ * resynchronization of sequence number fails and thus
+ * don't have the right sequence numbers
+ *
+ * 3) we don't have all the packets in the capture and
+ * get out of sequence.
+ *
+ * We might, instead, want to assume that a reply is a reply to
+ * the most recent not-already-replied-to request in the same
+ * connection. That also might mismatch replies to requests if
+ * packets are lost, but there's nothing you can do to fix that.
+ */
+
+ sequence_number = VALUE16(tvb, offset + 2);
opcode = (int)g_hash_table_lookup(state->seqtable,
- (int *)VALUE16(tvb, offset + 2));
+ (int *)sequence_number);
- if (check_col(pinfo->cinfo, COL_INFO))
- col_append_fstr(pinfo->cinfo, COL_INFO, "%s %s",
- sep,
- /*
- * don't print opcode value since if it's
- * unknown, we didn't know to save the
- * request opcode.
- */
- val_to_str(opcode, opcode_vals, "<Unknown opcode %d>"));
+ if (state->iconn_frame == 0 && state->resync == FALSE) {
+
+ /*
+ * We don't see the initial connection request and no
+ * resynchronization has been performed yet (first reply),
+ * set the current sequence number to the one of the
+ * current reply (this is only performed once).
+ */
+ state->sequencenumber = sequence_number;
+ state->resync = TRUE;
+ }
+
+ if (opcode == UNKNOWN_OPCODE) {
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_fstr(pinfo->cinfo, COL_INFO,
+ "%s to unknown request", sep);
+ proto_item_append_text(ti, ", Reply to unknown request");
+ } else {
+ if (check_col(pinfo->cinfo, COL_INFO))
+ col_append_fstr(pinfo->cinfo, COL_INFO, "%s %s",
+ sep,
+ val_to_str(opcode, state->opcode_vals,
+ "<Unknown opcode %d>"));
+
+ proto_item_append_text(ti, ", Reply, opcode: %d (%s)",
+ opcode, val_to_str(opcode,
+ state->opcode_vals,
+ "<Unknown opcode %d>"));
+ }
+
+ switch (opcode) {
+
+ /*
+ * Replies that need special processing outside tree
+ */
+
+ case X_QueryExtension:
- str = g_strdup_printf(", Reply, opcode: %d (%s)",
- opcode, val_to_str(opcode, opcode_vals,
- "<Unknown opcode %d>"));
+ /*
+ * if extension is present and request is known:
+ * store opcode of extension in value_string of
+ * opcodes
+ */
+ if (!VALUE8(tvb, offset + 8)) {
+ /* not present */
+ break;
+ }
- proto_item_append_text(ti, str);
- g_free(str);
+ vals_p = g_hash_table_lookup(state->valtable,
+ (int *)sequence_number);
+ if (vals_p != NULL) {
+ major_opcode = VALUE8(tvb, offset + 9);
+ vals_p->value = major_opcode;
+ g_hash_table_remove(state->valtable,
+ (int *)sequence_number);
+ }
+ break;
+
+ default:
+ break;
+ }
if (tree == NULL)
return;
switch (opcode) {
/*
* Requests that expect a reply.
- */
+ */
case X_GetWindowAttributes:
+ REPLYCONTENTS_COMMON();
+ break;
+
case X_GetGeometry:
+ REPLY(reply);
+ CARD8(depth);
+ SEQUENCENUMBER_REPLY(sequencenumber);
+ REPLYLENGTH(replylength);
+ WINDOW(rootwindow);
+ INT16(x);
+ INT16(y);
+ CARD16(width);
+ CARD16(height);
+ CARD16(border_width);
+ UNUSED(10);
+ break;
+
case X_QueryTree:
+ REPLYCONTENTS_COMMON();
+ break;
+
case X_InternAtom:
+ REPLY(reply);
+ UNUSED(1);
+ SEQUENCENUMBER_REPLY(sequencenumber);
+ REPLYLENGTH(replylength);
+ ATOM(atom);
+ UNUSED(20);
+ break;
+
case X_GetAtomName:
REPLYCONTENTS_COMMON();
break;
break;
case X_ListProperties:
+ REPLY(reply);
+ UNUSED(1);
+ SEQUENCENUMBER_REPLY(sequencenumber);
+ REPLYLENGTH(replylength);
+ length = CARD16(property_number);
+ UNUSED(22);
+ LISTofATOM(properties, length*4);
+ break;
+
case X_GetSelectionOwner:
+ REPLY(reply);
+ UNUSED(1);
+ SEQUENCENUMBER_REPLY(sequencenumber);
+ REPLYLENGTH(replylength);
+ WINDOW(owner);
+ UNUSED(20);
+ break;
+
case X_GrabPointer:
case X_GrabKeyboard:
+ REPLY(reply);
+ ENUM8(grab_status);
+ SEQUENCENUMBER_REPLY(sequencenumber);
+ REPLYLENGTH(replylength);
+ UNUSED(24);
+ break;
+
case X_QueryPointer:
+ REPLY(reply);
+ BOOL(same_screen);
+ SEQUENCENUMBER_REPLY(sequencenumber);
+ REPLYLENGTH(replylength);
+ WINDOW(rootwindow);
+ WINDOW(childwindow);
+ INT16(root_x);
+ INT16(root_y);
+ INT16(win_x);
+ INT16(win_y);
+ SETofKEYBUTMASK(mask);
+ UNUSED(6);
+ break;
+
case X_GetMotionEvents:
- case X_TranslateCoords:
REPLYCONTENTS_COMMON();
break;
+ case X_TranslateCoords:
+ REPLY(reply);
+ BOOL(same_screen);
+ SEQUENCENUMBER_REPLY(sequencenumber);
+ REPLYLENGTH(replylength);
+ WINDOW(childwindow);
+ INT16(dst_x);
+ INT16(dst_y);
+ UNUSED(16);
+ break;
+
+ case X_GetInputFocus:
+ REPLY(reply);
+ ENUM8(revert_to);
+ SEQUENCENUMBER_REPLY(sequencenumber);
+ REPLYLENGTH(replylength);
+ WINDOW(focus);
+ UNUSED(20);
+ break;
+
case X_QueryKeymap:
+ REPLY(reply);
+ UNUSED(1);
+ SEQUENCENUMBER_REPLY(sequencenumber);
+ REPLYLENGTH(replylength);
+ LISTofCARD8(keys, 32);
+ break;
+
case X_QueryFont:
case X_QueryTextExtents:
case X_ListFonts:
case X_GetImage:
case X_ListInstalledColormaps:
+ REPLYCONTENTS_COMMON();
+ break;
+
case X_AllocColor:
+ REPLY(reply);
+ UNUSED(1);
+ SEQUENCENUMBER_REPLY(sequencenumber);
+ REPLYLENGTH(replylength);
+ CARD16(red);
+ CARD16(green);
+ CARD16(blue);
+ UNUSED(2);
+ CARD32(pixel);
+ UNUSED(12);
+ break;
+
case X_QueryColors:
+ REPLYCONTENTS_COMMON();
+ break;
+
case X_LookupColor:
+ REPLY(reply);
+ UNUSED(1);
+ SEQUENCENUMBER_REPLY(sequencenumber);
+ REPLYLENGTH(replylength);
+ CARD16(exact_red);
+ CARD16(exact_green);
+ CARD16(exact_blue);
+ CARD16(visual_red);
+ CARD16(visual_green);
+ CARD16(visual_blue);
+ UNUSED(12);
+ break;
+
case X_QueryBestSize:
+ REPLY(reply);
+ UNUSED(1);
+ SEQUENCENUMBER_REPLY(sequencenumber);
+ REPLYLENGTH(replylength);
+ CARD16(width);
+ CARD16(height);
+ UNUSED(20);
+ break;
+
case X_QueryExtension:
+ REPLY(reply);
+ UNUSED(1);
+ SEQUENCENUMBER_REPLY(sequencenumber);
+ REPLYLENGTH(replylength);
+ BOOL(present);
+ CARD8(major_opcode);
+ CARD8(first_event);
+ CARD8(first_error);
+ UNUSED(20);
+ break;
+
case X_ListExtensions:
REPLYCONTENTS_COMMON();
break;
case X_GetKeyboardMapping:
- state->first_keycode
- = state->request.GetKeyboardMapping.first_keycode,
+ state->first_keycode =
+ state->request.GetKeyboardMapping.first_keycode;
REPLY(reply);
- state->keysyms_per_keycode
- = FIELD8(keysyms_per_keycode);
+ state->keysyms_per_keycode =
+ FIELD8(keysyms_per_keycode);
SEQUENCENUMBER_REPLY(sequencenumber);
length = REPLYLENGTH(replylength);
UNUSED(24);
LISTofKEYSYM(keysyms, state->keycodemap,
- state->request.GetKeyboardMapping.first_keycode,
- length / state->keysyms_per_keycode,
- state->keysyms_per_keycode);
+ state->request.GetKeyboardMapping.first_keycode,
+ length / state->keysyms_per_keycode,
+ state->keysyms_per_keycode);
break;
case X_GetKeyboardControl:
+ REPLYCONTENTS_COMMON();
+ break;
+
case X_GetPointerControl:
+ REPLY(reply);
+ UNUSED(1);
+ SEQUENCENUMBER_REPLY(sequencenumber);
+ REPLYLENGTH(replylength);
+ CARD16(acceleration_numerator);
+ CARD16(acceleration_denominator);
+ CARD16(threshold);
+ UNUSED(18);
+ break;
+
case X_GetScreenSaver:
+ REPLY(reply);
+ UNUSED(1);
+ SEQUENCENUMBER_REPLY(sequencenumber);
+ REPLYLENGTH(replylength);
+ CARD16(timeout);
+ CARD16(interval);
+ ENUM8(prefer_blanking);
+ ENUM8(allow_exposures);
+ UNUSED(18);
+ break;
+
case X_ListHosts:
case X_SetPointerMapping:
case X_GetPointerMapping:
case X_GetModifierMapping:
REPLY(reply);
- state->keycodes_per_modifier
- = FIELD8(keycodes_per_modifier);
+ state->keycodes_per_modifier =
+ FIELD8(keycodes_per_modifier);
SEQUENCENUMBER_REPLY(sequencenumber);
REPLYLENGTH(replylength);
UNUSED(24);
LISTofKEYCODE(state->modifiermap, keycodes,
- state->keycodes_per_modifier);
+ state->keycodes_per_modifier);
break;
default:
UNDECODED(left);
}
+static void
+same_screen_focus(tvbuff_t *tvb, int *offsetp, proto_tree *t)
+{
+ proto_item *ti;
+ guint32 bitmask_value;
+ int bitmask_offset;
+ int bitmask_size;
+ proto_tree *bitmask_tree;
+
+ bitmask_value = VALUE8(tvb, *offsetp);
+ bitmask_offset = *offsetp;
+ bitmask_size = 1;
+
+ ti = proto_tree_add_uint(t, hf_x11_same_screen_focus_mask, tvb, *offsetp, 1,
+ bitmask_value);
+ bitmask_tree = proto_item_add_subtree(ti, ett_x11_same_screen_focus);
+ FLAG(same_screen_focus, focus);
+ FLAG(same_screen_focus, same_screen);
+
+ *offsetp += 1;
+}
+
static void
dissect_x11_event(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
const char *volatile sep, x11_conv_data_t *volatile state,
{
int offset = 0, *offsetp = &offset, left;
unsigned char eventcode;
- char *str;
proto_item *ti;
proto_tree *t;
"<Unknown eventcode %u>"));
++offset;
- str = g_strdup_printf(", Event, eventcode: %d (%s)",
+ proto_item_append_text(ti, ", Event, eventcode: %d (%s)",
eventcode, val_to_str(eventcode, eventcode_vals,
"<Unknown eventcode %u>"));
- proto_item_append_text(ti, str);
- g_free(str);
-
if (tree == NULL)
return;
case EnterNotify:
case LeaveNotify:
- CARD8(detail);
+ ENUM8(event_detail);
CARD16(event_sequencenumber);
EVENTCONTENTS_COMMON();
- CARD8(same_screen);
+ ENUM8(grab_mode);
+ same_screen_focus(tvb, offsetp, t);
break;
case FocusIn:
case FocusOut:
+ ENUM8(focus_detail);
+ CARD16(event_sequencenumber);
+ WINDOW(eventwindow);
+ ENUM8(focus_mode);
+ UNUSED(23);
+ break;
+
case KeymapNotify:
+ break;
+
case Expose:
+ UNUSED(1);
+ CARD16(event_sequencenumber);
+ WINDOW(eventwindow);
+ INT16(x);
+ INT16(y);
+ CARD16(width);
+ CARD16(height);
+ CARD16(count);
+ UNUSED(14);
+ break;
+
case GraphicsExpose:
+ UNUSED(1);
+ CARD16(event_sequencenumber);
+ DRAWABLE(drawable);
+ CARD16(x);
+ CARD16(y);
+ CARD16(width);
+ CARD16(height);
+ CARD16(minor_opcode);
+ CARD16(count);
+ CARD8(major_opcode);
+ UNUSED(11);
+ break;
+
case NoExpose:
+ UNUSED(1);
+ CARD16(event_sequencenumber);
+ DRAWABLE(drawable);
+ CARD16(minor_opcode);
+ CARD8(major_opcode);
+ UNUSED(21);
+ break;
+
case VisibilityNotify:
+ UNUSED(1);
+ CARD16(event_sequencenumber);
+ WINDOW(eventwindow);
+ ENUM8(visibility_state);
+ UNUSED(23);
+ break;
+
case CreateNotify:
+ UNUSED(1);
+ CARD16(event_sequencenumber);
+ WINDOW(parent);
+ WINDOW(eventwindow);
+ INT16(x);
+ INT16(y);
+ CARD16(width);
+ CARD16(height);
+ CARD16(border_width);
+ BOOL(override_redirect);
+ UNUSED(9);
+ break;
+
case DestroyNotify:
+ UNUSED(1);
+ CARD16(event_sequencenumber);
+ WINDOW(eventwindow);
+ WINDOW(window);
+ UNUSED(20);
+ break;
+
case UnmapNotify:
+ UNUSED(1);
+ CARD16(event_sequencenumber);
+ WINDOW(eventwindow);
+ WINDOW(window);
+ BOOL(from_configure);
+ UNUSED(19);
+ break;
+
case MapNotify:
+ UNUSED(1);
+ CARD16(event_sequencenumber);
+ WINDOW(eventwindow);
+ WINDOW(window);
+ BOOL(override_redirect);
+ UNUSED(19);
+ break;
+
case MapRequest:
+ UNUSED(1);
+ CARD16(event_sequencenumber);
+ WINDOW(parent);
+ WINDOW(eventwindow);
+ UNUSED(20);
+ break;
+
case ReparentNotify:
+ UNUSED(1);
+ CARD16(event_sequencenumber);
+ WINDOW(eventwindow);
+ WINDOW(window);
+ WINDOW(parent);
+ INT16(x);
+ INT16(y);
+ BOOL(override_redirect);
+ UNUSED(11);
+ break;
+
case ConfigureNotify:
+ UNUSED(1);
+ CARD16(event_sequencenumber);
+ WINDOW(eventwindow);
+ WINDOW(window);
+ WINDOW(above_sibling);
+ INT16(x);
+ INT16(y);
+ CARD16(width);
+ CARD16(height);
+ CARD16(border_width);
+ BOOL(override_redirect);
+ UNUSED(5);
+ break;
+
case ConfigureRequest:
+ break;
+
case GravityNotify:
+ UNUSED(1);
+ CARD16(event_sequencenumber);
+ WINDOW(eventwindow);
+ WINDOW(window);
+ INT16(x);
+ INT16(y);
+ UNUSED(16);
+ break;
+
case ResizeRequest:
+ UNUSED(1);
+ CARD16(event_sequencenumber);
+ WINDOW(eventwindow);
+ CARD16(width);
+ CARD16(height);
+ UNUSED(20);
+ break;
+
case CirculateNotify:
+ UNUSED(1);
+ CARD16(event_sequencenumber);
+ WINDOW(eventwindow);
+ WINDOW(window);
+ UNUSED(4);
+ ENUM8(place);
+ UNUSED(15);
+ break;
+
case CirculateRequest:
+ UNUSED(1);
+ CARD16(event_sequencenumber);
+ WINDOW(parent);
+ WINDOW(eventwindow);
+ UNUSED(4);
+ ENUM8(place);
+ UNUSED(15);
+ break;
+
case PropertyNotify:
+ UNUSED(1);
+ CARD16(event_sequencenumber);
+ WINDOW(eventwindow);
+ ATOM(atom);
+ TIMESTAMP(time);
+ ENUM8(property_state);
+ UNUSED(15);
+ break;
+
case SelectionClear:
+ UNUSED(1);
+ CARD16(event_sequencenumber);
+ TIMESTAMP(time);
+ WINDOW(owner);
+ ATOM(selection);
+ UNUSED(16);
+ break;
+
case SelectionRequest:
+ UNUSED(1);
+ CARD16(event_sequencenumber);
+ TIMESTAMP(time);
+ WINDOW(owner);
+ WINDOW(requestor);
+ ATOM(selection);
+ ATOM(target);
+ ATOM(property);
+ UNUSED(4);
+ break;
+
case SelectionNotify:
+ UNUSED(1);
+ CARD16(event_sequencenumber);
+ TIMESTAMP(time);
+ WINDOW(requestor);
+ ATOM(selection);
+ ATOM(target);
+ ATOM(property);
+ UNUSED(8);
+ break;
+
case ColormapNotify:
+ UNUSED(1);
+ CARD16(event_sequencenumber);
+ WINDOW(eventwindow);
+ COLORMAP(cmap);
+ BOOL(new);
+ ENUM8(colormap_state);
+ UNUSED(18);
+ break;
+
case ClientMessage:
+ CARD8(format);
+ CARD16(event_sequencenumber);
+ WINDOW(eventwindow);
+ ATOM(type);
+ LISTofBYTE(data, 20);
+ break;
+
case MappingNotify:
default:
break;
static void
dissect_x11_error(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
- const char *volatile sep, _U_ x11_conv_data_t *volatile state,
+ const char *volatile sep, x11_conv_data_t *volatile state _U_,
gboolean little_endian)
{
int offset = 0, *offsetp = &offset, left;
unsigned char errorcode, error;
proto_item *ti;
proto_tree *t;
- char *str;
-
ti = proto_tree_add_item(tree, proto_x11, tvb, 0, -1, FALSE);
t = proto_item_add_subtree(ti, ett_x11);
"<Unknown errocode %u>"));
++offset;
- str = g_strdup_printf(", Error, errorcode: %d (%s)",
+ proto_item_append_text(ti, ", Error, errorcode: %d (%s)",
errorcode, val_to_str(errorcode, errorcode_vals,
"<Unknown errorcode %u>"));
- proto_item_append_text(ti, str);
- g_free(str);
-
if (tree == NULL)
return;
/* Setup list of header fields */
static hf_register_info hf[] = {
-/*
- { &hf_x11_FIELDABBREV,
- { "FIELDNAME", "x11.FIELDABBREV",
- FIELDTYPE, FIELDBASE, FIELDCONVERT, BITMASK,
- "FIELDDESCR", HFILL }
- },
-*/
#include "x11-register-info.h"
};
&ett_x11_window_value_mask,
&ett_x11_configure_window_mask,
&ett_x11_keyboard_value_mask,
+ &ett_x11_same_screen_focus,
};
module_t *x11_module;