By default, Bugzilla does not search the list of RESOLVED bugs.
You can force it to do so by putting the upper-case word ALL in front of your search query, e.g.: ALL tdelibs
We recommend searching for bugs this way, as you may discover that your bug has already been resolved and fixed in a later release. View | Details | Raw Unified | Return to bug 3206
Collapse All | Expand All

(-)tdenetwork-trinity-14.1.0-ORIG/krdc/CMakeLists.txt (-2 lines)
Lines 16-23 Link Here
16
include_directories(
16
include_directories(
17
  ${CMAKE_CURRENT_BINARY_DIR}
17
  ${CMAKE_CURRENT_BINARY_DIR}
18
  ${CMAKE_CURRENT_SOURCE_DIR}
18
  ${CMAKE_CURRENT_SOURCE_DIR}
19
  ${CMAKE_CURRENT_SOURCE_DIR}/../libtdevnc
20
  ${CMAKE_CURRENT_BINARY_DIR}/../libtdevnc
21
  ${CMAKE_BINARY_DIR}
19
  ${CMAKE_BINARY_DIR}
22
  ${TDE_INCLUDE_DIR}
20
  ${TDE_INCLUDE_DIR}
23
  ${TQT_INCLUDE_DIRS}
21
  ${TQT_INCLUDE_DIRS}
(-)tdenetwork-trinity-14.1.0-ORIG/krdc/kremoteview.h (-2 lines)
Lines 2-9 Link Here
2
                   kremoteview.h  -  widget that shows the remote framebuffer
2
                   kremoteview.h  -  widget that shows the remote framebuffer
3
                             -------------------
3
                             -------------------
4
    begin                : Wed Dec 25 23:58:12 CET 2002
4
    begin                : Wed Dec 25 23:58:12 CET 2002
5
    copyright            : (C) 2015 by Timothy Pearson
6
    copyright            : (C) 2007 by Urs Wolfer
7
    copyright            : (C) 2002-2003 by Tim Jansen
5
    copyright            : (C) 2002-2003 by Tim Jansen
8
    email                : tim@tjansen.de
6
    email                : tim@tjansen.de
9
 ***************************************************************************/
7
 ***************************************************************************/
(-)tdenetwork-trinity-14.1.0-ORIG/krdc/Makefile.am (-1 / +1 lines)
Lines 24-30 Link Here
24
dnssddata_DATA = _rfb._tcp
24
dnssddata_DATA = _rfb._tcp
25
25
26
krdc_LDADD   = vnc/libvnc.la rdp/librdp.la $(LIB_TDEUI) $(LIBXF86VIDMODE) $(LIB_SLP) $(LIB_TDEDNSSD) $(X_LDFLAGS) $(LIB_X11) -ltdewalletclient -lDCOP
26
krdc_LDADD   = vnc/libvnc.la rdp/librdp.la $(LIB_TDEUI) $(LIBXF86VIDMODE) $(LIB_SLP) $(LIB_TDEDNSSD) $(X_LDFLAGS) $(LIB_X11) -ltdewalletclient -lDCOP
27
krdc_LDFLAGS = $(all_libraries) $(KDE_RPATH) $(LIB_TQT) -lDCOP $(LIB_TDECORE)
27
krdc_LDFLAGS = $(all_libraries) $(KDE_RPATH) $(LIB_QT) -lDCOP $(LIB_TDECORE)
28
28
29
xdg_apps_DATA = krdc.desktop
29
xdg_apps_DATA = krdc.desktop
30
30
(-)tdenetwork-trinity-14.1.0-ORIG/krdc/rdp/Makefile.am (-1 / +1 lines)
Lines 8-11 Link Here
8
8
9
noinst_HEADERS = krdpview.h rdphostpref.h
9
noinst_HEADERS = krdpview.h rdphostpref.h
10
librdp_la_LIBADD   = $(LIB_TDEUI) $(LIBJPEG)
10
librdp_la_LIBADD   = $(LIB_TDEUI) $(LIBJPEG)
11
librdp_la_LDFLAGS = $(all_libraries) $(KDE_RPATH) $(LIB_TQT) -lDCOP $(LIB_TDECORE) $(LIB_TDEUI) -ltdefx $(LIB_TDEIO) -ltdetexteditor
11
librdp_la_LDFLAGS = $(all_libraries) $(KDE_RPATH) $(LIB_QT) -lDCOP $(LIB_TDECORE) $(LIB_TDEUI) -ltdefx $(LIB_TDEIO) -ltdetexteditor
(-)tdenetwork-trinity-14.1.0-ORIG/krdc/vnc/CMakeLists.txt (-10 / +2 lines)
Lines 1-8 Link Here
1
#################################################
1
#################################################
2
#
2
#
3
#  (C) 2015 Timothy Pearson
4
#  kb9vqf (AT) pearsoncomputing (DOT) net
5
#
6
#  (C) 2010-2011 Serghei Amelian
3
#  (C) 2010-2011 Serghei Amelian
7
#  serghei (DOT) amelian (AT) gmail.com
4
#  serghei (DOT) amelian (AT) gmail.com
8
#
5
#
Lines 16-24 Link Here
16
  ${CMAKE_CURRENT_BINARY_DIR}
13
  ${CMAKE_CURRENT_BINARY_DIR}
17
  ${CMAKE_CURRENT_SOURCE_DIR}
14
  ${CMAKE_CURRENT_SOURCE_DIR}
18
  ${CMAKE_CURRENT_SOURCE_DIR}/..
15
  ${CMAKE_CURRENT_SOURCE_DIR}/..
19
  ${CMAKE_CURRENT_SOURCE_DIR}/../../libtdevnc
20
  ${CMAKE_CURRENT_BINARY_DIR}/../../libtdevnc
21
  ${CMAKE_BINARY_DIR}
22
  ${TDE_INCLUDE_DIR}
16
  ${TDE_INCLUDE_DIR}
23
  ${TQT_INCLUDE_DIRS}
17
  ${TQT_INCLUDE_DIRS}
24
)
18
)
Lines 28-35 Link Here
28
22
29
tde_add_library( vnc STATIC_PIC AUTOMOC
23
tde_add_library( vnc STATIC_PIC AUTOMOC
30
  SOURCES
24
  SOURCES
31
    kvncview.cpp scaling.cpp threads.cpp
25
    kvncview.cpp threads.cpp colour.c d3des.c desktop.c rfbproto.c sockets.c
32
    vncprefs.ui vnchostpref.cpp
26
    vncauth.c vncprefs.ui vnchostpref.cpp
33
  LINK
34
    tdevncclient-static
35
)
27
)
(-)tdenetwork-trinity-14.1.0-ORIG/krdc/vnc/colour.c (+415 lines)
Line 0 Link Here
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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
17
 *  USA.
18
 */
19
20
/*
21
 * colour.c - functions to deal with colour - i.e. RFB pixel formats, X visuals
22
 * and colormaps.  Thanks to Grant McDorman for some of the ideas used here.
23
 */
24
25
#include "vncviewer.h"
26
#include <limits.h>
27
28
29
#define INVALID_PIXEL 0xffffffff
30
#define MAX_CMAP_SIZE 256
31
#define BGR233_SIZE 256
32
unsigned long BGR233ToPixel[BGR233_SIZE];
33
34
Colormap cmap;
35
Visual *vis;
36
unsigned int visdepth, visbpp;
37
Bool allocColorFailed = False;
38
39
static int nBGR233ColoursAllocated;
40
41
static int GetBPPForDepth(int depth);
42
static void SetupBGR233Map(void);
43
static void AllocateExactBGR233Colours(void);
44
static Bool AllocateBGR233Colour(int r, int g, int b);
45
46
47
/*
48
 * SetVisualAndCmap() deals with the wonderful world of X "visuals" (which are
49
 * equivalent to the RFB protocol's "pixel format").  Having decided on the
50
 * best visual, it also creates a colormap if necessary, sets the appropriate
51
 * resources on the toplevel widget, and sets up the myFormat structure to
52
 * describe the pixel format in terms that the RFB server will be able to
53
 * understand.
54
 *
55
 * The algorithm for deciding which visual to use is as follows:
56
 *
57
 * If forceOwnCmap is true then we try to use a PseudoColor visual - we first
58
 * see if there's one of the same depth as the RFB server, followed by an 8-bit
59
 * deep one.
60
 *
61
 * If forceTrueColour is true then we try to use a TrueColor visual - if
62
 * requestedDepth is set then it must be of that depth, otherwise any depth
63
 * will be used.
64
 *
65
 * Otherwise, we use the X server's default visual and colormap.  If this is
66
 * TrueColor then we just ask the RFB server for this format.  If the default
67
 * isn't TrueColor, or if useBGR233 is true, then we ask the RFB server for
68
 * BGR233 pixel format and use a lookup table to translate to the nearest
69
 * colours provided by the X server.
70
 */
71
72
void
73
SetVisualAndCmap()
74
{
75
  /* just use default visual and colormap */
76
77
  vis = DefaultVisual(dpy,DefaultScreen(dpy));
78
  visdepth = DefaultDepth(dpy,DefaultScreen(dpy));
79
  visbpp = GetBPPForDepth(visdepth);
80
  cmap = DefaultColormap(dpy,DefaultScreen(dpy));
81
82
  if (!appData.useBGR233 && (vis->class == TrueColor)) {
83
84
    myFormat.bitsPerPixel = visbpp;
85
    myFormat.depth = visdepth;
86
    myFormat.trueColour = 1;
87
    myFormat.bigEndian = (ImageByteOrder(dpy) == MSBFirst);
88
    myFormat.redShift = ffs(vis->red_mask) - 1;
89
    myFormat.greenShift = ffs(vis->green_mask) - 1;
90
    myFormat.blueShift = ffs(vis->blue_mask) - 1;
91
    myFormat.redMax = vis->red_mask >> myFormat.redShift;
92
    myFormat.greenMax = vis->green_mask >> myFormat.greenShift;
93
    myFormat.blueMax = vis->blue_mask >> myFormat.blueShift;
94
95
    fprintf(stderr,
96
	    "Using default colormap which is TrueColor.  Pixel format:\n");
97
    PrintPixelFormat(&myFormat);
98
    return;
99
  }
100
101
  appData.useBGR233 = True;
102
103
  myFormat.bitsPerPixel = 8;
104
  myFormat.depth = 8;
105
  myFormat.trueColour = 1;
106
  myFormat.bigEndian = 0;
107
  myFormat.redMax = 7;
108
  myFormat.greenMax = 7;
109
  myFormat.blueMax = 3;
110
  myFormat.redShift = 0;
111
  myFormat.greenShift = 3;
112
  myFormat.blueShift = 6;
113
114
  fprintf(stderr,
115
       "Using default colormap and translating from BGR233.  Pixel format:\n");
116
  PrintPixelFormat(&myFormat);
117
118
  SetupBGR233Map();
119
}
120
121
122
/*
123
 * GetBPPForDepth looks through the "pixmap formats" to find the bits-per-pixel
124
 * for the given depth.
125
 */
126
127
static int
128
GetBPPForDepth(int depth)
129
{
130
  XPixmapFormatValues *format;
131
  int nformats;
132
  int i;
133
  int bpp;
134
135
  format = XListPixmapFormats(dpy, &nformats);
136
137
  for (i = 0; i < nformats; i++) {
138
    if (format[i].depth == depth)
139
      break;
140
  }
141
142
  if (i == nformats) {
143
    fprintf(stderr,"no pixmap format for depth %d???\n", depth);
144
    exit(1);
145
  }
146
147
  bpp = format[i].bits_per_pixel;
148
149
  XFree(format);
150
151
  if (bpp != 1 && bpp != 8 && bpp != 16 && bpp != 32) {
152
    fprintf(stderr,"Can't cope with %d bits-per-pixel.  Sorry.\n", bpp);
153
    exit(1);
154
  }
155
156
  return bpp;
157
}
158
159
160
161
/*
162
 * SetupBGR233Map() sets up the BGR233ToPixel array.
163
 *
164
 * It calls AllocateExactBGR233Colours to allocate some exact BGR233 colours
165
 * (limited by space in the colormap and/or by the value of the nColours
166
 * resource).  If the number allocated is less than BGR233_SIZE then it fills
167
 * the rest in using the "nearest" colours available.  How this is done depends
168
 * on the value of the useSharedColours resource.  If it's false, we use only
169
 * colours from the exact BGR233 colours we've just allocated.  If it's true,
170
 * then we also use other clients' "shared" colours available in the colormap.
171
 */
172
173
static void
174
SetupBGR233Map(void)
175
{
176
  int r, g, b;
177
  long i;
178
  unsigned long nearestPixel = 0;
179
  int cmapSize;
180
  XColor cmapEntry[MAX_CMAP_SIZE];
181
  Bool exactBGR233[MAX_CMAP_SIZE];
182
  Bool shared[MAX_CMAP_SIZE];
183
  Bool usedAsNearest[MAX_CMAP_SIZE];
184
  int nSharedUsed = 0;
185
186
  if (visdepth > 8) {
187
    appData.nColours = 256; /* ignore nColours setting for > 8-bit deep */
188
  }
189
190
  for (i = 0; i < BGR233_SIZE; i++) {
191
    BGR233ToPixel[i] = INVALID_PIXEL;
192
  }
193
194
  AllocateExactBGR233Colours();
195
196
  fprintf(stderr,"Got %d exact BGR233 colours out of %d\n",
197
	  nBGR233ColoursAllocated, appData.nColours);
198
199
  if (nBGR233ColoursAllocated < BGR233_SIZE) {
200
201
    if (visdepth > 8) { /* shouldn't get here */
202
      fprintf(stderr,"Error: couldn't allocate BGR233 colours even though "
203
	      "depth is %d\n", visdepth);
204
      exit(1);
205
    }
206
207
    cmapSize = (1 << visdepth);
208
209
    for (i = 0; i < cmapSize; i++) {
210
      cmapEntry[i].pixel = i;
211
      exactBGR233[i] = False;
212
      shared[i] = False;
213
      usedAsNearest[i] = False;
214
    }
215
216
    XQueryColors(dpy, cmap, cmapEntry, cmapSize);
217
218
    /* mark all our exact BGR233 pixels */
219
220
    for (i = 0; i < BGR233_SIZE; i++) {
221
      if (BGR233ToPixel[i] != INVALID_PIXEL)
222
	exactBGR233[BGR233ToPixel[i]] = True;
223
    }
224
225
    if (appData.useSharedColours) {
226
227
      /* Try to find existing shared colours.  This is harder than it sounds
228
	 because XQueryColors doesn't tell us whether colours are shared,
229
	 private or unallocated.  What we do is go through the colormap and for
230
	 each pixel try to allocate exactly its RGB values.  If this returns a
231
	 different pixel then it's definitely either a private or unallocated
232
	 pixel, so no use to us.  If it returns us the same pixel again, then
233
	 it's likely that it's a shared colour - however, it is possible that
234
	 it was actually an unallocated pixel, which we've now allocated.  We
235
	 minimise this possibility by going through the pixels in reverse order
236
	 - this helps becuse the X server allocates new pixels from the lowest
237
	 number up, so it should only be a problem for the lowest unallocated
238
	 pixel.  Got that? */
239
240
      for (i = cmapSize-1; i >= 0; i--) {
241
	if (!exactBGR233[i] &&
242
	    XAllocColor(dpy, cmap, &cmapEntry[i])) {
243
244
	  if (cmapEntry[i].pixel == (unsigned long) i) {
245
246
	    shared[i] = True; /* probably shared */
247
248
	  } else {
249
250
	    /* "i" is either unallocated or private.  We have now unnecessarily
251
	       allocated cmapEntry[i].pixel.  Free it. */
252
253
	    XFreeColors(dpy, cmap, &cmapEntry[i].pixel, 1, 0);
254
	  }
255
	}
256
      }
257
    }
258
259
    /* Now fill in the nearest colours */
260
261
    for (r = 0; r < 8; r++) {
262
      for (g = 0; g < 8; g++) {
263
	for (b = 0; b < 4; b++) {
264
	  if (BGR233ToPixel[(b<<6) | (g<<3) | r] == INVALID_PIXEL) {
265
266
	    unsigned long minDistance = ULONG_MAX;
267
268
	    for (i = 0; i < cmapSize; i++) {
269
	      if (exactBGR233[i] || shared[i]) {
270
		unsigned long distance
271
		  = (abs(cmapEntry[i].red - r * 65535 / 7)
272
		     + abs(cmapEntry[i].green - g * 65535 / 7)
273
		     + abs(cmapEntry[i].blue - b * 65535 / 3));
274
275
		if (distance < minDistance) {
276
		  minDistance = distance;
277
		  nearestPixel = i;
278
		}
279
	      }
280
	    }
281
282
	    BGR233ToPixel[(b<<6) | (g<<3) | r] = nearestPixel;
283
	    if (shared[nearestPixel] && !usedAsNearest[nearestPixel])
284
	      nSharedUsed++;
285
	    usedAsNearest[nearestPixel] = True;
286
	  }
287
	}
288
      }
289
    }
290
291
    /* Tidy up shared colours which we allocated but aren't going to use */
292
293
    for (i = 0; i < cmapSize; i++) {
294
      if (shared[i] && !usedAsNearest[i]) {
295
	  XFreeColors(dpy, cmap, (unsigned long *)&i, 1, 0);
296
      }
297
    }
298
299
    fprintf(stderr,"Using %d existing shared colours\n", nSharedUsed);
300
  }
301
}
302
303
304
/*
305
 * AllocateExactBGR233Colours() attempts to allocate each of the colours in the
306
 * BGR233 colour cube, stopping when an allocation fails.  The order it does
307
 * this in is such that we should get a fairly well spread subset of the cube,
308
 * however many allocations are made.  There's probably a neater algorithm for
309
 * doing this, but it's not obvious to me anyway.  The way this algorithm works
310
 * is:
311
 *
312
 * At each stage, we introduce a new value for one of the primaries, and
313
 * allocate all the colours with the new value of that primary and all previous
314
 * values of the other two primaries.  We start with r=0 as the "new" value
315
 * for r, and g=0, b=0 as the "previous" values of g and b.  So we get:
316
 *
317
 * New primary value   Previous values of other primaries   Colours allocated
318
 * -----------------   ----------------------------------   -----------------
319
 * r=0                 g=0       b=0                        r0 g0 b0
320
 * g=7                 r=0       b=0                        r0 g7 b0
321
 * b=3                 r=0       g=0,7                      r0 g0 b3
322
 *                                                          r0 g7 b3
323
 * r=7                 g=0,7     b=0,3                      r7 g0 b0
324
 * 		       		 			    r7 g0 b3
325
 * 							    r7 g7 b0
326
 *							    r7 g7 b3
327
 * g=3                 r=0,7     b=0,3                      r0 g3 b0
328
 *                                                          r0 g3 b3
329
 *                                                          r7 g3 b0
330
 *                                                          r7 g3 b3
331
 * ....etc.
332
 * */
333
334
static void
335
AllocateExactBGR233Colours(void)
336
{
337
  int rv[] = {0,7,3,5,1,6,2,4};
338
  int gv[] = {0,7,3,5,1,6,2,4};
339
  int bv[] = {0,3,1,2};
340
  int rn = 0;
341
  int gn = 1;
342
  int bn = 1;
343
  int ri, gi, bi;
344
345
  nBGR233ColoursAllocated = 0;
346
347
  while (1) {
348
    if (rn == 8)
349
      break;
350
351
    ri = rn;
352
    for (gi = 0; gi < gn; gi++) {
353
      for (bi = 0; bi < bn; bi++) {
354
	if (!AllocateBGR233Colour(rv[ri], gv[gi], bv[bi]))
355
	  return;
356
      }
357
    }
358
    rn++;
359
360
    if (gn == 8)
361
      break;
362
363
    gi = gn;
364
    for (ri = 0; ri < rn; ri++) {
365
      for (bi = 0; bi < bn; bi++) {
366
	if (!AllocateBGR233Colour(rv[ri], gv[gi], bv[bi]))
367
	  return;
368
      }
369
    }
370
    gn++;
371
372
    if (bn < 4) {
373
374
      bi = bn;
375
      for (ri = 0; ri < rn; ri++) {
376
	for (gi = 0; gi < gn; gi++) {
377
	  if (!AllocateBGR233Colour(rv[ri], gv[gi], bv[bi]))
378
	    return;
379
	}
380
      }
381
      bn++;
382
    }
383
  }
384
}
385
386
387
/*
388
 * AllocateBGR233Colour() attempts to allocate the given BGR233 colour as a
389
 * shared colormap entry, storing its pixel value in the BGR233ToPixel array.
390
 * r is from 0 to 7, g from 0 to 7 and b from 0 to 3.  It fails either when the
391
 * allocation fails or when we would exceed the number of colours specified in
392
 * the nColours resource.
393
 */
394
395
static Bool
396
AllocateBGR233Colour(int r, int g, int b)
397
{
398
  XColor c;
399
400
  if (nBGR233ColoursAllocated >= appData.nColours)
401
    return False;
402
403
  c.red = r * 65535 / 7;
404
  c.green = g * 65535 / 7;
405
  c.blue = b * 65535 / 3;
406
407
  if (!XAllocColor(dpy, cmap, &c))
408
    return False;
409
410
  BGR233ToPixel[(b<<6) | (g<<3) | r] = c.pixel;
411
412
  nBGR233ColoursAllocated++;
413
414
  return True;
415
}
(-)tdenetwork-trinity-14.1.0-ORIG/krdc/vnc/d3des.c (+440 lines)
Line 0 Link Here
1
/*
2
 * This is D3DES (V5.09) by Richard Outerbridge with the double and
3
 * triple-length support removed for use in VNC.  Also the bytebit[] array
4
 * has been reversed so that the most significant bit in each byte of the
5
 * key is ignored, not the least significant.
6
 *
7
 * These changes are:
8
 *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
9
 *
10
 * This software is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13
 */
14
15
/* D3DES (V5.09) -
16
 *
17
 * A portable, public domain, version of the Data Encryption Standard.
18
 *
19
 * Written with Symantec's THINK (Lightspeed) C by Richard Outerbridge.
20
 * Thanks to: Dan Hoey for his excellent Initial and Inverse permutation
21
 * code;  Jim Gillogly & Phil Karn for the DES key schedule code; Dennis
22
 * Ferguson, Eric Young and Dana How for comparing notes; and Ray Lau,
23
 * for humouring me on.
24
 *
25
 * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge.
26
 * (GEnie : OUTER; CIS : [71755,204]) Graven Imagery, 1992.
27
 */
28
29
#include "d3des.h"
30
31
static void scrunch(unsigned char *, unsigned long *);
32
static void unscrun(unsigned long *, unsigned char *);
33
static void desfunc(unsigned long *, unsigned long *);
34
static void cookey(unsigned long *);
35
36
static unsigned long KnL[32] = { 0L };
37
static unsigned long KnR[32] = { 0L };
38
static unsigned long Kn3[32] = { 0L };
39
static unsigned char Df_Key[24] = {
40
	0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef,
41
	0xfe,0xdc,0xba,0x98,0x76,0x54,0x32,0x10,
42
	0x89,0xab,0xcd,0xef,0x01,0x23,0x45,0x67 };
43
44
static unsigned short bytebit[8]	= {
45
	01, 02, 04, 010, 020, 040, 0100, 0200 };
46
47
static unsigned long bigbyte[24] = {
48
	0x800000L,	0x400000L,	0x200000L,	0x100000L,
49
	0x80000L,	0x40000L,	0x20000L,	0x10000L,
50
	0x8000L,	0x4000L,	0x2000L,	0x1000L,
51
	0x800L, 	0x400L, 	0x200L, 	0x100L,
52
	0x80L,		0x40L,		0x20L,		0x10L,
53
	0x8L,		0x4L,		0x2L,		0x1L	};
54
55
/* Use the key schedule specified in the Standard (ANSI X3.92-1981). */
56
57
static unsigned char pc1[56] = {
58
	56, 48, 40, 32, 24, 16,  8,	 0, 57, 49, 41, 33, 25, 17,
59
	 9,  1, 58, 50, 42, 34, 26,	18, 10,  2, 59, 51, 43, 35,
60
	62, 54, 46, 38, 30, 22, 14,	 6, 61, 53, 45, 37, 29, 21,
61
	13,  5, 60, 52, 44, 36, 28,	20, 12,  4, 27, 19, 11,  3 };
62
63
static unsigned char totrot[16] = {
64
	1,2,4,6,8,10,12,14,15,17,19,21,23,25,27,28 };
65
66
static unsigned char pc2[48] = {
67
	13, 16, 10, 23,  0,  4,  2, 27, 14,  5, 20,  9,
68
	22, 18, 11,  3, 25,  7, 15,  6, 26, 19, 12,  1,
69
	40, 51, 30, 36, 46, 54, 29, 39, 50, 44, 32, 47,
70
	43, 48, 38, 55, 33, 52, 45, 41, 49, 35, 28, 31 };
71
72
void deskey(key, edf)	/* Thanks to James Gillogly & Phil Karn! */
73
unsigned char *key;
74
int edf;
75
{
76
	register int i, j, l, m, n;
77
	unsigned char pc1m[56], pcr[56];
78
	unsigned long kn[32];
79
80
	for ( j = 0; j < 56; j++ ) {
81
		l = pc1[j];
82
		m = l & 07;
83
		pc1m[j] = (key[l >> 3] & bytebit[m]) ? 1 : 0;
84
		}
85
	for( i = 0; i < 16; i++ ) {
86
		if( edf == DE1 ) m = (15 - i) << 1;
87
		else m = i << 1;
88
		n = m + 1;
89
		kn[m] = kn[n] = 0L;
90
		for( j = 0; j < 28; j++ ) {
91
			l = j + totrot[i];
92
			if( l < 28 ) pcr[j] = pc1m[l];
93
			else pcr[j] = pc1m[l - 28];
94
			}
95
		for( j = 28; j < 56; j++ ) {
96
		    l = j + totrot[i];
97
		    if( l < 56 ) pcr[j] = pc1m[l];
98
		    else pcr[j] = pc1m[l - 28];
99
		    }
100
		for( j = 0; j < 24; j++ ) {
101
			if( pcr[pc2[j]] ) kn[m] |= bigbyte[j];
102
			if( pcr[pc2[j+24]] ) kn[n] |= bigbyte[j];
103
			}
104
		}
105
	cookey(kn);
106
	return;
107
	}
108
109
static void cookey(raw1)
110
register unsigned long *raw1;
111
{
112
	register unsigned long *cook, *raw0;
113
	unsigned long dough[32];
114
	register int i;
115
116
	cook = dough;
117
	for( i = 0; i < 16; i++, raw1++ ) {
118
		raw0 = raw1++;
119
		*cook	 = (*raw0 & 0x00fc0000L) << 6;
120
		*cook	|= (*raw0 & 0x00000fc0L) << 10;
121
		*cook	|= (*raw1 & 0x00fc0000L) >> 10;
122
		*cook++ |= (*raw1 & 0x00000fc0L) >> 6;
123
		*cook	 = (*raw0 & 0x0003f000L) << 12;
124
		*cook	|= (*raw0 & 0x0000003fL) << 16;
125
		*cook	|= (*raw1 & 0x0003f000L) >> 4;
126
		*cook++ |= (*raw1 & 0x0000003fL);
127
		}
128
	usekey(dough);
129
	return;
130
	}
131
132
void cpkey(into)
133
register unsigned long *into;
134
{
135
	register unsigned long *from, *endp;
136
137
	from = KnL, endp = &KnL[32];
138
	while( from < endp ) *into++ = *from++;
139
	return;
140
	}
141
142
void usekey(from)
143
register unsigned long *from;
144
{
145
	register unsigned long *to, *endp;
146
147
	to = KnL, endp = &KnL[32];
148
	while( to < endp ) *to++ = *from++;
149
	return;
150
	}
151
152
void des(inblock, outblock)
153
unsigned char *inblock, *outblock;
154
{
155
	unsigned long work[2];
156
157
	scrunch(inblock, work);
158
	desfunc(work, KnL);
159
	unscrun(work, outblock);
160
	return;
161
	}
162
163
static void scrunch(outof, into)
164
register unsigned char *outof;
165
register unsigned long *into;
166
{
167
	*into	 = (*outof++ & 0xffL) << 24;
168
	*into	|= (*outof++ & 0xffL) << 16;
169
	*into	|= (*outof++ & 0xffL) << 8;
170
	*into++ |= (*outof++ & 0xffL);
171
	*into	 = (*outof++ & 0xffL) << 24;
172
	*into	|= (*outof++ & 0xffL) << 16;
173
	*into	|= (*outof++ & 0xffL) << 8;
174
	*into	|= (*outof   & 0xffL);
175
	return;
176
	}
177
178
static void unscrun(outof, into)
179
register unsigned long *outof;
180
register unsigned char *into;
181
{
182
	*into++ = (*outof >> 24) & 0xffL;
183
	*into++ = (*outof >> 16) & 0xffL;
184
	*into++ = (*outof >>  8) & 0xffL;
185
	*into++ =  *outof++	 & 0xffL;
186
	*into++ = (*outof >> 24) & 0xffL;
187
	*into++ = (*outof >> 16) & 0xffL;
188
	*into++ = (*outof >>  8) & 0xffL;
189
	*into	=  *outof	 & 0xffL;
190
	return;
191
	}
192
193
static unsigned long SP1[64] = {
194
	0x01010400L, 0x00000000L, 0x00010000L, 0x01010404L,
195
	0x01010004L, 0x00010404L, 0x00000004L, 0x00010000L,
196
	0x00000400L, 0x01010400L, 0x01010404L, 0x00000400L,
197
	0x01000404L, 0x01010004L, 0x01000000L, 0x00000004L,
198
	0x00000404L, 0x01000400L, 0x01000400L, 0x00010400L,
199
	0x00010400L, 0x01010000L, 0x01010000L, 0x01000404L,
200
	0x00010004L, 0x01000004L, 0x01000004L, 0x00010004L,
201
	0x00000000L, 0x00000404L, 0x00010404L, 0x01000000L,
202
	0x00010000L, 0x01010404L, 0x00000004L, 0x01010000L,
203
	0x01010400L, 0x01000000L, 0x01000000L, 0x00000400L,
204
	0x01010004L, 0x00010000L, 0x00010400L, 0x01000004L,
205
	0x00000400L, 0x00000004L, 0x01000404L, 0x00010404L,
206
	0x01010404L, 0x00010004L, 0x01010000L, 0x01000404L,
207
	0x01000004L, 0x00000404L, 0x00010404L, 0x01010400L,
208
	0x00000404L, 0x01000400L, 0x01000400L, 0x00000000L,
209
	0x00010004L, 0x00010400L, 0x00000000L, 0x01010004L };
210
211
static unsigned long SP2[64] = {
212
	0x80108020L, 0x80008000L, 0x00008000L, 0x00108020L,
213
	0x00100000L, 0x00000020L, 0x80100020L, 0x80008020L,
214
	0x80000020L, 0x80108020L, 0x80108000L, 0x80000000L,
215
	0x80008000L, 0x00100000L, 0x00000020L, 0x80100020L,
216
	0x00108000L, 0x00100020L, 0x80008020L, 0x00000000L,
217
	0x80000000L, 0x00008000L, 0x00108020L, 0x80100000L,
218
	0x00100020L, 0x80000020L, 0x00000000L, 0x00108000L,
219
	0x00008020L, 0x80108000L, 0x80100000L, 0x00008020L,
220
	0x00000000L, 0x00108020L, 0x80100020L, 0x00100000L,
221
	0x80008020L, 0x80100000L, 0x80108000L, 0x00008000L,
222
	0x80100000L, 0x80008000L, 0x00000020L, 0x80108020L,
223
	0x00108020L, 0x00000020L, 0x00008000L, 0x80000000L,
224
	0x00008020L, 0x80108000L, 0x00100000L, 0x80000020L,
225
	0x00100020L, 0x80008020L, 0x80000020L, 0x00100020L,
226
	0x00108000L, 0x00000000L, 0x80008000L, 0x00008020L,
227
	0x80000000L, 0x80100020L, 0x80108020L, 0x00108000L };
228
229
static unsigned long SP3[64] = {
230
	0x00000208L, 0x08020200L, 0x00000000L, 0x08020008L,
231
	0x08000200L, 0x00000000L, 0x00020208L, 0x08000200L,
232
	0x00020008L, 0x08000008L, 0x08000008L, 0x00020000L,
233
	0x08020208L, 0x00020008L, 0x08020000L, 0x00000208L,
234
	0x08000000L, 0x00000008L, 0x08020200L, 0x00000200L,
235
	0x00020200L, 0x08020000L, 0x08020008L, 0x00020208L,
236
	0x08000208L, 0x00020200L, 0x00020000L, 0x08000208L,
237
	0x00000008L, 0x08020208L, 0x00000200L, 0x08000000L,
238
	0x08020200L, 0x08000000L, 0x00020008L, 0x00000208L,
239
	0x00020000L, 0x08020200L, 0x08000200L, 0x00000000L,
240
	0x00000200L, 0x00020008L, 0x08020208L, 0x08000200L,
241
	0x08000008L, 0x00000200L, 0x00000000L, 0x08020008L,
242
	0x08000208L, 0x00020000L, 0x08000000L, 0x08020208L,
243
	0x00000008L, 0x00020208L, 0x00020200L, 0x08000008L,
244
	0x08020000L, 0x08000208L, 0x00000208L, 0x08020000L,
245
	0x00020208L, 0x00000008L, 0x08020008L, 0x00020200L };
246
247
static unsigned long SP4[64] = {
248
	0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
249
	0x00802080L, 0x00800081L, 0x00800001L, 0x00002001L,
250
	0x00000000L, 0x00802000L, 0x00802000L, 0x00802081L,
251
	0x00000081L, 0x00000000L, 0x00800080L, 0x00800001L,
252
	0x00000001L, 0x00002000L, 0x00800000L, 0x00802001L,
253
	0x00000080L, 0x00800000L, 0x00002001L, 0x00002080L,
254
	0x00800081L, 0x00000001L, 0x00002080L, 0x00800080L,
255
	0x00002000L, 0x00802080L, 0x00802081L, 0x00000081L,
256
	0x00800080L, 0x00800001L, 0x00802000L, 0x00802081L,
257
	0x00000081L, 0x00000000L, 0x00000000L, 0x00802000L,
258
	0x00002080L, 0x00800080L, 0x00800081L, 0x00000001L,
259
	0x00802001L, 0x00002081L, 0x00002081L, 0x00000080L,
260
	0x00802081L, 0x00000081L, 0x00000001L, 0x00002000L,
261
	0x00800001L, 0x00002001L, 0x00802080L, 0x00800081L,
262
	0x00002001L, 0x00002080L, 0x00800000L, 0x00802001L,
263
	0x00000080L, 0x00800000L, 0x00002000L, 0x00802080L };
264
265
static unsigned long SP5[64] = {
266
	0x00000100L, 0x02080100L, 0x02080000L, 0x42000100L,
267
	0x00080000L, 0x00000100L, 0x40000000L, 0x02080000L,
268
	0x40080100L, 0x00080000L, 0x02000100L, 0x40080100L,
269
	0x42000100L, 0x42080000L, 0x00080100L, 0x40000000L,
270
	0x02000000L, 0x40080000L, 0x40080000L, 0x00000000L,
271
	0x40000100L, 0x42080100L, 0x42080100L, 0x02000100L,
272
	0x42080000L, 0x40000100L, 0x00000000L, 0x42000000L,
273
	0x02080100L, 0x02000000L, 0x42000000L, 0x00080100L,
274
	0x00080000L, 0x42000100L, 0x00000100L, 0x02000000L,
275
	0x40000000L, 0x02080000L, 0x42000100L, 0x40080100L,
276
	0x02000100L, 0x40000000L, 0x42080000L, 0x02080100L,
277
	0x40080100L, 0x00000100L, 0x02000000L, 0x42080000L,
278
	0x42080100L, 0x00080100L, 0x42000000L, 0x42080100L,
279
	0x02080000L, 0x00000000L, 0x40080000L, 0x42000000L,
280
	0x00080100L, 0x02000100L, 0x40000100L, 0x00080000L,
281
	0x00000000L, 0x40080000L, 0x02080100L, 0x40000100L };
282
283
static unsigned long SP6[64] = {
284
	0x20000010L, 0x20400000L, 0x00004000L, 0x20404010L,
285
	0x20400000L, 0x00000010L, 0x20404010L, 0x00400000L,
286
	0x20004000L, 0x00404010L, 0x00400000L, 0x20000010L,
287
	0x00400010L, 0x20004000L, 0x20000000L, 0x00004010L,
288
	0x00000000L, 0x00400010L, 0x20004010L, 0x00004000L,
289
	0x00404000L, 0x20004010L, 0x00000010L, 0x20400010L,
290
	0x20400010L, 0x00000000L, 0x00404010L, 0x20404000L,
291
	0x00004010L, 0x00404000L, 0x20404000L, 0x20000000L,
292
	0x20004000L, 0x00000010L, 0x20400010L, 0x00404000L,
293
	0x20404010L, 0x00400000L, 0x00004010L, 0x20000010L,
294
	0x00400000L, 0x20004000L, 0x20000000L, 0x00004010L,
295
	0x20000010L, 0x20404010L, 0x00404000L, 0x20400000L,
296
	0x00404010L, 0x20404000L, 0x00000000L, 0x20400010L,
297
	0x00000010L, 0x00004000L, 0x20400000L, 0x00404010L,
298
	0x00004000L, 0x00400010L, 0x20004010L, 0x00000000L,
299
	0x20404000L, 0x20000000L, 0x00400010L, 0x20004010L };
300
301
static unsigned long SP7[64] = {
302
	0x00200000L, 0x04200002L, 0x04000802L, 0x00000000L,
303
	0x00000800L, 0x04000802L, 0x00200802L, 0x04200800L,
304
	0x04200802L, 0x00200000L, 0x00000000L, 0x04000002L,
305
	0x00000002L, 0x04000000L, 0x04200002L, 0x00000802L,
306
	0x04000800L, 0x00200802L, 0x00200002L, 0x04000800L,
307
	0x04000002L, 0x04200000L, 0x04200800L, 0x00200002L,
308
	0x04200000L, 0x00000800L, 0x00000802L, 0x04200802L,
309
	0x00200800L, 0x00000002L, 0x04000000L, 0x00200800L,
310
	0x04000000L, 0x00200800L, 0x00200000L, 0x04000802L,
311
	0x04000802L, 0x04200002L, 0x04200002L, 0x00000002L,
312
	0x00200002L, 0x04000000L, 0x04000800L, 0x00200000L,
313
	0x04200800L, 0x00000802L, 0x00200802L, 0x04200800L,
314
	0x00000802L, 0x04000002L, 0x04200802L, 0x04200000L,
315
	0x00200800L, 0x00000000L, 0x00000002L, 0x04200802L,
316
	0x00000000L, 0x00200802L, 0x04200000L, 0x00000800L,
317
	0x04000002L, 0x04000800L, 0x00000800L, 0x00200002L };
