PageRenderTime 63ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 1ms

/dix/dispatch.c

https://github.com/cubanismo/xserver
C | 3954 lines | 3129 code | 518 blank | 307 comment | 679 complexity | a5f6722dc3f3ce4f37c2982ae68d9e31 MD5 | raw file
Possible License(s): MIT

Large files files are truncated, but you can click here to view the full file

  1. /************************************************************
  2. Copyright 1987, 1989, 1998 The Open Group
  3. Permission to use, copy, modify, distribute, and sell this software and its
  4. documentation for any purpose is hereby granted without fee, provided that
  5. the above copyright notice appear in all copies and that both that
  6. copyright notice and this permission notice appear in supporting
  7. documentation.
  8. The above copyright notice and this permission notice shall be included in
  9. all copies or substantial portions of the Software.
  10. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  11. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  12. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  13. OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
  14. AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  15. CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  16. Except as contained in this notice, the name of The Open Group shall not be
  17. used in advertising or otherwise to promote the sale, use or other dealings
  18. in this Software without prior written authorization from The Open Group.
  19. Copyright 1987, 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
  20. All Rights Reserved
  21. Permission to use, copy, modify, and distribute this software and its
  22. documentation for any purpose and without fee is hereby granted,
  23. provided that the above copyright notice appear in all copies and that
  24. both that copyright notice and this permission notice appear in
  25. supporting documentation, and that the name of Digital not be
  26. used in advertising or publicity pertaining to distribution of the
  27. software without specific, written prior permission.
  28. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  29. ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  30. DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  31. ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  32. WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  33. ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  34. SOFTWARE.
  35. ********************************************************/
  36. /* The panoramix components contained the following notice */
  37. /*****************************************************************
  38. Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
  39. Permission is hereby granted, free of charge, to any person obtaining a copy
  40. of this software and associated documentation files (the "Software"), to deal
  41. in the Software without restriction, including without limitation the rights
  42. to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  43. copies of the Software.
  44. The above copyright notice and this permission notice shall be included in
  45. all copies or substantial portions of the Software.
  46. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  47. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  48. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  49. DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
  50. BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY,
  51. WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
  52. IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  53. Except as contained in this notice, the name of Digital Equipment Corporation
  54. shall not be used in advertising or otherwise to promote the sale, use or other
  55. dealings in this Software without prior written authorization from Digital
  56. Equipment Corporation.
  57. ******************************************************************/
  58. /* XSERVER_DTRACE additions:
  59. * Copyright (c) 2005-2006, Oracle and/or its affiliates. All rights reserved.
  60. *
  61. * Permission is hereby granted, free of charge, to any person obtaining a
  62. * copy of this software and associated documentation files (the "Software"),
  63. * to deal in the Software without restriction, including without limitation
  64. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  65. * and/or sell copies of the Software, and to permit persons to whom the
  66. * Software is furnished to do so, subject to the following conditions:
  67. *
  68. * The above copyright notice and this permission notice (including the next
  69. * paragraph) shall be included in all copies or substantial portions of the
  70. * Software.
  71. *
  72. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  73. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  74. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  75. * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  76. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  77. * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  78. * DEALINGS IN THE SOFTWARE.
  79. */
  80. #ifdef HAVE_DIX_CONFIG_H
  81. #include <dix-config.h>
  82. #include <version-config.h>
  83. #endif
  84. #ifdef PANORAMIX_DEBUG
  85. #include <stdio.h>
  86. int ProcInitialConnection();
  87. #endif
  88. #include "windowstr.h"
  89. #include <X11/fonts/fontstruct.h>
  90. #include "dixfontstr.h"
  91. #include "gcstruct.h"
  92. #include "selection.h"
  93. #include "colormapst.h"
  94. #include "cursorstr.h"
  95. #include "scrnintstr.h"
  96. #include "opaque.h"
  97. #include "input.h"
  98. #include "servermd.h"
  99. #include "extnsionst.h"
  100. #include "dixfont.h"
  101. #include "dispatch.h"
  102. #include "swaprep.h"
  103. #include "swapreq.h"
  104. #include "privates.h"
  105. #include "xace.h"
  106. #include "inputstr.h"
  107. #include "xkbsrv.h"
  108. #include "site.h"
  109. #include "client.h"
  110. #ifdef XSERVER_DTRACE
  111. #include "registry.h"
  112. #include <sys/types.h>
  113. typedef const char *string;
  114. #include "Xserver-dtrace.h"
  115. #endif
  116. #define mskcnt ((MAXCLIENTS + 31) / 32)
  117. #define BITMASK(i) (1U << ((i) & 31))
  118. #define MASKIDX(i) ((i) >> 5)
  119. #define MASKWORD(buf, i) buf[MASKIDX(i)]
  120. #define BITSET(buf, i) MASKWORD(buf, i) |= BITMASK(i)
  121. #define BITCLEAR(buf, i) MASKWORD(buf, i) &= ~BITMASK(i)
  122. #define GETBIT(buf, i) (MASKWORD(buf, i) & BITMASK(i))
  123. xConnSetupPrefix connSetupPrefix;
  124. PaddingInfo PixmapWidthPaddingInfo[33];
  125. static ClientPtr grabClient;
  126. #define GrabNone 0
  127. #define GrabActive 1
  128. #define GrabKickout 2
  129. static int grabState = GrabNone;
  130. static long grabWaiters[mskcnt];
  131. CallbackListPtr ServerGrabCallback = NULL;
  132. HWEventQueuePtr checkForInput[2];
  133. int connBlockScreenStart;
  134. static void KillAllClients(void);
  135. static int nextFreeClientID; /* always MIN free client ID */
  136. static int nClients; /* number of authorized clients */
  137. CallbackListPtr ClientStateCallback;
  138. /* dispatchException & isItTimeToYield must be declared volatile since they
  139. * are modified by signal handlers - otherwise optimizer may assume it doesn't
  140. * need to actually check value in memory when used and may miss changes from
  141. * signal handlers.
  142. */
  143. volatile char dispatchException = 0;
  144. volatile char isItTimeToYield;
  145. #define SAME_SCREENS(a, b) (\
  146. (a.pScreen == b.pScreen))
  147. void
  148. SetInputCheck(HWEventQueuePtr c0, HWEventQueuePtr c1)
  149. {
  150. checkForInput[0] = c0;
  151. checkForInput[1] = c1;
  152. }
  153. void
  154. UpdateCurrentTime(void)
  155. {
  156. TimeStamp systime;
  157. /* To avoid time running backwards, we must call GetTimeInMillis before
  158. * calling ProcessInputEvents.
  159. */
  160. systime.months = currentTime.months;
  161. systime.milliseconds = GetTimeInMillis();
  162. if (systime.milliseconds < currentTime.milliseconds)
  163. systime.months++;
  164. if (*checkForInput[0] != *checkForInput[1])
  165. ProcessInputEvents();
  166. if (CompareTimeStamps(systime, currentTime) == LATER)
  167. currentTime = systime;
  168. }
  169. /* Like UpdateCurrentTime, but can't call ProcessInputEvents */
  170. void
  171. UpdateCurrentTimeIf(void)
  172. {
  173. TimeStamp systime;
  174. systime.months = currentTime.months;
  175. systime.milliseconds = GetTimeInMillis();
  176. if (systime.milliseconds < currentTime.milliseconds)
  177. systime.months++;
  178. if (CompareTimeStamps(systime, currentTime) == LATER)
  179. currentTime = systime;
  180. }
  181. #undef SMART_DEBUG
  182. /* in milliseconds */
  183. #define SMART_SCHEDULE_DEFAULT_INTERVAL 5
  184. #define SMART_SCHEDULE_MAX_SLICE 15
  185. #if defined(WIN32) && !defined(__CYGWIN__)
  186. Bool SmartScheduleDisable = TRUE;
  187. #else
  188. Bool SmartScheduleDisable = FALSE;
  189. #endif
  190. long SmartScheduleSlice = SMART_SCHEDULE_DEFAULT_INTERVAL;
  191. long SmartScheduleInterval = SMART_SCHEDULE_DEFAULT_INTERVAL;
  192. long SmartScheduleMaxSlice = SMART_SCHEDULE_MAX_SLICE;
  193. long SmartScheduleTime;
  194. int SmartScheduleLatencyLimited = 0;
  195. static ClientPtr SmartLastClient;
  196. static int SmartLastIndex[SMART_MAX_PRIORITY - SMART_MIN_PRIORITY + 1];
  197. #ifdef SMART_DEBUG
  198. long SmartLastPrint;
  199. #endif
  200. void Dispatch(void);
  201. static int
  202. SmartScheduleClient(int *clientReady, int nready)
  203. {
  204. ClientPtr pClient;
  205. int i;
  206. int client;
  207. int bestPrio, best = 0;
  208. int bestRobin, robin;
  209. long now = SmartScheduleTime;
  210. long idle;
  211. bestPrio = -0x7fffffff;
  212. bestRobin = 0;
  213. idle = 2 * SmartScheduleSlice;
  214. for (i = 0; i < nready; i++) {
  215. client = clientReady[i];
  216. pClient = clients[client];
  217. /* Praise clients which haven't run in a while */
  218. if ((now - pClient->smart_stop_tick) >= idle) {
  219. if (pClient->smart_priority < 0)
  220. pClient->smart_priority++;
  221. }
  222. /* check priority to select best client */
  223. robin =
  224. (pClient->index -
  225. SmartLastIndex[pClient->smart_priority -
  226. SMART_MIN_PRIORITY]) & 0xff;
  227. if (pClient->smart_priority > bestPrio ||
  228. (pClient->smart_priority == bestPrio && robin > bestRobin)) {
  229. bestPrio = pClient->smart_priority;
  230. bestRobin = robin;
  231. best = client;
  232. }
  233. #ifdef SMART_DEBUG
  234. if ((now - SmartLastPrint) >= 5000)
  235. fprintf(stderr, " %2d: %3d", client, pClient->smart_priority);
  236. #endif
  237. }
  238. #ifdef SMART_DEBUG
  239. if ((now - SmartLastPrint) >= 5000) {
  240. fprintf(stderr, " use %2d\n", best);
  241. SmartLastPrint = now;
  242. }
  243. #endif
  244. pClient = clients[best];
  245. SmartLastIndex[bestPrio - SMART_MIN_PRIORITY] = pClient->index;
  246. /*
  247. * Set current client pointer
  248. */
  249. if (SmartLastClient != pClient) {
  250. pClient->smart_start_tick = now;
  251. SmartLastClient = pClient;
  252. }
  253. /*
  254. * Adjust slice
  255. */
  256. if (nready == 1 && SmartScheduleLatencyLimited == 0) {
  257. /*
  258. * If it's been a long time since another client
  259. * has run, bump the slice up to get maximal
  260. * performance from a single client
  261. */
  262. if ((now - pClient->smart_start_tick) > 1000 &&
  263. SmartScheduleSlice < SmartScheduleMaxSlice) {
  264. SmartScheduleSlice += SmartScheduleInterval;
  265. }
  266. }
  267. else {
  268. SmartScheduleSlice = SmartScheduleInterval;
  269. }
  270. return best;
  271. }
  272. void
  273. EnableLimitedSchedulingLatency(void)
  274. {
  275. ++SmartScheduleLatencyLimited;
  276. SmartScheduleSlice = SmartScheduleInterval;
  277. }
  278. void
  279. DisableLimitedSchedulingLatency(void)
  280. {
  281. --SmartScheduleLatencyLimited;
  282. /* protect against bugs */
  283. if (SmartScheduleLatencyLimited < 0)
  284. SmartScheduleLatencyLimited = 0;
  285. }
  286. void
  287. Dispatch(void)
  288. {
  289. int *clientReady; /* array of request ready clients */
  290. int result;
  291. ClientPtr client;
  292. int nready;
  293. HWEventQueuePtr *icheck = checkForInput;
  294. long start_tick;
  295. nextFreeClientID = 1;
  296. nClients = 0;
  297. clientReady = malloc(sizeof(int) * MaxClients);
  298. if (!clientReady)
  299. return;
  300. SmartScheduleSlice = SmartScheduleInterval;
  301. while (!dispatchException) {
  302. if (*icheck[0] != *icheck[1]) {
  303. ProcessInputEvents();
  304. FlushIfCriticalOutputPending();
  305. }
  306. nready = WaitForSomething(clientReady);
  307. if (nready && !SmartScheduleDisable) {
  308. clientReady[0] = SmartScheduleClient(clientReady, nready);
  309. nready = 1;
  310. }
  311. /*****************
  312. * Handle events in round robin fashion, doing input between
  313. * each round
  314. *****************/
  315. while (!dispatchException && (--nready >= 0)) {
  316. client = clients[clientReady[nready]];
  317. if (!client) {
  318. /* KillClient can cause this to happen */
  319. continue;
  320. }
  321. /* GrabServer activation can cause this to be true */
  322. if (grabState == GrabKickout) {
  323. grabState = GrabActive;
  324. break;
  325. }
  326. isItTimeToYield = FALSE;
  327. start_tick = SmartScheduleTime;
  328. while (!isItTimeToYield) {
  329. if (*icheck[0] != *icheck[1])
  330. ProcessInputEvents();
  331. FlushIfCriticalOutputPending();
  332. if (!SmartScheduleDisable &&
  333. (SmartScheduleTime - start_tick) >= SmartScheduleSlice) {
  334. /* Penalize clients which consume ticks */
  335. if (client->smart_priority > SMART_MIN_PRIORITY)
  336. client->smart_priority--;
  337. break;
  338. }
  339. /* now, finally, deal with client requests */
  340. /* Update currentTime so request time checks, such as for input
  341. * device grabs, are calculated correctly */
  342. UpdateCurrentTimeIf();
  343. result = ReadRequestFromClient(client);
  344. if (result <= 0) {
  345. if (result < 0)
  346. CloseDownClient(client);
  347. break;
  348. }
  349. client->sequence++;
  350. client->majorOp = ((xReq *) client->requestBuffer)->reqType;
  351. client->minorOp = 0;
  352. if (client->majorOp >= EXTENSION_BASE) {
  353. ExtensionEntry *ext = GetExtensionEntry(client->majorOp);
  354. if (ext)
  355. client->minorOp = ext->MinorOpcode(client);
  356. }
  357. #ifdef XSERVER_DTRACE
  358. if (XSERVER_REQUEST_START_ENABLED())
  359. XSERVER_REQUEST_START(LookupMajorName(client->majorOp),
  360. client->majorOp,
  361. ((xReq *) client->requestBuffer)->length,
  362. client->index,
  363. client->requestBuffer);
  364. #endif
  365. if (result > (maxBigRequestSize << 2))
  366. result = BadLength;
  367. else {
  368. result = XaceHookDispatch(client, client->majorOp);
  369. if (result == Success)
  370. result =
  371. (*client->requestVector[client->majorOp]) (client);
  372. XaceHookAuditEnd(client, result);
  373. }
  374. #ifdef XSERVER_DTRACE
  375. if (XSERVER_REQUEST_DONE_ENABLED())
  376. XSERVER_REQUEST_DONE(LookupMajorName(client->majorOp),
  377. client->majorOp, client->sequence,
  378. client->index, result);
  379. #endif
  380. if (client->noClientException != Success) {
  381. CloseDownClient(client);
  382. break;
  383. }
  384. else if (result != Success) {
  385. SendErrorToClient(client, client->majorOp,
  386. client->minorOp,
  387. client->errorValue, result);
  388. break;
  389. }
  390. }
  391. FlushAllOutput();
  392. client = clients[clientReady[nready]];
  393. if (client)
  394. client->smart_stop_tick = SmartScheduleTime;
  395. }
  396. dispatchException &= ~DE_PRIORITYCHANGE;
  397. }
  398. #if defined(DDXBEFORERESET)
  399. ddxBeforeReset();
  400. #endif
  401. KillAllClients();
  402. free(clientReady);
  403. dispatchException &= ~DE_RESET;
  404. SmartScheduleLatencyLimited = 0;
  405. ResetOsBuffers();
  406. }
  407. static int VendorRelease = VENDOR_RELEASE;
  408. static const char *VendorString = VENDOR_NAME;
  409. void
  410. SetVendorRelease(int release)
  411. {
  412. VendorRelease = release;
  413. }
  414. void
  415. SetVendorString(const char *vendor)
  416. {
  417. VendorString = vendor;
  418. }
  419. Bool
  420. CreateConnectionBlock(void)
  421. {
  422. xConnSetup setup;
  423. xWindowRoot root;
  424. xDepth depth;
  425. xVisualType visual;
  426. xPixmapFormat format;
  427. unsigned long vid;
  428. int i, j, k, lenofblock, sizesofar = 0;
  429. char *pBuf;
  430. memset(&setup, 0, sizeof(xConnSetup));
  431. /* Leave off the ridBase and ridMask, these must be sent with
  432. connection */
  433. setup.release = VendorRelease;
  434. /*
  435. * per-server image and bitmap parameters are defined in Xmd.h
  436. */
  437. setup.imageByteOrder = screenInfo.imageByteOrder;
  438. setup.bitmapScanlineUnit = screenInfo.bitmapScanlineUnit;
  439. setup.bitmapScanlinePad = screenInfo.bitmapScanlinePad;
  440. setup.bitmapBitOrder = screenInfo.bitmapBitOrder;
  441. setup.motionBufferSize = NumMotionEvents();
  442. setup.numRoots = screenInfo.numScreens;
  443. setup.nbytesVendor = strlen(VendorString);
  444. setup.numFormats = screenInfo.numPixmapFormats;
  445. setup.maxRequestSize = MAX_REQUEST_SIZE;
  446. QueryMinMaxKeyCodes(&setup.minKeyCode, &setup.maxKeyCode);
  447. lenofblock = sizeof(xConnSetup) +
  448. pad_to_int32(setup.nbytesVendor) +
  449. (setup.numFormats * sizeof(xPixmapFormat)) +
  450. (setup.numRoots * sizeof(xWindowRoot));
  451. ConnectionInfo = malloc(lenofblock);
  452. if (!ConnectionInfo)
  453. return FALSE;
  454. memmove(ConnectionInfo, (char *) &setup, sizeof(xConnSetup));
  455. sizesofar = sizeof(xConnSetup);
  456. pBuf = ConnectionInfo + sizeof(xConnSetup);
  457. memmove(pBuf, VendorString, (int) setup.nbytesVendor);
  458. sizesofar += setup.nbytesVendor;
  459. pBuf += setup.nbytesVendor;
  460. i = padding_for_int32(setup.nbytesVendor);
  461. sizesofar += i;
  462. while (--i >= 0)
  463. *pBuf++ = 0;
  464. memset(&format, 0, sizeof(xPixmapFormat));
  465. for (i = 0; i < screenInfo.numPixmapFormats; i++) {
  466. format.depth = screenInfo.formats[i].depth;
  467. format.bitsPerPixel = screenInfo.formats[i].bitsPerPixel;
  468. format.scanLinePad = screenInfo.formats[i].scanlinePad;
  469. memmove(pBuf, (char *) &format, sizeof(xPixmapFormat));
  470. pBuf += sizeof(xPixmapFormat);
  471. sizesofar += sizeof(xPixmapFormat);
  472. }
  473. connBlockScreenStart = sizesofar;
  474. memset(&depth, 0, sizeof(xDepth));
  475. memset(&visual, 0, sizeof(xVisualType));
  476. for (i = 0; i < screenInfo.numScreens; i++) {
  477. ScreenPtr pScreen;
  478. DepthPtr pDepth;
  479. VisualPtr pVisual;
  480. pScreen = screenInfo.screens[i];
  481. root.windowId = pScreen->root->drawable.id;
  482. root.defaultColormap = pScreen->defColormap;
  483. root.whitePixel = pScreen->whitePixel;
  484. root.blackPixel = pScreen->blackPixel;
  485. root.currentInputMask = 0; /* filled in when sent */
  486. root.pixWidth = pScreen->width;
  487. root.pixHeight = pScreen->height;
  488. root.mmWidth = pScreen->mmWidth;
  489. root.mmHeight = pScreen->mmHeight;
  490. root.minInstalledMaps = pScreen->minInstalledCmaps;
  491. root.maxInstalledMaps = pScreen->maxInstalledCmaps;
  492. root.rootVisualID = pScreen->rootVisual;
  493. root.backingStore = pScreen->backingStoreSupport;
  494. root.saveUnders = FALSE;
  495. root.rootDepth = pScreen->rootDepth;
  496. root.nDepths = pScreen->numDepths;
  497. memmove(pBuf, (char *) &root, sizeof(xWindowRoot));
  498. sizesofar += sizeof(xWindowRoot);
  499. pBuf += sizeof(xWindowRoot);
  500. pDepth = pScreen->allowedDepths;
  501. for (j = 0; j < pScreen->numDepths; j++, pDepth++) {
  502. lenofblock += sizeof(xDepth) +
  503. (pDepth->numVids * sizeof(xVisualType));
  504. pBuf = (char *) realloc(ConnectionInfo, lenofblock);
  505. if (!pBuf) {
  506. free(ConnectionInfo);
  507. return FALSE;
  508. }
  509. ConnectionInfo = pBuf;
  510. pBuf += sizesofar;
  511. depth.depth = pDepth->depth;
  512. depth.nVisuals = pDepth->numVids;
  513. memmove(pBuf, (char *) &depth, sizeof(xDepth));
  514. pBuf += sizeof(xDepth);
  515. sizesofar += sizeof(xDepth);
  516. for (k = 0; k < pDepth->numVids; k++) {
  517. vid = pDepth->vids[k];
  518. for (pVisual = pScreen->visuals;
  519. pVisual->vid != vid; pVisual++);
  520. visual.visualID = vid;
  521. visual.class = pVisual->class;
  522. visual.bitsPerRGB = pVisual->bitsPerRGBValue;
  523. visual.colormapEntries = pVisual->ColormapEntries;
  524. visual.redMask = pVisual->redMask;
  525. visual.greenMask = pVisual->greenMask;
  526. visual.blueMask = pVisual->blueMask;
  527. memmove(pBuf, (char *) &visual, sizeof(xVisualType));
  528. pBuf += sizeof(xVisualType);
  529. sizesofar += sizeof(xVisualType);
  530. }
  531. }
  532. }
  533. connSetupPrefix.success = xTrue;
  534. connSetupPrefix.length = lenofblock / 4;
  535. connSetupPrefix.majorVersion = X_PROTOCOL;
  536. connSetupPrefix.minorVersion = X_PROTOCOL_REVISION;
  537. return TRUE;
  538. }
  539. int
  540. ProcBadRequest(ClientPtr client)
  541. {
  542. return BadRequest;
  543. }
  544. int
  545. ProcCreateWindow(ClientPtr client)
  546. {
  547. WindowPtr pParent, pWin;
  548. REQUEST(xCreateWindowReq);
  549. int len, rc;
  550. REQUEST_AT_LEAST_SIZE(xCreateWindowReq);
  551. LEGAL_NEW_RESOURCE(stuff->wid, client);
  552. rc = dixLookupWindow(&pParent, stuff->parent, client, DixAddAccess);
  553. if (rc != Success)
  554. return rc;
  555. len = client->req_len - bytes_to_int32(sizeof(xCreateWindowReq));
  556. if (Ones(stuff->mask) != len)
  557. return BadLength;
  558. if (!stuff->width || !stuff->height) {
  559. client->errorValue = 0;
  560. return BadValue;
  561. }
  562. pWin = CreateWindow(stuff->wid, pParent, stuff->x,
  563. stuff->y, stuff->width, stuff->height,
  564. stuff->borderWidth, stuff->class,
  565. stuff->mask, (XID *) &stuff[1],
  566. (int) stuff->depth, client, stuff->visual, &rc);
  567. if (pWin) {
  568. Mask mask = pWin->eventMask;
  569. pWin->eventMask = 0; /* subterfuge in case AddResource fails */
  570. if (!AddResource(stuff->wid, RT_WINDOW, (void *) pWin))
  571. return BadAlloc;
  572. pWin->eventMask = mask;
  573. }
  574. return rc;
  575. }
  576. int
  577. ProcChangeWindowAttributes(ClientPtr client)
  578. {
  579. WindowPtr pWin;
  580. REQUEST(xChangeWindowAttributesReq);
  581. int len, rc;
  582. Mask access_mode = 0;
  583. REQUEST_AT_LEAST_SIZE(xChangeWindowAttributesReq);
  584. access_mode |= (stuff->valueMask & CWEventMask) ? DixReceiveAccess : 0;
  585. access_mode |= (stuff->valueMask & ~CWEventMask) ? DixSetAttrAccess : 0;
  586. rc = dixLookupWindow(&pWin, stuff->window, client, access_mode);
  587. if (rc != Success)
  588. return rc;
  589. len = client->req_len - bytes_to_int32(sizeof(xChangeWindowAttributesReq));
  590. if (len != Ones(stuff->valueMask))
  591. return BadLength;
  592. return ChangeWindowAttributes(pWin,
  593. stuff->valueMask, (XID *) &stuff[1], client);
  594. }
  595. int
  596. ProcGetWindowAttributes(ClientPtr client)
  597. {
  598. WindowPtr pWin;
  599. REQUEST(xResourceReq);
  600. xGetWindowAttributesReply wa;
  601. int rc;
  602. REQUEST_SIZE_MATCH(xResourceReq);
  603. rc = dixLookupWindow(&pWin, stuff->id, client, DixGetAttrAccess);
  604. if (rc != Success)
  605. return rc;
  606. memset(&wa, 0, sizeof(xGetWindowAttributesReply));
  607. GetWindowAttributes(pWin, client, &wa);
  608. WriteReplyToClient(client, sizeof(xGetWindowAttributesReply), &wa);
  609. return Success;
  610. }
  611. int
  612. ProcDestroyWindow(ClientPtr client)
  613. {
  614. WindowPtr pWin;
  615. REQUEST(xResourceReq);
  616. int rc;
  617. REQUEST_SIZE_MATCH(xResourceReq);
  618. rc = dixLookupWindow(&pWin, stuff->id, client, DixDestroyAccess);
  619. if (rc != Success)
  620. return rc;
  621. if (pWin->parent) {
  622. rc = dixLookupWindow(&pWin, pWin->parent->drawable.id, client,
  623. DixRemoveAccess);
  624. if (rc != Success)
  625. return rc;
  626. FreeResource(stuff->id, RT_NONE);
  627. }
  628. return Success;
  629. }
  630. int
  631. ProcDestroySubwindows(ClientPtr client)
  632. {
  633. WindowPtr pWin;
  634. REQUEST(xResourceReq);
  635. int rc;
  636. REQUEST_SIZE_MATCH(xResourceReq);
  637. rc = dixLookupWindow(&pWin, stuff->id, client, DixRemoveAccess);
  638. if (rc != Success)
  639. return rc;
  640. DestroySubwindows(pWin, client);
  641. return Success;
  642. }
  643. int
  644. ProcChangeSaveSet(ClientPtr client)
  645. {
  646. WindowPtr pWin;
  647. REQUEST(xChangeSaveSetReq);
  648. int rc;
  649. REQUEST_SIZE_MATCH(xChangeSaveSetReq);
  650. rc = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess);
  651. if (rc != Success)
  652. return rc;
  653. if (client->clientAsMask == (CLIENT_BITS(pWin->drawable.id)))
  654. return BadMatch;
  655. if ((stuff->mode == SetModeInsert) || (stuff->mode == SetModeDelete))
  656. return AlterSaveSetForClient(client, pWin, stuff->mode, FALSE, TRUE);
  657. client->errorValue = stuff->mode;
  658. return BadValue;
  659. }
  660. int
  661. ProcReparentWindow(ClientPtr client)
  662. {
  663. WindowPtr pWin, pParent;
  664. REQUEST(xReparentWindowReq);
  665. int rc;
  666. REQUEST_SIZE_MATCH(xReparentWindowReq);
  667. rc = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess);
  668. if (rc != Success)
  669. return rc;
  670. rc = dixLookupWindow(&pParent, stuff->parent, client, DixAddAccess);
  671. if (rc != Success)
  672. return rc;
  673. if (!SAME_SCREENS(pWin->drawable, pParent->drawable))
  674. return BadMatch;
  675. if ((pWin->backgroundState == ParentRelative) &&
  676. (pParent->drawable.depth != pWin->drawable.depth))
  677. return BadMatch;
  678. if ((pWin->drawable.class != InputOnly) &&
  679. (pParent->drawable.class == InputOnly))
  680. return BadMatch;
  681. return ReparentWindow(pWin, pParent,
  682. (short) stuff->x, (short) stuff->y, client);
  683. }
  684. int
  685. ProcMapWindow(ClientPtr client)
  686. {
  687. WindowPtr pWin;
  688. REQUEST(xResourceReq);
  689. int rc;
  690. REQUEST_SIZE_MATCH(xResourceReq);
  691. rc = dixLookupWindow(&pWin, stuff->id, client, DixShowAccess);
  692. if (rc != Success)
  693. return rc;
  694. MapWindow(pWin, client);
  695. /* update cache to say it is mapped */
  696. return Success;
  697. }
  698. int
  699. ProcMapSubwindows(ClientPtr client)
  700. {
  701. WindowPtr pWin;
  702. REQUEST(xResourceReq);
  703. int rc;
  704. REQUEST_SIZE_MATCH(xResourceReq);
  705. rc = dixLookupWindow(&pWin, stuff->id, client, DixListAccess);
  706. if (rc != Success)
  707. return rc;
  708. MapSubwindows(pWin, client);
  709. /* update cache to say it is mapped */
  710. return Success;
  711. }
  712. int
  713. ProcUnmapWindow(ClientPtr client)
  714. {
  715. WindowPtr pWin;
  716. REQUEST(xResourceReq);
  717. int rc;
  718. REQUEST_SIZE_MATCH(xResourceReq);
  719. rc = dixLookupWindow(&pWin, stuff->id, client, DixHideAccess);
  720. if (rc != Success)
  721. return rc;
  722. UnmapWindow(pWin, FALSE);
  723. /* update cache to say it is mapped */
  724. return Success;
  725. }
  726. int
  727. ProcUnmapSubwindows(ClientPtr client)
  728. {
  729. WindowPtr pWin;
  730. REQUEST(xResourceReq);
  731. int rc;
  732. REQUEST_SIZE_MATCH(xResourceReq);
  733. rc = dixLookupWindow(&pWin, stuff->id, client, DixListAccess);
  734. if (rc != Success)
  735. return rc;
  736. UnmapSubwindows(pWin);
  737. return Success;
  738. }
  739. int
  740. ProcConfigureWindow(ClientPtr client)
  741. {
  742. WindowPtr pWin;
  743. REQUEST(xConfigureWindowReq);
  744. int len, rc;
  745. REQUEST_AT_LEAST_SIZE(xConfigureWindowReq);
  746. rc = dixLookupWindow(&pWin, stuff->window, client,
  747. DixManageAccess | DixSetAttrAccess);
  748. if (rc != Success)
  749. return rc;
  750. len = client->req_len - bytes_to_int32(sizeof(xConfigureWindowReq));
  751. if (Ones((Mask) stuff->mask) != len)
  752. return BadLength;
  753. return ConfigureWindow(pWin, (Mask) stuff->mask, (XID *) &stuff[1], client);
  754. }
  755. int
  756. ProcCirculateWindow(ClientPtr client)
  757. {
  758. WindowPtr pWin;
  759. REQUEST(xCirculateWindowReq);
  760. int rc;
  761. REQUEST_SIZE_MATCH(xCirculateWindowReq);
  762. if ((stuff->direction != RaiseLowest) && (stuff->direction != LowerHighest)) {
  763. client->errorValue = stuff->direction;
  764. return BadValue;
  765. }
  766. rc = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess);
  767. if (rc != Success)
  768. return rc;
  769. CirculateWindow(pWin, (int) stuff->direction, client);
  770. return Success;
  771. }
  772. static int
  773. GetGeometry(ClientPtr client, xGetGeometryReply * rep)
  774. {
  775. DrawablePtr pDraw;
  776. int rc;
  777. REQUEST(xResourceReq);
  778. REQUEST_SIZE_MATCH(xResourceReq);
  779. rc = dixLookupDrawable(&pDraw, stuff->id, client, M_ANY, DixGetAttrAccess);
  780. if (rc != Success)
  781. return rc;
  782. rep->type = X_Reply;
  783. rep->length = 0;
  784. rep->sequenceNumber = client->sequence;
  785. rep->root = pDraw->pScreen->root->drawable.id;
  786. rep->depth = pDraw->depth;
  787. rep->width = pDraw->width;
  788. rep->height = pDraw->height;
  789. if (WindowDrawable(pDraw->type)) {
  790. WindowPtr pWin = (WindowPtr) pDraw;
  791. rep->x = pWin->origin.x - wBorderWidth(pWin);
  792. rep->y = pWin->origin.y - wBorderWidth(pWin);
  793. rep->borderWidth = pWin->borderWidth;
  794. }
  795. else { /* DRAWABLE_PIXMAP */
  796. rep->x = rep->y = rep->borderWidth = 0;
  797. }
  798. return Success;
  799. }
  800. int
  801. ProcGetGeometry(ClientPtr client)
  802. {
  803. xGetGeometryReply rep = { .type = X_Reply };
  804. int status;
  805. if ((status = GetGeometry(client, &rep)) != Success)
  806. return status;
  807. WriteReplyToClient(client, sizeof(xGetGeometryReply), &rep);
  808. return Success;
  809. }
  810. int
  811. ProcQueryTree(ClientPtr client)
  812. {
  813. xQueryTreeReply reply;
  814. int rc, numChildren = 0;
  815. WindowPtr pChild, pWin, pHead;
  816. Window *childIDs = (Window *) NULL;
  817. REQUEST(xResourceReq);
  818. REQUEST_SIZE_MATCH(xResourceReq);
  819. rc = dixLookupWindow(&pWin, stuff->id, client, DixListAccess);
  820. if (rc != Success)
  821. return rc;
  822. reply = (xQueryTreeReply) {
  823. .type = X_Reply,
  824. .sequenceNumber = client->sequence,
  825. .root = pWin->drawable.pScreen->root->drawable.id,
  826. .parent = (pWin->parent) ? pWin->parent->drawable.id : (Window) None
  827. };
  828. pHead = RealChildHead(pWin);
  829. for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
  830. numChildren++;
  831. if (numChildren) {
  832. int curChild = 0;
  833. childIDs = malloc(numChildren * sizeof(Window));
  834. if (!childIDs)
  835. return BadAlloc;
  836. for (pChild = pWin->lastChild; pChild != pHead;
  837. pChild = pChild->prevSib)
  838. childIDs[curChild++] = pChild->drawable.id;
  839. }
  840. reply.nChildren = numChildren;
  841. reply.length = bytes_to_int32(numChildren * sizeof(Window));
  842. WriteReplyToClient(client, sizeof(xQueryTreeReply), &reply);
  843. if (numChildren) {
  844. client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
  845. WriteSwappedDataToClient(client, numChildren * sizeof(Window),
  846. childIDs);
  847. free(childIDs);
  848. }
  849. return Success;
  850. }
  851. int
  852. ProcInternAtom(ClientPtr client)
  853. {
  854. Atom atom;
  855. char *tchar;
  856. REQUEST(xInternAtomReq);
  857. REQUEST_FIXED_SIZE(xInternAtomReq, stuff->nbytes);
  858. if ((stuff->onlyIfExists != xTrue) && (stuff->onlyIfExists != xFalse)) {
  859. client->errorValue = stuff->onlyIfExists;
  860. return BadValue;
  861. }
  862. tchar = (char *) &stuff[1];
  863. atom = MakeAtom(tchar, stuff->nbytes, !stuff->onlyIfExists);
  864. if (atom != BAD_RESOURCE) {
  865. xInternAtomReply reply = {
  866. .type = X_Reply,
  867. .sequenceNumber = client->sequence,
  868. .length = 0,
  869. .atom = atom
  870. };
  871. WriteReplyToClient(client, sizeof(xInternAtomReply), &reply);
  872. return Success;
  873. }
  874. else
  875. return BadAlloc;
  876. }
  877. int
  878. ProcGetAtomName(ClientPtr client)
  879. {
  880. const char *str;
  881. REQUEST(xResourceReq);
  882. REQUEST_SIZE_MATCH(xResourceReq);
  883. if ((str = NameForAtom(stuff->id))) {
  884. int len = strlen(str);
  885. xGetAtomNameReply reply = {
  886. .type = X_Reply,
  887. .sequenceNumber = client->sequence,
  888. .length = bytes_to_int32(len),
  889. .nameLength = len
  890. };
  891. WriteReplyToClient(client, sizeof(xGetAtomNameReply), &reply);
  892. WriteToClient(client, len, str);
  893. return Success;
  894. }
  895. else {
  896. client->errorValue = stuff->id;
  897. return BadAtom;
  898. }
  899. }
  900. int
  901. ProcGrabServer(ClientPtr client)
  902. {
  903. int rc;
  904. REQUEST_SIZE_MATCH(xReq);
  905. if (grabState != GrabNone && client != grabClient) {
  906. ResetCurrentRequest(client);
  907. client->sequence--;
  908. BITSET(grabWaiters, client->index);
  909. IgnoreClient(client);
  910. return Success;
  911. }
  912. rc = OnlyListenToOneClient(client);
  913. if (rc != Success)
  914. return rc;
  915. grabState = GrabKickout;
  916. grabClient = client;
  917. if (ServerGrabCallback) {
  918. ServerGrabInfoRec grabinfo;
  919. grabinfo.client = client;
  920. grabinfo.grabstate = SERVER_GRABBED;
  921. CallCallbacks(&ServerGrabCallback, (void *) &grabinfo);
  922. }
  923. return Success;
  924. }
  925. static void
  926. UngrabServer(ClientPtr client)
  927. {
  928. int i;
  929. grabState = GrabNone;
  930. ListenToAllClients();
  931. for (i = mskcnt; --i >= 0 && !grabWaiters[i];);
  932. if (i >= 0) {
  933. i <<= 5;
  934. while (!GETBIT(grabWaiters, i))
  935. i++;
  936. BITCLEAR(grabWaiters, i);
  937. AttendClient(clients[i]);
  938. }
  939. if (ServerGrabCallback) {
  940. ServerGrabInfoRec grabinfo;
  941. grabinfo.client = client;
  942. grabinfo.grabstate = SERVER_UNGRABBED;
  943. CallCallbacks(&ServerGrabCallback, (void *) &grabinfo);
  944. }
  945. }
  946. int
  947. ProcUngrabServer(ClientPtr client)
  948. {
  949. REQUEST_SIZE_MATCH(xReq);
  950. UngrabServer(client);
  951. return Success;
  952. }
  953. int
  954. ProcTranslateCoords(ClientPtr client)
  955. {
  956. REQUEST(xTranslateCoordsReq);
  957. WindowPtr pWin, pDst;
  958. xTranslateCoordsReply rep;
  959. int rc;
  960. REQUEST_SIZE_MATCH(xTranslateCoordsReq);
  961. rc = dixLookupWindow(&pWin, stuff->srcWid, client, DixGetAttrAccess);
  962. if (rc != Success)
  963. return rc;
  964. rc = dixLookupWindow(&pDst, stuff->dstWid, client, DixGetAttrAccess);
  965. if (rc != Success)
  966. return rc;
  967. rep = (xTranslateCoordsReply) {
  968. .type = X_Reply,
  969. .sequenceNumber = client->sequence,
  970. .length = 0
  971. };
  972. if (!SAME_SCREENS(pWin->drawable, pDst->drawable)) {
  973. rep.sameScreen = xFalse;
  974. rep.child = None;
  975. rep.dstX = rep.dstY = 0;
  976. }
  977. else {
  978. INT16 x, y;
  979. rep.sameScreen = xTrue;
  980. rep.child = None;
  981. /* computing absolute coordinates -- adjust to destination later */
  982. x = pWin->drawable.x + stuff->srcX;
  983. y = pWin->drawable.y + stuff->srcY;
  984. pWin = pDst->firstChild;
  985. while (pWin) {
  986. BoxRec box;
  987. if ((pWin->mapped) &&
  988. (x >= pWin->drawable.x - wBorderWidth(pWin)) &&
  989. (x < pWin->drawable.x + (int) pWin->drawable.width +
  990. wBorderWidth(pWin)) &&
  991. (y >= pWin->drawable.y - wBorderWidth(pWin)) &&
  992. (y < pWin->drawable.y + (int) pWin->drawable.height +
  993. wBorderWidth(pWin))
  994. /* When a window is shaped, a further check
  995. * is made to see if the point is inside
  996. * borderSize
  997. */
  998. && (!wBoundingShape(pWin) ||
  999. RegionContainsPoint(&pWin->borderSize, x, y, &box))
  1000. && (!wInputShape(pWin) ||
  1001. RegionContainsPoint(wInputShape(pWin),
  1002. x - pWin->drawable.x,
  1003. y - pWin->drawable.y, &box))
  1004. ) {
  1005. rep.child = pWin->drawable.id;
  1006. pWin = (WindowPtr) NULL;
  1007. }
  1008. else
  1009. pWin = pWin->nextSib;
  1010. }
  1011. /* adjust to destination coordinates */
  1012. rep.dstX = x - pDst->drawable.x;
  1013. rep.dstY = y - pDst->drawable.y;
  1014. }
  1015. WriteReplyToClient(client, sizeof(xTranslateCoordsReply), &rep);
  1016. return Success;
  1017. }
  1018. int
  1019. ProcOpenFont(ClientPtr client)
  1020. {
  1021. int err;
  1022. REQUEST(xOpenFontReq);
  1023. REQUEST_FIXED_SIZE(xOpenFontReq, stuff->nbytes);
  1024. client->errorValue = stuff->fid;
  1025. LEGAL_NEW_RESOURCE(stuff->fid, client);
  1026. err = OpenFont(client, stuff->fid, (Mask) 0,
  1027. stuff->nbytes, (char *) &stuff[1]);
  1028. if (err == Success) {
  1029. return Success;
  1030. }
  1031. else
  1032. return err;
  1033. }
  1034. int
  1035. ProcCloseFont(ClientPtr client)
  1036. {
  1037. FontPtr pFont;
  1038. int rc;
  1039. REQUEST(xResourceReq);
  1040. REQUEST_SIZE_MATCH(xResourceReq);
  1041. rc = dixLookupResourceByType((void **) &pFont, stuff->id, RT_FONT,
  1042. client, DixDestroyAccess);
  1043. if (rc == Success) {
  1044. FreeResource(stuff->id, RT_NONE);
  1045. return Success;
  1046. }
  1047. else {
  1048. client->errorValue = stuff->id;
  1049. return rc;
  1050. }
  1051. }
  1052. int
  1053. ProcQueryFont(ClientPtr client)
  1054. {
  1055. xQueryFontReply *reply;
  1056. FontPtr pFont;
  1057. int rc;
  1058. REQUEST(xResourceReq);
  1059. REQUEST_SIZE_MATCH(xResourceReq);
  1060. rc = dixLookupFontable(&pFont, stuff->id, client, DixGetAttrAccess);
  1061. if (rc != Success)
  1062. return rc;
  1063. {
  1064. xCharInfo *pmax = FONTINKMAX(pFont);
  1065. xCharInfo *pmin = FONTINKMIN(pFont);
  1066. int nprotoxcistructs;
  1067. int rlength;
  1068. nprotoxcistructs = (pmax->rightSideBearing == pmin->rightSideBearing &&
  1069. pmax->leftSideBearing == pmin->leftSideBearing &&
  1070. pmax->descent == pmin->descent &&
  1071. pmax->ascent == pmin->ascent &&
  1072. pmax->characterWidth == pmin->characterWidth) ?
  1073. 0 : N2dChars(pFont);
  1074. rlength = sizeof(xQueryFontReply) +
  1075. FONTINFONPROPS(FONTCHARSET(pFont)) * sizeof(xFontProp) +
  1076. nprotoxcistructs * sizeof(xCharInfo);
  1077. reply = calloc(1, rlength);
  1078. if (!reply) {
  1079. return BadAlloc;
  1080. }
  1081. reply->type = X_Reply;
  1082. reply->length = bytes_to_int32(rlength - sizeof(xGenericReply));
  1083. reply->sequenceNumber = client->sequence;
  1084. QueryFont(pFont, reply, nprotoxcistructs);
  1085. WriteReplyToClient(client, rlength, reply);
  1086. free(reply);
  1087. return Success;
  1088. }
  1089. }
  1090. int
  1091. ProcQueryTextExtents(ClientPtr client)
  1092. {
  1093. xQueryTextExtentsReply reply;
  1094. FontPtr pFont;
  1095. ExtentInfoRec info;
  1096. unsigned long length;
  1097. int rc;
  1098. REQUEST(xQueryTextExtentsReq);
  1099. REQUEST_AT_LEAST_SIZE(xQueryTextExtentsReq);
  1100. rc = dixLookupFontable(&pFont, stuff->fid, client, DixGetAttrAccess);
  1101. if (rc != Success)
  1102. return rc;
  1103. length = client->req_len - bytes_to_int32(sizeof(xQueryTextExtentsReq));
  1104. length = length << 1;
  1105. if (stuff->oddLength) {
  1106. if (length == 0)
  1107. return BadLength;
  1108. length--;
  1109. }
  1110. if (!QueryTextExtents(pFont, length, (unsigned char *) &stuff[1], &info))
  1111. return BadAlloc;
  1112. reply = (xQueryTextExtentsReply) {
  1113. .type = X_Reply,
  1114. .drawDirection = info.drawDirection,
  1115. .sequenceNumber = client->sequence,
  1116. .length = 0,
  1117. .fontAscent = info.fontAscent,
  1118. .fontDescent = info.fontDescent,
  1119. .overallAscent = info.overallAscent,
  1120. .overallDescent = info.overallDescent,
  1121. .overallWidth = info.overallWidth,
  1122. .overallLeft = info.overallLeft,
  1123. .overallRight = info.overallRight
  1124. };
  1125. WriteReplyToClient(client, sizeof(xQueryTextExtentsReply), &reply);
  1126. return Success;
  1127. }
  1128. int
  1129. ProcListFonts(ClientPtr client)
  1130. {
  1131. REQUEST(xListFontsReq);
  1132. REQUEST_FIXED_SIZE(xListFontsReq, stuff->nbytes);
  1133. return ListFonts(client, (unsigned char *) &stuff[1], stuff->nbytes,
  1134. stuff->maxNames);
  1135. }
  1136. int
  1137. ProcListFontsWithInfo(ClientPtr client)
  1138. {
  1139. REQUEST(xListFontsWithInfoReq);
  1140. REQUEST_FIXED_SIZE(xListFontsWithInfoReq, stuff->nbytes);
  1141. return StartListFontsWithInfo(client, stuff->nbytes,
  1142. (unsigned char *) &stuff[1], stuff->maxNames);
  1143. }
  1144. /**
  1145. *
  1146. * \param value must conform to DeleteType
  1147. */
  1148. int
  1149. dixDestroyPixmap(void *value, XID pid)
  1150. {
  1151. PixmapPtr pPixmap = (PixmapPtr) value;
  1152. return (*pPixmap->drawable.pScreen->DestroyPixmap) (pPixmap);
  1153. }
  1154. int
  1155. ProcCreatePixmap(ClientPtr client)
  1156. {
  1157. PixmapPtr pMap;
  1158. DrawablePtr pDraw;
  1159. REQUEST(xCreatePixmapReq);
  1160. DepthPtr pDepth;
  1161. int i, rc;
  1162. REQUEST_SIZE_MATCH(xCreatePixmapReq);
  1163. client->errorValue = stuff->pid;
  1164. LEGAL_NEW_RESOURCE(stuff->pid, client);
  1165. rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY,
  1166. DixGetAttrAccess);
  1167. if (rc != Success)
  1168. return rc;
  1169. if (!stuff->width || !stuff->height) {
  1170. client->errorValue = 0;
  1171. return BadValue;
  1172. }
  1173. if (stuff->width > 32767 || stuff->height > 32767) {
  1174. /* It is allowed to try and allocate a pixmap which is larger than
  1175. * 32767 in either dimension. However, all of the framebuffer code
  1176. * is buggy and does not reliably draw to such big pixmaps, basically
  1177. * because the Region data structure operates with signed shorts
  1178. * for the rectangles in it.
  1179. *
  1180. * Furthermore, several places in the X server computes the
  1181. * size in bytes of the pixmap and tries to store it in an
  1182. * integer. This integer can overflow and cause the allocated size
  1183. * to be much smaller.
  1184. *
  1185. * So, such big pixmaps are rejected here with a BadAlloc
  1186. */
  1187. return BadAlloc;
  1188. }
  1189. if (stuff->depth != 1) {
  1190. pDepth = pDraw->pScreen->allowedDepths;
  1191. for (i = 0; i < pDraw->pScreen->numDepths; i++, pDepth++)
  1192. if (pDepth->depth == stuff->depth)
  1193. goto CreatePmap;
  1194. client->errorValue = stuff->depth;
  1195. return BadValue;
  1196. }
  1197. CreatePmap:
  1198. pMap = (PixmapPtr) (*pDraw->pScreen->CreatePixmap)
  1199. (pDraw->pScreen, stuff->width, stuff->height, stuff->depth, 0);
  1200. if (pMap) {
  1201. pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
  1202. pMap->drawable.id = stuff->pid;
  1203. /* security creation/labeling check */
  1204. rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, RT_PIXMAP,
  1205. pMap, RT_NONE, NULL, DixCreateAccess);
  1206. if (rc != Success) {
  1207. (*pDraw->pScreen->DestroyPixmap) (pMap);
  1208. return rc;
  1209. }
  1210. if (AddResource(stuff->pid, RT_PIXMAP, (void *) pMap))
  1211. return Success;
  1212. }
  1213. return BadAlloc;
  1214. }
  1215. int
  1216. ProcFreePixmap(ClientPtr client)
  1217. {
  1218. PixmapPtr pMap;
  1219. int rc;
  1220. REQUEST(xResourceReq);
  1221. REQUEST_SIZE_MATCH(xResourceReq);
  1222. rc = dixLookupResourceByType((void **) &pMap, stuff->id, RT_PIXMAP,
  1223. client, DixDestroyAccess);
  1224. if (rc == Success) {
  1225. FreeResource(stuff->id, RT_NONE);
  1226. return Success;
  1227. }
  1228. else {
  1229. client->errorValue = stuff->id;
  1230. return rc;
  1231. }
  1232. }
  1233. int
  1234. ProcCreateGC(ClientPtr client)
  1235. {
  1236. int error, rc;
  1237. GC *pGC;
  1238. DrawablePtr pDraw;
  1239. unsigned len;
  1240. REQUEST(xCreateGCReq);
  1241. REQUEST_AT_LEAST_SIZE(xCreateGCReq);
  1242. client->errorValue = stuff->gc;
  1243. LEGAL_NEW_RESOURCE(stuff->gc, client);
  1244. rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0,
  1245. DixGetAttrAccess);
  1246. if (rc != Success)
  1247. return rc;
  1248. len = client->req_len - bytes_to_int32(sizeof(xCreateGCReq));
  1249. if (len != Ones(stuff->mask))
  1250. return BadLength;
  1251. pGC = (GC *) CreateGC(pDraw, stuff->mask, (XID *) &stuff[1], &error,
  1252. stuff->gc, client);
  1253. if (error != Success)
  1254. return error;
  1255. if (!AddResource(stuff->gc, RT_GC, (void *) pGC))
  1256. return BadAlloc;
  1257. return Success;
  1258. }
  1259. int
  1260. ProcChangeGC(ClientPtr client)
  1261. {
  1262. GC *pGC;
  1263. int result;
  1264. unsigned len;
  1265. REQUEST(xChangeGCReq);
  1266. REQUEST_AT_LEAST_SIZE(xChangeGCReq);
  1267. result = dixLookupGC(&pGC, stuff->gc, client, DixSetAttrAccess);
  1268. if (result != Success)
  1269. return result;
  1270. len = client->req_len - bytes_to_int32(sizeof(xChangeGCReq));
  1271. if (len != Ones(stuff->mask))
  1272. return BadLength;
  1273. return ChangeGCXIDs(client, pGC, stuff->mask, (CARD32 *) &stuff[1]);
  1274. }
  1275. int
  1276. ProcCopyGC(ClientPtr client)
  1277. {
  1278. GC *dstGC;
  1279. GC *pGC;
  1280. int result;
  1281. REQUEST(xCopyGCReq);
  1282. REQUEST_SIZE_MATCH(xCopyGCReq);
  1283. result = dixLookupGC(&pGC, stuff->srcGC, client, DixGetAttrAccess);
  1284. if (result != Success)
  1285. return result;
  1286. result = dixLookupGC(&dstGC, stuff->dstGC, client, DixSetAttrAccess);
  1287. if (result != Success)
  1288. return result;
  1289. if ((dstGC->pScreen != pGC->pScreen) || (dstGC->depth != pGC->depth))
  1290. return BadMatch;
  1291. if (stuff->mask & ~GCAllBits) {
  1292. client->errorValue = stuff->mask;
  1293. return BadValue;
  1294. }
  1295. return CopyGC(pGC, dstGC, stuff->mask);
  1296. }
  1297. int
  1298. ProcSetDashes(ClientPtr client)
  1299. {
  1300. GC *pGC;
  1301. int result;
  1302. REQUEST(xSetDashesReq);
  1303. REQUEST_FIXED_SIZE(xSetDashesReq, stuff->nDashes);
  1304. if (stuff->nDashes == 0) {
  1305. client->errorValue = 0;
  1306. return BadValue;
  1307. }
  1308. result = dixLookupGC(&pGC, stuff->gc, client, DixSetAttrAccess);
  1309. if (result != Success)
  1310. return result;
  1311. /* If there's an error, either there's no sensible errorValue,
  1312. * or there was a dash segment of 0. */
  1313. client->errorValue = 0;
  1314. return SetDashes(pGC, stuff->dashOffset, stuff->nDashes,
  1315. (unsigned char *) &stuff[1]);
  1316. }
  1317. int
  1318. ProcSetClipRectangles(ClientPtr client)
  1319. {
  1320. int nr, result;
  1321. GC *pGC;
  1322. REQUEST(xSetClipRectanglesReq);
  1323. REQUEST_AT_LEAST_SIZE(xSetClipRectanglesReq);
  1324. if ((stuff->ordering != Unsorted) && (stuff->ordering != YSorted) &&
  1325. (stuff->ordering != YXSorted) && (stuff->ordering != YXBanded)) {
  1326. client->errorValue = stuff->ordering;
  1327. return BadValue;
  1328. }
  1329. result = dixLookupGC(&pGC, stuff->gc, client, DixSetAttrAccess);
  1330. if (result != Success)
  1331. return result;
  1332. nr = (client->req_len << 2) - sizeof(xSetClipRectanglesReq);
  1333. if (nr & 4)
  1334. return BadLength;
  1335. nr >>= 3;
  1336. return SetClipRects(pGC, stuff->xOrigin, stuff->yOrigin,
  1337. nr, (xRectangle *) &stuff[1], (int) stuff->ordering);
  1338. }
  1339. int
  1340. ProcFreeGC(ClientPtr client)
  1341. {
  1342. GC *pGC;
  1343. int rc;
  1344. REQUEST(xResourceReq);
  1345. REQUEST_SIZE_MATCH(xResourceReq);
  1346. rc = dixLookupGC(&pGC, stuff->id, client, DixDestroyAccess);
  1347. if (rc != Success)
  1348. return rc;
  1349. FreeResource(stuff->id, RT_NONE);
  1350. return Success;
  1351. }
  1352. int
  1353. ProcClearToBackground(ClientPtr client)
  1354. {
  1355. REQUEST(xClearAreaReq);
  1356. WindowPtr pWin;
  1357. int rc;
  1358. REQUEST_SIZE_MATCH(xClearAreaReq);
  1359. rc = dixLookupWindow(&pWin, stuff->window, client, DixWriteAccess);
  1360. if (rc != Success)
  1361. return rc;
  1362. if (pWin->drawable.class == InputOnly) {
  1363. client->errorValue = stuff->window;
  1364. return BadMatch;
  1365. }
  1366. if ((stuff->exposures != xTrue) && (stuff->exposures != xFalse)) {
  1367. client->errorValue = stuff->exposures;
  1368. return BadValue;
  1369. }
  1370. (*pWin->drawable.pScreen->ClearToBackground) (pWin, stuff->x, stuff->y,
  1371. stuff->width, stuff->height,
  1372. (Bool) stuff->exposures);
  1373. return Success;
  1374. }
  1375. int
  1376. ProcCopyArea(ClientPtr client)
  1377. {
  1378. DrawablePtr pDst;
  1379. DrawablePtr pSrc;
  1380. GC *pGC;
  1381. REQUEST(xCopyAreaReq);
  1382. RegionPtr pRgn;
  1383. int rc;
  1384. REQUEST_SIZE_MATCH(xCopyAreaReq);
  1385. VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pDst, DixWriteAccess);
  1386. if (stuff->dstDrawable != stuff->srcDrawable) {
  1387. rc = dixLookupDrawable(&pSrc, stuff->srcDrawable, client, 0,
  1388. DixReadAccess);
  1389. if (rc != Success)
  1390. return rc;
  1391. if ((pDst->pScreen != pSrc->pScreen) || (pDst->depth != pSrc->depth)) {
  1392. client->errorValue = stuff->dstDrawable;
  1393. return BadMatch;
  1394. }
  1395. }
  1396. else
  1397. pSrc = pDst;
  1398. pRgn = (*pGC->ops->CopyArea) (pSrc, pDst, pGC, stuff->srcX, stuff->srcY,
  1399. stuff->width, stuff->height,
  1400. stuff->dstX, stuff->dstY);
  1401. if (pGC->graphicsExposures) {
  1402. (*pDst->pScreen->SendGraphicsExpose)
  1403. (client, pRgn, stuff->dstDrawable, X_CopyArea, 0);
  1404. if (pRgn)
  1405. RegionDestroy(pRgn);
  1406. }
  1407. return Success;
  1408. }
  1409. int
  1410. ProcCopyPlane(ClientPtr client)
  1411. {
  1412. DrawablePtr psrcDraw, pdstDraw;
  1413. GC *pGC;
  1414. REQUEST(xCopyPlaneReq);
  1415. RegionPtr pRgn;
  1416. int rc;
  1417. REQUEST_SIZE_MATCH(xCopyPlaneReq);
  1418. VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pdstDraw, DixWriteAccess);
  1419. if (stuff->dstDrawable != stuff->srcDrawable) {
  1420. rc = dixLookupDrawable(&psrcDraw, stuff->srcDrawable, client, 0,
  1421. DixReadAccess);
  1422. if (rc != Success)
  1423. return rc;
  1424. if (pdstDraw->pScreen != psrcDraw->pScreen) {
  1425. client->errorValue = stuff->dstDrawable;
  1426. return BadMatch;
  1427. }
  1428. }
  1429. else
  1430. psrcDraw = pdstDraw;
  1431. /* Check to see if stuff->bitPlane has exactly ONE good bit set */
  1432. if (stuff->bitPlane == 0 || (stuff->bitPlane & (stuff->bitPlane - 1)) ||
  1433. (stuff->bitPlane > (1L << (psrcDraw->depth - 1)))) {
  1434. client->errorValue = stuff->bitPlane;
  1435. return BadValue;
  1436. }
  1437. pRgn =
  1438. (*pGC->ops->CopyPlane) (psrcDraw, pdstDraw, pGC, stuff->srcX,
  1439. stuff->srcY, stuff->width, stuff->height,
  1440. stuff->dstX, stuff->dstY, stuff->bitPlane);
  1441. if (pGC->graphicsExposures) {
  1442. (*pdstDraw->pScreen->SendGraphicsExpose)
  1443. (client, pRgn, stuff->dstDrawable, X_CopyPlane, 0);
  1444. if (pRgn)
  1445. RegionDestroy(pRgn);
  1446. }
  1447. return Success;
  1448. }
  1449. int
  1450. ProcPolyPoint(ClientPtr client)
  1451. {
  1452. int npoint;
  1453. GC *pGC;

Large files files are truncated, but you can click here to view the full file