Tray icons can send "opcodes" to 
        the system tray. These are X client messages, sent with
        NoEventMask, a
        message_type of
        _NET_SYSTEM_TRAY_OPCODE, and format 32. 
        The first data field in the message is a timestamp (the stamp
        of the current event, if available, otherwise CurrentTime).
        The second data field is an integer indicating the op code 
        of the message:
         
#define SYSTEM_TRAY_REQUEST_DOCK    0
#define SYSTEM_TRAY_BEGIN_MESSAGE   1
#define SYSTEM_TRAY_CANCEL_MESSAGE  2
         The content remaining three data fields depends on the type of message being sent. If they are unused by a particular message, they should always be set to 0.
Here is an example of how to send a client message:
#include <X11/Xlib.h>
void send_message(
     Display* dpy, /* display */
     Window w,     /* sender (tray icon window) */
     long message, /* message opcode */
     long data1    /* message data 1 */
     long data2    /* message data 2 */
     long data3    /* message data 3 */
){
    XEvent ev;
  
    memset(&ev, 0, sizeof(ev));
    ev.xclient.type = ClientMessage;
    ev.xclient.window = w;
    ev.xclient.message_type = XInternAtom (dpy, "_NET_SYSTEM_TRAY_OPCODE", False );
    ev.xclient.format = 32;
    ev.xclient.data.l[0] = x_time;
    ev.xclient.data.l[1] = message;
    ev.xclient.data.l[2] = data1;
    ev.xclient.data.l[3] = data2;
    ev.xclient.data.l[4] = data3;
    trap_errors();
    XSendEvent(dpy, w, False, NoEventMask, &ev);
    XSync(dpy, False);
    if (untrap_errors()) {
	/* Handle failure */
    }
}