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.

vncExt.c 8.1KB

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