示例#1
0
/***********************************************************************************************************************************
Compress data
***********************************************************************************************************************************/
static Buffer *
testCompress(IoFilter *compress, Buffer *decompressed, size_t inputSize, size_t outputSize)
{
    Buffer *compressed = bufNew(1024 * 1024);
    size_t inputTotal = 0;
    ioBufferSizeSet(outputSize);

    IoFilterGroup *filterGroup = ioFilterGroupNew();
    ioFilterGroupAdd(filterGroup, compress);
    IoWrite *write = ioBufferWriteNew(compressed);
    ioWriteFilterGroupSet(write, filterGroup);
    ioWriteOpen(write);

    // Compress input data
    while (inputTotal < bufSize(decompressed))
    {
        // Generate the input buffer based on input size.  This breaks the data up into chunks as it would be in a real scenario.
        Buffer *input = bufNewC(
            bufPtr(decompressed) + inputTotal,
            inputSize > bufSize(decompressed) - inputTotal ? bufSize(decompressed) - inputTotal : inputSize);

        ioWrite(write, input);

        inputTotal += bufUsed(input);
        bufFree(input);
    }

    ioWriteClose(write);
    memContextFree(((GzipCompress *)ioFilterDriver(compress))->memContext);

    return compressed;
}
示例#2
0
文件: io.c 项目: cmwshang/pgbackrest
/***********************************************************************************************************************************
Read all IO into a buffer
***********************************************************************************************************************************/
Buffer *
ioReadBuf(IoRead *read)
{
    FUNCTION_TEST_BEGIN();
        FUNCTION_TEST_PARAM(IO_READ, read);
    FUNCTION_TEST_END();

    ASSERT(read != NULL);

    Buffer *result = NULL;

    MEM_CONTEXT_TEMP_BEGIN()
    {
        // Read IO into the buffer
        result = bufNew(0);

        do
        {
            bufResize(result, bufSize(result) + ioBufferSize());
            ioRead(read, result);
        }
        while (!ioReadEof(read));

        // Resize the buffer and move to calling context
        bufResize(result, bufUsed(result));
        bufMove(result, MEM_CONTEXT_OLD());
    }
    MEM_CONTEXT_TEMP_END();

    FUNCTION_TEST_RETURN(result);
}
示例#3
0
// (sys 'any ['any]) -> sym
any doSys(any x) {
   any y;

   y = evSym(x = cdr(x));
   {
      char nm[bufSize(y)];

      bufString(y,nm);
      if (!isCell(x = cdr(x)))
         return mkStr(getenv(nm));
      y = evSym(x);
      {
         char val[bufSize(y)];

         bufString(y,val);
         return setenv(nm,val,1)? Nil : y;
      }
   }
}
// -----------------------------------------------------------------------------
// CCbsTopicMessages::GetMessageContentsL
// Returns the content of the message to the client.
// (other items were commented in a header).
// -----------------------------------------------------------------------------
//
void CCbsTopicMessages::GetMessageContentsL()
    {
    // Read the parameters from the client side.
    TPckgBuf< TCbsMessageHandle > pckgHandle( 0 );
    Message().ReadL( 0, pckgHandle );

    TInt bufSize( 0 );
    bufSize = Message().Int1();

    TCbsDbMessage message;
    iMessages.FindMessageByHandleL( pckgHandle(), message );
    
    if ( message.iLength != 0 )
        {
        // Message is not empty. 
        // First allocate memory and then get the contents.
        // Finally write data to client side.
        TInt size ( ( message.iLength < bufSize ) ? 
            message.iLength : bufSize );

        // guaranteed to allocate n bytes, n >= size
        HBufC* buffer = HBufC::NewLC( size );    // on CS

        TPtr16 pointer( buffer->Des() );
        pointer.Zero();

        // Note: parameter 'size' required, since MaxLength 
        // may be > bufSize
        iMessages.GetMessageContentsL( pckgHandle(), pointer, size );

#ifndef _DEBUG
        Message().WriteL( 2, pointer );
#else
        TRAPD( result, Message().WriteL( 2, pointer ) );
        if ( result != KErrNone )
            {
            RDebug::Print(_L("Server buffer length: %d, max: %d"), 
                pointer.Length(), pointer.MaxLength());
            __DEBUGGER();
            User::Leave( result );
            }
        
#endif
        CleanupStack::PopAndDestroy(); // buffer
        }

    // Complete the request.
    Message().Complete( KErrNone );
    }
