Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319
  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 <stdint.h>
  20. #define NEED_REPLIES
  21. #include <X11/Xlib.h>
  22. #include <X11/Xlibint.h>
  23. #define _VNCEXT_PROTO_
  24. #include "vncExt.h"
  25. static Bool XVncExtQueryConnectNotifyWireToEvent(Display* dpy, XEvent* e,
  26. xEvent* w);
  27. static Bool extensionInited = False;
  28. static XExtCodes* codes = 0;
  29. static Bool checkExtension(Display* dpy)
  30. {
  31. if (!extensionInited) {
  32. extensionInited = True;
  33. codes = XInitExtension(dpy, VNCEXTNAME);
  34. if (!codes) return False;
  35. XESetWireToEvent(dpy, codes->first_event + VncExtQueryConnectNotify,
  36. XVncExtQueryConnectNotifyWireToEvent);
  37. }
  38. return codes != 0;
  39. }
  40. Bool XVncExtQueryExtension(Display* dpy, int* event_basep, int* error_basep)
  41. {
  42. if (!checkExtension(dpy)) return False;
  43. *event_basep = codes->first_event;
  44. *error_basep = codes->first_error;
  45. return True;
  46. }
  47. Bool XVncExtSetParam(Display* dpy, const char* param)
  48. {
  49. xVncExtSetParamReq* req;
  50. xVncExtSetParamReply rep;
  51. int paramLen = strlen(param);
  52. if (paramLen > 255) return False;
  53. if (!checkExtension(dpy)) return False;
  54. LockDisplay(dpy);
  55. GetReq(VncExtSetParam, req);
  56. req->reqType = codes->major_opcode;
  57. req->vncExtReqType = X_VncExtSetParam;
  58. req->length += (paramLen + 3) >> 2;
  59. req->paramLen = paramLen;
  60. Data(dpy, param, paramLen);
  61. if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
  62. UnlockDisplay(dpy);
  63. SyncHandle();
  64. return False;
  65. }
  66. UnlockDisplay(dpy);
  67. SyncHandle();
  68. return rep.success;
  69. }
  70. Bool XVncExtGetParam(Display* dpy, const char* param, char** value, int* len)
  71. {
  72. xVncExtGetParamReq* req;
  73. xVncExtGetParamReply rep;
  74. int paramLen = strlen(param);
  75. *value = 0;
  76. *len = 0;
  77. if (paramLen > 255) return False;
  78. if (!checkExtension(dpy)) return False;
  79. LockDisplay(dpy);
  80. GetReq(VncExtGetParam, req);
  81. req->reqType = codes->major_opcode;
  82. req->vncExtReqType = X_VncExtGetParam;
  83. req->length += (paramLen + 3) >> 2;
  84. req->paramLen = paramLen;
  85. Data(dpy, param, paramLen);
  86. if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
  87. UnlockDisplay(dpy);
  88. SyncHandle();
  89. return False;
  90. }
  91. if (rep.success) {
  92. *len = rep.valueLen;
  93. *value = (char*) Xmalloc (*len+1);
  94. if (!*value) {
  95. _XEatData(dpy, (*len+1)&~1);
  96. return False;
  97. }
  98. _XReadPad(dpy, *value, *len);
  99. (*value)[*len] = 0;
  100. }
  101. UnlockDisplay(dpy);
  102. SyncHandle();
  103. return rep.success;
  104. }
  105. char* XVncExtGetParamDesc(Display* dpy, const char* param)
  106. {
  107. xVncExtGetParamDescReq* req;
  108. xVncExtGetParamDescReply rep;
  109. char* desc = 0;
  110. int paramLen = strlen(param);
  111. if (paramLen > 255) return False;
  112. if (!checkExtension(dpy)) return False;
  113. LockDisplay(dpy);
  114. GetReq(VncExtGetParamDesc, req);
  115. req->reqType = codes->major_opcode;
  116. req->vncExtReqType = X_VncExtGetParamDesc;
  117. req->length += (paramLen + 3) >> 2;
  118. req->paramLen = paramLen;
  119. Data(dpy, param, paramLen);
  120. if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
  121. UnlockDisplay(dpy);
  122. SyncHandle();
  123. return False;
  124. }
  125. if (rep.success) {
  126. desc = (char*)Xmalloc(rep.descLen+1);
  127. if (!desc) {
  128. _XEatData(dpy, (rep.descLen+1)&~1);
  129. return False;
  130. }
  131. _XReadPad(dpy, desc, rep.descLen);
  132. desc[rep.descLen] = 0;
  133. }
  134. UnlockDisplay(dpy);
  135. SyncHandle();
  136. return desc;
  137. }
  138. char** XVncExtListParams(Display* dpy, int* nParams)
  139. {
  140. xVncExtListParamsReq* req;
  141. xVncExtListParamsReply rep;
  142. char** list = 0;
  143. char* ch;
  144. int rlen, paramLen, i;
  145. if (!checkExtension(dpy)) return False;
  146. LockDisplay(dpy);
  147. GetReq(VncExtListParams, req);
  148. req->reqType = codes->major_opcode;
  149. req->vncExtReqType = X_VncExtListParams;
  150. if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
  151. UnlockDisplay(dpy);
  152. SyncHandle();
  153. return False;
  154. }
  155. UnlockDisplay(dpy);
  156. SyncHandle();
  157. if (rep.nParams) {
  158. list = (char**)Xmalloc(rep.nParams * sizeof(char*));
  159. rlen = rep.length << 2;
  160. ch = (char*)Xmalloc(rlen + 1);
  161. if (!list || !ch) {
  162. if (list) Xfree((char*)list);
  163. if (ch) Xfree(ch);
  164. _XEatData(dpy, rlen);
  165. UnlockDisplay(dpy);
  166. SyncHandle();
  167. return 0;
  168. }
  169. _XReadPad(dpy, ch, rlen);
  170. paramLen = *ch++;
  171. for (i = 0; i < rep.nParams; i++) {
  172. list[i] = ch;
  173. ch += paramLen;
  174. paramLen = *ch;
  175. *ch++ = 0;
  176. }
  177. }
  178. *nParams = rep.nParams;
  179. UnlockDisplay(dpy);
  180. SyncHandle();
  181. return list;
  182. }
  183. void XVncExtFreeParamList(char** list)
  184. {
  185. if (list) {
  186. Xfree(list[0]-1);
  187. Xfree((char*)list);
  188. }
  189. }
  190. Bool XVncExtSelectInput(Display* dpy, Window w, int mask)
  191. {
  192. xVncExtSelectInputReq* req;
  193. if (!checkExtension(dpy)) return False;
  194. LockDisplay(dpy);
  195. GetReq(VncExtSelectInput, req);
  196. req->reqType = codes->major_opcode;
  197. req->vncExtReqType = X_VncExtSelectInput;
  198. req->window = w;
  199. req->mask = mask;
  200. UnlockDisplay(dpy);
  201. SyncHandle();
  202. return True;
  203. }
  204. Bool XVncExtConnect(Display* dpy, const char* hostAndPort)
  205. {
  206. xVncExtConnectReq* req;
  207. xVncExtConnectReply rep;
  208. int strLen = strlen(hostAndPort);
  209. if (strLen > 255) return False;
  210. if (!checkExtension(dpy)) return False;
  211. LockDisplay(dpy);
  212. GetReq(VncExtConnect, req);
  213. req->reqType = codes->major_opcode;
  214. req->vncExtReqType = X_VncExtConnect;
  215. req->length += (strLen + 3) >> 2;
  216. req->strLen = strLen;
  217. Data(dpy, hostAndPort, strLen);
  218. if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
  219. UnlockDisplay(dpy);
  220. SyncHandle();
  221. return False;
  222. }
  223. UnlockDisplay(dpy);
  224. SyncHandle();
  225. return rep.success;
  226. }
  227. Bool XVncExtGetQueryConnect(Display* dpy, char** addr, char** user,
  228. int* timeout, void** opaqueId)
  229. {
  230. xVncExtGetQueryConnectReq* req;
  231. xVncExtGetQueryConnectReply rep;
  232. if (!checkExtension(dpy)) return False;
  233. LockDisplay(dpy);
  234. GetReq(VncExtGetQueryConnect, req);
  235. req->reqType = codes->major_opcode;
  236. req->vncExtReqType = X_VncExtGetQueryConnect;
  237. if (!_XReply(dpy, (xReply *)&rep, 0, xFalse)) {
  238. UnlockDisplay(dpy);
  239. SyncHandle();
  240. return False;
  241. }
  242. UnlockDisplay(dpy);
  243. SyncHandle();
  244. *addr = Xmalloc(rep.addrLen+1);
  245. *user = Xmalloc(rep.userLen+1);
  246. if (!*addr || !*user) {
  247. Xfree(*addr);
  248. Xfree(*user);
  249. _XEatData(dpy, ((rep.addrLen+1)&~1) + ((rep.userLen+1)&~1));
  250. return False;
  251. }
  252. _XReadPad(dpy, *addr, rep.addrLen);
  253. (*addr)[rep.addrLen] = 0;
  254. _XReadPad(dpy, *user, rep.userLen);
  255. (*user)[rep.userLen] = 0;
  256. *timeout = rep.timeout;
  257. *opaqueId = (void*)(intptr_t)rep.opaqueId;
  258. return True;
  259. }
  260. Bool XVncExtApproveConnect(Display* dpy, void* opaqueId, int approve)
  261. {
  262. xVncExtApproveConnectReq* req;
  263. if (!checkExtension(dpy)) return False;
  264. LockDisplay(dpy);
  265. GetReq(VncExtApproveConnect, req);
  266. req->reqType = codes->major_opcode;
  267. req->vncExtReqType = X_VncExtApproveConnect;
  268. req->approve = approve;
  269. req->opaqueId = (CARD32)(intptr_t)opaqueId;
  270. UnlockDisplay(dpy);
  271. SyncHandle();
  272. return True;
  273. }
  274. static Bool XVncExtQueryConnectNotifyWireToEvent(Display* dpy, XEvent* e,
  275. xEvent* w)
  276. {
  277. XVncExtQueryConnectEvent* ev = (XVncExtQueryConnectEvent*)e;
  278. xVncExtQueryConnectNotifyEvent* wire
  279. = (xVncExtQueryConnectNotifyEvent*)w;
  280. ev->type = wire->type & 0x7f;
  281. ev->serial = _XSetLastRequestRead(dpy,(xGenericReply*)wire);
  282. ev->send_event = (wire->type & 0x80) != 0;
  283. ev->display = dpy;
  284. ev->window = wire->window;
  285. return True;
  286. }