You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

CMsgWriter.cxx 4.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. /* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
  2. *
  3. * This is free software; you can redistribute it and/or modify
  4. * it under the terms of the GNU General Public License as published by
  5. * the Free Software Foundation; either version 2 of the License, or
  6. * (at your option) any later version.
  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. See the
  11. * GNU General Public License for more details.
  12. *
  13. * You should have received a copy of the GNU General Public License
  14. * along with this software; if not, write to the Free Software
  15. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
  16. * USA.
  17. */
  18. #include <stdio.h>
  19. #include <rdr/OutStream.h>
  20. #include <rfb/msgTypes.h>
  21. #include <rfb/PixelFormat.h>
  22. #include <rfb/Rect.h>
  23. #include <rfb/ConnParams.h>
  24. #include <rfb/Decoder.h>
  25. #include <rfb/CMsgWriter.h>
  26. using namespace rfb;
  27. CMsgWriter::CMsgWriter(ConnParams* cp_, rdr::OutStream* os_)
  28. : cp(cp_), os(os_)
  29. {
  30. }
  31. CMsgWriter::~CMsgWriter()
  32. {
  33. }
  34. void CMsgWriter::writeSetPixelFormat(const PixelFormat& pf)
  35. {
  36. startMsg(msgTypeSetPixelFormat);
  37. os->pad(3);
  38. pf.write(os);
  39. endMsg();
  40. }
  41. void CMsgWriter::writeSetEncodings(int nEncodings, rdr::U32* encodings)
  42. {
  43. startMsg(msgTypeSetEncodings);
  44. os->skip(1);
  45. os->writeU16(nEncodings);
  46. for (int i = 0; i < nEncodings; i++)
  47. os->writeU32(encodings[i]);
  48. endMsg();
  49. }
  50. // Ask for encodings based on which decoders are supported. Assumes higher
  51. // encoding numbers are more desirable.
  52. void CMsgWriter::writeSetEncodings(int preferredEncoding, bool useCopyRect)
  53. {
  54. int nEncodings = 0;
  55. rdr::U32 encodings[encodingMax+3];
  56. if (cp->supportsLocalCursor)
  57. encodings[nEncodings++] = pseudoEncodingCursor;
  58. if (cp->supportsDesktopResize)
  59. encodings[nEncodings++] = pseudoEncodingDesktopSize;
  60. if (cp->supportsExtendedDesktopSize)
  61. encodings[nEncodings++] = pseudoEncodingExtendedDesktopSize;
  62. if (cp->supportsDesktopRename)
  63. encodings[nEncodings++] = pseudoEncodingDesktopName;
  64. if (Decoder::supported(preferredEncoding)) {
  65. encodings[nEncodings++] = preferredEncoding;
  66. }
  67. if (useCopyRect) {
  68. encodings[nEncodings++] = encodingCopyRect;
  69. }
  70. /*
  71. * Prefer encodings in this order:
  72. *
  73. * Tight, ZRLE, Hextile, *
  74. */
  75. if ((preferredEncoding != encodingTight) &&
  76. Decoder::supported(encodingTight))
  77. encodings[nEncodings++] = encodingTight;
  78. if ((preferredEncoding != encodingZRLE) &&
  79. Decoder::supported(encodingZRLE))
  80. encodings[nEncodings++] = encodingZRLE;
  81. if ((preferredEncoding != encodingHextile) &&
  82. Decoder::supported(encodingHextile))
  83. encodings[nEncodings++] = encodingHextile;
  84. // Remaining encodings
  85. for (int i = encodingMax; i >= 0; i--) {
  86. switch (i) {
  87. case encodingTight:
  88. case encodingZRLE:
  89. case encodingHextile:
  90. break;
  91. default:
  92. if ((i != preferredEncoding) && Decoder::supported(i))
  93. encodings[nEncodings++] = i;
  94. }
  95. }
  96. encodings[nEncodings++] = pseudoEncodingLastRect;
  97. if (cp->customCompressLevel && cp->compressLevel >= 0 && cp->compressLevel <= 9)
  98. encodings[nEncodings++] = pseudoEncodingCompressLevel0 + cp->compressLevel;
  99. if (!cp->noJpeg && cp->qualityLevel >= 0 && cp->qualityLevel <= 9)
  100. encodings[nEncodings++] = pseudoEncodingQualityLevel0 + cp->qualityLevel;
  101. writeSetEncodings(nEncodings, encodings);
  102. }
  103. void CMsgWriter::writeFramebufferUpdateRequest(const Rect& r, bool incremental)
  104. {
  105. startMsg(msgTypeFramebufferUpdateRequest);
  106. os->writeU8(incremental);
  107. os->writeU16(r.tl.x);
  108. os->writeU16(r.tl.y);
  109. os->writeU16(r.width());
  110. os->writeU16(r.height());
  111. endMsg();
  112. }
  113. void CMsgWriter::keyEvent(rdr::U32 key, bool down)
  114. {
  115. startMsg(msgTypeKeyEvent);
  116. os->writeU8(down);
  117. os->pad(2);
  118. os->writeU32(key);
  119. endMsg();
  120. }
  121. void CMsgWriter::pointerEvent(const Point& pos, int buttonMask)
  122. {
  123. Point p(pos);
  124. if (p.x < 0) p.x = 0;
  125. if (p.y < 0) p.y = 0;
  126. if (p.x >= cp->width) p.x = cp->width - 1;
  127. if (p.y >= cp->height) p.y = cp->height - 1;
  128. startMsg(msgTypePointerEvent);
  129. os->writeU8(buttonMask);
  130. os->writeU16(p.x);
  131. os->writeU16(p.y);
  132. endMsg();
  133. }
  134. void CMsgWriter::clientCutText(const char* str, rdr::U32 len)
  135. {
  136. startMsg(msgTypeClientCutText);
  137. os->pad(3);
  138. os->writeU32(len);
  139. os->writeBytes(str, len);
  140. endMsg();
  141. }