示例#5
0
// (call 'any ..) -> flg
any doCall(any ex) {
   pid_t pid;
   any x, y;
   int res, i, ac = length(x = cdr(ex));
   char *av[ac+1];

   if (ac == 0)
      return Nil;
   av[0] = alloc(NULL, pathSize(y = evSym(x))),  pathString(y, av[0]);
   for (i = 1; isCell(x = cdr(x)); ++i)
      av[i] = alloc(NULL, bufSize(y = evSym(x))),  bufString(y, av[i]);
   av[ac] = NULL;
   flushAll();
   if ((pid = fork()) == 0) {
      setpgid(0,0);
      execvp(av[0], av);
      execError(av[0]);
   }
   i = 0;  do
      free(av[i]);
   while (++i < ac);
   if (pid < 0)
      err(ex, NULL, "fork");
   setpgid(pid,0);
   if (Termio)
      tcsetpgrp(0,pid);
   for (;;) {
      while (waitpid(pid, &res, WUNTRACED) < 0) {
         if (errno != EINTR)
            err(ex, NULL, "wait pid");
         if (*Signal)
            sighandler(ex);
      }
      if (Termio)
         tcsetpgrp(0,getpgrp());
      if (!WIFSTOPPED(res))
         return res == 0? T : Nil;
      load(NULL, '+', Nil);
      if (Termio)
         tcsetpgrp(0,pid);
      kill(pid, SIGCONT);
   }
}
示例#6
0
// (term-decode 'sym) -> num | Nil
any plisp_term_decode(any ex) {
  any x, y;
  unsigned i, total = sizeof(term_key_names) / sizeof(char*);

  x = cdr(ex), y = EVAL(car(x));
  NeedSymb(ex, y);
  char key[bufSize(y)];
  bufString(y, key);

  if (*key != 'K')
    return Nil;

  for (i = 0; i < total; i++)
    if (!strcmp(key, term_key_names[i]))
      break;

  if (i == total)
    return Nil;
  else
    return box(i + TERM_FIRST_KEY);
}
示例#7
0
// (tmr-decode 'sym) -> num
any tmr_decode(any ex) {
  char* pend;
  long res;
  any x, y;

  x = cdr(ex), y = EVAL(car(x));
  NeedSym(ex, y);
  char key[bufSize(y)];
  bufString(y, key);
  if (strlen(key) > MAX_VTIMER_NAME_LEN ||
      strlen(key) < MIN_VTIMER_NAME_LEN)
    return box(0);
  if (strncmp(key, "VIRT", 4))
    return box(0);
  res = strtol(key + 4, &pend, 10);
  if (*pend != '\0')
    return box(0);
  if (res >= VTMR_NUM_TIMERS)
    return box(0);

  return box(res + VTMR_FIRST_ID);
}
示例#8
0
/***********************************************************************************************************************************
Test Run
***********************************************************************************************************************************/
void
testRun(void)
{
    FUNCTION_HARNESS_VOID();

    // *****************************************************************************************************************************
    if (testBegin("gzipError"))
    {
        TEST_RESULT_INT(gzipError(Z_OK), Z_OK, "check ok");
        TEST_RESULT_INT(gzipError(Z_STREAM_END), Z_STREAM_END, "check stream end");
        TEST_ERROR(gzipError(Z_NEED_DICT), AssertError, "zlib threw error: [2] need dictionary");
        TEST_ERROR(gzipError(Z_ERRNO), AssertError, "zlib threw error: [-1] file error");
        TEST_ERROR(gzipError(Z_STREAM_ERROR), FormatError, "zlib threw error: [-2] stream error");
        TEST_ERROR(gzipError(Z_DATA_ERROR), FormatError, "zlib threw error: [-3] data error");
        TEST_ERROR(gzipError(Z_MEM_ERROR), MemoryError, "zlib threw error: [-4] insufficient memory");
        TEST_ERROR(gzipError(Z_BUF_ERROR), AssertError, "zlib threw error: [-5] no space in buffer");
        TEST_ERROR(gzipError(Z_VERSION_ERROR), FormatError, "zlib threw error: [-6] incompatible version");
        TEST_ERROR(gzipError(999), AssertError, "zlib threw error: [999] unknown error");
    }

    // *****************************************************************************************************************************
    if (testBegin("gzipWindowBits"))
    {

        TEST_RESULT_INT(gzipWindowBits(true), -15, "raw window bits");
        TEST_RESULT_INT(gzipWindowBits(false), 31, "gzip window bits");
    }

    // *****************************************************************************************************************************
    if (testBegin("GzipCompress and GzipDecompress"))
    {
        const char *simpleData = "A simple string";
        Buffer *compressed = NULL;
        Buffer *decompressed = bufNewC(simpleData, strlen(simpleData));

        TEST_ASSIGN(
            compressed, testCompress(gzipCompressNew(3, false), decompressed, 1024, 1024),
            "simple data - compress large in/large out buffer");

        TEST_RESULT_BOOL(
            bufEq(compressed, testCompress(gzipCompressNew(3, false), decompressed, 1024, 1)), true,
            "simple data - compress large in/small out buffer");

        TEST_RESULT_BOOL(
            bufEq(compressed, testCompress(gzipCompressNew(3, false), decompressed, 1, 1024)), true,
            "simple data - compress small in/large out buffer");

        TEST_RESULT_BOOL(
            bufEq(compressed, testCompress(gzipCompressNew(3, false), decompressed, 1, 1)), true,
            "simple data - compress small in/small out buffer");

        TEST_RESULT_BOOL(
            bufEq(decompressed, testDecompress(gzipDecompressNew(false), compressed, 1024, 1024)), true,
            "simple data - decompress large in/large out buffer");

        TEST_RESULT_BOOL(
            bufEq(decompressed, testDecompress(gzipDecompressNew(false), compressed, 1024, 1)), true,
            "simple data - decompress large in/small out buffer");

        TEST_RESULT_BOOL(
            bufEq(decompressed, testDecompress(gzipDecompressNew(false), compressed, 1, 1024)), true,
            "simple data - decompress small in/large out buffer");

        TEST_RESULT_BOOL(
            bufEq(decompressed, testDecompress(gzipDecompressNew(false), compressed, 1, 1)), true,
            "simple data - decompress small in/small out buffer");

        // Compress a large zero input buffer into small output buffer
        // -------------------------------------------------------------------------------------------------------------------------
        decompressed = bufNew(1024 * 1024 - 1);
        memset(bufPtr(decompressed), 0, bufSize(decompressed));
        bufUsedSet(decompressed, bufSize(decompressed));

        TEST_ASSIGN(
            compressed, testCompress(gzipCompressNew(3, true), decompressed, bufSize(decompressed), 1024),
            "zero data - compress large in/small out buffer");

        TEST_RESULT_BOOL(
            bufEq(decompressed, testDecompress(gzipDecompressNew(true), compressed, bufSize(compressed), 1024 * 256)), true,
            "zero data - decompress large in/small out buffer");
    }

    // *****************************************************************************************************************************
    if (testBegin("gzipDecompressToLog() and gzipCompressToLog()"))
    {
        GzipDecompress *decompress = (GzipDecompress *)ioFilterDriver(gzipDecompressNew(false));

        TEST_RESULT_STR(strPtr(gzipDecompressToLog(decompress)), "{inputSame: false, done: false, availIn: 0}", "format object");

        decompress->inputSame = true;
        decompress->done = true;
        TEST_RESULT_STR(strPtr(gzipDecompressToLog(decompress)), "{inputSame: true, done: true, availIn: 0}", "format object");
    }

    FUNCTION_HARNESS_RESULT_VOID();
}
示例#9
0
 size_t mask() const                    { return bufSize() - 1; }
