saver.c revision 475c125c
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 pAttr->values = 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 /* 951 * go through the mask, checking the values, 952 * looking up pixmaps and cursors and hold a reference 953 * to them. 954 */ 955 pAttr->mask = tmask = stuff->mask | CWOverrideRedirect; 956 pVlist = (unsigned int *) (stuff + 1); 957 while (tmask) { 958 imask = lowbit (tmask); 959 tmask &= ~imask; 960 switch (imask) 961 { 962 case CWBackPixmap: 963 pixID = (Pixmap )*pVlist; 964 if (pixID == None) 965 { 966 *values++ = None; 967 } 968 else if (pixID == ParentRelative) 969 { 970 if (depth != pParent->drawable.depth) 971 { 972 ret = BadMatch; 973 goto PatchUp; 974 } 975 *values++ = ParentRelative; 976 } 977 else 978 { 979 ret = dixLookupResourceByType((pointer *)&pPixmap, pixID, RT_PIXMAP, 980 client, DixReadAccess); 981 if (ret == Success) 982 { 983 if ((pPixmap->drawable.depth != depth) || 984 (pPixmap->drawable.pScreen != pScreen)) 985 { 986 ret = BadMatch; 987 goto PatchUp; 988 } 989 pAttr->pBackgroundPixmap = pPixmap; 990 pPixmap->refcnt++; 991 pAttr->mask &= ~CWBackPixmap; 992 } 993 else 994 { 995 client->errorValue = pixID; 996 goto PatchUp; 997 } 998 } 999 break; 1000 case CWBackPixel: 1001 *values++ = (CARD32) *pVlist; 1002 break; 1003 case CWBorderPixmap: 1004 pixID = (Pixmap ) *pVlist; 1005 if (pixID == CopyFromParent) 1006 { 1007 if (depth != pParent->drawable.depth) 1008 { 1009 ret = BadMatch; 1010 goto PatchUp; 1011 } 1012 *values++ = CopyFromParent; 1013 } 1014 else 1015 { 1016 ret = dixLookupResourceByType((pointer *)&pPixmap, pixID, RT_PIXMAP, 1017 client, DixReadAccess); 1018 if (ret == Success) 1019 { 1020 if ((pPixmap->drawable.depth != depth) || 1021 (pPixmap->drawable.pScreen != pScreen)) 1022 { 1023 ret = BadMatch; 1024 goto PatchUp; 1025 } 1026 pAttr->pBorderPixmap = pPixmap; 1027 pPixmap->refcnt++; 1028 pAttr->mask &= ~CWBorderPixmap; 1029 } 1030 else 1031 { 1032 client->errorValue = pixID; 1033 goto PatchUp; 1034 } 1035 } 1036 break; 1037 case CWBorderPixel: 1038 *values++ = (CARD32) *pVlist; 1039 break; 1040 case CWBitGravity: 1041 val = (CARD8 )*pVlist; 1042 if (val > StaticGravity) 1043 { 1044 ret = BadValue; 1045 client->errorValue = val; 1046 goto PatchUp; 1047 } 1048 *values++ = val; 1049 break; 1050 case CWWinGravity: 1051 val = (CARD8 )*pVlist; 1052 if (val > StaticGravity) 1053 { 1054 ret = BadValue; 1055 client->errorValue = val; 1056 goto PatchUp; 1057 } 1058 *values++ = val; 1059 break; 1060 case CWBackingStore: 1061 val = (CARD8 )*pVlist; 1062 if ((val != NotUseful) && (val != WhenMapped) && (val != Always)) 1063 { 1064 ret = BadValue; 1065 client->errorValue = val; 1066 goto PatchUp; 1067 } 1068 *values++ = val; 1069 break; 1070 case CWBackingPlanes: 1071 *values++ = (CARD32) *pVlist; 1072 break; 1073 case CWBackingPixel: 1074 *values++ = (CARD32) *pVlist; 1075 break; 1076 case CWSaveUnder: 1077 val = (BOOL) *pVlist; 1078 if ((val != xTrue) && (val != xFalse)) 1079 { 1080 ret = BadValue; 1081 client->errorValue = val; 1082 goto PatchUp; 1083 } 1084 *values++ = val; 1085 break; 1086 case CWEventMask: 1087 *values++ = (CARD32) *pVlist; 1088 break; 1089 case CWDontPropagate: 1090 *values++ = (CARD32) *pVlist; 1091 break; 1092 case CWOverrideRedirect: 1093 if (!(stuff->mask & CWOverrideRedirect)) 1094 pVlist--; 1095 else 1096 { 1097 val = (BOOL ) *pVlist; 1098 if ((val != xTrue) && (val != xFalse)) 1099 { 1100 ret = BadValue; 1101 client->errorValue = val; 1102 goto PatchUp; 1103 } 1104 } 1105 *values++ = xTrue; 1106 break; 1107 case CWColormap: 1108 cmap = (Colormap) *pVlist; 1109 ret = dixLookupResourceByType((pointer *)&pCmap, cmap, RT_COLORMAP, 1110 client, DixUseAccess); 1111 if (ret != Success) 1112 { 1113 client->errorValue = cmap; 1114 goto PatchUp; 1115 } 1116 if (pCmap->pVisual->vid != visual || pCmap->pScreen != pScreen) 1117 { 1118 ret = BadMatch; 1119 goto PatchUp; 1120 } 1121 pAttr->colormap = cmap; 1122 pAttr->mask &= ~CWColormap; 1123 break; 1124 case CWCursor: 1125 cursorID = (Cursor ) *pVlist; 1126 if ( cursorID == None) 1127 { 1128 *values++ = None; 1129 } 1130 else 1131 { 1132 ret = dixLookupResourceByType((pointer *)&pCursor, cursorID, 1133 RT_CURSOR, client, DixUseAccess); 1134 if (ret != Success) 1135 { 1136 client->errorValue = cursorID; 1137 goto PatchUp; 1138 } 1139 pCursor->refcnt++; 1140 pAttr->pCursor = pCursor; 1141 pAttr->mask &= ~CWCursor; 1142 } 1143 break; 1144 default: 1145 ret = BadValue; 1146 client->errorValue = stuff->mask; 1147 goto PatchUp; 1148 } 1149 pVlist++; 1150 } 1151 if (pPriv->attr) 1152 FreeScreenAttr (pPriv->attr); 1153 pPriv->attr = pAttr; 1154 pAttr->resource = FakeClientID (client->index); 1155 if (!AddResource (pAttr->resource, AttrType, (pointer) pAttr)) 1156 return BadAlloc; 1157 return Success; 1158PatchUp: 1159 FreeAttrs (pAttr); 1160bail: 1161 CheckScreenPrivate (pScreen); 1162 if (pAttr) free(pAttr->values); 1163 free(pAttr); 1164 return ret; 1165} 1166 1167static int 1168ScreenSaverUnsetAttributes (ClientPtr client) 1169{ 1170 REQUEST(xScreenSaverSetAttributesReq); 1171 DrawablePtr pDraw; 1172 ScreenSaverScreenPrivatePtr pPriv; 1173 int rc; 1174 1175 REQUEST_SIZE_MATCH (xScreenSaverUnsetAttributesReq); 1176 rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, 1177 DixGetAttrAccess); 1178 if (rc != Success) 1179 return rc; 1180 pPriv = GetScreenPrivate (pDraw->pScreen); 1181 if (pPriv && pPriv->attr && pPriv->attr->client == client) 1182 { 1183 FreeResource (pPriv->attr->resource, AttrType); 1184 FreeScreenAttr (pPriv->attr); 1185 pPriv->attr = NULL; 1186 CheckScreenPrivate (pDraw->pScreen); 1187 } 1188 return Success; 1189} 1190 1191static int 1192ProcScreenSaverSetAttributes (ClientPtr client) 1193{ 1194#ifdef PANORAMIX 1195 if(!noPanoramiXExtension) { 1196 REQUEST(xScreenSaverSetAttributesReq); 1197 PanoramiXRes *draw; 1198 PanoramiXRes *backPix = NULL; 1199 PanoramiXRes *bordPix = NULL; 1200 PanoramiXRes *cmap = NULL; 1201 int i, status, len; 1202 int pback_offset = 0, pbord_offset = 0, cmap_offset = 0; 1203 XID orig_visual, tmp; 1204 1205 REQUEST_AT_LEAST_SIZE (xScreenSaverSetAttributesReq); 1206 1207 status = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, 1208 XRC_DRAWABLE, client, DixWriteAccess); 1209 if (status != Success) 1210 return (status == BadValue) ? BadDrawable : status; 1211 1212 len = stuff->length - bytes_to_int32(sizeof(xScreenSaverSetAttributesReq)); 1213 if (Ones(stuff->mask) != len) 1214 return BadLength; 1215 1216 if((Mask)stuff->mask & CWBackPixmap) { 1217 pback_offset = Ones((Mask)stuff->mask & (CWBackPixmap - 1)); 1218 tmp = *((CARD32 *) &stuff[1] + pback_offset); 1219 if ((tmp != None) && (tmp != ParentRelative)) { 1220 status = dixLookupResourceByType((pointer *)&backPix, tmp, 1221 XRT_PIXMAP, client, 1222 DixReadAccess); 1223 if (status != Success) 1224 return status; 1225 } 1226 } 1227 1228 if ((Mask)stuff->mask & CWBorderPixmap) { 1229 pbord_offset = Ones((Mask)stuff->mask & (CWBorderPixmap - 1)); 1230 tmp = *((CARD32 *) &stuff[1] + pbord_offset); 1231 if (tmp != CopyFromParent) { 1232 status = dixLookupResourceByType((pointer *)&bordPix, tmp, 1233 XRT_PIXMAP, client, 1234 DixReadAccess); 1235 if (status != Success) 1236 return status; 1237 } 1238 } 1239 1240 if ((Mask)stuff->mask & CWColormap) { 1241 cmap_offset = Ones((Mask)stuff->mask & (CWColormap - 1)); 1242 tmp = *((CARD32 *) &stuff[1] + cmap_offset); 1243 if ((tmp != CopyFromParent) && (tmp != None)) { 1244 status = dixLookupResourceByType((pointer *)&cmap, tmp, 1245 XRT_COLORMAP, client, 1246 DixReadAccess); 1247 if (status != Success) 1248 return status; 1249 } 1250 } 1251 1252 orig_visual = stuff->visualID; 1253 1254 FOR_NSCREENS_BACKWARD(i) { 1255 stuff->drawable = draw->info[i].id; 1256 if (backPix) 1257 *((CARD32 *) &stuff[1] + pback_offset) = backPix->info[i].id; 1258 if (bordPix) 1259 *((CARD32 *) &stuff[1] + pbord_offset) = bordPix->info[i].id; 1260 if (cmap) 1261 *((CARD32 *) &stuff[1] + cmap_offset) = cmap->info[i].id; 1262 1263 if (orig_visual != CopyFromParent) 1264 stuff->visualID = PanoramiXTranslateVisualID(i, orig_visual); 1265 1266 status = ScreenSaverSetAttributes(client); 1267 } 1268 1269 return status; 1270 } 1271#endif 1272 1273 return ScreenSaverSetAttributes(client); 1274} 1275 1276static int 1277ProcScreenSaverUnsetAttributes (ClientPtr client) 1278{ 1279#ifdef PANORAMIX 1280 if(!noPanoramiXExtension) { 1281 REQUEST(xScreenSaverUnsetAttributesReq); 1282 PanoramiXRes *draw; 1283 int rc, i; 1284 1285 rc = dixLookupResourceByClass((pointer *)&draw, stuff->drawable, 1286 XRC_DRAWABLE, client, DixWriteAccess); 1287 if (rc != Success) 1288 return (rc == BadValue) ? BadDrawable : rc; 1289 1290 for(i = PanoramiXNumScreens - 1; i > 0; i--) { 1291 stuff->drawable = draw->info[i].id; 1292 ScreenSaverUnsetAttributes(client); 1293 } 1294 1295 stuff->drawable = draw->info[0].id; 1296 } 1297#endif 1298 1299 return ScreenSaverUnsetAttributes(client); 1300} 1301 1302static int 1303ProcScreenSaverSuspend (ClientPtr client) 1304{ 1305 ScreenSaverSuspensionPtr *prev, this; 1306 1307 REQUEST(xScreenSaverSuspendReq); 1308 REQUEST_SIZE_MATCH(xScreenSaverSuspendReq); 1309 1310 /* Check if this client is suspending the screensaver */ 1311 for (prev = &suspendingClients; (this = *prev); prev = &this->next) 1312 if (this->pClient == client) 1313 break; 1314 1315 if (this) 1316 { 1317 if (stuff->suspend == TRUE) 1318 this->count++; 1319 else if (--this->count == 0) 1320 FreeResource (this->clientResource, RT_NONE); 1321 1322 return Success; 1323 } 1324 1325 /* If we get to this point, this client isn't suspending the screensaver */ 1326 if (stuff->suspend == FALSE) 1327 return Success; 1328 1329 /* 1330 * Allocate a suspension record for the client, and stop the screensaver 1331 * if it isn't already suspended by another client. We attach a resource ID 1332 * to the record, so the screensaver will be reenabled and the record freed 1333 * if the client disconnects without reenabling it first. 1334 */ 1335 this = malloc(sizeof (ScreenSaverSuspensionRec)); 1336 1337 if (!this) 1338 return BadAlloc; 1339 1340 this->next = NULL; 1341 this->pClient = client; 1342 this->count = 1; 1343 this->clientResource = FakeClientID (client->index); 1344 1345 if (!AddResource (this->clientResource, SuspendType, (pointer) this)) 1346 { 1347 free(this); 1348 return BadAlloc; 1349 } 1350 1351 *prev = this; 1352 if (!screenSaverSuspended) 1353 { 1354 screenSaverSuspended = TRUE; 1355 FreeScreenSaverTimer(); 1356 } 1357 1358 return Success; 1359} 1360 1361static int (*NormalVector[]) (ClientPtr /* client */) = { 1362 ProcScreenSaverQueryVersion, 1363 ProcScreenSaverQueryInfo, 1364 ProcScreenSaverSelectInput, 1365 ProcScreenSaverSetAttributes, 1366 ProcScreenSaverUnsetAttributes, 1367 ProcScreenSaverSuspend, 1368}; 1369 1370#define NUM_REQUESTS ((sizeof NormalVector) / (sizeof NormalVector[0])) 1371 1372static int 1373ProcScreenSaverDispatch (ClientPtr client) 1374{ 1375 REQUEST(xReq); 1376 1377 if (stuff->data < NUM_REQUESTS) 1378 return (*NormalVector[stuff->data])(client); 1379 return BadRequest; 1380} 1381 1382static int 1383SProcScreenSaverQueryVersion (ClientPtr client) 1384{ 1385 REQUEST(xScreenSaverQueryVersionReq); 1386 int n; 1387 1388 swaps (&stuff->length, n); 1389 REQUEST_SIZE_MATCH(xScreenSaverQueryVersionReq); 1390 return ProcScreenSaverQueryVersion (client); 1391} 1392 1393static int 1394SProcScreenSaverQueryInfo (ClientPtr client) 1395{ 1396 REQUEST(xScreenSaverQueryInfoReq); 1397 int n; 1398 1399 swaps (&stuff->length, n); 1400 REQUEST_SIZE_MATCH(xScreenSaverQueryInfoReq); 1401 swapl (&stuff->drawable, n); 1402 return ProcScreenSaverQueryInfo (client); 1403} 1404 1405static int 1406SProcScreenSaverSelectInput (ClientPtr client) 1407{ 1408 REQUEST(xScreenSaverSelectInputReq); 1409 int n; 1410 1411 swaps (&stuff->length, n); 1412 REQUEST_SIZE_MATCH(xScreenSaverSelectInputReq); 1413 swapl (&stuff->drawable, n); 1414 swapl (&stuff->eventMask, n); 1415 return ProcScreenSaverSelectInput (client); 1416} 1417 1418static int 1419SProcScreenSaverSetAttributes (ClientPtr client) 1420{ 1421 REQUEST(xScreenSaverSetAttributesReq); 1422 int n; 1423 1424 swaps (&stuff->length, n); 1425 REQUEST_AT_LEAST_SIZE(xScreenSaverSetAttributesReq); 1426 swapl (&stuff->drawable, n); 1427 swaps (&stuff->x, n); 1428 swaps (&stuff->y, n); 1429 swaps (&stuff->width, n); 1430 swaps (&stuff->height, n); 1431 swaps (&stuff->borderWidth, n); 1432 swapl (&stuff->visualID, n); 1433 swapl (&stuff->mask, n); 1434 SwapRestL(stuff); 1435 return ProcScreenSaverSetAttributes (client); 1436} 1437 1438static int 1439SProcScreenSaverUnsetAttributes (ClientPtr client) 1440{ 1441 REQUEST(xScreenSaverUnsetAttributesReq); 1442 int n; 1443 1444 swaps (&stuff->length, n); 1445 REQUEST_SIZE_MATCH(xScreenSaverUnsetAttributesReq); 1446 swapl (&stuff->drawable, n); 1447 return ProcScreenSaverUnsetAttributes (client); 1448} 1449 1450static int 1451SProcScreenSaverSuspend (ClientPtr client) 1452{ 1453 int n; 1454 REQUEST(xScreenSaverSuspendReq); 1455 1456 swaps(&stuff->length, n); 1457 REQUEST_SIZE_MATCH(xScreenSaverSuspendReq); 1458 swapl(&stuff->suspend, n); 1459 return ProcScreenSaverSuspend (client); 1460} 1461 1462static int (*SwappedVector[]) (ClientPtr /* client */) = { 1463 SProcScreenSaverQueryVersion, 1464 SProcScreenSaverQueryInfo, 1465 SProcScreenSaverSelectInput, 1466 SProcScreenSaverSetAttributes, 1467 SProcScreenSaverUnsetAttributes, 1468 SProcScreenSaverSuspend, 1469}; 1470 1471static int 1472SProcScreenSaverDispatch (ClientPtr client) 1473{ 1474 REQUEST(xReq); 1475 1476 if (stuff->data < NUM_REQUESTS) 1477 return (*SwappedVector[stuff->data])(client); 1478 return BadRequest; 1479} 1480 1481void 1482ScreenSaverExtensionInit(INITARGS) 1483{ 1484 ExtensionEntry *extEntry; 1485 int i; 1486 ScreenPtr pScreen; 1487 1488 if (!dixRegisterPrivateKey(&ScreenPrivateKeyRec, PRIVATE_SCREEN, 0)) 1489 return; 1490 1491 AttrType = CreateNewResourceType(ScreenSaverFreeAttr, "SaverAttr"); 1492 SaverEventType = CreateNewResourceType(ScreenSaverFreeEvents, 1493 "SaverEvent"); 1494 SuspendType = CreateNewResourceType(ScreenSaverFreeSuspend, 1495 "SaverSuspend"); 1496 1497 for (i = 0; i < screenInfo.numScreens; i++) 1498 { 1499 pScreen = screenInfo.screens[i]; 1500 SetScreenPrivate (pScreen, NULL); 1501 } 1502 if (AttrType && SaverEventType && SuspendType && 1503 (extEntry = AddExtension(ScreenSaverName, ScreenSaverNumberEvents, 0, 1504 ProcScreenSaverDispatch, SProcScreenSaverDispatch, 1505 NULL, StandardMinorOpcode))) 1506 { 1507 ScreenSaverEventBase = extEntry->eventBase; 1508 EventSwapVector[ScreenSaverEventBase] = (EventSwapPtr) SScreenSaverNotifyEvent; 1509 } 1510} 1511