| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| #include "rfb/rfb.h" |
| #include "rfb/rfbregion.h" |
| |
| static void PrintPixelFormat(rfbPixelFormat *pf); |
| static rfbBool rfbSetClientColourMapBGR233(rfbClientPtr cl); |
| |
| rfbBool rfbEconomicTranslate = FALSE; |
| |
| |
| |
| |
| |
| static const rfbPixelFormat BGR233Format = { |
| 8, 8, 0, 1, 7, 7, 3, 0, 3, 6, 0, 0 |
| }; |
| |
| |
| |
| |
| |
| |
| #define PF_EQ(x,y) \ |
| ((x.bitsPerPixel == y.bitsPerPixel) && \ |
| (x.depth == y.depth) && \ |
| ((x.bigEndian == y.bigEndian) || (x.bitsPerPixel == 8)) && \ |
| (x.trueColour == y.trueColour) && \ |
| (!x.trueColour || ((x.redMax == y.redMax) && \ |
| (x.greenMax == y.greenMax) && \ |
| (x.blueMax == y.blueMax) && \ |
| (x.redShift == y.redShift) && \ |
| (x.greenShift == y.greenShift) && \ |
| (x.blueShift == y.blueShift)))) |
| |
| #define CONCAT2(a,b) a##b |
| #define CONCAT2E(a,b) CONCAT2(a,b) |
| #define CONCAT3(a,b,c) a##b##c |
| #define CONCAT3E(a,b,c) CONCAT3(a,b,c) |
| #define CONCAT4(a,b,c,d) a##b##c##d |
| #define CONCAT4E(a,b,c,d) CONCAT4(a,b,c,d) |
| |
| #undef OUT |
| #undef IN |
| |
| #define OUT 8 |
| #include "tableinitcmtemplate.c" |
| #include "tableinittctemplate.c" |
| #define IN 8 |
| #include "tabletranstemplate.c" |
| #undef IN |
| #define IN 16 |
| #include "tabletranstemplate.c" |
| #undef IN |
| #define IN 32 |
| #include "tabletranstemplate.c" |
| #undef IN |
| #undef OUT |
| |
| #define OUT 16 |
| #include "tableinitcmtemplate.c" |
| #include "tableinittctemplate.c" |
| #define IN 8 |
| #include "tabletranstemplate.c" |
| #undef IN |
| #define IN 16 |
| #include "tabletranstemplate.c" |
| #undef IN |
| #define IN 32 |
| #include "tabletranstemplate.c" |
| #undef IN |
| #undef OUT |
| |
| #define OUT 32 |
| #include "tableinitcmtemplate.c" |
| #include "tableinittctemplate.c" |
| #define IN 8 |
| #include "tabletranstemplate.c" |
| #undef IN |
| #define IN 16 |
| #include "tabletranstemplate.c" |
| #undef IN |
| #define IN 32 |
| #include "tabletranstemplate.c" |
| #undef IN |
| #undef OUT |
| |
| #define COUNT_OFFSETS 4 |
| #define BPP2OFFSET(bpp) ((bpp)/8-1) |
| #include "tableinit24.c" |
| #define BPP 8 |
| #include "tabletrans24template.c" |
| #undef BPP |
| #define BPP 16 |
| #include "tabletrans24template.c" |
| #undef BPP |
| #define BPP 24 |
| #include "tabletrans24template.c" |
| #undef BPP |
| #define BPP 32 |
| #include "tabletrans24template.c" |
| #undef BPP |
| |
| typedef void (*rfbInitCMTableFnType)(char **table, rfbPixelFormat *in, |
| rfbPixelFormat *out,rfbColourMap* cm); |
| typedef void (*rfbInitTableFnType)(char **table, rfbPixelFormat *in, |
| rfbPixelFormat *out); |
| |
| rfbInitCMTableFnType rfbInitColourMapSingleTableFns[COUNT_OFFSETS] = { |
| rfbInitColourMapSingleTable8, |
| rfbInitColourMapSingleTable16, |
| rfbInitColourMapSingleTable24, |
| rfbInitColourMapSingleTable32 |
| }; |
| |
| rfbInitTableFnType rfbInitTrueColourSingleTableFns[COUNT_OFFSETS] = { |
| rfbInitTrueColourSingleTable8, |
| rfbInitTrueColourSingleTable16, |
| rfbInitTrueColourSingleTable24, |
| rfbInitTrueColourSingleTable32 |
| }; |
| |
| rfbInitTableFnType rfbInitTrueColourRGBTablesFns[COUNT_OFFSETS] = { |
| rfbInitTrueColourRGBTables8, |
| rfbInitTrueColourRGBTables16, |
| rfbInitTrueColourRGBTables24, |
| rfbInitTrueColourRGBTables32 |
| }; |
| |
| rfbTranslateFnType rfbTranslateWithSingleTableFns[COUNT_OFFSETS][COUNT_OFFSETS] = { |
| { rfbTranslateWithSingleTable8to8, |
| rfbTranslateWithSingleTable8to16, |
| rfbTranslateWithSingleTable8to24, |
| rfbTranslateWithSingleTable8to32 }, |
| { rfbTranslateWithSingleTable16to8, |
| rfbTranslateWithSingleTable16to16, |
| rfbTranslateWithSingleTable16to24, |
| rfbTranslateWithSingleTable16to32 }, |
| { rfbTranslateWithSingleTable24to8, |
| rfbTranslateWithSingleTable24to16, |
| rfbTranslateWithSingleTable24to24, |
| rfbTranslateWithSingleTable24to32 }, |
| { rfbTranslateWithSingleTable32to8, |
| rfbTranslateWithSingleTable32to16, |
| rfbTranslateWithSingleTable32to24, |
| rfbTranslateWithSingleTable32to32 } |
| }; |
| |
| rfbTranslateFnType rfbTranslateWithRGBTablesFns[COUNT_OFFSETS][COUNT_OFFSETS] = { |
| { rfbTranslateWithRGBTables8to8, |
| rfbTranslateWithRGBTables8to16, |
| rfbTranslateWithRGBTables8to24, |
| rfbTranslateWithRGBTables8to32 }, |
| { rfbTranslateWithRGBTables16to8, |
| rfbTranslateWithRGBTables16to16, |
| rfbTranslateWithRGBTables16to24, |
| rfbTranslateWithRGBTables16to32 }, |
| { rfbTranslateWithRGBTables24to8, |
| rfbTranslateWithRGBTables24to16, |
| rfbTranslateWithRGBTables24to24, |
| rfbTranslateWithRGBTables24to32 }, |
| { rfbTranslateWithRGBTables32to8, |
| rfbTranslateWithRGBTables32to16, |
| rfbTranslateWithRGBTables32to24, |
| rfbTranslateWithRGBTables32to32 } |
| }; |
| |
| |
| |
| |
| |
| |
| |
| void |
| rfbTranslateNone(char *table, rfbPixelFormat *in, rfbPixelFormat *out, |
| char *iptr, char *optr, int bytesBetweenInputLines, |
| int width, int height) |
| { |
| int bytesPerOutputLine = width * (out->bitsPerPixel / 8); |
| |
| while (height > 0) { |
| memcpy(optr, iptr, bytesPerOutputLine); |
| iptr += bytesBetweenInputLines; |
| optr += bytesPerOutputLine; |
| height--; |
| } |
| } |
| |
| |
| |
| |
| |
| |
| rfbBool |
| rfbSetTranslateFunction(cl) |
| rfbClientPtr cl; |
| { |
| rfbLog("Pixel format for client %s:\n",cl->host); |
| PrintPixelFormat(&cl->format); |
| |
| |
| |
| |
| |
| if ((cl->screen->rfbServerFormat.bitsPerPixel != 8) && |
| (cl->screen->rfbServerFormat.bitsPerPixel != 16) && |
| (cl->screen->rfbServerFormat.bitsPerPixel != 24) && |
| (cl->screen->rfbServerFormat.bitsPerPixel != 32)) |
| { |
| rfbErr("%s: server bits per pixel not 8, 16 or 32 (is %d)\n", |
| "rfbSetTranslateFunction", |
| cl->screen->rfbServerFormat.bitsPerPixel); |
| rfbCloseClient(cl); |
| return FALSE; |
| } |
| |
| if ((cl->format.bitsPerPixel != 8) && |
| (cl->format.bitsPerPixel != 16) && |
| (cl->format.bitsPerPixel != 24) && |
| (cl->format.bitsPerPixel != 32)) |
| { |
| rfbErr("%s: client bits per pixel not 8, 16 or 32\n", |
| "rfbSetTranslateFunction"); |
| rfbCloseClient(cl); |
| return FALSE; |
| } |
| |
| if (!cl->format.trueColour && (cl->format.bitsPerPixel != 8)) { |
| rfbErr("rfbSetTranslateFunction: client has colour map " |
| "but %d-bit - can only cope with 8-bit colour maps\n", |
| cl->format.bitsPerPixel); |
| rfbCloseClient(cl); |
| return FALSE; |
| } |
| |
| |
| |
| |
| |
| if (!cl->format.trueColour) { |
| |
| |
| |
| |
| |
| |
| |
| if (!rfbSetClientColourMapBGR233(cl)) |
| return FALSE; |
| |
| cl->format = BGR233Format; |
| } |
| |
| |
| |
| if (PF_EQ(cl->format,cl->screen->rfbServerFormat)) { |
| |
| |
| |
| rfbLog("no translation needed\n"); |
| cl->translateFn = rfbTranslateNone; |
| return TRUE; |
| } |
| |
| if ((cl->screen->rfbServerFormat.bitsPerPixel < 16) || |
| ((!cl->screen->rfbServerFormat.trueColour || !rfbEconomicTranslate) && |
| (cl->screen->rfbServerFormat.bitsPerPixel == 16))) { |
| |
| |
| |
| cl->translateFn = rfbTranslateWithSingleTableFns |
| [BPP2OFFSET(cl->screen->rfbServerFormat.bitsPerPixel)] |
| [BPP2OFFSET(cl->format.bitsPerPixel)]; |
| |
| if(cl->screen->rfbServerFormat.trueColour) |
| (*rfbInitTrueColourSingleTableFns |
| [BPP2OFFSET(cl->format.bitsPerPixel)]) (&cl->translateLookupTable, |
| &(cl->screen->rfbServerFormat), &cl->format); |
| else |
| (*rfbInitColourMapSingleTableFns |
| [BPP2OFFSET(cl->format.bitsPerPixel)]) (&cl->translateLookupTable, |
| &(cl->screen->rfbServerFormat), &cl->format,&cl->screen->colourMap); |
| |
| } else { |
| |
| |
| |
| cl->translateFn = rfbTranslateWithRGBTablesFns |
| [BPP2OFFSET(cl->screen->rfbServerFormat.bitsPerPixel)] |
| [BPP2OFFSET(cl->format.bitsPerPixel)]; |
| |
| (*rfbInitTrueColourRGBTablesFns |
| [BPP2OFFSET(cl->format.bitsPerPixel)]) (&cl->translateLookupTable, |
| &(cl->screen->rfbServerFormat), &cl->format); |
| } |
| |
| return TRUE; |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| static rfbBool |
| rfbSetClientColourMapBGR233(cl) |
| rfbClientPtr cl; |
| { |
| char buf[sz_rfbSetColourMapEntriesMsg + 256 * 3 * 2]; |
| rfbSetColourMapEntriesMsg *scme = (rfbSetColourMapEntriesMsg *)buf; |
| uint16_t *rgb = (uint16_t *)(&buf[sz_rfbSetColourMapEntriesMsg]); |
| int i, len; |
| int r, g, b; |
| |
| if (cl->format.bitsPerPixel != 8 ) { |
| rfbErr("%s: client not 8 bits per pixel\n", |
| "rfbSetClientColourMapBGR233"); |
| rfbCloseClient(cl); |
| return FALSE; |
| } |
| |
| scme->type = rfbSetColourMapEntries; |
| |
| scme->firstColour = Swap16IfLE(0); |
| scme->nColours = Swap16IfLE(256); |
| |
| len = sz_rfbSetColourMapEntriesMsg; |
| |
| i = 0; |
| |
| for (b = 0; b < 4; b++) { |
| for (g = 0; g < 8; g++) { |
| for (r = 0; r < 8; r++) { |
| rgb[i++] = Swap16IfLE(r * 65535 / 7); |
| rgb[i++] = Swap16IfLE(g * 65535 / 7); |
| rgb[i++] = Swap16IfLE(b * 65535 / 3); |
| } |
| } |
| } |
| |
| len += 256 * 3 * 2; |
| |
| if (WriteExact(cl, buf, len) < 0) { |
| rfbLogPerror("rfbSetClientColourMapBGR233: write"); |
| rfbCloseClient(cl); |
| return FALSE; |
| } |
| return TRUE; |
| } |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| rfbBool |
| rfbSetClientColourMap(cl, firstColour, nColours) |
| rfbClientPtr cl; |
| int firstColour; |
| int nColours; |
| { |
| if (cl->screen->rfbServerFormat.trueColour || !cl->readyForSetColourMapEntries) { |
| return TRUE; |
| } |
| |
| if (nColours == 0) { |
| nColours = cl->screen->colourMap.count; |
| } |
| |
| if (cl->format.trueColour) { |
| (*rfbInitColourMapSingleTableFns |
| [BPP2OFFSET(cl->format.bitsPerPixel)]) (&cl->translateLookupTable, |
| &cl->screen->rfbServerFormat, &cl->format,&cl->screen->colourMap); |
| |
| sraRgnDestroy(cl->modifiedRegion); |
| cl->modifiedRegion = |
| sraRgnCreateRect(0,0,cl->screen->width,cl->screen->height); |
| |
| return TRUE; |
| } |
| |
| return rfbSendSetColourMapEntries(cl, firstColour, nColours); |
| } |
| |
| |
| |
| |
| |
| |
| void |
| rfbSetClientColourMaps(rfbScreen, firstColour, nColours) |
| rfbScreenInfoPtr rfbScreen; |
| int firstColour; |
| int nColours; |
| { |
| rfbClientIteratorPtr i; |
| rfbClientPtr cl; |
| |
| i = rfbGetClientIterator(rfbScreen); |
| while((cl = rfbClientIteratorNext(i))) |
| rfbSetClientColourMap(cl, firstColour, nColours); |
| rfbReleaseClientIterator(i); |
| } |
| |
| static void |
| PrintPixelFormat(pf) |
| rfbPixelFormat *pf; |
| { |
| if (pf->bitsPerPixel == 1) { |
| rfbLog(" 1 bpp, %s sig bit in each byte is leftmost on the screen.\n", |
| (pf->bigEndian ? "most" : "least")); |
| } else { |
| rfbLog(" %d bpp, depth %d%s\n",pf->bitsPerPixel,pf->depth, |
| ((pf->bitsPerPixel == 8) ? "" |
| : (pf->bigEndian ? ", big endian" : ", little endian"))); |
| if (pf->trueColour) { |
| rfbLog(" true colour: max r %d g %d b %d, shift r %d g %d b %d\n", |
| pf->redMax, pf->greenMax, pf->blueMax, |
| pf->redShift, pf->greenShift, pf->blueShift); |
| } else { |
| rfbLog(" uses a colour map (not true colour).\n"); |
| } |
| } |
| } |