InlineResponses.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298
  1. using System.IO;
  2. using System.Text;
  3. namespace Ryujinx.HLE.HOS.Applets.SoftwareKeyboard
  4. {
  5. internal class InlineResponses
  6. {
  7. private const uint MaxStrLenUTF8 = 0x7D4;
  8. private const uint MaxStrLenUTF16 = 0x3EC;
  9. private static void BeginResponse(InlineKeyboardState state, InlineKeyboardResponse resCode, BinaryWriter writer)
  10. {
  11. writer.Write((uint)state);
  12. writer.Write((uint)resCode);
  13. }
  14. private static uint WriteString(string text, BinaryWriter writer, uint maxSize, Encoding encoding)
  15. {
  16. // Ensure the text fits in the buffer, but do not straight cut the bytes because
  17. // this may corrupt the encoding. Search for a cut in the source string that fits.
  18. byte[] bytes = null;
  19. for (int maxStr = text.Length; maxStr >= 0; maxStr--)
  20. {
  21. // This loop will probably will run only once.
  22. bytes = encoding.GetBytes(text.Substring(0, maxStr));
  23. if (bytes.Length <= maxSize)
  24. {
  25. break;
  26. }
  27. }
  28. writer.Write(bytes);
  29. writer.Seek((int)maxSize - bytes.Length, SeekOrigin.Current);
  30. writer.Write((uint)text.Length); // String size
  31. return (uint)text.Length; // Return the cursor position at the end of the text
  32. }
  33. private static void WriteStringWithCursor(string text, uint cursor, BinaryWriter writer, uint maxSize, Encoding encoding, bool padMiddle)
  34. {
  35. uint length = WriteString(text, writer, maxSize, encoding);
  36. if (cursor > length)
  37. {
  38. cursor = length;
  39. }
  40. if (padMiddle)
  41. {
  42. writer.Write((int)-1); // ?
  43. writer.Write((int)-1); // ?
  44. }
  45. writer.Write(cursor); // Cursor position
  46. }
  47. public static byte[] FinishedInitialize(InlineKeyboardState state)
  48. {
  49. uint resSize = 2 * sizeof(uint) + 0x1;
  50. using (MemoryStream stream = new MemoryStream(new byte[resSize]))
  51. using (BinaryWriter writer = new BinaryWriter(stream))
  52. {
  53. BeginResponse(state, InlineKeyboardResponse.FinishedInitialize, writer);
  54. writer.Write((byte)1); // Data (ignored by the program)
  55. return stream.ToArray();
  56. }
  57. }
  58. public static byte[] Default(InlineKeyboardState state)
  59. {
  60. uint resSize = 2 * sizeof(uint);
  61. using (MemoryStream stream = new MemoryStream(new byte[resSize]))
  62. using (BinaryWriter writer = new BinaryWriter(stream))
  63. {
  64. BeginResponse(state, InlineKeyboardResponse.Default, writer);
  65. return stream.ToArray();
  66. }
  67. }
  68. public static byte[] ChangedString(string text, uint cursor, InlineKeyboardState state)
  69. {
  70. uint resSize = 6 * sizeof(uint) + MaxStrLenUTF16;
  71. using (MemoryStream stream = new MemoryStream(new byte[resSize]))
  72. using (BinaryWriter writer = new BinaryWriter(stream))
  73. {
  74. BeginResponse(state, InlineKeyboardResponse.ChangedString, writer);
  75. WriteStringWithCursor(text, cursor, writer, MaxStrLenUTF16, Encoding.Unicode, true);
  76. return stream.ToArray();
  77. }
  78. }
  79. public static byte[] MovedCursor(string text, uint cursor, InlineKeyboardState state)
  80. {
  81. uint resSize = 4 * sizeof(uint) + MaxStrLenUTF16;
  82. using (MemoryStream stream = new MemoryStream(new byte[resSize]))
  83. using (BinaryWriter writer = new BinaryWriter(stream))
  84. {
  85. BeginResponse(state, InlineKeyboardResponse.MovedCursor, writer);
  86. WriteStringWithCursor(text, cursor, writer, MaxStrLenUTF16, Encoding.Unicode, false);
  87. return stream.ToArray();
  88. }
  89. }
  90. public static byte[] MovedTab(string text, uint cursor, InlineKeyboardState state)
  91. {
  92. // Should be the same as MovedCursor.
  93. uint resSize = 4 * sizeof(uint) + MaxStrLenUTF16;
  94. using (MemoryStream stream = new MemoryStream(new byte[resSize]))
  95. using (BinaryWriter writer = new BinaryWriter(stream))
  96. {
  97. BeginResponse(state, InlineKeyboardResponse.MovedTab, writer);
  98. WriteStringWithCursor(text, cursor, writer, MaxStrLenUTF16, Encoding.Unicode, false);
  99. return stream.ToArray();
  100. }
  101. }
  102. public static byte[] DecidedEnter(string text, InlineKeyboardState state)
  103. {
  104. uint resSize = 3 * sizeof(uint) + MaxStrLenUTF16;
  105. using (MemoryStream stream = new MemoryStream(new byte[resSize]))
  106. using (BinaryWriter writer = new BinaryWriter(stream))
  107. {
  108. BeginResponse(state, InlineKeyboardResponse.DecidedEnter, writer);
  109. WriteString(text, writer, MaxStrLenUTF16, Encoding.Unicode);
  110. return stream.ToArray();
  111. }
  112. }
  113. public static byte[] DecidedCancel(InlineKeyboardState state)
  114. {
  115. uint resSize = 2 * sizeof(uint);
  116. using (MemoryStream stream = new MemoryStream(new byte[resSize]))
  117. using (BinaryWriter writer = new BinaryWriter(stream))
  118. {
  119. BeginResponse(state, InlineKeyboardResponse.DecidedCancel, writer);
  120. return stream.ToArray();
  121. }
  122. }
  123. public static byte[] ChangedStringUtf8(string text, uint cursor, InlineKeyboardState state)
  124. {
  125. uint resSize = 6 * sizeof(uint) + MaxStrLenUTF8;
  126. using (MemoryStream stream = new MemoryStream(new byte[resSize]))
  127. using (BinaryWriter writer = new BinaryWriter(stream))
  128. {
  129. BeginResponse(state, InlineKeyboardResponse.ChangedStringUtf8, writer);
  130. WriteStringWithCursor(text, cursor, writer, MaxStrLenUTF8, Encoding.UTF8, true);
  131. return stream.ToArray();
  132. }
  133. }
  134. public static byte[] MovedCursorUtf8(string text, uint cursor, InlineKeyboardState state)
  135. {
  136. uint resSize = 4 * sizeof(uint) + MaxStrLenUTF8;
  137. using (MemoryStream stream = new MemoryStream(new byte[resSize]))
  138. using (BinaryWriter writer = new BinaryWriter(stream))
  139. {
  140. BeginResponse(state, InlineKeyboardResponse.MovedCursorUtf8, writer);
  141. WriteStringWithCursor(text, cursor, writer, MaxStrLenUTF8, Encoding.UTF8, false);
  142. return stream.ToArray();
  143. }
  144. }
  145. public static byte[] DecidedEnterUtf8(string text, InlineKeyboardState state)
  146. {
  147. uint resSize = 3 * sizeof(uint) + MaxStrLenUTF8;
  148. using (MemoryStream stream = new MemoryStream(new byte[resSize]))
  149. using (BinaryWriter writer = new BinaryWriter(stream))
  150. {
  151. BeginResponse(state, InlineKeyboardResponse.DecidedEnterUtf8, writer);
  152. WriteString(text, writer, MaxStrLenUTF8, Encoding.UTF8);
  153. return stream.ToArray();
  154. }
  155. }
  156. public static byte[] UnsetCustomizeDic(InlineKeyboardState state)
  157. {
  158. uint resSize = 2 * sizeof(uint);
  159. using (MemoryStream stream = new MemoryStream(new byte[resSize]))
  160. using (BinaryWriter writer = new BinaryWriter(stream))
  161. {
  162. BeginResponse(state, InlineKeyboardResponse.UnsetCustomizeDic, writer);
  163. return stream.ToArray();
  164. }
  165. }
  166. public static byte[] ReleasedUserWordInfo(InlineKeyboardState state)
  167. {
  168. uint resSize = 2 * sizeof(uint);
  169. using (MemoryStream stream = new MemoryStream(new byte[resSize]))
  170. using (BinaryWriter writer = new BinaryWriter(stream))
  171. {
  172. BeginResponse(state, InlineKeyboardResponse.ReleasedUserWordInfo, writer);
  173. return stream.ToArray();
  174. }
  175. }
  176. public static byte[] UnsetCustomizedDictionaries(InlineKeyboardState state)
  177. {
  178. uint resSize = 2 * sizeof(uint);
  179. using (MemoryStream stream = new MemoryStream(new byte[resSize]))
  180. using (BinaryWriter writer = new BinaryWriter(stream))
  181. {
  182. BeginResponse(state, InlineKeyboardResponse.UnsetCustomizedDictionaries, writer);
  183. return stream.ToArray();
  184. }
  185. }
  186. public static byte[] ChangedStringV2(string text, uint cursor, InlineKeyboardState state)
  187. {
  188. uint resSize = 6 * sizeof(uint) + MaxStrLenUTF16 + 0x1;
  189. using (MemoryStream stream = new MemoryStream(new byte[resSize]))
  190. using (BinaryWriter writer = new BinaryWriter(stream))
  191. {
  192. BeginResponse(state, InlineKeyboardResponse.ChangedStringV2, writer);
  193. WriteStringWithCursor(text, cursor, writer, MaxStrLenUTF16, Encoding.Unicode, true);
  194. writer.Write((byte)0); // Flag == 0
  195. return stream.ToArray();
  196. }
  197. }
  198. public static byte[] MovedCursorV2(string text, uint cursor, InlineKeyboardState state)
  199. {
  200. uint resSize = 4 * sizeof(uint) + MaxStrLenUTF16 + 0x1;
  201. using (MemoryStream stream = new MemoryStream(new byte[resSize]))
  202. using (BinaryWriter writer = new BinaryWriter(stream))
  203. {
  204. BeginResponse(state, InlineKeyboardResponse.MovedCursorV2, writer);
  205. WriteStringWithCursor(text, cursor, writer, MaxStrLenUTF16, Encoding.Unicode, false);
  206. writer.Write((byte)0); // Flag == 0
  207. return stream.ToArray();
  208. }
  209. }
  210. public static byte[] ChangedStringUtf8V2(string text, uint cursor, InlineKeyboardState state)
  211. {
  212. uint resSize = 6 * sizeof(uint) + MaxStrLenUTF8 + 0x1;
  213. using (MemoryStream stream = new MemoryStream(new byte[resSize]))
  214. using (BinaryWriter writer = new BinaryWriter(stream))
  215. {
  216. BeginResponse(state, InlineKeyboardResponse.ChangedStringUtf8V2, writer);
  217. WriteStringWithCursor(text, cursor, writer, MaxStrLenUTF8, Encoding.UTF8, true);
  218. writer.Write((byte)0); // Flag == 0
  219. return stream.ToArray();
  220. }
  221. }
  222. public static byte[] MovedCursorUtf8V2(string text, uint cursor, InlineKeyboardState state)
  223. {
  224. uint resSize = 4 * sizeof(uint) + MaxStrLenUTF8 + 0x1;
  225. using (MemoryStream stream = new MemoryStream(new byte[resSize]))
  226. using (BinaryWriter writer = new BinaryWriter(stream))
  227. {
  228. BeginResponse(state, InlineKeyboardResponse.MovedCursorUtf8V2, writer);
  229. WriteStringWithCursor(text, cursor, writer, MaxStrLenUTF8, Encoding.UTF8, false);
  230. writer.Write((byte)0); // Flag == 0
  231. return stream.ToArray();
  232. }
  233. }
  234. }
  235. }