示例#10
0
文件: lib.c 项目: CyberShadow/hax11
static void* x11connThreadWriteProc(void* dataPtr)
{
	X11ConnData* data = (X11ConnData*)dataPtr;

	unsigned char *buf = NULL;
	size_t bufLen = 0;

	{
		xConnSetupPrefix header;
		if (!recvAll(data->server, &header, sz_xConnSetupPrefix)) goto done;
		if (!sendAll(data->client, &header, sz_xConnSetupPrefix)) goto done;

		log_debug("Server connection setup reply: %d\n", header.success);

		size_t dataLength = header.length * 4;
		bufSize(&buf, &bufLen, dataLength);
		if (!recvAll(data->server, buf, dataLength)) goto done;
		if (!sendAll(data->client, buf, dataLength)) goto done;
	}

	bufSize(&buf, &bufLen, sz_xReply);
	while (!data->exiting)
	{
		if (!recvAll(data->server, buf, sz_xReply)) goto done;
		size_t ofs = sz_xReply;
		const xReply* reply = (xReply*)buf;

		if (reply->generic.type == X_Reply || reply->generic.type == GenericEvent)
		{
			size_t dataLength = reply->generic.length * 4;
			bufSize(&buf, &bufLen, ofs + dataLength);
			reply = (xReply*)buf; // in case bufSize moved buf
			if (!recvAll(data->server, buf+ofs, dataLength)) goto done;
			ofs += dataLength;
		}
		log_debug2(" [%d]Response: %d sequenceNumber=%d length=%d\n", data->index, reply->generic.type, reply->generic.sequenceNumber, ofs);

		if (reply->generic.type == X_Reply)
		{
			switch (data->notes[reply->generic.sequenceNumber])
			{
				case Note_X_GetGeometry:
				{
					xGetGeometryReply* reply = (xGetGeometryReply*)buf;
					log_debug2("  XGetGeometry(%d,%d,%d,%d)\n", reply->x, reply->y, reply->width, reply->height);
					fixCoords(&reply->x, &reply->y, &reply->width, &reply->height);
					log_debug2("  ->          (%d,%d,%d,%d)\n", reply->x, reply->y, reply->width, reply->height);
					break;
				}

				case Note_X_InternAtom_Other:
				{
					xInternAtomReply* reply = (xInternAtomReply*)buf;
					log_debug2("  X_InternAtom: atom=%d\n", reply->atom);
					break;
				}

				case Note_X_QueryExtension_XFree86_VidModeExtension:
				{
					xQueryExtensionReply* reply = (xQueryExtensionReply*)buf;
					log_debug2("  X_QueryExtension (XFree86-VidModeExtension): present=%d major_opcode=%d first_event=%d first_error=%d\n",
						reply->present, reply->major_opcode, reply->first_event, reply->first_error);
					if (reply->present)
						data->opcode_XFree86_VidModeExtension = reply->major_opcode;
					break;
				}

				case Note_X_QueryExtension_RANDR:
				{
					xQueryExtensionReply* reply = (xQueryExtensionReply*)buf;
					log_debug2("  X_QueryExtension (RANDR): present=%d major_opcode=%d first_event=%d first_error=%d\n",
						reply->present, reply->major_opcode, reply->first_event, reply->first_error);
					if (reply->present)
						data->opcode_RANDR = reply->major_opcode;
					break;
				}

				case Note_X_QueryExtension_Xinerama:
				{
					xQueryExtensionReply* reply = (xQueryExtensionReply*)buf;
					log_debug2("  X_QueryExtension (XINERAMA): present=%d major_opcode=%d first_event=%d first_error=%d\n",
						reply->present, reply->major_opcode, reply->first_event, reply->first_error);
					if (reply->present)
						data->opcode_Xinerama = reply->major_opcode;
					break;
				}

				case Note_X_QueryExtension_NV_GLX:
				{
					xQueryExtensionReply* reply = (xQueryExtensionReply*)buf;
					log_debug2("  X_QueryExtension (NV-GLX): present=%d major_opcode=%d first_event=%d first_error=%d\n",
						reply->present, reply->major_opcode, reply->first_event, reply->first_error);
					if (reply->present)
						data->opcode_NV_GLX = reply->major_opcode;
					break;
				}

				case Note_X_QueryExtension_Other:
				{
					xQueryExtensionReply* reply = (xQueryExtensionReply*)buf;
					log_debug2("  X_QueryExtension: present=%d major_opcode=%d first_event=%d first_error=%d\n",
						reply->present, reply->major_opcode, reply->first_event, reply->first_error);
					break;
				}

				case Note_X_XF86VidModeGetModeLine:
				{
					xXF86VidModeGetModeLineReply* reply = (xXF86VidModeGetModeLineReply*)buf;
					log_debug2("  X_XF86VidModeGetModeLine(%d x %d)\n", reply->hdisplay, reply->vdisplay);
					fixSize(&reply->hdisplay, &reply->vdisplay);
					log_debug2("  ->                      (%d x %d)\n", reply->hdisplay, reply->vdisplay);
					break;
				}

				case Note_X_XF86VidModeGetAllModeLines:
				{
					xXF86VidModeGetAllModeLinesReply* reply = (xXF86VidModeGetAllModeLinesReply*)buf;
					xXF86VidModeModeInfo* modeInfos = (xXF86VidModeModeInfo*)(buf + sz_xXF86VidModeGetAllModeLinesReply);
					for (size_t i=0; i<reply->modecount; i++)
					{
						xXF86VidModeModeInfo* modeInfo = modeInfos + i;
						log_debug2("  X_XF86VidModeGetAllModeLines[%d] = %d x %d\n", i, modeInfo->hdisplay, modeInfo->vdisplay);
						fixSize(&modeInfo->hdisplay, &modeInfo->vdisplay);
						log_debug2("  ->                                %d x %d\n",    modeInfo->hdisplay, modeInfo->vdisplay);
					}
					break;
				}

				case Note_X_RRGetScreenInfo:
				{
					xRRGetScreenInfoReply* reply = (xRRGetScreenInfoReply*)buf;
					xScreenSizes* sizes = (xScreenSizes*)(buf+sz_xRRGetScreenInfoReply);
					for (size_t i=0; i<reply->nSizes; i++)
					{
						xScreenSizes* size = sizes+i;
						log_debug2("  X_RRGetScreenInfo[%d] = %d x %d\n", i, size->widthInPixels, size->heightInPixels);
						fixSize(&size->widthInPixels, &size->heightInPixels);
						log_debug2("  ->                      %d x %d\n",    size->widthInPixels, size->heightInPixels);
					}
					break;
				}

				case Note_X_RRGetScreenResources:
				{
					xRRGetScreenResourcesReply* reply = (xRRGetScreenResourcesReply*)buf;
					void* ptr = buf+sz_xRRGetScreenResourcesReply;
					ptr += reply->nCrtcs * sizeof(CARD32);
					ptr += reply->nOutputs * sizeof(CARD32);
					for (size_t i=0; i<reply->nModes; i++)
					{
						xRRModeInfo* modeInfo = (xRRModeInfo*)ptr;
						log_debug2("  X_RRGetScreenResources[%d] = %d x %d\n", i, modeInfo->width, modeInfo->height);
						fixSize(&modeInfo->width, &modeInfo->height);
						log_debug2("  ->                           %d x %d\n",    modeInfo->width, modeInfo->height);
						ptr += sz_xRRModeInfo;
					}
					break;
				}

				case Note_X_RRGetCrtcInfo:
				{
					xRRGetCrtcInfoReply* reply = (xRRGetCrtcInfoReply*)buf;
					log_debug2("  X_RRGetCrtcInfo = %dx%d @ %dx%d\n", reply->width, reply->height, reply->x, reply->y);
					if (reply->mode != None)
					{
						fixMonitor(&reply->x, &reply->y, &reply->width, &reply->height);
						if (!reply->width || !reply->height)
						{
							reply->x = reply->y = reply->width = reply->height = 0;
							reply->mode = None;
							reply->rotation = reply->rotations = RR_Rotate_0;
							reply->nOutput = reply->nPossibleOutput = 0;
						}
					}
					log_debug2("  ->                %dx%d @ %dx%d\n", reply->width, reply->height, reply->x, reply->y);
					break;
				}

				case Note_X_XineramaQueryScreens:
				{
					xXineramaQueryScreensReply* reply = (xXineramaQueryScreensReply*)buf;
					xXineramaScreenInfo* screens = (xXineramaScreenInfo*)(buf+sz_XineramaQueryScreensReply);
					for (size_t i=0; i<reply->number; i++)
					{
						xXineramaScreenInfo* screen = screens+i;
						log_debug2("  X_XineramaQueryScreens[%d] = %dx%d @ %dx%d\n", i, screen->width, screen->height, screen->x_org, screen->y_org);
						fixCoords(&screen->x_org, &screen->y_org, &screen->width, &screen->height);
						log_debug2("  ->                           %dx%d @ %dx%d\n",    screen->width, screen->height, screen->x_org, screen->y_org);
					}
					break;
				}

				case Note_NV_GLX:
				{
#if 0
					char fn[256];
					static int counter = 0;
					sprintf(fn, "/tmp/hax11-NV-%d-rsp-%d", reply->generic.sequenceNumber, counter++);
					FILE* f = fopen(fn, "wb");
					fwrite(buf, 1, ofs, f);
					fclose(f);
#endif
					break;
				}
			}
		}

		if (config.debug >= 2 && config.actualX && config.actualY && memmem(buf, ofs, &config.actualX, 2) && memmem(buf, ofs, &config.actualY, 2))
			log_debug2("   Found actualW/H in output! ----------------------------------------------------------------------------------------------\n");

		if (!sendAll(data->client, buf, ofs)) goto done;
	}
done:
	log_debug("Exiting write thread.\n");
	data->exiting = 1;
	close(data->client);
	close(data->server);
	return NULL;
}
示例#11
0
文件: lib.c 项目: CyberShadow/hax11
static void* x11connThreadReadProc(void* dataPtr)
{
	X11ConnData* data = (X11ConnData*)dataPtr;
	unsigned char *buf = NULL;
	size_t bufLen = 0;
	bufSize(&buf, &bufLen, 1<<16);

	xConnClientPrefix header;
	if (!recvAll(data->client, &header, sizeof(header))) goto done;
	if (header.byteOrder != 'l')
	{
		log_debug("Unsupported byte order %c!\n", header.byteOrder);
		goto done;
	}
	if (!sendAll(data->server, &header, sz_xConnClientPrefix)) goto done;

	if (!recvAll(data->client, buf, pad(header.nbytesAuthProto))) goto done;
	if (!sendAll(data->server, buf, pad(header.nbytesAuthProto))) goto done;
	if (!recvAll(data->client, buf, pad(header.nbytesAuthString))) goto done;
	if (!sendAll(data->server, buf, pad(header.nbytesAuthString))) goto done;

	unsigned short sequenceNumber = 0;

	while (!data->exiting)
	{
		sequenceNumber++;

		size_t ofs = 0;
		if (!recvAll(data->client, buf+ofs, sz_xReq)) goto done;
		ofs += sz_xReq;

		const xReq* req = (xReq*)buf;
		uint requestLength = req->length * 4;
		if (requestLength == 0) // Big Requests Extension
		{
			recvAll(data->client, buf+ofs, 4);
			requestLength = *(uint*)(buf+ofs) * 4;
			ofs += 4;
		}
		log_debug2("[%d][%d] Request %d (%s) with data %d, length %d\n", data->index, sequenceNumber, req->reqType, requestNames[req->reqType], req->data, requestLength);
		bufSize(&buf, &bufLen, requestLength);
		req = (xReq*)buf; // in case bufSize moved buf

		if (!recvAll(data->client, buf+ofs, requestLength - ofs)) goto done;

		data->notes[sequenceNumber] = Note_None;
		switch (req->reqType)
		{
			// Fix for games that create the window of the wrong size or on the wrong monitor.
			case X_CreateWindow:
			{
				xCreateWindowReq* req = (xCreateWindowReq*)buf;
				log_debug2(" XCreateWindow(%dx%d @ %dx%d)\n", req->width, req->height, req->x, req->y);
				fixCoords(&req->x, &req->y, &req->width, &req->height);
				log_debug2(" ->           (%dx%d @ %dx%d)\n", req->width, req->height, req->x, req->y);
				break;
			}

			case X_ConfigureWindow:
			{
				xConfigureWindowReq* req = (xConfigureWindowReq*)buf;

				INT16 dummyXY = 0;
				CARD16 dummyW = config.mainW;
				CARD16 dummyH = config.mainH;
				INT16 *x = &dummyXY, *y = &dummyXY;
				CARD16 *w = &dummyW, *h = &dummyH;

				int* ptr = (int*)(buf + sz_xConfigureWindowReq);
				if (req->mask & 0x0001) // x
				{
					x = (INT16*)ptr;
					ptr++;
				}
				if (req->mask & 0x0002) // y
				{
					y = (INT16*)ptr;
					ptr++;
				}
				if (req->mask & 0x0004) // width
				{
					w = (CARD16*)ptr;
					ptr++;
				}
				if (req->mask & 0x0008) // height
				{
					h = (CARD16*)ptr;
					ptr++;
				}

				log_debug2(" XConfigureWindow(%dx%d @ %dx%d)\n", *w, *h, *x, *y);
				fixCoords(x, y, w, h);
				log_debug2(" ->              (%dx%d @ %dx%d)\n", *w, *h, *x, *y);
				break;
			}

			// Fix for games setting their window size based on the X root window size
			// (which can encompass multiple physical monitors).
			case X_GetGeometry:
			{
				data->notes[sequenceNumber] = Note_X_GetGeometry;
				break;
			}

			case X_InternAtom:
			{
				xInternAtomReq* req = (xInternAtomReq*)buf;
				const char* name = (const char*)(buf + sz_xInternAtomReq);
				log_debug2(" XInternAtom: %.*s\n", req->nbytes, name);
				data->notes[sequenceNumber] = Note_X_InternAtom_Other;
				break;
			}

			case X_ChangeProperty:
			{
				xChangePropertyReq* req = (xChangePropertyReq*)buf;
				log_debug2(" XChangeProperty: property=%d type=%d format=%d)\n", req->property, req->type, req->format);
				if (req->type == XA_WM_SIZE_HINTS)
				{
					XSizeHints* data = (XSizeHints*)(buf + sz_xChangePropertyReq);
					fixCoords((INT16*)&data->x, (INT16*)&data->y, (CARD16*)&data->width, (CARD16*)&data->height);
					fixSize((CARD16*)&data->max_width, (CARD16*)&data->max_height);
					fixSize((CARD16*)&data->base_width, (CARD16*)&data->base_height);
				}
				break;
			}

			case X_QueryExtension:
			{
				xQueryExtensionReq* req = (xQueryExtensionReq*)buf;
				const char* name = (const char*)(buf + sz_xQueryExtensionReq);
				log_debug2(" XQueryExtension(%.*s)\n", req->nbytes, name);

				if (!strmemcmp("XFree86-VidModeExtension", name, req->nbytes))
					data->notes[sequenceNumber] = Note_X_QueryExtension_XFree86_VidModeExtension;
				else
				if (!strmemcmp("RANDR", name, req->nbytes))
					data->notes[sequenceNumber] = Note_X_QueryExtension_RANDR;
				else
				if (!strmemcmp("XINERAMA", name, req->nbytes))
					data->notes[sequenceNumber] = Note_X_QueryExtension_Xinerama;
				else
				if (!strmemcmp("NV-GLX", name, req->nbytes))
					data->notes[sequenceNumber] = Note_X_QueryExtension_NV_GLX;
				else
					data->notes[sequenceNumber] = Note_X_QueryExtension_Other;
			}

			case 0:
				break;

			default:
			{
				if (req->reqType == data->opcode_XFree86_VidModeExtension)
				{
					xXF86VidModeGetModeLineReq* req = (xXF86VidModeGetModeLineReq*)buf;
					log_debug2(" XFree86_VidModeExtension - %d\n", req->xf86vidmodeReqType);
					switch (req->xf86vidmodeReqType)
					{
						case X_XF86VidModeGetModeLine:
							data->notes[sequenceNumber] = Note_X_XF86VidModeGetModeLine;
							break;
						case X_XF86VidModeGetAllModeLines:
							data->notes[sequenceNumber] = Note_X_XF86VidModeGetAllModeLines;
							break;
					}
				}
				else
				if (req->reqType == data->opcode_RANDR)
				{
					log_debug2(" RANDR - %d\n", req->data);
					switch (req->data)
					{
						case X_RRGetScreenInfo:
							data->notes[sequenceNumber] = Note_X_RRGetScreenInfo;
							break;
						case X_RRGetScreenResources:
							data->notes[sequenceNumber] = Note_X_RRGetScreenResources;
							break;
						case X_RRGetCrtcInfo:
							data->notes[sequenceNumber] = Note_X_RRGetCrtcInfo;
							break;
					}
				}
				else
				if (req->reqType == data->opcode_Xinerama)
				{
					log_debug2(" Xinerama - %d\n", req->data);
					switch (req->data)
					{
						case X_XineramaQueryScreens:
							data->notes[sequenceNumber] = Note_X_XineramaQueryScreens;
							break;
					}
				}
				else
				if (req->reqType == data->opcode_NV_GLX)
				{
#if 0
					char fn[256];
					sprintf(fn, "/tmp/hax11-NV-%d-req", sequenceNumber);
					FILE* f = fopen(fn, "wb");
					fwrite(buf, 1, requestLength, f);
					fclose(f);
#endif
					data->notes[sequenceNumber] = Note_NV_GLX;
				}
				break;
			}
		}

		if (config.debug >= 2 && config.actualX && config.actualY && memmem(buf, requestLength, &config.actualX, 2) && memmem(buf, requestLength, &config.actualY, 2))
			log_debug2("   Found actualW/H in input! ----------------------------------------------------------------------------------------------\n");

		if (!sendAll(data->server, buf, requestLength)) goto done;
	}
done:
	log_debug("Exiting read thread.\n");
	data->exiting = 1;
	close(data->client);
	close(data->server);
	return NULL;
}