318
319
static unsigned long SP8[64] = {
320
	0x10001040L, 0x00001000L, 0x00040000L, 0x10041040L,
321
	0x10000000L, 0x10001040L, 0x00000040L, 0x10000000L,
322
	0x00040040L, 0x10040000L, 0x10041040L, 0x00041000L,
323
	0x10041000L, 0x00041040L, 0x00001000L, 0x00000040L,
324
	0x10040000L, 0x10000040L, 0x10001000L, 0x00001040L,
325
	0x00041000L, 0x00040040L, 0x10040040L, 0x10041000L,
326
	0x00001040L, 0x00000000L, 0x00000000L, 0x10040040L,
327
	0x10000040L, 0x10001000L, 0x00041040L, 0x00040000L,
328
	0x00041040L, 0x00040000L, 0x10041000L, 0x00001000L,
329
	0x00000040L, 0x10040040L, 0x00001000L, 0x00041040L,
330
	0x10001000L, 0x00000040L, 0x10000040L, 0x10040000L,
331
	0x10040040L, 0x10000000L, 0x00040000L, 0x10001040L,
332
	0x00000000L, 0x10041040L, 0x00040040L, 0x10000040L,
333
	0x10040000L, 0x10001000L, 0x10001040L, 0x00000000L,
334
	0x10041040L, 0x00041000L, 0x00041000L, 0x00001040L,
335
	0x00001040L, 0x00040040L, 0x10000000L, 0x10041000L };
336
337
static void desfunc(block, keys)
338
register unsigned long *block, *keys;
339
{
340
	register unsigned long fval, work, right, leftt;
341
	register int round;
342
343
	leftt = block[0];
344
	right = block[1];
345
	work = ((leftt >> 4) ^ right) & 0x0f0f0f0fL;
346
	right ^= work;
347
	leftt ^= (work << 4);
348
	work = ((leftt >> 16) ^ right) & 0x0000ffffL;
349
	right ^= work;
350
	leftt ^= (work << 16);
351
	work = ((right >> 2) ^ leftt) & 0x33333333L;
352
	leftt ^= work;
353
	right ^= (work << 2);
354
	work = ((right >> 8) ^ leftt) & 0x00ff00ffL;
355
	leftt ^= work;
356
	right ^= (work << 8);
357
	right = ((right << 1) | ((right >> 31) & 1L)) & 0xffffffffL;
358
	work = (leftt ^ right) & 0xaaaaaaaaL;
359
	leftt ^= work;
360
	right ^= work;
361
	leftt = ((leftt << 1) | ((leftt >> 31) & 1L)) & 0xffffffffL;
362
363
	for( round = 0; round < 8; round++ ) {
364
		work  = (right << 28) | (right >> 4);
365
		work ^= *keys++;
366
		fval  = SP7[ work		 & 0x3fL];
367
		fval |= SP5[(work >>  8) & 0x3fL];
368
		fval |= SP3[(work >> 16) & 0x3fL];
369
		fval |= SP1[(work >> 24) & 0x3fL];
370
		work  = right ^ *keys++;
371
		fval |= SP8[ work		 & 0x3fL];
372
		fval |= SP6[(work >>  8) & 0x3fL];
373
		fval |= SP4[(work >> 16) & 0x3fL];
374
		fval |= SP2[(work >> 24) & 0x3fL];
375
		leftt ^= fval;
376
		work  = (leftt << 28) | (leftt >> 4);
377
		work ^= *keys++;
378
		fval  = SP7[ work		 & 0x3fL];
379
		fval |= SP5[(work >>  8) & 0x3fL];
380
		fval |= SP3[(work >> 16) & 0x3fL];
381
		fval |= SP1[(work >> 24) & 0x3fL];
382
		work  = leftt ^ *keys++;
383
		fval |= SP8[ work		 & 0x3fL];
384
		fval |= SP6[(work >>  8) & 0x3fL];
385
		fval |= SP4[(work >> 16) & 0x3fL];
386
		fval |= SP2[(work >> 24) & 0x3fL];
387
		right ^= fval;
388
		}
389
390
	right = (right << 31) | (right >> 1);
391
	work = (leftt ^ right) & 0xaaaaaaaaL;
392
	leftt ^= work;
393
	right ^= work;
394
	leftt = (leftt << 31) | (leftt >> 1);
395
	work = ((leftt >> 8) ^ right) & 0x00ff00ffL;
396
	right ^= work;
397
	leftt ^= (work << 8);
398
	work = ((leftt >> 2) ^ right) & 0x33333333L;
399
	right ^= work;
400
	leftt ^= (work << 2);
401
	work = ((right >> 16) ^ leftt) & 0x0000ffffL;
402
	leftt ^= work;
403
	right ^= (work << 16);
404
	work = ((right >> 4) ^ leftt) & 0x0f0f0f0fL;
405
	leftt ^= work;
406
	right ^= (work << 4);
407
	*block++ = right;
408
	*block = leftt;
409
	return;
410
	}
411
412
/* Validation sets:
413
 *
414
 * Single-length key, single-length plaintext -
415
 * Key	  : 0123 4567 89ab cdef
416
 * Plain  : 0123 4567 89ab cde7
417
 * Cipher : c957 4425 6a5e d31d
418
 *
419
 * Double-length key, single-length plaintext -
420
 * Key	  : 0123 4567 89ab cdef fedc ba98 7654 3210
421
 * Plain  : 0123 4567 89ab cde7
422
 * Cipher : 7f1d 0a77 826b 8aff
423
 *
424
 * Double-length key, double-length plaintext -
425
 * Key	  : 0123 4567 89ab cdef fedc ba98 7654 3210
426
 * Plain  : 0123 4567 89ab cdef 0123 4567 89ab cdff
427
 * Cipher : 27a0 8440 406a df60 278f 47cf 42d6 15d7
428
 *
429
 * Triple-length key, single-length plaintext -
430
 * Key	  : 0123 4567 89ab cdef fedc ba98 7654 3210 89ab cdef 0123 4567
431
 * Plain  : 0123 4567 89ab cde7
432
 * Cipher : de0b 7c06 ae5e 0ed5
433
 *
434
 * Triple-length key, double-length plaintext -
435
 * Key	  : 0123 4567 89ab cdef fedc ba98 7654 3210 89ab cdef 0123 4567
436
 * Plain  : 0123 4567 89ab cdef 0123 4567 89ab cdff
437
 * Cipher : ad0d 1b30 ac17 cf07 0ed1 1c63 81e4 4de5
438
 *
439
 * d3des V5.0a rwo 9208.07 18:44 Graven Imagery
440
 **********************************************************************/
(-)tdenetwork-trinity-14.1.0-ORIG/krdc/vnc/d3des.h (+51 lines)
Line 0 Link Here
1
/*
2
 * This is D3DES (V5.09) by Richard Outerbridge with the double and
3
 * triple-length support removed for use in VNC.
4
 *
5
 * These changes are:
6
 *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
7
 *
8
 * This software is distributed in the hope that it will be useful,
9
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11
 */
12
13
/* d3des.h -
14
 *
15
 *	Headers and defines for d3des.c
16
 *	Graven Imagery, 1992.
17
 *
18
 * Copyright (c) 1988,1989,1990,1991,1992 by Richard Outerbridge
19
 *	(GEnie : OUTER; CIS : [71755,204])
20
 */
21
22
#define EN0	0	/* MODE == encrypt */
23
#define DE1	1	/* MODE == decrypt */
24
25
extern void deskey(unsigned char *, int);
26
/*		      hexkey[8]     MODE
27
 * Sets the internal key register according to the hexadecimal
28
 * key contained in the 8 bytes of hexkey, according to the DES,
29
 * for encryption or decryption according to MODE.
30
 */
31
32
extern void usekey(unsigned long *);
33
/*		    cookedkey[32]
34
 * Loads the internal key register with the data in cookedkey.
35
 */
36
37
extern void cpkey(unsigned long *);
38
/*		   cookedkey[32]
39
 * Copies the contents of the internal key register into the storage
40
 * located at &cookedkey[0].
41
 */
42
43
extern void des(unsigned char *, unsigned char *);
44
/*		    from[8]	      to[8]
45
 * Encrypts/Decrypts (according to the key currently loaded in the
46
 * internal key register) one block of eight bytes at address 'from'
47
 * into the block at address 'to'.  They can be the same.
48
 */
49
50
/* d3des.h V5.09 rwo 9208.04 15:06 Graven Imagery
51
 ********************************************************************/
(-)tdenetwork-trinity-14.1.0-ORIG/krdc/vnc/desktop.c (+1613 lines)
Line 0 Link Here
1
/*
2
 *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
3
 *  Copyright (C) 2002 Tim Jansen. All Rights Reserved.
4
 *  Copyright (C) 1999-2001 Anders Lindstr�m
5
 * 
6
 *  
7
 *
8
 *  This is free software; you can redistribute it and/or modify
9
 *  it under the terms of the GNU General Public License as published by
10
 *  the Free Software Foundation; either version 2 of the License, or
11
 *  (at your option) any later version.
12
 *
13
 *  This software is distributed in the hope that it will be useful,
14
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 *  GNU General Public License for more details.
17
 *
18
 *  You should have received a copy of the GNU General Public License
19
 *  along with this software; if not, write to the Free Software
20
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
21
 *  USA.
22
 *
23
 * tim@tjansen.de: - removed stuff for krdc 
24
 *                 - merged with shm.c and misc.c
25
 *                 - added FillRectangle and Sync methods to draw only on 
26
 *                   the image
27
 *                 - added Zoom functionality, based on rotation funcs from
28
 *                   SGE by Anders Lindstr�m)
29
 *                 - added support for softcursor encoding
30
 *
31
 */
32
33
/*
34
 * desktop.c - functions to deal with "desktop" window.
35
 */
36
37
#include <X11/Xlib.h>
38
#include <sys/ipc.h>
39
#include <sys/shm.h>
40
#include <X11/extensions/XShm.h>
41
#include <math.h>
42
#include <limits.h>
43
#include "vncviewer.h"
44
45
static XShmSegmentInfo shminfo;
46
static Bool caughtShmError = False;
47
static Bool needShmCleanup = False;
48
49
static XShmSegmentInfo zoomshminfo;
50
static Bool caughtZoomShmError = False;
51
static Bool needZoomShmCleanup = False;
52
53
static Bool gcInited = False;
54
GC gc;
55
GC srcGC, dstGC; /* used for debugging copyrect */
56
Dimension dpyWidth, dpyHeight;
57
58
static XImage *image = NULL;
59
Bool useShm = True;
60
61
static Bool zoomActive = False;
62
static int zoomWidth, zoomHeight;
63
static XImage *zoomImage = NULL;
64
static Bool useZoomShm = True;
65
66
/* for softcursor */
67
static char *savedArea = NULL;
68
69
typedef enum {
70
  SOFTCURSOR_UNDER,
71
  SOFTCURSOR_PART_UNDER,
72
  SOFTCURSOR_UNAFFECTED
73
} SoftCursorState;
74
75
typedef int Sint32;
76
typedef short Sint16;
77
typedef char Sint8;
78
typedef unsigned int Uint32;
79
typedef unsigned short Uint16;
80
typedef unsigned char Uint8;
81
82
typedef struct {
83
  int w, h;
84
  unsigned int pitch;
85
  void *pixels;
86
  int BytesPerPixel;
87
} Surface;
88
89
typedef struct {
90
        Sint16 x, y;
91
        Uint16 w, h;
92
} Rect;
93
94
static void bgr233cpy(CARD8 *dst, CARD8 *src, int len);
95
static void CopyDataToScreenRaw(char *buf, int x, int y, int width, int height);
96
static void CopyBGR233ToScreen(CARD8 *buf, int x, int y, int width,int height);
97
static void FillRectangleBGR233(CARD8 buf, int x, int y, int width,int height);
98
static int CheckRectangle(int x, int y, int width, int height);
99
static SoftCursorState getSoftCursorState(int x, int y, int width, int height);
100
static void discardCursorSavedArea(void);
101
static void saveCursorSavedArea(void);
102
103
static void ZoomInit(void);
104
static void transformZoomSrc(int six, int siy, int siw, int sih,
105
			     int *dix, int *diy, int *diw, int *dih,
106
			     int srcW, int dstW, int srcH, int dstH);
107
static void transformZoomDst(int *six, int *siy, int *siw, int *sih,
108
			     int dix, int diy, int diw, int dih,
109
			     int srcW, int dstW, int srcH, int dstH);
110
static void ZoomSurfaceSrcCoords(int x, int y, int w, int h, 
111
				 int *dix, int *diy, int *diw, int *dih,
112
				 Surface * src, Surface * dst);
113
static void ZoomSurfaceCoords32(int sx, int sy, int sw, int sh,
114
				int dx, int dy, Surface * src, Surface * dst);
115
static void sge_transform(Surface *src, Surface *dst, float xscale, float yscale,
116
			  Uint16 qx, Uint16 qy);
117
118
119
void
120
DesktopInit(Window win)
121
{
122
  XGCValues gcv;
123
124
  image = CreateShmImage();
125
126
  if (!image) {
127
    useShm = False;
128
    image = XCreateImage(dpy, vis, visdepth, ZPixmap, 0, NULL,
129
			 si.framebufferWidth, si.framebufferHeight,
130
			 BitmapPad(dpy), 0);
131
132
    image->data = calloc(image->bytes_per_line * image->height, 1);
133
    if (!image->data) {
134
      fprintf(stderr,"malloc failed\n");
135
      exit(1);
136
    }
137
  }
138
139
  gc = XCreateGC(dpy,win,0,NULL);
140
141
  gcv.function = GXxor;
142
  gcv.foreground = 0x0f0f0f0f;
143
  srcGC = XCreateGC(dpy,win,GCFunction|GCForeground,&gcv);
144
  gcv.foreground = 0xf0f0f0f0;
145
  dstGC = XCreateGC(dpy,win,GCFunction|GCForeground,&gcv);
146
  gcInited = True;
147
}
148
149
/*
150
 * DrawScreenRegionX11Thread
151
 * Never call from any other desktop.c function, only for X11 thread
152
 */
153
154
void
155
DrawScreenRegionX11Thread(Window win, int x, int y, int width, int height) {
156
  zoomActive = False;
157
  zoomWidth = 0;
158
  zoomHeight = 0;
159
160
  if (!image)
161
    return;
162
163
  if (useShm) 
164
    XShmPutImage(dpy, win, gc, image, x, y, x, y, width, height, False);
165
  else
166
    XPutImage(dpy, win, gc, image, x, y, x, y, width, height);
167
}
168
169
/*
170
 * CheckRectangle
171
 */
172
173
static int CheckRectangle(int x, int y, int width, int height) {
174
  if ((x < 0) || (y < 0))
175
    return 0;
176
177
  if (((x+width) > si.framebufferWidth) || ((y+height) > si.framebufferHeight))
178
    return 0;
179
180
  return 1;
181
}
182
183
static 
184
void bgr233cpy(CARD8 *dst, CARD8 *src, int len) {
185
  int i;
186
  CARD16 *d16;
187
  CARD32 *d32;
188
189
  switch (visbpp) {
190
  case 8:
191
    for (i = 0; i < len; i++) 
192
      *(dst++) = (CARD8) BGR233ToPixel[*(src++)];
193
    break;
194
  case 16:
195
    d16 = (CARD16*) dst;
196
    for (i = 0; i < len; i++) 
197
      *(d16++) = (CARD16) BGR233ToPixel[*(src++)];
198
    break;
199
  case 32:
200
    d32 = (CARD32*) dst;
201
    for (i = 0; i < len; i++) 
202
      *(d32++) = (CARD32) BGR233ToPixel[*(src++)];
203
    break;
204
  default:
205
    fprintf(stderr, "Unsupported softcursor depth %d\n", visbpp);
206
  }
207
}
208
209
210
/*
211
 * CopyDataToScreen.
212
 */
213
214
void
215
CopyDataToScreen(char *buf, int x, int y, int width, int height)
216
{
217
  SoftCursorState s;
218
219
  if (!CheckRectangle(x, y, width, height))
220
    return;
221
222
  LockFramebuffer();
223
  s = getSoftCursorState(x, y, width, height);
224
  if (s == SOFTCURSOR_PART_UNDER)
225
    undrawCursor();
226
227
  if (!appData.useBGR233)
228
    CopyDataToScreenRaw(buf, x, y, width, height);
229
  else
230
    CopyBGR233ToScreen((CARD8 *)buf, x, y, width, height);
231
232
  if (s != SOFTCURSOR_UNAFFECTED)
233
    drawCursor();
234
235
  UnlockFramebuffer();
236
  SyncScreenRegion(x, y, width, height);
237
}
238
239
/*
240
 * CopyDataToScreenRaw.
241
 */
242
243
static void
244
CopyDataToScreenRaw(char *buf, int x, int y, int width, int height)
245
{
246
  int h;
247
  int widthInBytes = width * visbpp / 8;
248
  int scrWidthInBytes = image->bytes_per_line;
249
  char *scr = (image->data + y * scrWidthInBytes
250
	       + x * visbpp / 8);
251
  
252
  for (h = 0; h < height; h++) {
253
    memcpy(scr, buf, widthInBytes);
254
    buf += widthInBytes;
255
    scr += scrWidthInBytes;
256
  }
257
}
258
259
/*
260
 * CopyBGR233ToScreen.
261
 */
262
263
static void
264
CopyBGR233ToScreen(CARD8 *buf, int x, int y, int width, int height)
265
{
266
  int p, q;
267
  int xoff = 7 - (x & 7);
268
  int xcur;
269
  int fbwb = si.framebufferWidth / 8;
270
  CARD8 *scr1 = ((CARD8 *)image->data) + y * fbwb + x / 8;
271
  CARD8 *scrt;
272
  CARD8 *scr8 = ((CARD8 *)image->data) + y * si.framebufferWidth + x;
273
  CARD16 *scr16 = ((CARD16 *)image->data) + y * si.framebufferWidth + x;
274
  CARD32 *scr32 = ((CARD32 *)image->data) + y * si.framebufferWidth + x;
275
276
  switch (visbpp) {
277
278
    /* thanks to Chris Hooper for single bpp support */
279
280
  case 1:
281
    for (q = 0; q < height; q++) {
282
      xcur = xoff;
283
      scrt = scr1;
284
      for (p = 0; p < width; p++) {
285
	*scrt = ((*scrt & ~(1 << xcur))
286
		 | (BGR233ToPixel[*(buf++)] << xcur));
287
288
	if (xcur-- == 0) {
289
	  xcur = 7;
290
	  scrt++;
291
	}
292
      }
293
      scr1 += fbwb;
294
    }
295
    break;
296
297
  case 8:
298
    for (q = 0; q < height; q++) {
299
      for (p = 0; p < width; p++) {
300
	*(scr8++) = BGR233ToPixel[*(buf++)];
301
      }
302
      scr8 += si.framebufferWidth - width;
303
    }
304
    break;
305
306
  case 16:
307
    for (q = 0; q < height; q++) {
308
      for (p = 0; p < width; p++) {
309
	*(scr16++) = BGR233ToPixel[*(buf++)];
310
      }
311
      scr16 += si.framebufferWidth - width;
312
    }
313
    break;
314
315
  case 32:
316
    for (q = 0; q < height; q++) {
317
      for (p = 0; p < width; p++) {
318
	*(scr32++) = BGR233ToPixel[*(buf++)];
319
      }
320
      scr32 += si.framebufferWidth - width;
321
    }
322
    break;
323
  }
324
}
325
326
/*
327
 * FillRectangle8.
328
 */
329
330
void
331
FillRectangle8(CARD8 fg, int x, int y, int width, int height)
332
{
333
  SoftCursorState s;
334
335
  if (!CheckRectangle(x, y, width, height))
336
    return;
337
338
  s = getSoftCursorState(x, y, width, height);
339
  if (s == SOFTCURSOR_PART_UNDER)
340
    undrawCursor();
341
342
  if (!appData.useBGR233) {
343
    int h;
344
    int widthInBytes = width * visbpp / 8;
345
    int scrWidthInBytes = image->bytes_per_line;
346
347
    char *scr = (image->data + y * scrWidthInBytes
348
		 + x * visbpp / 8);
349
350
    for (h = 0; h < height; h++) {
351
      memset(scr, fg, widthInBytes);
352
      scr += scrWidthInBytes;
353
    }
354
  } else {
355
    FillRectangleBGR233(fg, x, y, width, height);
356
  }
357
358
  if (s != SOFTCURSOR_UNAFFECTED)
359
    drawCursor();
360
}
361
362
/*
363
 * FillRectangleBGR233.
364
 */
365
366
static void
367
FillRectangleBGR233(CARD8 fg, int x, int y, int width, int height)
368
{
369
  int p, q;
370
  int xoff = 7 - (x & 7);
371
  int xcur;
372
  int fbwb = si.framebufferWidth / 8;
373
  CARD8 *scr1 = ((CARD8 *)image->data) + y * fbwb + x / 8;
374
  CARD8 *scrt;
375
  CARD8 *scr8 = ((CARD8 *)image->data) + y * si.framebufferWidth + x;
376
  CARD16 *scr16 = ((CARD16 *)image->data) + y * si.framebufferWidth + x;
377
  CARD32 *scr32 = ((CARD32 *)image->data) + y * si.framebufferWidth + x;
378
379
  unsigned long fg233 = BGR233ToPixel[fg];
380
381
  switch (visbpp) {
382
383
    /* thanks to Chris Hooper for single bpp support */
384
385
  case 1:
386
    for (q = 0; q < height; q++) {
387
      xcur = xoff;
388
      scrt = scr1;
389
      for (p = 0; p < width; p++) {
390
	*scrt = ((*scrt & ~(1 << xcur))
391
		 | (fg233 << xcur));
392
393
	if (xcur-- == 0) {
394
	  xcur = 7;
395
	  scrt++;
396
	}
397
      }
398
      scr1 += fbwb;
399
    }
400
    break;
401
402
  case 8:
403
    for (q = 0; q < height; q++) {
404
      for (p = 0; p < width; p++) {
405
	*(scr8++) = fg233;
406
      }
407
      scr8 += si.framebufferWidth - width;
408
    }
409
    break;
410
411
  case 16:
412
    for (q = 0; q < height; q++) {
413
      for (p = 0; p < width; p++) {
414
	*(scr16++) = fg233;
415
      }
416
      scr16 += si.framebufferWidth - width;
417
    }
418
    break;
419
420
  case 32:
421
    for (q = 0; q < height; q++) {
422
      for (p = 0; p < width; p++) {
423
	*(scr32++) = fg233;
424
      }
425
      scr32 += si.framebufferWidth - width;
426
    }
427
    break;
428
  }
429
}
430
431
/*
432
 * FillRectangle16
433
 */
434
435
void
436
FillRectangle16(CARD16 fg, int x, int y, int width, int height)
437
{
438
  int i, h;
439
  int scrWidthInBytes = image->bytes_per_line;
440
  
441
  char *scr = (image->data + y * scrWidthInBytes
442
	       + x * visbpp / 8);
443
  CARD16 *scr16;
444
  SoftCursorState s;
445
446
  if (!CheckRectangle(x, y, width, height))
447
    return;
448
449
  s = getSoftCursorState(x, y, width, height);
450
  if (s == SOFTCURSOR_PART_UNDER)
451
    undrawCursor();
452
453
  for (h = 0; h < height; h++) {
454
    scr16 = (CARD16*) scr;
455
    for (i = 0; i < width; i++)
456
      scr16[i] = fg;
457
    scr += scrWidthInBytes;
458
  }
459
460
  if (s != SOFTCURSOR_UNAFFECTED)
461
    drawCursor();
462
}
463
464
/*
465
 * FillRectangle32
466
 */
467
468
void
469
FillRectangle32(CARD32 fg, int x, int y, int width, int height)
470
{
471
  int i, h;
472
  int scrWidthInBytes = image->bytes_per_line;
473
  SoftCursorState s;
474
  
475
  char *scr = (image->data + y * scrWidthInBytes
476
	       + x * visbpp / 8);
477
  CARD32 *scr32;
478
479
  if (!CheckRectangle(x, y, width, height))
480
    return;
481
482
  s = getSoftCursorState(x, y, width, height);
483
  if (s == SOFTCURSOR_PART_UNDER)
484
    undrawCursor();
485
486
  for (h = 0; h < height; h++) {
487
    scr32 = (CARD32*) scr;
488
    for (i = 0; i < width; i++)
489
      scr32[i] = fg;
490
    scr += scrWidthInBytes;
491
  }
492
493
  if (s != SOFTCURSOR_UNAFFECTED)
494
    drawCursor();
495
}
496
497
/*
498
 * CopyDataFromScreen.
499
 */
500
501
void
502
CopyDataFromScreen(char *buf, int x, int y, int width, int height)
503
{
504
  int widthInBytes = width * visbpp / 8;
505
  int scrWidthInBytes = image->bytes_per_line;
506
  char *src = (image->data + y * scrWidthInBytes
507
	       + x * visbpp / 8);
508
  int h;
509
510
  if (!CheckRectangle(x, y, width, height))
511
    return;
512
513
  for (h = 0; h < height; h++) {
514
    memcpy(buf, src, widthInBytes);
515
    src += scrWidthInBytes;
516
    buf += widthInBytes;
517
  }
518
}
519
520
/*
521
 * CopyArea
522
 */
523
524
void
525
CopyArea(int srcX, int srcY, int width, int height, int x, int y)
526
{
527
  int widthInBytes = width * visbpp / 8;
528
  SoftCursorState sSrc, sDst;
529
530
  LockFramebuffer();
531
  sSrc = getSoftCursorState(srcX, srcY, width, height);
532
  sDst = getSoftCursorState(x, y, width, height);
533
  if ((sSrc != SOFTCURSOR_UNAFFECTED) ||
534
      (sDst == SOFTCURSOR_PART_UNDER))
535
    undrawCursor();
536
537
  if ((srcY+height < y) || (y+height < srcY) ||
538
      (srcX+width  < x) || (x+width  < srcX)) {
539
540
    int scrWidthInBytes = image->bytes_per_line;
541
    char *src = (image->data + srcY * scrWidthInBytes
542
		 + srcX * visbpp / 8);
543
    char *dst = (image->data + y * scrWidthInBytes
544
		 + x * visbpp / 8);
545
    int h;
546
547
    if (!CheckRectangle(srcX, srcY, width, height)) {
548
      UnlockFramebuffer();
549
      return;
550
    }
551
    if (!CheckRectangle(x, y, width, height)) {
552
      UnlockFramebuffer();
553
      return;
554
    }
555
      
556
    for (h = 0; h < height; h++) {
557
      memcpy(dst, src, widthInBytes);
558
      src += scrWidthInBytes;
559
      dst += scrWidthInBytes;
560
    }
561
  }
562
  else { 
563
    char *buf = malloc(widthInBytes*height);
564
    if (!buf) {
565
      UnlockFramebuffer();
566
      fprintf(stderr, "Out of memory, CopyArea impossible\n");
567
      return;
568
    }
569
    CopyDataFromScreen(buf, srcX, srcY, width, height);
570
    CopyDataToScreenRaw(buf, x, y, width, height);
571
    free(buf);
572
  }
573
  if ((sSrc != SOFTCURSOR_UNAFFECTED) ||
574
      (sDst != SOFTCURSOR_UNAFFECTED))
575
    drawCursor();
576
  UnlockFramebuffer();
577
  SyncScreenRegion(x, y, width, height);
578
}
579
580
void SyncScreenRegion(int x, int y, int width, int height) {
581
  int dx, dy, dw, dh; 
582
583
  if (zoomActive) {
584
    Surface src, dest;
585
    src.w = si.framebufferWidth;
586
    src.h = si.framebufferHeight;
587
    src.pitch = image->bytes_per_line;
588
    src.pixels = image->data;
589
    src.BytesPerPixel = visbpp / 8;
590
    dest.w = zoomWidth;
591
    dest.h = zoomHeight;
592
    dest.pitch = zoomImage->bytes_per_line;
593
    dest.pixels = zoomImage->data;
594
    dest.BytesPerPixel = visbpp / 8;
595
    ZoomSurfaceSrcCoords(x, y, width, height, &dx, &dy, &dw, &dh, &src, &dest);
596
  }
597
  else {
598
    dx = x; dy = y;
599
    dw = width; dh = height;
600
  }
601
  DrawScreenRegion(dx, dy, dw, dh);
602
}
603
604
void SyncScreenRegionX11Thread(int x, int y, int width, int height) {
605
  int dx, dy, dw, dh; 
606
607
  if (zoomActive) {
608
    Surface src, dest;
609
    src.w = si.framebufferWidth;
610
    src.h = si.framebufferHeight;
611
    src.pitch = image->bytes_per_line;
612
    src.pixels = image->data;
613
    src.BytesPerPixel = visbpp / 8;
614
    dest.w = zoomWidth;
615
    dest.h = zoomHeight;
616
    dest.pitch = zoomImage->bytes_per_line;
617
    dest.pixels = zoomImage->data;
618
    dest.BytesPerPixel = visbpp / 8;
619
    ZoomSurfaceSrcCoords(x, y, width, height, &dx, &dy, &dw, &dh, &src, &dest);
620
  }
621
  else {
622
    dx = x; dy = y;
623
    dw = width; dh = height;
624
  }
625
  DrawAnyScreenRegionX11Thread(dx, dy, dw, dh);
626
}
627
628
/*
629
 * ToplevelInitBeforeRealization sets the title, geometry and other resources
630
 * on the toplevel window.
631
 */
632
633
void
634
ToplevelInit()
635
{
636
  dpyWidth = WidthOfScreen(DefaultScreenOfDisplay(dpy));
637
  dpyHeight = HeightOfScreen(DefaultScreenOfDisplay(dpy));
638
}
639
640
/*
641
 * Cleanup - perform shm cleanup operations prior to exiting.
642
 */
643
644
void
645
Cleanup()
646
{
647
  if (useShm || useZoomShm)
648
    ShmCleanup();
649
}
650
651
void
652
ShmCleanup()
653
{
654
  fprintf(stderr,"ShmCleanup called\n");
655
  if (needShmCleanup) {
656
    shmdt(shminfo.shmaddr);
657
    shmctl(shminfo.shmid, IPC_RMID, 0);
658
    needShmCleanup = False;
659
  }
660
  if (needZoomShmCleanup) {
661
    shmdt(zoomshminfo.shmaddr);
662
    shmctl(zoomshminfo.shmid, IPC_RMID, 0);
663
    needZoomShmCleanup = False;
664
  }
665
}
666
667
static int
668
ShmCreationXErrorHandler(Display *d, XErrorEvent *e)
669
{
670
  caughtShmError = True;
671
  return 0;
672
}
673
674
XImage *
675
CreateShmImage()
676
{
677
  XImage *_image;
678
  XErrorHandler oldXErrorHandler;
679
680
  if (!XShmQueryExtension(dpy))
681
    return NULL;
682
683
  _image = XShmCreateImage(dpy, vis, visdepth, ZPixmap, NULL, &shminfo,
684
			  si.framebufferWidth, si.framebufferHeight);
685
  if (!_image) return NULL;
686
687
  shminfo.shmid = shmget(IPC_PRIVATE,
688
			 _image->bytes_per_line * _image->height,
689
			 IPC_CREAT|0777);
690
691
  if (shminfo.shmid == -1) {
692
    XDestroyImage(_image);
693
    return NULL;
694
  }
695
696
  shminfo.shmaddr = _image->data = shmat(shminfo.shmid, 0, 0);
697
698
  if (shminfo.shmaddr == (char *)-1) {
699
    XDestroyImage(_image);
700
    shmctl(shminfo.shmid, IPC_RMID, 0);
701
    return NULL;
702
  }
703
704
  shminfo.readOnly = True;
705
706
  oldXErrorHandler = XSetErrorHandler(ShmCreationXErrorHandler);
707
  XShmAttach(dpy, &shminfo);
708
  XSync(dpy, False);
709
  XSetErrorHandler(oldXErrorHandler);
710
711
  if (caughtShmError) {
712
    XDestroyImage(_image);
713
    shmdt(shminfo.shmaddr);
714
    shmctl(shminfo.shmid, IPC_RMID, 0);
715
    return NULL;
716
  }
717
718
  needShmCleanup = True;
719
720
  fprintf(stderr,"Using shared memory PutImage\n");
721
722
  return _image;
723
}
724
725
void undrawCursor() {
726
  int x, y, w, h;
727
  
728
  if ((imageIndex < 0) || !savedArea)
729
    return;
730
731
  getBoundingRectCursor(cursorX, cursorY, imageIndex,
732
			&x, &y, &w, &h);
733
734
  if ((w < 1) || (h < 1))
735
    return;
736
737
  CopyDataToScreenRaw(savedArea, x, y, w, h);
738
  discardCursorSavedArea();
739
}
740
741
static void drawCursorImage() {
742
  int x, y, w, h, pw, pixelsLeft, processingMask;
743
  int skipLeft, skipRight;
744
  PointerImage *pi = &pointerImages[imageIndex];
745
  CARD8 *img = (CARD8*) pi->image;
746
  CARD8 *imgEnd = &img[pi->len];
747
  CARD8 *fb;
748
749
  /* check whether the source image has ended (image broken) */
750
#define CHECK_IMG(x) if (&img[x] > imgEnd) goto imgError
751
752
/* check whether the end of the framebuffer has been reached (last line) */
753
#define CHECK_END()  if ((wl == 0) && (h == 1)) return
754
755
/* skip x pixels in the source (x must be < pixelsLeft!) */
756
#define SKIP_IMG(x)  if ((x > 0) && !processingMask) { \
757
      CHECK_END();   \
758
      img += pw * x; \
759
      CHECK_IMG(0);  \
760
   }
761
762
/* skip x pixels in source and destination */
763
#define SKIP_PIXELS(x) { int wl = x; \
764
    while (pixelsLeft <= wl) { \
765
      wl -= pixelsLeft;        \
766
      SKIP_IMG(pixelsLeft);    \
767
      CHECK_END();             \
768
      pixelsLeft = *(img++);   \
769
      CHECK_IMG(0);            \
770
      processingMask = processingMask ? 0 : 1; \
771
    }                          \
772
    pixelsLeft -= wl;          \
773
    SKIP_IMG(wl);              \
774
  }
775
776
  if (!img)
777
    return;
778
779
  x = cursorX - pi->hotX;
780
  y = cursorY - pi->hotY;
781
  w = pi->w;
782
  h = pi->h;
783
784
  if (!rectsIntersect(x, y, w, h, 
785
		      0, 0, si.framebufferWidth, si.framebufferHeight)) {
786
    fprintf(stderr, "intersect abort\n");
787
    return;
788
  }
789
790
  pw = myFormat.bitsPerPixel / 8;
791
  processingMask = 1;
792
  pixelsLeft = *(img++);
793
794
/* at this point everything is initialized for the macros */
795
796
  /* skip/clip bottom lines */
797
  if ((y+h) > si.framebufferHeight) 
798
    h = si.framebufferHeight - y;
799
800
  /* Skip invisible top lines */
801
  while (y < 0) {
802
    SKIP_PIXELS(w);
803
    y++;
804
    h--;
805
  }
806
807
  /* calculate left/right clipping */
808
  if (x < 0) {
809
    skipLeft = -x;
810
    w += x;
811
    x = 0;
812
  }
813
  else
814
    skipLeft = 0;
815
816
  if ((x+w) > si.framebufferWidth) {
817
    skipRight = (x+w) - si.framebufferWidth;
818
    w = si.framebufferWidth - x;
819
  }
820
  else
821
    skipRight = 0;
822
823
  fb = (CARD8*) image->data + y * image->bytes_per_line + x * visbpp / 8;
824
825
  /* Paint the thing */
826
  while (h > 0) {
827
    SKIP_PIXELS(skipLeft);
828
829
    {
830
      CARD8 *fbx = fb;
831
      int wl = w;
832
      while (pixelsLeft <= wl) {
833
	wl -= pixelsLeft;
834
	if ((pixelsLeft > 0) && !processingMask) {
835
	  int pl = pw * pixelsLeft;
836
	  CHECK_IMG(pl);
837
	  if (!appData.useBGR233)
838
	    memcpy(fbx, img, pl);
839
	  else
840
	    bgr233cpy(fbx, img, pixelsLeft);
841
	  img += pl;
842
	}
843
844
        CHECK_END();
845
	fbx += pixelsLeft * visbpp / 8;
846
	pixelsLeft = *(img++);
847
848
	CHECK_IMG(0);
849
	processingMask = processingMask ? 0 : 1;
850
      }
851
      pixelsLeft -= wl;
852
      if ((wl > 0) && !processingMask) {
853
	int pl = pw * wl;
854
	CHECK_IMG(pl);
855
	if (!appData.useBGR233)
856
	  memcpy(fbx, img, pl);
857
	else
858
	  bgr233cpy(fbx, img, wl);
859
	img += pl;
860
      }
861
    }
862
863
    SKIP_PIXELS(skipRight);
864
    fb += image->bytes_per_line;
865
    h--;
866
  }
867
  return;
868
869
imgError:
870
  fprintf(stderr, "Error in softcursor image %d\n", imageIndex);
871
  pointerImages[imageIndex].set = 0;
