28 #ifdef __STRICT_ANSI__ 36 #ifdef LIBVNCSERVER_HAVE_FCNTL_H 43 #define DEBUGPROTO(x) x 49 #define CEIL(x) ( (double) ((int) (x)) == (x) ? \ 50 (double) ((int) (x)) : (double) ((int) (x) + 1) ) 51 #define FLOOR(x) ( (double) ((int) (x)) ) 54 #define InlineX __inline 56 # ifndef __STRICT_ANSI__ 57 # define InlineX inline 64 static InlineX int pad4(
int value)
66 int remainder = value & 3;
67 if (!remainder)
return value;
68 return value + 4 - remainder;
71 int ScaleX(rfbScreenInfoPtr from, rfbScreenInfoPtr to,
int x)
73 if ((from==to) || (from==NULL) || (to==NULL))
return x;
74 return ((
int)(((
double) x / (
double)from->width) * (
double)to->width ));
77 int ScaleY(rfbScreenInfoPtr from, rfbScreenInfoPtr to,
int y)
79 if ((from==to) || (from==NULL) || (to==NULL))
return y;
80 return ((
int)(((
double) y / (
double)from->height) * (
double)to->height ));
86 void rfbScaledCorrection(rfbScreenInfoPtr from, rfbScreenInfoPtr to,
int *
x,
int *
y,
int *w,
int *h,
const char *
function)
88 double x1,y1,w1,h1, x2, y2, w2, h2;
89 double scaleW = ((double) to->width) / ((double) from->width);
90 double scaleH = ((double) to->height) / ((double) from->height);
101 x1 = ((double) *x) * scaleW;
102 y1 = ((double) *y) * scaleH;
103 w1 = ((double) *w) * scaleW;
104 h1 = ((double) *h) * scaleH;
112 w2 =
CEIL(w1 + ( x1 - x2 ));
113 h2 =
CEIL(h1 + ( y1 - y2 ));
131 if (*x+*w > to->width) *w=to->width - *
x;
132 if (*y+*h > to->height) *h=to->height - *
y;
139 int bitsPerPixel, bytesPerPixel, bytesPerLine, areaX, areaY, area2;
140 unsigned char *srcptr, *dstptr;
143 if (screen==ptr)
return;
151 x0 =
ScaleX(ptr, screen, x1);
152 y0 =
ScaleY(ptr, screen, y1);
153 w0 =
ScaleX(ptr, screen, w1);
154 h0 =
ScaleY(ptr, screen, h1);
156 bitsPerPixel = screen->bitsPerPixel;
157 bytesPerPixel = bitsPerPixel / 8;
158 bytesPerLine = w1 * bytesPerPixel;
159 srcptr = (
unsigned char *)(screen->frameBuffer +
160 (y0 * screen->paddedWidthInBytes + x0 * bytesPerPixel));
161 dstptr = (
unsigned char *)(ptr->frameBuffer +
162 ( y1 * ptr->paddedWidthInBytes + x1 * bytesPerPixel));
164 areaX =
ScaleX(ptr,screen,1);
165 areaY =
ScaleY(ptr,screen,1);
170 if ((x1+w1) > (ptr->width))
172 if (x1==0) w1=ptr->width;
else x1 = ptr->width - w1;
174 if ((y1+h1) > (ptr->height))
176 if (y1==0) h1=ptr->height;
else y1 = ptr->height - h1;
184 if (screen->serverFormat.trueColour) {
185 unsigned char *srcptr2;
186 unsigned long pixel_value, red, green, blue;
187 unsigned int redShift = screen->serverFormat.redShift;
188 unsigned int greenShift = screen->serverFormat.greenShift;
189 unsigned int blueShift = screen->serverFormat.blueShift;
190 unsigned long redMax = screen->serverFormat.redMax;
191 unsigned long greenMax = screen->serverFormat.greenMax;
192 unsigned long blueMax = screen->serverFormat.blueMax;
195 for (y = 0; y < h1; y++) {
196 for (x = 0; x < w1; x++) {
197 red = green = blue = 0;
199 for (w = 0; w < areaX; w++) {
200 for (v = 0; v < areaY; v++) {
201 srcptr2 = &srcptr[(((x * areaX) + w) * bytesPerPixel) +
202 (v * screen->paddedWidthInBytes)];
206 switch (bytesPerPixel) {
207 case 4: pixel_value = *((
unsigned int *)srcptr2);
break;
208 case 2: pixel_value = *((
unsigned short *)srcptr2);
break;
209 case 1: pixel_value = *((
unsigned char *)srcptr2);
break;
212 for (z = 0; z < bytesPerPixel; z++)
213 pixel_value += ((
unsigned long)srcptr2[z] << (8 * z));
220 red += ((pixel_value >> redShift) & redMax);
221 green += ((pixel_value >> greenShift) & greenMax);
222 blue += ((pixel_value >> blueShift) & blueMax);
231 pixel_value = ((red & redMax) << redShift) | ((green & greenMax) << greenShift) | ((blue & blueMax) << blueShift);
233 switch (bytesPerPixel) {
234 case 4: *((
unsigned int *)dstptr) = (
unsigned int) pixel_value;
break;
235 case 2: *((
unsigned short *)dstptr) = (
unsigned short) pixel_value;
break;
236 case 1: *((
unsigned char *)dstptr) = (
unsigned char) pixel_value;
break;
239 for (z = 0; z < bytesPerPixel; z++)
240 dstptr[z]=(pixel_value >> (8 * z)) & 0xff;
243 dstptr += bytesPerPixel;
245 srcptr += (screen->paddedWidthInBytes * areaY);
246 dstptr += (ptr->paddedWidthInBytes - bytesPerLine);
250 for (y = y1; y < (y1+h1); y++) {
251 for (x = x1; x < (x1+w1); x++)
252 memcpy (&ptr->frameBuffer[(y *ptr->paddedWidthInBytes) + (x * bytesPerPixel)],
253 &screen->frameBuffer[(y * areaY * screen->paddedWidthInBytes) + (x *areaX * bytesPerPixel)], bytesPerPixel);
263 rfbScreenInfoPtr ptr;
267 for (ptr=screen->scaledScreenNext;ptr!=NULL;ptr=ptr->scaledScreenNext)
270 if (ptr->scaledScreenRefCount>0)
281 rfbScreenInfoPtr ptr;
294 allocSize = pad4(width * (ptr->bitsPerPixel/8));
295 if (height == 0 || allocSize >= SIZE_MAX / height)
304 ptr->paddedWidthInBytes = (ptr->bitsPerPixel/8)*ptr->width;
307 ptr->paddedWidthInBytes = pad4(ptr->paddedWidthInBytes);
310 ptr->scaledScreenRefCount = 0;
312 ptr->sizeInBytes = ptr->paddedWidthInBytes * ptr->height;
313 ptr->serverFormat = cl->screen->serverFormat;
315 ptr->frameBuffer = malloc(ptr->sizeInBytes);
316 if (ptr->frameBuffer!=NULL)
321 LOCK(cl->updateMutex);
322 ptr->scaledScreenNext = cl->screen->scaledScreenNext;
323 cl->screen->scaledScreenNext = ptr;
342 rfbScreenInfoPtr ptr;
344 for (ptr=cl->screen; ptr!=NULL; ptr=ptr->scaledScreenNext)
346 if ((ptr->width==width) && (ptr->height==height))
355 rfbScreenInfoPtr ptr;
364 if (ptr->scaledScreenRefCount<1)
373 LOCK(cl->updateMutex);
374 cl->scaledScreen->scaledScreenRefCount--;
375 ptr->scaledScreenRefCount++;
376 cl->scaledScreen=ptr;
377 cl->newFBSizePending =
TRUE;
380 rfbLog(
"Scaling to %dx%d (refcount=%d)\n",width,height,ptr->scaledScreenRefCount);
383 rfbLog(
"Scaling to %dx%d failed, leaving things alone\n",width,height);
389 if (cl->useNewFBSize && cl->newFBSizePending)
392 LOCK(cl->updateMutex);
393 cl->newFBSizePending =
FALSE;
396 if (cl->PalmVNC==
TRUE)
407 rfbLog(
"Sending a response to a PalmVNC style frameuffer resize event (%dx%d)\n", cl->scaledScreen->width, cl->scaledScreen->height);
421 rfbLog(
"Sending a response to a UltraVNC style frameuffer resize event (%dx%d)\n", cl->scaledScreen->width, cl->scaledScreen->height);
#define sz_rfbResizeFrameBufferMsg
void rfbScaledScreenUpdate(rfbScreenInfoPtr screen, int x1, int y1, int x2, int y2)
void rfbScaledScreenUpdateRect(rfbScreenInfoPtr screen, rfbScreenInfoPtr ptr, int x0, int y0, int w0, int h0)
int rfbWriteExact(rfbClientPtr cl, const char *buf, int len)
#define rfbPalmVNCReSizeFrameBuffer
Per-screen (framebuffer) structure.
#define rfbResizeFrameBuffer
void rfbLogPerror(const char *str)
rfbScreenInfoPtr rfbScalingFind(rfbClientPtr cl, int width, int height)
int ScaleX(rfbScreenInfoPtr from, rfbScreenInfoPtr to, int x)
uint16_t framebufferWidth
int rfbSendNewScaleSize(rfbClientPtr cl)
void rfbScaledCorrection(rfbScreenInfoPtr from, rfbScreenInfoPtr to, int *x, int *y, int *w, int *h, const char *function)
#define sz_rfbPalmVNCReSizeFrameBufferMsg
void rfbScalingSetup(rfbClientPtr cl, int width, int height)
rfbScreenInfoPtr rfbScaledScreenAllocate(rfbClientPtr cl, int width, int height)
uint16_t framebufferHeigth
void rfbCloseClient(rfbClientPtr cl)
int ScaleY(rfbScreenInfoPtr from, rfbScreenInfoPtr to, int y)