I am not a huge fan of threading when it can be avoided. I always thought that it was OK for GUI programs to be threaded. I just discovered that you can handle X events from a select loop.

    dis = XOpenDisplay(DISPLAY);
    fd = ConnectionNumber(dis);

    FD_SET(fd, &in_fds);

    select(fd+1, &in_fds, NULL, NULL, NULL);

    ...