All XI2 events are cookie events
Retrieving an XI2 event needs to look like this:
if (XGetEventData(display, &event))
XGenericEventCookie *cookie = &event.xcookie;
if (cookie->extension == xi_opcode &&
cookie->evtype == XI_Motion)
The data pointer is always the extension-specific event, depending on evtype. More on that in the next XI2 recipes post. Failure to call XFreeEventData() will result in a memory leak.
XIFreeEventData is gone
Previous examples featured XIFreeEventData, this call is now replaced by XFreeEventData in Xlib. They both do the same thing, so you can just run sed over your source files.
Less pointers in events
The removal of the size restrictions means a few pointers in events have changed into structs - nothing a search/replace can't fix. One example for this is the button state which used to be a pointer - now it's part of the XIDeviceEvent struct.
No XIEvent padding
This isn't related to cookies but it's quite important: XIEvents may not be used for passing into XNextEvent. The previous struct included padding to force the same size as an XEvent. Except not on 64 bit, so it was broken anyway. The padding is removed, so you must not pass XIEvents into XNextEvent() and similar functions (unless you are a big fan of scrambled memory).