Home | History | Annotate | Download | only in libvncclient
      1 /*
      2  *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
      3  *
      4  *  This is free software; you can redistribute it and/or modify
      5  *  it under the terms of the GNU General Public License as published by
      6  *  the Free Software Foundation; either version 2 of the License, or
      7  *  (at your option) any later version.
      8  *
      9  *  This software is distributed in the hope that it will be useful,
     10  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
     11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12  *  GNU General Public License for more details.
     13  *
     14  *  You should have received a copy of the GNU General Public License
     15  *  along with this software; if not, write to the Free Software
     16  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,
     17  *  USA.
     18  */
     19 
     20 /*
     21  * hextile.c - handle hextile encoding.
     22  *
     23  * This file shouldn't be compiled directly.  It is included multiple times by
     24  * rfbproto.c, each time with a different definition of the macro BPP.  For
     25  * each value of BPP, this file defines a function which handles a hextile
     26  * encoded rectangle with BPP bits per pixel.
     27  */
     28 
     29 #define HandleHextileBPP CONCAT2E(HandleHextile,BPP)
     30 #define CARDBPP CONCAT3E(uint,BPP,_t)
     31 
     32 static rfbBool
     33 HandleHextileBPP (rfbClient* client, int rx, int ry, int rw, int rh)
     34 {
     35   CARDBPP bg, fg;
     36   int i;
     37   uint8_t *ptr;
     38   int x, y, w, h;
     39   int sx, sy, sw, sh;
     40   uint8_t subencoding;
     41   uint8_t nSubrects;
     42 
     43   for (y = ry; y < ry+rh; y += 16) {
     44     for (x = rx; x < rx+rw; x += 16) {
     45       w = h = 16;
     46       if (rx+rw - x < 16)
     47 	w = rx+rw - x;
     48       if (ry+rh - y < 16)
     49 	h = ry+rh - y;
     50 
     51       if (!ReadFromRFBServer(client, (char *)&subencoding, 1))
     52 	return FALSE;
     53 
     54       if (subencoding & rfbHextileRaw) {
     55 	if (!ReadFromRFBServer(client, client->buffer, w * h * (BPP / 8)))
     56 	  return FALSE;
     57 
     58 	CopyRectangle(client, (uint8_t *)client->buffer, x, y, w, h);
     59 
     60 	continue;
     61       }
     62 
     63       if (subencoding & rfbHextileBackgroundSpecified)
     64 	if (!ReadFromRFBServer(client, (char *)&bg, sizeof(bg)))
     65 	  return FALSE;
     66 
     67       FillRectangle(client, x, y, w, h, bg);
     68 
     69       if (subencoding & rfbHextileForegroundSpecified)
     70 	if (!ReadFromRFBServer(client, (char *)&fg, sizeof(fg)))
     71 	  return FALSE;
     72 
     73       if (!(subencoding & rfbHextileAnySubrects)) {
     74 	continue;
     75       }
     76 
     77       if (!ReadFromRFBServer(client, (char *)&nSubrects, 1))
     78 	return FALSE;
     79 
     80       ptr = (uint8_t*)client->buffer;
     81 
     82       if (subencoding & rfbHextileSubrectsColoured) {
     83 	if (!ReadFromRFBServer(client, client->buffer, nSubrects * (2 + (BPP / 8))))
     84 	  return FALSE;
     85 
     86 	for (i = 0; i < nSubrects; i++) {
     87 #if BPP==8
     88 	  GET_PIXEL8(fg, ptr);
     89 #elif BPP==16
     90 	  GET_PIXEL16(fg, ptr);
     91 #elif BPP==32
     92 	  GET_PIXEL32(fg, ptr);
     93 #else
     94 #error "Invalid BPP"
     95 #endif
     96 	  sx = rfbHextileExtractX(*ptr);
     97 	  sy = rfbHextileExtractY(*ptr);
     98 	  ptr++;
     99 	  sw = rfbHextileExtractW(*ptr);
    100 	  sh = rfbHextileExtractH(*ptr);
    101 	  ptr++;
    102 
    103 	  FillRectangle(client, x+sx, y+sy, sw, sh, fg);
    104 	}
    105 
    106       } else {
    107 	if (!ReadFromRFBServer(client, client->buffer, nSubrects * 2))
    108 	  return FALSE;
    109 
    110 	for (i = 0; i < nSubrects; i++) {
    111 	  sx = rfbHextileExtractX(*ptr);
    112 	  sy = rfbHextileExtractY(*ptr);
    113 	  ptr++;
    114 	  sw = rfbHextileExtractW(*ptr);
    115 	  sh = rfbHextileExtractH(*ptr);
    116 	  ptr++;
    117 
    118 	  FillRectangle(client, x+sx, y+sy, sw, sh, fg);
    119 	}
    120       }
    121     }
    122   }
    123 
    124   return TRUE;
    125 }
    126 
    127 #undef CARDBPP
    128