872
}
873
874
static void discardCursorSavedArea() {
875
  if (savedArea)
876
    free(savedArea);
877
  savedArea = 0;
878
}
879
880
static void saveCursorSavedArea() {
881
  int x, y, w, h;
882
883
  if (imageIndex < 0)
884
    return;
885
  getBoundingRectCursor(cursorX, cursorY, imageIndex,
886
			&x, &y, &w, &h);
887
  if ((w < 1) || (h < 1))
888
    return;
889
  discardCursorSavedArea();
890
  savedArea = malloc(h*image->bytes_per_line);
891
  if (!savedArea) {
892
    fprintf(stderr,"malloc failed, saving cursor not possible\n");
893
    exit(1);
894
  }
895
  CopyDataFromScreen(savedArea, x, y, w, h);  
896
}
897
898
void drawCursor() {
899
  saveCursorSavedArea();
900
  drawCursorImage();
901
}
902
903
void getBoundingRectCursor(int cx, int cy, int _imageIndex,
904
			   int *x, int *y, int *w, int *h) {
905
  int nx, ny, nw, nh;
906
907
  if ((_imageIndex < 0) || !pointerImages[_imageIndex].set) {
908
    *x = 0;
909
    *y = 0;
910
    *w = 0;
911
    *h = 0;
912
    return;
913
  }
914
915
  nx = cx - pointerImages[_imageIndex].hotX;
916
  ny = cy - pointerImages[_imageIndex].hotY;
917
  nw = pointerImages[_imageIndex].w;
918
  nh = pointerImages[_imageIndex].h;
919
  if (nx < 0) {
920
    nw += nx;
921
    nx = 0;
922
  }
923
  if (ny < 0) {
924
    nh += ny;
925
    ny = 0;
926
  }
927
  if ((nx+nw) > si.framebufferWidth)
928
    nw = si.framebufferWidth - nx;
929
  if ((ny+nh) > si.framebufferHeight)
930
    nh = si.framebufferHeight - ny;
931
  if ((nw <= 0) || (nh <= 0)) {
932
    *x = 0;
933
    *y = 0;
934
    *w = 0;
935
    *h = 0;
936
    return;
937
  }
938
939
  *x = nx;
940
  *y = ny;
941
  *w = nw;
942
  *h = nh;
943
}
944
945
static SoftCursorState getSoftCursorState(int x, int y, int w, int h) {
946
  int cx, cy, cw, ch;
947
948
  if (imageIndex < 0)
949
    return SOFTCURSOR_UNAFFECTED;
950
951
  getBoundingRectCursor(cursorX, cursorY, imageIndex,
952
			&cx, &cy, &cw, &ch);
953
954
  if ((cw == 0) || (ch == 0))
955
    return SOFTCURSOR_UNAFFECTED;
956
957
  if (!rectsIntersect(x, y, w, h, cx, cy, cw, ch))
958
    return SOFTCURSOR_UNAFFECTED;
959
  if (rectContains(x, y, w, h, cx, cy, cw, ch))
960
    return SOFTCURSOR_UNDER;
961
  else
962
    return SOFTCURSOR_PART_UNDER;
963
}
964
965
int rectsIntersect(int x, int y, int w, int h, 
966
		   int x2, int y2, int w2, int h2) {
967
  if (x2 >= (x+w))
968
    return 0;
969
  if (y2 >= (y+h))
970
    return 0;
971
  if ((x2+w2) <= x)
972
    return 0;
973
  if ((y2+h2) <= y)
974
    return 0;
975
  return 1;
976
}
977
978
int rectContains(int outX, int outY, int outW, int outH, 
979
		 int inX, int inY, int inW, int inH) {
980
  if (inX < outX)
981
    return 0;
982
  if (inY < outY)
983
    return 0;
984
  if ((inX+inW) > (outX+outW))
985
    return 0;
986
  if ((inY+inH) > (outY+outH))
987
    return 0;
988
  return 1;
989
}
990
991
void rectsJoin(int *nx1, int *ny1, int *nw1, int *nh1, 
992
	       int x2, int y2, int w2, int h2) {
993
  int ox, oy, ow, oh;
994
  ox = *nx1;
995
  oy = *ny1;
996
  ow = *nw1;
997
  oh = *nh1;
998
  
999
  if (x2 < ox) {
1000
    ow += ox - x2;
1001
    ox = x2;
1002
  }
1003
  if (y2 < oy) {
1004
    oh += oy - y2;
1005
    oy = y2;
1006
  }
1007
  if ((x2+w2) > (ox+ow))
1008
    ow = (x2+w2) - ox;
1009
  if ((y2+h2) > (oy+oh))
1010
    oh = (y2+h2) - oy;
1011
1012
  *nx1 = ox;
1013
  *ny1 = oy;
1014
  *nw1 = ow;
1015
  *nh1 = oh;
1016
}
1017
1018
XImage *
1019
CreateShmZoomImage()
1020
{
1021
  XImage *_image;
1022
  XErrorHandler oldXErrorHandler;
1023
1024
  if (!XShmQueryExtension(dpy))
1025
    return NULL;
1026
1027
  _image = XShmCreateImage(dpy, vis, visdepth, ZPixmap, NULL, &zoomshminfo,
1028
			  si.framebufferWidth, si.framebufferHeight);
1029
  if (!_image) return NULL;
1030
1031
  zoomshminfo.shmid = shmget(IPC_PRIVATE,
1032
			     _image->bytes_per_line * _image->height,
1033
			     IPC_CREAT|0777);
1034
1035
  if (zoomshminfo.shmid == -1) {
1036
    XDestroyImage(_image);
1037
    return NULL;
1038
  }
1039
1040
  zoomshminfo.shmaddr = _image->data = shmat(zoomshminfo.shmid, 0, 0);
1041
1042
  if (zoomshminfo.shmaddr == (char *)-1) {
1043
    XDestroyImage(_image);
1044
    shmctl(zoomshminfo.shmid, IPC_RMID, 0);
1045
    return NULL;
1046
  }
1047
1048
  zoomshminfo.readOnly = True;
1049
1050
  oldXErrorHandler = XSetErrorHandler(ShmCreationXErrorHandler);
1051
  XShmAttach(dpy, &zoomshminfo);
1052
  XSync(dpy, False);
1053
  XSetErrorHandler(oldXErrorHandler);
1054
1055
  if (caughtZoomShmError) {
1056
    XDestroyImage(_image);
1057
    shmdt(zoomshminfo.shmaddr);
1058
    shmctl(zoomshminfo.shmid, IPC_RMID, 0);
1059
    return NULL;
1060
  }
1061
1062
  needZoomShmCleanup = True;
1063
1064
  fprintf(stderr,"Using shared memory PutImage\n");
1065
1066
  return _image;
1067
}
1068
1069
1070
/*
1071
 * DrawZoomedScreenRegionX11Thread
1072
 * Never call from any other desktop.c function, only for X11 thread
1073
 */
1074
1075
void
1076
DrawZoomedScreenRegionX11Thread(Window win, int zwidth, int zheight, 
1077
				int x, int y, int width, int height) {
1078
  if (!image)
1079
    return;				
1080
				
1081
  if (zwidth > si.framebufferWidth)
1082
    zwidth = si.framebufferWidth;
1083
  if (zheight > si.framebufferHeight)
1084
    zheight = si.framebufferHeight;
1085
  
1086
  if (!zoomActive) {
1087
    ZoomInit();
1088
    zoomActive = True;
1089
  }
1090
  
1091
  if ((zoomWidth != zwidth) || (zoomHeight != zheight)) {
1092
    Surface src, dest;
1093
1094
    zoomWidth = zwidth;
1095
    zoomHeight = zheight;
1096
  
1097
    src.w = si.framebufferWidth;
1098
    src.h = si.framebufferHeight;
1099
    src.pitch = image->bytes_per_line;
1100
    src.pixels = image->data;
1101
    src.BytesPerPixel = visbpp / 8;
1102
    dest.w = zwidth;
1103
    dest.h = zheight;
1104
    dest.pitch = zoomImage->bytes_per_line;
1105
    dest.pixels = zoomImage->data;
1106
    dest.BytesPerPixel = visbpp / 8;
1107
    sge_transform(&src, &dest,  
1108
		  (float)dest.w/(float)src.w, (float)dest.h/(float)src.h,
1109
		  0, 0);
1110
1111
    if (useZoomShm) 
1112
      XShmPutImage(dpy, win, gc, zoomImage, 0, 0, 0, 0, zwidth, zheight, False);
1113
    else
1114
      XPutImage(dpy, win, gc, zoomImage, 0, 0, 0, 0, zwidth, zheight);
1115
    return;
1116
  }
1117
1118
  if (useZoomShm) 
1119
    XShmPutImage(dpy, win, gc, zoomImage, x, y, x, y, width, height, False);
1120
  else
1121
    XPutImage(dpy, win, gc, zoomImage, x, y, x, y, width, height);
1122
}
1123
1124
1125
static void
1126
ZoomInit()
1127
{
1128
  if (zoomImage)
1129
    return;
1130
1131
   zoomImage = CreateShmZoomImage(); 
1132
1133
  if (!zoomImage) {
1134
    useZoomShm = False;
1135
    zoomImage = XCreateImage(dpy, vis, visdepth, ZPixmap, 0, NULL,
1136
			     si.framebufferWidth, si.framebufferHeight,
1137
			     BitmapPad(dpy), 0);
1138
1139
    zoomImage->data = calloc(zoomImage->bytes_per_line * zoomImage->height, 1);
1140
    if (!zoomImage->data) {
1141
      fprintf(stderr,"malloc failed\n");
1142
      exit(1);
1143
    }
1144
  }
1145
}
1146
1147
static void transformZoomSrc(int six, int siy, int siw, int sih,
1148
			     int *dix, int *diy, int *diw, int *dih,
1149
			     int srcW, int dstW, int srcH, int dstH) {
1150
  double sx, sy, sw, sh;
1151
  double dx, dy, dw, dh;
1152
  double wq, hq;
1153
1154
  sx = six; sy = siy;
1155
  sw = siw; sh = sih;
1156
1157
  wq = ((double)dstW) / (double) srcW;
1158
  hq = ((double)dstH) / (double) srcH;
1159
1160
  dx = sx * wq;
1161
  dy = sy * hq;
1162
  dw = sw * wq;
1163
  dh = sh * hq;
1164
  
1165
  *dix = dx;
1166
  *diy = dy;
1167
  *diw = dw+(dx-(int)dx)+0.5;
1168
  *dih = dh+(dy-(int)dy)+0.5;
1169
}
1170
1171
static void transformZoomDst(int *six, int *siy, int *siw, int *sih,
1172
			     int dix, int diy, int diw, int dih,
1173
			     int srcW, int dstW, int srcH, int dstH) {
1174
  double sx, sy, sw, sh;
1175
  double dx, dy, dw, dh;
1176
  double wq, hq;
1177
1178
  dx = dix; dy = diy;
1179
  dw = diw; dh = dih;
1180
1181
  wq = ((double)dstW) / (double) srcW;
1182
  hq = ((double)dstH) / (double) srcH;
1183
1184
  sx = dx / wq;
1185
  sy = dy / hq;
1186
  sw = dw / wq;
1187
  sh = dh / hq;
1188
  
1189
  *six = sx;
1190
  *siy = sy;
1191
  *siw = sw+(sx-(int)sx)+0.5;
1192
  *sih = sh+(sy-(int)sy)+0.5;
1193
}
1194
1195
1196
static void ZoomSurfaceSrcCoords(int six, int siy, int siw, int sih,
1197
				 int *dix, int *diy, int *diw, int *dih,
1198
				 Surface * src, Surface * dst)
1199
{
1200
  int dx, dy, dw, dh;
1201
  int sx, sy, sw, sh;
1202
1203
  transformZoomSrc(six, siy, siw, sih,
1204
		   &dx, &dy, &dw, &dh,
1205
		   src->w, dst->w, src->h, dst->h);
1206
  dx-=2;
1207
  dy-=2;
1208
  dw+=4;
1209
  dh+=4;
1210
1211
  if (dx < 0)
1212
    dx = 0;
1213
  if (dy < 0)
1214
    dy = 0;
1215
  if (dx+dw > dst->w)
1216
    dw = dst->w - dx;
1217
  if (dy+dh > dst->h)
1218
    dh = dst->h - dy;
1219
  
1220
  transformZoomDst(&sx, &sy, &sw, &sh,
1221
		   dx, dy, dw, dh,
1222
		   src->w, dst->w, src->h, dst->h);
1223
1224
  if (sx+sw > src->w)
1225
    sw = src->w - sx;
1226
  if (sy+sh > src->h)
1227
    sh = src->h - sy;
1228
1229
  ZoomSurfaceCoords32(sx, sy, sw, sh, dx, dy, src, dst);
1230
1231
  *dix = dx;
1232
  *diy = dy;
1233
  *diw = dw;
1234
  *dih = dh;
1235
}
1236
1237
static void ZoomSurfaceCoords32(int sx, int sy, int sw, int sh,
1238
				int dx, int dy, 
1239
				Surface * src, Surface * dst)
1240
{
1241
  Surface s2;
1242
1243
  s2 = *src;
1244
  s2.pixels = ((char*)s2.pixels) + (sx * s2.BytesPerPixel) + (sy * src->pitch);
1245
  s2.w = sw;
1246
  s2.h = sh;
1247
  sge_transform(&s2, dst,  
1248
		(float)dst->w/(float)src->w, (float)dst->h/(float)src->h,
1249
		dx, dy);
1250
}
1251
1252
1253
#define sge_clip_xmin(pnt) 0
1254
#define sge_clip_xmax(pnt) pnt->w
1255
#define sge_clip_ymin(pnt) 0
1256
#define sge_clip_ymax(pnt) pnt->h
1257
1258
/*==================================================================================
1259
// Helper function to sge_transform()
1260
// Returns the bounding box
1261
//==================================================================================
1262
*/
1263
static void _calcRect(Surface *src, Surface *dst, float xscale, float yscale, 
1264
		      Uint16 qx, Uint16 qy, 
1265
		      Sint16 *xmin, Sint16 *ymin, Sint16 *xmax, Sint16 *ymax)
1266
{
1267
	Sint16 x, y, rx, ry;
1268
	int i;
1269
	
1270
	/* Clip to src surface */
1271
	Sint16 sxmin = sge_clip_xmin(src);
1272
	Sint16 sxmax = sge_clip_xmax(src);
1273
	Sint16 symin = sge_clip_ymin(src);
1274
	Sint16 symax = sge_clip_ymax(src);
1275
	Sint16 sx[5];
1276
	Sint16 sy[4];
1277
	
1278
	/* We don't really need fixed-point here
1279
	 * but why not? */
1280
	Sint32 ictx = (Sint32) (xscale * 8192.0);
1281
	Sint32 icty = (Sint32) (yscale * 8192.0);
1282
1283
	sx[0] = sxmin;
1284
	sx[1] = sxmax;
1285
	sx[2] = sxmin;
1286
	sx[3] = sxmax;
1287
	sy[0] = symin;
1288
	sy[1] = symax;
1289
	sy[2] = symax;
1290
	sy[3] = symin;
1291
1292
	/* Calculate the four corner points */
1293
	for(i=0; i<4; i++){
1294
		rx = sx[i];
1295
		ry = sy[i];
1296
		
1297
		x = (Sint16)(((ictx*rx) >> 13) + qx);
1298
		y = (Sint16)(((icty*ry) >> 13) + qy);
1299
		
1300
		
1301
		if(i==0){
1302
			*xmax = *xmin = x;
1303
			*ymax = *ymin = y;
1304
		}else{
1305
			if(x>*xmax)
1306
				*xmax=x;
1307
			else if(x<*xmin)
1308
				*xmin=x;
1309
				
1310
			if(y>*ymax)
1311
				*ymax=y;
1312
			else if(y<*ymin)
1313
				*ymin=y;
1314
		}
1315
	}
1316
	
1317
	/* Better safe than sorry...*/
1318
	*xmin -= 1;
1319
	*ymin -= 1;
1320
	*xmax += 1;
1321
	*ymax += 1;
1322
	
1323
	/* Clip to dst surface */
1324
	if( !dst )
1325
		return;
1326
	if( *xmin < sge_clip_xmin(dst) )
1327
		*xmin = sge_clip_xmin(dst);
1328
	if( *xmax > sge_clip_xmax(dst) )
1329
		*xmax = sge_clip_xmax(dst);
1330
	if( *ymin < sge_clip_ymin(dst) )
1331
		*ymin = sge_clip_ymin(dst);
1332
	if( *ymax > sge_clip_ymax(dst) )
1333
		*ymax = sge_clip_ymax(dst);
1334
}
1335
1336
1337
/*==================================================================================
1338
** Scale by scale and place at position (qx,qy). 
1339
** 
1340
**
1341
** Developed with the help from Terry Hancock (hancock@earthlink.net)
1342
**
1343
**==================================================================================*/
1344
/* First we need some macros to handle different bpp
1345
 *  I'm sorry about this... 
1346
 */
1347
#define TRANSFORM(UintXX, DIV) \
1348
	Sint32 src_pitch=src->pitch/DIV; \
1349
	Sint32 dst_pitch=dst->pitch/DIV; \
1350
	UintXX *src_row = (UintXX *)src->pixels; \
1351
	UintXX *dst_row; \
1352
\
1353
	for (y=ymin; y<ymax; y++){ \
1354
		dy = y - qy; \
1355
\
1356
		sx = (Sint32)ctdx;  /* Compute source anchor points */ \
1357
		sy = (Sint32)(cty*dy); \
1358
\
1359
		/* Calculate pointer to dst surface */ \
1360
		dst_row = (UintXX *)dst->pixels + y*dst_pitch; \
1361
\
1362
		for (x=xmin; x<xmax; x++){ \
1363
			rx=(Sint16)(sx >> 13);  /* Convert from fixed-point */ \
1364
			ry=(Sint16)(sy >> 13); \
1365
\
1366
			/* Make sure the source pixel is actually in the source image. */ \
1367
			if( (rx>=sxmin) && (rx<sxmax) && (ry>=symin) && (ry<symax) ) \
1368
				*(dst_row + x) = *(src_row + ry*src_pitch + rx); \
1369
\
1370
			sx += ctx;  /* Incremental transformations */ \
1371
		} \
1372
	}
1373
	
1374
	
1375
/* Interpolated transform */
1376
#define TRANSFORM_AA(UintXX, DIV) \
1377
	Sint32 src_pitch=src->pitch/DIV; \
1378
	Sint32 dst_pitch=dst->pitch/DIV; \
1379
	UintXX *src_row = (UintXX *)src->pixels; \
1380
	UintXX *dst_row; \
1381
	UintXX c1, c2, c3, c4;\
1382
	Uint32 R, G, B, A=0; \
1383
	UintXX Rmask = image->red_mask;\
1384
        UintXX Gmask = image->green_mask;\
1385
        UintXX Bmask = image->blue_mask;\
1386
        UintXX Amask = 0;\
1387
	Uint32 wx, wy;\
1388
	Uint32 p1, p2, p3, p4;\
1389
\
1390
	/* 
1391
	*  Interpolation:
1392
	*  We calculate the distances from our point to the four nearest pixels, d1..d4.
1393
	*  d(a,b) = sqrt(a�+b�) ~= 0.707(a+b)  (Pythagoras (Taylor) expanded around (0.5;0.5))
1394
	*  
1395
	*    1  wx 2
1396
	*     *-|-*  (+ = our point at (x,y))
1397
	*     | | |  (* = the four nearest pixels)
1398
	*  wy --+ |  wx = float(x) - int(x)
1399
	*     |   |  wy = float(y) - int(y)
1400
	*     *---*
1401
	*    3     4
1402
	*  d1 = d(wx,wy)  d2 = d(1-wx,wy)  d3 = d(wx,1-wy)  d4 = d(1-wx,1-wy)
1403
	*  We now want to weight each pixels importance - it's vicinity to our point:
1404
	*  w1=d4  w2=d3  w3=d2  w4=d1  (Yes it works... just think a bit about it)
1405
	*
1406
	*  If the pixels have the colors c1..c4 then our point should have the color
1407
	*  c = (w1*c1 + w2*c2 + w3*c3 + w4*c4)/(w1+w2+w3+w4)   (the weighted average)
1408
	*  but  w1+w2+w3+w4 = 4*0.707  so we might as well write it as
1409
	*  c = p1*c1 + p2*c2 + p3*c3 + p4*c4  where  p1..p4 = (w1..w4)/(4*0.707)
1410
	*
1411
	*  But p1..p4 are fixed point so we can just divide the fixed point constant!
1412
	*  8192/(4*0.71) = 2897  and we can skip 0.71 too (the division will cancel it everywhere)
1413
	*  8192/4 = 2048
1414
	*
1415
	*  020102: I changed the fixed-point representation for the variables in the weighted average
1416
	*          to 24.7 to avoid problems with 32bit colors. Everything else is still 18.13. This
1417
	*          does however not solve the problem with 32bit RGBA colors... 
1418
	*/\
1419
\
1420
	Sint32 one = 2048>>6;   /* 1 in Fixed-point */ \
1421
	Sint32 two = 2*2048>>6; /* 2 in Fixed-point */ \
1422
\
1423
	for (y=ymin; y<ymax; y++){ \
1424
		dy = y - qy; \
1425
\
1426
		sx = (Sint32)(ctdx);  /* Compute source anchor points */ \
1427
		sy = (Sint32)(cty*dy); \
1428
\
1429
		/* Calculate pointer to dst surface */ \
1430
		dst_row = (UintXX *)dst->pixels + y*dst_pitch; \
1431
\
1432
		for (x=xmin; x<xmax; x++){ \
1433
			rx=(Sint16)(sx >> 13);  /* Convert from fixed-point */ \
1434
			ry=(Sint16)(sy >> 13); \
1435
\
1436
			/* Make sure the source pixel is actually in the source image. */ \
1437
			if( (rx>=sxmin) && (rx+1<sxmax) && (ry>=symin) && (ry+1<symax) ){ \
1438
				wx = (sx & 0x00001FFF) >>8;  /* (float(x) - int(x)) / 4 */ \
1439
				wy = (sy & 0x00001FFF) >>8;\
1440
\
1441
				p4 = wx+wy;\
1442
				p3 = one-wx+wy;\
1443
				p2 = wx+one-wy;\
1444
				p1 = two-wx-wy;\
1445
\
1446
				c1 = *(src_row + ry*src_pitch + rx);\
1447
				c2 = *(src_row + ry*src_pitch + rx+1);\
1448
				c3 = *(src_row + (ry+1)*src_pitch + rx);\
1449
				c4 = *(src_row + (ry+1)*src_pitch + rx+1);\
1450
\
1451
				/* Calculate the average */\
1452
				R = ((p1*(c1 & Rmask) + p2*(c2 & Rmask) + p3*(c3 & Rmask) + p4*(c4 & Rmask))>>7) & Rmask;\
1453
				G = ((p1*(c1 & Gmask) + p2*(c2 & Gmask) + p3*(c3 & Gmask) + p4*(c4 & Gmask))>>7) & Gmask;\
1454
				B = ((p1*(c1 & Bmask) + p2*(c2 & Bmask) + p3*(c3 & Bmask) + p4*(c4 & Bmask))>>7) & Bmask;\
1455
				if(Amask)\
1456
					A = ((p1*(c1 & Amask) + p2*(c2 & Amask) + p3*(c3 & Amask) + p4*(c4 & Amask))>>7) & Amask;\
1457
				\
1458
				*(dst_row + x) = R | G | B | A;\
1459
			} \
1460
			sx += ctx;  /* Incremental transformations */ \
1461
		} \
1462
	} 
1463
1464
void sge_transform(Surface *src, Surface *dst, float xscale, float yscale, Uint16 qx, Uint16 qy)
1465
{
1466
	Sint32 dy, sx, sy;
1467
	Sint16 x, y, rx, ry;
1468
	Rect r;
1469
1470
	Sint32 ctx, cty;
1471
	Sint16 xmin, xmax, ymin, ymax;
1472
	Sint16 sxmin, sxmax, symin, symax;
1473
	Sint32 dx, ctdx;
1474
1475
1476
	/* Here we use 18.13 fixed point integer math
1477
	// Sint32 should have 31 usable bits and one for sign
1478
	// 2^13 = 8192
1479
	*/
1480
1481
	/* Check scales */
1482
	Sint32 maxint = (Sint32)(pow(2, sizeof(Sint32)*8 - 1 - 13));  /* 2^(31-13) */
1483
1484
	r.x = r.y = r.w = r.h = 0;
1485
	
1486
	if( xscale == 0 || yscale == 0)
1487
		return;
1488
		
1489
	if( 8192.0/xscale > maxint )
1490
		xscale =  (float)(8192.0/maxint);
1491
	else if( 8192.0/xscale < -maxint )
1492
		xscale =  (float)(-8192.0/maxint);	
1493
		
1494
	if( 8192.0/yscale > maxint )
1495
		yscale =  (float)(8192.0/maxint);
1496
	else if( 8192.0/yscale < -maxint )
1497
		yscale =  (float)(-8192.0/maxint);
1498
1499
1500
	/* Fixed-point equivalents */
1501
	ctx = (Sint32)(8192.0/xscale);
1502
	cty = (Sint32)(8192.0/yscale);
1503
1504
	/* Compute a bounding rectangle */
1505
	xmin=0; xmax=dst->w; ymin=0; ymax=dst->h;
1506
	_calcRect(src, dst, xscale, yscale, 
1507
		  qx, qy, &xmin, &ymin, &xmax, &ymax);	
1508
1509
	/* Clip to src surface */
1510
	sxmin = sge_clip_xmin(src);
1511
	sxmax = sge_clip_xmax(src);
1512
	symin = sge_clip_ymin(src);
1513
	symax = sge_clip_ymax(src);
1514
1515
	/* Some terms in the transform are constant */
1516
	dx = xmin - qx;
1517
	ctdx = ctx*dx;
1518
	
1519
	/* Use the correct bpp */
1520
	if( src->BytesPerPixel == dst->BytesPerPixel){
1521
		switch( src->BytesPerPixel ){
1522
			case 1: { /* Assuming 8-bpp */
1523
				TRANSFORM(Uint8, 1)
1524
			}
1525
			break;
1526
			case 2: { /* Probably 15-bpp or 16-bpp */
1527
				TRANSFORM_AA(Uint16, 2)
1528
			}
1529
			break;
1530
			case 4: { /* Probably 32-bpp */
1531
				TRANSFORM_AA(Uint32, 4)
1532
			}
1533
			break;
1534
		}
1535
	}
1536
}
1537
1538
void freeDesktopResources() {
1539
  Cleanup();
1540
  if (image) {
1541
    XDestroyImage(image);
1542
  }
1543
  if (zoomImage) {
1544
    XDestroyImage(zoomImage);
1545
  }
1546
  if (savedArea)
1547
    free(savedArea);
1548
1549
  if (gcInited) {
1550
    XFreeGC(dpy, gc);
1551
    XFreeGC(dpy, srcGC);
1552
    XFreeGC(dpy, dstGC);
1553
  }
1554
1555
  caughtShmError = False;
1556
  needShmCleanup = False;
1557
  caughtZoomShmError = False;
1558
  needZoomShmCleanup = False;
1559
  gcInited = False;
1560
  image = NULL;
1561
  useShm = True;
1562
  zoomActive = False;
1563
  zoomImage = NULL;
1564
  useZoomShm = True;
1565
  savedArea = NULL;
1566
}
1567
1568
1569
/*
1570
 * ColorRectangle32
1571
 * Only used for debugging / visualizing output
1572
 */
1573
/*
1574
static void
1575
ColorRectangle32(XImage *img, CARD32 fg, int x, int y, int width, int height)
1576
{
1577
  int i, h;
1578
  int scrWidthInBytes = img->bytes_per_line;
1579
  char *scr;
1580
  CARD32 *scr32;
1581
1582
  if ((!img) || (!img->data))
1583
    return;
1584
1585
  scr = (img->data + y * scrWidthInBytes + x * 4);
1586
    
1587
  if (!CheckRectangle(x, y, width, height))
1588
    return;
1589
1590
  for (h = 0; h < height; h++) {
1591
    scr32 = (CARD32*) scr;
1592
    for (i = 0; i < width; i++) {
1593
      CARD32 n = 0;
1594
      CARD32 p = scr32[i];
1595
      if (0xff & fg)
1596
	n |= (((    0xff & p)+(    0xff & fg)) >> 2) & 0xff;
1597
      else
1598
	n |= (0xff & p);
1599
      if (0xff00 & fg)
1600
	n |= (((  0xff00 & p)+(  0xff00 & fg)) >> 2) & 0xff00;
1601
      else
1602
	n |= (0xff00 & p);
1603
      if (0xff0000 & fg)
1604
	n |= (((0xff0000 & p)+(0xff0000 & fg)) >> 2) & 0xff0000;
1605
      else
1606
	n |= (0xff0000 & p);
1607
      scr32[i] = n;
1608
    }
1609
    scr += scrWidthInBytes;
1610
  }
1611
}
1612
*/
1613
(-)tdenetwork-trinity-14.1.0-ORIG/krdc/vnc/hextile.c (+129 lines)
Line 0 Link Here
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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
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 CONCAT2E(CARD,BPP)
31
#define GET_PIXEL CONCAT2E(GET_PIXEL,BPP)
32
#define FillRectangleBPP CONCAT2E(FillRectangle,BPP)
33
34
static Bool
35
HandleHextileBPP (int rx, int ry, int rw, int rh)
36
{
37
  CARDBPP bg, fg;
38
  int i;
39
  CARD8 *ptr;
40
  int x, y, w, h;
41
  int sx, sy, sw, sh;
42
  CARD8 subencoding;
43
  CARD8 nSubrects;
44
45
  for (y = ry; y < ry+rh; y += 16) {
46
    for (x = rx; x < rx+rw; x += 16) {
47
      w = h = 16;
48
      if (rx+rw - x < 16)
49
	w = rx+rw - x;
50
      if (ry+rh - y < 16)
51
	h = ry+rh - y;
52
53
      if (!ReadFromRFBServer((char *)&subencoding, 1))
54
	return False;
55
56
      if (subencoding & rfbHextileRaw) {
57
	if (!ReadFromRFBServer(buffer, w * h * (BPP / 8)))
58
	  return False;
59
60
	CopyDataToScreen(buffer, x, y, w, h);
61
	continue;
62
      }
63
64
      if (subencoding & rfbHextileBackgroundSpecified)
65
	if (!ReadFromRFBServer((char *)&bg, sizeof(bg)))
66
	  return False;
67
68
      LockFramebuffer();
69
      FillRectangleBPP(bg, x, y, w, h);
70
71
      if (subencoding & rfbHextileForegroundSpecified)
72
	if (!ReadFromRFBServer((char *)&fg, sizeof(fg))) {
73
	  UnlockFramebuffer();
74
	  return False;
75
	}
76
77
      if (!(subencoding & rfbHextileAnySubrects)) {
78
	UnlockFramebuffer();
79
	SyncScreenRegion(x, y, w, h);
80
	continue;
81
      }
82
83
      if (!ReadFromRFBServer((char *)&nSubrects, 1)) {
84
	UnlockFramebuffer();
85
	return False;
86
      }
87
88
      ptr = (CARD8 *)buffer;
89
90
      if (subencoding & rfbHextileSubrectsColoured) {
91
	if (!ReadFromRFBServer(buffer, nSubrects * (2 + (BPP / 8)))) {
92
	  UnlockFramebuffer();
93
	  return False;
94
	}
95
96
	for (i = 0; i < nSubrects; i++) {
97
	  GET_PIXEL(fg, ptr);
98
	  sx = rfbHextileExtractX(*ptr);
99
	  sy = rfbHextileExtractY(*ptr);
100
	  ptr++;
101
	  sw = rfbHextileExtractW(*ptr);
102
	  sh = rfbHextileExtractH(*ptr);
103
	  ptr++;
104
	  FillRectangleBPP(fg, x+sx, y+sy, sw, sh);
105
	}
106
107
      } else {
108
	if (!ReadFromRFBServer(buffer, nSubrects * 2)) {
109
	  UnlockFramebuffer();
110
	  return False;
111
	}
112
113
	for (i = 0; i < nSubrects; i++) {
114
	  sx = rfbHextileExtractX(*ptr);
115
	  sy = rfbHextileExtractY(*ptr);
116
	  ptr++;
117
	  sw = rfbHextileExtractW(*ptr);
118
	  sh = rfbHextileExtractH(*ptr);
119
	  ptr++;
120
	  FillRectangleBPP(fg, x+sx, y+sy, sw, sh);
121
	}
122
      }
123
      UnlockFramebuffer();
124
      SyncScreenRegion(x, y, w, h);
125
    }
126
  }
127
128
  return True;
129
}
(-)tdenetwork-trinity-14.1.0-ORIG/krdc/vnc/kvncview.cpp (-74 / +70 lines)
Lines 2-9 Link Here
2
                          kvncview.cpp  -  main widget
2
                          kvncview.cpp  -  main widget
3
                             -------------------
3
                             -------------------
4
    begin                : Thu Dec 20 15:11:42 CET 2001
4
    begin                : Thu Dec 20 15:11:42 CET 2001
5
    copyright            : (C) 2015 Timothy Pearson <kb9vqf@pearsoncomputing.net>
5
    copyright            : (C) 2001-2003 by Tim Jansen
6
                           (C) 2001-2003 by Tim Jansen
7
    email                : tim@tjansen.de
6
    email                : tim@tjansen.de
8
 ***************************************************************************/
7
 ***************************************************************************/
9
8
Lines 35-42 Link Here
35
#include <tqbitmap.h>
34
#include <tqbitmap.h>
36
#include <tqmutex.h>
35
#include <tqmutex.h>
37
#include <tqvbox.h>
36
#include <tqvbox.h>
38
#include <tqtimer.h>
39
#include <tqpainter.h>
40
#include <tqwaitcondition.h>
37
#include <tqwaitcondition.h>
41
38
42
#include "vncviewer.h"
39
#include "vncviewer.h"
Lines 50-55 Link Here
50
 * application resource specs.  The AppData structure is defined in the header
47
 * application resource specs.  The AppData structure is defined in the header
51
 * file.
48
 * file.
52
 */
49
 */
50
AppData appData;
53
bool appDataConfigured = false;
51
bool appDataConfigured = false;
54
52
55
Display* dpy;
53
Display* dpy;
Lines 75-81 Link Here
75
		   DotCursorState dotCursorState,
73
		   DotCursorState dotCursorState,
76
		   const TQString &encodings) :
74
		   const TQString &encodings) :
77
  KRemoteView(parent, name, TQt::WResizeNoErase | TQt::WRepaintNoErase | TQt::WStaticContents),
75
  KRemoteView(parent, name, TQt::WResizeNoErase | TQt::WRepaintNoErase | TQt::WStaticContents),
78
  m_cthreadObject(this, m_quitFlag),
76
  m_cthread(this, m_wthread, m_quitFlag),
77
  m_wthread(this, m_quitFlag),
79
  m_quitFlag(false),
78
  m_quitFlag(false),
80
  m_enableFramebufferLocking(false),
79
  m_enableFramebufferLocking(false),
81
  m_scaling(false),
80
  m_scaling(false),
Lines 148-153 Link Here
148
147
149
void KVncView::startQuitting() {
148
void KVncView::startQuitting() {
150
	m_quitFlag = true;
149
	m_quitFlag = true;
150
	m_wthread.kick();
151
	m_cthread.kick();
151
}
152
}
152
153
153
bool KVncView::isQuitting() {
154
bool KVncView::isQuitting() {
Lines 156-192 Link Here
156
157
157
void KVncView::configureApp(Quality q, const TQString specialEncodings) {
158
void KVncView::configureApp(Quality q, const TQString specialEncodings) {
158
	appDataConfigured = true;
159
	appDataConfigured = true;
159
	m_cthreadObject.cl->appData.shareDesktop = 1;
160
	appData.shareDesktop = 1;
160
	m_cthreadObject.cl->appData.viewOnly = 0;
161
	appData.viewOnly = 0;
161
162
162
	if (q == QUALITY_LOW) {
163
	if (q == QUALITY_LOW) {
163
		m_cthreadObject.cl->appData.useBGR233 = 1;
164
		appData.useBGR233 = 1;
164
		m_cthreadObject.cl->appData.encodingsString = "tight zrle ultra copyrect hextile zlib corre rre raw";
165
		appData.encodingsString = "background copyrect softcursor tight zlib hextile raw";
165
		m_cthreadObject.cl->appData.compressLevel = 9;
166
		appData.compressLevel = -1;
166
		m_cthreadObject.cl->appData.qualityLevel = 1;
167
		appData.qualityLevel = 1;
167
		m_cthreadObject.cl->appData.useRemoteCursor = 1;
168
		appData.dotCursor = 1;
168
	}
169
	}
169
	else if (q == QUALITY_MEDIUM) {
170
	else if (q == QUALITY_MEDIUM) {
170
		m_cthreadObject.cl->appData.useBGR233 = 0;
171
		appData.useBGR233 = 0;
171
		m_cthreadObject.cl->appData.encodingsString = "tight zrle ultra copyrect hextile zlib corre rre raw";
172
		appData.encodingsString = "background copyrect softcursor tight zlib hextile raw";
172
		m_cthreadObject.cl->appData.compressLevel = 5;
173
		appData.compressLevel = -1;
173
		m_cthreadObject.cl->appData.qualityLevel = 7;
174
		appData.qualityLevel = 7;
174
		m_cthreadObject.cl->appData.useRemoteCursor = 1;
175
		appData.dotCursor = 1;
175
	}
176
	}
176
	else if ((q == QUALITY_HIGH) || (q == QUALITY_UNKNOWN)) {
177
	else if ((q == QUALITY_HIGH) || (q == QUALITY_UNKNOWN)) {
177
		m_cthreadObject.cl->appData.useBGR233 = 0;
178
		appData.useBGR233 = 0;
178
		m_cthreadObject.cl->appData.encodingsString = "copyrect hextile raw";
179
		appData.encodingsString = "copyrect softcursor hextile raw";
179
		m_cthreadObject.cl->appData.compressLevel = 0;
180
		appData.compressLevel = -1;
180
		m_cthreadObject.cl->appData.qualityLevel = 9;
181
		appData.qualityLevel = 9;
181
		m_cthreadObject.cl->appData.useRemoteCursor = 1;
182
		appData.dotCursor = 1;
182
	}
183
	}
183
184
184
	if (!specialEncodings.isNull()) {
185
	if (!specialEncodings.isNull())
185
		m_cthreadObject.cl->appData.encodingsString = specialEncodings.latin1();
186
		appData.encodingsString = specialEncodings.latin1();
186
	}
187
188
	appData.nColours = 256;
189
	appData.useSharedColours = 1;
190
	appData.requestedDepth = 0;
191
192
	appData.rawDelay = 0;
193
	appData.copyRectDelay = 0;
187
194
188
	m_cthreadObject.cl->appData.nColours = 256;
195
	if (!appData.dotCursor)
189
	m_cthreadObject.cl->appData.requestedDepth = 0;
196
		m_cursorState = DOT_CURSOR_OFF;
197
	showDotCursorInternal();
190
}
198
}
191
199
192
bool KVncView::checkLocalKRfb() {
200
bool KVncView::checkLocalKRfb() {
Lines 289-298 Link Here
289
297
290
	setStatus(REMOTE_VIEW_CONNECTING);
298
	setStatus(REMOTE_VIEW_CONNECTING);
291
299
292
	m_cthreadObject.moveToThread(&m_cthread);
293
	TQTimer::singleShot(0, &m_cthreadObject, SLOT(run()));
294
	m_cthread.start();
300
	m_cthread.start();
295
296
	setBackgroundMode(TQt::NoBackground);
301
	setBackgroundMode(TQt::NoBackground);
297
	return true;
302
	return true;
298
}
303
}
Lines 301-306 Link Here
301
{
306
{
302
	startQuitting();
307
	startQuitting();
303
	m_cthread.wait();
308
	m_cthread.wait();
309
	m_wthread.wait();
310
	freeResources();
304
}
311
}
305
312
306
bool KVncView::supportsLocalCursor() const {
313
bool KVncView::supportsLocalCursor() const {
Lines 345-360 Link Here
345
			setMaximumSize(m_framebufferSize);
352
			setMaximumSize(m_framebufferSize);
346
			setMinimumSize(m_framebufferSize.width()/16,
353
			setMinimumSize(m_framebufferSize.width()/16,
347
				       m_framebufferSize.height()/16);
354
				       m_framebufferSize.height()/16);
348
349
			m_cthreadObject.setScaling(width(), height());
350
		}
355
		}
351
		else {
356
		else
352
			setFixedSize(m_framebufferSize);
357
			setFixedSize(m_framebufferSize);
353
			m_cthreadObject.setScaling(-1, -1);
354
		}
355
356
		// Force full redraw
357
		drawRegion(0, 0, width(), height());
358
	}
358
	}
