There aren't any up-to-date books that I know of. You really just have to read a bunch of specs and source code. Fortunately it isn't that complicated.
I'd say reading the source to gtk+/gdk/x11 (the X backend to GTK) and the source to your favorite couple of WMs would go a long way. The ICCCM and EMWH specs are essential.
A huge change in X programming since the old guides is that nobody likes to use many of the server-side facilities for drawing, fonts, printing, etc. anymore. So XDrawFoo functions, everything about fonts, XPrint, GCs, colormaps, all that is more or less obsolete. Drawing is generally done on the client side now with libraries such as Cairo or Skia.
The stuff about windows and pixmaps and the basic way X works in those old books would still be accurate though.
Some good general X advice if you're messing with a WM:
you need to respond to events rather than getting state. For example, always consider your size to be the last size you got a ConfigureNotify for; don't call XGetGeometry or something to get your size. Getting state has two problems: it kills performance (blocking for a round trip = performance death) and it introduces race conditions.
in a WM, you're dealing with other apps' windows, and they can be destroyed at any time, which will result in an error if you're touching that window. so any function you call on a window may fail.
never use CurrentTime, always use a real timestamp, or you'll create freaky race condition bugs that will drive you crazy
There are lots more tips I guess but those are three to get you started avoiding common mistakes ;-)