dbe.c 56 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830
  1. /******************************************************************************
  2. *
  3. * Copyright (c) 1994, 1995 Hewlett-Packard Company
  4. *
  5. * Permission is hereby granted, free of charge, to any person obtaining
  6. * a copy of this software and associated documentation files (the
  7. * "Software"), to deal in the Software without restriction, including
  8. * without limitation the rights to use, copy, modify, merge, publish,
  9. * distribute, sublicense, and/or sell copies of the Software, and to
  10. * permit persons to whom the Software is furnished to do so, subject to
  11. * the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included
  14. * in all copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  17. * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  18. * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
  19. * IN NO EVENT SHALL HEWLETT-PACKARD COMPANY BE LIABLE FOR ANY CLAIM,
  20. * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  21. * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
  22. * THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  23. *
  24. * Except as contained in this notice, the name of the Hewlett-Packard
  25. * Company shall not be used in advertising or otherwise to promote the
  26. * sale, use or other dealings in this Software without prior written
  27. * authorization from the Hewlett-Packard Company.
  28. *
  29. * DIX DBE code
  30. *
  31. *****************************************************************************/
  32. /* INCLUDES */
  33. #ifdef HAVE_DIX_CONFIG_H
  34. #include <dix-config.h>
  35. #endif
  36. #include <string.h>
  37. #include <stdint.h>
  38. #include <X11/X.h>
  39. #include <X11/Xproto.h>
  40. #include "scrnintstr.h"
  41. #include "extnsionst.h"
  42. #include "extinit.h"
  43. #include "gcstruct.h"
  44. #include "dixstruct.h"
  45. #define NEED_DBE_PROTOCOL
  46. #include "dbestruct.h"
  47. #include "midbe.h"
  48. /* GLOBALS */
  49. /* Per-screen initialization functions [init'ed by DbeRegisterFunction()] */
  50. static Bool (*DbeInitFunct[MAXSCREENS]) (); /* pScreen, pDbeScreenPriv */
  51. /* These are static globals copied to DBE's screen private for use by DDX */
  52. static int dbeScreenPrivIndex;
  53. static int dbeWindowPrivIndex;
  54. /* These are static globals copied to DBE's screen private for use by DDX */
  55. static RESTYPE dbeDrawableResType;
  56. static RESTYPE dbeWindowPrivResType;
  57. /* This global is used by DbeAllocWinPrivPrivIndex() */
  58. static int winPrivPrivCount = 0;
  59. /* Used to generate DBE's BadBuffer error. */
  60. static int dbeErrorBase;
  61. /* Used by DbeRegisterFunction() to initialize the initialization function
  62. * table only once per server lifetime.
  63. */
  64. static Bool firstRegistrationPass = TRUE;
  65. /******************************************************************************
  66. *
  67. * DBE DIX Procedure: DbeValidateBuffer
  68. *
  69. * Description:
  70. *
  71. * This function is called from VALIDATE_DRAWABLE_AND_GC and from
  72. * various places in dispatch.c if the server has been compiled with
  73. * the flags -DNEED_DBE_BUF_BITS and -DNEED_DBE_BUF_VALIDATE.
  74. * When pWin->dstBuffer changes, this function will be called with pWin
  75. * as the first argument, the drawable ID that was specified as the
  76. * second argument (could be a back buffer id), and True for the third
  77. * argument.
  78. * When pWin->srcBuffer changes, the third argument will be False, and
  79. * the first two arguments are as described for dstBuffer.
  80. *
  81. * This function should prepare the hardware to access the specified
  82. * buffer for reads (if dstbuf is False) or writes (if dstbuf is True).
  83. *
  84. *****************************************************************************/
  85. void
  86. DbeValidateBuffer(WindowPtr pWin, XID drawID, Bool dstbuf)
  87. {
  88. DbeScreenPrivPtr pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW(pWin);
  89. if (pDbeScreenPriv->ValidateBuffer)
  90. (*pDbeScreenPriv->ValidateBuffer) (pWin, drawID, dstbuf);
  91. }
  92. /******************************************************************************
  93. *
  94. * DBE DIX Procedure: DbeRegisterFunction
  95. *
  96. * Description:
  97. *
  98. * This function registers the DBE init function for the specified screen.
  99. *
  100. *****************************************************************************/
  101. void
  102. DbeRegisterFunction(ScreenPtr pScreen, Bool (*funct) ( /* ??? */ ))
  103. {
  104. int i;
  105. /* Initialize the initialization function table if it has not been
  106. * initialized already.
  107. */
  108. if (firstRegistrationPass) {
  109. for (i = 0; i < MAXSCREENS; i++) {
  110. DbeInitFunct[i] = NULL;
  111. }
  112. firstRegistrationPass = FALSE;
  113. }
  114. DbeInitFunct[pScreen->myNum] = funct;
  115. } /* DbeRegisterFunction() */
  116. /******************************************************************************
  117. *
  118. * DBE DIX Procedure: DbeAllocWinPriv
  119. *
  120. * Description:
  121. *
  122. * This function was cloned from AllocateWindow() in window.c.
  123. * This function allocates a window priv structure to be associated
  124. * with a double-buffered window.
  125. *
  126. *****************************************************************************/
  127. static DbeWindowPrivPtr
  128. DbeAllocWinPriv(ScreenPtr pScreen)
  129. {
  130. DbeWindowPrivPtr pDbeWindowPriv;
  131. DbeScreenPrivPtr pDbeScreenPriv;
  132. char *ptr;
  133. DevUnion *ppriv;
  134. unsigned int *sizes;
  135. unsigned int size;
  136. int i;
  137. pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
  138. pDbeWindowPriv =
  139. malloc(pDbeScreenPriv->totalWinPrivSize);
  140. if (pDbeWindowPriv) {
  141. ppriv = (DevUnion *) (pDbeWindowPriv + 1);
  142. pDbeWindowPriv->devPrivates = ppriv;
  143. sizes = pDbeScreenPriv->winPrivPrivSizes;
  144. ptr = (char *) (ppriv + pDbeScreenPriv->winPrivPrivLen);
  145. for (i = pDbeScreenPriv->winPrivPrivLen; --i >= 0; ppriv++, sizes++) {
  146. if ((size = *sizes)) {
  147. ppriv->ptr = (pointer) ptr;
  148. ptr += size;
  149. }
  150. else
  151. ppriv->ptr = (pointer) NULL;
  152. }
  153. }
  154. return (pDbeWindowPriv);
  155. } /* DbeAllocWinPriv() */
  156. /******************************************************************************
  157. *
  158. * DBE DIX Procedure: DbeFallbackAllocWinPriv
  159. *
  160. * Description:
  161. *
  162. * This is a fallback function for AllocWinPriv().
  163. *
  164. *****************************************************************************/
  165. #if 0 /* NOT USED */
  166. static DbeWindowPrivPtr
  167. DbeFallbackAllocWinPriv(pScreen)
  168. ScreenPtr pScreen;
  169. {
  170. return (NULL);
  171. } /* DbeFallbackAllocWinPriv() */
  172. #endif
  173. /******************************************************************************
  174. *
  175. * DBE DIX Procedure: DbeAllocWinPrivPrivIndex
  176. *
  177. * Description:
  178. *
  179. * This function was cloned from AllocateWindowPrivateIndex() in window.c.
  180. * This function allocates a new window priv priv index by simply returning
  181. * an incremented private counter.
  182. *
  183. *****************************************************************************/
  184. static int
  185. DbeAllocWinPrivPrivIndex(void)
  186. {
  187. return winPrivPrivCount++;
  188. } /* DbeAllocWinPrivPrivIndex() */
  189. /******************************************************************************
  190. *
  191. * DBE DIX Procedure: DbeAllocWinPrivPriv
  192. *
  193. * Description:
  194. *
  195. * This function was cloned from AllocateWindowPrivate() in privates.c.
  196. * This function allocates a private structure to be hung off
  197. * a window private.
  198. *
  199. *****************************************************************************/
  200. static Bool
  201. DbeAllocWinPrivPriv(register ScreenPtr pScreen, int index, unsigned int amount)
  202. {
  203. DbeScreenPrivPtr pDbeScreenPriv;
  204. unsigned int oldamount;
  205. pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
  206. if (index >= pDbeScreenPriv->winPrivPrivLen) {
  207. unsigned *nsizes;
  208. nsizes = (unsigned *) realloc(pDbeScreenPriv->winPrivPrivSizes,
  209. (index + 1) * sizeof(unsigned));
  210. if (!nsizes) {
  211. return (FALSE);
  212. }
  213. while (pDbeScreenPriv->winPrivPrivLen <= index) {
  214. nsizes[pDbeScreenPriv->winPrivPrivLen++] = 0;
  215. pDbeScreenPriv->totalWinPrivSize += sizeof(DevUnion);
  216. }
  217. pDbeScreenPriv->winPrivPrivSizes = nsizes;
  218. }
  219. oldamount = pDbeScreenPriv->winPrivPrivSizes[index];
  220. if (amount > oldamount) {
  221. pDbeScreenPriv->winPrivPrivSizes[index] = amount;
  222. pDbeScreenPriv->totalWinPrivSize += (amount - oldamount);
  223. }
  224. return (TRUE);
  225. } /* DbeAllocWinPrivPriv() */
  226. /******************************************************************************
  227. *
  228. * DBE DIX Procedure: DbeStubScreen
  229. *
  230. * Description:
  231. *
  232. * This is function stubs the function pointers in the given DBE screen
  233. * private and increments the number of stubbed screens.
  234. *
  235. *****************************************************************************/
  236. static void
  237. DbeStubScreen(DbeScreenPrivPtr pDbeScreenPriv, int *nStubbedScreens)
  238. {
  239. /* Stub DIX. */
  240. pDbeScreenPriv->SetupBackgroundPainter = NULL;
  241. pDbeScreenPriv->AllocWinPriv = NULL;
  242. pDbeScreenPriv->AllocWinPrivPrivIndex = NULL;
  243. pDbeScreenPriv->AllocWinPrivPriv = NULL;
  244. /* Do not unwrap PositionWindow nor DestroyWindow. If the DDX
  245. * initialization function failed, we assume that it did not wrap
  246. * PositionWindow. Also, DestroyWindow is only wrapped if the DDX
  247. * initialization function succeeded.
  248. */
  249. /* Stub DDX. */
  250. pDbeScreenPriv->GetVisualInfo = NULL;
  251. pDbeScreenPriv->AllocBackBufferName = NULL;
  252. pDbeScreenPriv->SwapBuffers = NULL;
  253. pDbeScreenPriv->BeginIdiom = NULL;
  254. pDbeScreenPriv->EndIdiom = NULL;
  255. pDbeScreenPriv->WinPrivDelete = NULL;
  256. pDbeScreenPriv->ResetProc = NULL;
  257. pDbeScreenPriv->ValidateBuffer = NULL;
  258. (*nStubbedScreens)++;
  259. } /* DbeStubScreen() */
  260. /******************************************************************************
  261. *
  262. * DBE DIX Procedure: ProcDbeGetVersion
  263. *
  264. * Description:
  265. *
  266. * This function is for processing a DbeGetVersion request.
  267. * This request returns the major and minor version numbers of this
  268. * extension.
  269. *
  270. * Return Values:
  271. *
  272. * Success
  273. *
  274. *****************************************************************************/
  275. static int
  276. ProcDbeGetVersion(ClientPtr client)
  277. {
  278. /* REQUEST(xDbeGetVersionReq); */
  279. xDbeGetVersionReply rep;
  280. REQUEST_SIZE_MATCH(xDbeGetVersionReq);
  281. rep.type = X_Reply;
  282. rep.length = 0;
  283. rep.sequenceNumber = client->sequence;
  284. rep.majorVersion = DBE_MAJOR_VERSION;
  285. rep.minorVersion = DBE_MINOR_VERSION;
  286. if (client->swapped) {
  287. swaps(&rep.sequenceNumber);
  288. }
  289. WriteToClient(client, sizeof(xDbeGetVersionReply), (char *) &rep);
  290. return (client->noClientException);
  291. } /* ProcDbeGetVersion() */
  292. /******************************************************************************
  293. *
  294. * DBE DIX Procedure: ProcDbeAllocateBackBufferName
  295. *
  296. * Description:
  297. *
  298. * This function is for processing a DbeAllocateBackBufferName request.
  299. * This request allocates a drawable ID used to refer to the back buffer
  300. * of a window.
  301. *
  302. * Return Values:
  303. *
  304. * BadAlloc - server can not allocate resources
  305. * BadIDChoice - id is out of range for client; id is already in use
  306. * BadMatch - window is not an InputOutput window;
  307. * visual of window is not on list returned by
  308. * DBEGetVisualInfo;
  309. * BadValue - invalid swap action is specified
  310. * BadWindow - window is not a valid window
  311. * Success
  312. *
  313. *****************************************************************************/
  314. static int
  315. ProcDbeAllocateBackBufferName(ClientPtr client)
  316. {
  317. REQUEST(xDbeAllocateBackBufferNameReq);
  318. WindowPtr pWin;
  319. DbeScreenPrivPtr pDbeScreenPriv;
  320. DbeWindowPrivPtr pDbeWindowPriv;
  321. XdbeScreenVisualInfo scrVisInfo;
  322. int i;
  323. Bool visualMatched = FALSE;
  324. xDbeSwapAction swapAction;
  325. VisualID visual;
  326. int status;
  327. REQUEST_SIZE_MATCH(xDbeAllocateBackBufferNameReq);
  328. /* The window must be valid. */
  329. if (!(pWin = SecurityLookupWindow(stuff->window, client,
  330. SecurityWriteAccess))) {
  331. return (BadWindow);
  332. }
  333. /* The window must be InputOutput. */
  334. if (pWin->drawable.class != InputOutput) {
  335. return BadMatch;
  336. }
  337. /* The swap action must be valid. */
  338. swapAction = stuff->swapAction; /* use local var for performance. */
  339. if ((swapAction != XdbeUndefined) &&
  340. (swapAction != XdbeBackground) &&
  341. (swapAction != XdbeUntouched) && (swapAction != XdbeCopied)) {
  342. return BadValue;
  343. }
  344. /* The id must be in range and not already in use. */
  345. LEGAL_NEW_RESOURCE(stuff->buffer, client);
  346. /* The visual of the window must be in the list returned by
  347. * GetVisualInfo.
  348. */
  349. pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW(pWin);
  350. if (!pDbeScreenPriv->GetVisualInfo)
  351. return BadMatch; /* screen doesn't support double buffering */
  352. if (!(*pDbeScreenPriv->GetVisualInfo) (pWin->drawable.pScreen, &scrVisInfo)) {
  353. /* GetVisualInfo() failed to allocate visual info data. */
  354. return BadAlloc;
  355. }
  356. /* See if the window's visual is on the list. */
  357. visual = wVisual(pWin);
  358. for (i = 0; (i < scrVisInfo.count) && !visualMatched; i++) {
  359. if (scrVisInfo.visinfo[i].visual == visual) {
  360. visualMatched = TRUE;
  361. }
  362. }
  363. /* Free what was allocated by the GetVisualInfo() call above. */
  364. free(scrVisInfo.visinfo);
  365. if (!visualMatched) {
  366. return BadMatch;
  367. }
  368. if ((pDbeWindowPriv = DBE_WINDOW_PRIV(pWin)) == NULL) {
  369. /* There is no buffer associated with the window.
  370. * Allocate a window priv.
  371. */
  372. if (!(pDbeWindowPriv =
  373. (*pDbeScreenPriv->AllocWinPriv) (pWin->drawable.pScreen))) {
  374. return (BadAlloc);
  375. }
  376. /* Make the window priv a DBE window priv resource. */
  377. if (!AddResource(stuff->buffer, dbeWindowPrivResType,
  378. (pointer) pDbeWindowPriv)) {
  379. free(pDbeWindowPriv);
  380. return (BadAlloc);
  381. }
  382. /* Fill out window priv information. */
  383. pDbeWindowPriv->pWindow = pWin;
  384. pDbeWindowPriv->width = pWin->drawable.width;
  385. pDbeWindowPriv->height = pWin->drawable.height;
  386. pDbeWindowPriv->x = pWin->drawable.x;
  387. pDbeWindowPriv->y = pWin->drawable.y;
  388. pDbeWindowPriv->nBufferIDs = 0;
  389. /* Set the buffer ID array pointer to the initial (static) array). */
  390. pDbeWindowPriv->IDs = pDbeWindowPriv->initIDs;
  391. /* Initialize the buffer ID list. */
  392. pDbeWindowPriv->maxAvailableIDs = DBE_INIT_MAX_IDS;
  393. pDbeWindowPriv->IDs[0] = stuff->buffer;
  394. for (i = 1; i < DBE_INIT_MAX_IDS; i++) {
  395. pDbeWindowPriv->IDs[i] = DBE_FREE_ID_ELEMENT;
  396. }
  397. /* Actually connect the window priv to the window. */
  398. pWin->devPrivates[dbeWindowPrivIndex].ptr = (pointer) pDbeWindowPriv;
  399. } /* if -- There is no buffer associated with the window. */
  400. else {
  401. /* A buffer is already associated with the window.
  402. * Add the new buffer ID to the array, reallocating the array memory
  403. * if necessary.
  404. */
  405. /* Determine if there is a free element in the ID array. */
  406. for (i = 0; i < pDbeWindowPriv->maxAvailableIDs; i++) {
  407. if (pDbeWindowPriv->IDs[i] == DBE_FREE_ID_ELEMENT) {
  408. /* There is still room in the ID array. */
  409. break;
  410. }
  411. }
  412. if (i == pDbeWindowPriv->maxAvailableIDs) {
  413. /* No more room in the ID array -- reallocate another array. */
  414. XID *pIDs;
  415. /* Setup an array pointer for the realloc operation below. */
  416. if (pDbeWindowPriv->maxAvailableIDs == DBE_INIT_MAX_IDS) {
  417. /* We will malloc a new array. */
  418. pIDs = NULL;
  419. }
  420. else {
  421. /* We will realloc a new array. */
  422. pIDs = pDbeWindowPriv->IDs;
  423. }
  424. /* malloc/realloc a new array and initialize all elements to 0. */
  425. pDbeWindowPriv->IDs = (XID *) realloc(pIDs,
  426. (pDbeWindowPriv->
  427. maxAvailableIDs +
  428. DBE_INCR_MAX_IDS) *
  429. sizeof(XID));
  430. if (!pDbeWindowPriv->IDs) {
  431. return BadAlloc;
  432. }
  433. memset(&pDbeWindowPriv->IDs[pDbeWindowPriv->nBufferIDs], 0,
  434. (pDbeWindowPriv->maxAvailableIDs + DBE_INCR_MAX_IDS -
  435. pDbeWindowPriv->nBufferIDs) * sizeof(XID));
  436. if (pDbeWindowPriv->maxAvailableIDs == DBE_INIT_MAX_IDS) {
  437. /* We just went from using the initial (static) array to a
  438. * newly allocated array. Copy the IDs from the initial array
  439. * to the new array.
  440. */
  441. memcpy(pDbeWindowPriv->IDs, pDbeWindowPriv->initIDs,
  442. DBE_INIT_MAX_IDS * sizeof(XID));
  443. }
  444. pDbeWindowPriv->maxAvailableIDs += DBE_INCR_MAX_IDS;
  445. }
  446. /* Finally, record the buffer ID in the array. */
  447. pDbeWindowPriv->IDs[i] = stuff->buffer;
  448. /* Associate the new ID with an existing window priv. */
  449. if (!AddResource(stuff->buffer, dbeWindowPrivResType,
  450. (pointer) pDbeWindowPriv)) {
  451. pDbeWindowPriv->IDs[i] = DBE_FREE_ID_ELEMENT;
  452. return (BadAlloc);
  453. }
  454. } /* else -- A buffer is already associated with the window. */
  455. /* Call the DDX routine to allocate the back buffer. */
  456. status = (*pDbeScreenPriv->AllocBackBufferName) (pWin, stuff->buffer,
  457. stuff->swapAction);
  458. if ((status != Success) && (pDbeWindowPriv->nBufferIDs == 0)) {
  459. /* The DDX buffer allocation routine failed for the first buffer of
  460. * this window.
  461. */
  462. free(pDbeWindowPriv);
  463. return (status);
  464. }
  465. /* Increment the number of buffers (XIDs) associated with this window. */
  466. pDbeWindowPriv->nBufferIDs++;
  467. /* Set swap action on all calls. */
  468. pDbeWindowPriv->swapAction = stuff->swapAction;
  469. return (status);
  470. } /* ProcDbeAllocateBackBufferName() */
  471. /******************************************************************************
  472. *
  473. * DBE DIX Procedure: ProcDbeDeallocateBackBufferName
  474. *
  475. * Description:
  476. *
  477. * This function is for processing a DbeDeallocateBackBufferName request.
  478. * This request frees a drawable ID that was obtained by a
  479. * DbeAllocateBackBufferName request.
  480. *
  481. * Return Values:
  482. *
  483. * BadBuffer - buffer to deallocate is not associated with a window
  484. * Success
  485. *
  486. *****************************************************************************/
  487. static int
  488. ProcDbeDeallocateBackBufferName(ClientPtr client)
  489. {
  490. REQUEST(xDbeDeallocateBackBufferNameReq);
  491. DbeWindowPrivPtr pDbeWindowPriv;
  492. int i;
  493. REQUEST_SIZE_MATCH(xDbeDeallocateBackBufferNameReq);
  494. /* Buffer name must be valid */
  495. if (!(pDbeWindowPriv = (DbeWindowPrivPtr) SecurityLookupIDByType(client,
  496. stuff->
  497. buffer,
  498. dbeWindowPrivResType,
  499. SecurityDestroyAccess))
  500. ||
  501. !(SecurityLookupIDByType
  502. (client, stuff->buffer, dbeDrawableResType, SecurityDestroyAccess))) {
  503. client->errorValue = stuff->buffer;
  504. return (dbeErrorBase + DbeBadBuffer);
  505. }
  506. /* Make sure that the id is valid for the window.
  507. * This is paranoid code since we already looked up the ID by type
  508. * above.
  509. */
  510. for (i = 0; i < pDbeWindowPriv->nBufferIDs; i++) {
  511. /* Loop through the ID list to find the ID. */
  512. if (pDbeWindowPriv->IDs[i] == stuff->buffer) {
  513. break;
  514. }
  515. }
  516. if (i == pDbeWindowPriv->nBufferIDs) {
  517. /* We did not find the ID in the ID list. */
  518. client->errorValue = stuff->buffer;
  519. return dbeErrorBase + DbeBadBuffer;
  520. }
  521. FreeResource(stuff->buffer, RT_NONE);
  522. return Success;
  523. } /* ProcDbeDeallocateBackBufferName() */
  524. /******************************************************************************
  525. *
  526. * DBE DIX Procedure: ProcDbeSwapBuffers
  527. *
  528. * Description:
  529. *
  530. * This function is for processing a DbeSwapBuffers request.
  531. * This request swaps the buffers for all windows listed, applying the
  532. * appropriate swap action for each window.
  533. *
  534. * Return Values:
  535. *
  536. * BadAlloc - local allocation failed; this return value is not defined
  537. * by the protocol
  538. * BadMatch - a window in request is not double-buffered; a window in
  539. * request is listed more than once
  540. * BadValue - invalid swap action is specified; no swap action is
  541. * specified
  542. * BadWindow - a window in request is not valid
  543. * Success
  544. *
  545. *****************************************************************************/
  546. static int
  547. ProcDbeSwapBuffers(ClientPtr client)
  548. {
  549. REQUEST(xDbeSwapBuffersReq);
  550. WindowPtr pWin;
  551. DbeScreenPrivPtr pDbeScreenPriv;
  552. DbeSwapInfoPtr swapInfo;
  553. xDbeSwapInfo *dbeSwapInfo;
  554. int error;
  555. int i, j;
  556. int nStuff;
  557. REQUEST_AT_LEAST_SIZE(xDbeSwapBuffersReq);
  558. nStuff = stuff->n; /* use local variable for performance. */
  559. if (nStuff == 0) {
  560. return Success;
  561. }
  562. if (nStuff > UINT32_MAX / sizeof(DbeSwapInfoRec))
  563. return BadAlloc;
  564. /* Get to the swap info appended to the end of the request. */
  565. dbeSwapInfo = (xDbeSwapInfo *) &stuff[1];
  566. /* Allocate array to record swap information. */
  567. swapInfo = malloc(nStuff * sizeof(DbeSwapInfoRec));
  568. if (swapInfo == NULL) {
  569. return BadAlloc;
  570. }
  571. for (i = 0; i < nStuff; i++) {
  572. /* Check all windows to swap. */
  573. /* Each window must be a valid window - BadWindow. */
  574. if (!(pWin = SecurityLookupWindow(dbeSwapInfo[i].window, client,
  575. SecurityWriteAccess))) {
  576. free(swapInfo);
  577. return (BadWindow);
  578. }
  579. /* Each window must be double-buffered - BadMatch. */
  580. if (DBE_WINDOW_PRIV(pWin) == NULL) {
  581. free(swapInfo);
  582. return BadMatch;
  583. }
  584. /* Each window must only be specified once - BadMatch. */
  585. for (j = i + 1; j < nStuff; j++) {
  586. if (dbeSwapInfo[i].window == dbeSwapInfo[j].window) {
  587. free(swapInfo);
  588. return BadMatch;
  589. }
  590. }
  591. /* Each swap action must be valid - BadValue. */
  592. if ((dbeSwapInfo[i].swapAction != XdbeUndefined) &&
  593. (dbeSwapInfo[i].swapAction != XdbeBackground) &&
  594. (dbeSwapInfo[i].swapAction != XdbeUntouched) &&
  595. (dbeSwapInfo[i].swapAction != XdbeCopied)) {
  596. free(swapInfo);
  597. return BadValue;
  598. }
  599. /* Everything checks out OK. Fill in the swap info array. */
  600. swapInfo[i].pWindow = pWin;
  601. swapInfo[i].swapAction = dbeSwapInfo[i].swapAction;
  602. } /* for (i = 0; i < nStuff; i++) */
  603. /* Call the DDX routine to perform the swap(s). The DDX routine should
  604. * scan the swap list (swap info), swap any buffers that it knows how to
  605. * handle, delete them from the list, and update nStuff to indicate how
  606. * many windows it did not handle.
  607. *
  608. * This scheme allows a range of sophistication in the DDX SwapBuffers()
  609. * implementation. Naive implementations could just swap the first buffer
  610. * in the list, move the last buffer to the front, decrement nStuff, and
  611. * return. The next level of sophistication could be to scan the whole
  612. * list for windows on the same screen. Up another level, the DDX routine
  613. * could deal with cross-screen synchronization.
  614. */
  615. while (nStuff > 0) {
  616. pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW(swapInfo[0].pWindow);
  617. error = (*pDbeScreenPriv->SwapBuffers) (client, &nStuff, swapInfo);
  618. if (error != Success) {
  619. free(swapInfo);
  620. return (error);
  621. }
  622. }
  623. free(swapInfo);
  624. return (Success);
  625. } /* ProcDbeSwapBuffers() */
  626. /******************************************************************************
  627. *
  628. * DBE DIX Procedure: ProcDbeBeginIdiom
  629. *
  630. * Description:
  631. *
  632. * This function is for processing a DbeBeginIdiom request.
  633. * This request informs the server that a complex swap will immediately
  634. * follow this request.
  635. *
  636. * Return Values:
  637. *
  638. * Success
  639. *
  640. *****************************************************************************/
  641. static int
  642. ProcDbeBeginIdiom(ClientPtr client)
  643. {
  644. /* REQUEST(xDbeBeginIdiomReq); */
  645. DbeScreenPrivPtr pDbeScreenPriv;
  646. int i;
  647. REQUEST_SIZE_MATCH(xDbeBeginIdiomReq);
  648. for (i = 0; i < screenInfo.numScreens; i++) {
  649. pDbeScreenPriv = DBE_SCREEN_PRIV(screenInfo.screens[i]);
  650. /* Call the DDX begin idiom procedure if there is one. */
  651. if (pDbeScreenPriv->BeginIdiom) {
  652. (*pDbeScreenPriv->BeginIdiom) (client);
  653. }
  654. }
  655. return (Success);
  656. } /* ProcDbeBeginIdiom() */
  657. /******************************************************************************
  658. *
  659. * DBE DIX Procedure: ProcDbeGetVisualInfo
  660. *
  661. * Description:
  662. *
  663. * This function is for processing a ProcDbeGetVisualInfo request.
  664. * This request returns information about which visuals support
  665. * double buffering.
  666. *
  667. * Return Values:
  668. *
  669. * BadDrawable - value in screen specifiers is not a valid drawable
  670. * Success
  671. *
  672. *****************************************************************************/
  673. static int
  674. ProcDbeGetVisualInfo(ClientPtr client)
  675. {
  676. REQUEST(xDbeGetVisualInfoReq);
  677. DbeScreenPrivPtr pDbeScreenPriv;
  678. xDbeGetVisualInfoReply rep;
  679. Drawable *drawables;
  680. DrawablePtr *pDrawables = NULL;
  681. int i, j;
  682. int count; /* number of visual infos in reply */
  683. int length; /* length of reply */
  684. ScreenPtr pScreen;
  685. XdbeScreenVisualInfo *pScrVisInfo;
  686. REQUEST_AT_LEAST_SIZE(xDbeGetVisualInfoReq);
  687. if (stuff->n > UINT32_MAX / sizeof(DrawablePtr))
  688. return BadAlloc;
  689. /* Make sure any specified drawables are valid. */
  690. if (stuff->n != 0) {
  691. if (!(pDrawables = malloc(stuff->n *
  692. sizeof(DrawablePtr)))) {
  693. return (BadAlloc);
  694. }
  695. drawables = (Drawable *) &stuff[1];
  696. for (i = 0; i < stuff->n; i++) {
  697. if (!
  698. (pDrawables[i] =
  699. (DrawablePtr) SecurityLookupDrawable(drawables[i], client,
  700. SecurityReadAccess))) {
  701. free(pDrawables);
  702. return (BadDrawable);
  703. }
  704. }
  705. }
  706. count = (stuff->n == 0) ? screenInfo.numScreens : stuff->n;
  707. if (!(pScrVisInfo = malloc(count *
  708. sizeof
  709. (XdbeScreenVisualInfo))))
  710. {
  711. if (pDrawables) {
  712. free(pDrawables);
  713. }
  714. return (BadAlloc);
  715. }
  716. length = 0;
  717. for (i = 0; i < count; i++) {
  718. pScreen = (stuff->n == 0) ? screenInfo.screens[i] :
  719. pDrawables[i]->pScreen;
  720. pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
  721. if (!(*pDbeScreenPriv->GetVisualInfo) (pScreen, &pScrVisInfo[i])) {
  722. /* We failed to alloc pScrVisInfo[i].visinfo. */
  723. /* Free visinfos that we allocated for previous screen infos. */
  724. for (j = 0; j < i; j++) {
  725. free(pScrVisInfo[j].visinfo);
  726. }
  727. /* Free pDrawables if we needed to allocate it above. */
  728. if (pDrawables) {
  729. free(pDrawables);
  730. }
  731. return (BadAlloc);
  732. }
  733. /* Account for n, number of xDbeVisInfo items in list. */
  734. length += sizeof(CARD32);
  735. /* Account for n xDbeVisInfo items */
  736. length += pScrVisInfo[i].count * sizeof(xDbeVisInfo);
  737. }
  738. rep.type = X_Reply;
  739. rep.sequenceNumber = client->sequence;
  740. rep.length = length >> 2;
  741. rep.m = count;
  742. if (client->swapped) {
  743. swaps(&rep.sequenceNumber);
  744. swapl(&rep.length);
  745. swapl(&rep.m);
  746. }
  747. /* Send off reply. */
  748. WriteToClient(client, sizeof(xDbeGetVisualInfoReply), (char *) &rep);
  749. for (i = 0; i < count; i++) {
  750. CARD32 data32;
  751. /* For each screen in the reply, send off the visual info */
  752. /* Send off number of visuals. */
  753. data32 = (CARD32) pScrVisInfo[i].count;
  754. if (client->swapped) {
  755. swapl(&data32);
  756. }
  757. WriteToClient(client, sizeof(CARD32), (char *) &data32);
  758. /* Now send off visual info items. */
  759. for (j = 0; j < pScrVisInfo[i].count; j++) {
  760. xDbeVisInfo visInfo;
  761. /* Copy the data in the client data structure to a protocol
  762. * data structure. We will send data to the client from the
  763. * protocol data structure.
  764. */
  765. visInfo.visualID = (CARD32) pScrVisInfo[i].visinfo[j].visual;
  766. visInfo.depth = (CARD8) pScrVisInfo[i].visinfo[j].depth;
  767. visInfo.perfLevel = (CARD8) pScrVisInfo[i].visinfo[j].perflevel;
  768. if (client->swapped) {
  769. swapl(&visInfo.visualID);
  770. /* We do not need to swap depth and perfLevel since they are
  771. * already 1 byte quantities.
  772. */
  773. }
  774. /* Write visualID(32), depth(8), perfLevel(8), and pad(16). */
  775. WriteToClient(client, 2 * sizeof(CARD32),
  776. (char *) &visInfo.visualID);
  777. }
  778. }
  779. /* Clean up memory. */
  780. for (i = 0; i < count; i++) {
  781. free(pScrVisInfo[i].visinfo);
  782. }
  783. free(pScrVisInfo);
  784. if (pDrawables) {
  785. free(pDrawables);
  786. }
  787. return (client->noClientException);
  788. } /* ProcDbeGetVisualInfo() */
  789. /******************************************************************************
  790. *
  791. * DBE DIX Procedure: ProcDbeGetbackBufferAttributes
  792. *
  793. * Description:
  794. *
  795. * This function is for processing a ProcDbeGetbackBufferAttributes
  796. * request. This request returns information about a back buffer.
  797. *
  798. * Return Values:
  799. *
  800. * Success
  801. *
  802. *****************************************************************************/
  803. static int
  804. ProcDbeGetBackBufferAttributes(ClientPtr client)
  805. {
  806. REQUEST(xDbeGetBackBufferAttributesReq);
  807. xDbeGetBackBufferAttributesReply rep;
  808. DbeWindowPrivPtr pDbeWindowPriv;
  809. REQUEST_SIZE_MATCH(xDbeGetBackBufferAttributesReq);
  810. if (!(pDbeWindowPriv = (DbeWindowPrivPtr) SecurityLookupIDByType(client,
  811. stuff->
  812. buffer,
  813. dbeWindowPrivResType,
  814. SecurityReadAccess)))
  815. {
  816. rep.attributes = None;
  817. }
  818. else {
  819. rep.attributes = pDbeWindowPriv->pWindow->drawable.id;
  820. }
  821. rep.type = X_Reply;
  822. rep.sequenceNumber = client->sequence;
  823. rep.length = 0;
  824. if (client->swapped) {
  825. swaps(&rep.sequenceNumber);
  826. swapl(&rep.length);
  827. swapl(&rep.attributes);
  828. }
  829. WriteToClient(client, sizeof(xDbeGetBackBufferAttributesReply),
  830. (char *) &rep);
  831. return (client->noClientException);
  832. } /* ProcDbeGetbackBufferAttributes() */
  833. /******************************************************************************
  834. *
  835. * DBE DIX Procedure: ProcDbeDispatch
  836. *
  837. * Description:
  838. *
  839. * This function dispatches DBE requests.
  840. *
  841. *****************************************************************************/
  842. static int
  843. ProcDbeDispatch(ClientPtr client)
  844. {
  845. REQUEST(xReq);
  846. switch (stuff->data) {
  847. case X_DbeGetVersion:
  848. return (ProcDbeGetVersion(client));
  849. case X_DbeAllocateBackBufferName:
  850. return (ProcDbeAllocateBackBufferName(client));
  851. case X_DbeDeallocateBackBufferName:
  852. return (ProcDbeDeallocateBackBufferName(client));
  853. case X_DbeSwapBuffers:
  854. return (ProcDbeSwapBuffers(client));
  855. case X_DbeBeginIdiom:
  856. return Success;
  857. case X_DbeEndIdiom:
  858. return Success;
  859. case X_DbeGetVisualInfo:
  860. return (ProcDbeGetVisualInfo(client));
  861. case X_DbeGetBackBufferAttributes:
  862. return (ProcDbeGetBackBufferAttributes(client));
  863. default:
  864. return BadRequest;
  865. }
  866. } /* ProcDbeDispatch() */
  867. /******************************************************************************
  868. *
  869. * DBE DIX Procedure: SProcDbeGetVersion
  870. *
  871. * Description:
  872. *
  873. * This function is for processing a DbeGetVersion request on a swapped
  874. * server. This request returns the major and minor version numbers of
  875. * this extension.
  876. *
  877. * Return Values:
  878. *
  879. * Success
  880. *
  881. *****************************************************************************/
  882. static int
  883. SProcDbeGetVersion(ClientPtr client)
  884. {
  885. REQUEST(xDbeGetVersionReq);
  886. swaps(&stuff->length);
  887. return (ProcDbeGetVersion(client));
  888. } /* SProcDbeGetVersion() */
  889. /******************************************************************************
  890. *
  891. * DBE DIX Procedure: SProcDbeAllocateBackBufferName
  892. *
  893. * Description:
  894. *
  895. * This function is for processing a DbeAllocateBackBufferName request on
  896. * a swapped server. This request allocates a drawable ID used to refer
  897. * to the back buffer of a window.
  898. *
  899. * Return Values:
  900. *
  901. * BadAlloc - server can not allocate resources
  902. * BadIDChoice - id is out of range for client; id is already in use
  903. * BadMatch - window is not an InputOutput window;
  904. * visual of window is not on list returned by
  905. * DBEGetVisualInfo;
  906. * BadValue - invalid swap action is specified
  907. * BadWindow - window is not a valid window
  908. * Success
  909. *
  910. *****************************************************************************/
  911. static int
  912. SProcDbeAllocateBackBufferName(ClientPtr client)
  913. {
  914. REQUEST(xDbeAllocateBackBufferNameReq);
  915. swaps(&stuff->length);
  916. REQUEST_SIZE_MATCH(xDbeAllocateBackBufferNameReq);
  917. swapl(&stuff->window);
  918. swapl(&stuff->buffer);
  919. /* stuff->swapAction is a byte. We do not need to swap this field. */
  920. return (ProcDbeAllocateBackBufferName(client));
  921. } /* SProcDbeAllocateBackBufferName() */
  922. /******************************************************************************
  923. *
  924. * DBE DIX Procedure: SProcDbeDeallocateBackBufferName
  925. *
  926. * Description:
  927. *
  928. * This function is for processing a DbeDeallocateBackBufferName request
  929. * on a swapped server. This request frees a drawable ID that was
  930. * obtained by a DbeAllocateBackBufferName request.
  931. *
  932. * Return Values:
  933. *
  934. * BadBuffer - buffer to deallocate is not associated with a window
  935. * Success
  936. *
  937. *****************************************************************************/
  938. static int
  939. SProcDbeDeallocateBackBufferName(ClientPtr client)
  940. {
  941. REQUEST(xDbeDeallocateBackBufferNameReq);
  942. swaps(&stuff->length);
  943. REQUEST_SIZE_MATCH(xDbeDeallocateBackBufferNameReq);
  944. swapl(&stuff->buffer);
  945. return (ProcDbeDeallocateBackBufferName(client));
  946. } /* SProcDbeDeallocateBackBufferName() */
  947. /******************************************************************************
  948. *
  949. * DBE DIX Procedure: SProcDbeSwapBuffers
  950. *
  951. * Description:
  952. *
  953. * This function is for processing a DbeSwapBuffers request on a swapped
  954. * server. This request swaps the buffers for all windows listed,
  955. * applying the appropriate swap action for each window.
  956. *
  957. * Return Values:
  958. *
  959. * BadMatch - a window in request is not double-buffered; a window in
  960. * request is listed more than once; all windows in request do
  961. * not have the same root
  962. * BadValue - invalid swap action is specified
  963. * BadWindow - a window in request is not valid
  964. * Success
  965. *
  966. *****************************************************************************/
  967. static int
  968. SProcDbeSwapBuffers(ClientPtr client)
  969. {
  970. REQUEST(xDbeSwapBuffersReq);
  971. int i;
  972. xDbeSwapInfo *pSwapInfo;
  973. swaps(&stuff->length);
  974. REQUEST_AT_LEAST_SIZE(xDbeSwapBuffersReq);
  975. swapl(&stuff->n);
  976. if (stuff->n != 0) {
  977. pSwapInfo = (xDbeSwapInfo *) stuff + 1;
  978. /* The swap info following the fix part of this request is a window(32)
  979. * followed by a 1 byte swap action and then 3 pad bytes. We only need
  980. * to swap the window information.
  981. */
  982. for (i = 0; i < stuff->n; i++) {
  983. swapl(&pSwapInfo->window);
  984. }
  985. }
  986. return (ProcDbeSwapBuffers(client));
  987. } /* SProcDbeSwapBuffers() */
  988. /******************************************************************************
  989. *
  990. * DBE DIX Procedure: SProcDbeBeginIdiom
  991. *
  992. * Description:
  993. *
  994. * This function is for processing a DbeBeginIdiom request on a swapped
  995. * server. This request informs the server that a complex swap will
  996. * immediately follow this request.
  997. *
  998. * Return Values:
  999. *
  1000. * Success
  1001. *
  1002. *****************************************************************************/
  1003. static int
  1004. SProcDbeBeginIdiom(ClientPtr client)
  1005. {
  1006. REQUEST(xDbeBeginIdiomReq);
  1007. swaps(&stuff->length);
  1008. return (ProcDbeBeginIdiom(client));
  1009. } /* SProcDbeBeginIdiom() */
  1010. /******************************************************************************
  1011. *
  1012. * DBE DIX Procedure: SProcDbeGetVisualInfo
  1013. *
  1014. * Description:
  1015. *
  1016. * This function is for processing a ProcDbeGetVisualInfo request on a
  1017. * swapped server. This request returns information about which visuals
  1018. * support double buffering.
  1019. *
  1020. * Return Values:
  1021. *
  1022. * BadDrawable - value in screen specifiers is not a valid drawable
  1023. * Success
  1024. *
  1025. *****************************************************************************/
  1026. static int
  1027. SProcDbeGetVisualInfo(ClientPtr client)
  1028. {
  1029. REQUEST(xDbeGetVisualInfoReq);
  1030. swaps(&stuff->length);
  1031. REQUEST_AT_LEAST_SIZE(xDbeGetVisualInfoReq);
  1032. swapl(&stuff->n);
  1033. SwapRestL(stuff);
  1034. return (ProcDbeGetVisualInfo(client));
  1035. } /* SProcDbeGetVisualInfo() */
  1036. /******************************************************************************
  1037. *
  1038. * DBE DIX Procedure: SProcDbeGetbackBufferAttributes
  1039. *
  1040. * Description:
  1041. *
  1042. * This function is for processing a ProcDbeGetbackBufferAttributes
  1043. * request on a swapped server. This request returns information about a
  1044. * back buffer.
  1045. *
  1046. * Return Values:
  1047. *
  1048. * Success
  1049. *
  1050. *****************************************************************************/
  1051. static int
  1052. SProcDbeGetBackBufferAttributes(ClientPtr client)
  1053. {
  1054. REQUEST(xDbeGetBackBufferAttributesReq);
  1055. swaps(&stuff->length);
  1056. REQUEST_SIZE_MATCH(xDbeGetBackBufferAttributesReq);
  1057. swapl(&stuff->buffer);
  1058. return (ProcDbeGetBackBufferAttributes(client));
  1059. } /* SProcDbeGetBackBufferAttributes() */
  1060. /******************************************************************************
  1061. *
  1062. * DBE DIX Procedure: SProcDbeDispatch
  1063. *
  1064. * Description:
  1065. *
  1066. * This function dispatches DBE requests on a swapped server.
  1067. *
  1068. *****************************************************************************/
  1069. static int
  1070. SProcDbeDispatch(ClientPtr client)
  1071. {
  1072. REQUEST(xReq);
  1073. switch (stuff->data) {
  1074. case X_DbeGetVersion:
  1075. return (SProcDbeGetVersion(client));
  1076. case X_DbeAllocateBackBufferName:
  1077. return (SProcDbeAllocateBackBufferName(client));
  1078. case X_DbeDeallocateBackBufferName:
  1079. return (SProcDbeDeallocateBackBufferName(client));
  1080. case X_DbeSwapBuffers:
  1081. return (SProcDbeSwapBuffers(client));
  1082. case X_DbeBeginIdiom:
  1083. return (SProcDbeBeginIdiom(client));
  1084. case X_DbeEndIdiom:
  1085. return (Success);
  1086. case X_DbeGetVisualInfo:
  1087. return (SProcDbeGetVisualInfo(client));
  1088. case X_DbeGetBackBufferAttributes:
  1089. return (SProcDbeGetBackBufferAttributes(client));
  1090. default:
  1091. return (BadRequest);
  1092. }
  1093. } /* SProcDbeDispatch() */
  1094. /******************************************************************************
  1095. *
  1096. * DBE DIX Procedure: DbeSetupBackgroundPainter
  1097. *
  1098. * Description:
  1099. *
  1100. * This function sets up pGC to clear pixmaps.
  1101. *
  1102. * Return Values:
  1103. *
  1104. * TRUE - setup was successful
  1105. * FALSE - the window's background state is NONE
  1106. *
  1107. *****************************************************************************/
  1108. static Bool
  1109. DbeSetupBackgroundPainter(WindowPtr pWin, GCPtr pGC)
  1110. {
  1111. pointer gcvalues[4];
  1112. int ts_x_origin, ts_y_origin;
  1113. PixUnion background;
  1114. int backgroundState;
  1115. Mask gcmask;
  1116. /* First take care of any ParentRelative stuff by altering the
  1117. * tile/stipple origin to match the coordinates of the upper-left
  1118. * corner of the first ancestor without a ParentRelative background.
  1119. * This coordinate is, of course, negative.
  1120. */
  1121. ts_x_origin = ts_y_origin = 0;
  1122. while (pWin->backgroundState == ParentRelative) {
  1123. ts_x_origin -= pWin->origin.x;
  1124. ts_y_origin -= pWin->origin.y;
  1125. pWin = pWin->parent;
  1126. }
  1127. backgroundState = pWin->backgroundState;
  1128. background = pWin->background;
  1129. switch (backgroundState) {
  1130. case BackgroundPixel:
  1131. gcvalues[0] = (pointer) background.pixel;
  1132. gcvalues[1] = (pointer) FillSolid;
  1133. gcmask = GCForeground | GCFillStyle;
  1134. break;
  1135. case BackgroundPixmap:
  1136. gcvalues[0] = (pointer) FillTiled;
  1137. gcvalues[1] = (pointer) background.pixmap;
  1138. gcvalues[2] = (pointer) (long) ts_x_origin;
  1139. gcvalues[3] = (pointer) (long) ts_y_origin;
  1140. gcmask = GCFillStyle | GCTile | GCTileStipXOrigin | GCTileStipYOrigin;
  1141. break;
  1142. default:
  1143. /* pWin->backgroundState == None */
  1144. return (FALSE);
  1145. }
  1146. if (DoChangeGC(pGC, gcmask, (XID *) gcvalues, TRUE) != 0) {
  1147. return (FALSE);
  1148. }
  1149. return (TRUE);
  1150. } /* DbeSetupBackgroundPainter() */
  1151. /******************************************************************************
  1152. *
  1153. * DBE DIX Procedure: DbeDrawableDelete
  1154. *
  1155. * Description:
  1156. *
  1157. * This is the resource delete function for dbeDrawableResType.
  1158. * It is registered when the drawable resource type is created in
  1159. * DbeExtensionInit().
  1160. *
  1161. * To make resource deletion simple, we do not do anything in this function
  1162. * and leave all resource deleteion to DbeWindowPrivDelete(), which will
  1163. * eventually be called or already has been called. Deletion functions are
  1164. * not guaranteed to be called in any particular order.
  1165. *
  1166. *****************************************************************************/
  1167. static int
  1168. DbeDrawableDelete(pointer pDrawable, XID id)
  1169. {
  1170. return Success;
  1171. } /* DbeDrawableDelete() */
  1172. /******************************************************************************
  1173. *
  1174. * DBE DIX Procedure: DbeWindowPrivDelete
  1175. *
  1176. * Description:
  1177. *
  1178. * This is the resource delete function for dbeWindowPrivResType.
  1179. * It is registered when the drawable resource type is created in
  1180. * DbeExtensionInit().
  1181. *
  1182. *****************************************************************************/
  1183. static int
  1184. DbeWindowPrivDelete(pointer pDbeWinPriv, XID id)
  1185. {
  1186. DbeScreenPrivPtr pDbeScreenPriv;
  1187. DbeWindowPrivPtr pDbeWindowPriv = (DbeWindowPrivPtr) pDbeWinPriv;
  1188. int i;
  1189. /*
  1190. **************************************************************************
  1191. ** Remove the buffer ID from the ID array.
  1192. **************************************************************************
  1193. */
  1194. /* Find the ID in the ID array. */
  1195. i = 0;
  1196. while ((i < pDbeWindowPriv->nBufferIDs) && (pDbeWindowPriv->IDs[i] != id)) {
  1197. i++;
  1198. }
  1199. if (i == pDbeWindowPriv->nBufferIDs) {
  1200. /* We did not find the ID in the array. We should never get here. */
  1201. return BadValue;
  1202. }
  1203. /* Remove the ID from the array. */
  1204. if (i < (pDbeWindowPriv->nBufferIDs - 1)) {
  1205. /* Compress the buffer ID array, overwriting the ID in the process. */
  1206. memmove(&pDbeWindowPriv->IDs[i], &pDbeWindowPriv->IDs[i + 1],
  1207. (pDbeWindowPriv->nBufferIDs - i - 1) * sizeof(XID));
  1208. }
  1209. else {
  1210. /* We are removing the last ID in the array, in which case, the
  1211. * assignement below is all that we need to do.
  1212. */
  1213. }
  1214. pDbeWindowPriv->IDs[pDbeWindowPriv->nBufferIDs - 1] = DBE_FREE_ID_ELEMENT;
  1215. pDbeWindowPriv->nBufferIDs--;
  1216. /* If an extended array was allocated, then check to see if the remaining
  1217. * buffer IDs will fit in the static array.
  1218. */
  1219. if ((pDbeWindowPriv->maxAvailableIDs > DBE_INIT_MAX_IDS) &&
  1220. (pDbeWindowPriv->nBufferIDs == DBE_INIT_MAX_IDS)) {
  1221. /* Copy the IDs back into the static array. */
  1222. memcpy(pDbeWindowPriv->initIDs, pDbeWindowPriv->IDs,
  1223. DBE_INIT_MAX_IDS * sizeof(XID));
  1224. /* Free the extended array; use the static array. */
  1225. free(pDbeWindowPriv->IDs);
  1226. pDbeWindowPriv->IDs = pDbeWindowPriv->initIDs;
  1227. pDbeWindowPriv->maxAvailableIDs = DBE_INIT_MAX_IDS;
  1228. }
  1229. /*
  1230. **************************************************************************
  1231. ** Perform DDX level tasks.
  1232. **************************************************************************
  1233. */
  1234. pDbeScreenPriv = DBE_SCREEN_PRIV_FROM_WINDOW_PRIV((DbeWindowPrivPtr)
  1235. pDbeWindowPriv);
  1236. (*pDbeScreenPriv->WinPrivDelete) ((DbeWindowPrivPtr) pDbeWindowPriv, id);
  1237. /*
  1238. **************************************************************************
  1239. ** Perform miscellaneous tasks if this is the last buffer associated
  1240. ** with the window.
  1241. **************************************************************************
  1242. */
  1243. if (pDbeWindowPriv->nBufferIDs == 0) {
  1244. /* Reset the DBE window priv pointer. */
  1245. pDbeWindowPriv->pWindow->devPrivates[dbeWindowPrivIndex].ptr =
  1246. (pointer) NULL;
  1247. /* We are done with the window priv. */
  1248. free(pDbeWindowPriv);
  1249. }
  1250. return (Success);
  1251. } /* DbeWindowPrivDelete() */
  1252. /******************************************************************************
  1253. *
  1254. * DBE DIX Procedure: DbeResetProc
  1255. *
  1256. * Description:
  1257. *
  1258. * This routine is called at the end of every server generation.
  1259. * It deallocates any memory reserved for the extension and performs any
  1260. * other tasks related to shutting down the extension.
  1261. *
  1262. *****************************************************************************/
  1263. static void
  1264. DbeResetProc(ExtensionEntry * extEntry)
  1265. {
  1266. int i;
  1267. ScreenPtr pScreen;
  1268. DbeScreenPrivPtr pDbeScreenPriv;
  1269. if (dbeScreenPrivIndex < 0) {
  1270. return;
  1271. }
  1272. for (i = 0; i < screenInfo.numScreens; i++) {
  1273. pScreen = screenInfo.screens[i];
  1274. pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
  1275. if (pDbeScreenPriv) {
  1276. /* Unwrap DestroyWindow, which was wrapped in DbeExtensionInit(). */
  1277. pScreen->DestroyWindow = pDbeScreenPriv->DestroyWindow;
  1278. if (pDbeScreenPriv->ResetProc)
  1279. (*pDbeScreenPriv->ResetProc) (pScreen);
  1280. if (pDbeScreenPriv->winPrivPrivSizes) {
  1281. free(pDbeScreenPriv->winPrivPrivSizes);
  1282. }
  1283. free(pDbeScreenPriv);
  1284. }
  1285. }
  1286. /* We want to init the initialization function table after every server
  1287. * reset in DbeRegisterFunction().
  1288. */
  1289. firstRegistrationPass = TRUE;
  1290. } /* DbeResetProc() */
  1291. /******************************************************************************
  1292. *
  1293. * DBE DIX Procedure: DbeDestroyWindow
  1294. *
  1295. * Description:
  1296. *
  1297. * This is the wrapper for pScreen->DestroyWindow.
  1298. * This function frees buffer resources for a window before it is
  1299. * destroyed.
  1300. *
  1301. *****************************************************************************/
  1302. static Bool
  1303. DbeDestroyWindow(WindowPtr pWin)
  1304. {
  1305. DbeScreenPrivPtr pDbeScreenPriv;
  1306. DbeWindowPrivPtr pDbeWindowPriv;
  1307. ScreenPtr pScreen;
  1308. Bool ret;
  1309. /*
  1310. **************************************************************************
  1311. ** 1. Unwrap the member routine.
  1312. **************************************************************************
  1313. */
  1314. pScreen = pWin->drawable.pScreen;
  1315. pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
  1316. pScreen->DestroyWindow = pDbeScreenPriv->DestroyWindow;
  1317. /*
  1318. **************************************************************************
  1319. ** 2. Do any work necessary before the member routine is called.
  1320. **
  1321. ** Call the window priv delete function for all buffer IDs associated
  1322. ** with this window.
  1323. **************************************************************************
  1324. */
  1325. if ((pDbeWindowPriv = DBE_WINDOW_PRIV(pWin))) {
  1326. while (pDbeWindowPriv) {
  1327. /* *DbeWinPrivDelete() will free the window private and set it to
  1328. * NULL if there are no more buffer IDs associated with this
  1329. * window.
  1330. */
  1331. FreeResource(pDbeWindowPriv->IDs[0], RT_NONE);
  1332. pDbeWindowPriv = DBE_WINDOW_PRIV(pWin);
  1333. }
  1334. }
  1335. /*
  1336. **************************************************************************
  1337. ** 3. Call the member routine, saving its result if necessary.
  1338. **************************************************************************
  1339. */
  1340. ret = (*pScreen->DestroyWindow) (pWin);
  1341. /*
  1342. **************************************************************************
  1343. ** 4. Rewrap the member routine, restoring the wrapper value first in case
  1344. ** the wrapper (or something that it wrapped) change this value.
  1345. **************************************************************************
  1346. */
  1347. pDbeScreenPriv->DestroyWindow = pScreen->DestroyWindow;
  1348. pScreen->DestroyWindow = DbeDestroyWindow;
  1349. /*
  1350. **************************************************************************
  1351. ** 5. Do any work necessary after the member routine has been called.
  1352. **
  1353. ** In this case we do not need to do anything.
  1354. **************************************************************************
  1355. */
  1356. return ret;
  1357. } /* DbeDestroyWindow() */
  1358. /******************************************************************************
  1359. *
  1360. * DBE DIX Procedure: DbeExtensionInit
  1361. *
  1362. * Description:
  1363. *
  1364. * Called from InitExtensions in main()
  1365. *
  1366. *****************************************************************************/
  1367. void
  1368. DbeExtensionInit(void)
  1369. {
  1370. ExtensionEntry *extEntry;
  1371. int i, j;
  1372. ScreenPtr pScreen = NULL;
  1373. DbeScreenPrivPtr pDbeScreenPriv;
  1374. int nStubbedScreens = 0;
  1375. Bool ddxInitSuccess;
  1376. /* Allocate private pointers in windows and screens. */
  1377. if ((dbeScreenPrivIndex = AllocateScreenPrivateIndex()) < 0) {
  1378. return;
  1379. }
  1380. if ((dbeWindowPrivIndex = AllocateWindowPrivateIndex()) < 0) {
  1381. return;
  1382. }
  1383. /* Initialize the priv priv counts between server generations. */
  1384. winPrivPrivCount = 0;
  1385. /* Create the resource types. */
  1386. dbeDrawableResType =
  1387. CreateNewResourceType(DbeDrawableDelete) | RC_CACHED | RC_DRAWABLE;
  1388. dbeWindowPrivResType = CreateNewResourceType(DbeWindowPrivDelete);
  1389. for (i = 0; i < screenInfo.numScreens; i++) {
  1390. /* For each screen, set up DBE screen privates and init DIX and DDX
  1391. * interface.
  1392. */
  1393. pScreen = screenInfo.screens[i];
  1394. if (!AllocateWindowPrivate(pScreen, dbeWindowPrivIndex, 0) ||
  1395. !(pDbeScreenPriv =
  1396. calloc(sizeof(DbeScreenPrivRec), 1))) {
  1397. /* If we can not alloc a window or screen private,
  1398. * then free any privates that we already alloc'ed and return
  1399. */
  1400. for (j = 0; j < i; j++) {
  1401. free(screenInfo.screens[j]->devPrivates[dbeScreenPrivIndex].
  1402. ptr);
  1403. screenInfo.screens[j]->devPrivates[dbeScreenPrivIndex].ptr =
  1404. NULL;
  1405. }
  1406. return;
  1407. }
  1408. pScreen->devPrivates[dbeScreenPrivIndex].ptr = (pointer) pDbeScreenPriv;
  1409. /* Store the DBE priv priv size info for later use when allocating
  1410. * priv privs at the driver level.
  1411. */
  1412. pDbeScreenPriv->winPrivPrivLen = 0;
  1413. pDbeScreenPriv->winPrivPrivSizes = (unsigned *) NULL;
  1414. pDbeScreenPriv->totalWinPrivSize = sizeof(DbeWindowPrivRec);
  1415. /* Copy the resource types */
  1416. pDbeScreenPriv->dbeDrawableResType = dbeDrawableResType;
  1417. pDbeScreenPriv->dbeWindowPrivResType = dbeWindowPrivResType;
  1418. /* Copy the private indices */
  1419. pDbeScreenPriv->dbeScreenPrivIndex = dbeScreenPrivIndex;
  1420. pDbeScreenPriv->dbeWindowPrivIndex = dbeWindowPrivIndex;
  1421. if (DbeInitFunct[i]) {
  1422. /* This screen supports DBE. */
  1423. /* Setup DIX. */
  1424. pDbeScreenPriv->SetupBackgroundPainter = DbeSetupBackgroundPainter;
  1425. pDbeScreenPriv->AllocWinPriv = DbeAllocWinPriv;
  1426. pDbeScreenPriv->AllocWinPrivPrivIndex = DbeAllocWinPrivPrivIndex;
  1427. pDbeScreenPriv->AllocWinPrivPriv = DbeAllocWinPrivPriv;
  1428. /* Setup DDX. */
  1429. ddxInitSuccess = (*DbeInitFunct[i]) (pScreen, pDbeScreenPriv);
  1430. /* DDX DBE initialization may have the side affect of
  1431. * reallocating pDbeScreenPriv, so we need to update it.
  1432. */
  1433. pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
  1434. if (ddxInitSuccess) {
  1435. /* Wrap DestroyWindow. The DDX initialization function
  1436. * already wrapped PositionWindow for us.
  1437. */
  1438. pDbeScreenPriv->DestroyWindow = pScreen->DestroyWindow;
  1439. pScreen->DestroyWindow = DbeDestroyWindow;
  1440. }
  1441. else {
  1442. /* DDX initialization failed. Stub the screen. */
  1443. DbeStubScreen(pDbeScreenPriv, &nStubbedScreens);
  1444. }
  1445. }
  1446. else {
  1447. /* This screen does not support DBE. */
  1448. #ifndef DISABLE_MI_DBE_BY_DEFAULT
  1449. /* Setup DIX. */
  1450. pDbeScreenPriv->SetupBackgroundPainter = DbeSetupBackgroundPainter;
  1451. pDbeScreenPriv->AllocWinPriv = DbeAllocWinPriv;
  1452. pDbeScreenPriv->AllocWinPrivPrivIndex = DbeAllocWinPrivPrivIndex;
  1453. pDbeScreenPriv->AllocWinPrivPriv = DbeAllocWinPrivPriv;
  1454. /* Setup DDX. */
  1455. ddxInitSuccess = miDbeInit(pScreen, pDbeScreenPriv);
  1456. /* DDX DBE initialization may have the side affect of
  1457. * reallocating pDbeScreenPriv, so we need to update it.
  1458. */
  1459. pDbeScreenPriv = DBE_SCREEN_PRIV(pScreen);
  1460. if (ddxInitSuccess) {
  1461. /* Wrap DestroyWindow. The DDX initialization function
  1462. * already wrapped PositionWindow for us.
  1463. */
  1464. pDbeScreenPriv->DestroyWindow = pScreen->DestroyWindow;
  1465. pScreen->DestroyWindow = DbeDestroyWindow;
  1466. }
  1467. else {
  1468. /* DDX initialization failed. Stub the screen. */
  1469. DbeStubScreen(pDbeScreenPriv, &nStubbedScreens);
  1470. }
  1471. #else
  1472. DbeStubScreen(pDbeScreenPriv, &nStubbedScreens);
  1473. #endif
  1474. }
  1475. } /* for (i = 0; i < screenInfo.numScreens; i++) */
  1476. if (nStubbedScreens == screenInfo.numScreens) {
  1477. /* All screens stubbed. Clean up and return. */
  1478. for (i = 0; i < screenInfo.numScreens; i++) {
  1479. free(screenInfo.screens[i]->devPrivates[dbeScreenPrivIndex].ptr);
  1480. pScreen->devPrivates[dbeScreenPrivIndex].ptr = NULL;
  1481. }
  1482. return;
  1483. }
  1484. /* Now add the extension. */
  1485. extEntry = AddExtension(DBE_PROTOCOL_NAME, DbeNumberEvents,
  1486. DbeNumberErrors, ProcDbeDispatch, SProcDbeDispatch,
  1487. DbeResetProc, StandardMinorOpcode);
  1488. dbeErrorBase = extEntry->errorBase;
  1489. } /* DbeExtensionInit() */