359
}
359
}
360
360
Lines 365-382 Link Here
365
		   e->rect().height());
365
		   e->rect().height());
366
}
366
}
367
367
368
void KVncView::resizeEvent(TQResizeEvent *e) {
369
	if (m_scaling) {
370
		m_cthreadObject.setScaling(width(), height());
371
372
		// Force full redraw
373
		drawRegion(0, 0, width(), height());
374
	}
375
}
376
377
void KVncView::drawRegion(int x, int y, int w, int h) {
368
void KVncView::drawRegion(int x, int y, int w, int h) {
378
	TQPainter painter(this);
369
	if (m_scaling)
379
	painter.drawImage(TQRect(x, y, w, h), m_cthreadObject.image(x, y, w, h));
370
		DrawZoomedScreenRegionX11Thread(winId(), width(), height(),
371
						x, y, w, h);
372
	else
373
		DrawScreenRegionX11Thread(winId(), x, y, w, h);
380
}
374
}
381
375
382
void KVncView::customEvent(TQCustomEvent *e)
376
void KVncView::customEvent(TQCustomEvent *e)
Lines 391-396 Link Here
391
		setFixedSize(m_framebufferSize);
385
		setFixedSize(m_framebufferSize);
392
		emit changeSize(sre->width(), sre->height());
386
		emit changeSize(sre->width(), sre->height());
393
	}
387
	}
388
	else if (e->type() == DesktopInitEventType) {
389
		m_cthread.desktopInit();
390
	}
394
	else if (e->type() == StatusChangeEventType) {
391
	else if (e->type() == StatusChangeEventType) {
395
		StatusChangeEvent *sce = (StatusChangeEvent*) e;
392
		StatusChangeEvent *sce = (StatusChangeEvent*) e;
396
		setStatus(sce->status());
393
		setStatus(sce->status());
Lines 448-454 Link Here
448
				wallet->setFolder(krdc_folder);
445
				wallet->setFolder(krdc_folder);
449
				TQString newPass;
446
				TQString newPass;
450
				if ( wallet->hasEntry(kvncview->host()) && !wallet->readPassword(kvncview->host(), newPass) ) {
447
				if ( wallet->hasEntry(kvncview->host()) && !wallet->readPassword(kvncview->host(), newPass) ) {
451
					password=newPass;
448
					password=newPass.latin1();
452
				}
449
				}
453
			}
450
			}
454
		}
451
		}
Lines 566-578 Link Here
566
		x = (x * m_framebufferSize.width()) / width();
563
		x = (x * m_framebufferSize.width()) / width();
567
		y = (y * m_framebufferSize.height()) / height();
564
		y = (y * m_framebufferSize.height()) / height();
568
	}
565
	}
569
	m_cthreadObject.queueMouseEvent(x, y, m_buttonMask);
566
	m_wthread.queueMouseEvent(x, y, m_buttonMask);
570
567
571
	if (m_enableClientCursor) {
568
	if (m_enableClientCursor)
572
		// FIXME
569
		DrawCursorX11Thread(x, y); // in rfbproto.c
573
		// How to draw soft cursor?
574
		// DrawCursorX11Thread(x, y); // in rfbproto.c
575
	}
576
}
570
}
577
571
578
void KVncView::mousePressEvent(TQMouseEvent *e) {
572
void KVncView::mousePressEvent(TQMouseEvent *e) {
Lines 613-620 Link Here
613
		x = (x * m_framebufferSize.width()) / width();
607
		x = (x * m_framebufferSize.width()) / width();
614
		y = (y * m_framebufferSize.height()) / height();
608
		y = (y * m_framebufferSize.height()) / height();
615
	}
609
	}
616
	m_cthreadObject.queueMouseEvent(x, y, eb|m_buttonMask);
610
	m_wthread.queueMouseEvent(x, y, eb|m_buttonMask);
617
	m_cthreadObject.queueMouseEvent(x, y, m_buttonMask);
611
	m_wthread.queueMouseEvent(x, y, m_buttonMask);
618
	e->accept();
612
	e->accept();
619
}
613
}
620
614
Lines 627-651 Link Here
627
	KKeyNative k(xe);
621
	KKeyNative k(xe);
628
	uint mod = k.mod();
622
	uint mod = k.mod();
629
	if (mod & KKeyNative::modX(KKey::SHIFT))
623
	if (mod & KKeyNative::modX(KKey::SHIFT))
630
		m_cthreadObject.queueKeyEvent(XK_Shift_L, true);
624
		m_wthread.queueKeyEvent(XK_Shift_L, true);
631
	if (mod & KKeyNative::modX(KKey::CTRL))
625
	if (mod & KKeyNative::modX(KKey::CTRL))
632
		m_cthreadObject.queueKeyEvent(XK_Control_L, true);
626
		m_wthread.queueKeyEvent(XK_Control_L, true);
633
	if (mod & KKeyNative::modX(KKey::ALT))
627
	if (mod & KKeyNative::modX(KKey::ALT))
634
		m_cthreadObject.queueKeyEvent(XK_Alt_L, true);
628
		m_wthread.queueKeyEvent(XK_Alt_L, true);
635
	if (mod & KKeyNative::modX(KKey::WIN))
629
	if (mod & KKeyNative::modX(KKey::WIN))
636
		m_cthreadObject.queueKeyEvent(XK_Meta_L, true);
630
		m_wthread.queueKeyEvent(XK_Meta_L, true);
637
631
638
	m_cthreadObject.queueKeyEvent(k.sym(), true);
632
	m_wthread.queueKeyEvent(k.sym(), true);
639
	m_cthreadObject.queueKeyEvent(k.sym(), false);
633
	m_wthread.queueKeyEvent(k.sym(), false);
640
634
641
	if (mod & KKeyNative::modX(KKey::WIN))
635
	if (mod & KKeyNative::modX(KKey::WIN))
642
		m_cthreadObject.queueKeyEvent(XK_Meta_L, false);
636
		m_wthread.queueKeyEvent(XK_Meta_L, false);
643
	if (mod & KKeyNative::modX(KKey::ALT))
637
	if (mod & KKeyNative::modX(KKey::ALT))
644
		m_cthreadObject.queueKeyEvent(XK_Alt_L, false);
638
		m_wthread.queueKeyEvent(XK_Alt_L, false);
645
	if (mod & KKeyNative::modX(KKey::CTRL))
639
	if (mod & KKeyNative::modX(KKey::CTRL))
646
		m_cthreadObject.queueKeyEvent(XK_Control_L, false);
640
		m_wthread.queueKeyEvent(XK_Control_L, false);
647
	if (mod & KKeyNative::modX(KKey::SHIFT))
641
	if (mod & KKeyNative::modX(KKey::SHIFT))
648
		m_cthreadObject.queueKeyEvent(XK_Shift_L, false);
642
		m_wthread.queueKeyEvent(XK_Shift_L, false);
649
643
650
	m_mods.clear();
644
	m_mods.clear();
651
}
645
}
Lines 678-684 Link Here
678
			else
672
			else
679
				unpressModifiers();
673
				unpressModifiers();
680
		}
674
		}
681
		m_cthreadObject.queueKeyEvent(s, pressed);
675
		m_wthread.queueKeyEvent(s, pressed);
682
	}
676
	}
683
	return true;
677
	return true;
684
}
678
}
Lines 687-693 Link Here
687
	TQValueList<unsigned int> keys = m_mods.keys();
681
	TQValueList<unsigned int> keys = m_mods.keys();
688
	TQValueList<unsigned int>::const_iterator it = keys.begin();
682
	TQValueList<unsigned int>::const_iterator it = keys.begin();
689
	while (it != keys.end()) {
683
	while (it != keys.end()) {
690
		m_cthreadObject.queueKeyEvent(*it, false);
684
		m_wthread.queueKeyEvent(*it, false);
691
		it++;
685
		it++;
692
	}
686
	}
693
	m_mods.clear();
687
	m_mods.clear();
Lines 725-731 Link Here
725
	if (text.length() > MAX_SELECTION_LENGTH)
719
	if (text.length() > MAX_SELECTION_LENGTH)
726
		return;
720
		return;
727
721
728
	m_cthreadObject.queueClientCut(text);
722
	m_wthread.queueClientCut(text);
729
}
723
}
730
724
731
void KVncView::selectionChanged() {
725
void KVncView::selectionChanged() {
Lines 744-750 Link Here
744
	if (text.length() > MAX_SELECTION_LENGTH)
738
	if (text.length() > MAX_SELECTION_LENGTH)
745
		return;
739
		return;
746
740
747
	m_cthreadObject.queueClientCut(text);
741
	m_wthread.queueClientCut(text);
748
}
742
}
749
743
750
744
Lines 776-782 Link Here
776
	locks and signals are there to protect against deadlocks and other
770
	locks and signals are there to protect against deadlocks and other
777
	horribleness. Be careful making changes here. 
771
	horribleness. Be careful making changes here. 
778
*/
772
*/
779
int getPassword(char * &passwd) {
773
int getPassword(char *passwd, int pwlen) {
780
	int retV = 0;
774
	int retV = 0;
781
775
782
	//Prepare the system
776
	//Prepare the system
Lines 803-809 Link Here
803
797
804
	//Process the password if we got it, clear it if we didn't
798
	//Process the password if we got it, clear it if we didn't
805
	if (retV) {
799
	if (retV) {
806
		passwd = strdup(password.utf8());
800
		strncpy(passwd, password.utf8(), pwlen);
801
	} else {
802
		passwd[0] = 0;
807
	}
803
	}
808
804
809
	//Pack up and go home
805
	//Pack up and go home
(-)tdenetwork-trinity-14.1.0-ORIG/krdc/vnc/kvncview.h (-7 / +4 lines)
Lines 2-9 Link Here
2
                  kvncview.h  -  widget that shows the vnc client
2
                  kvncview.h  -  widget that shows the vnc client
3
                             -------------------
3
                             -------------------
4
    begin                : Thu Dec 20 15:11:42 CET 2001
4
    begin                : Thu Dec 20 15:11:42 CET 2001
5
    copyright            : (C) 2015 Timothy Pearson <kb9vqf@pearsoncomputing.net>
5
    copyright            : (C) 2001-2003 by Tim Jansen
6
                           (C) 2001-2003 by Tim Jansen
7
    email                : tim@tjansen.de
6
    email                : tim@tjansen.de
8
 ***************************************************************************/
7
 ***************************************************************************/
9
8
Lines 25-30 Link Here
25
24
26
#include "pointerlatencyometer.h"
25
#include "pointerlatencyometer.h"
27
#include "hostpreferences.h"
26
#include "hostpreferences.h"
27
#include "vnctypes.h"
28
#include "threads.h"
28
#include "threads.h"
29
29
30
class TQClipBoard;
30
class TQClipBoard;
Lines 34-41 Link Here
34
	TQ_OBJECT
34
	TQ_OBJECT
35
  
35
  
36
private:
36
private:
37
	ControllerThreadObject m_cthreadObject;
37
	ControllerThread m_cthread;
38
	TQEventLoopThread m_cthread;
38
	WriterThread m_wthread;
39
	volatile bool m_quitFlag; // if set: all threads should die ASAP
39
	volatile bool m_quitFlag; // if set: all threads should die ASAP
40
	TQMutex m_framebufferLock;
40
	TQMutex m_framebufferLock;
41
	bool m_enableFramebufferLocking;
41
	bool m_enableFramebufferLocking;
Lines 74-80 Link Here
74
	void mouseMoveEvent(TQMouseEvent*);
74
	void mouseMoveEvent(TQMouseEvent*);
75
	void wheelEvent(TQWheelEvent *);
75
	void wheelEvent(TQWheelEvent *);
76
	void focusOutEvent(TQFocusEvent *);
76
	void focusOutEvent(TQFocusEvent *);
77
	void resizeEvent(TQResizeEvent *);
78
	bool x11Event(XEvent*);
77
	bool x11Event(XEvent*);
79
78
80
public:
79
public:
Lines 117-124 Link Here
117
116
118
117
119
private slots:
118
private slots:
120
// 	void requestPassword();
121
122
	void clipboardChanged();
119
	void clipboardChanged();
123
	void selectionChanged();
120
	void selectionChanged();
124
};
121
};
(-)tdenetwork-trinity-14.1.0-ORIG/krdc/vnc/rfbproto.c (+1342 lines)
Line 0 Link Here
1
/*
2
 *  Copyright (C) 2002, Tim Jansen.  All Rights Reserved.
3
 *  Copyright (C) 2000-2002 Constantin Kaplinsky.  All Rights Reserved.
4
 *  Copyright (C) 2000 Tridia Corporation.  All Rights Reserved.
5
 *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
6
 *
7
 *  This is free software; you can redistribute it and/or modify
8
 *  it under the terms of the GNU General Public License as published by
9
 *  the Free Software Foundation; either version 2 of the License, or
10
 *  (at your option) any later version.
11
 *
12
 *  This software is distributed in the hope that it will be useful,
13
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 *  GNU General Public License for more details.
16
 *
17
 *  You should have received a copy of the GNU General Public License
18
 *  along with this software; if not, write to the Free Software
19
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
20
 *  USA.
21
 */
22
23
/*
24
 * rfbproto.c - functions to deal with client side of RFB protocol.
25
 * tim@tjansen.de: - added softcursor encoding
26
 *                 - changed various things for krdc
27
 */
28
29
#include <unistd.h>
30
#include <errno.h>
31
#include <pwd.h>
32
#include "vncviewer.h"
33
#include "vncauth.h"
34
#include <zlib.h>
35
#include <jpeglib.h>
36
37
static Bool HandleHextile8(int rx, int ry, int rw, int rh);
38
static Bool HandleHextile16(int rx, int ry, int rw, int rh);
39
static Bool HandleHextile32(int rx, int ry, int rw, int rh);
40
static Bool HandleZlib8(int rx, int ry, int rw, int rh);
41
static Bool HandleZlib16(int rx, int ry, int rw, int rh);
42
static Bool HandleZlib32(int rx, int ry, int rw, int rh);
43
static Bool HandleTight8(int rx, int ry, int rw, int rh);
44
static Bool HandleTight16(int rx, int ry, int rw, int rh);
45
static Bool HandleTight32(int rx, int ry, int rw, int rh);
46
47
static long ReadCompactLen (void);
48
49
static void JpegInitSource(j_decompress_ptr cinfo);
50
static boolean JpegFillInputBuffer(j_decompress_ptr cinfo);
51
static void JpegSkipInputData(j_decompress_ptr cinfo, long num_bytes);
52
static void JpegTermSource(j_decompress_ptr cinfo);
53
static void JpegSetSrcManager(j_decompress_ptr cinfo, CARD8 *compressedData,
54
                              int compressedLen);
