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.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199
  1. /* Copyright (C) 2002-2005 RealVNC Ltd. All Rights Reserved.
  2. * Copyright 2009-2014 Pierre Ossman for Cendio AB
  3. *
  4. * This is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 2 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This software is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this software; if not, write to the Free Software
  16. * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
  17. * USA.
  18. */
  19. #include <stdio.h>
  20. #include <rdr/OutStream.h>
  21. #include <rfb/msgTypes.h>
  22. #include <rfb/fenceTypes.h>
  23. #include <rfb/qemuTypes.h>
  24. #include <rfb/Exception.h>
  25. #include <rfb/PixelFormat.h>
  26. #include <rfb/Rect.h>
  27. #include <rfb/ServerParams.h>
  28. #include <rfb/CMsgWriter.h>
  29. using namespace rfb;
  30. CMsgWriter::CMsgWriter(ServerParams* server_, rdr::OutStream* os_)
  31. : server(server_), os(os_)
  32. {
  33. }
  34. CMsgWriter::~CMsgWriter()
  35. {
  36. }
  37. void CMsgWriter::writeClientInit(bool shared)
  38. {
  39. os->writeU8(shared);
  40. endMsg();
  41. }
  42. void CMsgWriter::writeSetPixelFormat(const PixelFormat& pf)
  43. {
  44. startMsg(msgTypeSetPixelFormat);
  45. os->pad(3);
  46. pf.write(os);
  47. endMsg();
  48. }
  49. void CMsgWriter::writeSetEncodings(const std::list<rdr::U32> encodings)
  50. {
  51. std::list<rdr::U32>::const_iterator iter;
  52. startMsg(msgTypeSetEncodings);
  53. os->skip(1);
  54. os->writeU16(encodings.size());
  55. for (iter = encodings.begin(); iter != encodings.end(); ++iter)
  56. os->writeU32(*iter);
  57. endMsg();
  58. }
  59. void CMsgWriter::writeSetDesktopSize(int width, int height,
  60. const ScreenSet& layout)
  61. {
  62. if (!server->supportsSetDesktopSize)
  63. throw Exception("Server does not support SetDesktopSize");
  64. startMsg(msgTypeSetDesktopSize);
  65. os->pad(1);
  66. os->writeU16(width);
  67. os->writeU16(height);
  68. os->writeU8(layout.num_screens());
  69. os->pad(1);
  70. ScreenSet::const_iterator iter;
  71. for (iter = layout.begin();iter != layout.end();++iter) {
  72. os->writeU32(iter->id);
  73. os->writeU16(iter->dimensions.tl.x);
  74. os->writeU16(iter->dimensions.tl.y);
  75. os->writeU16(iter->dimensions.width());
  76. os->writeU16(iter->dimensions.height());
  77. os->writeU32(iter->flags);
  78. }
  79. endMsg();
  80. }
  81. void CMsgWriter::writeFramebufferUpdateRequest(const Rect& r, bool incremental)
  82. {
  83. startMsg(msgTypeFramebufferUpdateRequest);
  84. os->writeU8(incremental);
  85. os->writeU16(r.tl.x);
  86. os->writeU16(r.tl.y);
  87. os->writeU16(r.width());
  88. os->writeU16(r.height());
  89. endMsg();
  90. }
  91. void CMsgWriter::writeEnableContinuousUpdates(bool enable,
  92. int x, int y, int w, int h)
  93. {
  94. if (!server->supportsContinuousUpdates)
  95. throw Exception("Server does not support continuous updates");
  96. startMsg(msgTypeEnableContinuousUpdates);
  97. os->writeU8(!!enable);
  98. os->writeU16(x);
  99. os->writeU16(y);
  100. os->writeU16(w);
  101. os->writeU16(h);
  102. endMsg();
  103. }
  104. void CMsgWriter::writeFence(rdr::U32 flags, unsigned len, const char data[])
  105. {
  106. if (!server->supportsFence)
  107. throw Exception("Server does not support fences");
  108. if (len > 64)
  109. throw Exception("Too large fence payload");
  110. if ((flags & ~fenceFlagsSupported) != 0)
  111. throw Exception("Unknown fence flags");
  112. startMsg(msgTypeClientFence);
  113. os->pad(3);
  114. os->writeU32(flags);
  115. os->writeU8(len);
  116. os->writeBytes(data, len);
  117. endMsg();
  118. }
  119. void CMsgWriter::writeKeyEvent(rdr::U32 keysym, rdr::U32 keycode, bool down)
  120. {
  121. if (!server->supportsQEMUKeyEvent || !keycode) {
  122. /* This event isn't meaningful without a valid keysym */
  123. if (!keysym)
  124. return;
  125. startMsg(msgTypeKeyEvent);
  126. os->writeU8(down);
  127. os->pad(2);
  128. os->writeU32(keysym);
  129. endMsg();
  130. } else {
  131. startMsg(msgTypeQEMUClientMessage);
  132. os->writeU8(qemuExtendedKeyEvent);
  133. os->writeU16(down);
  134. os->writeU32(keysym);
  135. os->writeU32(keycode);
  136. endMsg();
  137. }
  138. }
  139. void CMsgWriter::writePointerEvent(const Point& pos, int buttonMask)
  140. {
  141. Point p(pos);
  142. if (p.x < 0) p.x = 0;
  143. if (p.y < 0) p.y = 0;
  144. if (p.x >= server->width()) p.x = server->width() - 1;
  145. if (p.y >= server->height()) p.y = server->height() - 1;
  146. startMsg(msgTypePointerEvent);
  147. os->writeU8(buttonMask);
  148. os->writeU16(p.x);
  149. os->writeU16(p.y);
  150. endMsg();
  151. }
  152. void CMsgWriter::writeClientCutText(const char* str, rdr::U32 len)
  153. {
  154. startMsg(msgTypeClientCutText);
  155. os->pad(3);
  156. os->writeU32(len);
  157. os->writeBytes(str, len);
  158. endMsg();
  159. }
  160. void CMsgWriter::startMsg(int type)
  161. {
  162. os->writeU8(type);
  163. }
  164. void CMsgWriter::endMsg()
  165. {
  166. os->flush();
  167. }