saver.c 37 KB

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