rrxinerama.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  1. /*
  2. * Copyright © 2006 Keith Packard
  3. *
  4. * Permission to use, copy, modify, distribute, and sell this software and its
  5. * documentation for any purpose is hereby granted without fee, provided that
  6. * the above copyright notice appear in all copies and that both that copyright
  7. * notice and this permission notice appear in supporting documentation, and
  8. * that the name of the copyright holders not be used in advertising or
  9. * publicity pertaining to distribution of the software without specific,
  10. * written prior permission. The copyright holders make no representations
  11. * about the suitability of this software for any purpose. It is provided "as
  12. * is" without express or implied warranty.
  13. *
  14. * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
  15. * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
  16. * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
  17. * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
  18. * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
  19. * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
  20. * OF THIS SOFTWARE.
  21. */
  22. /*
  23. * This Xinerama implementation comes from the SiS driver which has
  24. * the following notice:
  25. */
  26. /*
  27. * SiS driver main code
  28. *
  29. * Copyright (C) 2001-2005 by Thomas Winischhofer, Vienna, Austria.
  30. *
  31. * Redistribution and use in source and binary forms, with or without
  32. * modification, are permitted provided that the following conditions
  33. * are met:
  34. * 1) Redistributions of source code must retain the above copyright
  35. * notice, this list of conditions and the following disclaimer.
  36. * 2) Redistributions in binary form must reproduce the above copyright
  37. * notice, this list of conditions and the following disclaimer in the
  38. * documentation and/or other materials provided with the distribution.
  39. * 3) The name of the author may not be used to endorse or promote products
  40. * derived from this software without specific prior written permission.
  41. *
  42. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  43. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  44. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  45. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  46. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  47. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  48. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  49. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  50. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  51. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  52. *
  53. * Author: Thomas Winischhofer <thomas@winischhofer.net>
  54. * - driver entirely rewritten since 2001, only basic structure taken from
  55. * old code (except sis_dri.c, sis_shadow.c, sis_accel.c and parts of
  56. * sis_dga.c; these were mostly taken over; sis_dri.c was changed for
  57. * new versions of the DRI layer)
  58. *
  59. * This notice covers the entire driver code unless indicated otherwise.
  60. *
  61. * Formerly based on code which was
  62. * Copyright (C) 1998, 1999 by Alan Hourihane, Wigan, England.
  63. * Written by:
  64. * Alan Hourihane <alanh@fairlite.demon.co.uk>,
  65. * Mike Chapman <mike@paranoia.com>,
  66. * Juanjo Santamarta <santamarta@ctv.es>,
  67. * Mitani Hiroshi <hmitani@drl.mei.co.jp>,
  68. * David Thomas <davtom@dream.org.uk>.
  69. */
  70. #include "randrstr.h"
  71. #include "swaprep.h"
  72. #include <X11/extensions/panoramiXproto.h>
  73. #define RR_XINERAMA_MAJOR_VERSION 1
  74. #define RR_XINERAMA_MINOR_VERSION 1
  75. /* Xinerama is not multi-screen capable; just report about screen 0 */
  76. #define RR_XINERAMA_SCREEN 0
  77. static int ProcRRXineramaQueryVersion(ClientPtr client);
  78. static int ProcRRXineramaGetState(ClientPtr client);
  79. static int ProcRRXineramaGetScreenCount(ClientPtr client);
  80. static int ProcRRXineramaGetScreenSize(ClientPtr client);
  81. static int ProcRRXineramaIsActive(ClientPtr client);
  82. static int ProcRRXineramaQueryScreens(ClientPtr client);
  83. static int SProcRRXineramaDispatch(ClientPtr client);
  84. /* Proc */
  85. int
  86. ProcRRXineramaQueryVersion(ClientPtr client)
  87. {
  88. xPanoramiXQueryVersionReply rep;
  89. REQUEST_SIZE_MATCH(xPanoramiXQueryVersionReq);
  90. rep.type = X_Reply;
  91. rep.length = 0;
  92. rep.sequenceNumber = client->sequence;
  93. rep.majorVersion = RR_XINERAMA_MAJOR_VERSION;
  94. rep.minorVersion = RR_XINERAMA_MINOR_VERSION;
  95. if (client->swapped) {
  96. swaps(&rep.sequenceNumber);
  97. swapl(&rep.length);
  98. swaps(&rep.majorVersion);
  99. swaps(&rep.minorVersion);
  100. }
  101. WriteToClient(client, sizeof(xPanoramiXQueryVersionReply), (char *) &rep);
  102. return (client->noClientException);
  103. }
  104. int
  105. ProcRRXineramaGetState(ClientPtr client)
  106. {
  107. REQUEST(xPanoramiXGetStateReq);
  108. WindowPtr pWin;
  109. xPanoramiXGetStateReply rep;
  110. ScreenPtr pScreen;
  111. rrScrPrivPtr pScrPriv;
  112. Bool active = FALSE;
  113. REQUEST_SIZE_MATCH(xPanoramiXGetStateReq);
  114. pWin = LookupWindow(stuff->window, client);
  115. if (!pWin)
  116. return BadWindow;
  117. pScreen = pWin->drawable.pScreen;
  118. pScrPriv = rrGetScrPriv(pScreen);
  119. if (pScrPriv) {
  120. /* XXX do we need more than this? */
  121. active = TRUE;
  122. }
  123. rep.type = X_Reply;
  124. rep.length = 0;
  125. rep.sequenceNumber = client->sequence;
  126. rep.state = active;
  127. if (client->swapped) {
  128. swaps(&rep.sequenceNumber);
  129. swapl(&rep.length);
  130. }
  131. WriteToClient(client, sizeof(xPanoramiXGetStateReply), (char *) &rep);
  132. return client->noClientException;
  133. }
  134. static Bool
  135. RRXineramaScreenActive(ScreenPtr pScreen)
  136. {
  137. return rrGetScrPriv(pScreen) != NULL;
  138. }
  139. static Bool
  140. RRXineramaCrtcActive(RRCrtcPtr crtc)
  141. {
  142. return crtc->mode != NULL && crtc->numOutputs > 0;
  143. }
  144. static int
  145. RRXineramaScreenCount(ScreenPtr pScreen)
  146. {
  147. int i, n;
  148. n = 0;
  149. if (RRXineramaScreenActive(pScreen)) {
  150. rrScrPriv(pScreen);
  151. for (i = 0; i < pScrPriv->numCrtcs; i++)
  152. if (RRXineramaCrtcActive(pScrPriv->crtcs[i]))
  153. n++;
  154. }
  155. return n;
  156. }
  157. int
  158. ProcRRXineramaGetScreenCount(ClientPtr client)
  159. {
  160. REQUEST(xPanoramiXGetScreenCountReq);
  161. WindowPtr pWin;
  162. xPanoramiXGetScreenCountReply rep;
  163. REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq);
  164. pWin = LookupWindow(stuff->window, client);
  165. if (!pWin)
  166. return BadWindow;
  167. rep.type = X_Reply;
  168. rep.length = 0;
  169. rep.sequenceNumber = client->sequence;
  170. rep.ScreenCount = RRXineramaScreenCount(pWin->drawable.pScreen);
  171. if (client->swapped) {
  172. swaps(&rep.sequenceNumber);
  173. swapl(&rep.length);
  174. }
  175. WriteToClient(client, sizeof(xPanoramiXGetScreenCountReply), (char *) &rep);
  176. return client->noClientException;
  177. }
  178. int
  179. ProcRRXineramaGetScreenSize(ClientPtr client)
  180. {
  181. REQUEST(xPanoramiXGetScreenSizeReq);
  182. WindowPtr pWin, pRoot;
  183. ScreenPtr pScreen;
  184. xPanoramiXGetScreenSizeReply rep;
  185. REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq);
  186. pWin = LookupWindow(stuff->window, client);
  187. if (!pWin)
  188. return BadWindow;
  189. pScreen = pWin->drawable.pScreen;
  190. pRoot = WindowTable[pScreen->myNum];
  191. rep.type = X_Reply;
  192. rep.length = 0;
  193. rep.sequenceNumber = client->sequence;
  194. rep.width = pRoot->drawable.width;
  195. rep.height = pRoot->drawable.height;
  196. if (client->swapped) {
  197. swaps(&rep.sequenceNumber);
  198. swapl(&rep.length);
  199. swapl(&rep.width);
  200. swapl(&rep.height);
  201. }
  202. WriteToClient(client, sizeof(xPanoramiXGetScreenSizeReply), (char *) &rep);
  203. return client->noClientException;
  204. }
  205. int
  206. ProcRRXineramaIsActive(ClientPtr client)
  207. {
  208. xXineramaIsActiveReply rep;
  209. REQUEST_SIZE_MATCH(xXineramaIsActiveReq);
  210. rep.type = X_Reply;
  211. rep.length = 0;
  212. rep.sequenceNumber = client->sequence;
  213. rep.state = RRXineramaScreenActive(screenInfo.screens[RR_XINERAMA_SCREEN]);
  214. if (client->swapped) {
  215. swaps(&rep.sequenceNumber);
  216. swapl(&rep.length);
  217. swapl(&rep.state);
  218. }
  219. WriteToClient(client, sizeof(xXineramaIsActiveReply), (char *) &rep);
  220. return client->noClientException;
  221. }
  222. int
  223. ProcRRXineramaQueryScreens(ClientPtr client)
  224. {
  225. xXineramaQueryScreensReply rep;
  226. ScreenPtr pScreen = screenInfo.screens[RR_XINERAMA_SCREEN];
  227. REQUEST_SIZE_MATCH(xXineramaQueryScreensReq);
  228. if (RRXineramaScreenActive(pScreen)) {
  229. rrScrPriv(pScreen);
  230. if (pScrPriv->numCrtcs == 0 || pScrPriv->numOutputs == 0)
  231. RRGetInfo(pScreen);
  232. }
  233. rep.type = X_Reply;
  234. rep.sequenceNumber = client->sequence;
  235. rep.number = RRXineramaScreenCount(pScreen);
  236. rep.length = rep.number * sz_XineramaScreenInfo >> 2;
  237. if (client->swapped) {
  238. swaps(&rep.sequenceNumber);
  239. swapl(&rep.length);
  240. swapl(&rep.number);
  241. }
  242. WriteToClient(client, sizeof(xXineramaQueryScreensReply), (char *) &rep);
  243. if (rep.number) {
  244. rrScrPriv(pScreen);
  245. xXineramaScreenInfo scratch;
  246. int i;
  247. for (i = 0; i < pScrPriv->numCrtcs; i++) {
  248. RRCrtcPtr crtc = pScrPriv->crtcs[i];
  249. if (RRXineramaCrtcActive(crtc)) {
  250. int width, height;
  251. RRCrtcGetScanoutSize(crtc, &width, &height);
  252. scratch.x_org = crtc->x;
  253. scratch.y_org = crtc->y;
  254. scratch.width = width;
  255. scratch.height = height;
  256. if (client->swapped) {
  257. swaps(&scratch.x_org);
  258. swaps(&scratch.y_org);
  259. swaps(&scratch.width);
  260. swaps(&scratch.height);
  261. }
  262. WriteToClient(client, sz_XineramaScreenInfo, (char *) &scratch);
  263. }
  264. }
  265. }
  266. return client->noClientException;
  267. }
  268. static int
  269. ProcRRXineramaDispatch(ClientPtr client)
  270. {
  271. REQUEST(xReq);
  272. switch (stuff->data) {
  273. case X_PanoramiXQueryVersion:
  274. return ProcRRXineramaQueryVersion(client);
  275. case X_PanoramiXGetState:
  276. return ProcRRXineramaGetState(client);
  277. case X_PanoramiXGetScreenCount:
  278. return ProcRRXineramaGetScreenCount(client);
  279. case X_PanoramiXGetScreenSize:
  280. return ProcRRXineramaGetScreenSize(client);
  281. case X_XineramaIsActive:
  282. return ProcRRXineramaIsActive(client);
  283. case X_XineramaQueryScreens:
  284. return ProcRRXineramaQueryScreens(client);
  285. }
  286. return BadRequest;
  287. }
  288. /* SProc */
  289. static int
  290. SProcRRXineramaQueryVersion(ClientPtr client)
  291. {
  292. REQUEST(xPanoramiXQueryVersionReq);
  293. swaps(&stuff->length);
  294. REQUEST_SIZE_MATCH(xPanoramiXQueryVersionReq);
  295. return ProcRRXineramaQueryVersion(client);
  296. }
  297. static int
  298. SProcRRXineramaGetState(ClientPtr client)
  299. {
  300. REQUEST(xPanoramiXGetStateReq);
  301. swaps(&stuff->length);
  302. REQUEST_SIZE_MATCH(xPanoramiXGetStateReq);
  303. return ProcRRXineramaGetState(client);
  304. }
  305. static int
  306. SProcRRXineramaGetScreenCount(ClientPtr client)
  307. {
  308. REQUEST(xPanoramiXGetScreenCountReq);
  309. swaps(&stuff->length);
  310. REQUEST_SIZE_MATCH(xPanoramiXGetScreenCountReq);
  311. return ProcRRXineramaGetScreenCount(client);
  312. }
  313. static int
  314. SProcRRXineramaGetScreenSize(ClientPtr client)
  315. {
  316. REQUEST(xPanoramiXGetScreenSizeReq);
  317. swaps(&stuff->length);
  318. REQUEST_SIZE_MATCH(xPanoramiXGetScreenSizeReq);
  319. return ProcRRXineramaGetScreenSize(client);
  320. }
  321. static int
  322. SProcRRXineramaIsActive(ClientPtr client)
  323. {
  324. REQUEST(xXineramaIsActiveReq);
  325. swaps(&stuff->length);
  326. REQUEST_SIZE_MATCH(xXineramaIsActiveReq);
  327. return ProcRRXineramaIsActive(client);
  328. }
  329. static int
  330. SProcRRXineramaQueryScreens(ClientPtr client)
  331. {
  332. REQUEST(xXineramaQueryScreensReq);
  333. swaps(&stuff->length);
  334. REQUEST_SIZE_MATCH(xXineramaQueryScreensReq);
  335. return ProcRRXineramaQueryScreens(client);
  336. }
  337. int
  338. SProcRRXineramaDispatch(ClientPtr client)
  339. {
  340. REQUEST(xReq);
  341. switch (stuff->data) {
  342. case X_PanoramiXQueryVersion:
  343. return SProcRRXineramaQueryVersion(client);
  344. case X_PanoramiXGetState:
  345. return SProcRRXineramaGetState(client);
  346. case X_PanoramiXGetScreenCount:
  347. return SProcRRXineramaGetScreenCount(client);
  348. case X_PanoramiXGetScreenSize:
  349. return SProcRRXineramaGetScreenSize(client);
  350. case X_XineramaIsActive:
  351. return SProcRRXineramaIsActive(client);
  352. case X_XineramaQueryScreens:
  353. return SProcRRXineramaQueryScreens(client);
  354. }
  355. return BadRequest;
  356. }
  357. static void
  358. RRXineramaResetProc(ExtensionEntry * extEntry)
  359. {
  360. }
  361. void
  362. RRXineramaExtensionInit(void)
  363. {
  364. return;
  365. (void) AddExtension(PANORAMIX_PROTOCOL_NAME, 0, 0,
  366. ProcRRXineramaDispatch,
  367. SProcRRXineramaDispatch,
  368. RRXineramaResetProc, StandardMinorOpcode);
  369. }