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