saver.c revision 9ace9065
1/* 2 * 3Copyright (c) 1992 X Consortium 4 5Permission is hereby granted, free of charge, to any person obtaining a copy 6of this software and associated documentation files (the "Software"), to deal 7in the Software without restriction, including without limitation the rights 8to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9copies of the Software, and to permit persons to whom the Software is 10furnished to do so, subject to the following conditions: 11 12The above copyright notice and this permission notice shall be included in 13all copies or substantial portions of the Software. 14 15THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN 19AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 22Except as contained in this notice, the name of the X Consortium shall not be 23used in advertising or otherwise to promote the sale, use or other dealings 24in this Software without prior written authorization from the X Consortium. 25 * 26 * Author: Keith Packard, MIT X Consortium 27 */ 28 29 30#ifdef HAVE_DIX_CONFIG_H 31#include <dix-config.h> 32#endif 33 34#include <X11/X.h> 35#include <X11/Xproto.h> 36#include "misc.h" 37#include "os.h" 38#include "windowstr.h" 39#include "scrnintstr.h" 40#include "pixmapstr.h" 41#include "extnsionst.h" 42#include "dixstruct.h" 43#include "resource.h" 44#include "opaque.h" 45#include <X11/extensions/saverproto.h> 46#include "gcstruct.h" 47#include "cursorstr.h" 48#include "colormapst.h" 49#include "xace.h" 50#ifdef PANORAMIX 51#include "panoramiX.h" 52#include "panoramiXsrv.h" 53#endif 54#ifdef DPMSExtension 55#include <X11/extensions/dpmsconst.h> 56#endif 57#include "protocol-versions.h" 58 59#include <stdio.h> 60 61#include "modinit.h" 62 63static int ScreenSaverEventBase = 0; 64 65 66static Bool ScreenSaverHandle ( 67 ScreenPtr /* pScreen */, 68 int /* xstate */, 69 Bool /* force */ 70 ); 71 72static Bool 73CreateSaverWindow ( 74 ScreenPtr /* pScreen */ 75 ); 76 77static Bool 78DestroySaverWindow ( 79 ScreenPtr /* pScreen */ 80 ); 81 82static void 83UninstallSaverColormap ( 84 ScreenPtr /* pScreen */ 85 ); 86 87static void 88CheckScreenPrivate ( 89 ScreenPtr /* pScreen */ 90 ); 91 92static void SScreenSaverNotifyEvent ( 93 xScreenSaverNotifyEvent * /* from */, 94 xScreenSaverNotifyEvent * /* to */ 95 ); 96 97static RESTYPE SuspendType; /* resource type for suspension records */ 98 99typedef struct _ScreenSaverSuspension *ScreenSaverSuspensionPtr; 100 101/* List of clients that are suspending the screensaver. */ 102static ScreenSaverSuspensionPtr suspendingClients = NULL; 103 104/* 105 * clientResource is a resource ID that's added when the record is 106 * allocated, so the record is freed and the screensaver resumed when 107 * the client disconnects. count is the number of times the client has 108 * requested the screensaver be suspended. 109 */ 110typedef struct _ScreenSaverSuspension 111{ 112 ScreenSaverSuspensionPtr next; 113 ClientPtr pClient; 114 XID clientResource; 115 int count; 116} ScreenSaverSuspensionRec; 117 118static int ScreenSaverFreeSuspend( 119 pointer /*value */, 120 XID /* id */ 121); 122 123/* 124 * each screen has a list of clients requesting 125 * ScreenSaverNotify events. Each client has a resource 126 * for each screen it selects ScreenSaverNotify input for, 127 * this resource is used to delete the ScreenSaverNotifyRec 128 * entry from the per-screen queue. 129 */ 130 131static RESTYPE SaverEventType; /* resource type for event masks */ 132 133typedef struct _ScreenSaverEvent *ScreenSaverEventPtr; 134 135typedef struct _ScreenSaverEvent { 136 ScreenSaverEventPtr next; 137 ClientPtr client; 138 ScreenPtr screen; 139 XID resource; 140 CARD32 mask; 141} ScreenSaverEventRec; 142 143static int ScreenSaverFreeEvents( 144 pointer /* value */, 145 XID /* id */ 146); 147 148static Bool setEventMask ( 149 ScreenPtr /* pScreen */, 150 ClientPtr /* client */, 151 unsigned long /* mask */ 152); 153 154static unsigned long getEventMask ( 155 ScreenPtr /* pScreen */, 156 ClientPtr /* client */ 157); 158 159/* 160 * when a client sets the screen saver attributes, a resource is 161 * kept to be freed when the client exits 162 */ 163 164static RESTYPE AttrType; /* resource type for attributes */ 165 166typedef struct _ScreenSaverAttr { 167 ScreenPtr screen; 168 ClientPtr client; 169 XID resource; 170 short x, y; 171 unsigned short width, height, borderWidth; 172 unsigned char class; 173 unsigned char depth; 174 VisualID visual; 175 CursorPtr pCursor; 176 PixmapPtr pBackgroundPixmap; 177 PixmapPtr pBorderPixmap; 178 Colormap colormap; 179 unsigned long mask; /* no pixmaps or cursors */ 180 unsigned long *values; 181} ScreenSaverAttrRec, *ScreenSaverAttrPtr; 182 183static int ScreenSaverFreeAttr ( 184 pointer /* value */, 185 XID /* id */ 186); 187 188static void FreeAttrs ( 189 ScreenSaverAttrPtr /* pAttr */ 190); 191 192static void FreeScreenAttr ( 193 ScreenSaverAttrPtr /* pAttr */ 194); 195 196static void 197SendScreenSaverNotify ( 198 ScreenPtr /* pScreen */, 199 int /* state */, 200 Bool /* forced */ 201); 202 203typedef struct _ScreenSaverScreenPrivate { 204 ScreenSaverEventPtr events; 205 ScreenSaverAttrPtr attr; 206 Bool hasWindow; 207 Colormap installedMap; 208} ScreenSaverScreenPrivateRec, *ScreenSaverScreenPrivatePtr; 209 210static ScreenSaverScreenPrivatePtr 211MakeScreenPrivate ( 212 ScreenPtr /* pScreen */ 213 ); 214 215static DevPrivateKeyRec ScreenPrivateKeyRec; 216#define ScreenPrivateKey (&ScreenPrivateKeyRec) 217 218#define GetScreenPrivate(s) ((ScreenSaverScreenPrivatePtr) \ 219 dixLookupPrivate(&(s)->devPrivates, ScreenPrivateKey)) 220#define SetScreenPrivate(s,v) \ 221 dixSetPrivate(&(s)->devPrivates, ScreenPrivateKey, v); 222#define SetupScreen(s) ScreenSaverScreenPrivatePtr pPriv = (s ? GetScreenPrivate(s) : NULL) 223 224#define New(t) (malloc(sizeof (t))) 225 226static void 227CheckScreenPrivate (ScreenPtr pScreen) 228{ 229 SetupScreen (pScreen); 230 231 if (!pPriv) 232 return; 233 if (!pPriv->attr && !pPriv->events && 234 !pPriv->hasWindow && pPriv->installedMap == None) 235 { 236 free(pPriv); 237 SetScreenPrivate (pScreen, NULL); 238 pScreen->screensaver.ExternalScreenSaver = NULL; 239 } 240} 241 242static ScreenSaverScreenPrivatePtr 243MakeScreenPrivate (ScreenPtr pScreen) 244{ 245 SetupScreen (pScreen); 246 247 if (pPriv) 248 return pPriv; 249 pPriv = New (ScreenSaverScreenPrivateRec); 250 if (!pPriv) 251 return 0; 252 pPriv->events = 0; 253 pPriv->attr = 0; 254 pPriv->hasWindow = FALSE; 255 pPriv->installedMap = None; 256 SetScreenPrivate (pScreen, pPriv); 257 pScreen->screensaver.ExternalScreenSaver = ScreenSaverHandle; 258 return pPriv; 259} 260 261static unsigned long 262getEventMask (ScreenPtr pScreen, ClientPtr client) 263{ 264 SetupScreen(pScreen); 265 ScreenSaverEventPtr pEv; 266 267 if (!pPriv) 268 return 0; 269 for (pEv = pPriv->events; pEv; pEv = pEv->next) 270 if (pEv->client == client) 271 return pEv->mask; 272 return 0; 273} 274 275static Bool 276setEventMask (ScreenPtr pScreen, ClientPtr client, unsigned long mask) 277{ 278 SetupScreen(pScreen); 279 ScreenSaverEventPtr pEv, *pPrev; 280 281 if (getEventMask (pScreen, client) == mask) 282 return TRUE; 283 if (!pPriv) 284 { 285 pPriv = MakeScreenPrivate (pScreen); 286 if (!pPriv) 287 return FALSE; 288 } 289 for (pPrev = &pPriv->events; (pEv = *pPrev) != 0; pPrev = &pEv->next) 290 if (pEv->client == client) 291 break; 292 if (mask == 0) 293 { 294 FreeResource (pEv->resource, SaverEventType); 295 *pPrev = pEv->next; 296 free(pEv); 297 CheckScreenPrivate (pScreen); 298 } 299 else 300 { 301 if (!pEv) 302 { 303 pEv = New (ScreenSaverEventRec); 304 if (!pEv) 305 { 306 CheckScreenPrivate (pScreen); 307 return FALSE; 308 } 309 *pPrev = pEv; 310 pEv->next = NULL; 311 pEv->client = client; 312 pEv->screen = pScreen; 313 pEv->resource = FakeClientID (client->index); 314 if (!AddResource (pEv->resource, SaverEventType, (pointer) pEv)) 315 return FALSE; 316 } 317 pEv->mask = mask; 318 } 319 return TRUE; 320} 321 322static void 323FreeAttrs (ScreenSaverAttrPtr pAttr) 324{ 325 PixmapPtr pPixmap; 326 CursorPtr pCursor; 327 328 if ((pPixmap = pAttr->pBackgroundPixmap) != 0) 329 (*pPixmap->drawable.pScreen->DestroyPixmap)(pPixmap); 330 if ((pPixmap = pAttr->pBorderPixmap) != 0) 331 (*pPixmap->drawable.pScreen->DestroyPixmap)(pPixmap); 332 if ((pCursor = pAttr->pCursor) != 0) 333 FreeCursor (pCursor, (Cursor) 0); 334} 335 336static void 337FreeScreenAttr (ScreenSaverAttrPtr pAttr) 338{ 339 FreeAttrs (pAttr); 340 free(pAttr->values); 341 free(pAttr); 342} 343 344static int 345ScreenSaverFreeEvents (pointer value, XID id) 346{ 347 ScreenSaverEventPtr pOld = (ScreenSaverEventPtr)value; 348 ScreenPtr pScreen = pOld->screen; 349 SetupScreen (pScreen); 350 ScreenSaverEventPtr pEv, *pPrev; 351 352 if (!pPriv) 353 return TRUE; 354 for (pPrev = &pPriv->events; (pEv = *pPrev) != 0; pPrev = &pEv->next) 355 if (pEv == pOld) 356 break; 357 if (!pEv) 358 return TRUE; 359 *pPrev = pEv->next; 360 free(pEv); 361 CheckScreenPrivate (pScreen); 362 return TRUE; 363} 364 365static int 366ScreenSaverFreeAttr (pointer value, XID id) 367{ 368 ScreenSaverAttrPtr pOldAttr = (ScreenSaverAttrPtr)value; 369 ScreenPtr pScreen = pOldAttr->screen; 370 SetupScreen (pScreen); 371 372 if (!pPriv) 373 return TRUE; 374 if (pPriv->attr != pOldAttr) 375 return TRUE; 376 FreeScreenAttr (pOldAttr); 377 pPriv->attr = NULL; 378 if (pPriv->hasWindow) 379 { 380 dixSaveScreens (serverClient, SCREEN_SAVER_FORCER, ScreenSaverReset); 381 dixSaveScreens (serverClient, SCREEN_SAVER_FORCER, ScreenSaverActive); 382 } 383 CheckScreenPrivate (pScreen); 384 return TRUE; 385} 386 387static int 388ScreenSaverFreeSuspend (pointer value, XID id) 389{ 390 ScreenSaverSuspensionPtr data = (ScreenSaverSuspensionPtr) value; 391 ScreenSaverSuspensionPtr *prev, this; 392 393 /* Unlink and free the suspension record for the client */ 394 for (prev = &suspendingClients; (this = *prev); prev = &this->next) 395 { 396 if (this == data) 397 { 398 *prev = this->next; 399 free(this); 400 break; 401 } 402 } 403 404 /* Reenable the screensaver if this was the last client suspending it. */ 405 if (screenSaverSuspended && suspendingClients == NULL) 406 { 407 screenSaverSuspended = FALSE; 408 409 /* The screensaver could be active, since suspending it (by design) 410 doesn't prevent it from being forceably activated */ 411#ifdef DPMSExtension 412 if (screenIsSaved != SCREEN_SAVER_ON && DPMSPowerLevel == DPMSModeOn) 413#else 414 if (screenIsSaved != SCREEN_SAVER_ON) 415#endif 416 { 417 UpdateCurrentTimeIf(); 418 lastDeviceEventTime = currentTime; 419 SetScreenSaverTimer(); 420 } 421 } 422 423 return Success; 424} 425 426static void 427SendScreenSaverNotify (ScreenPtr pScreen, int state, Bool forced) 428{ 429 ScreenSaverScreenPrivatePtr pPriv; 430 ScreenSaverEventPtr pEv; 431 unsigned long mask; 432 xScreenSaverNotifyEvent ev; 433 int kind; 434 435 UpdateCurrentTimeIf (); 436 mask = ScreenSaverNotifyMask; 437 if (state == ScreenSaverCycle) 438 mask = ScreenSaverCycleMask; 439 pScreen = screenInfo.screens[pScreen->myNum]; 440 pPriv = GetScreenPrivate(pScreen); 441 if (!pPriv) 442 return; 443 if (pPriv->attr) 444 kind = ScreenSaverExternal; 445 else if (ScreenSaverBlanking != DontPreferBlanking) 446 kind = ScreenSaverBlanked; 447 else 448 kind = ScreenSaverInternal; 449 for (pEv = pPriv->events; pEv; pEv = pEv->next) 450 { 451 if (!(pEv->mask & mask)) 452 continue; 453 ev.type = ScreenSaverNotify + ScreenSaverEventBase; 454 ev.state = state; 455 ev.timestamp = currentTime.milliseconds; 456 ev.root = pScreen->root->drawable.id; 457 ev.window = pScreen->screensaver.wid; 458 ev.kind = kind; 459 ev.forced = forced; 460 WriteEventsToClient (pEv->client, 1, (xEvent *) &ev); 461 } 462} 463 464static void 465SScreenSaverNotifyEvent (xScreenSaverNotifyEvent *from, 466 xScreenSaverNotifyEvent *to) 467{ 468 to->type = from->type; 469 to->state = from->state; 470 cpswaps (from->sequenceNumber, to->sequenceNumber); 471 cpswapl (from->timestamp, to->timestamp); 472 cpswapl (from->root, to->root); 473 cpswapl (from->window, to->window); 474 to->kind = from->kind; 475 to->forced = from->forced; 476} 477 478static void 479UninstallSaverColormap (ScreenPtr pScreen) 480{ 481 SetupScreen(pScreen); 482 ColormapPtr pCmap; 483 int rc; 484 485 if (pPriv && pPriv->installedMap != None) 486 { 487 rc = dixLookupResourceByType((pointer *)&pCmap, pPriv->installedMap, 488 RT_COLORMAP, serverClient, 489 DixUninstallAccess); 490 if (rc == Success) 491 (*pCmap->pScreen->UninstallColormap) (pCmap); 492 pPriv->installedMap = None; 493 CheckScreenPrivate (pScreen); 494 } 495} 496 497static Bool 498CreateSaverWindow (ScreenPtr pScreen) 499{ 500 SetupScreen (pScreen); 501 ScreenSaverStuffPtr pSaver; 502 ScreenSaverAttrPtr pAttr; 503 WindowPtr pWin; 504 int result; 505 unsigned long mask; 506 Colormap *installedMaps; 507 int numInstalled; 508 int i; 509 Colormap wantMap; 510 ColormapPtr pCmap; 511 512 pSaver = &pScreen->screensaver; 513 if (pSaver->pWindow) 514 { 515 pSaver->pWindow = NullWindow; 516 FreeResource (pSaver->wid, RT_NONE); 517 if (pPriv) 518 { 519 UninstallSaverColormap (pScreen); 520 pPriv->hasWindow = FALSE; 521 CheckScreenPrivate (pScreen); 522 } 523 } 524 525 if (!pPriv || !(pAttr = pPriv->attr)) 526 return FALSE; 527 528 pPriv->installedMap = None; 529 530 if (GrabInProgress && GrabInProgress != pAttr->client->index) 531 return FALSE; 532 533 pWin = CreateWindow (pSaver->wid, pScreen->root, 534 pAttr->x, pAttr->y, pAttr->width, pAttr->height, 535 pAttr->borderWidth, pAttr->class, 536 pAttr->mask, (XID *)pAttr->values, 537 pAttr->depth, serverClient, pAttr->visual, 538 &result); 539 if (!pWin) 540 return FALSE; 541 542 if (!AddResource(pWin->drawable.id, RT_WINDOW, pWin)) 543 return FALSE; 544 545 mask = 0; 546 if (pAttr->pBackgroundPixmap) 547 { 548 pWin->backgroundState = BackgroundPixmap; 549 pWin->background.pixmap = pAttr->pBackgroundPixmap; 550 pAttr->pBackgroundPixmap->refcnt++; 551 mask |= CWBackPixmap; 552 } 553 if (pAttr->pBorderPixmap) 554 { 555 pWin->borderIsPixel = FALSE; 556 pWin->border.pixmap = pAttr->pBorderPixmap; 557 pAttr->pBorderPixmap->refcnt++; 558 mask |= CWBorderPixmap; 559 } 560 if (pAttr->pCursor) 561 { 562 if (!pWin->optional) 563 if (!MakeWindowOptional (pWin)) 564 { 565 FreeResource (pWin->drawable.id, RT_NONE); 566 return FALSE; 567 } 568 pAttr->pCursor->refcnt++; 569 if (pWin->optional->cursor) 570 FreeCursor (pWin->optional->cursor, (Cursor)0); 571 pWin->optional->cursor = pAttr->pCursor; 572 pWin->cursorIsNone = FALSE; 573 CheckWindowOptionalNeed (pWin); 574 mask |= CWCursor; 575 } 576 if (mask) 577 (*pScreen->ChangeWindowAttributes) (pWin, mask); 578 579 if (pAttr->colormap != None) 580 (void) ChangeWindowAttributes (pWin, CWColormap, &pAttr->colormap, 581 serverClient); 582 583 MapWindow (pWin, serverClient); 584 585 pPriv->hasWindow = TRUE; 586 pSaver->pWindow = pWin; 587 588 /* check and install our own colormap if it isn't installed now */ 589 wantMap = wColormap (pWin); 590 if (wantMap == None) 591 return TRUE; 592 installedMaps = malloc(pScreen->maxInstalledCmaps * sizeof (Colormap)); 593 numInstalled = (*pWin->drawable.pScreen->ListInstalledColormaps) 594 (pScreen, installedMaps); 595 for (i = 0; i < numInstalled; i++) 596 if (installedMaps[i] == wantMap) 597 break; 598 599 free((char *) installedMaps); 600 601 if (i < numInstalled) 602 return TRUE; 603 604 result = dixLookupResourceByType((pointer *)&pCmap, wantMap, RT_COLORMAP, 605 serverClient, DixInstallAccess); 606 if (result != Success) 607 return TRUE; 608 609 pPriv->installedMap = wantMap; 610 611 (*pCmap->pScreen->InstallColormap) (pCmap); 612 613 return TRUE; 614} 615 616static Bool 617DestroySaverWindow (ScreenPtr pScreen) 618{ 619 SetupScreen(pScreen); 620 ScreenSaverStuffPtr pSaver; 621 622 if (!pPriv || !pPriv->hasWindow) 623 return FALSE; 624 625 pSaver = &pScreen->screensaver; 626 if (pSaver->pWindow) 627 { 628 pSaver->pWindow = NullWindow; 629 FreeResource (pSaver->wid, RT_NONE); 630 } 631 pPriv->hasWindow = FALSE; 632 CheckScreenPrivate (pScreen); 633 UninstallSaverColormap (pScreen); 634 return TRUE; 635} 636 637static Bool 638ScreenSaverHandle (ScreenPtr pScreen, int xstate, Bool force) 639{ 640 int state = 0; 641 Bool ret = FALSE; 642 ScreenSaverScreenPrivatePtr pPriv; 643 644 switch (xstate) 645 { 646 case SCREEN_SAVER_ON: 647 state = ScreenSaverOn; 648 ret = CreateSaverWindow (pScreen); 649 break; 650 case SCREEN_SAVER_OFF: 651 state = ScreenSaverOff; 652 ret = DestroySaverWindow (pScreen); 653 break; 654 case SCREEN_SAVER_CYCLE: 655 state = ScreenSaverCycle; 656 pPriv = GetScreenPrivate (pScreen); 657 if (pPriv && pPriv->hasWindow) 658 ret = TRUE; 659 660 } 661#ifdef PANORAMIX 662 if(noPanoramiXExtension || !pScreen->myNum) 663#endif 664 SendScreenSaverNotify (pScreen, state, force); 665 return ret; 666} 667 668static int 669ProcScreenSaverQueryVersion (ClientPtr client) 670{ 671 xScreenSaverQueryVersionReply rep; 672 int n; 673 674 REQUEST_SIZE_MATCH (xScreenSaverQueryVersionReq); 675 rep.type = X_Reply; 676 rep.length = 0; 677 rep.sequenceNumber = client->sequence; 678 rep.majorVersion = SERVER_SAVER_MAJOR_VERSION; 679 rep.minorVersion = SERVER_SAVER_MINOR_VERSION; 680 if (client->swapped) { 681 swaps(&rep.sequenceNumber, n); 682 swapl(&rep.length, n); 683 } 684 WriteToClient(client, sizeof (xScreenSaverQueryVersionReply), (char *)&rep); 685 return Success; 686} 687 688static int 689ProcScreenSaverQueryInfo (ClientPtr client) 690{ 691 REQUEST(xScreenSaverQueryInfoReq); 692 xScreenSaverQueryInfoReply rep; 693 int n, rc; 694 ScreenSaverStuffPtr pSaver; 695 DrawablePtr pDraw; 696 CARD32 lastInput; 697 ScreenSaverScreenPrivatePtr pPriv; 698 699 REQUEST_SIZE_MATCH (xScreenSaverQueryInfoReq); 700 rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, 701 DixGetAttrAccess); 702 if (rc != Success) 703 return rc; 704 rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, pDraw->pScreen, 705 DixGetAttrAccess); 706 if (rc != Success) 707 return rc; 708 709 pSaver = &pDraw->pScreen->screensaver; 710 pPriv = GetScreenPrivate (pDraw->pScreen); 711 712 UpdateCurrentTime (); 713 lastInput = GetTimeInMillis() - lastDeviceEventTime.milliseconds; 714 715 rep.type = X_Reply; 716 rep.length = 0; 717 rep.sequenceNumber = client->sequence; 718 rep.window = pSaver->wid; 719 if (screenIsSaved != SCREEN_SAVER_OFF) 720 { 721 rep.state = ScreenSaverOn; 722 if (ScreenSaverTime) 723 rep.tilOrSince = lastInput - ScreenSaverTime; 724 else 725 rep.tilOrSince = 0; 726 } 727 else 728 { 729 if (ScreenSaverTime) 730 { 731 rep.state = ScreenSaverOff; 732 if (ScreenSaverTime < lastInput) 733 rep.tilOrSince = 0; 734 else 735 rep.tilOrSince = ScreenSaverTime - lastInput; 736 } 737 else 738 { 739 rep.state = ScreenSaverDisabled; 740 rep.tilOrSince = 0; 741 } 742 } 743 rep.idle = lastInput; 744 rep.eventMask = getEventMask (pDraw->pScreen, client); 745 if (pPriv && pPriv->attr) 746 rep.kind = ScreenSaverExternal; 747 else if (ScreenSaverBlanking != DontPreferBlanking) 748 rep.kind = ScreenSaverBlanked; 749 else 750 rep.kind = ScreenSaverInternal; 751 if (client->swapped) 752 { 753 swaps (&rep.sequenceNumber, n); 754 swapl (&rep.length, n); 755 swapl (&rep.window, n); 756 swapl (&rep.tilOrSince, n); 757 swapl (&rep.idle, n); 758 swapl (&rep.eventMask, n); 759 } 760 WriteToClient(client, sizeof (xScreenSaverQueryInfoReply), (char *)&rep); 761 return Success; 762} 763 764static int 765ProcScreenSaverSelectInput (ClientPtr client) 766{ 767 REQUEST(xScreenSaverSelectInputReq); 768 DrawablePtr pDraw; 769 int rc; 770 771 REQUEST_SIZE_MATCH (xScreenSaverSelectInputReq); 772 rc = dixLookupDrawable (&pDraw, stuff->drawable, client, 0, 773 DixGetAttrAccess); 774 if (rc != Success) 775 return rc; 776 777 rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, pDraw->pScreen, 778 DixSetAttrAccess); 779 if (rc != Success) 780 return rc; 781 782 if (!setEventMask (pDraw->pScreen, client, stuff->eventMask)) 783 return BadAlloc; 784 return Success; 785} 786 787static int 788ScreenSaverSetAttributes (ClientPtr client) 789{ 790 REQUEST(xScreenSaverSetAttributesReq); 791 DrawablePtr pDraw; 792 WindowPtr pParent; 793 ScreenPtr pScreen; 794 ScreenSaverScreenPrivatePtr pPriv = 0; 795 ScreenSaverAttrPtr pAttr = 0; 796 int ret, len, class, bw, depth; 797 unsigned long visual; 798 int idepth, ivisual; 799 Bool fOK; 800 DepthPtr pDepth; 801 WindowOptPtr ancwopt; 802 unsigned int *pVlist; 803 unsigned long *values = 0; 804 unsigned long tmask, imask; 805 unsigned long val; 806 Pixmap pixID; 807 PixmapPtr pPixmap; 808 Cursor cursorID; 809 CursorPtr pCursor; 810 Colormap cmap; 811 ColormapPtr pCmap; 812 813 REQUEST_AT_LEAST_SIZE (xScreenSaverSetAttributesReq); 814 ret = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, 815 DixGetAttrAccess); 816 if (ret != Success) 817 return ret; 818 pScreen = pDraw->pScreen; 819 pParent = pScreen->root; 820 821 ret = XaceHook(XACE_SCREENSAVER_ACCESS, client, pScreen, DixSetAttrAccess); 822 if (ret != Success) 823 return ret; 824 825 len = stuff->length - bytes_to_int32(sizeof(xScreenSaverSetAttributesReq)); 826 if (Ones(stuff->mask) != len) 827 return BadLength; 828 if (!stuff->width || !stuff->height) 829 { 830 client->errorValue = 0; 831 return BadValue; 832 } 833 switch (class = stuff->c_class) 834 { 835 case CopyFromParent: 836 case InputOnly: 837 case InputOutput: 838 break; 839 default: 840 client->errorValue = class; 841 return BadValue; 842 } 843 bw = stuff->borderWidth; 844 depth = stuff->depth; 845 visual = stuff->visualID; 846 847 /* copied directly from CreateWindow */ 848 849 if (class == CopyFromParent) 850 class = pParent->drawable.class; 851 852 if ((class != InputOutput) && (class != InputOnly)) 853 { 854 client->errorValue = class; 855 return BadValue; 856 } 857 858 if ((class != InputOnly) && (pParent->drawable.class == InputOnly)) 859 return BadMatch; 860 861 if ((class == InputOnly) && ((bw != 0) || (depth != 0))) 862 return BadMatch; 863 864 if ((class == InputOutput) && (depth == 0)) 865 depth = pParent->drawable.depth; 866 ancwopt = pParent->optional; 867 if (!ancwopt) 868 ancwopt = FindWindowWithOptional(pParent)->optional; 869 if (visual == CopyFromParent) 870 visual = ancwopt->visual; 871 872 /* Find out if the depth and visual are acceptable for this Screen */ 873 if ((visual != ancwopt->visual) || (depth != pParent->drawable.depth)) 874 { 875 fOK = FALSE; 876 for(idepth = 0; idepth < pScreen->numDepths; idepth++) 877 { 878 pDepth = (DepthPtr) &pScreen->allowedDepths[idepth]; 879 if ((depth == pDepth->depth) || (depth == 0)) 880 { 881 for (ivisual = 0; ivisual < pDepth->numVids; ivisual++) 882 { 883 if (visual == pDepth->vids[ivisual]) 884 { 885 fOK = TRUE; 886 break; 887 } 888 } 889 } 890 } 891 if (fOK == FALSE) 892 return BadMatch; 893 } 894 895 if (((stuff->mask & (CWBorderPixmap | CWBorderPixel)) == 0) && 896 (class != InputOnly) && 897 (depth != pParent->drawable.depth)) 898 { 899 return BadMatch; 900 } 901 902 if (((stuff->mask & CWColormap) == 0) && 903 (class != InputOnly) && 904 ((visual != ancwopt->visual) || (ancwopt->colormap == None))) 905 { 906 return BadMatch; 907 } 908 909 /* end of errors from CreateWindow */ 910 911 pPriv = GetScreenPrivate (pScreen); 912 if (pPriv && pPriv->attr) 913 { 914 if (pPriv->attr->client != client) 915 return BadAccess; 916 } 917 if (!pPriv) 918 { 919 pPriv = MakeScreenPrivate (pScreen); 920 if (!pPriv) 921 return FALSE; 922 } 923 pAttr = New (ScreenSaverAttrRec); 924 if (!pAttr) 925 { 926 ret = BadAlloc; 927 goto bail; 928 } 929 /* over allocate for override redirect */ 930 values = malloc((len + 1) * sizeof (unsigned long)); 931 if (!values) 932 { 933 ret = BadAlloc; 934 goto bail; 935 } 936 pAttr->screen = pScreen; 937 pAttr->client = client; 938 pAttr->x = stuff->x; 939 pAttr->y = stuff->y; 940 pAttr->width = stuff->width; 941 pAttr->height = stuff->height; 942 pAttr->borderWidth = stuff->borderWidth; 943 pAttr->class = stuff->c_class; 944 pAttr->depth = depth; 945 pAttr->visual = visual; 946 pAttr->colormap = None; 947 pAttr->pCursor = NullCursor; 948 pAttr->pBackgroundPixmap = NullPixmap; 949 pAttr->pBorderPixmap = NullPixmap; 950 pAttr->values = values; 951 /* 952 * go through the mask, checking the values, 953 * looking up pixmaps and cursors and hold a reference 954 * to them. 955 */ 956 pAttr->mask = tmask = stuff->mask | CWOverrideRedirect; 957 pVlist = (unsigned int *) (stuff + 1); 958 while (tmask) { 959 imask = lowbit (tmask); 960 tmask &= ~imask; 961 switch (imask) 962 { 963 case CWBackPixmap: 964 pixID = (Pixmap )*pVlist; 965 if (pixID == None) 966 { 967 *values++ = None; 968 } 969 else if (pixID == ParentRelative) 970 { 971 if (depth != pParent->drawable.depth) 972 { 973 ret = BadMatch; 974 goto PatchUp; 975 } 976 *values++ = ParentRelative; 977 } 978 else 979 { 980 ret = dixLookupResourceByType((pointer *)&pPixmap, pixID, RT_PIXMAP, 981 client, DixReadAccess); 982 if (ret == Success) 983 { 984 if ((pPixmap->drawable.depth != depth) || 985 (pPixmap->drawable.pScreen != pScreen)) 986 { 987 ret = BadMatch; 988 goto PatchUp; 989 } 990 pAttr->pBackgroundPixmap = pPixmap; 991 pPixmap->refcnt++; 992 pAttr->mask &= ~CWBackPixmap; 993 } 994 else 995 { 996 client->errorValue = pixID; 997 goto PatchUp; 998 } 999 } 1000 break; 1001 case CWBackPixel: 1002 *values++ = (CARD32) *pVlist; 1003 break; 1004 case CWBorderPixmap: 1005 pixID = (Pixmap ) *pVlist; 1006 if (pixID == CopyFromParent) 1007 { 1008 if (depth != pParent->drawable.depth) 1009 { 1010 ret = BadMatch; 1011 goto PatchUp; 1012 } 1013 *values++ = CopyFromParent; 1014 } 1015 else 1016 { 1017 ret = dixLookupResourceByType((pointer *)&pPixmap, pixID, RT_PIXMAP, 1018 client, DixReadAccess); 1019 if (ret == Success) 1020 { 1021 if ((pPixmap->drawable.depth != depth) || 1022 (pPixmap->drawable.pScreen != pScreen)) 1023 { 1024 ret = BadMatch; 1025 goto PatchUp; 1026 } 1027 pAttr->pBorderPixmap = pPixmap; 1028 pPixmap->refcnt++; 1029 pAttr->mask &= ~CWBorderPixmap; 1030 } 1031 else 1032 { 1033 client->errorValue = pixID; 1034 goto PatchUp; 1035 } 1036 } 1037 break; 1038 case CWBorderPixel: 1039 *values++ = (CARD32) *pVlist; 1040 break; 1041 case CWBitGravity: 1042 val = (CARD8 )*pVlist; 1043 if (val > StaticGravity) 1044 { 1045 ret = BadValue; 1046 client->errorValue = val; 1047 goto PatchUp; 1048 } 1049 *values++ = val; 1050 break; 1051 case CWWinGravity: 1052 val = (CARD8 )*pVlist; 1053 if (val > StaticGravity) 1054 { 1055 ret = BadValue; 1056 client->errorValue = val; 1057 goto PatchUp; 1058 } 1059 *values++ = val; 1060 break; 1061 case CWBackingStore: 1062 val = (CARD8 )*pVlist; 1063 if ((val != NotUseful) && (val != WhenMapped) && (val != Always)) 1064 { 1065 ret = BadValue; 1066 client->errorValue = val; 1067 goto PatchUp; 1068 } 1069 *values++ = val; 1070 break; 1071 case CWBackingPlanes: 1072 *values++ = (CARD32) *pVlist; 1073 break; 1074 case CWBackingPixel: 1075 *values++ = (CARD32) *pVlist; 1076 break; 1077 case CWSaveUnder: 1078 val = (BOOL) *pVlist; 1079 if ((val != xTrue) && (val != xFalse)) 1080 { 1081 ret = BadValue; 1082 client->errorValue = val; 1083 goto PatchUp; 1084 } 1085 *values++ = val; 1086 break; 1087 case CWEventMask: 1088 *values++ = (CARD32) *pVlist; 1089 break; 1090 case CWDontPropagate: 1091 *values++ = (CARD32) *pVlist; 1092 break; 1093 case CWOverrideRedirect: 1094 if (!(stuff->mask & CWOverrideRedirect)) 1095 pVlist--; 1096 else 1097 { 1098 val = (BOOL ) *pVlist; 1099 if ((val != xTrue) && (val != xFalse)) 1100 { 1101 ret = BadValue; 1102 client->errorValue = val; 1103 goto PatchUp; 1104 } 1105 } 1106 *values++ = xTrue; 1107 break; 1108 case CWColormap: 1109 cmap = (Colormap) *pVlist; 1110 ret = dixLookupResourceByType((pointer *)&pCmap, cmap, RT_COLORMAP, 1111 client, DixUseAccess); 1112 if (ret != Success) 1113 { 1114 client->errorValue = cmap; 1115 goto PatchUp; 1116 } 1117 if (pCmap->pVisual->vid != visual || pCmap->pScreen != pScreen) 1118 { 1119 ret = BadMatch; 1120 goto PatchUp; 1121 } 1122 pAttr->colormap = cmap; 1123 pAttr->mask &= ~CWColormap; 1124 break; 1125 case CWCursor: 1126 cursorID = (Cursor ) *pVlist; 1127 if ( cursorID == None) 1128 { 1129 *values++ = None; 1130 } 1131 else 1132 { 1133 ret = dixLookupResourceByType((pointer *)&pCursor, cursorID, 1134 RT_CURSOR, client, DixUseAccess); 1135 if (ret != Success) 1136 { 1137 client->errorValue = cursorID; 1138 goto PatchUp; 1139 } 1140 pCursor->refcnt++; 1141 pAttr->pCursor = pCursor; 1142 pAttr->mask &= ~CWCursor; 1143 } 1144 break; 1145 default: 1146 ret = BadValue; 1147 client->errorValue = stuff->mask; 1148 goto PatchUp; 1149 } 1150 pVlist++; 1151 } 1152 if (pPriv->attr) 1153 FreeScreenAttr (pPriv->attr); 1154 pPriv->attr = pAttr; 1155 pAttr->resource = FakeClientID (client->index); 1156 if (!AddResource (pAttr->resource, AttrType, (pointer) pAttr)) 1157 return BadAlloc; 1158 return Success; 1159PatchUp: 1160 FreeAttrs (pAttr); 1161bail: 1162 CheckScreenPrivate (pScreen); 1163 if (pAttr) free(pAttr->values); 1164 free(pAttr); 1165 return ret; 1166} 1167 1168static int 1169ScreenSaverUnsetAttributes (ClientPtr client) 1170{ 1171 REQUEST(xScreenSaverSetAttributesReq); 1172 DrawablePtr pDraw; 1173 ScreenSaverScreenPrivatePtr pPriv; 1174 int rc; 1175 1176 REQUEST_SIZE_MATCH (xScreenSaverUnsetAttributesReq); 1177 rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, 1178 DixGetAttrAccess); 1179 if (rc != Success) 1180 return rc; 1181 pPriv = GetScreenPrivate (pDraw->pScreen); 1182 if (pPriv && pPriv->attr && pPriv->attr->client == client) 1183 { 1184 FreeResource (pPriv->attr->resource, AttrType); 1185 FreeScreenAttr (pPriv->attr); 1186 pPriv->attr = NULL; 1187 CheckScreenPrivate (pDraw->pScreen); 1188 } 1189 return Success; 1190} 1191 1192static int 1193ProcScreenSaverSetAttributes (ClientPtr client) 1194{ 1195#ifdef PANORAMIX 1196 if(!noPanoramiXExtension) { 1197 REQUEST(xScreenSaverSetAttributesReq); 1198 PanoramiXRes *draw; 1199 PanoramiXRes *backPix = NULL; 1200 PanoramiXRes *bordPix = NULL; 1201 PanoramiXRes *cmap = NULL; 1202 int i, status, len; 1203 int pback_offset = 0, pbord_offset = 0, cmap_offset = 0; 1204 XID orig_visual, tmp; 1205 1206 REQUEST_AT_LEAST_SIZE (xScreenSaverSetAttributesReq); 1207 1208 status = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, 1209 XRC_DRAWABLE, client, DixWriteAccess); 1210 if (status != Success) 1211 return (status == BadValue) ? BadDrawable : status; 1212 1213 len = stuff->length - bytes_to_int32(sizeof(xScreenSaverSetAttributesReq)); 1214 if (Ones(stuff->mask) != len) 1215 return BadLength; 1216 1217 if((Mask)stuff->mask & CWBackPixmap) { 1218 pback_offset = Ones((Mask)stuff->mask & (CWBackPixmap - 1)); 1219 tmp = *((CARD32 *) &stuff[1] + pback_offset); 1220 if ((tmp != None) && (tmp != ParentRelative)) { 1221 status = dixLookupResourceByType((pointer *)&backPix, tmp, 1222 XRT_PIXMAP, client, 1223 DixReadAccess); 1224 if (status != Success) 1225 return status; 1226 } 1227 } 1228 1229 if ((Mask)stuff->mask & CWBorderPixmap) { 1230 pbord_offset = Ones((Mask)stuff->mask & (CWBorderPixmap - 1)); 1231 tmp = *((CARD32 *) &stuff[1] + pbord_offset); 1232 if (tmp != CopyFromParent) { 1233 status = dixLookupResourceByType((pointer *)&bordPix, tmp, 1234 XRT_PIXMAP, client, 1235 DixReadAccess); 1236 if (status != Success) 1237 return status; 1238 } 1239 } 1240 1241 if ((Mask)stuff->mask & CWColormap) { 1242 cmap_offset = Ones((Mask)stuff->mask & (CWColormap - 1)); 1243 tmp = *((CARD32 *) &stuff[1] + cmap_offset); 1244 if ((tmp != CopyFromParent) && (tmp != None)) { 1245 status = dixLookupResourceByType((pointer *)&cmap, tmp, 1246 XRT_COLORMAP, client, 1247 DixReadAccess); 1248 if (status != Success) 1249 return status; 1250 } 1251 } 1252 1253 orig_visual = stuff->visualID; 1254 1255 FOR_NSCREENS_BACKWARD(i) { 1256 stuff->drawable = draw->info[i].id; 1257 if (backPix) 1258 *((CARD32 *) &stuff[1] + pback_offset) = backPix->info[i].id; 1259 if (bordPix) 1260 *((CARD32 *) &stuff[1] + pbord_offset) = bordPix->info[i].id; 1261 if (cmap) 1262 *((CARD32 *) &stuff[1] + cmap_offset) = cmap->info[i].id; 1263 1264 if (orig_visual != CopyFromParent) 1265 stuff->visualID = PanoramiXTranslateVisualID(i, orig_visual); 1266 1267 status = ScreenSaverSetAttributes(client); 1268 } 1269 1270 return status; 1271 } 1272#endif 1273 1274 return ScreenSaverSetAttributes(client); 1275} 1276 1277static int 1278ProcScreenSaverUnsetAttributes (ClientPtr client) 1279{ 1280#ifdef PANORAMIX 1281 if(!noPanoramiXExtension) { 1282 REQUEST(xScreenSaverUnsetAttributesReq); 1283 PanoramiXRes *draw; 1284 int rc, i; 1285 1286 rc = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, 1287 XRC_DRAWABLE, client, DixWriteAccess); 1288 if (rc != Success) 1289 return (rc == BadValue) ? BadDrawable : rc; 1290 1291 for(i = PanoramiXNumScreens - 1; i > 0; i--) { 1292 stuff->drawable = draw->info[i].id; 1293 ScreenSaverUnsetAttributes(client); 1294 } 1295 1296 stuff->drawable = draw->info[0].id; 1297 } 1298#endif 1299 1300 return ScreenSaverUnsetAttributes(client); 1301} 1302 1303static int 1304ProcScreenSaverSuspend (ClientPtr client) 1305{ 1306 ScreenSaverSuspensionPtr *prev, this; 1307 1308 REQUEST(xScreenSaverSuspendReq); 1309 REQUEST_SIZE_MATCH(xScreenSaverSuspendReq); 1310 1311 /* Check if this client is suspending the screensaver */ 1312 for (prev = &suspendingClients; (this = *prev); prev = &this->next) 1313 if (this->pClient == client) 1314 break; 1315 1316 if (this) 1317 { 1318 if (stuff->suspend == TRUE) 1319 this->count++; 1320 else if (--this->count == 0) 1321 FreeResource (this->clientResource, RT_NONE); 1322 1323 return Success; 1324 } 1325 1326 /* If we get to this point, this client isn't suspending the screensaver */ 1327 if (stuff->suspend == FALSE) 1328 return Success; 1329 1330 /* 1331 * Allocate a suspension record for the client, and stop the screensaver 1332 * if it isn't already suspended by another client. We attach a resource ID 1333 * to the record, so the screensaver will be reenabled and the record freed 1334 * if the client disconnects without reenabling it first. 1335 */ 1336 this = malloc(sizeof (ScreenSaverSuspensionRec)); 1337 1338 if (!this) 1339 return BadAlloc; 1340 1341 this->next = NULL; 1342 this->pClient = client; 1343 this->count = 1; 1344 this->clientResource = FakeClientID (client->index); 1345 1346 if (!AddResource (this->clientResource, SuspendType, (pointer) this)) 1347 { 1348 free(this); 1349 return BadAlloc; 1350 } 1351 1352 *prev = this; 1353 if (!screenSaverSuspended) 1354 { 1355 screenSaverSuspended = TRUE; 1356 FreeScreenSaverTimer(); 1357 } 1358 1359 return Success; 1360} 1361 1362static int (*NormalVector[]) (ClientPtr /* client */) = { 1363 ProcScreenSaverQueryVersion, 1364 ProcScreenSaverQueryInfo, 1365 ProcScreenSaverSelectInput, 1366 ProcScreenSaverSetAttributes, 1367 ProcScreenSaverUnsetAttributes, 1368 ProcScreenSaverSuspend, 1369}; 1370 1371#define NUM_REQUESTS ((sizeof NormalVector) / (sizeof NormalVector[0])) 1372 1373static int 1374ProcScreenSaverDispatch (ClientPtr client) 1375{ 1376 REQUEST(xReq); 1377 1378 if (stuff->data < NUM_REQUESTS) 1379 return (*NormalVector[stuff->data])(client); 1380 return BadRequest; 1381} 1382 1383static int 1384SProcScreenSaverQueryVersion (ClientPtr client) 1385{ 1386 REQUEST(xScreenSaverQueryVersionReq); 1387 int n; 1388 1389 swaps (&stuff->length, n); 1390 REQUEST_SIZE_MATCH(xScreenSaverQueryVersionReq); 1391 return ProcScreenSaverQueryVersion (client); 1392} 1393 1394static int 1395SProcScreenSaverQueryInfo (ClientPtr client) 1396{ 1397 REQUEST(xScreenSaverQueryInfoReq); 1398 int n; 1399 1400 swaps (&stuff->length, n); 1401 REQUEST_SIZE_MATCH(xScreenSaverQueryInfoReq); 1402 swapl (&stuff->drawable, n); 1403 return ProcScreenSaverQueryInfo (client); 1404} 1405 1406static int 1407SProcScreenSaverSelectInput (ClientPtr client) 1408{ 1409 REQUEST(xScreenSaverSelectInputReq); 1410 int n; 1411 1412 swaps (&stuff->length, n); 1413 REQUEST_SIZE_MATCH(xScreenSaverSelectInputReq); 1414 swapl (&stuff->drawable, n); 1415 swapl (&stuff->eventMask, n); 1416 return ProcScreenSaverSelectInput (client); 1417} 1418 1419static int 1420SProcScreenSaverSetAttributes (ClientPtr client) 1421{ 1422 REQUEST(xScreenSaverSetAttributesReq); 1423 int n; 1424 1425 swaps (&stuff->length, n); 1426 REQUEST_AT_LEAST_SIZE(xScreenSaverSetAttributesReq); 1427 swapl (&stuff->drawable, n); 1428 swaps (&stuff->x, n); 1429 swaps (&stuff->y, n); 1430 swaps (&stuff->width, n); 1431 swaps (&stuff->height, n); 1432 swaps (&stuff->borderWidth, n); 1433 swapl (&stuff->visualID, n); 1434 swapl (&stuff->mask, n); 1435 SwapRestL(stuff); 1436 return ProcScreenSaverSetAttributes (client); 1437} 1438 1439static int 1440SProcScreenSaverUnsetAttributes (ClientPtr client) 1441{ 1442 REQUEST(xScreenSaverUnsetAttributesReq); 1443 int n; 1444 1445 swaps (&stuff->length, n); 1446 REQUEST_SIZE_MATCH(xScreenSaverUnsetAttributesReq); 1447 swapl (&stuff->drawable, n); 1448 return ProcScreenSaverUnsetAttributes (client); 1449} 1450 1451static int 1452SProcScreenSaverSuspend (ClientPtr client) 1453{ 1454 int n; 1455 REQUEST(xScreenSaverSuspendReq); 1456 1457 swaps(&stuff->length, n); 1458 REQUEST_SIZE_MATCH(xScreenSaverSuspendReq); 1459 swapl(&stuff->suspend, n); 1460 return ProcScreenSaverSuspend (client); 1461} 1462 1463static int (*SwappedVector[]) (ClientPtr /* client */) = { 1464 SProcScreenSaverQueryVersion, 1465 SProcScreenSaverQueryInfo, 1466 SProcScreenSaverSelectInput, 1467 SProcScreenSaverSetAttributes, 1468 SProcScreenSaverUnsetAttributes, 1469 SProcScreenSaverSuspend, 1470}; 1471 1472static int 1473SProcScreenSaverDispatch (ClientPtr client) 1474{ 1475 REQUEST(xReq); 1476 1477 if (stuff->data < NUM_REQUESTS) 1478 return (*SwappedVector[stuff->data])(client); 1479 return BadRequest; 1480} 1481 1482void 1483ScreenSaverExtensionInit(INITARGS) 1484{ 1485 ExtensionEntry *extEntry; 1486 int i; 1487 ScreenPtr pScreen; 1488 1489 if (!dixRegisterPrivateKey(&ScreenPrivateKeyRec, PRIVATE_SCREEN, 0)) 1490 return; 1491 1492 AttrType = CreateNewResourceType(ScreenSaverFreeAttr, "SaverAttr"); 1493 SaverEventType = CreateNewResourceType(ScreenSaverFreeEvents, 1494 "SaverEvent"); 1495 SuspendType = CreateNewResourceType(ScreenSaverFreeSuspend, 1496 "SaverSuspend"); 1497 1498 for (i = 0; i < screenInfo.numScreens; i++) 1499 { 1500 pScreen = screenInfo.screens[i]; 1501 SetScreenPrivate (pScreen, NULL); 1502 } 1503 if (AttrType && SaverEventType && SuspendType && 1504 (extEntry = AddExtension(ScreenSaverName, ScreenSaverNumberEvents, 0, 1505 ProcScreenSaverDispatch, SProcScreenSaverDispatch, 1506 NULL, StandardMinorOpcode))) 1507 { 1508 ScreenSaverEventBase = extEntry->eventBase; 1509 EventSwapVector[ScreenSaverEventBase] = (EventSwapPtr) SScreenSaverNotifyEvent; 1510 } 1511} 1512