dispatch.c revision b1d344b3
1/************************************************************ 2 3Copyright 1987, 1989, 1998 The Open Group 4 5Permission to use, copy, modify, distribute, and sell this software and its 6documentation for any purpose is hereby granted without fee, provided that 7the above copyright notice appear in all copies and that both that 8copyright notice and this permission notice appear in supporting 9documentation. 10 11The above copyright notice and this permission notice shall be included in 12all copies or substantial portions of the Software. 13 14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 18AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 19CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 21Except as contained in this notice, the name of The Open Group shall not be 22used in advertising or otherwise to promote the sale, use or other dealings 23in this Software without prior written authorization from The Open Group. 24 25 26Copyright 1987, 1989 by Digital Equipment Corporation, Maynard, Massachusetts. 27 28 All Rights Reserved 29 30Permission to use, copy, modify, and distribute this software and its 31documentation for any purpose and without fee is hereby granted, 32provided that the above copyright notice appear in all copies and that 33both that copyright notice and this permission notice appear in 34supporting documentation, and that the name of Digital not be 35used in advertising or publicity pertaining to distribution of the 36software without specific, written prior permission. 37 38DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 39ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL 40DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR 41ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 42WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, 43ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS 44SOFTWARE. 45 46********************************************************/ 47 48/* The panoramix components contained the following notice */ 49/***************************************************************** 50 51Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts. 52 53Permission is hereby granted, free of charge, to any person obtaining a copy 54of this software and associated documentation files (the "Software"), to deal 55in the Software without restriction, including without limitation the rights 56to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 57copies of the Software. 58 59The above copyright notice and this permission notice shall be included in 60all copies or substantial portions of the Software. 61 62THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 63IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 64FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 65DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING, 66BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY, 67WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR 68IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 69 70Except as contained in this notice, the name of Digital Equipment Corporation 71shall not be used in advertising or otherwise to promote the sale, use or other 72dealings in this Software without prior written authorization from Digital 73Equipment Corporation. 74 75******************************************************************/ 76 77/* XSERVER_DTRACE additions: 78 * Copyright 2005-2006 Sun Microsystems, Inc. All rights reserved. 79 * 80 * Permission is hereby granted, free of charge, to any person obtaining a 81 * copy of this software and associated documentation files (the 82 * "Software"), to deal in the Software without restriction, including 83 * without limitation the rights to use, copy, modify, merge, publish, 84 * distribute, and/or sell copies of the Software, and to permit persons 85 * to whom the Software is furnished to do so, provided that the above 86 * copyright notice(s) and this permission notice appear in all copies of 87 * the Software and that both the above copyright notice(s) and this 88 * permission notice appear in supporting documentation. 89 * 90 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 91 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 92 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT 93 * OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 94 * HOLDERS INCLUDED IN THIS NOTICE BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL 95 * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING 96 * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, 97 * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION 98 * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 99 * 100 * Except as contained in this notice, the name of a copyright holder 101 * shall not be used in advertising or otherwise to promote the sale, use 102 * or other dealings in this Software without prior written authorization 103 * of the copyright holder. 104 */ 105 106 107 108#ifdef HAVE_DIX_CONFIG_H 109#include <dix-config.h> 110#endif 111 112#ifdef PANORAMIX_DEBUG 113#include <stdio.h> 114int ProcInitialConnection(); 115#endif 116 117#include "windowstr.h" 118#include <X11/fonts/fontstruct.h> 119#include "dixfontstr.h" 120#include "gcstruct.h" 121#include "selection.h" 122#include "colormapst.h" 123#include "cursorstr.h" 124#include "scrnintstr.h" 125#include "opaque.h" 126#include "input.h" 127#include "servermd.h" 128#include "extnsionst.h" 129#include "dixfont.h" 130#include "dispatch.h" 131#include "swaprep.h" 132#include "swapreq.h" 133#ifdef PANORAMIX 134#include "panoramiX.h" 135#include "panoramiXsrv.h" 136#endif 137#include "privates.h" 138#include "xace.h" 139#ifdef XKB 140#ifndef XKB_IN_SERVER 141#define XKB_IN_SERVER 142#endif 143#include "inputstr.h" 144#include <xkbsrv.h> 145#endif 146 147#ifdef XSERVER_DTRACE 148#include "registry.h" 149#include <sys/types.h> 150typedef const char *string; 151#include "Xserver-dtrace.h" 152#endif 153 154#define mskcnt ((MAXCLIENTS + 31) / 32) 155#define BITMASK(i) (1U << ((i) & 31)) 156#define MASKIDX(i) ((i) >> 5) 157#define MASKWORD(buf, i) buf[MASKIDX(i)] 158#define BITSET(buf, i) MASKWORD(buf, i) |= BITMASK(i) 159#define BITCLEAR(buf, i) MASKWORD(buf, i) &= ~BITMASK(i) 160#define GETBIT(buf, i) (MASKWORD(buf, i) & BITMASK(i)) 161 162extern xConnSetupPrefix connSetupPrefix; 163 164static ClientPtr grabClient; 165#define GrabNone 0 166#define GrabActive 1 167#define GrabKickout 2 168static int grabState = GrabNone; 169static long grabWaiters[mskcnt]; 170_X_EXPORT CallbackListPtr ServerGrabCallback = NULL; 171HWEventQueuePtr checkForInput[2]; 172extern int connBlockScreenStart; 173 174static void KillAllClients(void); 175 176static int nextFreeClientID; /* always MIN free client ID */ 177 178static int nClients; /* number of authorized clients */ 179 180_X_EXPORT CallbackListPtr ClientStateCallback; 181 182/* dispatchException & isItTimeToYield must be declared volatile since they 183 * are modified by signal handlers - otherwise optimizer may assume it doesn't 184 * need to actually check value in memory when used and may miss changes from 185 * signal handlers. 186 */ 187_X_EXPORT volatile char dispatchException = 0; 188_X_EXPORT volatile char isItTimeToYield; 189 190/* Various of the DIX function interfaces were not designed to allow 191 * the client->errorValue to be set on BadValue and other errors. 192 * Rather than changing interfaces and breaking untold code we introduce 193 * a new global that dispatch can use. 194 */ 195XID clientErrorValue; /* XXX this is a kludge */ 196 197#define SAME_SCREENS(a, b) (\ 198 (a.pScreen == b.pScreen)) 199 200void 201SetInputCheck(HWEventQueuePtr c0, HWEventQueuePtr c1) 202{ 203 checkForInput[0] = c0; 204 checkForInput[1] = c1; 205} 206 207_X_EXPORT void 208UpdateCurrentTime(void) 209{ 210 TimeStamp systime; 211 212 /* To avoid time running backwards, we must call GetTimeInMillis before 213 * calling ProcessInputEvents. 214 */ 215 systime.months = currentTime.months; 216 systime.milliseconds = GetTimeInMillis(); 217 if (systime.milliseconds < currentTime.milliseconds) 218 systime.months++; 219 if (*checkForInput[0] != *checkForInput[1]) 220 ProcessInputEvents(); 221 if (CompareTimeStamps(systime, currentTime) == LATER) 222 currentTime = systime; 223} 224 225/* Like UpdateCurrentTime, but can't call ProcessInputEvents */ 226_X_EXPORT void 227UpdateCurrentTimeIf(void) 228{ 229 TimeStamp systime; 230 231 systime.months = currentTime.months; 232 systime.milliseconds = GetTimeInMillis(); 233 if (systime.milliseconds < currentTime.milliseconds) 234 systime.months++; 235 if (*checkForInput[0] == *checkForInput[1]) 236 currentTime = systime; 237} 238 239 240#undef SMART_DEBUG 241 242#define SMART_SCHEDULE_DEFAULT_INTERVAL 20 /* ms */ 243#define SMART_SCHEDULE_MAX_SLICE 200 /* ms */ 244 245Bool SmartScheduleDisable = FALSE; 246long SmartScheduleSlice = SMART_SCHEDULE_DEFAULT_INTERVAL; 247long SmartScheduleInterval = SMART_SCHEDULE_DEFAULT_INTERVAL; 248long SmartScheduleMaxSlice = SMART_SCHEDULE_MAX_SLICE; 249long SmartScheduleTime; 250int SmartScheduleLatencyLimited = 0; 251static ClientPtr SmartLastClient; 252static int SmartLastIndex[SMART_MAX_PRIORITY-SMART_MIN_PRIORITY+1]; 253 254#ifdef SMART_DEBUG 255long SmartLastPrint; 256#endif 257 258void Dispatch(void); 259void InitProcVectors(void); 260 261static int 262SmartScheduleClient (int *clientReady, int nready) 263{ 264 ClientPtr pClient; 265 int i; 266 int client; 267 int bestPrio, best = 0; 268 int bestRobin, robin; 269 long now = SmartScheduleTime; 270 long idle; 271 272 bestPrio = -0x7fffffff; 273 bestRobin = 0; 274 idle = 2 * SmartScheduleSlice; 275 for (i = 0; i < nready; i++) 276 { 277 client = clientReady[i]; 278 pClient = clients[client]; 279 /* Praise clients which are idle */ 280 if ((now - pClient->smart_check_tick) >= idle) 281 { 282 if (pClient->smart_priority < 0) 283 pClient->smart_priority++; 284 } 285 pClient->smart_check_tick = now; 286 287 /* check priority to select best client */ 288 robin = (pClient->index - SmartLastIndex[pClient->smart_priority-SMART_MIN_PRIORITY]) & 0xff; 289 if (pClient->smart_priority > bestPrio || 290 (pClient->smart_priority == bestPrio && robin > bestRobin)) 291 { 292 bestPrio = pClient->smart_priority; 293 bestRobin = robin; 294 best = client; 295 } 296#ifdef SMART_DEBUG 297 if ((now - SmartLastPrint) >= 5000) 298 fprintf (stderr, " %2d: %3d", client, pClient->smart_priority); 299#endif 300 } 301#ifdef SMART_DEBUG 302 if ((now - SmartLastPrint) >= 5000) 303 { 304 fprintf (stderr, " use %2d\n", best); 305 SmartLastPrint = now; 306 } 307#endif 308 pClient = clients[best]; 309 SmartLastIndex[bestPrio-SMART_MIN_PRIORITY] = pClient->index; 310 /* 311 * Set current client pointer 312 */ 313 if (SmartLastClient != pClient) 314 { 315 pClient->smart_start_tick = now; 316 SmartLastClient = pClient; 317 } 318 /* 319 * Adjust slice 320 */ 321 if (nready == 1 && SmartScheduleLatencyLimited == 0) 322 { 323 /* 324 * If it's been a long time since another client 325 * has run, bump the slice up to get maximal 326 * performance from a single client 327 */ 328 if ((now - pClient->smart_start_tick) > 1000 && 329 SmartScheduleSlice < SmartScheduleMaxSlice) 330 { 331 SmartScheduleSlice += SmartScheduleInterval; 332 } 333 } 334 else 335 { 336 SmartScheduleSlice = SmartScheduleInterval; 337 } 338 return best; 339} 340 341void 342EnableLimitedSchedulingLatency(void) 343{ 344 ++SmartScheduleLatencyLimited; 345 SmartScheduleSlice = SmartScheduleInterval; 346} 347 348void 349DisableLimitedSchedulingLatency(void) 350{ 351 --SmartScheduleLatencyLimited; 352 353 /* protect against bugs */ 354 if (SmartScheduleLatencyLimited < 0) 355 SmartScheduleLatencyLimited = 0; 356} 357 358#define MAJOROP ((xReq *)client->requestBuffer)->reqType 359 360void 361Dispatch(void) 362{ 363 int *clientReady; /* array of request ready clients */ 364 int result; 365 ClientPtr client; 366 int nready; 367 HWEventQueuePtr* icheck = checkForInput; 368 long start_tick; 369 370 nextFreeClientID = 1; 371 nClients = 0; 372 373 clientReady = (int *) xalloc(sizeof(int) * MaxClients); 374 if (!clientReady) 375 return; 376 377 SmartScheduleSlice = SmartScheduleInterval; 378 while (!dispatchException) 379 { 380 if (*icheck[0] != *icheck[1]) 381 { 382 ProcessInputEvents(); 383 FlushIfCriticalOutputPending(); 384 } 385 386 nready = WaitForSomething(clientReady); 387 388 if (nready && !SmartScheduleDisable) 389 { 390 clientReady[0] = SmartScheduleClient (clientReady, nready); 391 nready = 1; 392 } 393 /***************** 394 * Handle events in round robin fashion, doing input between 395 * each round 396 *****************/ 397 398 while (!dispatchException && (--nready >= 0)) 399 { 400 client = clients[clientReady[nready]]; 401 if (! client) 402 { 403 /* KillClient can cause this to happen */ 404 continue; 405 } 406 /* GrabServer activation can cause this to be true */ 407 if (grabState == GrabKickout) 408 { 409 grabState = GrabActive; 410 break; 411 } 412 isItTimeToYield = FALSE; 413 414 start_tick = SmartScheduleTime; 415 while (!isItTimeToYield) 416 { 417 if (*icheck[0] != *icheck[1]) 418 ProcessInputEvents(); 419 420 FlushIfCriticalOutputPending(); 421 if (!SmartScheduleDisable && 422 (SmartScheduleTime - start_tick) >= SmartScheduleSlice) 423 { 424 /* Penalize clients which consume ticks */ 425 if (client->smart_priority > SMART_MIN_PRIORITY) 426 client->smart_priority--; 427 break; 428 } 429 /* now, finally, deal with client requests */ 430 431 result = ReadRequestFromClient(client); 432 if (result <= 0) 433 { 434 if (result < 0) 435 CloseDownClient(client); 436 break; 437 } 438 439 client->sequence++; 440#ifdef DEBUG 441 if (client->requestLogIndex == MAX_REQUEST_LOG) 442 client->requestLogIndex = 0; 443 client->requestLog[client->requestLogIndex] = MAJOROP; 444 client->requestLogIndex++; 445#endif 446#ifdef XSERVER_DTRACE 447 XSERVER_REQUEST_START(LookupMajorName(MAJOROP), MAJOROP, 448 ((xReq *)client->requestBuffer)->length, 449 client->index, client->requestBuffer); 450#endif 451 if (result > (maxBigRequestSize << 2)) 452 result = BadLength; 453 else { 454 result = XaceHookDispatch(client, MAJOROP); 455 if (result == Success) 456 result = (* client->requestVector[MAJOROP])(client); 457 XaceHookAuditEnd(client, result); 458 } 459#ifdef XSERVER_DTRACE 460 XSERVER_REQUEST_DONE(LookupMajorName(MAJOROP), MAJOROP, 461 client->sequence, client->index, result); 462#endif 463 464 if (result != Success) 465 { 466 if (client->noClientException != Success) 467 CloseDownClient(client); 468 else 469 SendErrorToClient(client, MAJOROP, 470 MinorOpcodeOfRequest(client), 471 client->errorValue, result); 472 break; 473 } 474 } 475 FlushAllOutput(); 476 client = clients[clientReady[nready]]; 477 if (client) 478 client->smart_stop_tick = SmartScheduleTime; 479 } 480 dispatchException &= ~DE_PRIORITYCHANGE; 481 } 482#if defined(DDXBEFORERESET) 483 ddxBeforeReset (); 484#endif 485 KillAllClients(); 486 xfree(clientReady); 487 dispatchException &= ~DE_RESET; 488 SmartScheduleLatencyLimited = 0; 489} 490 491#undef MAJOROP 492 493_X_EXPORT int 494ProcBadRequest(ClientPtr client) 495{ 496 return (BadRequest); 497} 498 499int 500ProcCreateWindow(ClientPtr client) 501{ 502 WindowPtr pParent, pWin; 503 REQUEST(xCreateWindowReq); 504 int len, rc; 505 506 REQUEST_AT_LEAST_SIZE(xCreateWindowReq); 507 508 LEGAL_NEW_RESOURCE(stuff->wid, client); 509 rc = dixLookupWindow(&pParent, stuff->parent, client, DixAddAccess); 510 if (rc != Success) 511 return rc; 512 len = client->req_len - (sizeof(xCreateWindowReq) >> 2); 513 if (Ones(stuff->mask) != len) 514 return BadLength; 515 if (!stuff->width || !stuff->height) 516 { 517 client->errorValue = 0; 518 return BadValue; 519 } 520 pWin = CreateWindow(stuff->wid, pParent, stuff->x, 521 stuff->y, stuff->width, stuff->height, 522 stuff->borderWidth, stuff->class, 523 stuff->mask, (XID *) &stuff[1], 524 (int)stuff->depth, 525 client, stuff->visual, &rc); 526 if (pWin) 527 { 528 Mask mask = pWin->eventMask; 529 530 pWin->eventMask = 0; /* subterfuge in case AddResource fails */ 531 if (!AddResource(stuff->wid, RT_WINDOW, (pointer)pWin)) 532 return BadAlloc; 533 pWin->eventMask = mask; 534 } 535 if (client->noClientException != Success) 536 return(client->noClientException); 537 else 538 return rc; 539} 540 541int 542ProcChangeWindowAttributes(ClientPtr client) 543{ 544 WindowPtr pWin; 545 REQUEST(xChangeWindowAttributesReq); 546 int result, len, rc; 547 Mask access_mode = 0; 548 549 REQUEST_AT_LEAST_SIZE(xChangeWindowAttributesReq); 550 access_mode |= (stuff->valueMask & CWEventMask) ? DixReceiveAccess : 0; 551 access_mode |= (stuff->valueMask & ~CWEventMask) ? DixSetAttrAccess : 0; 552 rc = dixLookupWindow(&pWin, stuff->window, client, access_mode); 553 if (rc != Success) 554 return rc; 555 len = client->req_len - (sizeof(xChangeWindowAttributesReq) >> 2); 556 if (len != Ones(stuff->valueMask)) 557 return BadLength; 558 result = ChangeWindowAttributes(pWin, 559 stuff->valueMask, 560 (XID *) &stuff[1], 561 client); 562 if (client->noClientException != Success) 563 return(client->noClientException); 564 else 565 return(result); 566} 567 568int 569ProcGetWindowAttributes(ClientPtr client) 570{ 571 WindowPtr pWin; 572 REQUEST(xResourceReq); 573 xGetWindowAttributesReply wa; 574 int rc; 575 576 REQUEST_SIZE_MATCH(xResourceReq); 577 rc = dixLookupWindow(&pWin, stuff->id, client, DixGetAttrAccess); 578 if (rc != Success) 579 return rc; 580 GetWindowAttributes(pWin, client, &wa); 581 WriteReplyToClient(client, sizeof(xGetWindowAttributesReply), &wa); 582 return(client->noClientException); 583} 584 585int 586ProcDestroyWindow(ClientPtr client) 587{ 588 WindowPtr pWin; 589 REQUEST(xResourceReq); 590 int rc; 591 592 REQUEST_SIZE_MATCH(xResourceReq); 593 rc = dixLookupWindow(&pWin, stuff->id, client, DixDestroyAccess); 594 if (rc != Success) 595 return rc; 596 if (pWin->parent) { 597 rc = dixLookupWindow(&pWin, pWin->parent->drawable.id, client, 598 DixRemoveAccess); 599 if (rc != Success) 600 return rc; 601 FreeResource(stuff->id, RT_NONE); 602 } 603 return(client->noClientException); 604} 605 606int 607ProcDestroySubwindows(ClientPtr client) 608{ 609 WindowPtr pWin; 610 REQUEST(xResourceReq); 611 int rc; 612 613 REQUEST_SIZE_MATCH(xResourceReq); 614 rc = dixLookupWindow(&pWin, stuff->id, client, DixRemoveAccess); 615 if (rc != Success) 616 return rc; 617 DestroySubwindows(pWin, client); 618 return(client->noClientException); 619} 620 621int 622ProcChangeSaveSet(ClientPtr client) 623{ 624 WindowPtr pWin; 625 REQUEST(xChangeSaveSetReq); 626 int result, rc; 627 628 REQUEST_SIZE_MATCH(xChangeSaveSetReq); 629 rc = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess); 630 if (rc != Success) 631 return rc; 632 if (client->clientAsMask == (CLIENT_BITS(pWin->drawable.id))) 633 return BadMatch; 634 if ((stuff->mode == SetModeInsert) || (stuff->mode == SetModeDelete)) 635 { 636 result = AlterSaveSetForClient(client, pWin, stuff->mode, FALSE, TRUE); 637 if (client->noClientException != Success) 638 return(client->noClientException); 639 else 640 return(result); 641 } 642 else 643 { 644 client->errorValue = stuff->mode; 645 return( BadValue ); 646 } 647} 648 649int 650ProcReparentWindow(ClientPtr client) 651{ 652 WindowPtr pWin, pParent; 653 REQUEST(xReparentWindowReq); 654 int result, rc; 655 656 REQUEST_SIZE_MATCH(xReparentWindowReq); 657 rc = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess); 658 if (rc != Success) 659 return rc; 660 rc = dixLookupWindow(&pParent, stuff->parent, client, DixAddAccess); 661 if (rc != Success) 662 return rc; 663 if (SAME_SCREENS(pWin->drawable, pParent->drawable)) 664 { 665 if ((pWin->backgroundState == ParentRelative) && 666 (pParent->drawable.depth != pWin->drawable.depth)) 667 return BadMatch; 668 if ((pWin->drawable.class != InputOnly) && 669 (pParent->drawable.class == InputOnly)) 670 return BadMatch; 671 result = ReparentWindow(pWin, pParent, 672 (short)stuff->x, (short)stuff->y, client); 673 if (client->noClientException != Success) 674 return(client->noClientException); 675 else 676 return(result); 677 } 678 else 679 return (BadMatch); 680} 681 682int 683ProcMapWindow(ClientPtr client) 684{ 685 WindowPtr pWin; 686 REQUEST(xResourceReq); 687 int rc; 688 689 REQUEST_SIZE_MATCH(xResourceReq); 690 rc = dixLookupWindow(&pWin, stuff->id, client, DixShowAccess); 691 if (rc != Success) 692 return rc; 693 MapWindow(pWin, client); 694 /* update cache to say it is mapped */ 695 return(client->noClientException); 696} 697 698int 699ProcMapSubwindows(ClientPtr client) 700{ 701 WindowPtr pWin; 702 REQUEST(xResourceReq); 703 int rc; 704 705 REQUEST_SIZE_MATCH(xResourceReq); 706 rc = dixLookupWindow(&pWin, stuff->id, client, DixListAccess); 707 if (rc != Success) 708 return rc; 709 MapSubwindows(pWin, client); 710 /* update cache to say it is mapped */ 711 return(client->noClientException); 712} 713 714int 715ProcUnmapWindow(ClientPtr client) 716{ 717 WindowPtr pWin; 718 REQUEST(xResourceReq); 719 int rc; 720 721 REQUEST_SIZE_MATCH(xResourceReq); 722 rc = dixLookupWindow(&pWin, stuff->id, client, DixHideAccess); 723 if (rc != Success) 724 return rc; 725 UnmapWindow(pWin, FALSE); 726 /* update cache to say it is mapped */ 727 return(client->noClientException); 728} 729 730int 731ProcUnmapSubwindows(ClientPtr client) 732{ 733 WindowPtr pWin; 734 REQUEST(xResourceReq); 735 int rc; 736 737 REQUEST_SIZE_MATCH(xResourceReq); 738 rc = dixLookupWindow(&pWin, stuff->id, client, DixListAccess); 739 if (rc != Success) 740 return rc; 741 UnmapSubwindows(pWin); 742 return(client->noClientException); 743} 744 745int 746ProcConfigureWindow(ClientPtr client) 747{ 748 WindowPtr pWin; 749 REQUEST(xConfigureWindowReq); 750 int result; 751 int len, rc; 752 753 REQUEST_AT_LEAST_SIZE(xConfigureWindowReq); 754 rc = dixLookupWindow(&pWin, stuff->window, client, 755 DixManageAccess|DixSetAttrAccess); 756 if (rc != Success) 757 return rc; 758 len = client->req_len - (sizeof(xConfigureWindowReq) >> 2); 759 if (Ones((Mask)stuff->mask) != len) 760 return BadLength; 761 result = ConfigureWindow(pWin, (Mask)stuff->mask, (XID *) &stuff[1], 762 client); 763 if (client->noClientException != Success) 764 return(client->noClientException); 765 else 766 return(result); 767} 768 769int 770ProcCirculateWindow(ClientPtr client) 771{ 772 WindowPtr pWin; 773 REQUEST(xCirculateWindowReq); 774 int rc; 775 776 REQUEST_SIZE_MATCH(xCirculateWindowReq); 777 if ((stuff->direction != RaiseLowest) && 778 (stuff->direction != LowerHighest)) 779 { 780 client->errorValue = stuff->direction; 781 return BadValue; 782 } 783 rc = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess); 784 if (rc != Success) 785 return rc; 786 CirculateWindow(pWin, (int)stuff->direction, client); 787 return(client->noClientException); 788} 789 790static int 791GetGeometry(ClientPtr client, xGetGeometryReply *rep) 792{ 793 DrawablePtr pDraw; 794 int rc; 795 REQUEST(xResourceReq); 796 REQUEST_SIZE_MATCH(xResourceReq); 797 798 rc = dixLookupDrawable(&pDraw, stuff->id, client, M_ANY, DixGetAttrAccess); 799 if (rc != Success) 800 return rc; 801 802 rep->type = X_Reply; 803 rep->length = 0; 804 rep->sequenceNumber = client->sequence; 805 rep->root = WindowTable[pDraw->pScreen->myNum]->drawable.id; 806 rep->depth = pDraw->depth; 807 rep->width = pDraw->width; 808 rep->height = pDraw->height; 809 810 /* XXX - Because the pixmap-implementation of the multibuffer extension 811 * may have the buffer-id's drawable resource value be a pointer 812 * to the buffer's window instead of the buffer itself 813 * (this happens if the buffer is the displayed buffer), 814 * we also have to check that the id matches before we can 815 * truly say that it is a DRAWABLE_WINDOW. 816 */ 817 818 if ((pDraw->type == UNDRAWABLE_WINDOW) || 819 ((pDraw->type == DRAWABLE_WINDOW) && (stuff->id == pDraw->id))) 820 { 821 WindowPtr pWin = (WindowPtr)pDraw; 822 rep->x = pWin->origin.x - wBorderWidth (pWin); 823 rep->y = pWin->origin.y - wBorderWidth (pWin); 824 rep->borderWidth = pWin->borderWidth; 825 } 826 else /* DRAWABLE_PIXMAP or DRAWABLE_BUFFER */ 827 { 828 rep->x = rep->y = rep->borderWidth = 0; 829 } 830 831 return Success; 832} 833 834 835int 836ProcGetGeometry(ClientPtr client) 837{ 838 xGetGeometryReply rep; 839 int status; 840 841 if ((status = GetGeometry(client, &rep)) != Success) 842 return status; 843 844 WriteReplyToClient(client, sizeof(xGetGeometryReply), &rep); 845 return(client->noClientException); 846} 847 848 849int 850ProcQueryTree(ClientPtr client) 851{ 852 xQueryTreeReply reply; 853 int rc, numChildren = 0; 854 WindowPtr pChild, pWin, pHead; 855 Window *childIDs = (Window *)NULL; 856 REQUEST(xResourceReq); 857 858 REQUEST_SIZE_MATCH(xResourceReq); 859 rc = dixLookupWindow(&pWin, stuff->id, client, DixListAccess); 860 if (rc != Success) 861 return rc; 862 reply.type = X_Reply; 863 reply.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id; 864 reply.sequenceNumber = client->sequence; 865 if (pWin->parent) 866 reply.parent = pWin->parent->drawable.id; 867 else 868 reply.parent = (Window)None; 869 pHead = RealChildHead(pWin); 870 for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib) 871 numChildren++; 872 if (numChildren) 873 { 874 int curChild = 0; 875 876 childIDs = (Window *) xalloc(numChildren * sizeof(Window)); 877 if (!childIDs) 878 return BadAlloc; 879 for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib) 880 childIDs[curChild++] = pChild->drawable.id; 881 } 882 883 reply.nChildren = numChildren; 884 reply.length = (numChildren * sizeof(Window)) >> 2; 885 886 WriteReplyToClient(client, sizeof(xQueryTreeReply), &reply); 887 if (numChildren) 888 { 889 client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write; 890 WriteSwappedDataToClient(client, numChildren * sizeof(Window), childIDs); 891 xfree(childIDs); 892 } 893 894 return(client->noClientException); 895} 896 897int 898ProcInternAtom(ClientPtr client) 899{ 900 Atom atom; 901 char *tchar; 902 REQUEST(xInternAtomReq); 903 904 REQUEST_FIXED_SIZE(xInternAtomReq, stuff->nbytes); 905 if ((stuff->onlyIfExists != xTrue) && (stuff->onlyIfExists != xFalse)) 906 { 907 client->errorValue = stuff->onlyIfExists; 908 return(BadValue); 909 } 910 tchar = (char *) &stuff[1]; 911 atom = MakeAtom(tchar, stuff->nbytes, !stuff->onlyIfExists); 912 if (atom != BAD_RESOURCE) 913 { 914 xInternAtomReply reply; 915 reply.type = X_Reply; 916 reply.length = 0; 917 reply.sequenceNumber = client->sequence; 918 reply.atom = atom; 919 WriteReplyToClient(client, sizeof(xInternAtomReply), &reply); 920 return(client->noClientException); 921 } 922 else 923 return (BadAlloc); 924} 925 926int 927ProcGetAtomName(ClientPtr client) 928{ 929 char *str; 930 xGetAtomNameReply reply; 931 int len; 932 REQUEST(xResourceReq); 933 934 REQUEST_SIZE_MATCH(xResourceReq); 935 if ( (str = NameForAtom(stuff->id)) ) 936 { 937 len = strlen(str); 938 reply.type = X_Reply; 939 reply.length = (len + 3) >> 2; 940 reply.sequenceNumber = client->sequence; 941 reply.nameLength = len; 942 WriteReplyToClient(client, sizeof(xGetAtomNameReply), &reply); 943 (void)WriteToClient(client, len, str); 944 return(client->noClientException); 945 } 946 else 947 { 948 client->errorValue = stuff->id; 949 return (BadAtom); 950 } 951} 952 953int 954ProcGrabServer(ClientPtr client) 955{ 956 int rc; 957 REQUEST_SIZE_MATCH(xReq); 958 if (grabState != GrabNone && client != grabClient) 959 { 960 ResetCurrentRequest(client); 961 client->sequence--; 962 BITSET(grabWaiters, client->index); 963 IgnoreClient(client); 964 return(client->noClientException); 965 } 966 rc = OnlyListenToOneClient(client); 967 if (rc != Success) 968 return rc; 969 grabState = GrabKickout; 970 grabClient = client; 971 972 if (ServerGrabCallback) 973 { 974 ServerGrabInfoRec grabinfo; 975 grabinfo.client = client; 976 grabinfo.grabstate = SERVER_GRABBED; 977 CallCallbacks(&ServerGrabCallback, (pointer)&grabinfo); 978 } 979 980 return(client->noClientException); 981} 982 983static void 984UngrabServer(ClientPtr client) 985{ 986 int i; 987 988 grabState = GrabNone; 989 ListenToAllClients(); 990 for (i = mskcnt; --i >= 0 && !grabWaiters[i]; ) 991 ; 992 if (i >= 0) 993 { 994 i <<= 5; 995 while (!GETBIT(grabWaiters, i)) 996 i++; 997 BITCLEAR(grabWaiters, i); 998 AttendClient(clients[i]); 999 } 1000 1001 if (ServerGrabCallback) 1002 { 1003 ServerGrabInfoRec grabinfo; 1004 grabinfo.client = client; 1005 grabinfo.grabstate = SERVER_UNGRABBED; 1006 CallCallbacks(&ServerGrabCallback, (pointer)&grabinfo); 1007 } 1008} 1009 1010int 1011ProcUngrabServer(ClientPtr client) 1012{ 1013 REQUEST_SIZE_MATCH(xReq); 1014 UngrabServer(client); 1015 return(client->noClientException); 1016} 1017 1018int 1019ProcTranslateCoords(ClientPtr client) 1020{ 1021 REQUEST(xTranslateCoordsReq); 1022 1023 WindowPtr pWin, pDst; 1024 xTranslateCoordsReply rep; 1025 int rc; 1026 1027 REQUEST_SIZE_MATCH(xTranslateCoordsReq); 1028 rc = dixLookupWindow(&pWin, stuff->srcWid, client, DixGetAttrAccess); 1029 if (rc != Success) 1030 return rc; 1031 rc = dixLookupWindow(&pDst, stuff->dstWid, client, DixGetAttrAccess); 1032 if (rc != Success) 1033 return rc; 1034 rep.type = X_Reply; 1035 rep.length = 0; 1036 rep.sequenceNumber = client->sequence; 1037 if (!SAME_SCREENS(pWin->drawable, pDst->drawable)) 1038 { 1039 rep.sameScreen = xFalse; 1040 rep.child = None; 1041 rep.dstX = rep.dstY = 0; 1042 } 1043 else 1044 { 1045 INT16 x, y; 1046 rep.sameScreen = xTrue; 1047 rep.child = None; 1048 /* computing absolute coordinates -- adjust to destination later */ 1049 x = pWin->drawable.x + stuff->srcX; 1050 y = pWin->drawable.y + stuff->srcY; 1051 pWin = pDst->firstChild; 1052 while (pWin) 1053 { 1054 BoxRec box; 1055 if ((pWin->mapped) && 1056 (x >= pWin->drawable.x - wBorderWidth (pWin)) && 1057 (x < pWin->drawable.x + (int)pWin->drawable.width + 1058 wBorderWidth (pWin)) && 1059 (y >= pWin->drawable.y - wBorderWidth (pWin)) && 1060 (y < pWin->drawable.y + (int)pWin->drawable.height + 1061 wBorderWidth (pWin)) 1062 /* When a window is shaped, a further check 1063 * is made to see if the point is inside 1064 * borderSize 1065 */ 1066 && (!wBoundingShape(pWin) || 1067 POINT_IN_REGION(pWin->drawable.pScreen, 1068 &pWin->borderSize, x, y, &box)) 1069 1070 && (!wInputShape(pWin) || 1071 POINT_IN_REGION(pWin->drawable.pScreen, 1072 wInputShape(pWin), 1073 x - pWin->drawable.x, 1074 y - pWin->drawable.y, &box)) 1075 ) 1076 { 1077 rep.child = pWin->drawable.id; 1078 pWin = (WindowPtr) NULL; 1079 } 1080 else 1081 pWin = pWin->nextSib; 1082 } 1083 /* adjust to destination coordinates */ 1084 rep.dstX = x - pDst->drawable.x; 1085 rep.dstY = y - pDst->drawable.y; 1086 } 1087 WriteReplyToClient(client, sizeof(xTranslateCoordsReply), &rep); 1088 return(client->noClientException); 1089} 1090 1091int 1092ProcOpenFont(ClientPtr client) 1093{ 1094 int err; 1095 REQUEST(xOpenFontReq); 1096 1097 REQUEST_FIXED_SIZE(xOpenFontReq, stuff->nbytes); 1098 client->errorValue = stuff->fid; 1099 LEGAL_NEW_RESOURCE(stuff->fid, client); 1100 err = OpenFont(client, stuff->fid, (Mask) 0, 1101 stuff->nbytes, (char *)&stuff[1]); 1102 if (err == Success) 1103 { 1104 return(client->noClientException); 1105 } 1106 else 1107 return err; 1108} 1109 1110int 1111ProcCloseFont(ClientPtr client) 1112{ 1113 FontPtr pFont; 1114 REQUEST(xResourceReq); 1115 1116 REQUEST_SIZE_MATCH(xResourceReq); 1117 pFont = (FontPtr)SecurityLookupIDByType(client, stuff->id, RT_FONT, 1118 DixDestroyAccess); 1119 if ( pFont != (FontPtr)NULL) /* id was valid */ 1120 { 1121 FreeResource(stuff->id, RT_NONE); 1122 return(client->noClientException); 1123 } 1124 else 1125 { 1126 client->errorValue = stuff->id; 1127 return (BadFont); 1128 } 1129} 1130 1131int 1132ProcQueryFont(ClientPtr client) 1133{ 1134 xQueryFontReply *reply; 1135 FontPtr pFont; 1136 GC *pGC; 1137 int rc; 1138 REQUEST(xResourceReq); 1139 REQUEST_SIZE_MATCH(xResourceReq); 1140 1141 client->errorValue = stuff->id; /* EITHER font or gc */ 1142 rc = dixLookupResourceByType((pointer *)&pFont, stuff->id, RT_FONT, client, 1143 DixGetAttrAccess); 1144 if (rc == BadValue) { 1145 rc = dixLookupResourceByType((pointer *)&pGC, stuff->id, RT_GC, client, 1146 DixGetAttrAccess); 1147 if (rc == Success) 1148 pFont = pGC->font; 1149 } 1150 if (rc != Success) 1151 return (rc == BadValue) ? BadFont: rc; 1152 1153 { 1154 xCharInfo *pmax = FONTINKMAX(pFont); 1155 xCharInfo *pmin = FONTINKMIN(pFont); 1156 int nprotoxcistructs; 1157 int rlength; 1158 1159 nprotoxcistructs = ( 1160 pmax->rightSideBearing == pmin->rightSideBearing && 1161 pmax->leftSideBearing == pmin->leftSideBearing && 1162 pmax->descent == pmin->descent && 1163 pmax->ascent == pmin->ascent && 1164 pmax->characterWidth == pmin->characterWidth) ? 1165 0 : N2dChars(pFont); 1166 1167 rlength = sizeof(xQueryFontReply) + 1168 FONTINFONPROPS(FONTCHARSET(pFont)) * sizeof(xFontProp) + 1169 nprotoxcistructs * sizeof(xCharInfo); 1170 reply = (xQueryFontReply *)xalloc(rlength); 1171 if(!reply) 1172 { 1173 return(BadAlloc); 1174 } 1175 1176 reply->type = X_Reply; 1177 reply->length = (rlength - sizeof(xGenericReply)) >> 2; 1178 reply->sequenceNumber = client->sequence; 1179 QueryFont( pFont, reply, nprotoxcistructs); 1180 1181 WriteReplyToClient(client, rlength, reply); 1182 xfree(reply); 1183 return(client->noClientException); 1184 } 1185} 1186 1187int 1188ProcQueryTextExtents(ClientPtr client) 1189{ 1190 xQueryTextExtentsReply reply; 1191 FontPtr pFont; 1192 GC *pGC; 1193 ExtentInfoRec info; 1194 unsigned long length; 1195 int rc; 1196 REQUEST(xQueryTextExtentsReq); 1197 REQUEST_AT_LEAST_SIZE(xQueryTextExtentsReq); 1198 1199 client->errorValue = stuff->fid; /* EITHER font or gc */ 1200 rc = dixLookupResourceByType((pointer *)&pFont, stuff->fid, RT_FONT, client, 1201 DixGetAttrAccess); 1202 if (rc == BadValue) { 1203 rc = dixLookupResourceByType((pointer *)&pGC, stuff->fid, RT_GC, client, 1204 DixGetAttrAccess); 1205 if (rc == Success) 1206 pFont = pGC->font; 1207 } 1208 if (rc != Success) 1209 return (rc == BadValue) ? BadFont: rc; 1210 1211 length = client->req_len - (sizeof(xQueryTextExtentsReq) >> 2); 1212 length = length << 1; 1213 if (stuff->oddLength) 1214 { 1215 if (length == 0) 1216 return(BadLength); 1217 length--; 1218 } 1219 if (!QueryTextExtents(pFont, length, (unsigned char *)&stuff[1], &info)) 1220 return(BadAlloc); 1221 reply.type = X_Reply; 1222 reply.length = 0; 1223 reply.sequenceNumber = client->sequence; 1224 reply.drawDirection = info.drawDirection; 1225 reply.fontAscent = info.fontAscent; 1226 reply.fontDescent = info.fontDescent; 1227 reply.overallAscent = info.overallAscent; 1228 reply.overallDescent = info.overallDescent; 1229 reply.overallWidth = info.overallWidth; 1230 reply.overallLeft = info.overallLeft; 1231 reply.overallRight = info.overallRight; 1232 WriteReplyToClient(client, sizeof(xQueryTextExtentsReply), &reply); 1233 return(client->noClientException); 1234} 1235 1236int 1237ProcListFonts(ClientPtr client) 1238{ 1239 REQUEST(xListFontsReq); 1240 1241 REQUEST_FIXED_SIZE(xListFontsReq, stuff->nbytes); 1242 1243 return ListFonts(client, (unsigned char *) &stuff[1], stuff->nbytes, 1244 stuff->maxNames); 1245} 1246 1247int 1248ProcListFontsWithInfo(ClientPtr client) 1249{ 1250 REQUEST(xListFontsWithInfoReq); 1251 1252 REQUEST_FIXED_SIZE(xListFontsWithInfoReq, stuff->nbytes); 1253 1254 return StartListFontsWithInfo(client, stuff->nbytes, 1255 (unsigned char *) &stuff[1], stuff->maxNames); 1256} 1257 1258/** 1259 * 1260 * \param value must conform to DeleteType 1261 */ 1262int 1263dixDestroyPixmap(pointer value, XID pid) 1264{ 1265 PixmapPtr pPixmap = (PixmapPtr)value; 1266 return (*pPixmap->drawable.pScreen->DestroyPixmap)(pPixmap); 1267} 1268 1269int 1270ProcCreatePixmap(ClientPtr client) 1271{ 1272 PixmapPtr pMap; 1273 DrawablePtr pDraw; 1274 REQUEST(xCreatePixmapReq); 1275 DepthPtr pDepth; 1276 int i, rc; 1277 1278 REQUEST_SIZE_MATCH(xCreatePixmapReq); 1279 client->errorValue = stuff->pid; 1280 LEGAL_NEW_RESOURCE(stuff->pid, client); 1281 1282 rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY, 1283 DixGetAttrAccess); 1284 if (rc != Success) 1285 return rc; 1286 1287 if (!stuff->width || !stuff->height) 1288 { 1289 client->errorValue = 0; 1290 return BadValue; 1291 } 1292 if (stuff->width > 32767 || stuff->height > 32767) 1293 { 1294 /* It is allowed to try and allocate a pixmap which is larger than 1295 * 32767 in either dimension. However, all of the framebuffer code 1296 * is buggy and does not reliably draw to such big pixmaps, basically 1297 * because the Region data structure operates with signed shorts 1298 * for the rectangles in it. 1299 * 1300 * Furthermore, several places in the X server computes the 1301 * size in bytes of the pixmap and tries to store it in an 1302 * integer. This integer can overflow and cause the allocated size 1303 * to be much smaller. 1304 * 1305 * So, such big pixmaps are rejected here with a BadAlloc 1306 */ 1307 return BadAlloc; 1308 } 1309 if (stuff->depth != 1) 1310 { 1311 pDepth = pDraw->pScreen->allowedDepths; 1312 for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++) 1313 if (pDepth->depth == stuff->depth) 1314 goto CreatePmap; 1315 client->errorValue = stuff->depth; 1316 return BadValue; 1317 } 1318CreatePmap: 1319 pMap = (PixmapPtr)(*pDraw->pScreen->CreatePixmap) 1320 (pDraw->pScreen, stuff->width, 1321 stuff->height, stuff->depth, 0); 1322 if (pMap) 1323 { 1324 pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER; 1325 pMap->drawable.id = stuff->pid; 1326 /* security creation/labeling check */ 1327 rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, RT_PIXMAP, 1328 pMap, RT_NONE, NULL, DixCreateAccess); 1329 if (rc != Success) { 1330 (*pDraw->pScreen->DestroyPixmap)(pMap); 1331 return rc; 1332 } 1333 if (AddResource(stuff->pid, RT_PIXMAP, (pointer)pMap)) 1334 return(client->noClientException); 1335 (*pDraw->pScreen->DestroyPixmap)(pMap); 1336 } 1337 return (BadAlloc); 1338} 1339 1340int 1341ProcFreePixmap(ClientPtr client) 1342{ 1343 PixmapPtr pMap; 1344 int rc; 1345 REQUEST(xResourceReq); 1346 REQUEST_SIZE_MATCH(xResourceReq); 1347 1348 rc = dixLookupResourceByType((pointer *)&pMap, stuff->id, RT_PIXMAP, client, 1349 DixDestroyAccess); 1350 if (rc == Success) 1351 { 1352 FreeResource(stuff->id, RT_NONE); 1353 return(client->noClientException); 1354 } 1355 else 1356 { 1357 client->errorValue = stuff->id; 1358 return (rc == BadValue) ? BadPixmap : rc; 1359 } 1360} 1361 1362int 1363ProcCreateGC(ClientPtr client) 1364{ 1365 int error, rc; 1366 GC *pGC; 1367 DrawablePtr pDraw; 1368 unsigned len; 1369 REQUEST(xCreateGCReq); 1370 1371 REQUEST_AT_LEAST_SIZE(xCreateGCReq); 1372 client->errorValue = stuff->gc; 1373 LEGAL_NEW_RESOURCE(stuff->gc, client); 1374 rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, 1375 DixGetAttrAccess); 1376 if (rc != Success) 1377 return rc; 1378 1379 len = client->req_len - (sizeof(xCreateGCReq) >> 2); 1380 if (len != Ones(stuff->mask)) 1381 return BadLength; 1382 pGC = (GC *)CreateGC(pDraw, stuff->mask, (XID *) &stuff[1], &error, 1383 stuff->gc, client); 1384 if (error != Success) 1385 return error; 1386 if (!AddResource(stuff->gc, RT_GC, (pointer)pGC)) 1387 return (BadAlloc); 1388 return(client->noClientException); 1389} 1390 1391int 1392ProcChangeGC(ClientPtr client) 1393{ 1394 GC *pGC; 1395 int result; 1396 unsigned len; 1397 REQUEST(xChangeGCReq); 1398 REQUEST_AT_LEAST_SIZE(xChangeGCReq); 1399 1400 result = dixLookupGC(&pGC, stuff->gc, client, DixSetAttrAccess); 1401 if (result != Success) 1402 return result; 1403 1404 len = client->req_len - (sizeof(xChangeGCReq) >> 2); 1405 if (len != Ones(stuff->mask)) 1406 return BadLength; 1407 1408 result = dixChangeGC(client, pGC, stuff->mask, (CARD32 *) &stuff[1], 0); 1409 if (client->noClientException != Success) 1410 return(client->noClientException); 1411 else 1412 { 1413 client->errorValue = clientErrorValue; 1414 return(result); 1415 } 1416} 1417 1418int 1419ProcCopyGC(ClientPtr client) 1420{ 1421 GC *dstGC; 1422 GC *pGC; 1423 int result; 1424 REQUEST(xCopyGCReq); 1425 REQUEST_SIZE_MATCH(xCopyGCReq); 1426 1427 result = dixLookupGC(&pGC, stuff->srcGC, client, DixGetAttrAccess); 1428 if (result != Success) 1429 return result; 1430 result = dixLookupGC(&dstGC, stuff->dstGC, client, DixSetAttrAccess); 1431 if (result != Success) 1432 return result; 1433 if ((dstGC->pScreen != pGC->pScreen) || (dstGC->depth != pGC->depth)) 1434 return (BadMatch); 1435 result = CopyGC(pGC, dstGC, stuff->mask); 1436 if (client->noClientException != Success) 1437 return(client->noClientException); 1438 else 1439 { 1440 client->errorValue = clientErrorValue; 1441 return(result); 1442 } 1443} 1444 1445int 1446ProcSetDashes(ClientPtr client) 1447{ 1448 GC *pGC; 1449 int result; 1450 REQUEST(xSetDashesReq); 1451 1452 REQUEST_FIXED_SIZE(xSetDashesReq, stuff->nDashes); 1453 if (stuff->nDashes == 0) 1454 { 1455 client->errorValue = 0; 1456 return BadValue; 1457 } 1458 1459 result = dixLookupGC(&pGC,stuff->gc, client, DixSetAttrAccess); 1460 if (result != Success) 1461 return result; 1462 1463 result = SetDashes(pGC, stuff->dashOffset, stuff->nDashes, 1464 (unsigned char *)&stuff[1]); 1465 if (client->noClientException != Success) 1466 return(client->noClientException); 1467 else 1468 { 1469 client->errorValue = clientErrorValue; 1470 return(result); 1471 } 1472} 1473 1474int 1475ProcSetClipRectangles(ClientPtr client) 1476{ 1477 int nr, result; 1478 GC *pGC; 1479 REQUEST(xSetClipRectanglesReq); 1480 1481 REQUEST_AT_LEAST_SIZE(xSetClipRectanglesReq); 1482 if ((stuff->ordering != Unsorted) && (stuff->ordering != YSorted) && 1483 (stuff->ordering != YXSorted) && (stuff->ordering != YXBanded)) 1484 { 1485 client->errorValue = stuff->ordering; 1486 return BadValue; 1487 } 1488 result = dixLookupGC(&pGC,stuff->gc, client, DixSetAttrAccess); 1489 if (result != Success) 1490 return result; 1491 1492 nr = (client->req_len << 2) - sizeof(xSetClipRectanglesReq); 1493 if (nr & 4) 1494 return(BadLength); 1495 nr >>= 3; 1496 result = SetClipRects(pGC, stuff->xOrigin, stuff->yOrigin, 1497 nr, (xRectangle *)&stuff[1], (int)stuff->ordering); 1498 if (client->noClientException != Success) 1499 return(client->noClientException); 1500 else 1501 return(result); 1502} 1503 1504int 1505ProcFreeGC(ClientPtr client) 1506{ 1507 GC *pGC; 1508 int rc; 1509 REQUEST(xResourceReq); 1510 REQUEST_SIZE_MATCH(xResourceReq); 1511 1512 rc = dixLookupGC(&pGC, stuff->id, client, DixDestroyAccess); 1513 if (rc != Success) 1514 return rc; 1515 1516 FreeResource(stuff->id, RT_NONE); 1517 return(client->noClientException); 1518} 1519 1520int 1521ProcClearToBackground(ClientPtr client) 1522{ 1523 REQUEST(xClearAreaReq); 1524 WindowPtr pWin; 1525 int rc; 1526 1527 REQUEST_SIZE_MATCH(xClearAreaReq); 1528 rc = dixLookupWindow(&pWin, stuff->window, client, DixWriteAccess); 1529 if (rc != Success) 1530 return rc; 1531 if (pWin->drawable.class == InputOnly) 1532 { 1533 client->errorValue = stuff->window; 1534 return (BadMatch); 1535 } 1536 if ((stuff->exposures != xTrue) && (stuff->exposures != xFalse)) 1537 { 1538 client->errorValue = stuff->exposures; 1539 return(BadValue); 1540 } 1541 (*pWin->drawable.pScreen->ClearToBackground)(pWin, stuff->x, stuff->y, 1542 stuff->width, stuff->height, 1543 (Bool)stuff->exposures); 1544 return(client->noClientException); 1545} 1546 1547int 1548ProcCopyArea(ClientPtr client) 1549{ 1550 DrawablePtr pDst; 1551 DrawablePtr pSrc; 1552 GC *pGC; 1553 REQUEST(xCopyAreaReq); 1554 RegionPtr pRgn; 1555 int rc; 1556 1557 REQUEST_SIZE_MATCH(xCopyAreaReq); 1558 1559 VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pDst, DixWriteAccess); 1560 if (stuff->dstDrawable != stuff->srcDrawable) 1561 { 1562 rc = dixLookupDrawable(&pSrc, stuff->srcDrawable, client, 0, 1563 DixReadAccess); 1564 if (rc != Success) 1565 return rc; 1566 if ((pDst->pScreen != pSrc->pScreen) || (pDst->depth != pSrc->depth)) 1567 { 1568 client->errorValue = stuff->dstDrawable; 1569 return (BadMatch); 1570 } 1571 } 1572 else 1573 pSrc = pDst; 1574 1575 pRgn = (*pGC->ops->CopyArea)(pSrc, pDst, pGC, stuff->srcX, stuff->srcY, 1576 stuff->width, stuff->height, 1577 stuff->dstX, stuff->dstY); 1578 if (pGC->graphicsExposures) 1579 { 1580 (*pDst->pScreen->SendGraphicsExpose) 1581 (client, pRgn, stuff->dstDrawable, X_CopyArea, 0); 1582 if (pRgn) 1583 REGION_DESTROY(pDst->pScreen, pRgn); 1584 } 1585 1586 return(client->noClientException); 1587} 1588 1589int 1590ProcCopyPlane(ClientPtr client) 1591{ 1592 DrawablePtr psrcDraw, pdstDraw; 1593 GC *pGC; 1594 REQUEST(xCopyPlaneReq); 1595 RegionPtr pRgn; 1596 int rc; 1597 1598 REQUEST_SIZE_MATCH(xCopyPlaneReq); 1599 1600 VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pdstDraw, DixWriteAccess); 1601 if (stuff->dstDrawable != stuff->srcDrawable) 1602 { 1603 rc = dixLookupDrawable(&psrcDraw, stuff->srcDrawable, client, 0, 1604 DixReadAccess); 1605 if (rc != Success) 1606 return rc; 1607 1608 if (pdstDraw->pScreen != psrcDraw->pScreen) 1609 { 1610 client->errorValue = stuff->dstDrawable; 1611 return (BadMatch); 1612 } 1613 } 1614 else 1615 psrcDraw = pdstDraw; 1616 1617 /* Check to see if stuff->bitPlane has exactly ONE good bit set */ 1618 if(stuff->bitPlane == 0 || (stuff->bitPlane & (stuff->bitPlane - 1)) || 1619 (stuff->bitPlane > (1L << (psrcDraw->depth - 1)))) 1620 { 1621 client->errorValue = stuff->bitPlane; 1622 return(BadValue); 1623 } 1624 1625 pRgn = (*pGC->ops->CopyPlane)(psrcDraw, pdstDraw, pGC, stuff->srcX, stuff->srcY, 1626 stuff->width, stuff->height, 1627 stuff->dstX, stuff->dstY, stuff->bitPlane); 1628 if (pGC->graphicsExposures) 1629 { 1630 (*pdstDraw->pScreen->SendGraphicsExpose) 1631 (client, pRgn, stuff->dstDrawable, X_CopyPlane, 0); 1632 if (pRgn) 1633 REGION_DESTROY(pdstDraw->pScreen, pRgn); 1634 } 1635 return(client->noClientException); 1636} 1637 1638int 1639ProcPolyPoint(ClientPtr client) 1640{ 1641 int npoint; 1642 GC *pGC; 1643 DrawablePtr pDraw; 1644 REQUEST(xPolyPointReq); 1645 1646 REQUEST_AT_LEAST_SIZE(xPolyPointReq); 1647 if ((stuff->coordMode != CoordModeOrigin) && 1648 (stuff->coordMode != CoordModePrevious)) 1649 { 1650 client->errorValue = stuff->coordMode; 1651 return BadValue; 1652 } 1653 VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 1654 npoint = ((client->req_len << 2) - sizeof(xPolyPointReq)) >> 2; 1655 if (npoint) 1656 (*pGC->ops->PolyPoint)(pDraw, pGC, stuff->coordMode, npoint, 1657 (xPoint *) &stuff[1]); 1658 return (client->noClientException); 1659} 1660 1661int 1662ProcPolyLine(ClientPtr client) 1663{ 1664 int npoint; 1665 GC *pGC; 1666 DrawablePtr pDraw; 1667 REQUEST(xPolyLineReq); 1668 1669 REQUEST_AT_LEAST_SIZE(xPolyLineReq); 1670 if ((stuff->coordMode != CoordModeOrigin) && 1671 (stuff->coordMode != CoordModePrevious)) 1672 { 1673 client->errorValue = stuff->coordMode; 1674 return BadValue; 1675 } 1676 VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 1677 npoint = ((client->req_len << 2) - sizeof(xPolyLineReq)) >> 2; 1678 if (npoint > 1) 1679 (*pGC->ops->Polylines)(pDraw, pGC, stuff->coordMode, npoint, 1680 (DDXPointPtr) &stuff[1]); 1681 return(client->noClientException); 1682} 1683 1684int 1685ProcPolySegment(ClientPtr client) 1686{ 1687 int nsegs; 1688 GC *pGC; 1689 DrawablePtr pDraw; 1690 REQUEST(xPolySegmentReq); 1691 1692 REQUEST_AT_LEAST_SIZE(xPolySegmentReq); 1693 VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 1694 nsegs = (client->req_len << 2) - sizeof(xPolySegmentReq); 1695 if (nsegs & 4) 1696 return(BadLength); 1697 nsegs >>= 3; 1698 if (nsegs) 1699 (*pGC->ops->PolySegment)(pDraw, pGC, nsegs, (xSegment *) &stuff[1]); 1700 return (client->noClientException); 1701} 1702 1703int 1704ProcPolyRectangle (ClientPtr client) 1705{ 1706 int nrects; 1707 GC *pGC; 1708 DrawablePtr pDraw; 1709 REQUEST(xPolyRectangleReq); 1710 1711 REQUEST_AT_LEAST_SIZE(xPolyRectangleReq); 1712 VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 1713 nrects = (client->req_len << 2) - sizeof(xPolyRectangleReq); 1714 if (nrects & 4) 1715 return(BadLength); 1716 nrects >>= 3; 1717 if (nrects) 1718 (*pGC->ops->PolyRectangle)(pDraw, pGC, 1719 nrects, (xRectangle *) &stuff[1]); 1720 return(client->noClientException); 1721} 1722 1723int 1724ProcPolyArc(ClientPtr client) 1725{ 1726 int narcs; 1727 GC *pGC; 1728 DrawablePtr pDraw; 1729 REQUEST(xPolyArcReq); 1730 1731 REQUEST_AT_LEAST_SIZE(xPolyArcReq); 1732 VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 1733 narcs = (client->req_len << 2) - sizeof(xPolyArcReq); 1734 if (narcs % sizeof(xArc)) 1735 return(BadLength); 1736 narcs /= sizeof(xArc); 1737 if (narcs) 1738 (*pGC->ops->PolyArc)(pDraw, pGC, narcs, (xArc *) &stuff[1]); 1739 return (client->noClientException); 1740} 1741 1742int 1743ProcFillPoly(ClientPtr client) 1744{ 1745 int things; 1746 GC *pGC; 1747 DrawablePtr pDraw; 1748 REQUEST(xFillPolyReq); 1749 1750 REQUEST_AT_LEAST_SIZE(xFillPolyReq); 1751 if ((stuff->shape != Complex) && (stuff->shape != Nonconvex) && 1752 (stuff->shape != Convex)) 1753 { 1754 client->errorValue = stuff->shape; 1755 return BadValue; 1756 } 1757 if ((stuff->coordMode != CoordModeOrigin) && 1758 (stuff->coordMode != CoordModePrevious)) 1759 { 1760 client->errorValue = stuff->coordMode; 1761 return BadValue; 1762 } 1763 1764 VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 1765 things = ((client->req_len << 2) - sizeof(xFillPolyReq)) >> 2; 1766 if (things) 1767 (*pGC->ops->FillPolygon) (pDraw, pGC, stuff->shape, 1768 stuff->coordMode, things, 1769 (DDXPointPtr) &stuff[1]); 1770 return(client->noClientException); 1771} 1772 1773int 1774ProcPolyFillRectangle(ClientPtr client) 1775{ 1776 int things; 1777 GC *pGC; 1778 DrawablePtr pDraw; 1779 REQUEST(xPolyFillRectangleReq); 1780 1781 REQUEST_AT_LEAST_SIZE(xPolyFillRectangleReq); 1782 VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 1783 things = (client->req_len << 2) - sizeof(xPolyFillRectangleReq); 1784 if (things & 4) 1785 return(BadLength); 1786 things >>= 3; 1787 1788 if (things) 1789 (*pGC->ops->PolyFillRect) (pDraw, pGC, things, 1790 (xRectangle *) &stuff[1]); 1791 return (client->noClientException); 1792} 1793 1794int 1795ProcPolyFillArc(ClientPtr client) 1796{ 1797 int narcs; 1798 GC *pGC; 1799 DrawablePtr pDraw; 1800 REQUEST(xPolyFillArcReq); 1801 1802 REQUEST_AT_LEAST_SIZE(xPolyFillArcReq); 1803 VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 1804 narcs = (client->req_len << 2) - sizeof(xPolyFillArcReq); 1805 if (narcs % sizeof(xArc)) 1806 return(BadLength); 1807 narcs /= sizeof(xArc); 1808 if (narcs) 1809 (*pGC->ops->PolyFillArc) (pDraw, pGC, narcs, (xArc *) &stuff[1]); 1810 return (client->noClientException); 1811} 1812 1813#ifdef MATCH_CLIENT_ENDIAN 1814 1815int 1816ServerOrder (void) 1817{ 1818 int whichbyte = 1; 1819 1820 if (*((char *) &whichbyte)) 1821 return LSBFirst; 1822 return MSBFirst; 1823} 1824 1825#define ClientOrder(client) ((client)->swapped ? !ServerOrder() : ServerOrder()) 1826 1827void 1828ReformatImage (char *base, int nbytes, int bpp, int order) 1829{ 1830 switch (bpp) { 1831 case 1: /* yuck */ 1832 if (BITMAP_BIT_ORDER != order) 1833 BitOrderInvert ((unsigned char *) base, nbytes); 1834#if IMAGE_BYTE_ORDER != BITMAP_BIT_ORDER && BITMAP_SCANLINE_UNIT != 8 1835 ReformatImage (base, nbytes, BITMAP_SCANLINE_UNIT, order); 1836#endif 1837 break; 1838 case 4: 1839 break; /* yuck */ 1840 case 8: 1841 break; 1842 case 16: 1843 if (IMAGE_BYTE_ORDER != order) 1844 TwoByteSwap ((unsigned char *) base, nbytes); 1845 break; 1846 case 32: 1847 if (IMAGE_BYTE_ORDER != order) 1848 FourByteSwap ((unsigned char *) base, nbytes); 1849 break; 1850 } 1851} 1852#else 1853#define ReformatImage(b,n,bpp,o) 1854#endif 1855 1856/* 64-bit server notes: the protocol restricts padding of images to 1857 * 8-, 16-, or 32-bits. We would like to have 64-bits for the server 1858 * to use internally. Removes need for internal alignment checking. 1859 * All of the PutImage functions could be changed individually, but 1860 * as currently written, they call other routines which require things 1861 * to be 64-bit padded on scanlines, so we changed things here. 1862 * If an image would be padded differently for 64- versus 32-, then 1863 * copy each scanline to a 64-bit padded scanline. 1864 * Also, we need to make sure that the image is aligned on a 64-bit 1865 * boundary, even if the scanlines are padded to our satisfaction. 1866 */ 1867int 1868ProcPutImage(ClientPtr client) 1869{ 1870 GC *pGC; 1871 DrawablePtr pDraw; 1872 long length; /* length of scanline server padded */ 1873 long lengthProto; /* length of scanline protocol padded */ 1874 char *tmpImage; 1875 REQUEST(xPutImageReq); 1876 1877 REQUEST_AT_LEAST_SIZE(xPutImageReq); 1878 VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 1879 if (stuff->format == XYBitmap) 1880 { 1881 if ((stuff->depth != 1) || 1882 (stuff->leftPad >= (unsigned int)screenInfo.bitmapScanlinePad)) 1883 return BadMatch; 1884 length = BitmapBytePad(stuff->width + stuff->leftPad); 1885 } 1886 else if (stuff->format == XYPixmap) 1887 { 1888 if ((pDraw->depth != stuff->depth) || 1889 (stuff->leftPad >= (unsigned int)screenInfo.bitmapScanlinePad)) 1890 return BadMatch; 1891 length = BitmapBytePad(stuff->width + stuff->leftPad); 1892 length *= stuff->depth; 1893 } 1894 else if (stuff->format == ZPixmap) 1895 { 1896 if ((pDraw->depth != stuff->depth) || (stuff->leftPad != 0)) 1897 return BadMatch; 1898 length = PixmapBytePad(stuff->width, stuff->depth); 1899 } 1900 else 1901 { 1902 client->errorValue = stuff->format; 1903 return BadValue; 1904 } 1905 1906 tmpImage = (char *)&stuff[1]; 1907 lengthProto = length; 1908 1909 if (((((lengthProto * stuff->height) + (unsigned)3) >> 2) + 1910 (sizeof(xPutImageReq) >> 2)) != client->req_len) 1911 return BadLength; 1912 1913 ReformatImage (tmpImage, lengthProto * stuff->height, 1914 stuff->format == ZPixmap ? BitsPerPixel (stuff->depth) : 1, 1915 ClientOrder(client)); 1916 1917 (*pGC->ops->PutImage) (pDraw, pGC, stuff->depth, stuff->dstX, stuff->dstY, 1918 stuff->width, stuff->height, 1919 stuff->leftPad, stuff->format, tmpImage); 1920 1921 return (client->noClientException); 1922} 1923 1924static int 1925DoGetImage(ClientPtr client, int format, Drawable drawable, 1926 int x, int y, int width, int height, 1927 Mask planemask, xGetImageReply **im_return) 1928{ 1929 DrawablePtr pDraw; 1930 int nlines, linesPerBuf, rc; 1931 int linesDone; 1932 long widthBytesLine, length; 1933 Mask plane = 0; 1934 char *pBuf; 1935 xGetImageReply xgi; 1936 RegionPtr pVisibleRegion = NULL; 1937 1938 if ((format != XYPixmap) && (format != ZPixmap)) 1939 { 1940 client->errorValue = format; 1941 return(BadValue); 1942 } 1943 rc = dixLookupDrawable(&pDraw, drawable, client, 0, DixReadAccess); 1944 if (rc != Success) 1945 return rc; 1946 1947 if(pDraw->type == DRAWABLE_WINDOW) 1948 { 1949 if( /* check for being viewable */ 1950 !((WindowPtr) pDraw)->realized || 1951 /* check for being on screen */ 1952 pDraw->x + x < 0 || 1953 pDraw->x + x + width > pDraw->pScreen->width || 1954 pDraw->y + y < 0 || 1955 pDraw->y + y + height > pDraw->pScreen->height || 1956 /* check for being inside of border */ 1957 x < - wBorderWidth((WindowPtr)pDraw) || 1958 x + width > wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width || 1959 y < -wBorderWidth((WindowPtr)pDraw) || 1960 y + height > wBorderWidth ((WindowPtr)pDraw) + (int)pDraw->height 1961 ) 1962 return(BadMatch); 1963 xgi.visual = wVisual (((WindowPtr) pDraw)); 1964 } 1965 else 1966 { 1967 if(x < 0 || 1968 x+width > (int)pDraw->width || 1969 y < 0 || 1970 y+height > (int)pDraw->height 1971 ) 1972 return(BadMatch); 1973 xgi.visual = None; 1974 } 1975 1976 xgi.type = X_Reply; 1977 xgi.sequenceNumber = client->sequence; 1978 xgi.depth = pDraw->depth; 1979 if(format == ZPixmap) 1980 { 1981 widthBytesLine = PixmapBytePad(width, pDraw->depth); 1982 length = widthBytesLine * height; 1983 1984 } 1985 else 1986 { 1987 widthBytesLine = BitmapBytePad(width); 1988 plane = ((Mask)1) << (pDraw->depth - 1); 1989 /* only planes asked for */ 1990 length = widthBytesLine * height * 1991 Ones(planemask & (plane | (plane - 1))); 1992 1993 } 1994 1995 xgi.length = length; 1996 1997 if (im_return) { 1998 pBuf = (char *)xalloc(sz_xGetImageReply + length); 1999 if (!pBuf) 2000 return (BadAlloc); 2001 if (widthBytesLine == 0) 2002 linesPerBuf = 0; 2003 else 2004 linesPerBuf = height; 2005 *im_return = (xGetImageReply *)pBuf; 2006 *(xGetImageReply *)pBuf = xgi; 2007 pBuf += sz_xGetImageReply; 2008 } else { 2009 xgi.length = (xgi.length + 3) >> 2; 2010 if (widthBytesLine == 0 || height == 0) 2011 linesPerBuf = 0; 2012 else if (widthBytesLine >= IMAGE_BUFSIZE) 2013 linesPerBuf = 1; 2014 else 2015 { 2016 linesPerBuf = IMAGE_BUFSIZE / widthBytesLine; 2017 if (linesPerBuf > height) 2018 linesPerBuf = height; 2019 } 2020 length = linesPerBuf * widthBytesLine; 2021 if (linesPerBuf < height) 2022 { 2023 /* we have to make sure intermediate buffers don't need padding */ 2024 while ((linesPerBuf > 1) && 2025 (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD)-1))) 2026 { 2027 linesPerBuf--; 2028 length -= widthBytesLine; 2029 } 2030 while (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD)-1)) 2031 { 2032 linesPerBuf++; 2033 length += widthBytesLine; 2034 } 2035 } 2036 if(!(pBuf = (char *) xalloc(length))) 2037 return (BadAlloc); 2038 WriteReplyToClient(client, sizeof (xGetImageReply), &xgi); 2039 } 2040 2041 if (pDraw->type == DRAWABLE_WINDOW) 2042 { 2043 pVisibleRegion = NotClippedByChildren((WindowPtr)pDraw); 2044 if (pVisibleRegion) 2045 { 2046 REGION_TRANSLATE(pDraw->pScreen, pVisibleRegion, 2047 -pDraw->x, -pDraw->y); 2048 } 2049 } 2050 2051 if (linesPerBuf == 0) 2052 { 2053 /* nothing to do */ 2054 } 2055 else if (format == ZPixmap) 2056 { 2057 linesDone = 0; 2058 while (height - linesDone > 0) 2059 { 2060 nlines = min(linesPerBuf, height - linesDone); 2061 (*pDraw->pScreen->GetImage) (pDraw, 2062 x, 2063 y + linesDone, 2064 width, 2065 nlines, 2066 format, 2067 planemask, 2068 (pointer) pBuf); 2069 if (pVisibleRegion) 2070 XaceCensorImage(client, pVisibleRegion, widthBytesLine, 2071 pDraw, x, y + linesDone, width, 2072 nlines, format, pBuf); 2073 2074 /* Note that this is NOT a call to WriteSwappedDataToClient, 2075 as we do NOT byte swap */ 2076 if (!im_return) 2077 { 2078 ReformatImage (pBuf, (int)(nlines * widthBytesLine), 2079 BitsPerPixel (pDraw->depth), 2080 ClientOrder(client)); 2081 2082/* Don't split me, gcc pukes when you do */ 2083 (void)WriteToClient(client, 2084 (int)(nlines * widthBytesLine), 2085 pBuf); 2086 } 2087 linesDone += nlines; 2088 } 2089 } 2090 else /* XYPixmap */ 2091 { 2092 for (; plane; plane >>= 1) 2093 { 2094 if (planemask & plane) 2095 { 2096 linesDone = 0; 2097 while (height - linesDone > 0) 2098 { 2099 nlines = min(linesPerBuf, height - linesDone); 2100 (*pDraw->pScreen->GetImage) (pDraw, 2101 x, 2102 y + linesDone, 2103 width, 2104 nlines, 2105 format, 2106 plane, 2107 (pointer)pBuf); 2108 if (pVisibleRegion) 2109 XaceCensorImage(client, pVisibleRegion, 2110 widthBytesLine, 2111 pDraw, x, y + linesDone, width, 2112 nlines, format, pBuf); 2113 2114 /* Note: NOT a call to WriteSwappedDataToClient, 2115 as we do NOT byte swap */ 2116 if (im_return) { 2117 pBuf += nlines * widthBytesLine; 2118 } else { 2119 ReformatImage (pBuf, 2120 (int)(nlines * widthBytesLine), 2121 1, 2122 ClientOrder (client)); 2123 2124/* Don't split me, gcc pukes when you do */ 2125 (void)WriteToClient(client, 2126 (int)(nlines * widthBytesLine), 2127 pBuf); 2128 } 2129 linesDone += nlines; 2130 } 2131 } 2132 } 2133 } 2134 if (pVisibleRegion) 2135 REGION_DESTROY(pDraw->pScreen, pVisibleRegion); 2136 if (!im_return) 2137 xfree(pBuf); 2138 return (client->noClientException); 2139} 2140 2141int 2142ProcGetImage(ClientPtr client) 2143{ 2144 REQUEST(xGetImageReq); 2145 2146 REQUEST_SIZE_MATCH(xGetImageReq); 2147 2148 return DoGetImage(client, stuff->format, stuff->drawable, 2149 stuff->x, stuff->y, 2150 (int)stuff->width, (int)stuff->height, 2151 stuff->planeMask, (xGetImageReply **)NULL); 2152} 2153 2154int 2155ProcPolyText(ClientPtr client) 2156{ 2157 int err; 2158 REQUEST(xPolyTextReq); 2159 DrawablePtr pDraw; 2160 GC *pGC; 2161 2162 REQUEST_AT_LEAST_SIZE(xPolyTextReq); 2163 VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 2164 2165 err = PolyText(client, 2166 pDraw, 2167 pGC, 2168 (unsigned char *)&stuff[1], 2169 ((unsigned char *) stuff) + (client->req_len << 2), 2170 stuff->x, 2171 stuff->y, 2172 stuff->reqType, 2173 stuff->drawable); 2174 2175 if (err == Success) 2176 { 2177 return(client->noClientException); 2178 } 2179 else 2180 return err; 2181} 2182 2183int 2184ProcImageText8(ClientPtr client) 2185{ 2186 int err; 2187 DrawablePtr pDraw; 2188 GC *pGC; 2189 2190 REQUEST(xImageTextReq); 2191 2192 REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars); 2193 VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 2194 2195 err = ImageText(client, 2196 pDraw, 2197 pGC, 2198 stuff->nChars, 2199 (unsigned char *)&stuff[1], 2200 stuff->x, 2201 stuff->y, 2202 stuff->reqType, 2203 stuff->drawable); 2204 2205 if (err == Success) 2206 { 2207 return(client->noClientException); 2208 } 2209 else 2210 return err; 2211} 2212 2213int 2214ProcImageText16(ClientPtr client) 2215{ 2216 int err; 2217 DrawablePtr pDraw; 2218 GC *pGC; 2219 2220 REQUEST(xImageTextReq); 2221 2222 REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars << 1); 2223 VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess); 2224 2225 err = ImageText(client, 2226 pDraw, 2227 pGC, 2228 stuff->nChars, 2229 (unsigned char *)&stuff[1], 2230 stuff->x, 2231 stuff->y, 2232 stuff->reqType, 2233 stuff->drawable); 2234 2235 if (err == Success) 2236 { 2237 return(client->noClientException); 2238 } 2239 else 2240 return err; 2241} 2242 2243 2244int 2245ProcCreateColormap(ClientPtr client) 2246{ 2247 VisualPtr pVisual; 2248 ColormapPtr pmap; 2249 Colormap mid; 2250 WindowPtr pWin; 2251 ScreenPtr pScreen; 2252 REQUEST(xCreateColormapReq); 2253 int i, result; 2254 2255 REQUEST_SIZE_MATCH(xCreateColormapReq); 2256 2257 if ((stuff->alloc != AllocNone) && (stuff->alloc != AllocAll)) 2258 { 2259 client->errorValue = stuff->alloc; 2260 return(BadValue); 2261 } 2262 mid = stuff->mid; 2263 LEGAL_NEW_RESOURCE(mid, client); 2264 result = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess); 2265 if (result != Success) 2266 return result; 2267 2268 pScreen = pWin->drawable.pScreen; 2269 for (i = 0, pVisual = pScreen->visuals; 2270 i < pScreen->numVisuals; 2271 i++, pVisual++) 2272 { 2273 if (pVisual->vid != stuff->visual) 2274 continue; 2275 result = CreateColormap(mid, pScreen, pVisual, &pmap, 2276 (int)stuff->alloc, client->index); 2277 if (client->noClientException != Success) 2278 return(client->noClientException); 2279 else 2280 return(result); 2281 } 2282 client->errorValue = stuff->visual; 2283 return(BadMatch); 2284} 2285 2286int 2287ProcFreeColormap(ClientPtr client) 2288{ 2289 ColormapPtr pmap; 2290 int rc; 2291 REQUEST(xResourceReq); 2292 2293 REQUEST_SIZE_MATCH(xResourceReq); 2294 rc = dixLookupResourceByType((pointer *)&pmap, stuff->id, RT_COLORMAP, client, 2295 DixDestroyAccess); 2296 if (rc == Success) 2297 { 2298 /* Freeing a default colormap is a no-op */ 2299 if (!(pmap->flags & IsDefault)) 2300 FreeResource(stuff->id, RT_NONE); 2301 return (client->noClientException); 2302 } 2303 else 2304 { 2305 client->errorValue = stuff->id; 2306 return (rc == BadValue) ? BadColor : rc; 2307 } 2308} 2309 2310 2311int 2312ProcCopyColormapAndFree(ClientPtr client) 2313{ 2314 Colormap mid; 2315 ColormapPtr pSrcMap; 2316 REQUEST(xCopyColormapAndFreeReq); 2317 int rc; 2318 2319 REQUEST_SIZE_MATCH(xCopyColormapAndFreeReq); 2320 mid = stuff->mid; 2321 LEGAL_NEW_RESOURCE(mid, client); 2322 rc = dixLookupResourceByType((pointer *)&pSrcMap, stuff->srcCmap, RT_COLORMAP, 2323 client, DixReadAccess|DixRemoveAccess); 2324 if (rc == Success) 2325 { 2326 rc = CopyColormapAndFree(mid, pSrcMap, client->index); 2327 if (client->noClientException != Success) 2328 return(client->noClientException); 2329 else 2330 return rc; 2331 } 2332 else 2333 { 2334 client->errorValue = stuff->srcCmap; 2335 return (rc == BadValue) ? BadColor : rc; 2336 } 2337} 2338 2339int 2340ProcInstallColormap(ClientPtr client) 2341{ 2342 ColormapPtr pcmp; 2343 int rc; 2344 REQUEST(xResourceReq); 2345 REQUEST_SIZE_MATCH(xResourceReq); 2346 2347 rc = dixLookupResourceByType((pointer *)&pcmp, stuff->id, RT_COLORMAP, client, 2348 DixInstallAccess); 2349 if (rc != Success) 2350 goto out; 2351 2352 rc = XaceHook(XACE_SCREEN_ACCESS, client, pcmp->pScreen, DixSetAttrAccess); 2353 if (rc != Success) 2354 goto out; 2355 2356 (*(pcmp->pScreen->InstallColormap)) (pcmp); 2357 2358 rc = client->noClientException; 2359out: 2360 client->errorValue = stuff->id; 2361 return (rc == BadValue) ? BadColor : rc; 2362} 2363 2364int 2365ProcUninstallColormap(ClientPtr client) 2366{ 2367 ColormapPtr pcmp; 2368 int rc; 2369 REQUEST(xResourceReq); 2370 REQUEST_SIZE_MATCH(xResourceReq); 2371 2372 rc = dixLookupResourceByType((pointer *)&pcmp, stuff->id, RT_COLORMAP, client, 2373 DixUninstallAccess); 2374 if (rc != Success) 2375 goto out; 2376 2377 rc = XaceHook(XACE_SCREEN_ACCESS, client, pcmp->pScreen, DixSetAttrAccess); 2378 if (rc != Success) 2379 goto out; 2380 2381 if(pcmp->mid != pcmp->pScreen->defColormap) 2382 (*(pcmp->pScreen->UninstallColormap)) (pcmp); 2383 2384 rc = client->noClientException; 2385out: 2386 client->errorValue = stuff->id; 2387 return (rc == BadValue) ? BadColor : rc; 2388} 2389 2390int 2391ProcListInstalledColormaps(ClientPtr client) 2392{ 2393 xListInstalledColormapsReply *preply; 2394 int nummaps, rc; 2395 WindowPtr pWin; 2396 REQUEST(xResourceReq); 2397 REQUEST_SIZE_MATCH(xResourceReq); 2398 2399 rc = dixLookupWindow(&pWin, stuff->id, client, DixGetAttrAccess); 2400 if (rc != Success) 2401 goto out; 2402 2403 rc = XaceHook(XACE_SCREEN_ACCESS, client, pWin->drawable.pScreen, 2404 DixGetAttrAccess); 2405 if (rc != Success) 2406 goto out; 2407 2408 preply = (xListInstalledColormapsReply *) 2409 xalloc(sizeof(xListInstalledColormapsReply) + 2410 pWin->drawable.pScreen->maxInstalledCmaps * 2411 sizeof(Colormap)); 2412 if(!preply) 2413 return(BadAlloc); 2414 2415 preply->type = X_Reply; 2416 preply->sequenceNumber = client->sequence; 2417 nummaps = (*pWin->drawable.pScreen->ListInstalledColormaps) 2418 (pWin->drawable.pScreen, (Colormap *)&preply[1]); 2419 preply->nColormaps = nummaps; 2420 preply->length = nummaps; 2421 WriteReplyToClient(client, sizeof (xListInstalledColormapsReply), preply); 2422 client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write; 2423 WriteSwappedDataToClient(client, nummaps * sizeof(Colormap), &preply[1]); 2424 xfree(preply); 2425 rc = client->noClientException; 2426out: 2427 return rc; 2428} 2429 2430int 2431ProcAllocColor (ClientPtr client) 2432{ 2433 ColormapPtr pmap; 2434 int rc; 2435 xAllocColorReply acr; 2436 REQUEST(xAllocColorReq); 2437 2438 REQUEST_SIZE_MATCH(xAllocColorReq); 2439 rc = dixLookupResourceByType((pointer *)&pmap, stuff->cmap, RT_COLORMAP, client, 2440 DixAddAccess); 2441 if (rc == Success) 2442 { 2443 acr.type = X_Reply; 2444 acr.length = 0; 2445 acr.sequenceNumber = client->sequence; 2446 acr.red = stuff->red; 2447 acr.green = stuff->green; 2448 acr.blue = stuff->blue; 2449 acr.pixel = 0; 2450 if( (rc = AllocColor(pmap, &acr.red, &acr.green, &acr.blue, 2451 &acr.pixel, client->index)) ) 2452 { 2453 if (client->noClientException != Success) 2454 return(client->noClientException); 2455 else 2456 return rc; 2457 } 2458#ifdef PANORAMIX 2459 if (noPanoramiXExtension || !pmap->pScreen->myNum) 2460#endif 2461 WriteReplyToClient(client, sizeof(xAllocColorReply), &acr); 2462 return (client->noClientException); 2463 2464 } 2465 else 2466 { 2467 client->errorValue = stuff->cmap; 2468 return (rc == BadValue) ? BadColor : rc; 2469 } 2470} 2471 2472int 2473ProcAllocNamedColor (ClientPtr client) 2474{ 2475 ColormapPtr pcmp; 2476 int rc; 2477 REQUEST(xAllocNamedColorReq); 2478 2479 REQUEST_FIXED_SIZE(xAllocNamedColorReq, stuff->nbytes); 2480 rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client, 2481 DixAddAccess); 2482 if (rc == Success) 2483 { 2484 xAllocNamedColorReply ancr; 2485 2486 ancr.type = X_Reply; 2487 ancr.length = 0; 2488 ancr.sequenceNumber = client->sequence; 2489 2490 if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1], stuff->nbytes, 2491 &ancr.exactRed, &ancr.exactGreen, &ancr.exactBlue)) 2492 { 2493 ancr.screenRed = ancr.exactRed; 2494 ancr.screenGreen = ancr.exactGreen; 2495 ancr.screenBlue = ancr.exactBlue; 2496 ancr.pixel = 0; 2497 if( (rc = AllocColor(pcmp, 2498 &ancr.screenRed, &ancr.screenGreen, &ancr.screenBlue, 2499 &ancr.pixel, client->index)) ) 2500 { 2501 if (client->noClientException != Success) 2502 return(client->noClientException); 2503 else 2504 return rc; 2505 } 2506#ifdef PANORAMIX 2507 if (noPanoramiXExtension || !pcmp->pScreen->myNum) 2508#endif 2509 WriteReplyToClient(client, sizeof (xAllocNamedColorReply), &ancr); 2510 return (client->noClientException); 2511 } 2512 else 2513 return(BadName); 2514 2515 } 2516 else 2517 { 2518 client->errorValue = stuff->cmap; 2519 return (rc == BadValue) ? BadColor : rc; 2520 } 2521} 2522 2523int 2524ProcAllocColorCells (ClientPtr client) 2525{ 2526 ColormapPtr pcmp; 2527 int rc; 2528 REQUEST(xAllocColorCellsReq); 2529 2530 REQUEST_SIZE_MATCH(xAllocColorCellsReq); 2531 rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client, 2532 DixAddAccess); 2533 if (rc == Success) 2534 { 2535 xAllocColorCellsReply accr; 2536 int npixels, nmasks; 2537 long length; 2538 Pixel *ppixels, *pmasks; 2539 2540 npixels = stuff->colors; 2541 if (!npixels) 2542 { 2543 client->errorValue = npixels; 2544 return (BadValue); 2545 } 2546 if (stuff->contiguous != xTrue && stuff->contiguous != xFalse) 2547 { 2548 client->errorValue = stuff->contiguous; 2549 return (BadValue); 2550 } 2551 nmasks = stuff->planes; 2552 length = ((long)npixels + (long)nmasks) * sizeof(Pixel); 2553 ppixels = (Pixel *)xalloc(length); 2554 if(!ppixels) 2555 return(BadAlloc); 2556 pmasks = ppixels + npixels; 2557 2558 if( (rc = AllocColorCells(client->index, pcmp, npixels, nmasks, 2559 (Bool)stuff->contiguous, ppixels, pmasks)) ) 2560 { 2561 xfree(ppixels); 2562 if (client->noClientException != Success) 2563 return(client->noClientException); 2564 else 2565 return rc; 2566 } 2567#ifdef PANORAMIX 2568 if (noPanoramiXExtension || !pcmp->pScreen->myNum) 2569#endif 2570 { 2571 accr.type = X_Reply; 2572 accr.length = length >> 2; 2573 accr.sequenceNumber = client->sequence; 2574 accr.nPixels = npixels; 2575 accr.nMasks = nmasks; 2576 WriteReplyToClient(client, sizeof (xAllocColorCellsReply), &accr); 2577 client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write; 2578 WriteSwappedDataToClient(client, length, ppixels); 2579 } 2580 xfree(ppixels); 2581 return (client->noClientException); 2582 } 2583 else 2584 { 2585 client->errorValue = stuff->cmap; 2586 return (rc == BadValue) ? BadColor : rc; 2587 } 2588} 2589 2590int 2591ProcAllocColorPlanes(ClientPtr client) 2592{ 2593 ColormapPtr pcmp; 2594 int rc; 2595 REQUEST(xAllocColorPlanesReq); 2596 2597 REQUEST_SIZE_MATCH(xAllocColorPlanesReq); 2598 rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client, 2599 DixAddAccess); 2600 if (rc == Success) 2601 { 2602 xAllocColorPlanesReply acpr; 2603 int npixels; 2604 long length; 2605 Pixel *ppixels; 2606 2607 npixels = stuff->colors; 2608 if (!npixels) 2609 { 2610 client->errorValue = npixels; 2611 return (BadValue); 2612 } 2613 if (stuff->contiguous != xTrue && stuff->contiguous != xFalse) 2614 { 2615 client->errorValue = stuff->contiguous; 2616 return (BadValue); 2617 } 2618 acpr.type = X_Reply; 2619 acpr.sequenceNumber = client->sequence; 2620 acpr.nPixels = npixels; 2621 length = (long)npixels * sizeof(Pixel); 2622 ppixels = (Pixel *)xalloc(length); 2623 if(!ppixels) 2624 return(BadAlloc); 2625 if( (rc = AllocColorPlanes(client->index, pcmp, npixels, 2626 (int)stuff->red, (int)stuff->green, (int)stuff->blue, 2627 (Bool)stuff->contiguous, ppixels, 2628 &acpr.redMask, &acpr.greenMask, &acpr.blueMask)) ) 2629 { 2630 xfree(ppixels); 2631 if (client->noClientException != Success) 2632 return(client->noClientException); 2633 else 2634 return rc; 2635 } 2636 acpr.length = length >> 2; 2637#ifdef PANORAMIX 2638 if (noPanoramiXExtension || !pcmp->pScreen->myNum) 2639#endif 2640 { 2641 WriteReplyToClient(client, sizeof(xAllocColorPlanesReply), &acpr); 2642 client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write; 2643 WriteSwappedDataToClient(client, length, ppixels); 2644 } 2645 xfree(ppixels); 2646 return (client->noClientException); 2647 } 2648 else 2649 { 2650 client->errorValue = stuff->cmap; 2651 return (rc == BadValue) ? BadColor : rc; 2652 } 2653} 2654 2655int 2656ProcFreeColors(ClientPtr client) 2657{ 2658 ColormapPtr pcmp; 2659 int rc; 2660 REQUEST(xFreeColorsReq); 2661 2662 REQUEST_AT_LEAST_SIZE(xFreeColorsReq); 2663 rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client, 2664 DixRemoveAccess); 2665 if (rc == Success) 2666 { 2667 int count; 2668 2669 if(pcmp->flags & AllAllocated) 2670 return(BadAccess); 2671 count = ((client->req_len << 2)- sizeof(xFreeColorsReq)) >> 2; 2672 rc = FreeColors(pcmp, client->index, count, 2673 (Pixel *)&stuff[1], (Pixel)stuff->planeMask); 2674 if (client->noClientException != Success) 2675 return(client->noClientException); 2676 else 2677 { 2678 client->errorValue = clientErrorValue; 2679 return rc; 2680 } 2681 2682 } 2683 else 2684 { 2685 client->errorValue = stuff->cmap; 2686 return (rc == BadValue) ? BadColor : rc; 2687 } 2688} 2689 2690int 2691ProcStoreColors (ClientPtr client) 2692{ 2693 ColormapPtr pcmp; 2694 int rc; 2695 REQUEST(xStoreColorsReq); 2696 2697 REQUEST_AT_LEAST_SIZE(xStoreColorsReq); 2698 rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client, 2699 DixWriteAccess); 2700 if (rc == Success) 2701 { 2702 int count; 2703 2704 count = (client->req_len << 2) - sizeof(xStoreColorsReq); 2705 if (count % sizeof(xColorItem)) 2706 return(BadLength); 2707 count /= sizeof(xColorItem); 2708 rc = StoreColors(pcmp, count, (xColorItem *)&stuff[1]); 2709 if (client->noClientException != Success) 2710 return(client->noClientException); 2711 else 2712 { 2713 client->errorValue = clientErrorValue; 2714 return rc; 2715 } 2716 } 2717 else 2718 { 2719 client->errorValue = stuff->cmap; 2720 return (rc == BadValue) ? BadColor : rc; 2721 } 2722} 2723 2724int 2725ProcStoreNamedColor (ClientPtr client) 2726{ 2727 ColormapPtr pcmp; 2728 int rc; 2729 REQUEST(xStoreNamedColorReq); 2730 2731 REQUEST_FIXED_SIZE(xStoreNamedColorReq, stuff->nbytes); 2732 rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client, 2733 DixWriteAccess); 2734 if (rc == Success) 2735 { 2736 xColorItem def; 2737 2738 if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1], 2739 stuff->nbytes, &def.red, &def.green, &def.blue)) 2740 { 2741 def.flags = stuff->flags; 2742 def.pixel = stuff->pixel; 2743 rc = StoreColors(pcmp, 1, &def); 2744 if (client->noClientException != Success) 2745 return(client->noClientException); 2746 else 2747 return rc; 2748 } 2749 return (BadName); 2750 } 2751 else 2752 { 2753 client->errorValue = stuff->cmap; 2754 return (rc == BadValue) ? BadColor : rc; 2755 } 2756} 2757 2758int 2759ProcQueryColors(ClientPtr client) 2760{ 2761 ColormapPtr pcmp; 2762 int rc; 2763 REQUEST(xQueryColorsReq); 2764 2765 REQUEST_AT_LEAST_SIZE(xQueryColorsReq); 2766 rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client, 2767 DixReadAccess); 2768 if (rc == Success) 2769 { 2770 int count; 2771 xrgb *prgbs; 2772 xQueryColorsReply qcr; 2773 2774 count = ((client->req_len << 2) - sizeof(xQueryColorsReq)) >> 2; 2775 prgbs = (xrgb *)xalloc(count * sizeof(xrgb)); 2776 if(!prgbs && count) 2777 return(BadAlloc); 2778 if( (rc = QueryColors(pcmp, count, (Pixel *)&stuff[1], prgbs)) ) 2779 { 2780 if (prgbs) xfree(prgbs); 2781 if (client->noClientException != Success) 2782 return(client->noClientException); 2783 else 2784 { 2785 client->errorValue = clientErrorValue; 2786 return rc; 2787 } 2788 } 2789 qcr.type = X_Reply; 2790 qcr.length = (count * sizeof(xrgb)) >> 2; 2791 qcr.sequenceNumber = client->sequence; 2792 qcr.nColors = count; 2793 WriteReplyToClient(client, sizeof(xQueryColorsReply), &qcr); 2794 if (count) 2795 { 2796 client->pSwapReplyFunc = (ReplySwapPtr) SQColorsExtend; 2797 WriteSwappedDataToClient(client, count * sizeof(xrgb), prgbs); 2798 } 2799 if (prgbs) xfree(prgbs); 2800 return(client->noClientException); 2801 2802 } 2803 else 2804 { 2805 client->errorValue = stuff->cmap; 2806 return (rc == BadValue) ? BadColor : rc; 2807 } 2808} 2809 2810int 2811ProcLookupColor(ClientPtr client) 2812{ 2813 ColormapPtr pcmp; 2814 int rc; 2815 REQUEST(xLookupColorReq); 2816 2817 REQUEST_FIXED_SIZE(xLookupColorReq, stuff->nbytes); 2818 rc = dixLookupResourceByType((pointer *)&pcmp, stuff->cmap, RT_COLORMAP, client, 2819 DixReadAccess); 2820 if (rc == Success) 2821 { 2822 xLookupColorReply lcr; 2823 2824 if(OsLookupColor(pcmp->pScreen->myNum, (char *)&stuff[1], stuff->nbytes, 2825 &lcr.exactRed, &lcr.exactGreen, &lcr.exactBlue)) 2826 { 2827 lcr.type = X_Reply; 2828 lcr.length = 0; 2829 lcr.sequenceNumber = client->sequence; 2830 lcr.screenRed = lcr.exactRed; 2831 lcr.screenGreen = lcr.exactGreen; 2832 lcr.screenBlue = lcr.exactBlue; 2833 (*pcmp->pScreen->ResolveColor)(&lcr.screenRed, 2834 &lcr.screenGreen, 2835 &lcr.screenBlue, 2836 pcmp->pVisual); 2837 WriteReplyToClient(client, sizeof(xLookupColorReply), &lcr); 2838 return(client->noClientException); 2839 } 2840 return (BadName); 2841 } 2842 else 2843 { 2844 client->errorValue = stuff->cmap; 2845 return (rc == BadValue) ? BadColor : rc; 2846 } 2847} 2848 2849int 2850ProcCreateCursor (ClientPtr client) 2851{ 2852 CursorPtr pCursor; 2853 PixmapPtr src; 2854 PixmapPtr msk; 2855 unsigned char * srcbits; 2856 unsigned char * mskbits; 2857 unsigned short width, height; 2858 long n; 2859 CursorMetricRec cm; 2860 int rc; 2861 2862 REQUEST(xCreateCursorReq); 2863 2864 REQUEST_SIZE_MATCH(xCreateCursorReq); 2865 LEGAL_NEW_RESOURCE(stuff->cid, client); 2866 2867 rc = dixLookupResourceByType((pointer *)&src, stuff->source, RT_PIXMAP, client, 2868 DixReadAccess); 2869 if (rc != Success) { 2870 client->errorValue = stuff->source; 2871 return (rc == BadValue) ? BadPixmap : rc; 2872 } 2873 2874 rc = dixLookupResourceByType((pointer *)&msk, stuff->mask, RT_PIXMAP, client, 2875 DixReadAccess); 2876 if (rc != Success) 2877 { 2878 if (stuff->mask != None) 2879 { 2880 client->errorValue = stuff->mask; 2881 return (rc == BadValue) ? BadPixmap : rc; 2882 } 2883 } 2884 else if ( src->drawable.width != msk->drawable.width 2885 || src->drawable.height != msk->drawable.height 2886 || src->drawable.depth != 1 2887 || msk->drawable.depth != 1) 2888 return (BadMatch); 2889 2890 width = src->drawable.width; 2891 height = src->drawable.height; 2892 2893 if ( stuff->x > width 2894 || stuff->y > height ) 2895 return (BadMatch); 2896 2897 n = BitmapBytePad(width)*height; 2898 srcbits = xcalloc(1, n); 2899 if (!srcbits) 2900 return (BadAlloc); 2901 mskbits = xalloc(n); 2902 if (!mskbits) 2903 { 2904 xfree(srcbits); 2905 return (BadAlloc); 2906 } 2907 2908 (* src->drawable.pScreen->GetImage)( (DrawablePtr)src, 0, 0, width, height, 2909 XYPixmap, 1, (pointer)srcbits); 2910 if ( msk == (PixmapPtr)NULL) 2911 { 2912 unsigned char *bits = mskbits; 2913 while (--n >= 0) 2914 *bits++ = ~0; 2915 } 2916 else 2917 { 2918 /* zeroing the (pad) bits helps some ddx cursor handling */ 2919 bzero((char *)mskbits, n); 2920 (* msk->drawable.pScreen->GetImage)( (DrawablePtr)msk, 0, 0, width, 2921 height, XYPixmap, 1, (pointer)mskbits); 2922 } 2923 cm.width = width; 2924 cm.height = height; 2925 cm.xhot = stuff->x; 2926 cm.yhot = stuff->y; 2927 rc = AllocARGBCursor(srcbits, mskbits, NULL, &cm, 2928 stuff->foreRed, stuff->foreGreen, stuff->foreBlue, 2929 stuff->backRed, stuff->backGreen, stuff->backBlue, 2930 &pCursor, client, stuff->cid); 2931 2932 if (rc != Success) 2933 return rc; 2934 if (!AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor)) 2935 return BadAlloc; 2936 2937 return client->noClientException; 2938} 2939 2940int 2941ProcCreateGlyphCursor (ClientPtr client) 2942{ 2943 CursorPtr pCursor; 2944 int res; 2945 2946 REQUEST(xCreateGlyphCursorReq); 2947 2948 REQUEST_SIZE_MATCH(xCreateGlyphCursorReq); 2949 LEGAL_NEW_RESOURCE(stuff->cid, client); 2950 2951 res = AllocGlyphCursor(stuff->source, stuff->sourceChar, 2952 stuff->mask, stuff->maskChar, 2953 stuff->foreRed, stuff->foreGreen, stuff->foreBlue, 2954 stuff->backRed, stuff->backGreen, stuff->backBlue, 2955 &pCursor, client, stuff->cid); 2956 if (res != Success) 2957 return res; 2958 if (AddResource(stuff->cid, RT_CURSOR, (pointer)pCursor)) 2959 return client->noClientException; 2960 return BadAlloc; 2961} 2962 2963 2964int 2965ProcFreeCursor (ClientPtr client) 2966{ 2967 CursorPtr pCursor; 2968 int rc; 2969 REQUEST(xResourceReq); 2970 2971 REQUEST_SIZE_MATCH(xResourceReq); 2972 rc = dixLookupResourceByType((pointer *)&pCursor, stuff->id, RT_CURSOR, client, 2973 DixDestroyAccess); 2974 if (rc == Success) 2975 { 2976 FreeResource(stuff->id, RT_NONE); 2977 return (client->noClientException); 2978 } 2979 else 2980 { 2981 client->errorValue = stuff->id; 2982 return (rc == BadValue) ? BadCursor : rc; 2983 } 2984} 2985 2986int 2987ProcQueryBestSize (ClientPtr client) 2988{ 2989 xQueryBestSizeReply reply; 2990 DrawablePtr pDraw; 2991 ScreenPtr pScreen; 2992 int rc; 2993 REQUEST(xQueryBestSizeReq); 2994 REQUEST_SIZE_MATCH(xQueryBestSizeReq); 2995 2996 if ((stuff->class != CursorShape) && 2997 (stuff->class != TileShape) && 2998 (stuff->class != StippleShape)) 2999 { 3000 client->errorValue = stuff->class; 3001 return(BadValue); 3002 } 3003 3004 rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY, 3005 DixGetAttrAccess); 3006 if (rc != Success) 3007 return rc; 3008 if (stuff->class != CursorShape && pDraw->type == UNDRAWABLE_WINDOW) 3009 return (BadMatch); 3010 pScreen = pDraw->pScreen; 3011 rc = XaceHook(XACE_SCREEN_ACCESS, client, pScreen, DixGetAttrAccess); 3012 if (rc != Success) 3013 return rc; 3014 (* pScreen->QueryBestSize)(stuff->class, &stuff->width, 3015 &stuff->height, pScreen); 3016 reply.type = X_Reply; 3017 reply.length = 0; 3018 reply.sequenceNumber = client->sequence; 3019 reply.width = stuff->width; 3020 reply.height = stuff->height; 3021 WriteReplyToClient(client, sizeof(xQueryBestSizeReply), &reply); 3022 return (client->noClientException); 3023} 3024 3025 3026int 3027ProcSetScreenSaver (ClientPtr client) 3028{ 3029 int rc, i, blankingOption, exposureOption; 3030 REQUEST(xSetScreenSaverReq); 3031 REQUEST_SIZE_MATCH(xSetScreenSaverReq); 3032 3033 for (i = 0; i < screenInfo.numScreens; i++) { 3034 rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, screenInfo.screens[i], 3035 DixSetAttrAccess); 3036 if (rc != Success) 3037 return rc; 3038 } 3039 3040 blankingOption = stuff->preferBlank; 3041 if ((blankingOption != DontPreferBlanking) && 3042 (blankingOption != PreferBlanking) && 3043 (blankingOption != DefaultBlanking)) 3044 { 3045 client->errorValue = blankingOption; 3046 return BadValue; 3047 } 3048 exposureOption = stuff->allowExpose; 3049 if ((exposureOption != DontAllowExposures) && 3050 (exposureOption != AllowExposures) && 3051 (exposureOption != DefaultExposures)) 3052 { 3053 client->errorValue = exposureOption; 3054 return BadValue; 3055 } 3056 if (stuff->timeout < -1) 3057 { 3058 client->errorValue = stuff->timeout; 3059 return BadValue; 3060 } 3061 if (stuff->interval < -1) 3062 { 3063 client->errorValue = stuff->interval; 3064 return BadValue; 3065 } 3066 3067 if (blankingOption == DefaultBlanking) 3068 ScreenSaverBlanking = defaultScreenSaverBlanking; 3069 else 3070 ScreenSaverBlanking = blankingOption; 3071 if (exposureOption == DefaultExposures) 3072 ScreenSaverAllowExposures = defaultScreenSaverAllowExposures; 3073 else 3074 ScreenSaverAllowExposures = exposureOption; 3075 3076 if (stuff->timeout >= 0) 3077 ScreenSaverTime = stuff->timeout * MILLI_PER_SECOND; 3078 else 3079 ScreenSaverTime = defaultScreenSaverTime; 3080 if (stuff->interval >= 0) 3081 ScreenSaverInterval = stuff->interval * MILLI_PER_SECOND; 3082 else 3083 ScreenSaverInterval = defaultScreenSaverInterval; 3084 3085 SetScreenSaverTimer(); 3086 return (client->noClientException); 3087} 3088 3089int 3090ProcGetScreenSaver(ClientPtr client) 3091{ 3092 xGetScreenSaverReply rep; 3093 int rc, i; 3094 REQUEST_SIZE_MATCH(xReq); 3095 3096 for (i = 0; i < screenInfo.numScreens; i++) { 3097 rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, screenInfo.screens[i], 3098 DixGetAttrAccess); 3099 if (rc != Success) 3100 return rc; 3101 } 3102 3103 rep.type = X_Reply; 3104 rep.length = 0; 3105 rep.sequenceNumber = client->sequence; 3106 rep.timeout = ScreenSaverTime / MILLI_PER_SECOND; 3107 rep.interval = ScreenSaverInterval / MILLI_PER_SECOND; 3108 rep.preferBlanking = ScreenSaverBlanking; 3109 rep.allowExposures = ScreenSaverAllowExposures; 3110 WriteReplyToClient(client, sizeof(xGetScreenSaverReply), &rep); 3111 return (client->noClientException); 3112} 3113 3114int 3115ProcChangeHosts(ClientPtr client) 3116{ 3117 REQUEST(xChangeHostsReq); 3118 int result; 3119 3120 REQUEST_FIXED_SIZE(xChangeHostsReq, stuff->hostLength); 3121 3122 if(stuff->mode == HostInsert) 3123 result = AddHost(client, (int)stuff->hostFamily, 3124 stuff->hostLength, (pointer)&stuff[1]); 3125 else if (stuff->mode == HostDelete) 3126 result = RemoveHost(client, (int)stuff->hostFamily, 3127 stuff->hostLength, (pointer)&stuff[1]); 3128 else 3129 { 3130 client->errorValue = stuff->mode; 3131 return BadValue; 3132 } 3133 if (!result) 3134 result = client->noClientException; 3135 return (result); 3136} 3137 3138int 3139ProcListHosts(ClientPtr client) 3140{ 3141 xListHostsReply reply; 3142 int len, nHosts, result; 3143 pointer pdata; 3144 /* REQUEST(xListHostsReq); */ 3145 3146 REQUEST_SIZE_MATCH(xListHostsReq); 3147 3148 /* untrusted clients can't list hosts */ 3149 result = XaceHook(XACE_SERVER_ACCESS, client, DixReadAccess); 3150 if (result != Success) 3151 return result; 3152 3153 result = GetHosts(&pdata, &nHosts, &len, &reply.enabled); 3154 if (result != Success) 3155 return(result); 3156 reply.type = X_Reply; 3157 reply.sequenceNumber = client->sequence; 3158 reply.nHosts = nHosts; 3159 reply.length = len >> 2; 3160 WriteReplyToClient(client, sizeof(xListHostsReply), &reply); 3161 if (nHosts) 3162 { 3163 client->pSwapReplyFunc = (ReplySwapPtr) SLHostsExtend; 3164 WriteSwappedDataToClient(client, len, pdata); 3165 } 3166 xfree(pdata); 3167 return (client->noClientException); 3168} 3169 3170int 3171ProcChangeAccessControl(ClientPtr client) 3172{ 3173 int result; 3174 REQUEST(xSetAccessControlReq); 3175 3176 REQUEST_SIZE_MATCH(xSetAccessControlReq); 3177 if ((stuff->mode != EnableAccess) && (stuff->mode != DisableAccess)) 3178 { 3179 client->errorValue = stuff->mode; 3180 return BadValue; 3181 } 3182 result = ChangeAccessControl(client, stuff->mode == EnableAccess); 3183 if (!result) 3184 result = client->noClientException; 3185 return (result); 3186} 3187 3188/********************* 3189 * CloseDownRetainedResources 3190 * 3191 * Find all clients that are gone and have terminated in RetainTemporary 3192 * and destroy their resources. 3193 *********************/ 3194 3195static void 3196CloseDownRetainedResources(void) 3197{ 3198 int i; 3199 ClientPtr client; 3200 3201 for (i=1; i<currentMaxClients; i++) 3202 { 3203 client = clients[i]; 3204 if (client && (client->closeDownMode == RetainTemporary) 3205 && (client->clientGone)) 3206 CloseDownClient(client); 3207 } 3208} 3209 3210int 3211ProcKillClient(ClientPtr client) 3212{ 3213 REQUEST(xResourceReq); 3214 ClientPtr killclient; 3215 int rc; 3216 3217 REQUEST_SIZE_MATCH(xResourceReq); 3218 if (stuff->id == AllTemporary) 3219 { 3220 CloseDownRetainedResources(); 3221 return (client->noClientException); 3222 } 3223 3224 rc = dixLookupClient(&killclient, stuff->id, client, DixDestroyAccess); 3225 if (rc == Success) { 3226 CloseDownClient(killclient); 3227 /* if an LBX proxy gets killed, isItTimeToYield will be set */ 3228 if (isItTimeToYield || (client == killclient)) 3229 { 3230 /* force yield and return Success, so that Dispatch() 3231 * doesn't try to touch client 3232 */ 3233 isItTimeToYield = TRUE; 3234 return (Success); 3235 } 3236 return (client->noClientException); 3237 } 3238 else 3239 return rc; 3240} 3241 3242int 3243ProcSetFontPath(ClientPtr client) 3244{ 3245 unsigned char *ptr; 3246 unsigned long nbytes, total; 3247 long nfonts; 3248 int n, result; 3249 int error; 3250 REQUEST(xSetFontPathReq); 3251 3252 REQUEST_AT_LEAST_SIZE(xSetFontPathReq); 3253 3254 nbytes = (client->req_len << 2) - sizeof(xSetFontPathReq); 3255 total = nbytes; 3256 ptr = (unsigned char *)&stuff[1]; 3257 nfonts = stuff->nFonts; 3258 while (--nfonts >= 0) 3259 { 3260 if ((total == 0) || (total < (n = (*ptr + 1)))) 3261 return(BadLength); 3262 total -= n; 3263 ptr += n; 3264 } 3265 if (total >= 4) 3266 return(BadLength); 3267 result = SetFontPath(client, stuff->nFonts, (unsigned char *)&stuff[1], 3268 &error); 3269 if (!result) 3270 { 3271 result = client->noClientException; 3272 client->errorValue = error; 3273 } 3274 return (result); 3275} 3276 3277int 3278ProcGetFontPath(ClientPtr client) 3279{ 3280 xGetFontPathReply reply; 3281 int rc, stringLens, numpaths; 3282 unsigned char *bufferStart; 3283 /* REQUEST (xReq); */ 3284 3285 REQUEST_SIZE_MATCH(xReq); 3286 rc = GetFontPath(client, &numpaths, &stringLens, &bufferStart); 3287 if (rc != Success) 3288 return rc; 3289 3290 reply.type = X_Reply; 3291 reply.sequenceNumber = client->sequence; 3292 reply.length = (stringLens + numpaths + 3) >> 2; 3293 reply.nPaths = numpaths; 3294 3295 WriteReplyToClient(client, sizeof(xGetFontPathReply), &reply); 3296 if (stringLens || numpaths) 3297 (void)WriteToClient(client, stringLens + numpaths, (char *)bufferStart); 3298 return(client->noClientException); 3299} 3300 3301int 3302ProcChangeCloseDownMode(ClientPtr client) 3303{ 3304 int rc; 3305 REQUEST(xSetCloseDownModeReq); 3306 REQUEST_SIZE_MATCH(xSetCloseDownModeReq); 3307 3308 rc = XaceHook(XACE_CLIENT_ACCESS, client, client, DixManageAccess); 3309 if (rc != Success) 3310 return rc; 3311 3312 if ((stuff->mode == AllTemporary) || 3313 (stuff->mode == RetainPermanent) || 3314 (stuff->mode == RetainTemporary)) 3315 { 3316 client->closeDownMode = stuff->mode; 3317 return (client->noClientException); 3318 } 3319 else 3320 { 3321 client->errorValue = stuff->mode; 3322 return (BadValue); 3323 } 3324} 3325 3326int ProcForceScreenSaver(ClientPtr client) 3327{ 3328 int rc; 3329 REQUEST(xForceScreenSaverReq); 3330 3331 REQUEST_SIZE_MATCH(xForceScreenSaverReq); 3332 3333 if ((stuff->mode != ScreenSaverReset) && 3334 (stuff->mode != ScreenSaverActive)) 3335 { 3336 client->errorValue = stuff->mode; 3337 return BadValue; 3338 } 3339 rc = dixSaveScreens(client, SCREEN_SAVER_FORCER, (int)stuff->mode); 3340 if (rc != Success) 3341 return rc; 3342 return client->noClientException; 3343} 3344 3345int ProcNoOperation(ClientPtr client) 3346{ 3347 REQUEST_AT_LEAST_SIZE(xReq); 3348 3349 /* noop -- don't do anything */ 3350 return(client->noClientException); 3351} 3352 3353void 3354InitProcVectors(void) 3355{ 3356 int i; 3357 for (i = 0; i<256; i++) 3358 { 3359 if(!ProcVector[i]) 3360 { 3361 ProcVector[i] = SwappedProcVector[i] = ProcBadRequest; 3362 ReplySwapVector[i] = ReplyNotSwappd; 3363 } 3364 } 3365 for(i = LASTEvent; i < 128; i++) 3366 { 3367 EventSwapVector[i] = NotImplemented; 3368 } 3369 3370} 3371 3372/********************** 3373 * CloseDownClient 3374 * 3375 * Client can either mark his resources destroy or retain. If retained and 3376 * then killed again, the client is really destroyed. 3377 *********************/ 3378 3379char dispatchExceptionAtReset = DE_RESET; 3380 3381void 3382CloseDownClient(ClientPtr client) 3383{ 3384 Bool really_close_down = client->clientGone || 3385 client->closeDownMode == DestroyAll; 3386 3387 if (!client->clientGone) 3388 { 3389 /* ungrab server if grabbing client dies */ 3390 if (grabState != GrabNone && grabClient == client) 3391 { 3392 UngrabServer(client); 3393 } 3394 BITCLEAR(grabWaiters, client->index); 3395 DeleteClientFromAnySelections(client); 3396 ReleaseActiveGrabs(client); 3397 DeleteClientFontStuff(client); 3398 if (!really_close_down) 3399 { 3400 /* This frees resources that should never be retained 3401 * no matter what the close down mode is. Actually we 3402 * could do this unconditionally, but it's probably 3403 * better not to traverse all the client's resources 3404 * twice (once here, once a few lines down in 3405 * FreeClientResources) in the common case of 3406 * really_close_down == TRUE. 3407 */ 3408 FreeClientNeverRetainResources(client); 3409 client->clientState = ClientStateRetained; 3410 if (ClientStateCallback) 3411 { 3412 NewClientInfoRec clientinfo; 3413 3414 clientinfo.client = client; 3415 clientinfo.prefix = (xConnSetupPrefix *)NULL; 3416 clientinfo.setup = (xConnSetup *) NULL; 3417 CallCallbacks((&ClientStateCallback), (pointer)&clientinfo); 3418 } 3419 } 3420 client->clientGone = TRUE; /* so events aren't sent to client */ 3421 if (ClientIsAsleep(client)) 3422 ClientSignal (client); 3423 ProcessWorkQueueZombies(); 3424 CloseDownConnection(client); 3425 3426 /* If the client made it to the Running stage, nClients has 3427 * been incremented on its behalf, so we need to decrement it 3428 * now. If it hasn't gotten to Running, nClients has *not* 3429 * been incremented, so *don't* decrement it. 3430 */ 3431 if (client->clientState != ClientStateInitial && 3432 client->clientState != ClientStateAuthenticating ) 3433 { 3434 --nClients; 3435 } 3436 } 3437 3438 if (really_close_down) 3439 { 3440 if (client->clientState == ClientStateRunning && nClients == 0) 3441 dispatchException |= dispatchExceptionAtReset; 3442 3443 client->clientState = ClientStateGone; 3444 if (ClientStateCallback) 3445 { 3446 NewClientInfoRec clientinfo; 3447 3448 clientinfo.client = client; 3449 clientinfo.prefix = (xConnSetupPrefix *)NULL; 3450 clientinfo.setup = (xConnSetup *) NULL; 3451 CallCallbacks((&ClientStateCallback), (pointer)&clientinfo); 3452 } 3453 FreeClientResources(client); 3454#ifdef XSERVER_DTRACE 3455 XSERVER_CLIENT_DISCONNECT(client->index); 3456#endif 3457 if (client->index < nextFreeClientID) 3458 nextFreeClientID = client->index; 3459 clients[client->index] = NullClient; 3460 SmartLastClient = NullClient; 3461 dixFreePrivates(client->devPrivates); 3462 xfree(client); 3463 3464 while (!clients[currentMaxClients-1]) 3465 currentMaxClients--; 3466 } 3467} 3468 3469static void 3470KillAllClients(void) 3471{ 3472 int i; 3473 for (i=1; i<currentMaxClients; i++) 3474 if (clients[i]) { 3475 /* Make sure Retained clients are released. */ 3476 clients[i]->closeDownMode = DestroyAll; 3477 CloseDownClient(clients[i]); 3478 } 3479} 3480 3481void InitClient(ClientPtr client, int i, pointer ospriv) 3482{ 3483 client->index = i; 3484 client->sequence = 0; 3485 client->clientAsMask = ((Mask)i) << CLIENTOFFSET; 3486 client->clientGone = FALSE; 3487 client->closeDownMode = i ? DestroyAll : RetainPermanent; 3488 client->numSaved = 0; 3489 client->saveSet = (SaveSetElt *)NULL; 3490 client->noClientException = Success; 3491#ifdef DEBUG 3492 client->requestLogIndex = 0; 3493#endif 3494 client->requestVector = InitialVector; 3495 client->osPrivate = ospriv; 3496 client->swapped = FALSE; 3497 client->big_requests = FALSE; 3498 client->priority = 0; 3499 client->clientState = ClientStateInitial; 3500 client->devPrivates = NULL; 3501#ifdef XKB 3502 if (!noXkbExtension) { 3503 client->xkbClientFlags = 0; 3504 client->mapNotifyMask = 0; 3505 client->newKeyboardNotifyMask = 0; 3506 client->vMinor = client->vMajor = 0; 3507 QueryMinMaxKeyCodes(&client->minKC,&client->maxKC); 3508 } 3509#endif 3510 client->replyBytesRemaining = 0; 3511 client->fontResFunc = NULL; 3512 client->smart_priority = 0; 3513 client->smart_start_tick = SmartScheduleTime; 3514 client->smart_stop_tick = SmartScheduleTime; 3515 client->smart_check_tick = SmartScheduleTime; 3516 3517 client->clientPtr = NULL; 3518} 3519 3520/************************ 3521 * int NextAvailableClient(ospriv) 3522 * 3523 * OS dependent portion can't assign client id's because of CloseDownModes. 3524 * Returns NULL if there are no free clients. 3525 *************************/ 3526 3527ClientPtr NextAvailableClient(pointer ospriv) 3528{ 3529 int i; 3530 ClientPtr client; 3531 xReq data; 3532 3533 i = nextFreeClientID; 3534 if (i == MAXCLIENTS) 3535 return (ClientPtr)NULL; 3536 clients[i] = client = (ClientPtr)xalloc(sizeof(ClientRec)); 3537 if (!client) 3538 return (ClientPtr)NULL; 3539 InitClient(client, i, ospriv); 3540 if (!InitClientResources(client)) 3541 { 3542 xfree(client); 3543 return (ClientPtr)NULL; 3544 } 3545 data.reqType = 1; 3546 data.length = (sz_xReq + sz_xConnClientPrefix) >> 2; 3547 if (!InsertFakeRequest(client, (char *)&data, sz_xReq)) 3548 { 3549 FreeClientResources(client); 3550 xfree(client); 3551 return (ClientPtr)NULL; 3552 } 3553 if (i == currentMaxClients) 3554 currentMaxClients++; 3555 while ((nextFreeClientID < MAXCLIENTS) && clients[nextFreeClientID]) 3556 nextFreeClientID++; 3557 if (ClientStateCallback) 3558 { 3559 NewClientInfoRec clientinfo; 3560 3561 clientinfo.client = client; 3562 clientinfo.prefix = (xConnSetupPrefix *)NULL; 3563 clientinfo.setup = (xConnSetup *) NULL; 3564 CallCallbacks((&ClientStateCallback), (pointer)&clientinfo); 3565 } 3566 return(client); 3567} 3568 3569int 3570ProcInitialConnection(ClientPtr client) 3571{ 3572 REQUEST(xReq); 3573 xConnClientPrefix *prefix; 3574 int whichbyte = 1; 3575 3576 prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq); 3577 if ((prefix->byteOrder != 'l') && (prefix->byteOrder != 'B')) 3578 return (client->noClientException = -1); 3579 if (((*(char *) &whichbyte) && (prefix->byteOrder == 'B')) || 3580 (!(*(char *) &whichbyte) && (prefix->byteOrder == 'l'))) 3581 { 3582 client->swapped = TRUE; 3583 SwapConnClientPrefix(prefix); 3584 } 3585 stuff->reqType = 2; 3586 stuff->length += ((prefix->nbytesAuthProto + (unsigned)3) >> 2) + 3587 ((prefix->nbytesAuthString + (unsigned)3) >> 2); 3588 if (client->swapped) 3589 { 3590 swaps(&stuff->length, whichbyte); 3591 } 3592 ResetCurrentRequest(client); 3593 return (client->noClientException); 3594} 3595 3596static int 3597SendConnSetup(ClientPtr client, char *reason) 3598{ 3599 xWindowRoot *root; 3600 int i; 3601 int numScreens; 3602 char* lConnectionInfo; 3603 xConnSetupPrefix* lconnSetupPrefix; 3604 3605 if (reason) 3606 { 3607 xConnSetupPrefix csp; 3608 3609 csp.success = xFalse; 3610 csp.lengthReason = strlen(reason); 3611 csp.length = (csp.lengthReason + (unsigned)3) >> 2; 3612 csp.majorVersion = X_PROTOCOL; 3613 csp.minorVersion = X_PROTOCOL_REVISION; 3614 if (client->swapped) 3615 WriteSConnSetupPrefix(client, &csp); 3616 else 3617 (void)WriteToClient(client, sz_xConnSetupPrefix, (char *) &csp); 3618 (void)WriteToClient(client, (int)csp.lengthReason, reason); 3619 return (client->noClientException = -1); 3620 } 3621 3622 numScreens = screenInfo.numScreens; 3623 lConnectionInfo = ConnectionInfo; 3624 lconnSetupPrefix = &connSetupPrefix; 3625 3626 /* We're about to start speaking X protocol back to the client by 3627 * sending the connection setup info. This means the authorization 3628 * step is complete, and we can count the client as an 3629 * authorized one. 3630 */ 3631 nClients++; 3632 3633 client->requestVector = client->swapped ? SwappedProcVector : ProcVector; 3634 client->sequence = 0; 3635 ((xConnSetup *)lConnectionInfo)->ridBase = client->clientAsMask; 3636 ((xConnSetup *)lConnectionInfo)->ridMask = RESOURCE_ID_MASK; 3637#ifdef MATCH_CLIENT_ENDIAN 3638 ((xConnSetup *)lConnectionInfo)->imageByteOrder = ClientOrder (client); 3639 ((xConnSetup *)lConnectionInfo)->bitmapBitOrder = ClientOrder (client); 3640#endif 3641 /* fill in the "currentInputMask" */ 3642 root = (xWindowRoot *)(lConnectionInfo + connBlockScreenStart); 3643#ifdef PANORAMIX 3644 if (noPanoramiXExtension) 3645 numScreens = screenInfo.numScreens; 3646 else 3647 numScreens = ((xConnSetup *)ConnectionInfo)->numRoots; 3648#endif 3649 3650 for (i=0; i<numScreens; i++) 3651 { 3652 unsigned int j; 3653 xDepth *pDepth; 3654 3655 root->currentInputMask = WindowTable[i]->eventMask | 3656 wOtherEventMasks (WindowTable[i]); 3657 pDepth = (xDepth *)(root + 1); 3658 for (j = 0; j < root->nDepths; j++) 3659 { 3660 pDepth = (xDepth *)(((char *)(pDepth + 1)) + 3661 pDepth->nVisuals * sizeof(xVisualType)); 3662 } 3663 root = (xWindowRoot *)pDepth; 3664 } 3665 3666 if (client->swapped) 3667 { 3668 WriteSConnSetupPrefix(client, lconnSetupPrefix); 3669 WriteSConnectionInfo(client, 3670 (unsigned long)(lconnSetupPrefix->length << 2), 3671 lConnectionInfo); 3672 } 3673 else 3674 { 3675 (void)WriteToClient(client, sizeof(xConnSetupPrefix), 3676 (char *) lconnSetupPrefix); 3677 (void)WriteToClient(client, (int)(lconnSetupPrefix->length << 2), 3678 lConnectionInfo); 3679 } 3680 client->clientState = ClientStateRunning; 3681 if (ClientStateCallback) 3682 { 3683 NewClientInfoRec clientinfo; 3684 3685 clientinfo.client = client; 3686 clientinfo.prefix = lconnSetupPrefix; 3687 clientinfo.setup = (xConnSetup *)lConnectionInfo; 3688 CallCallbacks((&ClientStateCallback), (pointer)&clientinfo); 3689 } 3690 return (client->noClientException); 3691} 3692 3693int 3694ProcEstablishConnection(ClientPtr client) 3695{ 3696 char *reason, *auth_proto, *auth_string; 3697 xConnClientPrefix *prefix; 3698 REQUEST(xReq); 3699 3700 prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq); 3701 auth_proto = (char *)prefix + sz_xConnClientPrefix; 3702 auth_string = auth_proto + ((prefix->nbytesAuthProto + 3) & ~3); 3703 if ((prefix->majorVersion != X_PROTOCOL) || 3704 (prefix->minorVersion != X_PROTOCOL_REVISION)) 3705 reason = "Protocol version mismatch"; 3706 else 3707 reason = ClientAuthorized(client, 3708 (unsigned short)prefix->nbytesAuthProto, 3709 auth_proto, 3710 (unsigned short)prefix->nbytesAuthString, 3711 auth_string); 3712 /* 3713 * If Kerberos is being used for this client, the clientState 3714 * will be set to ClientStateAuthenticating at this point. 3715 * More messages need to be exchanged among the X server, Kerberos 3716 * server, and client to figure out if everyone is authorized. 3717 * So we don't want to send the connection setup info yet, since 3718 * the auth step isn't really done. 3719 */ 3720 if (client->clientState == ClientStateCheckingSecurity) 3721 client->clientState = ClientStateCheckedSecurity; 3722 else if (client->clientState != ClientStateAuthenticating) 3723 return(SendConnSetup(client, reason)); 3724 return(client->noClientException); 3725} 3726 3727_X_EXPORT void 3728SendErrorToClient(ClientPtr client, unsigned majorCode, unsigned minorCode, 3729 XID resId, int errorCode) 3730{ 3731 xError rep; 3732 3733 rep.type = X_Error; 3734 rep.sequenceNumber = client->sequence; 3735 rep.errorCode = errorCode; 3736 rep.majorCode = majorCode; 3737 rep.minorCode = minorCode; 3738 rep.resourceID = resId; 3739 3740 WriteEventsToClient (client, 1, (xEvent *)&rep); 3741} 3742 3743void 3744MarkClientException(ClientPtr client) 3745{ 3746 client->noClientException = -1; 3747} 3748