bugfix to a bug reported by Ian Schorr:
[obnox/wireshark/wip.git] / packet-x11.c
index 5ca7139bd68ceea5e74ee526701c8ab592eef084..2e124d0a283e6d6270510e7772ac645f23301085 100644 (file)
@@ -3,7 +3,7 @@
  * 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.
  *
@@ -86,6 +87,9 @@
 #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
@@ -119,16 +123,20 @@ Mod1Mask, Mod2Mask, Mod3Mask, Mod4Mask, Mod5Mask };
 #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 {
@@ -167,14 +175,15 @@ static gint ett_x11_segment = -1;
 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;
@@ -367,18 +376,39 @@ static const value_string close_down_mode_vals[] = {
       { 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
@@ -404,6 +434,26 @@ static const value_string fill_style_vals[] = {
       { 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" },
@@ -430,6 +480,22 @@ static const value_string function_vals[] = {
       {  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" },
@@ -491,6 +557,25 @@ static const value_string on_off_vals[] = {
       { 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        
@@ -612,6 +697,8 @@ static const value_string on_off_vals[] = {
 #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" },
@@ -639,7 +726,7 @@ static const value_string opcode_vals[] = {
       { X_SetSelectionOwner,            "SetSelectionOwner" },
       { X_GetSelectionOwner,            "GetSelectionOwner" },
       { X_ConvertSelection,             "ConvertSelection" },
-      /* { X_SendEvent,                   "SendEvent" }, */
+      { X_SendEvent,                    "SendEvent" },
       { X_GrabPointer,                  "GrabPointer" },
       { X_UngrabPointer,                "UngrabPointer" },
       { X_GrabButton,                   "GrabButton" },
@@ -772,6 +859,8 @@ static const value_string opcode_vals[] = {
 #define ColormapNotify         32
 #define ClientMessage          33
 #define MappingNotify          34
+#define FirstExtensionEvent    64
+#define LastExtensionEvent     127
 
 static const value_string eventcode_vals[] = {
        { KeyPress,          "KeyPress" },
@@ -1018,7 +1107,7 @@ static const value_string zero_is_none_vals[] = {
 #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)
@@ -1058,6 +1147,7 @@ keysyms_per_keycode) {\
 #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); }
@@ -1094,7 +1184,7 @@ keysyms_per_keycode) {\
        *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) 
 
@@ -1148,22 +1238,22 @@ keysyms_per_keycode) {\
 
 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
@@ -1392,6 +1482,107 @@ static gint compareGuint32(gconstpointer a, gconstpointer b)
       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, 
@@ -1410,7 +1601,9 @@ keycode2keysymString(int *keycodemap[256], int first_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;
@@ -1428,6 +1621,7 @@ keycode2keysymString(int *keycodemap[256], int first_keycode,
                                        lockmod_is_shiftlock = kc;
                                        break;
                        }
+               }
 
 
        /*
@@ -1441,8 +1635,8 @@ keycode2keysymString(int *keycodemap[256], int first_keycode,
 
        /* 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;
@@ -1475,65 +1669,64 @@ keycode2keysymString(int *keycodemap[256], int first_keycode,
         */
 
        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);
@@ -1545,7 +1738,7 @@ keycode2keysymString(int *keycodemap[256], int first_keycode,
                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;
        }
@@ -1553,7 +1746,7 @@ keycode2keysymString(int *keycodemap[256], int first_keycode,
                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);
@@ -1600,14 +1793,17 @@ static void listOfKeycode(tvbuff_t *tvb, int *offsetp, proto_tree *t, int hf,
       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);
@@ -1616,9 +1812,8 @@ static void listOfKeycode(tvbuff_t *tvb, int *offsetp, proto_tree *t, int hf,
            }
 
            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);
       }
 }
 
@@ -1639,14 +1834,15 @@ static void listOfKeysyms(tvbuff_t *tvb, int *offsetp, proto_tree *t, int hf,
 
 
       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. */
@@ -1654,9 +1850,9 @@ static void listOfKeysyms(tvbuff_t *tvb, int *offsetp, proto_tree *t, int hf,
 
                  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;
@@ -2191,7 +2387,6 @@ static void setOfKeyButMask(tvbuff_t *tvb, int *offsetp, proto_tree *t,
       *offsetp += 2;
 }
 
-
 static void setOfPointerEvent(tvbuff_t *tvb, int *offsetp, proto_tree *t,
                              gboolean little_endian)
 {
@@ -2216,22 +2411,14 @@ static void setOfPointerEvent(tvbuff_t *tvb, int *offsetp, proto_tree *t,
 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;
 }
 
@@ -2707,16 +2894,17 @@ static void dissect_x11_initial_conn(tvbuff_t *tvb, packet_info *pinfo,
        */
       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;
 
@@ -2726,32 +2914,37 @@ static void dissect_x11_initial_reply(tvbuff_t *tvb, packet_info *pinfo,
 
        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);
@@ -2767,12 +2960,12 @@ static void dissect_x11_request(tvbuff_t *tvb, packet_info *pinfo,
       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;
 
@@ -2793,19 +2986,47 @@ static void dissect_x11_request(tvbuff_t *tvb, packet_info *pinfo,
 
       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:
@@ -2837,7 +3058,6 @@ static void dissect_x11_request(tvbuff_t *tvb, packet_info *pinfo,
       case X_LookupColor:
       case X_QueryBestSize:
       case X_QueryColors:
-      case X_QueryExtension:
       case X_QueryFont:
       case X_QueryKeymap:
       case X_QueryPointer:
@@ -2849,13 +3069,22 @@ static void dissect_x11_request(tvbuff_t *tvb, packet_info *pinfo,
                /*
                 * 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.
                 */
@@ -3026,6 +3255,14 @@ static void dissect_x11_request(tvbuff_t *tvb, packet_info *pinfo,
            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();
@@ -3849,8 +4086,16 @@ static void dissect_x11_requests(tvbuff_t *tvb, packet_info *pinfo,
       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?
             */
@@ -4116,16 +4361,27 @@ static void dissect_x11_requests(tvbuff_t *tvb, packet_info *pinfo,
 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);
@@ -4164,8 +4420,12 @@ dissect_x11_replies(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
         * 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.
@@ -4173,8 +4433,16 @@ dissect_x11_replies(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
        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?
                */
@@ -4198,53 +4466,61 @@ dissect_x11_replies(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree)
 
                /*
                 * 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;
        }
@@ -4258,9 +4534,10 @@ dissect_x11_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
                  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),
@@ -4268,25 +4545,90 @@ dissect_x11_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        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; 
@@ -4294,12 +4636,39 @@ dissect_x11_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
        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; 
@@ -4316,48 +4685,187 @@ dissect_x11_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
                        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:
@@ -4367,13 +4875,13 @@ dissect_x11_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
 
                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:
@@ -4384,6 +4892,28 @@ dissect_x11_reply(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
            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,
@@ -4391,7 +4921,6 @@ dissect_x11_event(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
 {
        int offset = 0, *offsetp = &offset, left;
        unsigned char eventcode;
-       char *str;
        proto_item *ti;
        proto_tree *t;
 
@@ -4413,13 +4942,10 @@ dissect_x11_event(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
                                   "<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; 
 
@@ -4459,37 +4985,245 @@ dissect_x11_event(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
 
                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;
@@ -4503,15 +5237,13 @@ dissect_x11_event(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
 
 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);
@@ -4532,13 +5264,10 @@ dissect_x11_error(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
                                   "<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; 
 
@@ -4586,13 +5315,6 @@ void proto_register_x11(void)
 
 /* 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"
       };
 
@@ -4626,6 +5348,7 @@ void proto_register_x11(void)
            &ett_x11_window_value_mask,
            &ett_x11_configure_window_mask,
            &ett_x11_keyboard_value_mask,
+           &ett_x11_same_screen_focus,
       };
       module_t *x11_module;