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