Bool HandleCursorShape(int xhot, int yhot, int width, int height, CARD32 enc) { int bytesPerPixel; size_t bytesPerRow, bytesMaskData; /* Drawable dr;*/ rfbXCursorColors rgb; CARD32 colors[2]; char *buf; CARD8 *ptr; int x, y, b; bytesPerPixel = myFormat.bitsPerPixel / 8; bytesPerRow = (width + 7) / 8; bytesMaskData = bytesPerRow * height; /* dr = DefaultRootWindow(dpy);*/ FreeSoftCursor(); if (width * height == 0) return True; /* Allocate memory for pixel data and temporary mask data. */ rcSource = malloc(width * height * bytesPerPixel); if (rcSource == NULL) return False; buf = malloc(bytesMaskData); if (buf == NULL) { free(rcSource); return False; } /* Read and decode cursor pixel data, depending on the encoding type. */ if (enc == rfbEncodingXCursor) { /* Read and convert background and foreground colors. */ if (!ReadFromRFBServer((char *)&rgb, sz_rfbXCursorColors)) { free(rcSource); free(buf); return False; } colors[0] = RGB24_TO_PIXEL(32, rgb.backRed, rgb.backGreen, rgb.backBlue); colors[1] = RGB24_TO_PIXEL(32, rgb.foreRed, rgb.foreGreen, rgb.foreBlue); /* Read 1bpp pixel data into a temporary buffer. */ if (!ReadFromRFBServer(buf, bytesMaskData)) { free(rcSource); free(buf); return False; } /* Convert 1bpp data to byte-wide color indices. */ ptr = rcSource; for (y = 0; y < height; y++) { for (x = 0; x < width / 8; x++) { for (b = 7; b >= 0; b--) { *ptr = buf[y * bytesPerRow + x] >> b & 1; ptr += bytesPerPixel; } } for (b = 7; b > 7 - width % 8; b--) { *ptr = buf[y * bytesPerRow + x] >> b & 1; ptr += bytesPerPixel; } } /* Convert indices into the actual pixel values. */ switch (bytesPerPixel) { case 1: for (x = 0; x < width * height; x++) rcSource[x] = (CARD8)colors[rcSource[x]]; break; case 2: for (x = 0; x < width * height; x++) ((CARD16 *)rcSource)[x] = (CARD16)colors[rcSource[x * 2]]; break; case 4: for (x = 0; x < width * height; x++) ((CARD32 *)rcSource)[x] = colors[rcSource[x * 4]]; break; } } else { /* enc == rfbEncodingRichCursor */ if (!ReadFromRFBServer((char *)rcSource, width * height * bytesPerPixel)) {
int DecompressJpegRect(int x, int y, int w, int h) { struct jpeg_decompress_struct cinfo; struct jpeg_error_mgr jerr; int compressedLen; CARD8 *compressedData; CARD16 *pixelPtr; JSAMPROW rowPointer[1]; int dx, dy; compressedLen = (int)ReadCompactLen(); if (compressedLen <= 0) { fprintf(stderr, "Incorrect data received from the server.\n"); return 0; } compressedData = malloc(compressedLen); if (compressedData == NULL) { fprintf(stderr, "Memory allocation error.\n"); return 0; } if (!read_from_rfb_server(sock, (char*)compressedData, compressedLen)) { free(compressedData); return 0; } cinfo.err = jpeg_std_error(&jerr); jpeg_create_decompress(&cinfo); JpegSetSrcManager(&cinfo, compressedData, compressedLen); jpeg_read_header(&cinfo, TRUE); cinfo.out_color_space = JCS_RGB; jpeg_start_decompress(&cinfo); if (cinfo.output_width != w || cinfo.output_height != h || cinfo.output_components != 3) { fprintf(stderr, "Tight Encoding: Wrong JPEG data received.\n"); jpeg_destroy_decompress(&cinfo); free(compressedData); return 0; } rowPointer[0] = (JSAMPROW)buffer; dy = 0; while (cinfo.output_scanline < cinfo.output_height) { jpeg_read_scanlines(&cinfo, rowPointer, 1); if (jpegError) { break; } /* FIXME 16 bpp hardcoded */ /* Fill the second half of our global buffer with the uncompressed data */ pixelPtr = (CARD16 *)&buffer[BUFFER_SIZE / 2]; for (dx = 0; dx < w; dx++) { *pixelPtr++ = RGB24_TO_PIXEL(16, buffer[dx*3], buffer[dx*3+1], buffer[dx*3+2]); } /* write scanline to screen */ dfb_write_data_to_screen(x, y + dy, w, 1, &buffer[BUFFER_SIZE/2]); dy++; } if (!jpegError) jpeg_finish_decompress(&cinfo); jpeg_destroy_decompress(&cinfo); free(compressedData); return !jpegError; }