home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 8 Other / 08-Other.zip / pmvnc100.zip / rect32.c < prev    next >
C/C++ Source or Header  |  1999-09-10  |  17KB  |  609 lines

  1. /*
  2.  * rect32.c - PM VNC Viewer, Pixel Handling for 32 bit true color
  3.  */
  4.  
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7.  
  8. #define INCL_PM
  9. #include <os2.h>
  10.  
  11. #include "pmvncdef.h"
  12.  
  13. /*
  14.  * rbuff is used to parse CoRRE, it requires buffer of
  15.  * 255 * 255 * 32 bits (nearly 64KB * 4).
  16.  */
  17.  
  18. #define RBUFSIZ     (1024 * 256)
  19.  
  20. static  PUCHAR  rbuff = NULL ;          /* as recv buffer   */
  21.  
  22. /*
  23.  * buffer for bitmap scan conversion
  24.  */
  25.  
  26. #define MAXSCAN     (4096 * 8)
  27.  
  28. static  PUCHAR  ibuff = NULL ;          /* as scan buffer   */
  29.  
  30. /*
  31.  * minimum I/O unit min(MAXSCAN, RBUFSIZ)
  32.  */
  33.  
  34. #define MINBUF  MAXSCAN
  35.  
  36. /*
  37.  * Remote Frame Buffer
  38.  */
  39.  
  40. static  int     cxBitmap = 0 ;
  41. static  int     cyBitmap = 0 ;
  42.  
  43. static  HDC     hdcBitmap = NULLHANDLE ;
  44. static  HPS     hpsBitmap = NULLHANDLE ;
  45. static  HBITMAP hbmBitmap = NULLHANDLE ;
  46.  
  47. static  BITMAPINFO2     bmiBitmap ;
  48.  
  49. /*
  50.  * rectDone - finialize rectangle operation
  51.  */
  52.  
  53. static  void    rectDone(void)
  54. {
  55.     if (hbmBitmap != NULLHANDLE) {
  56.         GpiDeleteBitmap(hbmBitmap) ;
  57.     hbmBitmap = NULLHANDLE ;
  58.     }
  59.     if (hpsBitmap != NULLHANDLE) {
  60.         GpiDestroyPS(hpsBitmap) ;
  61.     hpsBitmap = NULLHANDLE ;
  62.     }
  63.     if (hdcBitmap != NULLHANDLE) {
  64.         DevCloseDC(hdcBitmap) ;
  65.     hdcBitmap = NULLHANDLE ;
  66.     }
  67.     if (rbuff != NULL) {
  68.         free(rbuff) ;
  69.     rbuff = NULL ;
  70.     }
  71.     if (ibuff != NULL) {
  72.         free(ibuff) ;
  73.     ibuff = NULL ;
  74.     }
  75. }
  76.  
  77. /*
  78.  * rectInit - create bitmap for Remote Frame Buffer
  79.  */
  80.  
  81. static  BOOL    rectInit(int cx, int cy)
  82. {
  83.     SIZEL   siz ;
  84.     POINTL  pt  ;
  85.     BITMAPINFOHEADER2   bmi ;
  86.     
  87.     /*
  88.      * prepare buffer for drawing
  89.      */
  90.      
  91.     rbuff = malloc(RBUFSIZ) ;
  92.     ibuff = malloc(MAXSCAN) ;
  93.     
  94.     if (rbuff == NULL || ibuff == NULL) {
  95.         rectDone() ;
  96.     return FALSE ;
  97.     }
  98.     
  99.     /*
  100.      * create bitmap for Remote Frame Buffer
  101.      */
  102.      
  103.     siz.cx = siz.cy = 0 ;
  104.     hdcBitmap = DevOpenDC(habNetwork, OD_MEMORY, "*", 0, NULL, NULLHANDLE) ;
  105.     hpsBitmap = GpiCreatePS(habNetwork, hdcBitmap, &siz,
  106.                     PU_PELS | GPIF_DEFAULT | GPIT_MICRO | GPIA_ASSOC) ;
  107.  
  108.     if (hdcBitmap == NULLHANDLE || hpsBitmap == NULLHANDLE) {
  109.         TRACE("rectInit - failed to create HDC/HPS\n") ;
  110.         rectDone() ;
  111.     return FALSE ;
  112.     }
  113.  
  114.     memset(&bmi, 0, sizeof(bmi)) ;
  115.     bmi.cbFix = sizeof(bmi) ;
  116.     bmi.cx = cxBitmap = cx ;
  117.     bmi.cy = cyBitmap = cy ;
  118.     bmi.cPlanes       = 1  ;
  119.     bmi.cBitCount     = 24 ;
  120.     bmi.ulCompression = 0  ;
  121.     bmi.cclrUsed      = 0  ;
  122.     bmi.cclrImportant = 0  ;   
  123.  
  124.     hbmBitmap = GpiCreateBitmap(hpsBitmap, &bmi, 0, NULL, NULL) ;
  125.  
  126.     if (hbmBitmap == NULLHANDLE) {
  127.         TRACE("rectInit - failed to create bitmap\n") ;
  128.     rectDone() ;
  129.     return FALSE ;
  130.     }
  131.     
  132.     GpiSetBitmap(hpsBitmap, hbmBitmap) ;
  133.  
  134.     if (GpiCreateLogColorTable(hpsBitmap, 0, LCOLF_RGB, 0, 0, NULL) != TRUE) {
  135.         TRACE("rectInit - failed to set color mode RGB\n") ;
  136.     rectDone() ;
  137.         return FALSE ;
  138.     }
  139.     
  140.     /*
  141.      * put initial message on it
  142.      */
  143.      
  144.     pt.x = 32 ;
  145.     pt.y = cyBitmap - 64 ;
  146.     GpiErase(hpsBitmap) ;
  147.     GpiCharStringAt(hpsBitmap, &pt, strlen(VncGreeting), VncGreeting) ;
  148.     
  149.     /*
  150.      * prepare bitmap info. header for later operation
  151.      */
  152.  
  153.     memset(&bmiBitmap, 0, sizeof(BITMAPINFO2)) ;
  154.     bmiBitmap.cbFix     = 16 ;
  155.     bmiBitmap.cPlanes   =  1 ;
  156.     bmiBitmap.cBitCount = 24 ;
  157.     
  158.     return TRUE ;
  159. }
  160.  
  161. /*
  162.  * rectDraw - draw bitmap to targte PS
  163.  */
  164.  
  165. static  BOOL    rectDraw(HPS hps, PPOINTL apt)
  166. {
  167.     if (hpsBitmap == NULLHANDLE) {
  168.         return FALSE ;
  169.     }
  170.     GpiBitBlt(hps, hpsBitmap, 4, apt, ROP_SRCCOPY, BBO_IGNORE) ;
  171.     return TRUE ;
  172. }
  173.  
  174. /*
  175.  * rectRaw - raw rectangle encoding
  176.  *      read RawRect data from Server and convert to PM Bitmap
  177.  */
  178.  
  179. static  void    rawConv(rfbRectangle *r, int lines, PUCHAR buff)
  180. {
  181.     PUCHAR  sp, dp ;
  182.     int     i, j   ;
  183.     int     bytesPerLine ;
  184.     POINTL  apt[4] ;
  185.     
  186.     /*
  187.      * convert to PM bitmap, reverse vertical order and align to ULONG
  188.      */
  189.      
  190.     bytesPerLine = ((r->w * 3) + 3) & ~0x03 ;
  191.     
  192.     for (i = 0, sp = buff ; i < lines ; i++) {
  193.     dp = &ibuff[bytesPerLine * (lines - i - 1)] ;
  194.     for (j = 0 ; j < r->w ; j++) {
  195.         dp[0] = sp[0] ;     /* Blue     */
  196.         dp[1] = sp[1] ;     /* Green    */
  197.         dp[2] = sp[2] ;     /* Red      */
  198.         sp += 4 ;
  199.         dp += 3 ;
  200.         }
  201.     }
  202.  
  203.     bmiBitmap.cx = r->w  ;
  204.     bmiBitmap.cy = lines ;
  205.     
  206.     apt[0].x = r->x ;
  207.     apt[0].y = (cyBitmap - r->y - lines) ;
  208.     apt[1].x = apt[0].x + r->w  - 1 ;
  209.     apt[1].y = apt[0].y + lines - 1 ;
  210.     apt[2].x = 0 ;
  211.     apt[2].y = 0 ;
  212.     apt[3].x = r->w  ;
  213.     apt[3].y = lines ;
  214.  
  215.     GpiDrawBits(hpsBitmap, ibuff, &bmiBitmap, 4, apt, ROP_SRCCOPY, 0) ;
  216. }
  217.  
  218. static  BOOL    rectRaw(rfbRectangle *r)
  219. {
  220.     int     bytesPerLine, linesToRead ;
  221.     
  222.     bytesPerLine  = r->w * 4 ;      /* for 32 bits depth specific   */
  223.     linesToRead   = MINBUF / bytesPerLine ;
  224.     
  225.     if (linesToRead == 0) {
  226.         netFail("rectRaw - scanline too large, recompile!!") ;
  227.     return FALSE ;
  228.     }
  229.  
  230.     while (r->h > 0) {
  231.         if (linesToRead > r->h) {
  232.             linesToRead = r->h ;
  233.         }
  234.         if (netRecv(rbuff, bytesPerLine * linesToRead) != TRUE) {
  235.         netFail("failed to recv Raw Scanline") ;
  236.         return FALSE ;
  237.     }
  238.         rawConv(r, linesToRead, rbuff) ;
  239.     r->h -= linesToRead ;
  240.     r->y += linesToRead ;
  241.     }
  242.     return TRUE ;
  243. }
  244.  
  245. /*
  246.  * rectCopy - copy rect encoding
  247.  */
  248.  
  249. static  BOOL    rectCopy(rfbRectangle *r)
  250. {
  251.     rfbCopyRect cr  ;
  252.     POINTL  apt[3]  ;
  253.     
  254.     if (netRecv((PUCHAR) &cr, sz_rfbCopyRect) != TRUE) {
  255.         netFail("failed to recv CopyRect") ;
  256.     return FALSE ;
  257.     }
  258.     cr.srcX = swap16(cr.srcX) ;
  259.     cr.srcY = swap16(cr.srcY) ;
  260.     
  261.     apt[0].x = r->x                      ;
  262.     apt[0].y = cyBitmap - r->y - r->h    ;
  263.     apt[1].x = r->x + r->w               ;
  264.     apt[1].y = cyBitmap - r->y           ;
  265.     apt[2].x = cr.srcX                   ;
  266.     apt[2].y = cyBitmap - cr.srcY - r->h ;
  267.     
  268.     GpiBitBlt(hpsBitmap, hpsBitmap, 3, apt, ROP_SRCCOPY, 0) ;
  269.     
  270.     return TRUE ;
  271. }
  272.  
  273. /*
  274.  * Fill Rectangle with Solid Color
  275.  */
  276.  
  277. #define     fillRect(mx, my, mw, mh, color)         \
  278. {                                                   \
  279.     POLYGON pg ;                                    \
  280.     POINTL  apt[4] ;                                \
  281.     GpiSetColor(hpsBitmap, (LONG) (color)) ;        \
  282.     if ((mw) == 1 && (mh) == 1) {                   \
  283.         apt[0].x = (mx)                   ;         \
  284.         apt[0].y = cyBitmap - (my) - (mh) ;         \
  285.         GpiSetPel(hpsBitmap, &apt[0])     ;         \
  286.     } else if ((mw) == 1) {                         \
  287.         apt[0].x = (mx)                   ;         \
  288.         apt[0].y = cyBitmap - (my) - (mh) ;         \
  289.         apt[1].x = (mx)                   ;         \
  290.         apt[1].y = cyBitmap - (my) - 1    ;         \
  291.         GpiMove(hpsBitmap, &apt[0])       ;         \
  292.     GpiLine(hpsBitmap, &apt[1])       ;         \
  293.     } else {                                        \
  294.         pg.ulPoints = 4  ;                              \
  295.     pg.aPointl = apt ;                              \
  296.         apt[2].x = apt[3].x = (mx)                   ;  \
  297.     apt[0].x = apt[1].x = (mx) + (mw) - 1        ;  \
  298.     apt[0].y = apt[3].y = cyBitmap - (my) - (mh) ;  \
  299.     apt[1].y = apt[2].y = cyBitmap - (my) - 1    ;  \
  300.         GpiMove(hpsBitmap, &apt[3])          ;          \
  301.         GpiPolygons(hpsBitmap, 1, &pg, 0, 0) ;          \
  302.     }                                                   \
  303. }
  304.  
  305. /*
  306.  * rectRRE - RRE encoding
  307.  */
  308.  
  309. static  BOOL    rectRRE(rfbRectangle *r)
  310. {
  311.     rfbRREHeader    hdr ;
  312.     rfbRectangle    subrect ;
  313.     CARD32  color    ;
  314.     int     i        ;
  315.     
  316.     if (netRecv((PUCHAR) &hdr, sz_rfbRREHeader) != TRUE) {
  317.         netFail("failed to recv RREHeader") ;
  318.     return FALSE ;
  319.     }
  320.     hdr.nSubrects = swap32(hdr.nSubrects) ;
  321.  
  322.     if (netRecv((PUCHAR) &color, sizeof(CARD32)) != TRUE) {
  323.         netFail("failed to recv BG color") ;
  324.     return FALSE ;
  325.     }
  326.  
  327.     color &= 0x00ffffff ;
  328.     fillRect(r->x, r->y, r->w, r->h, color) ;
  329.  
  330.     for (i = 0 ; i < hdr.nSubrects ; i++) {
  331.         if (netRecv((PUCHAR) &color, sizeof(CARD32)) != TRUE) {
  332.         netFail("failed to recv sub color") ;
  333.         return FALSE ;
  334.     }
  335.     if (netRecv((PUCHAR) &subrect, sz_rfbRectangle) != TRUE) {
  336.         netFail("failed to recv subrect") ;
  337.         return FALSE ;
  338.     }
  339.     subrect.x = r->x + swap16(subrect.x) ;
  340.     subrect.y = r->y + swap16(subrect.y) ;
  341.     subrect.w = swap16(subrect.w) ;
  342.     subrect.h = swap16(subrect.h) ;
  343.  
  344.         color &= 0x00ffffff ;
  345.         fillRect(subrect.x, subrect.y, subrect.w, subrect.h, color) ;
  346.     }
  347.     return TRUE ;
  348. }
  349.  
  350. /*
  351.  * rectCoRRE - CoRRE encoding
  352.  */
  353.  
  354. static  BOOL    rectCoRRE(rfbRectangle *r)
  355. {
  356.     rfbRREHeader    hdr ;
  357.     rfbRectangle    subrect ;
  358.     PUCHAR  sp       ;
  359.     CARD32  color    ;
  360.     int     i        ;
  361.  
  362.     if (netRecv((PUCHAR) &hdr, sz_rfbRREHeader) != TRUE) {
  363.         netFail("failed to recv RREHeader") ;
  364.     return FALSE ;
  365.     }
  366.     hdr.nSubrects = swap32(hdr.nSubrects) ;
  367.  
  368.     if (netRecv((PUCHAR) &color, sizeof(CARD32)) != TRUE) {
  369.         netFail("failed to recv BG color") ;
  370.     return FALSE ;
  371.     }
  372.  
  373.     color &= 0x00ffffff ;
  374.     fillRect(r->x, r->y, r->w, r->h, color) ;
  375.  
  376.     if (netRecv(rbuff, hdr.nSubrects * 8) != TRUE) {
  377.         netFail("failed to recv subrects") ;
  378.     return FALSE ;
  379.     }
  380.  
  381.     for (i = 0, sp = rbuff ; i < hdr.nSubrects ; i++, sp += 8) {
  382.         color = *(CARD32 *) sp ;
  383.     subrect.x = r->x + sp[4] ;
  384.     subrect.y = r->y + sp[5] ;
  385.     subrect.w = sp[6] ;
  386.     subrect.h = sp[7] ;
  387.  
  388.         color &= 0x00ffffff ;
  389.         fillRect(subrect.x, subrect.y, subrect.w, subrect.h, color) ;
  390.     }
  391.     return TRUE ;
  392. }
  393.  
  394. /*
  395.  * rectTile - Hextile encoding
  396.  */
  397.  
  398. static  CARD32  tileFg = 0xffffffff ;
  399. static  CARD32  tileBg = 0x00000000 ;
  400.  
  401. static  PUCHAR  tileScan[16] ;
  402. static  POINTL  tileBlit[4]  ;
  403.  
  404. static  void    hextileInit(int x, int y, int w, int h, CARD32 bg)
  405. {
  406.     int     i, j, bytesPerLine ;
  407.     PUCHAR  p, cp ;
  408.     
  409.     /*
  410.      * fill tile with background color
  411.      */
  412.      
  413.     bytesPerLine = ((w * 3) + 3) & ~0x03 ;
  414.     cp = (PUCHAR) &bg ;
  415.  
  416.     for (i = 0 ; i < h  ; i++) {
  417.         tileScan[i] = p = &ibuff[bytesPerLine * (h - i - 1)] ;
  418.     for (j = 0 ; j < w ; j++) {
  419.         p[0] = cp[0] ;
  420.         p[1] = cp[1] ;
  421.         p[2] = cp[2] ;
  422.         p += 3 ;
  423.     }
  424.     }
  425.  
  426.     /*
  427.      * prepare for final bitblt
  428.      */
  429.      
  430.     bmiBitmap.cx = w ;
  431.     bmiBitmap.cy = h ;
  432.  
  433.     tileBlit[0].x = x ;
  434.     tileBlit[0].y = (cyBitmap - y - h) ;
  435.     tileBlit[1].x = tileBlit[0].x + w  - 1 ;
  436.     tileBlit[1].y = tileBlit[0].y + h - 1 ;
  437.     tileBlit[2].x = 0 ;
  438.     tileBlit[2].y = 0 ;
  439.     tileBlit[3].x = w ;
  440.     tileBlit[3].y = h ;
  441. }
  442.  
  443. #define hextileDraw()   \
  444.     GpiDrawBits(hpsBitmap, ibuff, &bmiBitmap, 4, tileBlit, ROP_SRCCOPY, 0)
  445.  
  446. #define hextileFill(x, y, w, h, color)      \
  447. {                                           \
  448.     int     i, j ;                          \
  449.     ULONG   lcolor = (color) ;              \
  450.     PUCHAR  p, cp ;                         \
  451.     cp = (PUCHAR) &lcolor ;                 \
  452.     for (i = 0 ; i < (h) ; i++) {           \
  453.         p = tileScan[(y) + i] + ((x) * 3) ; \
  454.     for (j = 0 ; j < (w) ; j++) {       \
  455.         p[0] = cp[0] ;                  \
  456.         p[1] = cp[1] ;                  \
  457.         p[2] = cp[2] ;                  \
  458.         p += 3 ;                        \
  459.     }                                   \
  460.     }                                       \
  461. }
  462.  
  463. static  BOOL    rectTile(rfbRectangle *r)
  464. {
  465.     CARD8   subencoding, nSubrects ;
  466.     int     x, y, w, h ;
  467.     int     i, j, bytesPerLine ;
  468.     int     sn, sx, sy, sw, sh ;
  469.     PUCHAR  sp, dp ;
  470.     PULONG  cp     ;
  471.     POINTL  apt[4] ;
  472.     
  473.     for (y = r->y ; y < (r->y + r->h) ; y += 16) {
  474.         for (x = r->x ; x < (r->x + r->w) ; x += 16) {
  475.             w = h = 16 ;
  476.         if ((r->x + r->w - x) < 16) {
  477.             w = r->x + r->w - x ;
  478.         }
  479.         if ((r->y + r->h - y) < 16) {
  480.             h = r->y + r->h - y ;
  481.         }
  482.         if (netRecv((PUCHAR) &subencoding, 1) != TRUE) {
  483.             netFail("failed to recv sub encoding") ;
  484.         return FALSE ;
  485.         }
  486.         if (subencoding & rfbHextileRaw) {
  487.  
  488.                 bytesPerLine = ((w * 3) + 3) & ~0x03 ;
  489.  
  490.                 if (netRecv(rbuff, w * h * 4) != TRUE) {
  491.                     netFail("failed to hextile raw") ;
  492.                     return FALSE ;
  493.                 }
  494.     
  495.                 for (i = 0, sp = rbuff ; i < h ; i++) {
  496.                     dp = &ibuff[bytesPerLine * (h - i - 1)] ;
  497.                     for (j = 0 ; j < w ; j++) {
  498.                         dp[0] = sp[0] ;
  499.                         dp[1] = sp[1] ;
  500.                         dp[2] = sp[2] ;
  501.                         sp += 4 ;
  502.                         dp += 3 ;
  503.                     }
  504.                 }
  505.  
  506.                 bmiBitmap.cx = w ;
  507.                 bmiBitmap.cy = h ;
  508.     
  509.                 apt[0].x = x ;
  510.                 apt[0].y = (cyBitmap - y - h) ;
  511.                 apt[1].x = apt[0].x + w  - 1 ;
  512.                 apt[1].y = apt[0].y + h - 1 ;
  513.                 apt[2].x = 0 ;
  514.                 apt[2].y = 0 ;
  515.                 apt[3].x = w ;
  516.                 apt[3].y = h ;
  517.  
  518.                 GpiDrawBits(hpsBitmap, ibuff, 
  519.                         &bmiBitmap, 4, apt, ROP_SRCCOPY, 0) ;
  520.         continue ;
  521.         }
  522.         if (subencoding & rfbHextileBackgroundSpecified) {
  523.             if (netRecv((PUCHAR) &tileBg, sizeof(CARD32)) != TRUE) {
  524.             netFail("failed to recv BG color") ;
  525.             return FALSE ;
  526.         }
  527.         tileBg &= 0x00ffffff ;
  528.         }
  529.         if (subencoding & rfbHextileForegroundSpecified) {
  530.             if (netRecv((PUCHAR) &tileFg, sizeof(CARD32)) != TRUE) {
  531.             netFail("failed to recv FG color") ;
  532.             return FALSE ;
  533.         }
  534.         tileFg &= 0x00ffffff ;
  535.         }
  536.         if ((subencoding & rfbHextileAnySubrects) == 0) {
  537.                 hextileInit(x, y, w, h, tileBg) ;
  538.         hextileDraw() ;
  539.             } else if (subencoding & rfbHextileSubrectsColoured) {
  540.         hextileInit(x, y, w, h, tileBg) ;                
  541.                 if (netRecv((PUCHAR) &nSubrects, 1) != TRUE) {
  542.                     netFail("failed to recv hextile nSubrects") ;
  543.                     return FALSE ;
  544.                 }
  545.                 if (netRecv((PUCHAR) rbuff, nSubrects * 6) != TRUE) {
  546.                     netFail("failed to recv hextile Subrects") ;
  547.                     return FALSE ;
  548.                 }
  549.  
  550.                 for (sn = 0, sp = rbuff ; sn < nSubrects ; sn++, sp += 6) {
  551.                     cp = (PULONG) sp ;
  552.                     sx = rfbHextileExtractX(sp[4]) ;
  553.                     sy = rfbHextileExtractY(sp[4]) ;
  554.                     sw = rfbHextileExtractW(sp[5]) ;
  555.                     sh = rfbHextileExtractH(sp[5]) ;
  556.             hextileFill(sx, sy, sw, sh, *cp) ;
  557.                 }    
  558.         hextileDraw() ;
  559.         } else {
  560.         hextileInit(x, y, w, h, tileBg) ;
  561.                 if (netRecv((PUCHAR) &nSubrects, 1) != TRUE) {
  562.                     netFail("failed to recv hextile nSubrects") ;
  563.                     return FALSE ;
  564.                 }
  565.                 if (netRecv((PUCHAR) rbuff, nSubrects * 2) != TRUE) {
  566.                     netFail("failed to recv hextile Subrects") ;
  567.                     return FALSE ;
  568.                 }
  569.  
  570.                 for (sn = 0, sp = rbuff ; sn < nSubrects ; sn++, sp += 2) {
  571.                     sx = rfbHextileExtractX(sp[0]) ;
  572.                     sy = rfbHextileExtractY(sp[0]) ;
  573.                     sw = rfbHextileExtractW(sp[1]) ;
  574.                     sh = rfbHextileExtractH(sp[1]) ;
  575.             hextileFill(sx, sy, sw, sh, tileFg) ;
  576.                 }    
  577.         hextileDraw() ;
  578.         }
  579.         }
  580.     }
  581.     return TRUE ;
  582. }
  583.  
  584. /*
  585.  * VncPix32 - Drawing Context for 32 bit true color
  586.  */
  587.  
  588. VNCREC      VncCtx32 = {
  589.     /* bitsPerPixel */  32,         /* Current pixel format will fit    */
  590.     /* depth        */  32,         /* to PM's RGB structure with no    */
  591.     /* bigEndian    */  0,          /* conversions.                     */
  592.     /* trueColour   */  1,          /* It reduces client side load.     */
  593.     /* redMax       */  0x00ff,     /* But for reduce network traffic,  */
  594.     /* greenMax     */  0x00ff,     /* 8 bits BGR233 will be nice.      */
  595.     /* blureMax     */  0x00ff,
  596.     /* redShift     */  16,
  597.     /* greenShift   */  8,
  598.     /* blueShift    */  0,
  599.     /* pad1, pad2   */  0, 0,
  600.     /* rectDone     */  rectDone,
  601.     /* rectInit     */  rectInit,
  602.     /* rectDraw     */  rectDraw,
  603.     /* rectRaw      */  rectRaw,
  604.     /* rectCopy     */  rectCopy,
  605.     /* rectRRE      */  rectRRE,
  606.     /* rectCoRRE    */  rectCoRRE,
  607.     /* rectTile     */  rectTile
  608. } ;
  609.