#include #include #include #include #include #include #include #include #include #include #include Display *display; int screen; Window root, window; XEvent event; int RENDER; int fillRect(Picture dst, char* data) { unsigned int* req_i = (unsigned int*) data; unsigned short* req_s = (unsigned short*) data; unsigned char* req_b = (unsigned char*) data; /*Compiler's nightmare ;) */ req_b[0] = RENDER; req_b[1] = 26; //FillRectangles-Opcode req_s[1] = 9; //Request-length req_b[4] = 3; //Over req_i[2] = dst; req_s[6] = 0xffff; //green req_s[7] = 0xffff; //Red req_s[8] = 0; //Blue req_s[9] = 0xffff; //A req_s[10] = 100; req_s[11] = 100; req_s[12] = 20; req_s[13] = 20; req_s[14] = 120; req_s[15] = 120; req_s[16] = 10; req_s[17] = 10; return 36; } static void return_socket(void *closure) { } void testLoop(xcb_connection_t *con, char* buffer, Picture picture) { XRenderColor color_white = {.red=0xffff, .green=0xffff, .blue=0xffff, .alpha=0xffff}; int z; //The higher the iteration count, the sooner (more likely?) it happens for(z=0; z < 1000; z++) { /*Use a C based function*/ XRenderFillRectangle(display, PictOpOver, picture, &color_white, 0, 0, 1, 1); /*Grab the socket*/ int flags = 0; uint64_t sent; int ret = xcb_take_socket(con, &return_socket, &flags, 0, &sent); /*Produce self-generated protocol*/ int requests = 0; int written = 0; for(requests = 0; requests < 770; requests++) { //770 self-generated requests cause xcb to hang, 769 work perfectly. written += fillRect(picture, &buffer[written]); } /*Write self-generated protocol*/ struct iovec vect; vect.iov_base = buffer; vect.iov_len = written; xcb_writev(con, &vect, 1, requests); } } int main(int argc, char *argv[]) { /*Bosing initialization stuff*/ display=XOpenDisplay(NULL); int render_event_base, render_error_base; int render_present=XRenderQueryExtension(display, &render_event_base, &render_error_base); if (!render_present) { fprintf(stderr, "RENDER extension missing!\n"); abort(); } XRenderPictFormat *fmt=XRenderFindStandardFormat(display, PictStandardRGB24); screen=DefaultScreen(display); root=DefaultRootWindow(display); window = XCreateWindow(display, root, 0, 0, 640, 480, 0, DefaultDepth(display, screen), InputOutput, DefaultVisual(display, screen), 0, NULL); XRenderPictureAttributes pict_attr; pict_attr.poly_edge=PolyEdgeSmooth; pict_attr.poly_mode=PolyModeImprecise; Picture picture=XRenderCreatePicture(display, window, fmt, CPPolyEdge|CPPolyMode, &pict_attr); XSelectInput(display, window, KeyPressMask|KeyReleaseMask|ExposureMask |ButtonPressMask|StructureNotifyMask); /* now make the window visible */ XMapWindow(display, window); /*Fetch the RENDER extension's opcode*/ char renderName[] = RENDER_NAME; int x; XQueryExtension(display, renderName , &RENDER, &x, &x); xcb_connection_t* con = XGetXCBConnection(display); char* buffer = (char*) malloc(512000); while(1) { XNextEvent(display, &event); switch(event.type) { case Expose: { testLoop(con, buffer, picture); break; case DestroyNotify: return 0; } } } return 0; }