55
56
57
#define RGB24_TO_PIXEL(bpp,r,g,b)                                       \
58
   ((((CARD##bpp)(r) & 0xFF) * myFormat.redMax + 127) / 255             \
59
    << myFormat.redShift |                                              \
60
    (((CARD##bpp)(g) & 0xFF) * myFormat.greenMax + 127) / 255           \
61
    << myFormat.greenShift |                                            \
62
    (((CARD##bpp)(b) & 0xFF) * myFormat.blueMax + 127) / 255            \
63
    << myFormat.blueShift)
64
65
int rfbsock;
66
char *desktopName;
67
rfbPixelFormat myFormat;
68
rfbServerInitMsg si;
69
70
int endianTest = 1;
71
72
/*
73
 * Softcursor variables
74
 */
75
76
int cursorX, cursorY;
77
int imageIndex = -1;
78
79
PointerImage pointerImages[rfbSoftCursorMaxImages];
80
81
82
/*  Hextile assumes it is big enough to hold 16 * 16 * 32 bits.
83
   Tight encoding assumes BUFFER_SIZE is at least 16384 bytes. */
84
85
#define BUFFER_SIZE (16384)
86
static char buffer[BUFFER_SIZE];
87
88
89
/* The zlib encoding requires expansion/decompression/deflation of the
90
   compressed data in the "buffer" above into another, result buffer.
91
   However, the size of the result buffer can be determined precisely
92
   based on the bitsPerPixel, height and width of the rectangle.  We
93
   allocate this buffer one time to be the full size of the buffer. */
94
95
static int raw_buffer_size = -1;
96
static char *raw_buffer = NULL;
97
98
static z_stream decompStream;
99
static Bool decompStreamInited = False;
100
101
102
/*
103
 * Variables for the ``tight'' encoding implementation.
104
 */
105
106
/* Separate buffer for compressed data. */
107
#define ZLIB_BUFFER_SIZE 512
108
static char zlib_buffer[ZLIB_BUFFER_SIZE];
109
110
/* Four independent compression streams for zlib library. */
111
static z_stream zlibStream[4];
112
static Bool zlibStreamActive[4] = {
113
  False, False, False, False
114
};
115
116
/* Filter stuff. Should be initialized by filter initialization code. */
117
static Bool cutZeros;
118
static int rectWidth, rectColors;
119
static char tightPalette[256*4];
120
static CARD8 tightPrevRow[2048*3*sizeof(CARD16)];
121
122
/* JPEG decoder state. */
123
static Bool jpegError;
124
125
/* Maximum length for the cut buffer (16 MB)*/
126
#define MAX_CUTBUFFER (1024*1024*16)
127
128
/* Maximum length for the strings (64 kB)*/
129
#define MAX_STRING (1024*64)
130
131
/* Maximum length for the strings (32 MB)*/
132
#define MAX_JPEG_SIZE (1024*1024*32)
133
134
135
/*
136
 * ConnectToRFBServer.
137
 */
138
139
int
140
ConnectToRFBServer(const char *hostname, int port)
141
{
142
  unsigned int host;
143
144
  if (!StringToIPAddr(hostname, &host)) {
145
    fprintf(stderr,"Couldn't convert '%s' to host address\n", hostname);
146
    return -(int)INIT_NAME_RESOLUTION_FAILURE;
147
  }
148
149
  rfbsock = ConnectToTcpAddr(host, port);
150
  if (rfbsock < 0) {
151
    fprintf(stderr,"Unable to connect to VNC server\n");
152
  }
153
154
  return rfbsock;
155
}
156
157
158
/*
159
 * InitialiseRFBConnection.
160
 */
161
162
enum InitStatus
163
InitialiseRFBConnection()
164
{
165
  rfbProtocolVersionMsg pv;
166
  int major,minor;
167
  CARD32 authScheme, reasonLen, authResult;
168
  char *reason;
169
  CARD8 challenge[CHALLENGESIZE];
170
  char passwd[9];
171
  int i;
172
  rfbClientInitMsg ci;
173
174
  /* if the connection is immediately closed, don't report anything, so
175
       that pmw's monitor can make test connections */
176
177
  if (!ReadFromRFBServer(pv, sz_rfbProtocolVersionMsg)) return INIT_SERVER_BLOCKED;
178
179
  errorMessageOnReadFailure = True;
180
181
  pv[sz_rfbProtocolVersionMsg] = 0;
182
183
  if (sscanf(pv,rfbProtocolVersionFormat,&major,&minor) != 2) {
184
    fprintf(stderr,"Not a valid VNC server\n");
185
    return INIT_PROTOCOL_FAILURE;
186
  }
187
188
  fprintf(stderr,"VNC server supports protocol version %d.%d (viewer %d.%d)\n",
189
	  major, minor, rfbProtocolMajorVersion, rfbProtocolMinorVersion);
190
191
  major = rfbProtocolMajorVersion;
192
  minor = rfbProtocolMinorVersion;
193
194
  sprintf(pv,rfbProtocolVersionFormat,major,minor);
195
196
  if (!WriteExact(rfbsock, pv, sz_rfbProtocolVersionMsg)) return INIT_CONNECTION_FAILED;
197
198
  if (!ReadFromRFBServer((char *)&authScheme, 4)) return INIT_CONNECTION_FAILED;
199
200
  authScheme = Swap32IfLE(authScheme);
201
202
  switch (authScheme) {
203
204
  case rfbConnFailed:
205
    if (!ReadFromRFBServer((char *)&reasonLen, 4)) return INIT_CONNECTION_FAILED;
206
    reasonLen = Swap32IfLE(reasonLen);
207
208
    if (reasonLen > MAX_STRING) {
209
      fprintf(stderr, "Connection failure reason too long.\n");
210
      return INIT_CONNECTION_FAILED;
211
    }
212
      
213
    reason = malloc(reasonLen);
214
    if (!reason)
215
      return INIT_CONNECTION_FAILED;
216
      
217
    if (!ReadFromRFBServer(reason, reasonLen)) return INIT_CONNECTION_FAILED;
218
219
    fprintf(stderr,"VNC connection failed: %.*s\n",(int)reasonLen, reason);
220
    free(reason);
221
    return INIT_CONNECTION_FAILED;
222
223
  case rfbNoAuth:
224
    fprintf(stderr,"No authentication needed\n");
225
    break;
226
227
  case rfbVncAuth:
228
    if (!ReadFromRFBServer((char *)challenge, CHALLENGESIZE)) return INIT_CONNECTION_FAILED;
229
230
    if (!getPassword(passwd, 8))
231
      return INIT_ABORTED;
232
233
    passwd[8] = '\0';
234
235
    vncEncryptBytes(challenge, passwd);
236
237
	/* Lose the password from memory */
238
    for (i = strlen(passwd); i >= 0; i--) {
239
      passwd[i] = '\0';
240
    }
241
242
    if (!WriteExact(rfbsock, (char *)challenge, CHALLENGESIZE)) return INIT_CONNECTION_FAILED;
243
244
    if (!ReadFromRFBServer((char *)&authResult, 4)) return INIT_CONNECTION_FAILED;
245
246
    authResult = Swap32IfLE(authResult);
247
248
    switch (authResult) {
249
    case rfbVncAuthOK:
250
      fprintf(stderr,"VNC authentication succeeded\n");
251
      break;
252
    case rfbVncAuthFailed:
253
      fprintf(stderr,"VNC authentication failed\n");
254
      return INIT_AUTHENTICATION_FAILED;
255
    case rfbVncAuthTooMany:
256
      fprintf(stderr,"VNC authentication failed - too many tries\n");
257
      return INIT_AUTHENTICATION_FAILED;
258
    default:
259
      fprintf(stderr,"Unknown VNC authentication result: %d\n",
260
	      (int)authResult);
261
      return INIT_CONNECTION_FAILED;
262
    }
263
    break;
264
265
  default:
266
    fprintf(stderr,"Unknown authentication scheme from VNC server: %d\n",
267
	    (int)authScheme);
268
    return INIT_CONNECTION_FAILED;
269
  }
270
271
  ci.shared = (appData.shareDesktop ? 1 : 0);
272
273
  if (!WriteExact(rfbsock, (char *)&ci, sz_rfbClientInitMsg)) return INIT_CONNECTION_FAILED;
274
275
  if (!ReadFromRFBServer((char *)&si, sz_rfbServerInitMsg)) return INIT_CONNECTION_FAILED;
276
277
  si.framebufferWidth = Swap16IfLE(si.framebufferWidth);
278
  si.framebufferHeight = Swap16IfLE(si.framebufferHeight);
279
  si.format.redMax = Swap16IfLE(si.format.redMax);
280
  si.format.greenMax = Swap16IfLE(si.format.greenMax);
281
  si.format.blueMax = Swap16IfLE(si.format.blueMax);
282
  si.nameLength = Swap32IfLE(si.nameLength);
283
284
  if ((si.framebufferWidth*si.framebufferHeight) > (4096*4096))
285
    return INIT_CONNECTION_FAILED;
286
287
  if (si.nameLength > MAX_STRING) {
288
    fprintf(stderr, "Display name too long.\n");  
289
    return INIT_CONNECTION_FAILED;
290
  }
291
292
  desktopName = malloc(si.nameLength + 1);
293
  if (!desktopName) {
294
    fprintf(stderr, "Error allocating memory for desktop name, %lu bytes\n",
295
            (unsigned long)si.nameLength);
296
    return INIT_CONNECTION_FAILED;
297
  }
298
299
  if (!ReadFromRFBServer(desktopName, si.nameLength)) return INIT_CONNECTION_FAILED;
300
301
  desktopName[si.nameLength] = 0;
302
303
  fprintf(stderr,"Desktop name \"%s\"\n",desktopName);
304
305
  fprintf(stderr,"Connected to VNC server, using protocol version %d.%d\n",
306
	  rfbProtocolMajorVersion, rfbProtocolMinorVersion);
307
308
  fprintf(stderr,"VNC server default format:\n");
309
  PrintPixelFormat(&si.format);
310
311
  return INIT_OK;
312
}
313
314
315
/*
316
 * SetFormatAndEncodings.
317
 */
318
319
Bool
320
SetFormatAndEncodings()
321
{
322
  rfbSetPixelFormatMsg spf;
323
  char buf[sz_rfbSetEncodingsMsg + MAX_ENCODINGS * 4];
324
  rfbSetEncodingsMsg *se = (rfbSetEncodingsMsg *)buf;
325
  CARD32 *encs = (CARD32 *)(&buf[sz_rfbSetEncodingsMsg]);
326
  int len = 0;
327
  Bool requestCompressLevel = False;
328
  Bool requestQualityLevel = False;
329
  Bool requestLastRectEncoding = False;
330
331
  spf.type = rfbSetPixelFormat;
332
  spf.pad1 = 0;
333
  spf.pad2 = 0;
334
  spf.format = myFormat;
335
  spf.format.redMax = Swap16IfLE(spf.format.redMax);
336
  spf.format.greenMax = Swap16IfLE(spf.format.greenMax);
337
  spf.format.blueMax = Swap16IfLE(spf.format.blueMax);
338
339
  if (!WriteExact(rfbsock, (char *)&spf, sz_rfbSetPixelFormatMsg))
340
    return False;
341
342
  se->type = rfbSetEncodings;
343
  se->pad = 0;
344
  se->nEncodings = 0;
345
346
  if (appData.encodingsString) {
347
    const char *encStr = appData.encodingsString;
348
    int encStrLen;
349
    do {
350
      char *nextEncStr = strchr(encStr, ' ');
351
      if (nextEncStr) {
352
	encStrLen = nextEncStr - encStr;
353
	nextEncStr++;
354
      } else {
355
	encStrLen = strlen(encStr);
356
      }
357
358
      if (strncasecmp(encStr,"raw",encStrLen) == 0) {
359
	encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRaw);
360
      } else if (strncasecmp(encStr,"copyrect",encStrLen) == 0) {
361
	encs[se->nEncodings++] = Swap32IfLE(rfbEncodingCopyRect);
362
      } else if (strncasecmp(encStr,"softcursor",encStrLen) == 0) {
363
	encs[se->nEncodings++] = Swap32IfLE(rfbEncodingSoftCursor);
364
        /* if server supports SoftCursor, it will ignore X/RichCursor 
365
	 * and PointerPos */
366
        encs[se->nEncodings++] = Swap32IfLE(rfbEncodingXCursor);
367
        encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRichCursor);
368
        encs[se->nEncodings++] = Swap32IfLE(rfbEncodingPointerPos);
369
      } else if (strncasecmp(encStr,"background",encStrLen) == 0) {
370
	encs[se->nEncodings++] = Swap32IfLE(rfbEncodingBackground);
371
      } else if (strncasecmp(encStr,"tight",encStrLen) == 0) {
372
	encs[se->nEncodings++] = Swap32IfLE(rfbEncodingTight);
373
	requestLastRectEncoding = True;
374
	if (appData.compressLevel >= 0 && appData.compressLevel <= 9)
375
	  requestCompressLevel = True;
376
	if (appData.qualityLevel >= 0 && appData.qualityLevel <= 9)
377
	  requestQualityLevel = True;
378
      } else if (strncasecmp(encStr,"hextile",encStrLen) == 0) {
379
	encs[se->nEncodings++] = Swap32IfLE(rfbEncodingHextile);
380
      } else if (strncasecmp(encStr,"zlib",encStrLen) == 0) {
381
	encs[se->nEncodings++] = Swap32IfLE(rfbEncodingZlib);
382
	if (appData.compressLevel >= 0 && appData.compressLevel <= 9)
383
	  requestCompressLevel = True;
384
      } else {
385
	fprintf(stderr,"Unknown encoding '%.*s'\n",encStrLen,encStr);
386
      }
387
388
      encStr = nextEncStr;
389
    } while (encStr && se->nEncodings < MAX_ENCODINGS);
390
391
    if (se->nEncodings < MAX_ENCODINGS && requestCompressLevel) {
392
      encs[se->nEncodings++] = Swap32IfLE(appData.compressLevel +
393
					  rfbEncodingCompressLevel0);
394
    }
395
396
    if (se->nEncodings < MAX_ENCODINGS && requestQualityLevel) {
397
      encs[se->nEncodings++] = Swap32IfLE(appData.qualityLevel +
398
					  rfbEncodingQualityLevel0);
399
    }
400
401
    if (se->nEncodings < MAX_ENCODINGS && requestLastRectEncoding) {
402
      encs[se->nEncodings++] = Swap32IfLE(rfbEncodingLastRect);
403
    }
404
  }
405
  else {
406
    encs[se->nEncodings++] = Swap32IfLE(rfbEncodingCopyRect);
407
    encs[se->nEncodings++] = Swap32IfLE(rfbEncodingTight);
408
    encs[se->nEncodings++] = Swap32IfLE(rfbEncodingHextile);
409
    encs[se->nEncodings++] = Swap32IfLE(rfbEncodingZlib);
410
    encs[se->nEncodings++] = Swap32IfLE(rfbEncodingRaw);
411
412
    if (appData.compressLevel >= 0 && appData.compressLevel <= 9) {
413
      encs[se->nEncodings++] = Swap32IfLE(appData.compressLevel +
414
					  rfbEncodingCompressLevel0);
415
    } 
416
417
    if (appData.qualityLevel >= 0 && appData.qualityLevel <= 9) {
418
      encs[se->nEncodings++] = Swap32IfLE(appData.qualityLevel +
419
					  rfbEncodingQualityLevel0);
420
    }
421
422
    if (si.format.depth >= 8) 
423
      encs[se->nEncodings++] = Swap32IfLE(rfbEncodingSoftCursor);
424
    encs[se->nEncodings++] = Swap32IfLE(rfbEncodingLastRect);
425
  }
426
427
  len = sz_rfbSetEncodingsMsg + se->nEncodings * 4;
428
429
  se->nEncodings = Swap16IfLE(se->nEncodings);
430
431
  if (!WriteExact(rfbsock, buf, len)) return False;
432
433
  return True;
434
}
435
436
437
/*
438
 * SendIncrementalFramebufferUpdateRequest.
439
 * Note: this should only be called by the WriterThread
440
 */
441
442
Bool
443
SendIncrementalFramebufferUpdateRequest()
444
{
445
  return SendFramebufferUpdateRequest(0, 0, si.framebufferWidth,
446
				      si.framebufferHeight, True);
447
}
448
449
450
/*
451
 * SendFramebufferUpdateRequest.
452
 * Note: this should only be called by the WriterThread
453
 */
454
455
Bool
456
SendFramebufferUpdateRequest(int x, int y, int w, int h, Bool incremental)
457
{
458
  rfbFramebufferUpdateRequestMsg fur;
459
460
  fur.type = rfbFramebufferUpdateRequest;
461
  fur.incremental = incremental ? 1 : 0;
462
  fur.x = Swap16IfLE(x);
463
  fur.y = Swap16IfLE(y);
464
  fur.w = Swap16IfLE(w);
465
  fur.h = Swap16IfLE(h);
466
467
  if (!WriteExact(rfbsock, (char *)&fur, sz_rfbFramebufferUpdateRequestMsg))
468
    return False;
469
470
  return True;
471
}
472
473
474
/*
475
 * SendPointerEvent.
476
 * Note: this should only be called by the WriterThread
477
 */
478
479
Bool
480
SendPointerEvent(int x, int y, int buttonMask)
481
{
482
  rfbPointerEventMsg pe;
483
484
  pe.type = rfbPointerEvent;
485
  pe.buttonMask = buttonMask;
486
  if (x < 0) x = 0;
487
  if (y < 0) y = 0;
488
  pe.x = Swap16IfLE(x);
489
  pe.y = Swap16IfLE(y);
490
  return WriteExact(rfbsock, (char *)&pe, sz_rfbPointerEventMsg);
491
}
492
493
494
/*
495
 * SendKeyEvent.
496
 * Note: this should only be called by the WriterThread
497
 */
498
499
Bool
500
SendKeyEvent(CARD32 key, Bool down)
501
{
502
  rfbKeyEventMsg ke;
503
504
  memset(&ke, 0, sizeof(ke));
505
  ke.type = rfbKeyEvent;
506
  ke.down = down ? 1 : 0;
507
  ke.key = Swap32IfLE(key);
508
  return WriteExact(rfbsock, (char *)&ke, sz_rfbKeyEventMsg);
509
}
510
511
512
/*
513
 * SendClientCutText.
514
 * Note: this should only be called by the WriterThread
515
 */
516
517
Bool
518
SendClientCutText(const char *str, int len)
519
{
520
  rfbClientCutTextMsg cct;
521
522
  memset(&cct, 0, sizeof(cct));
523
  cct.type = rfbClientCutText;
524
  cct.length = Swap32IfLE((unsigned int)len);
525
  return  (WriteExact(rfbsock, (char *)&cct, sz_rfbClientCutTextMsg) &&
526
	   WriteExact(rfbsock, str, len));
527
}
528
529
530
static Bool
531
HandleSoftCursorSetImage(rfbSoftCursorSetImage *msg, rfbRectangle *rect) 
532
{
533
  int iindex = msg->imageIndex - rfbSoftCursorSetIconOffset;
534
  PointerImage *pi = &pointerImages[iindex];
535
  if (iindex >= rfbSoftCursorMaxImages) {
536
    fprintf(stderr, "Received invalid soft cursor image index %d for SetImage\n", iindex);
537
    return False;
538
  }
539
  EnableClientCursor(0);
540
541
  if (pi->set && pi->image) 
542
    free(pi->image);
543
544
  pi->w = rect->w;
545
  pi->h = rect->h;
546
  pi->hotX = rect->x;
547
  pi->hotY = rect->y;
548
  pi->len = Swap16IfLE(msg->imageLength);
549
  pi->image = malloc(pi->len);
550
  if (!pi->image) {
551
    fprintf(stderr, "out of memory (size=%d)\n", pi->len);
552
    return False;
553
  }
554
555
  if (!ReadFromRFBServer(pi->image, pi->len)) 
556
    return False;
557
  pi->set = 1;
558
  return True;
559
}
560
561
/* framebuffer must be locked when calling this!!! */
562
static Bool
563
PointerMove(unsigned int x, unsigned int y, unsigned int mask,
564
	    int ox, int oy, int ow, int oh) 
565
{
566
  int nx, ny, nw, nh;
567
568
  if (x >= si.framebufferWidth)
569
    x = si.framebufferWidth - 1;
570
  if (y >= si.framebufferHeight)
571
    y = si.framebufferHeight - 1;
572
573
  cursorX = x;
574
  cursorY = y;
575
  drawCursor();
576
  UnlockFramebuffer();
577
578
  getBoundingRectCursor(cursorX, cursorY, imageIndex,
579
			&nx, &ny, &nw, &nh);
580
581
  if (rectsIntersect(ox, oy, ow, oh, nx, ny, nw, nh)) {
582
    rectsJoin(&ox, &oy, &ow, &oh, nx, ny, nw, nh);
583
    SyncScreenRegion(ox, oy, ow, oh);
584
  }
585
  else {
586
    SyncScreenRegion(ox, oy, ow, oh);
587
    SyncScreenRegion(nx, ny, nw, nh);
588
  }
589
590
  postMouseEvent(cursorX, cursorY, mask);
591
592
  return True;
593
}
594
595
static Bool
596
HandleSoftCursorMove(rfbSoftCursorMove *msg, rfbRectangle *rect) 
597
{
598
  int ii, ox, oy, ow, oh;
599
600
  /* get old cursor rect to know what to update */
601
  getBoundingRectCursor(cursorX, cursorY, imageIndex,
602
			&ox, &oy, &ow, &oh);
603
604
  ii = msg->imageIndex;
605
  if (ii >= rfbSoftCursorMaxImages) {
606
    fprintf(stderr, "Received invalid soft cursor image index %d for Move\n", ii);
607
    return False;
608
  }
609
610
  if (!pointerImages[ii].set)
611
    return True;
612
613
  LockFramebuffer();
614
  undrawCursor();
615
  imageIndex = ii;
616
617
  return PointerMove(rect->w, rect->h, msg->buttonMask, ox, oy, ow, oh);
618
}
619
620
static Bool
621
HandleCursorPos(unsigned int x, unsigned int y) 
622
{
623
  int ox, oy, ow, oh;
624
625
  /* get old cursor rect to know what to update */
626
  getBoundingRectCursor(cursorX, cursorY, imageIndex,
627
			&ox, &oy, &ow, &oh);
628
  if (!pointerImages[0].set)
629
    return True;
630
631
  LockFramebuffer();
632
  undrawCursor();
633
  imageIndex = 0;
634
  return PointerMove(x, y, 0, ox, oy, ow, oh);
635
}
636
637
/* call only from X11 thread. Only updates framebuffer, does not sync! */
638
void DrawCursorX11Thread(int x, int y) {
639
  int ox, oy, ow, oh, nx, ny, nw, nh;
640
  if (!pointerImages[0].set)
641
    return;
642
  imageIndex = 0;
643
644
  if (x >= si.framebufferWidth)
645
    x = si.framebufferWidth - 1;
646
  if (y >= si.framebufferHeight)
647
    y = si.framebufferHeight - 1;
648
649
  LockFramebuffer();
650
  getBoundingRectCursor(cursorX, cursorY, imageIndex,
651
			&ox, &oy, &ow, &oh);
652
  undrawCursor();
653
  cursorX = x;
654
  cursorY = y;
655
  drawCursor();
656
  UnlockFramebuffer();
657
658
  getBoundingRectCursor(cursorX, cursorY, imageIndex,
659
			&nx, &ny, &nw, &nh);
660
  if (rectsIntersect(ox, oy, ow, oh, nx, ny, nw, nh)) {
661
    rectsJoin(&ox, &oy, &ow, &oh, nx, ny, nw, nh);
662
    SyncScreenRegionX11Thread(ox, oy, ow, oh);
663
  }
664
  else {
665
    SyncScreenRegionX11Thread(ox, oy, ow, oh);
666
    SyncScreenRegionX11Thread(nx, ny, nw, nh);
667
  }
668
}
669
670
/**
671
 * Create a softcursor in the "compressed alpha" format.
672
 * Returns the softcursor, caller owns the object
673
 */
674
static void *MakeSoftCursor(int bpp, int cursorWidth, int cursorHeight, 
675
			    CARD8 *cursorData, CARD8 *cursorMask, short *imageLen)
676
{
677
    int w = (cursorWidth+7)/8;
678
    unsigned char *cp, *sp, *dstData;
679
    int state; /* 0 = transparent, 1 otherwise */
680
    CARD8 *counter;
681
    unsigned char bit;
682
    int i,j;
683
    
684
    sp = (unsigned char*)cursorData;
685
    dstData = cp = (unsigned char*)calloc(cursorWidth*(bpp+2),cursorHeight);
686
    if (!dstData)
687
      return 0;
688
689
    state = 0;
690
    counter = cp++;
691
    *counter = 0;
692
    
693
    for(j=0;j<cursorHeight;j++)
694
	for(i=0,bit=0x80;i<cursorWidth;i++,bit=(bit&1)?0x80:bit>>1)
695
	    if(cursorMask[j*w+i/8]&bit) {
696
		if (state) {
697
		    memcpy(cp,sp,bpp);
698
		    cp += bpp;
699
		    sp += bpp;
700
		    (*counter)++;
701
		    if (*counter == 255) {
702
			state = 0;
703
			counter = cp++;
704
			*counter = 0;
705
		    }
706
		}
707
		else {
708
		    state = 1;
709
		    counter = cp++;
710
		    *counter = 1;
711
		    memcpy(cp,sp,bpp);
712
		    cp += bpp;
713
		    sp += bpp;
714
		}
715
	    }
716
	    else {
717
		if (!state) {
718
		    (*counter)++;
719
		    if (*counter == 255) {
720
			state = 1;
721
			counter = cp++;
722
			*counter = 0;
723
		    }
724
		}
725
		else {
726
		    state = 0;
727
		    counter = cp++;
728
		    *counter = 1;
729
		}
730
		sp += bpp;
731
	    }
732
733
    *imageLen = cp - dstData;
734
    return (void*) dstData;
735
}
736
737
738
/*********************************************************************
739
 * HandleCursorShape(). Support for XCursor and RichCursor shape
740
 * updates. We emulate cursor operating on the frame buffer (that is
741
 * why we call it "software cursor").
742
 ********************************************************************/
743
744
static Bool HandleCursorShape(int xhot, int yhot, int width, int height, CARD32 enc)
745
{
746
  int bytesPerPixel;
747
  size_t bytesPerRow, bytesMaskData;
748
  rfbXCursorColors rgb;
749
  CARD32 colors[2];
750
  CARD8 *ptr, *rcSource, *rcMask;
751
  void *softCursor;
752
  int x, y, b;
753
  int ox, oy, ow, oh;
754
  PointerImage *pi;
755
  short imageLen;
756
757
  bytesPerPixel = myFormat.bitsPerPixel / 8;
758
  bytesPerRow = (width + 7) / 8;
759
  bytesMaskData = bytesPerRow * height;
760
761
  if (width * height == 0)
762
    return True;
763
764
  /* Allocate memory for pixel data and temporary mask data. */
765
766
  rcSource = malloc(width * height * bytesPerPixel);
767
  if (rcSource == NULL)
768
    return False;
769
770
  rcMask = malloc(bytesMaskData);
771
  if (rcMask == NULL) {
772
    free(rcSource);
773
    return False;
774
  }
775
776
  /* Read and decode cursor pixel data, depending on the encoding type. */
777
778
  if (enc == rfbEncodingXCursor) {
779
    /* Read and convert background and foreground colors. */
780
    if (!ReadFromRFBServer((char *)&rgb, sz_rfbXCursorColors)) {
781
      free(rcSource);
782
      free(rcMask);
783
      return False;
784
    }
785
    colors[0] = RGB24_TO_PIXEL(32, rgb.backRed, rgb.backGreen, rgb.backBlue);
786
    colors[1] = RGB24_TO_PIXEL(32, rgb.foreRed, rgb.foreGreen, rgb.foreBlue);
787
788
    /* Read 1bpp pixel data into a temporary buffer. */
789
    if (!ReadFromRFBServer((char*)rcMask, bytesMaskData)) {
790
      free(rcSource);
791
      free(rcMask);
792
      return False;
793
    }
794
795
    /* Convert 1bpp data to byte-wide color indices. */
796
    ptr = rcSource;
797
    for (y = 0; y < height; y++) {
798
      for (x = 0; x < width / 8; x++) {
799
	for (b = 7; b >= 0; b--) {
800
	  *ptr = rcMask[y * bytesPerRow + x] >> b & 1;
801
	  ptr += bytesPerPixel;
802
	}
803
      }
804
      for (b = 7; b > 7 - width % 8; b--) {
805
	*ptr = rcMask[y * bytesPerRow + x] >> b & 1;
806
	ptr += bytesPerPixel;
807
      }
808
    }
809
810
    /* Convert indices into the actual pixel values. */
811
    switch (bytesPerPixel) {
812
    case 1:
813
      for (x = 0; x < width * height; x++)
814
	rcSource[x] = (CARD8)colors[rcSource[x]];
815
      break;
816
    case 2:
817
      for (x = 0; x < width * height; x++)
818
	((CARD16 *)rcSource)[x] = (CARD16)colors[rcSource[x * 2]];
819
      break;
820
    case 4:
821
      for (x = 0; x < width * height; x++)
822
	((CARD32 *)rcSource)[x] = colors[rcSource[x * 4]];
823
      break;
824
    }
825
    
826
827
  } else {
828
    if (!ReadFromRFBServer((char *)rcSource, width * height * bytesPerPixel)) {
829
      free(rcSource);
830
      free(rcMask);
831
      return False;
832
    }
833
  }
834
835
  /* Read mask data. */
836
837
  if (!ReadFromRFBServer((char*)rcMask, bytesMaskData)) {
838
    free(rcSource);
839
    free(rcMask);
840
    return False;
841
  }
842
843
844
  /* Set the soft cursor. */
845
  softCursor = MakeSoftCursor(bytesPerPixel, width, height, rcSource, rcMask, &imageLen);
846
  if (!softCursor) {
847
    free(rcMask);
848
    free(rcSource);
849
    return False;
850
  }
851
852
  /* get old cursor rect to know what to update */
853
  EnableClientCursor(1);
854
  LockFramebuffer();
855
  getBoundingRectCursor(cursorX, cursorY, imageIndex,
856
			&ox, &oy, &ow, &oh);
857
  undrawCursor();
858
859
  pi = &pointerImages[0];
860
  if (pi->set && pi->image)
861
    free(pi->image);
862
  pi->w = width;
863
  pi->h = height;
864
  pi->hotX = xhot;
865
  pi->hotY = yhot;
866
  pi->len = imageLen;
867
  pi->image = softCursor;
868
  pi->set = 1;
869
870
  imageIndex = 0;
871
872
  free(rcMask);
873
  free(rcSource);
874
875
  return PointerMove(cursorX, cursorY, 0, ox, oy, ow, oh);
876
}
877
878
879
880
/*
881
 * HandleRFBServerMessage.
882
 */
883
884
Bool
885
HandleRFBServerMessage()
886
{
887
  rfbServerToClientMsg msg;
888
  if (!ReadFromRFBServer((char *)&msg, 1))
889
    return False;
890
891
  switch (msg.type) {
892
893
  case rfbSetColourMapEntries:
894
  {
895
    int i;
896
    CARD16 rgb[3];
897
    XColor xc;
898
899
    if (!ReadFromRFBServer(((char *)&msg) + 1,
900
			   sz_rfbSetColourMapEntriesMsg - 1))
901
      return False;
902
903
    msg.scme.firstColour = Swap16IfLE(msg.scme.firstColour);
904
    msg.scme.nColours = Swap16IfLE(msg.scme.nColours);
905
906
    for (i = 0; i < msg.scme.nColours; i++) {
907
      if (!ReadFromRFBServer((char *)rgb, 6))
908
	return False;
909
      xc.pixel = msg.scme.firstColour + i;
910
      xc.red = Swap16IfLE(rgb[0]);
911
      xc.green = Swap16IfLE(rgb[1]);
912
      xc.blue = Swap16IfLE(rgb[2]);
913
      xc.flags = DoRed|DoGreen|DoBlue;
914
      /* Disable colormaps
915
      lockTQt();
916
      XStoreColor(dpy, cmap, &xc);
917
      unlockTQt();
918
      */
919
    }
920
921
    break;
922
  }
923
924
  case rfbFramebufferUpdate:
925
  {
926
    rfbFramebufferUpdateRectHeader rect;
927
    int linesToRead;
928
    int bytesPerLine;
929
    int i;
930
931
    announceIncrementalUpdateRequest();
932
933
    if (!ReadFromRFBServer(((char *)&msg.fu) + 1,
934
			   sz_rfbFramebufferUpdateMsg - 1))
935
      return False;
936
937
    msg.fu.nRects = Swap16IfLE(msg.fu.nRects);
938
939
    for (i = 0; i < msg.fu.nRects; i++) {
940
      if (!ReadFromRFBServer((char *)&rect, sz_rfbFramebufferUpdateRectHeader))
941
	return False;
942
943
      rect.encoding = Swap32IfLE(rect.encoding);
944
      if (rect.encoding == rfbEncodingLastRect)
945
	break;
946
947
      rect.r.x = Swap16IfLE(rect.r.x);
948
      rect.r.y = Swap16IfLE(rect.r.y);
949
      rect.r.w = Swap16IfLE(rect.r.w);
950
      rect.r.h = Swap16IfLE(rect.r.h);
951
952
      if (rect.encoding == rfbEncodingPointerPos) {
953
        if (!HandleCursorPos(rect.r.x, rect.r.y)) {
954
          return False;
955
        }
956
        continue;
957
      }
958
959
      if (rect.encoding == rfbEncodingXCursor ||
960
	  rect.encoding == rfbEncodingRichCursor) {
961
	if (!HandleCursorShape(rect.r.x, rect.r.y, rect.r.w, rect.r.h,
962
			      rect.encoding)) {
963
	  return False;
964
	}
965
	continue;
966
      }
967
968
      if ((rect.r.x + rect.r.w > si.framebufferWidth) ||
969
	  (rect.r.y + rect.r.h > si.framebufferHeight))
970
	{
971
	  fprintf(stderr,"Rect too large: %dx%d at (%d, %d)\n",
972
		  rect.r.w, rect.r.h, rect.r.x, rect.r.y);
973
	  return False;
974
	}
975
976
      if ((rect.r.h * rect.r.w == 0) && 
977
	  (rect.encoding != rfbEncodingSoftCursor)) {
978
	fprintf(stderr,"Zero size rect - ignoring\n");
979
	continue;
980
      }
981
982
      switch (rect.encoding) {
983
984
      case rfbEncodingRaw:
985
986
	bytesPerLine = rect.r.w * myFormat.bitsPerPixel / 8;
987
	/* RealVNC 4.x-5.x on OSX can induce bytesPerLine==0,
988
	   usually during GPU accel. */
989
	/* Regardless of cause, do not divide by zero. */
990
	linesToRead = bytesPerLine ? (BUFFER_SIZE / bytesPerLine) : 0;
991
992
	while (linesToRead && rect.r.h > 0) {
993
	  if (linesToRead > rect.r.h)
994
	    linesToRead = rect.r.h;
995
996
	  if (!ReadFromRFBServer(buffer,bytesPerLine * linesToRead))
997
	    return False;
998
999
	  CopyDataToScreen(buffer, rect.r.x, rect.r.y, rect.r.w,
1000
			   linesToRead);
1001
1002
	  rect.r.h -= linesToRead;
1003
	  rect.r.y += linesToRead;
1004
1005
	}
1006
	break;
1007
1008
      case rfbEncodingCopyRect:
1009
      {
1010
	rfbCopyRect cr;
1011
1012
	if (!ReadFromRFBServer((char *)&cr, sz_rfbCopyRect))
1013
	  return False;
1014
1015
	cr.srcX = Swap16IfLE(cr.srcX);
1016
	cr.srcY = Swap16IfLE(cr.srcY);
1017
1018
	CopyArea(cr.srcX, cr.srcY, rect.r.w, rect.r.h, rect.r.x, rect.r.y);
1019
1020
	break;
1021
      }
1022
1023
      case rfbEncodingHextile:
1024
      {
1025
	switch (myFormat.bitsPerPixel) {
1026
	case 8:
1027
	  if (!HandleHextile8(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1028
	    return False;
1029
	  break;
1030
	case 16:
1031
	  if (!HandleHextile16(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1032
	    return False;
1033
	  break;
1034
	case 32:
1035
	  if (!HandleHextile32(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1036
	    return False;
1037
	  break;
1038
	}
1039
	break;
1040
      }
1041
1042
      case rfbEncodingZlib:
1043
      {
1044
	switch (myFormat.bitsPerPixel) {
1045
	case 8:
1046
	  if (!HandleZlib8(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1047
	    return False;
1048
	  break;
1049
	case 16:
1050
	  if (!HandleZlib16(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1051
	    return False;
1052
	  break;
1053
	case 32:
1054
	  if (!HandleZlib32(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1055
	    return False;
1056
	  break;
1057
	}
1058
	break;
1059
     }
1060
1061
      case rfbEncodingTight:
1062
      {
1063
	switch (myFormat.bitsPerPixel) {
1064
	case 8:
1065
	  if (!HandleTight8(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1066
	    return False;
1067
	  break;
1068
	case 16:
1069
	  if (!HandleTight16(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1070
	    return False;
1071
	  break;
1072
	case 32:
1073
	  if (!HandleTight32(rect.r.x,rect.r.y,rect.r.w,rect.r.h))
1074
	    return False;
1075
	  break;
1076
	}
1077
	break;
1078
      }
1079
1080
      case rfbEncodingSoftCursor:
1081
      {
1082
	rfbSoftCursorMsg scmsg;
1083
	if (!ReadFromRFBServer((char *)&scmsg, 1))
1084
	  return False;
1085
	if (scmsg.type < rfbSoftCursorMaxImages) {
1086
	  if (!ReadFromRFBServer(((char *)&scmsg)+1, 
1087
				 sizeof(rfbSoftCursorMove)- 1))
1088
	    return False;
1089
	  if (!HandleSoftCursorMove(&scmsg.move, &rect.r))
1090
	    return False;
1091
	}
1092
	else if((scmsg.type >= rfbSoftCursorSetIconOffset) && 
1093
		(scmsg.type < rfbSoftCursorSetIconOffset+rfbSoftCursorMaxImages)) {
1094
	  if (!ReadFromRFBServer(((char *)&scmsg)+1, 
1095
				 sizeof(rfbSoftCursorSetImage)- 1))
1096
	    return False;
1097
	  if (!HandleSoftCursorSetImage(&scmsg.setImage, &rect.r))
1098
	    return False;
1099
	}
1100
	else {
1101
	  fprintf(stderr,"Unknown soft cursor image index %d\n", 
1102
		  (int)scmsg.type);
1103
	  return False;
1104
	}
1105
	break;
1106
      }
1107
1108
      default:
1109
	fprintf(stderr,"Unknown rect encoding %d\n",
1110
		(int)rect.encoding);
1111
	return False;
1112
      }
1113
1114
    }
1115
1116
    queueIncrementalUpdateRequest();
1117
1118
    break;
1119
  }
1120
1121
  case rfbBell:
1122
  {
1123
    beep();
1124
    break;
1125
  }
1126
1127
  case rfbServerCutText:
1128
  {
1129
    char *serverCutText;
1130
    if (!ReadFromRFBServer(((char *)&msg) + 1,
1131
			   sz_rfbServerCutTextMsg - 1))
1132
      return False;
1133
1134
    msg.sct.length = Swap32IfLE(msg.sct.length);
1135
1136
    if (msg.sct.length > MAX_CUTBUFFER) {
1137
      fprintf(stderr, "Cutbuffer too long.\n");
1138
      return False;
1139
    }
1140
1141
    serverCutText = malloc(msg.sct.length+1);
1142
1143
    if (!serverCutText) {
1144
      fprintf(stderr, "Out-of-memory, cutbuffer too long.\n");
1145
      return False;
1146
    }
1147
1148
    if (!ReadFromRFBServer(serverCutText, msg.sct.length)) {
1149
      free(serverCutText);
1150
      return False;
1151
    }
1152
1153
    serverCutText[msg.sct.length] = 0;
1154
    newServerCut(serverCutText, msg.sct.length); /* takes ownership of serverCutText */
1155
1156
    break;
1157
  }
1158
1159
  default:
1160
    fprintf(stderr,"Unknown message type %d from VNC server\n",msg.type);
1161
    return False;
1162
  }
1163
1164
  return True;
1165
}
1166
1167
1168
#define GET_PIXEL8(pix, ptr) ((pix) = *(ptr)++)
1169
1170
#define GET_PIXEL16(pix, ptr) (((CARD8*)&(pix))[0] = *(ptr)++, \
1171
			       ((CARD8*)&(pix))[1] = *(ptr)++)
1172
1173
#define GET_PIXEL32(pix, ptr) (((CARD8*)&(pix))[0] = *(ptr)++, \
1174
			       ((CARD8*)&(pix))[1] = *(ptr)++, \
1175
			       ((CARD8*)&(pix))[2] = *(ptr)++, \
1176
			       ((CARD8*)&(pix))[3] = *(ptr)++)
1177
1178
/* CONCAT2 concatenates its two arguments.  CONCAT2E does the same but also
1179
   expands its arguments if they are macros */
1180
1181
#define CONCAT2(a,b) a##b
1182
#define CONCAT2E(a,b) CONCAT2(a,b)
1183
1184
#define BPP 8
1185
#include "hextile.c"
1186
#include "zlib.c"
1187
#include "tight.c"
1188
#undef BPP
1189
#define BPP 16
1190
#include "hextile.c"
1191
#include "zlib.c"
1192
#include "tight.c"
1193
#undef BPP
1194
#define BPP 32
1195
#include "hextile.c"
1196
#include "zlib.c"
1197
#include "tight.c"
1198
#undef BPP
1199
1200
1201
/*
1202
 * PrintPixelFormat.
1203
 */
1204
1205
void
1206
PrintPixelFormat(format)
1207
    rfbPixelFormat *format;
1208
{
1209
  if (format->bitsPerPixel == 1) {
1210
    fprintf(stderr,"  Single bit per pixel.\n");
1211
    fprintf(stderr,
1212
	    "  %s significant bit in each byte is leftmost on the screen.\n",
1213
	    (format->bigEndian ? "Most" : "Least"));
1214
  } else {
1215
    fprintf(stderr,"  %d bits per pixel.\n",format->bitsPerPixel);
1216
    if (format->bitsPerPixel != 8) {
1217
      fprintf(stderr,"  %s significant byte first in each pixel.\n",
1218
	      (format->bigEndian ? "Most" : "Least"));
1219
    }
1220
    if (format->trueColour) {
1221
      fprintf(stderr,"  True colour: max red %d green %d blue %d",
1222
	      format->redMax, format->greenMax, format->blueMax);
1223
      fprintf(stderr,", shift red %d green %d blue %d\n",
1224
	      format->redShift, format->greenShift, format->blueShift);
1225
    } else {
1226
      fprintf(stderr,"  Colour map (not true colour).\n");
1227
    }
1228
  }
1229
}
1230
1231
static long
1232
ReadCompactLen (void)
1233
{
1234
  long len;
1235
  CARD8 b;
1236
1237
  if (!ReadFromRFBServer((char *)&b, 1))
1238
    return -1;
1239
  len = (int)b & 0x7F;
1240
  if (b & 0x80) {
1241
    if (!ReadFromRFBServer((char *)&b, 1))
1242
      return -1;
1243
    len |= ((int)b & 0x7F) << 7;
1244
    if (b & 0x80) {
1245
      if (!ReadFromRFBServer((char *)&b, 1))
1246
	return -1;
1247
      len |= ((int)b & 0xFF) << 14;
1248
    }
1249
  }
1250
  return len;
1251
}
1252
1253
void freeRFBProtoResources() {
1254
  int i;
1255
1256
  if (desktopName)
1257
    free(desktopName);
1258
  if (raw_buffer)
1259
    free(raw_buffer);
1260
  for (i = 0; i < rfbSoftCursorMaxImages; i++) 
1261
    if (pointerImages[i].set && pointerImages[i].image)
1262
      free(pointerImages[i].image);
1263
1264
  raw_buffer_size = -1;
1265
  raw_buffer = NULL;
1266
  decompStreamInited = False;
1267
  zlibStreamActive[0] = False;
1268
  zlibStreamActive[1] = False;
1269
  zlibStreamActive[2] = False;
1270
  zlibStreamActive[3] = False;
1271
  for (i = 0; i < rfbSoftCursorMaxImages; i++) 
1272
    pointerImages[i].set = 0;
1273
  imageIndex = -1;
1274
}
1275
1276
void freeResources() {
1277
  freeSocketsResources();
1278
  freeDesktopResources();
1279
  freeRFBProtoResources();
1280
}
1281
1282
/*
1283
 * JPEG source manager functions for JPEG decompression in Tight decoder.
1284
 */
1285
1286
static struct jpeg_source_mgr jpegSrcManager;
1287
static JOCTET *jpegBufferPtr;
1288
static size_t jpegBufferLen;
1289
1290
static void
1291
JpegInitSource(j_decompress_ptr cinfo)
1292
{
1293
  jpegError = False;
1294
}
1295
1296
static boolean
1297
JpegFillInputBuffer(j_decompress_ptr cinfo)
1298
{
1299
  jpegError = True;
1300
  jpegSrcManager.bytes_in_buffer = jpegBufferLen;
1301
  jpegSrcManager.next_input_byte = (JOCTET *)jpegBufferPtr;
1302
1303
  return TRUE;
1304
}
1305
1306
static void
1307
JpegSkipInputData(j_decompress_ptr cinfo, long num_bytes)
1308
{
1309
  if (num_bytes < 0 || num_bytes > jpegSrcManager.bytes_in_buffer) {
1310
    jpegError = True;
1311
    jpegSrcManager.bytes_in_buffer = jpegBufferLen;
1312
    jpegSrcManager.next_input_byte = (JOCTET *)jpegBufferPtr;
1313
  } else {
1314
    jpegSrcManager.next_input_byte += (size_t) num_bytes;
1315
    jpegSrcManager.bytes_in_buffer -= (size_t) num_bytes;
1316
  }
1317
}
1318
1319
static void
1320
JpegTermSource(j_decompress_ptr cinfo)
1321
{
1322
  /* No work necessary here. */
1323
}
1324
1325
static void
1326
JpegSetSrcManager(j_decompress_ptr cinfo, CARD8 *compressedData,
1327
		  int compressedLen)
1328
{
1329
  jpegBufferPtr = (JOCTET *)compressedData;
1330
  jpegBufferLen = (size_t)compressedLen;
1331
1332
  jpegSrcManager.init_source = JpegInitSource;
1333
  jpegSrcManager.fill_input_buffer = JpegFillInputBuffer;
1334
  jpegSrcManager.skip_input_data = JpegSkipInputData;
1335
  jpegSrcManager.resync_to_restart = jpeg_resync_to_restart;
1336
  jpegSrcManager.term_source = JpegTermSource;
1337
  jpegSrcManager.next_input_byte = jpegBufferPtr;
1338
  jpegSrcManager.bytes_in_buffer = jpegBufferLen;
1339
1340
  cinfo->src = &jpegSrcManager;
1341
}
1342
(-)tdenetwork-trinity-14.1.0-ORIG/krdc/vnc/rfbproto.h (+957 lines)
Line 0 Link Here
1
/*
2
 *  Copyright (C) 2000-2002 Constantin Kaplinsky.  All Rights Reserved.
3
 *  Copyright (C) 2000 Tridia Corporation.  All Rights Reserved.
4
 *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
5
 *
6
 *  This is free software; you can redistribute it and/or modify
7
 *  it under the terms of the GNU General Public License as published by
8
 *  the Free Software Foundation; either version 2 of the License, or
9
 *  (at your option) any later version.
10
 *
11
 *  This software is distributed in the hope that it will be useful,
12
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 *  GNU General Public License for more details.
15
 *
16
 *  You should have received a copy of the GNU General Public License
17
 *  along with this software; if not, write to the Free Software
18
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
19
 *  USA.
20
 */
21
22
/*
23
 * rfbproto.h - header file for the RFB protocol version 3.3
24
 *
25
 * Uses types CARD<n> for an n-bit unsigned integer, INT<n> for an n-bit signed
26
 * integer (for n = 8, 16 and 32).
27
 *
28
 * All multiple byte integers are in big endian (network) order (most
29
 * significant byte first).  Unless noted otherwise there is no special
30
 * alignment of protocol structures.
31
 *
32
 *
33
 * Once the initial handshaking is done, all messages start with a type byte,
34
 * (usually) followed by message-specific data.  The order of definitions in
35
 * this file is as follows:
36
 *
37
 *  (1) Structures used in several types of message.
38
 *  (2) Structures used in the initial handshaking.
39
 *  (3) Message types.
40
 *  (4) Encoding types.
41
 *  (5) For each message type, the form of the data following the type byte.
42
 *      Sometimes this is defined by a single structure but the more complex
43
 *      messages have to be explained by comments.
44
 */
45
46
#include "vnctypes.h"
47
48
/*****************************************************************************
49
 *
50
 * Structures used in several messages
51
 *
52
 *****************************************************************************/
53
54
/*-----------------------------------------------------------------------------
55
 * Structure used to specify a rectangle.  This structure is a multiple of 4
56
 * bytes so that it can be interspersed with 32-bit pixel data without
57
 * affecting alignment.
58
 */
59
60
typedef struct {
61
    CARD16 x;
62
    CARD16 y;
63
    CARD16 w;
64
    CARD16 h;
65
} rfbRectangle;
66
67
#define sz_rfbRectangle 8
68
69
70
/*-----------------------------------------------------------------------------
71
 * Structure used to specify pixel format.
72
 */
73
74
typedef struct {
75
76
    CARD8 bitsPerPixel;		/* 8,16,32 only */
77
78
    CARD8 depth;		/* 8 to 32 */
79
80
    CARD8 bigEndian;		/* True if multi-byte pixels are interpreted
81
				   as big endian, or if single-bit-per-pixel
82
				   has most significant bit of the byte
83
				   corresponding to first (leftmost) pixel. Of
84
				   course this is meaningless for 8 bits/pix */
85
86
    CARD8 trueColour;		/* If false then we need a "colour map" to
87
				   convert pixels to RGB.  If true, xxxMax and
88
				   xxxShift specify bits used for red, green
89
				   and blue */
90
91
    /* the following fields are only meaningful if trueColour is true */
92
93
    CARD16 redMax;		/* maximum red value (= 2^n - 1 where n is the
94
				   number of bits used for red). Note this
95
				   value is always in big endian order. */
96
97
    CARD16 greenMax;		/* similar for green */
98
99
    CARD16 blueMax;		/* and blue */
100
101
    CARD8 redShift;		/* number of shifts needed to get the red
102
				   value in a pixel to the least significant
103
				   bit. To find the red value from a given
104
				   pixel, do the following:
105
				   1) Swap pixel value according to bigEndian
106
				      (e.g. if bigEndian is false and host byte
107
				      order is big endian, then swap).
108
				   2) Shift right by redShift.
109
				   3) AND with redMax (in host byte order).
110
				   4) You now have the red value between 0 and
111
				      redMax. */
112
113
    CARD8 greenShift;		/* similar for green */
114
115
    CARD8 blueShift;		/* and blue */
116
117
    CARD8 pad1;
118
    CARD16 pad2;
119
120
} rfbPixelFormat;
121
122
#define sz_rfbPixelFormat 16
123
124
125
126
/*****************************************************************************
127
 *
128
 * Initial handshaking messages
129
 *
130
 *****************************************************************************/
131
132
/*-----------------------------------------------------------------------------
133
 * Protocol Version
134
 *
135
 * The server always sends 12 bytes to start which identifies the latest RFB
136
 * protocol version number which it supports.  These bytes are interpreted
137
 * as a string of 12 ASCII characters in the format "RFB xxx.yyy\n" where
138
 * xxx and yyy are the major and minor version numbers (for version 3.3
139
 * this is "RFB 003.003\n").
140
 *
141
 * The client then replies with a similar 12-byte message giving the version
142
 * number of the protocol which should actually be used (which may be different
143
 * to that quoted by the server).
144
 *
145
 * It is intended that both clients and servers may provide some level of
146
 * backwards compatibility by this mechanism.  Servers in particular should
147
 * attempt to provide backwards compatibility, and even forwards compatibility
148
 * to some extent.  For example if a client demands version 3.1 of the
149
 * protocol, a 3.0 server can probably assume that by ignoring requests for
150
 * encoding types it doesn't understand, everything will still work OK.  This
151
 * will probably not be the case for changes in the major version number.
152
 *
153
 * The format string below can be used in sprintf or sscanf to generate or
154
 * decode the version string respectively.
155
 */
156
157
#define rfbProtocolVersionFormat "RFB %03d.%03d\n"
158
#define rfbProtocolMajorVersion 3
159
#define rfbProtocolMinorVersion 3
160
161
typedef char rfbProtocolVersionMsg[13];	/* allow extra byte for null */
162
163
#define sz_rfbProtocolVersionMsg 12
164
165
166
/*-----------------------------------------------------------------------------
167
 * Authentication
168
 *
169
 * Once the protocol version has been decided, the server then sends a 32-bit
170
 * word indicating whether any authentication is needed on the connection.
171
 * The value of this word determines the authentication scheme in use.  For
172
 * version 3.0 of the protocol this may have one of the following values:
173
 */
174
175
#define rfbConnFailed 0
176
#define rfbNoAuth 1
177
#define rfbVncAuth 2
178
179
/*
180
 * rfbConnFailed:	For some reason the connection failed (e.g. the server
181
 *			cannot support the desired protocol version).  This is
182
 *			followed by a string describing the reason (where a
183
 *			string is specified as a 32-bit length followed by that
184
 *			many ASCII characters).
185
 *
186
 * rfbNoAuth:		No authentication is needed.
187
 *
188
 * rfbVncAuth:		The VNC authentication scheme is to be used.  A 16-byte
189
 *			challenge follows, which the client encrypts as
190
 *			appropriate using the password and sends the resulting
191
 *			16-byte response.  If the response is correct, the
192
 *			server sends the 32-bit word rfbVncAuthOK.  If a simple
193
 *			failure happens, the server sends rfbVncAuthFailed and
194
 *			closes the connection. If the server decides that too
195
 *			many failures have occurred, it sends rfbVncAuthTooMany
196
 *			and closes the connection.  In the latter case, the
197
 *			server should not allow an immediate reconnection by
198
 *			the client.
199
 */
200
201
#define rfbVncAuthOK 0
202
#define rfbVncAuthFailed 1
203
#define rfbVncAuthTooMany 2
204
205
206
/*-----------------------------------------------------------------------------
207
 * Client Initialisation Message
208
 *
209
 * Once the client and server are sure that they're happy to talk to one
210
 * another, the client sends an initialisation message.  At present this
211
 * message only consists of a boolean indicating whether the server should try
212
 * to share the desktop by leaving other clients connected, or give exclusive
213
 * access to this client by disconnecting all other clients.
214
 */
215
216
typedef struct {
217
    CARD8 shared;
218
} rfbClientInitMsg;
219
220
#define sz_rfbClientInitMsg 1
221
222
223
/*-----------------------------------------------------------------------------
224
 * Server Initialisation Message
225
 *
226
 * After the client initialisation message, the server sends one of its own.
227
 * This tells the client the width and height of the server's framebuffer,
228
 * its pixel format and the name associated with the desktop.
229
 */
230
231
typedef struct {
232
    CARD16 framebufferWidth;
233
    CARD16 framebufferHeight;
234
    rfbPixelFormat format;	/* the server's preferred pixel format */
235
    CARD32 nameLength;
236
    /* followed by char name[nameLength] */
237
} rfbServerInitMsg;
238
239
#define sz_rfbServerInitMsg (8 + sz_rfbPixelFormat)
240
241
242
/*
243
 * Following the server initialisation message it's up to the client to send
244
 * whichever protocol messages it wants.  Typically it will send a
245
 * SetPixelFormat message and a SetEncodings message, followed by a
246
 * FramebufferUpdateRequest.  From then on the server will send
247
 * FramebufferUpdate messages in response to the client's
248
 * FramebufferUpdateRequest messages.  The client should send
249
 * FramebufferUpdateRequest messages with incremental set to true when it has
250
 * finished processing one FramebufferUpdate and is ready to process another.
251
 * With a fast client, the rate at which FramebufferUpdateRequests are sent
252
 * should be regulated to avoid hogging the network.
253
 */
254
255
256
257
/*****************************************************************************
258
 *
259
 * Message types
260
 *
261
 *****************************************************************************/
262
263
/* server -> client */
264
265
#define rfbFramebufferUpdate 0
266
#define rfbSetColourMapEntries 1
267
#define rfbBell 2
268
#define rfbServerCutText 3
269
270
271
/* client -> server */
272
273
#define rfbSetPixelFormat 0
274
#define rfbFixColourMapEntries 1	/* not currently supported */
275
#define rfbSetEncodings 2
276
#define rfbFramebufferUpdateRequest 3
277
#define rfbKeyEvent 4
278
#define rfbPointerEvent 5
279
#define rfbClientCutText 6
280
281
282
283
284
/*****************************************************************************
285
 *
286
 * Encoding types
287
 *
288
 *****************************************************************************/
289
290
#define rfbEncodingRaw 0
291
#define rfbEncodingCopyRect 1
292
#define rfbEncodingRRE 2
293
#define rfbEncodingCoRRE 4
294
#define rfbEncodingHextile 5
295
#define rfbEncodingZlib 6
296
#define rfbEncodingTight 7
297
#define rfbEncodingZlibHex 8
298
299
/*
300
 * Special encoding numbers:
301
 *   0xFFFFFF00 .. 0xFFFFFF0F -- encoding-specific compression levels;
302
 *   0xFFFFFF10 .. 0xFFFFFF1F -- mouse cursor shape data;
303
 *   0xFFFFFF20 .. 0xFFFFFF2F -- various protocol extensions;
304
 *   0xFFFFFF30 .. 0xFFFFFFDF -- not allocated yet;
305
 *   0xFFFFFFE0 .. 0xFFFFFFEF -- quality level for JPEG compressor;
306
 *   0xFFFFFFF0 .. 0xFFFFFFFF -- cross-encoding compression levels.
307
 */
308
309
#define rfbEncodingCompressLevel0  0xFFFFFF00
310
#define rfbEncodingCompressLevel1  0xFFFFFF01
311
#define rfbEncodingCompressLevel2  0xFFFFFF02
312
#define rfbEncodingCompressLevel3  0xFFFFFF03
313
#define rfbEncodingCompressLevel4  0xFFFFFF04
314
#define rfbEncodingCompressLevel5  0xFFFFFF05
315
#define rfbEncodingCompressLevel6  0xFFFFFF06
316
#define rfbEncodingCompressLevel7  0xFFFFFF07
317
#define rfbEncodingCompressLevel8  0xFFFFFF08
318
#define rfbEncodingCompressLevel9  0xFFFFFF09
319
320
#define rfbEncodingXCursor         0xFFFFFF10
321
#define rfbEncodingRichCursor      0xFFFFFF11
322
#define rfbEncodingSoftCursor      0xFFFFFF12
323
#define rfbEncodingPointerPos      0xFFFFFF18
324
325
#define rfbEncodingLastRect        0xFFFFFF20
326
#define rfbEncodingBackground      0xFFFFFF25
327
328
#define rfbEncodingQualityLevel0   0xFFFFFFE0
329
#define rfbEncodingQualityLevel1   0xFFFFFFE1
330
#define rfbEncodingQualityLevel2   0xFFFFFFE2
331
#define rfbEncodingQualityLevel3   0xFFFFFFE3
332
#define rfbEncodingQualityLevel4   0xFFFFFFE4
333
#define rfbEncodingQualityLevel5   0xFFFFFFE5
334
#define rfbEncodingQualityLevel6   0xFFFFFFE6
335
#define rfbEncodingQualityLevel7   0xFFFFFFE7
336
#define rfbEncodingQualityLevel8   0xFFFFFFE8
337
#define rfbEncodingQualityLevel9   0xFFFFFFE9
338
339
340
/*****************************************************************************
341
 *
342
 * Server -> client message definitions
343
 *
344
 *****************************************************************************/
345
346
347
/*-----------------------------------------------------------------------------
348
 * FramebufferUpdate - a block of rectangles to be copied to the framebuffer.
349
 *
350
 * This message consists of a header giving the number of rectangles of pixel
351
 * data followed by the rectangles themselves.  The header is padded so that
352
 * together with the type byte it is an exact multiple of 4 bytes (to help
353
 * with alignment of 32-bit pixels):
354
 */
355
356
typedef struct {
357
    CARD8 type;			/* always rfbFramebufferUpdate */
358
    CARD8 pad;
359
    CARD16 nRects;
360
    /* followed by nRects rectangles */
361
} rfbFramebufferUpdateMsg;
362
363
#define sz_rfbFramebufferUpdateMsg 4
364
365
/*
366
 * Each rectangle of pixel data consists of a header describing the position
367
 * and size of the rectangle and a type word describing the encoding of the
368
 * pixel data, followed finally by the pixel data.  Note that if the client has
369
 * not sent a SetEncodings message then it will only receive raw pixel data.
370
 * Also note again that this structure is a multiple of 4 bytes.
371
 */
372
373
typedef struct {
374
    rfbRectangle r;
375
    CARD32 encoding;	/* one of the encoding types rfbEncoding... */
376
} rfbFramebufferUpdateRectHeader;
377
378
#define sz_rfbFramebufferUpdateRectHeader (sz_rfbRectangle + 4)
379
380
381
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
382
 * Raw Encoding.  Pixels are sent in top-to-bottom scanline order,
383
 * left-to-right within a scanline with no padding in between.
384
 */
385
386
387
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
388
 * CopyRect Encoding.  The pixels are specified simply by the x and y position
389
 * of the source rectangle.
390
 */
391
392
typedef struct {
393
    CARD16 srcX;
394
    CARD16 srcY;
395
} rfbCopyRect;
396
397
#define sz_rfbCopyRect 4
398
399
400
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
401
 * RRE - Rise-and-Run-length Encoding.  We have an rfbRREHeader structure
402
 * giving the number of subrectangles following.  Finally the data follows in
403
 * the form [<bgpixel><subrect><subrect>...] where each <subrect> is
404
 * [<pixel><rfbRectangle>].
405
 */
406
407
typedef struct {
408
    CARD32 nSubrects;
409
} rfbRREHeader;
410
411
#define sz_rfbRREHeader 4
412
413
414
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
415
 * CoRRE - Compact RRE Encoding.  We have an rfbRREHeader structure giving
416
 * the number of subrectangles following.  Finally the data follows in the form
417
 * [<bgpixel><subrect><subrect>...] where each <subrect> is
418
 * [<pixel><rfbCoRRERectangle>].  This means that
419
 * the whole rectangle must be at most 255x255 pixels.
420
 */
421
422
typedef struct {
423
    CARD8 x;
424
    CARD8 y;
425
    CARD8 w;
426
    CARD8 h;
427
} rfbCoRRERectangle;
428
429
#define sz_rfbCoRRERectangle 4
430
431
432
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
433
 * Hextile Encoding.  The rectangle is divided up into "tiles" of 16x16 pixels,
434
 * starting at the top left going in left-to-right, top-to-bottom order.  If
435
 * the width of the rectangle is not an exact multiple of 16 then the width of
436
 * the last tile in each row will be correspondingly smaller.  Similarly if the
437
 * height is not an exact multiple of 16 then the height of each tile in the
438
 * final row will also be smaller.  Each tile begins with a "subencoding" type
439
 * byte, which is a mask made up of a number of bits.  If the Raw bit is set
440
 * then the other bits are irrelevant; w*h pixel values follow (where w and h
441
 * are the width and height of the tile).  Otherwise the tile is encoded in a
442
 * similar way to RRE, except that the position and size of each subrectangle
443
 * can be specified in just two bytes.  The other bits in the mask are as
444
 * follows:
445
 *
446
 * BackgroundSpecified - if set, a pixel value follows which specifies
447
 *    the background colour for this tile.  The first non-raw tile in a
448
 *    rectangle must have this bit set.  If this bit isn't set then the
449
 *    background is the same as the last tile.
450
 *
451
 * ForegroundSpecified - if set, a pixel value follows which specifies
452
 *    the foreground colour to be used for all subrectangles in this tile.
453
 *    If this bit is set then the SubrectsColoured bit must be zero.
454
 *
455
 * AnySubrects - if set, a single byte follows giving the number of
456
 *    subrectangles following.  If not set, there are no subrectangles (i.e.
457
 *    the whole tile is just solid background colour).
458
 *
459
 * SubrectsColoured - if set then each subrectangle is preceded by a pixel
460
 *    value giving the colour of that subrectangle.  If not set, all
461
 *    subrectangles are the same colour, the foreground colour;  if the
462
 *    ForegroundSpecified bit wasn't set then the foreground is the same as
463
 *    the last tile.
464
 *
465
 * The position and size of each subrectangle is specified in two bytes.  The
466
 * Pack macros below can be used to generate the two bytes from x, y, w, h,
467
 * and the Extract macros can be used to extract the x, y, w, h values from
468
 * the two bytes.
469
 */
470
471
#define rfbHextileRaw			(1 << 0)
472
#define rfbHextileBackgroundSpecified	(1 << 1)
473
#define rfbHextileForegroundSpecified	(1 << 2)
474
#define rfbHextileAnySubrects		(1 << 3)
475
#define rfbHextileSubrectsColoured	(1 << 4)
476
477
#define rfbHextilePackXY(x,y) (((x) << 4) | (y))
478
#define rfbHextilePackWH(w,h) ((((w)-1) << 4) | ((h)-1))
479
#define rfbHextileExtractX(byte) ((byte) >> 4)
480
#define rfbHextileExtractY(byte) ((byte) & 0xf)
481
#define rfbHextileExtractW(byte) (((byte) >> 4) + 1)
482
#define rfbHextileExtractH(byte) (((byte) & 0xf) + 1)
483
484
485
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
486
 * zlib - zlib compressed Encoding.  We have an rfbZlibHeader structure
487
 * giving the number of bytes following.  Finally the data follows is
488
 * zlib compressed version of the raw pixel data as negotiated.
489
 */
490
491
typedef struct {
492
    CARD32 nBytes;
493
} rfbZlibHeader;
494
495
#define sz_rfbZlibHeader 4
496
497
498
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
499
 * Tight Encoding.
500
 *
501
 *-- The first byte of each Tight-encoded rectangle is a "compression control
502
 *   byte". Its format is as follows (bit 0 is the least significant one):
503
 *
504
 *   bit 0:    if 1, then compression stream 0 should be reset;
505
 *   bit 1:    if 1, then compression stream 1 should be reset;
506
 *   bit 2:    if 1, then compression stream 2 should be reset;
507
 *   bit 3:    if 1, then compression stream 3 should be reset;
508
 *   bits 7-4: if 1000 (0x08), then the compression type is "fill",
509
 *             if 1001 (0x09), then the compression type is "jpeg",
510
 *             if 0xxx, then the compression type is "basic",
511
 *             values greater than 1001 are not valid.
512
 *
513
 * If the compression type is "basic", then bits 6..4 of the
514
 * compression control byte (those xxx in 0xxx) specify the following:
515
 *
516
 *   bits 5-4:  decimal representation is the index of a particular zlib
517
 *              stream which should be used for decompressing the data;
518
 *   bit 6:     if 1, then a "filter id" byte is following this byte.
519
 *
520
 *-- The data that follows after the compression control byte described
521
 * above depends on the compression type ("fill", "jpeg" or "basic").
522
 *
523
 *-- If the compression type is "fill", then the only pixel value follows, in
524
 * client pixel format (see NOTE 1). This value applies to all pixels of the
525
 * rectangle.
526
 *
527
 *-- If the compression type is "jpeg", the following data stream looks like
528
 * this:
529
 *
530
 *   1..3 bytes:  data size (N) in compact representation;
531
 *   N bytes:     JPEG image.
532
 *
533
 * Data size is compactly represented in one, two or three bytes, according
534
 * to the following scheme:
535
 *
536
 *  0xxxxxxx                    (for values 0..127)
537
 *  1xxxxxxx 0yyyyyyy           (for values 128..16383)
538
 *  1xxxxxxx 1yyyyyyy zzzzzzzz  (for values 16384..4194303)
539
 *
540
 * Here each character denotes one bit, xxxxxxx are the least significant 7
541
 * bits of the value (bits 0-6), yyyyyyy are bits 7-13, and zzzzzzzz are the
542
 * most significant 8 bits (bits 14-21). For example, decimal value 10000
543
 * should be represented as two bytes: binary 10010000 01001110, or
544
 * hexadecimal 90 4E.
545
 *
546
 *-- If the compression type is "basic" and bit 6 of the compression control
547
 * byte was set to 1, then the next (second) byte specifies "filter id" which
548
 * tells the decoder what filter type was used by the encoder to pre-process
549
 * pixel data before the compression. The "filter id" byte can be one of the
550
 * following:
551
 *
552
 *   0:  no filter ("copy" filter);
553
 *   1:  "palette" filter;
554
 *   2:  "gradient" filter.
555
 *
556
 *-- If bit 6 of the compression control byte is set to 0 (no "filter id"
557
 * byte), or if the filter id is 0, then raw pixel values in the client
558
 * format (see NOTE 1) will be compressed. See below details on the
559
 * compression.
560
 *
561
 *-- The "gradient" filter pre-processes pixel data with a simple algorithm
562
 * which converts each color component to a difference between a "predicted"
563
 * intensity and the actual intensity. Such a technique does not affect
564
 * uncompressed data size, but helps to compress photo-like images better. 
565
 * Pseudo-code for converting intensities to differences is the following:
566
 *
567
 *   P[i,j] := V[i-1,j] + V[i,j-1] - V[i-1,j-1];
568
 *   if (P[i,j] < 0) then P[i,j] := 0;
569
 *   if (P[i,j] > MAX) then P[i,j] := MAX;
570
 *   D[i,j] := V[i,j] - P[i,j];
571
 *
572
 * Here V[i,j] is the intensity of a color component for a pixel at
573
 * coordinates (i,j). MAX is the maximum value of intensity for a color
574
 * component.
575
 *
576
 *-- The "palette" filter converts true-color pixel data to indexed colors
577
 * and a palette which can consist of 2..256 colors. If the number of colors
578
 * is 2, then each pixel is encoded in 1 bit, otherwise 8 bits is used to
579
 * encode one pixel. 1-bit encoding is performed such way that the most
580
 * significant bits correspond to the leftmost pixels, and each raw of pixels
581
 * is aligned to the byte boundary. When "palette" filter is used, the
582
 * palette is sent before the pixel data. The palette begins with an unsigned
583
 * byte which value is the number of colors in the palette minus 1 (i.e. 1
584
 * means 2 colors, 255 means 256 colors in the palette). Then follows the
585
 * palette itself which consist of pixel values in client pixel format (see
586
 * NOTE 1).
587
 *
588
 *-- The pixel data is compressed using the zlib library. But if the data
589
 * size after applying the filter but before the compression is less then 12,
590
 * then the data is sent as is, uncompressed. Four separate zlib streams
591
 * (0..3) can be used and the decoder should read the actual stream id from
592
 * the compression control byte (see NOTE 2).
593
 *
594
 * If the compression is not used, then the pixel data is sent as is,
595
 * otherwise the data stream looks like this:
596
 *
597
 *   1..3 bytes:  data size (N) in compact representation;
598
 *   N bytes:     zlib-compressed data.
599
 *
600
 * Data size is compactly represented in one, two or three bytes, just like
601
 * in the "jpeg" compression method (see above).
602
 *
603
 *-- NOTE 1. If the color depth is 24, and all three color components are
604
 * 8-bit wide, then one pixel in Tight encoding is always represented by
605
 * three bytes, where the first byte is red component, the second byte is
606
 * green component, and the third byte is blue component of the pixel color
607
 * value. This applies to colors in palettes as well.
608
 *
609
 *-- NOTE 2. The decoder must reset compression streams' states before
610
 * decoding the rectangle, if some of bits 0,1,2,3 in the compression control
611
 * byte are set to 1. Note that the decoder must reset zlib streams even if
612
 * the compression type is "fill" or "jpeg".
613
 *
614
 *-- NOTE 3. The "gradient" filter and "jpeg" compression may be used only
615
 * when bits-per-pixel value is either 16 or 32, not 8.
616
 *
617
 *-- NOTE 4. The width of any Tight-encoded rectangle cannot exceed 2048
618
 * pixels. If a rectangle is wider, it must be split into several rectangles
619
 * and each one should be encoded separately.
620
 *
621
 */
622
623
#define rfbTightExplicitFilter         0x04
624
#define rfbTightFill                   0x08
625
#define rfbTightJpeg                   0x09
626
#define rfbTightMaxSubencoding         0x09
627
628
/* Filters to improve compression efficiency */
629
#define rfbTightFilterCopy             0x00
630
#define rfbTightFilterPalette          0x01
631
#define rfbTightFilterGradient         0x02
632
633
634
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
635
 * XCursor encoding. This is a special encoding used to transmit X-style
636
 * cursor shapes from server to clients. Note that for this encoding,
637
 * coordinates in rfbFramebufferUpdateRectHeader structure hold hotspot
638
 * position (r.x, r.y) and cursor size (r.w, r.h). If (w * h != 0), two RGB
639
 * samples are sent after header in the rfbXCursorColors structure. They
640
 * denote foreground and background colors of the cursor. If a client
641
 * supports only black-and-white cursors, it should ignore these colors and
642
 * assume that foreground is black and background is white. Next, two bitmaps
643
 * (1 bits per pixel) follow: first one with actual data (value 0 denotes
644
 * background color, value 1 denotes foreground color), second one with
645
 * transparency data (bits with zero value mean that these pixels are
646
 * transparent). Both bitmaps represent cursor data in a byte stream, from
647
 * left to right, from top to bottom, and each row is byte-aligned. Most
648
 * significant bits correspond to leftmost pixels. The number of bytes in
649
 * each row can be calculated as ((w + 7) / 8). If (w * h == 0), cursor
650
 * should be hidden (or default local cursor should be set by the client).
651
 */
652
653
typedef struct {
654
    CARD8 foreRed;
655
    CARD8 foreGreen;
656
    CARD8 foreBlue;
657
    CARD8 backRed;
658
    CARD8 backGreen;
659
    CARD8 backBlue;
660
} rfbXCursorColors;
661
662
#define sz_rfbXCursorColors 6
663
664
665
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
666
 * RichCursor encoding. This is a special encoding used to transmit cursor
667
 * shapes from server to clients. It is similar to the XCursor encoding but
668
 * uses client pixel format instead of two RGB colors to represent cursor
669
 * image. For this encoding, coordinates in rfbFramebufferUpdateRectHeader
670
 * structure hold hotspot position (r.x, r.y) and cursor size (r.w, r.h).
671
 * After header, two pixmaps follow: first one with cursor image in current
672
 * client pixel format (like in raw encoding), second with transparency data
673
 * (1 bit per pixel, exactly the same format as used for transparency bitmap
674
 * in the XCursor encoding). If (w * h == 0), cursor should be hidden (or
675
 * default local cursor should be set by the client).
676
 */
677
678
679
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
680
 * SoftCursor encoding. This encoding is used to transmit image and position 
681
 * of the remote cursor. It has two sub-messages: SetImage is used to upload
682
 * one of 16 images, and Move selects the image and sets the position of the
683
 * cursor. 
684
 * Each SoftCursor message starts with a CARD8. If it is in the 0-15 range
685
 * it specifies the number of the cursor image and is followed by the 
686
 * rfbSoftCursorMove message. If the given cursor has not been set yet the 
687
 * message will be ignored. If the first CARD8 is in the 128-143 range it 
688
 * specifies the cursor that will be set in the following 
689
 * rfbSoftCursorSetImage message. To hide the cursor send a SetImage
690
 * message with width and height 0 and imageLength 0.
691
 * SetImage transmits the hotspot coordinates in the x/y fields of the
692
 * rfbFramebufferUpdateRectHeader, width and height of the image are in the
693
 * header's width and height fields.
694
 * Move transmits the pointer coordinates in the w/h fields of the
695
 * header, x/y are always 0.
696
 */
697
698
typedef struct {
699
  CARD8 imageIndex;
700
  CARD8 buttonMask; /* bits 0-7 are buttons 1-8, 0=up, 1=down */
701
} rfbSoftCursorMove;
702
703
typedef struct {
704
  CARD8 imageIndex;
705
  CARD8 padding;
706
  CARD16 imageLength;
707
  /* 
708
   * Followed by an image of the cursor in the client's image format
709
   * with the following RLE mask compression. It begins with CARD8 that
710
   * specifies the number of mask'ed pixels that will be NOT transmitted.
711
   * Then follows a CARD8 that specified by the number of unmask'd pixels 
712
   * that will be transmitted next. Then a CARD8 with the number of mask'd 
713
   * pixels and so on. 
714
   */
715
} rfbSoftCursorSetImage;
716
717
typedef union {
718
  CARD8 type;
719
  rfbSoftCursorMove move;
720
  rfbSoftCursorSetImage setImage;
721
} rfbSoftCursorMsg;
722
723
#define rfbSoftCursorMaxImages    16
724
#define rfbSoftCursorSetIconOffset    128
725
726
/*-----------------------------------------------------------------------------
727
 * SetColourMapEntries - these messages are only sent if the pixel
728
 * format uses a "colour map" (i.e. trueColour false) and the client has not
729
 * fixed the entire colour map using FixColourMapEntries.  In addition they
730
 * will only start being sent after the client has sent its first
731
 * FramebufferUpdateRequest.  So if the client always tells the server to use
732
 * trueColour then it never needs to process this type of message.
733
 */
734
735
typedef struct {
736
    CARD8 type;			/* always rfbSetColourMapEntries */
737
    CARD8 pad;
738
    CARD16 firstColour;
739
    CARD16 nColours;
740
741
    /* Followed by nColours * 3 * CARD16
742
       r1, g1, b1, r2, g2, b2, r3, g3, b3, ..., rn, bn, gn */
743
744
} rfbSetColourMapEntriesMsg;
745
746
#define sz_rfbSetColourMapEntriesMsg 6
747
748
749
750
/*-----------------------------------------------------------------------------
751
 * Bell - ring a bell on the client if it has one.
752
 */
753
754
typedef struct {
755
    CARD8 type;			/* always rfbBell */
756
} rfbBellMsg;
757
758
#define sz_rfbBellMsg 1
759
760
761
762
/*-----------------------------------------------------------------------------
763
 * ServerCutText - the server has new text in its cut buffer.
764
 */
765
766
typedef struct {
767
    CARD8 type;			/* always rfbServerCutText */
768
    CARD8 pad1;
769
    CARD16 pad2;
770
    CARD32 length;
771
    /* followed by char text[length] */
772
} rfbServerCutTextMsg;
773
774
#define sz_rfbServerCutTextMsg 8
775
776
777
/*-----------------------------------------------------------------------------
778
 * Union of all server->client messages.
779
 */
780
781
typedef union {
782
    CARD8 type;
783
    rfbFramebufferUpdateMsg fu;
784
    rfbSetColourMapEntriesMsg scme;
785
    rfbBellMsg b;
786
    rfbServerCutTextMsg sct;
787
} rfbServerToClientMsg;
788
789
790
791
/*****************************************************************************
792
 *
793
 * Message definitions (client -> server)
794
 *
795
 *****************************************************************************/
796
797
798
/*-----------------------------------------------------------------------------
799
 * SetPixelFormat - tell the RFB server the format in which the client wants
800
 * pixels sent.
801
 */
802
803
typedef struct {
804
    CARD8 type;			/* always rfbSetPixelFormat */
805
    CARD8 pad1;
806
    CARD16 pad2;
807
    rfbPixelFormat format;
808
} rfbSetPixelFormatMsg;
809
810
#define sz_rfbSetPixelFormatMsg (sz_rfbPixelFormat + 4)
811
812
813
/*-----------------------------------------------------------------------------
814
 * FixColourMapEntries - when the pixel format uses a "colour map", fix
815
 * read-only colour map entries.
816
 *
817
 *    ***************** NOT CURRENTLY SUPPORTED *****************
818
 */
819
820
typedef struct {
821
    CARD8 type;			/* always rfbFixColourMapEntries */
822
    CARD8 pad;
823
    CARD16 firstColour;
824
    CARD16 nColours;
825
826
    /* Followed by nColours * 3 * CARD16
827
       r1, g1, b1, r2, g2, b2, r3, g3, b3, ..., rn, bn, gn */
828
829
} rfbFixColourMapEntriesMsg;
830
831
#define sz_rfbFixColourMapEntriesMsg 6
832
833
834
/*-----------------------------------------------------------------------------
835
 * SetEncodings - tell the RFB server which encoding types we accept.  Put them
836
 * in order of preference, if we have any.  We may always receive raw
837
 * encoding, even if we don't specify it here.
838
 */
839
840
typedef struct {
841
    CARD8 type;			/* always rfbSetEncodings */
842
    CARD8 pad;
843
    CARD16 nEncodings;
844
    /* followed by nEncodings * CARD32 encoding types */
845
} rfbSetEncodingsMsg;
846
847
#define sz_rfbSetEncodingsMsg 4
848
849
850
/*-----------------------------------------------------------------------------
851
 * FramebufferUpdateRequest - request for a framebuffer update.  If incremental
852
 * is true then the client just wants the changes since the last update.  If
853
 * false then it wants the whole of the specified rectangle.
854
 */
855
856
typedef struct {
857
    CARD8 type;			/* always rfbFramebufferUpdateRequest */
858
    CARD8 incremental;
859
    CARD16 x;
860
    CARD16 y;
861
    CARD16 w;
862
    CARD16 h;
863
} rfbFramebufferUpdateRequestMsg;
864
865
#define sz_rfbFramebufferUpdateRequestMsg 10
866
867
868
/*-----------------------------------------------------------------------------
869
 * KeyEvent - key press or release
870
 *
871
 * Keys are specified using the "keysym" values defined by the X Window System.
872
 * For most ordinary keys, the keysym is the same as the corresponding ASCII
873
 * value.  Other common keys are:
874
 *
875
 * BackSpace		0xff08
876
 * Tab			0xff09
877
 * Return or Enter	0xff0d
878
 * Escape		0xff1b
879
 * Insert		0xff63
880
 * Delete		0xffff
881
 * Home			0xff50
882
 * End			0xff57
883
 * Page Up		0xff55
884
 * Page Down		0xff56
885
 * Left			0xff51
886
 * Up			0xff52
887
 * Right		0xff53
888
 * Down			0xff54
889
 * F1			0xffbe
890
 * F2			0xffbf
891
 * ...			...
892
 * F12			0xffc9
893
 * Shift		0xffe1
894
 * Control		0xffe3
895
 * Meta			0xffe7
896
 * Alt			0xffe9
897
 */
898
899
typedef struct {
900
    CARD8 type;			/* always rfbKeyEvent */
901
    CARD8 down;			/* true if down (press), false if up */
902
    CARD16 pad;
903
    CARD32 key;			/* key is specified as an X keysym */
904
} rfbKeyEventMsg;
905
906
#define sz_rfbKeyEventMsg 8
907
908
909
/*-----------------------------------------------------------------------------
910
 * PointerEvent - mouse/pen move and/or button press.
911
 */
912
913
typedef struct {
914
    CARD8 type;			/* always rfbPointerEvent */
915
    CARD8 buttonMask;		/* bits 0-7 are buttons 1-8, 0=up, 1=down */
916
    CARD16 x;
917
    CARD16 y;
918
} rfbPointerEventMsg;
919
920
#define rfbButton1Mask 1
921
#define rfbButton2Mask 2
922
#define rfbButton3Mask 4
923
924
#define sz_rfbPointerEventMsg 6
925
926
927
928
/*-----------------------------------------------------------------------------
929
 * ClientCutText - the client has new text in its cut buffer.
930
 */
931
932
typedef struct {
933
    CARD8 type;			/* always rfbClientCutText */
934
    CARD8 pad1;
935
    CARD16 pad2;
936
    CARD32 length;
937
    /* followed by char text[length] */
938
} rfbClientCutTextMsg;
939
940
#define sz_rfbClientCutTextMsg 8
941
942
943
944
/*-----------------------------------------------------------------------------
945
 * Union of all client->server messages.
946
 */
947
948
typedef union {
949
    CARD8 type;
950
    rfbSetPixelFormatMsg spf;
951
    rfbFixColourMapEntriesMsg fcme;
952
    rfbSetEncodingsMsg se;
953
    rfbFramebufferUpdateRequestMsg fur;
954
    rfbKeyEventMsg ke;
955
    rfbPointerEventMsg pe;
956
    rfbClientCutTextMsg cct;
957
} rfbClientToServerMsg;
(-)tdenetwork-trinity-14.1.0-ORIG/krdc/vnc/scaling.cpp (-331 lines)
Lines 1-331 Link Here
1
/****************************************************************************
2
**
3
** Copyright (C) 2015 Timothy Pearson <kb9vqf@pearsoncomputing.net>
4
**
5
** This file is part of TDE.
6
**
7
** This program is free software; you can redistribute it and/or modify
8
** it under the terms of the GNU General Public License as published by
9
** the Free Software Foundation; either version 2 of the License, or
10
** (at your option) any later version.
11
**
12
** This program is distributed in the hope that it will be useful,
13
** but WITHOUT ANY WARRANTY; without even the implied warranty of
14
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
** GNU General Public License for more details.
16
**
17
** You should have received a copy of the GNU General Public License
18
** along with this program; see the file COPYING. If not, write to
19
** the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20
** Boston, MA 02110-1301, USA.
21
**
22
****************************************************************************/
23
24
#include <tqimage.h>
25
26
/*!
27
28
    Smooth scaling function with ability to limit scaled region
29
    The selection rectangle is given in terms of destination coordinates
30
    It leaves areas outside of the selection rectangle undefined...
31
32
    Function code originally taken from qimage.cpp pnmscale () and modified
33
    to only scale a section of the source
34
35
    This function uses code based on pnmscale.c by Jef Poskanzer.
36
37
    pnmscale.c - read a portable anymap and scale it
38
39
    \legalese
40
41
    Copyright (C) 1989, 1991 by Jef Poskanzer.
42
43
    Permission to use, copy, modify, and distribute this software and
44
    its documentation for any purpose and without fee is hereby
45
    granted, provided that the above copyright notice appear in all
46
    copies and that both that copyright notice and this permission
47
    notice appear in supporting documentation. This software is
48
    provided "as is" without express or implied warranty.
49
50
*/
51
52
void pnmscale_fractional(const TQImage& src, TQImage& dst, int x, int y, int w, int h)
53
{
54
    TQRgb* xelrow = 0;
55
    TQRgb* tempxelrow = 0;
56
    TQRgb* xP;
57
    TQRgb* nxP;
58
    int rows, cols, rowsread, newrows, newcols;
59
    int row, col, needtoreadrow;
60
    const uchar maxval = 255;
61
    double xscale, yscale;
62
    long sxscale, syscale;
63
    long fracrowtofill, fracrowleft;
64
    long* as;
65
    long* rs;
66
    long* gs;
67
    long* bs;
68
    int rowswritten = 0;
69
    int colswritten = 0;
70
71
    cols = src.width();
72
    rows = src.height();
73
    newcols = dst.width();
74
    newrows = dst.height();
75
76
    long SCALE;
77
    long HALFSCALE;
78
79
    if (cols > 4096)
80
    {
81
        SCALE = 4096;
82
        HALFSCALE = 2048;
83
    }
84
    else
85
    {
86
        int fac = 4096;
87
88
        while (cols * fac > 4096)
89
        {
90
            fac /= 2;
91
        }
92
93
        SCALE = fac * cols;
94
        HALFSCALE = fac * cols / 2;
95
    }
96
97
    xscale = (double) newcols / (double) cols;
98
    yscale = (double) newrows / (double) rows;
99
100
    sxscale = (long)(xscale * SCALE);
101
    syscale = (long)(yscale * SCALE);
102
103
    if ( newrows != rows )	/* shortcut Y scaling if possible */
104
	tempxelrow = new TQRgb[cols];
105
106
    if ( src.hasAlphaBuffer() ) {
107
	dst.setAlphaBuffer(TRUE);
108
	as = new long[cols];
109
	for ( col = 0; col < cols; ++col )
110
	    as[col] = HALFSCALE;
111
    } else {
112
	as = 0;
113
    }
114
    rs = new long[cols];
115
    gs = new long[cols];
116
    bs = new long[cols];
117
    rowsread = 0;
118
    fracrowleft = syscale;
119
    needtoreadrow = 1;
120
    for ( col = 0; col < cols; ++col )
121
	rs[col] = gs[col] = bs[col] = HALFSCALE;
122
    fracrowtofill = SCALE;
123
124
    for ( row = 0; row < newrows; ++row ) {
125
	/* First scale Y from xelrow into tempxelrow. */
126
	if ( newrows == rows ) {
127
	    /* shortcut Y scaling if possible */
128
	    tempxelrow = xelrow = (TQRgb*)src.scanLine(rowsread++);
129
	} else {
130
	    while ( fracrowleft < fracrowtofill ) {
131
		if ( needtoreadrow && rowsread < rows )
132
		    xelrow = (TQRgb*)src.scanLine(rowsread++);
133
		for ( col = 0, xP = xelrow; col < cols; ++col, ++xP ) {
134
if ((rowswritten >= y) && (rowswritten <= (y + h))) {
135
		    if (as) {
136
			as[col] += fracrowleft * tqAlpha( *xP );
137
			rs[col] += fracrowleft * tqRed( *xP ) * tqAlpha( *xP ) / 255;
138
			gs[col] += fracrowleft * tqGreen( *xP ) * tqAlpha( *xP ) / 255;
139
			bs[col] += fracrowleft * tqBlue( *xP ) * tqAlpha( *xP ) / 255;
140
		    } else {
141
			rs[col] += fracrowleft * tqRed( *xP );
142
			gs[col] += fracrowleft * tqGreen( *xP );
143
			bs[col] += fracrowleft * tqBlue( *xP );
144
		    }
145
}
146
		}
147
		fracrowtofill -= fracrowleft;
148
		fracrowleft = syscale;
149
		needtoreadrow = 1;
150
	    }
151
	    /* Now fracrowleft is >= fracrowtofill, so we can produce a row. */
152
	    if ( needtoreadrow && rowsread < rows ) {
153
		xelrow = (TQRgb*)src.scanLine(rowsread++);
154
		needtoreadrow = 0;
155
	    }
156
	    long a=0;
157
	    for ( col = 0, xP = xelrow, nxP = tempxelrow, colswritten = 0;
158
		  col < cols; ++col, ++xP, ++nxP, ++colswritten )
159
	    {
160
if ((rowswritten >= y) && (rowswritten <= (y + h))) {
161
		long r, g, b;
162
163
		if ( as ) {
164
		    r = rs[col] + fracrowtofill * tqRed( *xP ) * tqAlpha( *xP ) / 255;
165
		    g = gs[col] + fracrowtofill * tqGreen( *xP ) * tqAlpha( *xP ) / 255;
166
		    b = bs[col] + fracrowtofill * tqBlue( *xP ) * tqAlpha( *xP ) / 255;
167
		    a = as[col] + fracrowtofill * tqAlpha( *xP );
168
		    if ( a ) {
169
			r = r * 255 / a * SCALE;
170
			g = g * 255 / a * SCALE;
171
			b = b * 255 / a * SCALE;
172
		    }
173
		} else {
174
		    r = rs[col] + fracrowtofill * tqRed( *xP );
175
		    g = gs[col] + fracrowtofill * tqGreen( *xP );
176
		    b = bs[col] + fracrowtofill * tqBlue( *xP );
177
		}
178
		r /= SCALE;
179
		if ( r > maxval ) r = maxval;
180
		g /= SCALE;
181
		if ( g > maxval ) g = maxval;
182
		b /= SCALE;
183
		if ( b > maxval ) b = maxval;
184
		if ( as ) {
185
		    a /= SCALE;
186
		    if ( a > maxval ) a = maxval;
187
		    *nxP = tqRgba( (int)r, (int)g, (int)b, (int)a );
188
		    as[col] = HALFSCALE;
189
		} else {
190
		    *nxP = tqRgb( (int)r, (int)g, (int)b );
191
		}
192
		rs[col] = gs[col] = bs[col] = HALFSCALE;
193
}
194
	    }
195
	    fracrowleft -= fracrowtofill;
196
	    if ( fracrowleft == 0 ) {
197
		fracrowleft = syscale;
198
		needtoreadrow = 1;
199
	    }
200
	    fracrowtofill = SCALE;
201
	}
202
203
	/* Now scale X from tempxelrow into dst and write it out. */
204
	if ( newcols == cols ) {
205
	    /* shortcut X scaling if possible */
206
	    memcpy(dst.scanLine(rowswritten++), tempxelrow, newcols*4);
207
	} else {
208
	    long a, r, g, b;
209
	    long fraccoltofill, fraccolleft = 0;
210
	    int needcol;
211
212
	    nxP = (TQRgb*)dst.scanLine(rowswritten++);
213
	    colswritten = 0;
214
	    fraccoltofill = SCALE;
215
	    a = r = g = b = HALFSCALE;
216
	    needcol = 0;
217
	    for ( col = 0, xP = tempxelrow; col < cols; ++col, ++xP ) {
218
		fraccolleft = sxscale;
219
		while ( fraccolleft >= fraccoltofill ) {
220
		    if ( needcol ) {
221
			++nxP;
222
			++colswritten;
223
			a = r = g = b = HALFSCALE;
224
		    }
225
if ((colswritten >= x) && (colswritten <= (x + w)) && (rowswritten >= y) && (rowswritten <= (y + h))) {
226
		    if ( as ) {
227
			r += fraccoltofill * tqRed( *xP ) * tqAlpha( *xP ) / 255;
228
			g += fraccoltofill * tqGreen( *xP ) * tqAlpha( *xP ) / 255;
229
			b += fraccoltofill * tqBlue( *xP ) * tqAlpha( *xP ) / 255;
230
			a += fraccoltofill * tqAlpha( *xP );
231
			if ( a ) {
232
			    r = r * 255 / a * SCALE;
233
			    g = g * 255 / a * SCALE;
234
			    b = b * 255 / a * SCALE;
235
			}
236
		    } else {
237
			r += fraccoltofill * tqRed( *xP );
238
			g += fraccoltofill * tqGreen( *xP );
239
			b += fraccoltofill * tqBlue( *xP );
240
		    }
241
		    r /= SCALE;
242
		    if ( r > maxval ) r = maxval;
243
		    g /= SCALE;
244
		    if ( g > maxval ) g = maxval;
245
		    b /= SCALE;
246
		    if ( b > maxval ) b = maxval;
247
		    if (as) {
248
			a /= SCALE;
249
			if ( a > maxval ) a = maxval;
250
			*nxP = tqRgba( (int)r, (int)g, (int)b, (int)a );
251
		    } else {
252
			*nxP = tqRgb( (int)r, (int)g, (int)b );
253
		    }
254
}
255
		    fraccolleft -= fraccoltofill;
256
		    fraccoltofill = SCALE;
257
		    needcol = 1;
258
		}
259
		if ( fraccolleft > 0 ) {
260
		    if ( needcol ) {
261
			++nxP;
262
			++colswritten;
263
			a = r = g = b = HALFSCALE;
264
			needcol = 0;
265
		    }
266
if ((rowswritten >= y) && (rowswritten <= (y + h))) {
267
		    if (as) {
268
			a += fraccolleft * tqAlpha( *xP );
269
			r += fraccolleft * tqRed( *xP ) * tqAlpha( *xP ) / 255;
270
			g += fraccolleft * tqGreen( *xP ) * tqAlpha( *xP ) / 255;
271
			b += fraccolleft * tqBlue( *xP ) * tqAlpha( *xP ) / 255;
272
		    } else {
273
			r += fraccolleft * tqRed( *xP );
274
			g += fraccolleft * tqGreen( *xP );
275
			b += fraccolleft * tqBlue( *xP );
276
		    }
277
}
278
		    fraccoltofill -= fraccolleft;
279
		}
280
	    }
281
	    if ( fraccoltofill > 0 ) {
282
		--xP;
283
if ((rowswritten >= y) && (rowswritten <= (y + h))) {
284
		if (as) {
285
		    a += fraccolleft * tqAlpha( *xP );
286
		    r += fraccoltofill * tqRed( *xP ) * tqAlpha( *xP ) / 255;
287
		    g += fraccoltofill * tqGreen( *xP ) * tqAlpha( *xP ) / 255;
288
		    b += fraccoltofill * tqBlue( *xP ) * tqAlpha( *xP ) / 255;
289
		    if ( a ) {
290
			r = r * 255 / a * SCALE;
291
			g = g * 255 / a * SCALE;
292
			b = b * 255 / a * SCALE;
293
		    }
294
		} else {
295
		    r += fraccoltofill * tqRed( *xP );
296
		    g += fraccoltofill * tqGreen( *xP );
297
		    b += fraccoltofill * tqBlue( *xP );
298
		}
299
}
300
	    }
301
	    if ( ! needcol ) {
302
if ((rowswritten >= y) && (rowswritten <= (y + h))) {
303
		r /= SCALE;
304
		if ( r > maxval ) r = maxval;
305
		g /= SCALE;
306
		if ( g > maxval ) g = maxval;
307
		b /= SCALE;
308
		if ( b > maxval ) b = maxval;
309
		if (as) {
310
		    a /= SCALE;
311
		    if ( a > maxval ) a = maxval;
312
		    *nxP = tqRgba( (int)r, (int)g, (int)b, (int)a );
313
		} else {
314
		    *nxP = tqRgb( (int)r, (int)g, (int)b );
315
		}
316
}
317
	    }
318
	}
319
    }
320
321
    if ( newrows != rows && tempxelrow )// Robust, tempxelrow might be 0 1 day
322
	delete [] tempxelrow;
323
    if ( as )				// Avoid purify complaint
324
	delete [] as;
325
    if ( rs )				// Robust, rs might be 0 one day
326
	delete [] rs;
327
    if ( gs )				// Robust, gs might be 0 one day
328
	delete [] gs;
329
    if ( bs )				// Robust, bs might be 0 one day
330
	delete [] bs;
331
}
(-)tdenetwork-trinity-14.1.0-ORIG/krdc/vnc/sockets.c (+325 lines)
Line 0 Link Here
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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
17
 *  USA.
18
 *
19
 * 03-05-2002 tim@tjansen.de: removed Xt event processing for krdc
20
 */
21
22
/*
23
 * sockets.c - functions to deal with sockets.
24
 */
25
26
#include <unistd.h>
27
#include <sys/socket.h>
28
#include <errno.h>
29
#include <netinet/in.h>
30
#include <netinet/tcp.h>
31
#include <arpa/inet.h>
32
#include <netdb.h>
33
#include <fcntl.h>
34
#include <assert.h>
35
#include "vncviewer.h"
36
37
void PrintInHex(char *buf, int len);
38
39
Bool errorMessageOnReadFailure = True;
40
41
#define BUF_SIZE 8192
42
static char buf[BUF_SIZE];
43
static char *bufoutptr = buf;
44
static unsigned int buffered = 0;
45
46
/* Wait duration of select in seconds */
47
#define SELECT_PERIOD 3
48
49
50
/*
51
 * ReadFromRFBServer is called whenever we want to read some data from the RFB
52
 * server.  
53
 */
54
Bool
55
ReadFromRFBServer(char *out, unsigned int n)
56
{
57
  fd_set fds;
58
  int e;
59
  struct timeval tx;
60
61
  if (isQuitFlagSet())
62
    return False;
63
64
  if (n <= buffered) {
65
    memcpy(out, bufoutptr, n);
66
    bufoutptr += n;
67
    buffered -= n;
68
    return True;
69
  }
70
71
  memcpy(out, bufoutptr, buffered);
72
73
  out += buffered;
74
  n -= buffered;
75
76
  bufoutptr = buf;
77
  buffered = 0;
78
79
  if (n <= BUF_SIZE) {
80
81
    while (buffered < n) {
82
      int i;
83
      if (isQuitFlagSet())
84
	return False;
85
      i = read(rfbsock, buf + buffered, BUF_SIZE - buffered);
86
87
      if (i <= 0) {
88
	if (i < 0) {
89
	  if (errno == EWOULDBLOCK || errno == EAGAIN) {
90
	    FD_ZERO(&fds);
91
	    FD_SET(rfbsock,&fds);
92
93
	    tx.tv_sec = SELECT_PERIOD;
94
	    tx.tv_usec = 0;
95
	    if ((e=select(rfbsock+1, &fds, NULL, &fds, &tx)) < 0) {
96
	      perror("krdc: select read");
97
	      return False;
98
	    }
99
	    i = 0;
100
	  } else {
101
	    perror("krdc: read");
102
	    return False;
103
	  }
104
	} else { 
105
	  fprintf(stderr,"VNC server closed connection\n");
106
	  return False;
107
	}
108
      }
109
      buffered += i;
110
    }
111
112
    memcpy(out, bufoutptr, n);
113
    bufoutptr += n;
114
    buffered -= n;
115
    return isQuitFlagSet() ? False : True;
116
117
  } else {
118
119
    while (n > 0) {
120
      int i;
121
      if (isQuitFlagSet())
122
	return False;
123
      i = read(rfbsock, out, n);
124
      if (i <= 0) {
125
	if (i < 0) {
126
	  if (errno == EWOULDBLOCK || errno == EAGAIN) {
127
	    FD_ZERO(&fds);
128
	    FD_SET(rfbsock,&fds);
129
130
	    tx.tv_sec = SELECT_PERIOD;
131
	    tx.tv_usec = 0;
132
	    if ((e=select(rfbsock+1, &fds, NULL, &fds, &tx)) < 0) {
133
	      perror("krdc: select");
134
	      return False;
135
	    }	    
136
	    i = 0;
137
	  } else {
138
	    perror("krdc: read");
139
	    return False;
140
	  }
141
	} else { 
142
	  fprintf(stderr,"VNC server closed connection\n");
143
	  return False;
144
	}
145
      }
146
      out += i;
147
      n -= i;
148
    }
149
150
    return isQuitFlagSet() ? False : True;
151
  }
152
}
153
154
155
/*
156
 * Write an exact number of bytes, and don't return until you've sent them.
157
 * Note: this should only be called by the WriterThread
158
 */
159
160
Bool
161
WriteExact(int sock, const char *_buf, int n)
162
{
163
  fd_set fds;
164
  int i = 0;
165
  int j;
166
  int e;
167
  struct timeval tx;
168
169
  while (i < n) {
170
    if (isQuitFlagSet())
171
      return False;
172
    j = write(sock, _buf + i, (n - i));
173
    if (j <= 0) {
174
      if (j < 0) {
175
	if (errno == EWOULDBLOCK || errno == EAGAIN) {
176
	  FD_ZERO(&fds);
177
	  FD_SET(rfbsock,&fds);
178
179
	  tx.tv_sec = SELECT_PERIOD;
180
	  tx.tv_usec = 0;
181
	  if ((e=select(rfbsock+1, NULL, &fds, NULL, &tx)) < 0) {
182
	    perror("krdc: select write");
183
	    return False;
184
	  }
185
	  j = 0;
186
	} else {
187
	  perror("krdc: write");
188
	  return False;
189
	}
190
      } else {
191
	fprintf(stderr,"write failed\n");
192
	return False;
193
      }
194
    }
195
    i += j;
196
  }
197
  return True;
198
}
199
200
201
/*
202
 * ConnectToTcpAddr connects to the given TCP port.
203
 */
204
205
int
206
ConnectToTcpAddr(unsigned int host, int port)
207
{
208
  int sock;
209
  struct sockaddr_in addr;
210
  int one = 1;
211
212
  addr.sin_family = AF_INET;
213
  addr.sin_port = htons(port);
214
  addr.sin_addr.s_addr = host;
215
216
  sock = socket(AF_INET, SOCK_STREAM, 0);
217
  if (sock < 0) {
218
    perror("krdc: ConnectToTcpAddr: socket");
219
    return -(int)INIT_CONNECTION_FAILED;
220
  }
221
222
  if (connect(sock, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
223
    perror("krdc: ConnectToTcpAddr: connect");
224
    close(sock);
225
    return -(int)INIT_NO_SERVER;
226
  }
227
228
  if (setsockopt(sock, IPPROTO_TCP, TCP_NODELAY,
229
		 (char *)&one, sizeof(one)) < 0) {
230
    perror("krdc: ConnectToTcpAddr: setsockopt");
231
    close(sock);
232
    return -(int)INIT_CONNECTION_FAILED;
233
  }
234
235
  if (fcntl(sock, F_SETFL, O_NONBLOCK) < 0) {
236
    perror(": AcceptTcpConnection: fcntl");
237
    close(sock);
238
    return -(int)INIT_CONNECTION_FAILED;
239
  }  
240
241
  return sock;
242
}
243
244
245
/*
246
 * StringToIPAddr - convert a host string to an IP address.
247
 */
248
249
Bool
250
StringToIPAddr(const char *str, unsigned int *addr)
251
{
252
  struct hostent *hp;
253
254
  if (strcmp(str,"") == 0) {
255
    *addr = 0; /* local */
256
    return True;
257
  }
258
259
  *addr = inet_addr(str);
260
261
  if (*addr != -1)
262
    return True;
263
264
  hp = gethostbyname(str);
265
266
  if (hp) {
267
    *addr = *(unsigned int *)hp->h_addr;
268
    return True;
269
  }
270
271
  return False;
272
}
273
274
275
/*
276
 * Print out the contents of a packet for debugging.
277
 */
278
279
void
280
PrintInHex(char *_buf, int len)
281
{
282
  int i, j;
283
  char c, str[17];
284
285
  str[16] = 0;
286
287
  fprintf(stderr,"ReadExact: ");
288
289
  for (i = 0; i < len; i++)
290
    {
291
      if ((i % 16 == 0) && (i != 0)) {
292
	fprintf(stderr,"           ");
293
      }
294
      c = _buf[i];
295
      str[i % 16] = (((c > 31) && (c < 127)) ? c : '.');
296
      fprintf(stderr,"%02x ",(unsigned char)c);
297
      if ((i % 4) == 3)
298
	fprintf(stderr," ");
299
      if ((i % 16) == 15)
300
	{
301
	  fprintf(stderr,"%s\n",str);
302
	}
303
    }
304
  if ((i % 16) != 0)
305
    {
306
      for (j = i % 16; j < 16; j++)
307
	{
308
	  fprintf(stderr,"   ");
309
	  if ((j % 4) == 3) fprintf(stderr," ");
310
	}
311
      str[i % 16] = 0;
312
      fprintf(stderr,"%s\n",str);
313
    }
314
315
  fflush(stderr);
316
}
317
318
void freeSocketsResources() {
319
  close(rfbsock);
320
321
  errorMessageOnReadFailure = True;
322
  bufoutptr = buf;
323
  buffered = 0;
324
}
325
(-)tdenetwork-trinity-14.1.0-ORIG/krdc/vnc/threads.cpp (-299 / +307 lines)
Lines 2-9 Link Here
2
                            threads.cpp  -  threads
2
                            threads.cpp  -  threads
3
                             -------------------
3
                             -------------------
4
    begin                : Thu May 09 17:01:44 CET 2002
4
    begin                : Thu May 09 17:01:44 CET 2002
5
    copyright            : (C) 2015 Timothy Pearson <kb9vqf@pearsoncomputing.net>
5
    copyright            : (C) 2002 by Tim Jansen
6
                           (C) 2002 by Tim Jansen
7
    email                : tim@tjansen.de
6
    email                : tim@tjansen.de
8
 ***************************************************************************/
7
 ***************************************************************************/
9
8
Lines 25-384 Link Here
25
#include "threads.h"
24
#include "threads.h"
26
25
27
#include <tqcstring.h>
26
#include <tqcstring.h>
28
#include <tqpainter.h>
29
27
30
#include <math.h>
28
// Maximum idle time for writer thread in ms. When it timeouts, it will request
29
// another incremental update. Must be smaller than the timeout of the server
30
// (krfb's is 20s).
31
static const int MAXIMUM_WAIT_PERIOD = 8000;
31
32
32
extern void pnmscale_fractional(const TQImage& src, TQImage& dst, int x, int y, int w, int h);
33
// time to postpone incremental updates that have not been requested explicitly
34
static const int POSTPONED_INCRRQ_WAIT_PERIOD = 110;
33
35
34
int getPassword(char * &passwd);
36
static const int MOUSEPRESS_QUEUE_SIZE = 5;
37
static const int MOUSEMOVE_QUEUE_SIZE = 3;
38
static const int KEY_QUEUE_SIZE = 8192;
35
39
36
extern rfbBool newclient(rfbClient *cl)
37
{
38
	int width = cl->width, height = cl->height, depth = cl->format.bitsPerPixel;
39
	int size = width * height * (depth / 8);
40
	uint8_t *buf = new uint8_t[size];
41
	memset(buf, '\0', size);
42
	cl->frameBuffer = buf;
43
	cl->format.bitsPerPixel = 32;
44
	cl->format.redShift = 16;
45
	cl->format.greenShift = 8;
46
	cl->format.blueShift = 0;
47
	cl->format.redMax = 0xff;
48
	cl->format.greenMax = 0xff;
49
	cl->format.blueMax = 0xff;
50
	
51
	SetFormatAndEncodings(cl);
52
	
53
	return true;
54
}
55
56
extern void updatefb(rfbClient* cl, int x, int y, int w, int h)
57
{
58
// 	kdDebug(5011) << "updated client: x: " << x << ", y: " << y << ", w: " << w << ", h: " << h << endl;
59
	
60
	int width = cl->width, height = cl->height;
61
	
62
	TQImage img(cl->frameBuffer, width, height, 32, NULL, 256, TQImage::IgnoreEndian);
63
	
64
	if (img.isNull())
65
		kdDebug(5011) << "image not loaded" << endl;
66
	
67
	
68
	ControllerThreadObject *t = (ControllerThreadObject*)rfbClientGetClientData(cl, 0);
69
	
70
	t->setImage(img);
71
	t->queueDrawRegion(x, y, w, h);
72
}
73
74
extern char *passwd(rfbClient *cl)
75
{
76
	Q_UNUSED(cl)
77
40
78
	kdDebug(5011) << "password request" << endl;
41
ControllerThread::ControllerThread(KVncView *v, WriterThread &wt, volatile bool &quitFlag) :
79
80
	char *passwd;
81
	if (getPassword(passwd)) {
82
		return passwd;
83
	}
84
	else {
85
		return NULL;
86
	}
87
}
88
89
extern void authresults(rfbClient *cl, uint32_t authResult)
90
{
91
	kdDebug(5011) << "authentication result: " << authResult << endl;
92
	
93
	ControllerThreadObject *t = (ControllerThreadObject*)rfbClientGetClientData(cl, 0);
94
95
	t->authenticationResults(authResult);
96
}
97
98
extern void networkstat(rfbClient *cl, uint32_t statuscode)
99
{
100
	kdDebug(5011) << "network status: " << statuscode << endl;
101
	
102
	ControllerThreadObject *t = (ControllerThreadObject*)rfbClientGetClientData(cl, 0);
103
104
	t->networkStatus(statuscode);
105
}
106
107
extern void output(const char *format, ...)
108
{
109
	va_list args;
110
	va_start(args, format);
111
	
112
	TQString message;
113
	message.vsprintf(format, args);
114
	
115
	va_end(args);
116
	
117
	kdDebug(5011) << message.local8Bit();
118
	
119
	if (message.contains("Could not open")) {
120
		kdDebug(5011) << "Server not found!" << endl;
121
	}
122
	
123
	if (message.contains("VNC authentication succeeded")) {
124
		kdDebug(5011) << "Password OK" << endl;
125
	}
126
}
127
128
ControllerThreadObject::ControllerThreadObject(KVncView *v, volatile bool &quitFlag) :
129
	cl(0L),
130
	m_view(v),
42
	m_view(v),
131
	m_status(REMOTE_VIEW_CONNECTING),
43
	m_status(REMOTE_VIEW_CONNECTING),
44
	m_wthread(wt),
132
	m_quitFlag(quitFlag),
45
	m_quitFlag(quitFlag),
133
	m_scaling(false),
46
	m_desktopInitialized(false)
134
	m_scalingWidth(-1),
135
	m_scalingHeight(-1),
136
	m_resizeEntireFrame(false)
137
{
47
{
138
	TQMutexLocker locker(&mutex);
139
140
	cl = rfbGetClient(8, 3, 4);
141
}
48
}
142
49
143
ControllerThreadObject::~ControllerThreadObject() {
50
void ControllerThread::changeStatus(RemoteViewStatus s) {
144
	TQMutexLocker locker(&mutex);
145
146
	rfbClientCleanup(cl);
147
}
148
149
void ControllerThreadObject::changeStatus(RemoteViewStatus s) {
150
	m_status = s;
51
	m_status = s;
151
	TQApplication::postEvent(m_view, new StatusChangeEvent(s));
52
	TQApplication::postEvent(m_view, new StatusChangeEvent(s));
152
}
53
}
153
54
154
void ControllerThreadObject::sendFatalError(ErrorCode s) {
55
void ControllerThread::sendFatalError(ErrorCode s) {
155
	m_quitFlag = true;
56
	m_quitFlag = true;
156
	TQApplication::postEvent(m_view, new FatalErrorEvent(s));
57
	TQApplication::postEvent(m_view, new FatalErrorEvent(s));
58
	m_wthread.kick();
157
}
59
}
158
60
159
void ControllerThreadObject::queueDrawRegion(int x, int y, int w, int h) {
61
/*
160
	if (m_scaling) {
62
 * Calls this from the X11 thread
161
		// Rescale desktop
63
 */
64
void ControllerThread::desktopInit() {
65
	SetVisualAndCmap();
66
	ToplevelInit();
67
	DesktopInit(m_view->winId());
68
	m_desktopInitialized = true;
69
	m_waiter.wakeAll();
70
}
71
72
void ControllerThread::kick() {
73
	m_waiter.wakeAll();
74
}
75
76
void ControllerThread::run() {
77
	int fd;
78
	fd = ConnectToRFBServer(m_view->host().latin1(), m_view->port());
79
	if (fd < 0) {
80
		if (fd == -(int)INIT_NO_SERVER)
81
			sendFatalError(ERROR_NO_SERVER);
82
		else if (fd == -(int)INIT_NAME_RESOLUTION_FAILURE)
83
			sendFatalError(ERROR_NAME);
84
		else
85
			sendFatalError(ERROR_CONNECTION);
86
		return;
87
	}
88
	if (m_quitFlag) {
89
		changeStatus(REMOTE_VIEW_DISCONNECTED);
90
		return;
91
	}
92
93
        changeStatus(REMOTE_VIEW_AUTHENTICATING);
162
94
163
		int new_x;
95
	enum InitStatus s = InitialiseRFBConnection();
164
		int new_y;
96
	if (s != INIT_OK) {
165
		int new_w;
97
		if (s == INIT_CONNECTION_FAILED)
166
		int new_h;
98
			sendFatalError(ERROR_IO);
99
		else if (s == INIT_SERVER_BLOCKED)
100
			sendFatalError(ERROR_SERVER_BLOCKED);
101
		else if (s == INIT_PROTOCOL_FAILURE)
102
			sendFatalError(ERROR_PROTOCOL);
103
		else if (s == INIT_AUTHENTICATION_FAILED)
104
			sendFatalError(ERROR_AUTHENTICATION);
105
		else if (s == INIT_ABORTED)
106
			changeStatus(REMOTE_VIEW_DISCONNECTED);
107
		else
108
			sendFatalError(ERROR_INTERNAL);
109
		return;
110
	}
167
111
168
		mutex.lock();
112
	TQApplication::postEvent(m_view,
113
				new ScreenResizeEvent(si.framebufferWidth,
114
						      si.framebufferHeight));
115
	m_wthread.queueUpdateRequest(TQRegion(TQRect(0,0,si.framebufferWidth,
116
		si.framebufferHeight)));
117
118
	TQApplication::postEvent(m_view, new DesktopInitEvent());
119
	while ((!m_quitFlag) && (!m_desktopInitialized))
120
		m_waiter.wait(1000);
169
121
170
		if (m_resizeEntireFrame) {
122
	if (m_quitFlag) {
171
			m_scaledImage.create(m_scalingWidth, m_scalingHeight, 32);
123
		changeStatus(REMOTE_VIEW_DISCONNECTED);
124
		return;
125
	}
172
126
173
			new_x = 0;
127
	changeStatus(REMOTE_VIEW_PREPARING);
174
			new_y = 0;
175
			new_w = m_scalingWidth;
176
			new_h = m_scalingHeight;
177
128
178
			TQImage scaledBlock = m_image.smoothScale(new_w, new_h);
129
	if (!SetFormatAndEncodings()) {
179
			bitBlt(&m_scaledImage, new_x, new_y, &scaledBlock, 0, 0, new_w, new_h);
130
		sendFatalError(ERROR_INTERNAL);
131
		return;
132
	}
180
133
181
			m_resizeEntireFrame = false;
134
	changeStatus(REMOTE_VIEW_CONNECTED);
182
		}
183
		else {
184
			// Extend redraw boundaries to avoid pixelation artifacts due to rounding errors
185
			x = x - round((2.0 * m_image.width()) / m_scalingWidth);
186
			y = y - round((2.0 * m_image.height()) / m_scalingHeight);
187
			w = w + round((4.0 * m_image.width()) / m_scalingWidth);
188
			h = h + round((4.0 * m_image.height()) / m_scalingHeight);
189
135
190
			if (x < 0) {
136
	m_wthread.start();
191
				x = 0;
192
			}
193
			if (y < 0) {
194
				y = 0;
195
			}
196
			if (w > m_image.width()) {
197
				w = m_image.width();
198
			}
199
			if (h > m_image.height()) {
200
				h = m_image.height();
201
			}
202
137
203
			new_x = round((x * m_scalingWidth) / m_image.width());
138
	while (!m_quitFlag) {
204
			new_y = round((y * m_scalingHeight) / m_image.height());
139
		if ((!HandleRFBServerMessage()) && (!m_quitFlag)) {
205
			new_w = round((w * m_scalingWidth) / m_image.width());
140
			sendFatalError(ERROR_IO);
206
			new_h = round((h * m_scalingHeight) / m_image.height());
141
			return;
207
208
			TQImage scaledBlock(m_scalingWidth, m_scalingHeight, 32);
209
			pnmscale_fractional(m_image, scaledBlock, new_x, new_y, new_w, new_h);
210
			bitBlt(&m_scaledImage, new_x, new_y, &scaledBlock, new_x, new_y, new_w, new_h);
211
		}
142
		}
143
	}
212
144
213
		mutex.unlock();
145
	m_quitFlag = true;
146
	changeStatus(REMOTE_VIEW_DISCONNECTED);
147
	m_wthread.kick();
148
}
214
149
215
		DrawScreenRegion(new_x, new_y, new_w, new_h);
150
enum RemoteViewStatus ControllerThread::status() {
216
	}
151
	return m_status;
217
	else {
218
		DrawScreenRegion(x, y, w, h);
219
	}
220
}
152
}
221
153
222
void ControllerThreadObject::setImage(const TQImage &img) {
223
	TQMutexLocker locker(&mutex);
224
154
225
	m_image = img;
226
}
227
155
228
const TQImage ControllerThreadObject::image(int x, int y, int w, int h) {
229
	TQMutexLocker locker(&mutex);
230
156
231
	if (m_scaling) {
232
		return m_scaledImage.copy(x, y, w, h);
233
	}
234
	else {
235
		return m_image.copy(x, y, w, h);
236
	}
237
}
238
157
239
void ControllerThreadObject::setScaling(int w, int h) {
158
static WriterThread *writerThread;
240
	bool scale;
159
void queueIncrementalUpdateRequest() {
160
	writerThread->queueIncrementalUpdateRequest();
161
}
241
162
242
	if (w <= 0) {
163
void announceIncrementalUpdateRequest() {
243
		scale = false;
164
	writerThread->announceIncrementalUpdateRequest();
244
	}
165
}
245
	else {
246
		scale = true;
247
	}
248
166
249
	if ((m_scalingWidth != w) || (m_scalingHeight = h) || (m_scaling != scale)) {
250
		m_resizeEntireFrame = true;
251
	}
252
167
253
	m_scaling = scale;
168
WriterThread::WriterThread(KVncView *v, volatile bool &quitFlag) :
254
	m_scalingWidth = w;
169
	m_quitFlag(quitFlag),
255
	m_scalingHeight = h;
170
	m_view(v),
256
}
171
	m_lastIncrUpdatePostponed(false),
257
172
	m_incrementalUpdateRQ(false),
258
void ControllerThreadObject::run() {
173
	m_incrementalUpdateAnnounced(false),
259
	mutex.lock();
174
	m_mouseEventNum(0),
260
175
	m_keyEventNum(0),
261
	rfbClientLog = output;
176
	m_clientCut(TQString())
262
	rfbClientErr = output;
177
{
263
	cl->MallocFrameBuffer = newclient;
178
	writerThread = this;
264
	cl->canHandleNewFBSize = true;
179
	m_lastIncrUpdate.start();
265
	cl->GetPassword = passwd;
180
}
266
	cl->AuthenticationResults = authresults;
267
	cl->NetworkStatus = networkstat;
268
	cl->GotFrameBufferUpdate = updatefb;
269
	rfbClientSetClientData(cl, 0, this);
270
271
	// make a copy of the host string...
272
	char *host = (char*) malloc(m_view->host().length());
273
	strcpy(host, m_view->host().ascii());
274
275
	cl->serverHost = host;
276
277
	int port = m_view->port();
278
	if(port >= 0 && port < 100) // the user most likely used the short form (e.g. :1)
279
		port += 5900;
280
	cl->serverPort = port;
281
181
282
	mutex.unlock();
182
bool WriterThread::sendIncrementalUpdateRequest() {
183
	m_lastIncrUpdate.restart();
184
	return SendIncrementalFramebufferUpdateRequest();
185
}
186
187
bool WriterThread::sendUpdateRequest(const TQRegion &region) {
188
	TQMemArray<TQRect> r = region.rects();
189
	for (unsigned int i = 0; i < r.size(); i++)
190
		if (!SendFramebufferUpdateRequest(r[i].x(),
191
						  r[i].y(),
192
						  r[i].width(),
193
						  r[i].height(), False))
194
			return false;
195
	return true;
196
}
283
197
284
	if(!rfbInitClient(cl, 0, 0)) {
198
bool WriterThread::sendInputEvents(const TQValueList<InputEvent> &events) {
285
		sendFatalError(ERROR_INTERNAL);
199
	TQValueList<InputEvent>::const_iterator it = events.begin();
286
		// Terminate thread
200
	while (it != events.end()) {
287
		TQThread::exit();
201
		if ((*it).type == KeyEventType) {
288
		return;
202
			if (!SendKeyEvent((*it).e.k.k, (*it).e.k.down ? True : False))
203
				return false;
204
		}
205
		else
206
			if (!SendPointerEvent((*it).e.m.x, (*it).e.m.y, (*it).e.m.buttons))
207
				return false;
208
		it++;
289
	}
209
	}
210
	return true;
211
}
290
212
291
	TQApplication::postEvent(m_view,
213
void WriterThread::queueIncrementalUpdateRequest() {
292
				new ScreenResizeEvent(cl->width,
214
	m_lock.lock();
293
						      cl->height));
215
	m_incrementalUpdateRQ = true;
216
	m_waiter.wakeAll();
217
	m_lock.unlock();
218
}
219
220
void WriterThread::announceIncrementalUpdateRequest() {
221
	m_lock.lock();
222
	m_incrementalUpdateAnnounced = true;
223
	m_lock.unlock();
224
}
294
225
295
	changeStatus(REMOTE_VIEW_CONNECTED);
296
	
297
	while (!m_quitFlag) {	
298
		int i = WaitForMessage(cl, 500);
299
		if (i < 0) {
300
			m_quitFlag = true;
301
			changeStatus(REMOTE_VIEW_DISCONNECTED);
302
226
303
			// Terminate thread
227
void WriterThread::queueUpdateRequest(const TQRegion &r) {
304
			TQThread::exit();
228
	m_lock.lock();
229
	m_updateRegionRQ += r;
230
	m_waiter.wakeAll();
231
	m_lock.unlock();
232
}
233
234
void WriterThread::queueMouseEvent(int x, int y, int buttonMask) {
235
	InputEvent e;
236
	e.type = MouseEventType;
237
	e.e.m.x = x;
238
	e.e.m.y = y;
239
	e.e.m.buttons = buttonMask;
240
241
	m_lock.lock();
242
	if (m_mouseEventNum > 0) {
243
		if ((e.e.m.x == m_lastMouseEvent.x) &&
244
		    (e.e.m.y == m_lastMouseEvent.y) &&
245
		    (e.e.m.buttons == m_lastMouseEvent.buttons)) {
246
			m_lock.unlock();
305
			return;
247
			return;
306
		}
248
		}
307
		if (i) {
249
		if (m_mouseEventNum >= MOUSEPRESS_QUEUE_SIZE) {
308
			if(!HandleRFBServerMessage(cl)) {
250
			m_lock.unlock();
309
				m_quitFlag = true;
251
			return;
310
				changeStatus(REMOTE_VIEW_DISCONNECTED);
252
		}
311
253
		if ((m_lastMouseEvent.buttons == buttonMask) &&
312
				// Terminate thread
254
		    (m_mouseEventNum >= MOUSEMOVE_QUEUE_SIZE)) {
313
				TQThread::exit();
255
			m_lock.unlock();
314
				return;
256
			return;
315
			}
316
		}
257
		}
317
	}
258
	}
318
259
319
	m_quitFlag = true;
260
	m_mouseEventNum++;
320
	changeStatus(REMOTE_VIEW_DISCONNECTED);
261
	m_lastMouseEvent = e.e.m;
321
322
	// Terminate thread
323
	TQThread::exit();
324
}
325
326
void ControllerThreadObject::authenticationResults(int resultCode) {
327
	if (resultCode == rfbVncAuthOK) {
328
		changeStatus(REMOTE_VIEW_PREPARING);
329
	}
330
	else {
331
		sendFatalError(ERROR_AUTHENTICATION);
332
262
333
		// Terminate thread
263
	m_inputEvents.push_back(e);
334
		TQThread::exit();
264
	m_waiter.wakeAll();
265
	m_lock.unlock();
266
}
267
268
void WriterThread::queueKeyEvent(unsigned int k, bool down) {
269
	InputEvent e;
270
	e.type = KeyEventType;
271
	e.e.k.k = k;
272
	e.e.k.down = down;
273
274
	m_lock.lock();
275
	if (m_keyEventNum >= KEY_QUEUE_SIZE) {
276
		m_lock.unlock();
277
		return;
335
	}
278
	}
336
}
337
279
338
void ControllerThreadObject::networkStatus(int statusCode) {
280
	m_keyEventNum++;
339
	if (statusCode == rfbNetworkConnectionSuccess) {
281
	m_inputEvents.push_back(e);
340
		// Stage 1 OK...
282
	m_waiter.wakeAll();
341
		changeStatus(REMOTE_VIEW_AUTHENTICATING);
283
	m_lock.unlock();
342
	}
284
}
343
	else if (statusCode == rfbNetworkRFBConnectionSuccess) {
285
344
		// Stage 2 OK!
286
void WriterThread::queueClientCut(const TQString &text) {
345
	}
287
	m_lock.lock();
346
	else {
288
347
		if (statusCode == rfbNetworkConnectionClosed) {
289
	m_clientCut = text;
348
			sendFatalError(ERROR_CONNECTION);
290
349
		}
291
	m_waiter.wakeAll();
350
		else if (statusCode == rfbNetworkConnectionFailed) {
292
	m_lock.unlock();
351
			sendFatalError(ERROR_CONNECTION);
293
}
352
		}
294
353
		else if (statusCode == rfbNetworkNameResolutionFailed) {
295
void WriterThread::kick() {
354
			sendFatalError(ERROR_NAME);
296
	m_waiter.wakeAll();
355
		}
297
}
356
		else if (statusCode == rfbNetworkRFBServerNotValid) {
298
357
			sendFatalError(ERROR_IO);
299
void WriterThread::run() {
300
	bool incrementalUpdateRQ = false;
301
	bool incrementalUpdateAnnounced = false;
302
	TQRegion updateRegionRQ;
303
	TQValueList<InputEvent> inputEvents;
304
	TQString clientCut;
305
306
	while (!m_quitFlag) {
307
		m_lock.lock();
308
		incrementalUpdateRQ = m_incrementalUpdateRQ;
309
		incrementalUpdateAnnounced = m_incrementalUpdateAnnounced;
310
		updateRegionRQ = m_updateRegionRQ;
311
		inputEvents = m_inputEvents;
312
		clientCut = m_clientCut;
313
314
		if ((!incrementalUpdateRQ) &&
315
		    (updateRegionRQ.isNull()) &&
316
		    (inputEvents.size() == 0) &&
317
		    (clientCut.isNull())) {
318
			if (!m_waiter.wait(&m_lock,
319
					   m_lastIncrUpdatePostponed ?
320
					   POSTPONED_INCRRQ_WAIT_PERIOD : MAXIMUM_WAIT_PERIOD))
321
				m_incrementalUpdateRQ = true;
322
			m_lock.unlock();
358
		}
323
		}
359
		else if (statusCode == rfbNetworkRFBProtocolFailure) {
324
		else {
360
			sendFatalError(ERROR_PROTOCOL);
325
			m_incrementalUpdateRQ = false;
326
			m_incrementalUpdateAnnounced = false;
327
			m_updateRegionRQ = TQRegion();
328
			m_inputEvents.clear();
329
			m_keyEventNum = 0;
330
			m_mouseEventNum = 0;
331
			m_clientCut = TQString();
332
			m_lock.unlock();
333
334
			// always send incremental update, unless
335
			// a) a framebuffer update is done ATM and will do the request later, or
336
			// b) the last unrequested update has been done less than 0.1s ago
337
			//
338
			// if the update has not been done because of b, postpone it.
339
			if (incrementalUpdateRQ || !incrementalUpdateAnnounced) {
340
				bool sendUpdate;
341
				if (incrementalUpdateRQ) {
342
					sendUpdate = true;
343
					m_lastIncrUpdatePostponed = false;
344
				}
345
				else {
346
					if (m_lastIncrUpdate.elapsed() < 100) {
347
						sendUpdate = false;
348
						m_lastIncrUpdatePostponed = true;
349
					}
350
					else {
351
						sendUpdate = true;
352
						m_lastIncrUpdatePostponed = false;
353
					}
354
				}
355
356
				if (sendUpdate)
357
					if (!sendIncrementalUpdateRequest()) {
358
						sendFatalError(ERROR_IO);
359
						break;
360
					}
361
			}
362
			else
363
				m_lastIncrUpdatePostponed = false;
364
365
			if (!updateRegionRQ.isNull())
366
				if (!sendUpdateRequest(updateRegionRQ)) {
367
					sendFatalError(ERROR_IO);
368
					break;
369
				}
370
			if (inputEvents.size() != 0)
371
				if (!sendInputEvents(inputEvents)) {
372
					sendFatalError(ERROR_IO);
373
					break;
374
				}
375
			if (!clientCut.isNull())  {
376
				TQCString cutTextUtf8(clientCut.utf8());
377
				if (!SendClientCutText(cutTextUtf8.data(),
378
						       (int)cutTextUtf8.length())) {
379
					sendFatalError(ERROR_IO);
380
					break;
381
				}
382
			}
361
		}
383
		}
362
	
363
		// Terminate thread
364
		TQThread::exit();
365
	}
384
	}
385
	m_quitFlag = true;
366
}
386
}
367
387
368
enum RemoteViewStatus ControllerThreadObject::status() {
388
void WriterThread::sendFatalError(ErrorCode s) {
369
	return m_status;
389
	m_quitFlag = true;
370
}
390
	TQApplication::postEvent(m_view, new FatalErrorEvent(s));
371
372
void ControllerThreadObject::queueMouseEvent(int x, int y, int buttonMask) {
373
	SendPointerEvent(cl, x, y, buttonMask);
374
}
375
376
void ControllerThreadObject::queueKeyEvent(unsigned int k, bool down) {
377
	SendKeyEvent(cl, k, down);
378
}
379
380
void ControllerThreadObject::queueClientCut(const TQString &text) {
381
	SendClientCutText(cl, (char*)text.ascii(), text.length());
382
}
391
}
383
392
384
#include "threads.moc"
(-)tdenetwork-trinity-14.1.0-ORIG/krdc/vnc/threads.h (-47 / +59 lines)
Lines 2-9 Link Here
2
                          threads.h  -  threads for kvncview
2
                          threads.h  -  threads for kvncview
3
                             -------------------
3
                             -------------------
4
    begin                : Thu May 09 16:01:42 CET 2002
4
    begin                : Thu May 09 16:01:42 CET 2002
5
    copyright            : (C) 2015 Timothy Pearson <kb9vqf@pearsoncomputing.net>
5
    copyright            : (C) 2002 by Tim Jansen
6
                           (C) 2002 by Tim Jansen
7
    email                : tim@tjansen.de
6
    email                : tim@tjansen.de
8
 ***************************************************************************/
7
 ***************************************************************************/
9
8
Lines 27-41 Link Here
27
#include <tqevent.h>
26
#include <tqevent.h>
28
#include <tqvaluelist.h>
27
#include <tqvaluelist.h>
29
#include <tqdatetime.h>
28
#include <tqdatetime.h>
30
#include <tqimage.h>
31
29
32
#include <stdlib.h> 
30
#include <stdlib.h> 
33
31
34
#include "events.h"
32
#include "events.h"
35
33
#include "vnctypes.h"
36
extern "C" {
37
#include <rfb/rfbclient.h>
38
}
39
34
40
class KVncView;
35
class KVncView;
41
36
Lines 62-112 Link Here
62
	} e;
57
	} e;
63
};
58
};
64
59
65
class ControllerThreadObject : public TQObject {
66
	TQ_OBJECT
67
68
	public:
69
		ControllerThreadObject(KVncView *v, volatile bool &quitFlag);
70
		~ControllerThreadObject();
71
72
		enum RemoteViewStatus status();	
73
60
74
		void setImage(const TQImage &img);
61
class WriterThread : public TQThread {
75
		const TQImage image(int x = 0, int y = 0, int w = 0, int h = 0);
62
private:
76
		void authenticationResults(int resultCode);
63
	TQMutex m_lock;
77
		void networkStatus(int statusCode);
64
	TQWaitCondition m_waiter;
65
	volatile bool &m_quitFlag;
66
	KVncView *m_view;
67
68
	TQTime m_lastIncrUpdate; // start()ed when a incr update is sent
69
	bool m_lastIncrUpdatePostponed;
70
71
	// all things that can be send follow:
72
	bool m_incrementalUpdateRQ; // for sending an incremental request
73
	bool m_incrementalUpdateAnnounced; // set when a RQ will come soon
74
	TQRegion m_updateRegionRQ;  // for sending updates, null if it is done
75
	TQValueList<InputEvent> m_inputEvents; // list of unsent input events
76
	MouseEvent m_lastMouseEvent;
77
	int m_mouseEventNum, m_keyEventNum;
78
	TQString m_clientCut;
78
79
79
		void setScaling(int w, int h);
80
	void sendFatalError(ErrorCode s);
80
		void queueDrawRegion(int x, int y, int w, int h);
81
81
82
		rfbClient *cl;
82
public:
83
	
83
	WriterThread(KVncView *v, volatile bool &quitFlag);
84
	public slots:
85
		void run();
86
	
87
	public:
88
		void queueMouseEvent(int x, int y, int buttonMask);
89
		void queueKeyEvent(unsigned int k, bool down);
90
		void queueClientCut(const TQString &text);
91
92
	private:
93
		KVncView *m_view;
94
		TQImage m_image;
95
		TQImage m_scaledImage;
96
		TQMutex mutex;
97
		enum RemoteViewStatus m_status;
98
		volatile bool &m_quitFlag;
99
100
		bool m_scaling;
101
		int m_scalingWidth;
102
		int m_scalingHeight;
103
		bool m_resizeEntireFrame;
104
	
84
	
105
		// all things that can be send follow:
85
	void queueIncrementalUpdateRequest();
106
		TQValueList<InputEvent> m_inputEvents; // list of unsent input events
86
	void announceIncrementalUpdateRequest();
87
	void queueUpdateRequest(const TQRegion &r);
88
	void queueMouseEvent(int x, int y, int buttonMask);
89
	void queueKeyEvent(unsigned int k, bool down);
90
	void queueClientCut(const TQString &text);
91
	void kick();
107
	
92
	
108
		void changeStatus(RemoteViewStatus s);
93
protected:
109
		void sendFatalError(ErrorCode s);
94
	void run();
95
	bool sendIncrementalUpdateRequest();
96
	bool sendUpdateRequest(const TQRegion &r);
97
	bool sendInputEvents(const TQValueList<InputEvent> &events);
98
};
99
100
101
102
class ControllerThread : public TQThread { 
103
private:
104
	KVncView *m_view;
105
	enum RemoteViewStatus m_status;
106
	WriterThread &m_wthread;
107
	volatile bool &m_quitFlag;
108
	volatile bool m_desktopInitialized;
109
	TQWaitCondition m_waiter;
110
111
	void changeStatus(RemoteViewStatus s);
112
	void sendFatalError(ErrorCode s);
113
114
public:
115
	ControllerThread(KVncView *v, WriterThread &wt, volatile bool &quitFlag);
116
	enum RemoteViewStatus status();	
117
	void desktopInit();
118
	void kick();
119
120
protected:
121
	void run();
110
};
122
};
111
123
112
124
(-)tdenetwork-trinity-14.1.0-ORIG/krdc/vnc/tight.c (+610 lines)
Line 0 Link Here
1
/*
2
 *  Copyright (C) 2000, 2001 Const Kaplinsky.  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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
17
 *  USA.
18
 */
19
20
/*
21
 * tight.c - handle ``tight'' encoding.
22
 *
23
 * This file shouldn't be compiled directly. It is included multiple
24
 * times by rfbproto.c, each time with a different definition of the
25
 * macro BPP. For each value of BPP, this file defines a function
26
 * which handles a tight-encoded rectangle with BPP bits per pixel.
27
 *
28
 */
29
30
#define TIGHT_MIN_TO_COMPRESS 12
31
32
#define CARDBPP CONCAT2E(CARD,BPP)
33
#define filterPtrBPP CONCAT2E(filterPtr,BPP)
34
35
#define HandleTightBPP CONCAT2E(HandleTight,BPP)
36
#define InitFilterCopyBPP CONCAT2E(InitFilterCopy,BPP)
37
#define InitFilterPaletteBPP CONCAT2E(InitFilterPalette,BPP)
38
#define InitFilterGradientBPP CONCAT2E(InitFilterGradient,BPP)
39
#define FilterCopyBPP CONCAT2E(FilterCopy,BPP)
40
#define FilterPaletteBPP CONCAT2E(FilterPalette,BPP)
41
#define FilterGradientBPP CONCAT2E(FilterGradient,BPP)
42
#define FillRectangleBPP CONCAT2E(FillRectangle,BPP)
43
44
#if BPP != 8
45
#define DecompressJpegRectBPP CONCAT2E(DecompressJpegRect,BPP)
46
#endif
47
48
#ifndef RGB_TO_PIXEL
49
50
#define RGB_TO_PIXEL(bpp,r,g,b)						\
51
  (((CARD##bpp)(r) & myFormat.redMax) << myFormat.redShift |		\
52
   ((CARD##bpp)(g) & myFormat.greenMax) << myFormat.greenShift |	\
53
   ((CARD##bpp)(b) & myFormat.blueMax) << myFormat.blueShift)
54
55
#define RGB24_TO_PIXEL(bpp,r,g,b)                                       \
56
   ((((CARD##bpp)(r) & 0xFF) * myFormat.redMax + 127) / 255             \
57
    << myFormat.redShift |                                              \
58
    (((CARD##bpp)(g) & 0xFF) * myFormat.greenMax + 127) / 255           \
59
    << myFormat.greenShift |                                            \
60
    (((CARD##bpp)(b) & 0xFF) * myFormat.blueMax + 127) / 255            \
61
    << myFormat.blueShift)
62
63
#define RGB24_TO_PIXEL32(r,g,b)						\
64
  (((CARD32)(r) & 0xFF) << myFormat.redShift |				\
65
   ((CARD32)(g) & 0xFF) << myFormat.greenShift |			\
66
   ((CARD32)(b) & 0xFF) << myFormat.blueShift)
67
68
#endif
69
70
/* Type declarations */
71
72
typedef void (*filterPtrBPP)(int, CARDBPP *);
73
74
/* Prototypes */
75
76
static int InitFilterCopyBPP (int rw, int rh);
77
static int InitFilterPaletteBPP (int rw, int rh);
78
static int InitFilterGradientBPP (int rw, int rh);
79
static void FilterCopyBPP (int numRows, CARDBPP *destBuffer);
80
static void FilterPaletteBPP (int numRows, CARDBPP *destBuffer);
81
static void FilterGradientBPP (int numRows, CARDBPP *destBuffer);
82
83
static Bool DecompressJpegRectBPP(int x, int y, int w, int h);
84
85
/* Definitions */
86
87
static Bool
88
HandleTightBPP (int rx, int ry, int rw, int rh)
89
{
90
  CARDBPP fill_colour;
91
  XGCValues gcv;
92
  CARD8 comp_ctl;
93
  CARD8 filter_id;
94
  filterPtrBPP filterFn;
95
  z_streamp zs;
96
  char *buffer2;
97
  int err, stream_id, compressedLen, bitsPixel;
98
  int bufferSize, rowSize, numRows, portionLen, rowsProcessed, extraBytes;
99
  CARDBPP *rawData;
100
101
  if (!ReadFromRFBServer((char *)&comp_ctl, 1))
102
    return False;
103
104
  /* Flush zlib streams if we are told by the server to do so. */
105
  for (stream_id = 0; stream_id < 4; stream_id++) {
106
    if ((comp_ctl & 1) && zlibStreamActive[stream_id]) {
107
      if (inflateEnd (&zlibStream[stream_id]) != Z_OK &&
108
	  zlibStream[stream_id].msg != NULL)
109
	fprintf(stderr, "inflateEnd: %s\n", zlibStream[stream_id].msg);
110
      zlibStreamActive[stream_id] = False;
111
    }
112
    comp_ctl >>= 1;
113
  }
114
115
  /* Handle solid rectangles. */
116
  if (comp_ctl == rfbTightFill) {
117
#if BPP == 32
118
    if (myFormat.depth == 24 && myFormat.redMax == 0xFF &&
119
	myFormat.greenMax == 0xFF && myFormat.blueMax == 0xFF) {
120
      if (!ReadFromRFBServer(buffer, 3))
121
	return False;
122
      fill_colour = RGB24_TO_PIXEL32(buffer[0], buffer[1], buffer[2]);
123
    } else {
124
      if (!ReadFromRFBServer((char*)&fill_colour, sizeof(fill_colour)))
125
	return False;
126
    }
127
#else
128
    if (!ReadFromRFBServer((char*)&fill_colour, sizeof(fill_colour)))
129
	return False;
130
#endif
131
    
132
    LockFramebuffer();
133
    FillRectangleBPP(fill_colour, rx, ry, rw, rh);
134
    UnlockFramebuffer();
135
    SyncScreenRegion(rx, ry, rw, rh);
136
    return True;
137
  }
138
139
#if BPP == 8
140
  if (comp_ctl == rfbTightJpeg) {
141
    fprintf(stderr, "Tight encoding: JPEG is not supported in 8 bpp mode.\n");
142
    return False;
143
  }
144
#else
145
  if (comp_ctl == rfbTightJpeg) {
146
    return DecompressJpegRectBPP(rx, ry, rw, rh);
147
  }
148
#endif
149
150
  /* Quit on unsupported subencoding value. */
151
  if (comp_ctl > rfbTightMaxSubencoding) {
152
    fprintf(stderr, "Tight encoding: bad subencoding value received.\n");
153
    return False;
154
  }
155
156
  /*
157
   * Here primary compression mode handling begins.
158
   * Data was processed with optional filter + zlib compression.
159
   */
160
161
  /* First, we should identify a filter to use. */
162
  if ((comp_ctl & rfbTightExplicitFilter) != 0) {
163
    if (!ReadFromRFBServer((char*)&filter_id, 1))
164
      return False;
165
166
    switch (filter_id) {
167
    case rfbTightFilterCopy:
168
      filterFn = FilterCopyBPP;
169
      bitsPixel = InitFilterCopyBPP(rw, rh);
170
      break;
171
    case rfbTightFilterPalette:
172
      filterFn = FilterPaletteBPP;
173
      bitsPixel = InitFilterPaletteBPP(rw, rh);
174
      break;
175
    case rfbTightFilterGradient:
176
      filterFn = FilterGradientBPP;
177
      bitsPixel = InitFilterGradientBPP(rw, rh);
178
      break;
179
    default:
180
      fprintf(stderr, "Tight encoding: unknown filter code received.\n");
181
      return False;
182
    }
183
  } else {
184
    filterFn = FilterCopyBPP;
185
    bitsPixel = InitFilterCopyBPP(rw, rh);
186
  }
187
  if (bitsPixel == 0) {
188
    fprintf(stderr, "Tight encoding: error receiving palette.\n");
189
    return False;
190
  }
191
192
  /* Determine if the data should be decompressed or just copied. */
193
  rowSize = (rw * bitsPixel + 7) / 8;
194
  if (rh * rowSize < TIGHT_MIN_TO_COMPRESS) {
195
    if (!ReadFromRFBServer((char*)buffer, rh * rowSize))
196
      return False;
197
198
    buffer2 = &buffer[TIGHT_MIN_TO_COMPRESS * 4];
199
    filterFn(rh, (CARDBPP *)buffer2);
200
    CopyDataToScreen(buffer2, rx, ry, rw, rh);
201
202
    return True;
203
  }
204
205
  /* Read the length (1..3 bytes) of compressed data following. */
206
  compressedLen = (int)ReadCompactLen();
207
  if (compressedLen <= 0) {
208
    fprintf(stderr, "Incorrect data received from the server.\n");
209
    return False;
210
  }
211
212
  /* Now let's initialize compression stream if needed. */
213
  stream_id = comp_ctl & 0x03;
214
  zs = &zlibStream[stream_id];
215
  if (!zlibStreamActive[stream_id]) {
216
    zs->zalloc = Z_NULL;
217
    zs->zfree = Z_NULL;
218
    zs->opaque = Z_NULL;
219
    err = inflateInit(zs);
220
    if (err != Z_OK) {
221
      if (zs->msg != NULL)
222
	fprintf(stderr, "InflateInit error: %s.\n", zs->msg);
223
      return False;
224
    }
225
    zlibStreamActive[stream_id] = True;
226
  }
227
228
  /* Read, decode and draw actual pixel data in a loop. */
229
230
  bufferSize = BUFFER_SIZE * bitsPixel / (bitsPixel + BPP) & 0xFFFFFFFC;
231
  buffer2 = &buffer[bufferSize];
232
  if (rowSize > bufferSize) {
233
    /* Should be impossible when BUFFER_SIZE >= 16384 */
234
    fprintf(stderr, "Internal error: incorrect buffer size.\n");
235
    return False;
236
  }
237
238
  rowsProcessed = 0;
239
  extraBytes = 0;
240
241
  while (compressedLen > 0) {
242
    if (compressedLen > ZLIB_BUFFER_SIZE)
243
      portionLen = ZLIB_BUFFER_SIZE;
244
    else
245
      portionLen = compressedLen;
246
247
    if (!ReadFromRFBServer((char*)zlib_buffer, portionLen))
248
      return False;
249
250
    compressedLen -= portionLen;
251
252
    zs->next_in = (Bytef *)zlib_buffer;
253
    zs->avail_in = portionLen;
254
255
    do {
256
      zs->next_out = (Bytef *)&buffer[extraBytes];
257
      zs->avail_out = bufferSize - extraBytes;
258
259
      err = inflate(zs, Z_SYNC_FLUSH);
260
      if (err == Z_BUF_ERROR)   /* Input exhausted -- no problem. */
261
	break;
262
      if (err != Z_OK && err != Z_STREAM_END) {
263
	if (zs->msg != NULL) {
264
	  fprintf(stderr, "Inflate error: %s.\n", zs->msg);
265
	} else {
266
	  fprintf(stderr, "Inflate error: %d.\n", err);
267
	}
268
	return False;
269
      }
270
271
      numRows = (bufferSize - zs->avail_out) / rowSize;
272
273
      filterFn(numRows, (CARDBPP *)buffer2);
274
275
      extraBytes = bufferSize - zs->avail_out - numRows * rowSize;
276
      if (extraBytes > 0)
277
	memcpy(buffer, &buffer[numRows * rowSize], extraBytes);
278
279
      CopyDataToScreen(buffer2, rx, ry + rowsProcessed, rw, numRows);
280
      rowsProcessed += numRows;
281
    }
282
    while (zs->avail_out == 0);
283
  }
284
285
  if (rowsProcessed != rh) {
286
    fprintf(stderr, "Incorrect number of scan lines after decompression.\n");
287
    return False;
288
  }
289
290
  return True;
291
}
292
293
/*----------------------------------------------------------------------------
294
 *
295
 * Filter stuff.
296
 *
297
 */
298
299
/*
300
   The following variables are defined in rfbproto.c:
301
     static Bool cutZeros;
302
     static int rectWidth, rectColors;
303
     static CARD8 tightPalette[256*4];
304
     static CARD8 tightPrevRow[2048*3*sizeof(CARD16)];
305
*/
306
307
static int
308
InitFilterCopyBPP (int rw, int rh)
309
{
310
  rectWidth = rw;
311
312
#if BPP == 32
313
  if (myFormat.depth == 24 && myFormat.redMax == 0xFF &&
314
      myFormat.greenMax == 0xFF && myFormat.blueMax == 0xFF) {
315
    cutZeros = True;
316
    return 24;
317
  } else {
318
    cutZeros = False;
319
  }
320
#endif
321
322
  return BPP;
323
}
324
325
static void
326
FilterCopyBPP (int numRows, CARDBPP *dst)
327
{
328
329
#if BPP == 32
330
  int x, y;
331
332
  if (cutZeros) {
333
    for (y = 0; y < numRows; y++) {
334
      for (x = 0; x < rectWidth; x++) {
335
	dst[y*rectWidth+x] =
336
	  RGB24_TO_PIXEL32(buffer[(y*rectWidth+x)*3],
337
			   buffer[(y*rectWidth+x)*3+1],
338
			   buffer[(y*rectWidth+x)*3+2]);
339
      }
340
    }
341
    return;
342
  }
343
#endif
344
345
  memcpy (dst, buffer, numRows * rectWidth * (BPP / 8));
346
}
347
348
static int
349
InitFilterGradientBPP (int rw, int rh)
350
{
351
  int bits;
352
353
  bits = InitFilterCopyBPP(rw, rh);
354
  if (cutZeros)
355
    memset(tightPrevRow, 0, rw * 3);
356
  else
357
    memset(tightPrevRow, 0, rw * 3 * sizeof(CARD16));
358
359
  return bits;
360
}
361
362
#if BPP == 32
363
364
static void
365
FilterGradient24 (int numRows, CARD32 *dst)
366
{
367
  int x, y, c;
368
  CARD8 thisRow[2048*3];
369
  CARD8 pix[3];
370
  int est[3];
371
372
  for (y = 0; y < numRows; y++) {
373
374
    /* First pixel in a row */
375
    for (c = 0; c < 3; c++) {
376
      pix[c] = tightPrevRow[c] + buffer[y*rectWidth*3+c];
377
      thisRow[c] = pix[c];
378
    }
379
    dst[y*rectWidth] = RGB24_TO_PIXEL32(pix[0], pix[1], pix[2]);
380
381
    /* Remaining pixels of a row */
382
    for (x = 1; x < rectWidth; x++) {
383
      for (c = 0; c < 3; c++) {
384
	est[c] = (int)tightPrevRow[x*3+c] + (int)pix[c] -
385
		 (int)tightPrevRow[(x-1)*3+c];
386
	if (est[c] > 0xFF) {
387
	  est[c] = 0xFF;
388
	} else if (est[c] < 0x00) {
389
	  est[c] = 0x00;
390
	}
391
	pix[c] = (CARD8)est[c] + buffer[(y*rectWidth+x)*3+c];
392
	thisRow[x*3+c] = pix[c];
393
      }
394
      dst[y*rectWidth+x] = RGB24_TO_PIXEL32(pix[0], pix[1], pix[2]);
395
    }
396
397
    memcpy(tightPrevRow, thisRow, rectWidth * 3);
398
  }
399
}
400
401
#endif
402
403
static void
404
FilterGradientBPP (int numRows, CARDBPP *dst)
405
{
406
  int x, y, c;
407
  CARDBPP *src = (CARDBPP *)buffer;
408
  CARD16 *thatRow = (CARD16 *)tightPrevRow;
409
  CARD16 thisRow[2048*3];
410
  CARD16 pix[3];
411
  CARD16 max[3];
412
  int shift[3];
413
  int est[3];
414
415
#if BPP == 32
416
  if (cutZeros) {
417
    FilterGradient24(numRows, dst);
418
    return;
419
  }
420
#endif
421
422
  max[0] = myFormat.redMax;
423
  max[1] = myFormat.greenMax;
424
  max[2] = myFormat.blueMax;
425
426
  shift[0] = myFormat.redShift;
427
  shift[1] = myFormat.greenShift;
428
  shift[2] = myFormat.blueShift;
429
430
  for (y = 0; y < numRows; y++) {
431
432
    /* First pixel in a row */
433
    for (c = 0; c < 3; c++) {
434
      pix[c] = (CARD16)((src[y*rectWidth] >> shift[c]) + thatRow[c] & max[c]);
435
      thisRow[c] = pix[c];
436
    }
437
    dst[y*rectWidth] = RGB_TO_PIXEL(BPP, pix[0], pix[1], pix[2]);
438
439
    /* Remaining pixels of a row */
440
    for (x = 1; x < rectWidth; x++) {
441
      for (c = 0; c < 3; c++) {
442
	est[c] = (int)thatRow[x*3+c] + (int)pix[c] - (int)thatRow[(x-1)*3+c];
443
	if (est[c] > (int)max[c]) {
444
	  est[c] = (int)max[c];
445
	} else if (est[c] < 0) {
446
	  est[c] = 0;
447
	}
448
	pix[c] = (CARD16)((src[y*rectWidth+x] >> shift[c]) + est[c] & max[c]);
449
	thisRow[x*3+c] = pix[c];
450
      }
451
      dst[y*rectWidth+x] = RGB_TO_PIXEL(BPP, pix[0], pix[1], pix[2]);
452
    }
453
    memcpy(thatRow, thisRow, rectWidth * 3 * sizeof(CARD16));
454
  }
455
}
456
457
static int
458
InitFilterPaletteBPP (int rw, int rh)
459
{
460
  int i;
461
  CARD8 numColors;
462
  CARDBPP *palette = (CARDBPP *)tightPalette;
463
464
  rectWidth = rw;
465
466
  if (!ReadFromRFBServer((char*)&numColors, 1))
467
    return 0;
468
469
  rectColors = (int)numColors;
470
  if (++rectColors < 2)
471
    return 0;
472
473
#if BPP == 32
474
  if (myFormat.depth == 24 && myFormat.redMax == 0xFF &&
475
      myFormat.greenMax == 0xFF && myFormat.blueMax == 0xFF) {
476
    if (!ReadFromRFBServer((char*)&tightPalette, rectColors * 3))
477
      return 0;
478
    for (i = rectColors - 1; i >= 0; i--) {
479
      palette[i] = RGB24_TO_PIXEL32(tightPalette[i*3],
480
				    tightPalette[i*3+1],
481
				    tightPalette[i*3+2]);
482
    }
483
    return (rectColors == 2) ? 1 : 8;
484
  }
485
#endif
486
487
  if (!ReadFromRFBServer((char*)&tightPalette, rectColors * (BPP / 8)))
488
    return 0;
489
490
  return (rectColors == 2) ? 1 : 8;
491
}
492
493
static void
494
FilterPaletteBPP (int numRows, CARDBPP *dst)
495
{
496
  int x, y, b, w;
497
  CARD8 *src = (CARD8 *)buffer;
498
  CARDBPP *palette = (CARDBPP *)tightPalette;
499
500
  if (rectColors == 2) {
501
    w = (rectWidth + 7) / 8;
502
    for (y = 0; y < numRows; y++) {
503
      for (x = 0; x < rectWidth / 8; x++) {
504
	for (b = 7; b >= 0; b--)
505
	  dst[y*rectWidth+x*8+7-b] = palette[src[y*w+x] >> b & 1];
506
      }
507
      for (b = 7; b >= 8 - rectWidth % 8; b--) {
508
	dst[y*rectWidth+x*8+7-b] = palette[src[y*w+x] >> b & 1];
509
      }
510
    }
511
  } else {
512
    for (y = 0; y < numRows; y++)
513
      for (x = 0; x < rectWidth; x++)
514
	dst[y*rectWidth+x] = palette[(int)src[y*rectWidth+x]];
515
  }
516
}
517
518
#if BPP != 8
519
520
/*----------------------------------------------------------------------------
521
 *
522
 * JPEG decompression.
523
 *
524
 */
525
526
/*
527
   The following variables are defined in rfbproto.c:
528
     static Bool jpegError;
529
     static struct jpeg_source_mgr jpegSrcManager;
530
     static JOCTET *jpegBufferPtr;
531
     static size_t *jpegBufferLen;
532
*/
533
534
static Bool
535
DecompressJpegRectBPP(int x, int y, int w, int h)
536
{
537
  struct jpeg_decompress_struct cinfo;
538
  struct jpeg_error_mgr jerr;
539
  int compressedLen;
540
  CARD8 *compressedData;
541
  CARDBPP *pixelPtr;
542
  JSAMPROW rowPointer[1];
543
  int dx, dy;
544
545
  compressedLen = (int)ReadCompactLen();
546
  if (compressedLen <= 0) {
547
    fprintf(stderr, "Incorrect data received from the server.\n");
548
    return False;
549
  }
550
551
  if (compressedLen > MAX_JPEG_SIZE) {
552
    fprintf(stderr, "To large data announced by the server.\n");
553
    return False;
554
  }
555
556
  compressedData = malloc(compressedLen);
557
  if (compressedData == NULL) {
558
    fprintf(stderr, "Memory allocation error.\n");
559
    return False;
560
  }
561
562
  if (!ReadFromRFBServer((char*)compressedData, compressedLen)) {
563
    free(compressedData);
564
    return False;
565
  }
566
567
  cinfo.err = jpeg_std_error(&jerr);
568
  jpeg_create_decompress(&cinfo);
569
570
  JpegSetSrcManager(&cinfo, compressedData, compressedLen);
571
572
  jpeg_read_header(&cinfo, TRUE);
573
  cinfo.out_color_space = JCS_RGB;
574
575
  jpeg_start_decompress(&cinfo);
576
  if (cinfo.output_width != w || cinfo.output_height != h ||
577
      cinfo.output_components != 3) {
578
    fprintf(stderr, "Tight Encoding: Wrong JPEG data received.\n");
579
    jpeg_destroy_decompress(&cinfo);
580
    free(compressedData);
581
    return False;
582
  }
583
584
  rowPointer[0] = (JSAMPROW)buffer;
585
  dy = 0;
586
  while (cinfo.output_scanline < cinfo.output_height) {
587
    jpeg_read_scanlines(&cinfo, rowPointer, 1);
588
    if (jpegError) {
589
      break;
590
    }
591
    pixelPtr = (CARDBPP *)&buffer[BUFFER_SIZE / 2];
592
    for (dx = 0; dx < w; dx++) {
593
      *pixelPtr++ =
594
	RGB24_TO_PIXEL(BPP, buffer[dx*3], buffer[dx*3+1], buffer[dx*3+2]);
595
    }
596
    CopyDataToScreen(&buffer[BUFFER_SIZE / 2], x, y + dy, w, 1);
597
    dy++;
598
  }
599
600
  if (!jpegError)
601
    jpeg_finish_decompress(&cinfo);
602
603
  jpeg_destroy_decompress(&cinfo);
604
  free(compressedData);
605
606
  return !jpegError;
607
}
608
609
#endif
610
(-)tdenetwork-trinity-14.1.0-ORIG/krdc/vnc/vncauth.c (+161 lines)
Line 0 Link Here
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 program; if not, write to the Free Software
16
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
17
 *  USA.
18
 */
19
20
/*
21
 * vncauth.c - Functions for VNC password management and authentication.
22
 */
23
24
#include <stdio.h>
25
#include <stdlib.h>
26
#include <string.h>
27
#include <sys/types.h>
28
#include <sys/stat.h>
29
#include <vncauth.h>
30
#include <d3des.h>
31
32
33
/*
34
 * We use a fixed key to store passwords, since we assume that our local
35
 * file system is secure but nonetheless don't want to store passwords
36
 * as plaintext.
37
 */
38
39
unsigned char fixedkey[8] = {23,82,107,6,35,78,88,7};
40
41
42
/*
43
 * Encrypt a password and store it in a file.  Returns 0 if successful,
44
 * 1 if the file could not be written.
45
 */
46
47
int
48
vncEncryptAndStorePasswd(char *passwd, char *fname)
49
{
50
    FILE *fp;
51
    int i;
52
    unsigned char encryptedPasswd[8];
53
54
    if ((fp = fopen(fname,"w")) == NULL) return 1;
55
56
    chmod(fname, S_IRUSR|S_IWUSR);
57
58
    /* pad password with nulls */
59
60
    for (i = 0; i < 8; i++) {
61
	if (i < strlen(passwd)) {
62
	    encryptedPasswd[i] = passwd[i];
63
	} else {
64
	    encryptedPasswd[i] = 0;
65
	}
66
    }
67
68
    /* Do encryption in-place - this way we overwrite our copy of the plaintext
69
       password */
70
71
    deskey(fixedkey, EN0);
72
    des(encryptedPasswd, encryptedPasswd);
73
74
    for (i = 0; i < 8; i++) {
75
	putc(encryptedPasswd[i], fp);
76
    }
77
  
78
    fclose(fp);
79
    return 0;
80
}
81
82
83
/*
84
 * Decrypt a password from a file.  Returns a pointer to a newly allocated
85
 * string containing the password or a null pointer if the password could
86
 * not be retrieved for some reason.
87
 */
88
89
char *
90
vncDecryptPasswdFromFile(char *fname)
91
{
92
    FILE *fp;
93
    int i, ch;
94
    unsigned char *passwd = (unsigned char *)malloc(9);
95
96
    if ((fp = fopen(fname,"r")) == NULL) return NULL;
97
98
    for (i = 0; i < 8; i++) {
99
	ch = getc(fp);
100
	if (ch == EOF) {
101
	    fclose(fp);
102
	    return NULL;
103
	}
104
	passwd[i] = ch;
105
    }
106
107
    fclose(fp);
108
109
    deskey(fixedkey, DE1);
110
    des(passwd, passwd);
111
112
    passwd[8] = 0;
113
114
    return (char *)passwd;
115
}
116
117
118
/*
119
 * Generate CHALLENGESIZE random bytes for use in challenge-response
120
 * authentication.
121
 */
122
123
void
124
vncRandomBytes(unsigned char *bytes)
125
{
126
    int i;
127
    unsigned int seed = (unsigned int) time(0);
128
129
    srandom(seed);
130
    for (i = 0; i < CHALLENGESIZE; i++) {
131
	bytes[i] = (unsigned char)(random() & 255);    
132
    }
133
}
134
135
136
/*
137
 * Encrypt CHALLENGESIZE bytes in memory using a password.
138
 */
139
140
void
141
vncEncryptBytes(unsigned char *bytes, char *passwd)
142
{
143
    unsigned char key[8];
144
    int i;
145
146
    /* key is simply password padded with nulls */
147
148
    for (i = 0; i < 8; i++) {
149
	if (i < strlen(passwd)) {
150
	    key[i] = passwd[i];
151
	} else {
152
	    key[i] = 0;
153
	}
154
    }
155
156
    deskey(key, EN0);
157
158
    for (i = 0; i < CHALLENGESIZE; i += 8) {
159
	des(bytes+i, bytes+i);
160
    }
161
}
(-)tdenetwork-trinity-14.1.0-ORIG/krdc/vnc/vncauth.h (+30 lines)
Line 0 Link Here
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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
17
 *  USA.
18
 */
19
20
/* 
21
 * vncauth.h - describes the functions provided by the vncauth library.
22
 */
23
24
#define MAXPWLEN 8
25
#define CHALLENGESIZE 16
26
27
extern int vncEncryptAndStorePasswd(char *passwd, char *fname);
28
extern char *vncDecryptPasswdFromFile(char *fname);
29
extern void vncRandomBytes(unsigned char *bytes);
30
extern void vncEncryptBytes(unsigned char *bytes, char *passwd);
(-)tdenetwork-trinity-14.1.0-ORIG/krdc/vnc/vnctypes.h (+73 lines)
Line 0 Link Here
1
/*
2
 *  Copyright (C) 2002 Tim Jansen.  All Rights Reserved.
3
 *  Copyright (C) 2000, 2001 Const Kaplinsky.  All Rights Reserved.
4
 *  Copyright (C) 2000 Tridia Corporation.  All Rights Reserved.
5
 *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
6
 *
7
 *  This is free software; you can redistribute it and/or modify
8
 *  it under the terms of the GNU General Public License as published by
9
 *  the Free Software Foundation; either version 2 of the License, or
10
 *  (at your option) any later version.
11
 *
12
 *  This software is distributed in the hope that it will be useful,
13
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 *  GNU General Public License for more details.
16
 *
17
 *  You should have received a copy of the GNU General Public License
18
 *  along with this software; if not, write to the Free Software
19
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
20
 *  USA.
21
 */
22
23
#ifndef VNCTYPES_H
24
#define VNCTYPES_H
25
26
#if(defined __cplusplus)
27
extern "C"
28
{
29
#endif
30
31
#include <X11/Xmd.h>
32
33
34
typedef struct {
35
  int shareDesktop; /* bool */
36
  int viewOnly; /* bool */
37
38
  const char* encodingsString;
39
40
  int useBGR233; /* bool */
41
  int nColours;
42
  int useSharedColours; /* bool */
43
  int requestedDepth;
44
45
  int rawDelay;
46
  int copyRectDelay;
47
48
  int debug; /* bool */
49
50
  int compressLevel;
51
  int qualityLevel;
52
  int dotCursor; /* bool */
53
54
} AppData;
55
56
57
enum InitStatus {
58
  INIT_OK = 0,
59
  INIT_NAME_RESOLUTION_FAILURE = 1,
60
  INIT_PROTOCOL_FAILURE = 2,
61
  INIT_CONNECTION_FAILED = 3,
62
  INIT_AUTHENTICATION_FAILED = 4,
63
  INIT_NO_SERVER = 5,
64
  INIT_SERVER_BLOCKED = 6,
65
  INIT_ABORTED = 7
66
};
67
68
69
#if(defined __cplusplus)
70
}
71
#endif
72
73
#endif
(-)tdenetwork-trinity-14.1.0-ORIG/krdc/vnc/vncviewer.h (-2 / +118 lines)
Lines 36-49 Link Here
36
#include <X11/keysym.h>
36
#include <X11/keysym.h>
37
#include <X11/Xatom.h>
37
#include <X11/Xatom.h>
38
#include <X11/Xmu/StdSel.h>
38
#include <X11/Xmu/StdSel.h>
39
#include "vnctypes.h" 
39
40
40
#if(defined __cplusplus)
41
#if(defined __cplusplus)
41
extern "C"
42
extern "C"
42
{
43
{
43
#endif
44
#endif
44
45
45
#include "rfb/rfbclient.h"
46
#include "rfbproto.h"
46
#include "rfb/rfbproto.h"
47
48
extern int endianTest;
49
50
#define Swap16IfLE(s) \
51
    (*(char *)&endianTest ? ((((s) & 0xff) << 8) | (((s) >> 8) & 0xff)) : (s))
52
53
#define Swap32IfLE(l) \
54
    (*(char *)&endianTest ? ((((l) & 0xff000000) >> 24) | \
55
			     (((l) & 0x00ff0000) >> 8)  | \
56
			     (((l) & 0x0000ff00) << 8)  | \
57
			     (((l) & 0x000000ff) << 24))  : (l))
58
59
#define MAX_ENCODINGS 20
60
47
61
48
/** kvncview.cpp **/
62
/** kvncview.cpp **/
49
63
Lines 64-69 Link Here
64
extern void newServerCut(char *bytes, int len);
78
extern void newServerCut(char *bytes, int len);
65
extern void postMouseEvent(int x, int y, int buttonMask);
79
extern void postMouseEvent(int x, int y, int buttonMask);
66
80
81
/** threads.cpp **/
82
83
extern void queueIncrementalUpdateRequest();
84
extern void announceIncrementalUpdateRequest();
85
86
/* colour.c */
87
88
extern unsigned long BGR233ToPixel[];
89
90
extern Colormap cmap;
91
extern Visual *vis;
92
extern unsigned int visdepth, visbpp;
93
94
extern void SetVisualAndCmap(void);
95
96
/* desktop.c */
97
98
extern Widget form, viewport, desktop;
99
extern GC gc;
100
extern GC srcGC, dstGC;
101
extern Dimension dpyWidth, dpyHeight;
102
103
extern void DesktopInit(Window win);
104
extern void ToplevelInit(void);
105
extern void SendRFBEvent(XEvent *event, String *params, Cardinal *num_params);
106
extern void CopyDataToScreen(char *buf, int x, int y, int width, int height);
107
extern void CopyDataFromScreen(char *buf, int x, int y, int width, int height);
108
extern void FillRectangle8(CARD8, int x, int y, int width, int height);
109
extern void FillRectangle16(CARD16, int x, int y, int width, int height);
110
extern void FillRectangle32(CARD32, int x, int y, int width, int height);
111
extern void CopyArea(int srcX, int srcY, int width, int height, int x, int y);
112
extern void SyncScreenRegion(int x, int y, int width, int height);
113
extern void SyncScreenRegionX11Thread(int x, int y, int width, int height);
114
extern void drawCursor(void);
115
extern void DrawCursorX11Thread(int x, int y);
116
extern void undrawCursor(void);
117
extern void getBoundingRectCursor(int cx, int cy, int _imageIndex,
118
				  int *x, int *y, int *w, int *h);
119
extern int rectsIntersect(int x, int y, int w, int h, 
120
			  int x2, int y2, int w2, int h2);
121
extern int rectContains(int outX, int outY, int outW, int outH, 
122
			int inX, int inY, int inW, int inH);
123
extern void rectsJoin(int *nx1, int *ny1, int *nw1, int *nh1, 
124
		      int x2, int y2, int w2, int h2);
125
extern void DrawZoomedScreenRegionX11Thread(Window win, int zwidth, 
126
					    int zheight, 
127
					    int x, int y, 
128
					    int width, int height);
129
extern void DrawScreenRegionX11Thread(Window win, int x, int y, 
130
				      int width, int height);
131
extern void Cleanup(void);
132
extern XImage *CreateShmZoomImage(void);
133
extern XImage *CreateShmImage(void);
134
extern void ShmCleanup(void);
135
extern void freeDesktopResources(void);
136
137
/* rfbproto.c */
138
139
extern int rfbsock;
140
extern Bool canUseCoRRE;
141
extern Bool canUseHextile;
142
extern char *desktopName;
143
extern rfbPixelFormat myFormat;
144
extern rfbServerInitMsg si;
145
146
extern int cursorX, cursorY;
147
extern int imageIndex;
148
typedef struct {
149
  int set;
150
  int w, h;
151
  int hotX, hotY;
152
  int len;
153
  char *image;
154
} PointerImage;
155
extern PointerImage pointerImages[];
156
157
extern int ConnectToRFBServer(const char *hostname, int port);
158
extern enum InitStatus InitialiseRFBConnection(void);
159
extern Bool SetFormatAndEncodings(void);
160
extern Bool SendIncrementalFramebufferUpdateRequest(void);
161
extern Bool SendFramebufferUpdateRequest(int x, int y, int w, int h,
162
					 Bool incremental);
163
extern Bool SendPointerEvent(int x, int y, int buttonMask);
164
extern Bool SendKeyEvent(CARD32 key, Bool down);
165
extern Bool SendClientCutText(const char *str, int len);
166
extern Bool HandleRFBServerMessage(void);
167
168
extern void PrintPixelFormat(rfbPixelFormat *format);
169
extern void freeRFBProtoResources(void);
170
extern void freeResources(void);
171
172
/* sockets.c */
173
174
extern Bool errorMessageOnReadFailure;
175
176
extern Bool ReadFromRFBServer(char *out, unsigned int n);
177
extern Bool WriteExact(int sock, const char *buf, int n);
178
extern int ConnectToTcpAddr(unsigned int host, int port);
179
180
extern int StringToIPAddr(const char *str, unsigned int *addr);
181
extern void freeSocketsResources(void);
182
67
#if(defined __cplusplus)
183
#if(defined __cplusplus)
68
}
184
}
69
#endif
185
#endif
(-)tdenetwork-trinity-14.1.0-ORIG/krdc/vnc/zlib.c (+157 lines)
Line 0 Link Here
1
/*
2
 *  Copyright (C) 2000 Tridia Corporation.  All Rights Reserved.
3
 *  Copyright (C) 1999 AT&T Laboratories Cambridge.  All Rights Reserved.
4
 *
5
 *  This is free software; you can redistribute it and/or modify
6
 *  it under the terms of the GNU General Public License as published by
7
 *  the Free Software Foundation; either version 2 of the License, or
8
 *  (at your option) any later version.
9
 *
10
 *  This software is distributed in the hope that it will be useful,
11
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 *  GNU General Public License for more details.
14
 *
15
 *  You should have received a copy of the GNU General Public License
16
 *  along with this software; if not, write to the Free Software
17
 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301,
18
 *  USA.
19
 */
20
21
/*
22
 * zlib.c - handle zlib encoding.
23
 *
24
 * This file shouldn't be compiled directly.  It is included multiple times by
25
 * rfbproto.c, each time with a different definition of the macro BPP.  For
26
 * each value of BPP, this file defines a function which handles an zlib
27
 * encoded rectangle with BPP bits per pixel.
28
 */
29
30
#define HandleZlibBPP CONCAT2E(HandleZlib,BPP)
31
#define CARDBPP CONCAT2E(CARD,BPP)
32
33
static Bool
34
HandleZlibBPP (int rx, int ry, int rw, int rh)
35
{
36
  rfbZlibHeader hdr;
37
  int remaining;
38
  int inflateResult;
39
  int toRead;
40
41
  /* First make sure we have a large enough raw buffer to hold the
42
   * decompressed data.  In practice, with a fixed BPP, fixed frame
43
   * buffer size and the first update containing the entire frame
44
   * buffer, this buffer allocation should only happen once, on the
45
   * first update.
46
   */
47
  if ( raw_buffer_size < (( rw * rh ) * ( BPP / 8 ))) {
48
49
    if ( raw_buffer != NULL ) {
50
51
      free( raw_buffer );
52
53
    }
54
55
    raw_buffer_size = (( rw * rh ) * ( BPP / 8 ));
56
    raw_buffer = (char*) malloc( raw_buffer_size );
57
58
  }
59
60
  if (!ReadFromRFBServer((char *)&hdr, sz_rfbZlibHeader))
61
    return False;
62
63
  remaining = Swap32IfLE(hdr.nBytes);
64
65
  /* Need to initialize the decompressor state. */
66
  decompStream.next_in   = ( Bytef * )buffer;
67
  decompStream.avail_in  = 0;
68
  decompStream.next_out  = ( Bytef * )raw_buffer;
69
  decompStream.avail_out = raw_buffer_size;
70
  decompStream.data_type = Z_BINARY;
71
72
  /* Initialize the decompression stream structures on the first invocation. */
73
  if ( decompStreamInited == False ) {
74
75
    inflateResult = inflateInit( &decompStream );
76
77
    if ( inflateResult != Z_OK ) {
78
      fprintf(stderr,
79
              "inflateInit returned error: %d, msg: %s\n",
80
              inflateResult,
81
              decompStream.msg);
82
      return False;
83
    }
84
85
    decompStreamInited = True;
86
87
  }
88
89
  inflateResult = Z_OK;
90
91
  /* Process buffer full of data until no more to process, or
92
   * some type of inflater error, or Z_STREAM_END.
93
   */
94
  while (( remaining > 0 ) &&
95
         ( inflateResult == Z_OK )) {
96
  
97
    if ( remaining > BUFFER_SIZE ) {
98
      toRead = BUFFER_SIZE;
99
    }
100
    else {
101
      toRead = remaining;
102
    }
103
104
    /* Fill the buffer, obtaining data from the server. */
105
    if (!ReadFromRFBServer(buffer,toRead))
106
      return False;
107
108
    decompStream.next_in  = ( Bytef * )buffer;
109
    decompStream.avail_in = toRead;
110
111
    /* Need to uncompress buffer full. */
112
    inflateResult = inflate( &decompStream, Z_SYNC_FLUSH );
113
114
    /* We never supply a dictionary for compression. */
115
    if ( inflateResult == Z_NEED_DICT ) {
116
      fprintf(stderr,"zlib inflate needs a dictionary!\n");
117
      return False;
118
    }
119
    if ( inflateResult < 0 ) {
120
      fprintf(stderr,
121
              "zlib inflate returned error: %d, msg: %s\n",
122
              inflateResult,
123
              decompStream.msg);
124
      return False;
125
    }
126
127
    /* Result buffer allocated to be at least large enough.  We should
128
     * never run out of space!
129
     */
130
    if (( decompStream.avail_in > 0 ) &&
131
        ( decompStream.avail_out <= 0 )) {
132
      fprintf(stderr,"zlib inflate ran out of space!\n");
133
      return False;
134
    }
135
136
    remaining -= toRead;
137
138
  } /* while ( remaining > 0 ) */
139
140
  if ( inflateResult == Z_OK ) {
141
142
    /* Put the uncompressed contents of the update on the screen. */
143
    CopyDataToScreen(raw_buffer, rx, ry, rw, rh);
144
145
  }
146
  else {
147
148
    fprintf(stderr,
149
            "zlib inflate returned error: %d, msg: %s\n",
150
            inflateResult,
151
            decompStream.msg);
152
    return False;
153
154
  }
155
156
  return True;
157
}

Return to bug 3206