1 /*
2 *
3 Copyright (c) 1992 X Consortium
4
5 Permission is hereby granted, free of charge, to any person obtaining a copy
6 of this software and associated documentation files (the "Software"), to deal
7 in the Software without restriction, including without limitation the rights
8 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 copies of the Software, and to permit persons to whom the Software is
10 furnished to do so, subject to the following conditions:
11
12 The above copyright notice and this permission notice shall be included in
13 all copies or substantial portions of the Software.
14
15 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
19 AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
22 Except as contained in this notice, the name of the X Consortium shall not be
23 used in advertising or otherwise to promote the sale, use or other dealings
24 in this Software without prior written authorization from the X Consortium.
25 *
26 * Author: Keith Packard, MIT X Consortium
27 */
28
29 #include <X11/Xlibint.h>
30 #include <X11/Xutil.h>
31 #include <X11/extensions/Xext.h>
32 #include <X11/extensions/extutil.h>
33 #include <X11/extensions/saverproto.h>
34 #include <X11/extensions/scrnsaver.h>
35
36
37 static XExtensionInfo _screen_saver_info_data;
38 static XExtensionInfo *screen_saver_info = &_screen_saver_info_data;
39 static const char *screen_saver_extension_name = ScreenSaverName;
40
41 #define ScreenSaverCheckExtension(dpy,i,val) \
42 XextCheckExtension (dpy, i, screen_saver_extension_name, val)
43 #define ScreenSaverSimpleCheckExtension(dpy,i) \
44 XextSimpleCheckExtension (dpy, i, screen_saver_extension_name)
45
46 static int close_display(
47 Display * /* dpy */,
48 XExtCodes * /* codes */
49 );
50
51 static Bool wire_to_event(
52 Display * /* dpy */,
53 XEvent * /* re */,
54 xEvent * /* event */
55 );
56
57 static Status event_to_wire(
58 Display * /* dpy */,
59 XEvent * /* re */,
60 xEvent * /* event */
61 );
62
63 static /* const */ XExtensionHooks screen_saver_extension_hooks = {
64 NULL, /* create_gc */
65 NULL, /* copy_gc */
66 NULL, /* flush_gc */
67 NULL, /* free_gc */
68 NULL, /* create_font */
69 NULL, /* free_font */
70 close_display, /* close_display */
71 wire_to_event, /* wire_to_event */
72 event_to_wire, /* event_to_wire */
73 NULL, /* error */
74 NULL, /* error_string */
75 };
76
77 static XEXT_GENERATE_FIND_DISPLAY (find_display, screen_saver_info,
78 screen_saver_extension_name,
79 &screen_saver_extension_hooks,
80 ScreenSaverNumberEvents, NULL)
81
XEXT_GENERATE_CLOSE_DISPLAY(close_display,screen_saver_info)82 static XEXT_GENERATE_CLOSE_DISPLAY (close_display, screen_saver_info)
83
84
85 static Bool wire_to_event (
86 Display *dpy,
87 XEvent *re,
88 xEvent *event)
89 {
90 XExtDisplayInfo *info = find_display (dpy);
91 XScreenSaverNotifyEvent *se;
92 xScreenSaverNotifyEvent *sevent;
93
94 ScreenSaverCheckExtension (dpy, info, False);
95
96 switch ((event->u.u.type & 0x7f) - info->codes->first_event) {
97 case ScreenSaverNotify:
98 se = (XScreenSaverNotifyEvent *) re;
99 sevent = (xScreenSaverNotifyEvent *) event;
100 se->type = sevent->type & 0x7f;
101 se->serial = _XSetLastRequestRead(dpy,(xGenericReply *) event);
102 se->send_event = (sevent->type & 0x80) != 0;
103 se->display = dpy;
104 se->window = sevent->window;
105 se->root = sevent->root;
106 se->state = sevent->state;
107 se->kind = sevent->kind;
108 se->forced = True;
109 if (sevent->forced == xFalse)
110 se->forced = False;
111 se->time = sevent->timestamp;
112 return True;
113 }
114 return False;
115 }
116
event_to_wire(Display * dpy,XEvent * re,xEvent * event)117 static Status event_to_wire (
118 Display *dpy,
119 XEvent *re,
120 xEvent *event)
121 {
122 XExtDisplayInfo *info = find_display (dpy);
123 XScreenSaverNotifyEvent *se;
124 xScreenSaverNotifyEvent *sevent;
125
126 ScreenSaverCheckExtension (dpy, info, 0);
127
128 switch ((re->type & 0x7f) - info->codes->first_event) {
129 case ScreenSaverNotify:
130 se = (XScreenSaverNotifyEvent *) re;
131 sevent = (xScreenSaverNotifyEvent *) event;
132 sevent->type = se->type | (se->send_event ? 0x80 : 0);
133 sevent->sequenceNumber = se->serial & 0xffff;
134 sevent->root = se->root;
135 sevent->window = se->window;
136 sevent->state = se->state;
137 sevent->kind = se->kind;
138 sevent->forced = xFalse;
139 if (se->forced == True)
140 sevent->forced = xTrue;
141 sevent->timestamp = se->time;
142 return 1;
143 }
144 return 0;
145 }
146
147 /****************************************************************************
148 * *
149 * ScreenSaver public interfaces *
150 * *
151 ****************************************************************************/
152
XScreenSaverQueryExtension(Display * dpy,int * event_base_return,int * error_base_return)153 Bool XScreenSaverQueryExtension (
154 Display *dpy,
155 int *event_base_return,
156 int *error_base_return)
157 {
158 XExtDisplayInfo *info = find_display (dpy);
159
160 if (XextHasExtension(info)) {
161 *event_base_return = info->codes->first_event;
162 *error_base_return = info->codes->first_error;
163 return True;
164 } else {
165 return False;
166 }
167 }
168
169
XScreenSaverQueryVersion(Display * dpy,int * major_version_return,int * minor_version_return)170 Status XScreenSaverQueryVersion(
171 Display *dpy,
172 int *major_version_return,
173 int *minor_version_return)
174 {
175 XExtDisplayInfo *info = find_display (dpy);
176 xScreenSaverQueryVersionReply rep;
177 register xScreenSaverQueryVersionReq *req;
178
179 ScreenSaverCheckExtension (dpy, info, 0);
180
181 LockDisplay (dpy);
182 GetReq (ScreenSaverQueryVersion, req);
183 req->reqType = info->codes->major_opcode;
184 req->saverReqType = X_ScreenSaverQueryVersion;
185 req->clientMajor = ScreenSaverMajorVersion;
186 req->clientMinor = ScreenSaverMinorVersion;
187 if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) {
188 UnlockDisplay (dpy);
189 SyncHandle ();
190 return 0;
191 }
192 *major_version_return = rep.majorVersion;
193 *minor_version_return = rep.minorVersion;
194 UnlockDisplay (dpy);
195 SyncHandle ();
196 return 1;
197 }
198
XScreenSaverAllocInfo(void)199 XScreenSaverInfo *XScreenSaverAllocInfo (void)
200 {
201 return (XScreenSaverInfo *) Xmalloc (sizeof (XScreenSaverInfo));
202 }
203
XScreenSaverQueryInfo(Display * dpy,Drawable drawable,XScreenSaverInfo * saver_info)204 Status XScreenSaverQueryInfo (
205 Display *dpy,
206 Drawable drawable,
207 XScreenSaverInfo *saver_info)
208 {
209 XExtDisplayInfo *info = find_display (dpy);
210 xScreenSaverQueryInfoReply rep;
211 register xScreenSaverQueryInfoReq *req;
212
213 ScreenSaverCheckExtension (dpy, info, 0);
214
215 LockDisplay (dpy);
216 GetReq (ScreenSaverQueryInfo, req);
217 req->reqType = info->codes->major_opcode;
218 req->saverReqType = X_ScreenSaverQueryInfo;
219 req->drawable = drawable;
220 if (!_XReply (dpy, (xReply *) &rep, 0, xTrue)) {
221 UnlockDisplay (dpy);
222 SyncHandle ();
223 return 0;
224 }
225 UnlockDisplay (dpy);
226 SyncHandle ();
227 saver_info->window = rep.window;
228 saver_info->state = rep.state;
229 saver_info->kind = rep.kind;
230 saver_info->til_or_since = rep.tilOrSince;
231 saver_info->idle = rep.idle;
232 saver_info->eventMask = rep.eventMask;
233 return 1;
234 }
235
XScreenSaverSelectInput(register Display * dpy,Drawable drawable,unsigned long mask)236 void XScreenSaverSelectInput (
237 register Display *dpy,
238 Drawable drawable,
239 unsigned long mask)
240 {
241 XExtDisplayInfo *info = find_display (dpy);
242 register xScreenSaverSelectInputReq *req;
243
244 ScreenSaverSimpleCheckExtension (dpy, info);
245
246 LockDisplay (dpy);
247 GetReq (ScreenSaverSelectInput, req);
248 req->reqType = info->codes->major_opcode;
249 req->saverReqType = X_ScreenSaverSelectInput;
250 req->drawable = drawable;
251 req->eventMask = mask;
252 UnlockDisplay (dpy);
253 SyncHandle ();
254 }
255
256 static void
XScreenSaverProcessWindowAttributes(register Display * dpy,xChangeWindowAttributesReq * req,register unsigned long valuemask,register XSetWindowAttributes * attributes)257 XScreenSaverProcessWindowAttributes (
258 register Display *dpy,
259 xChangeWindowAttributesReq *req,
260 register unsigned long valuemask,
261 register XSetWindowAttributes *attributes)
262 {
263 unsigned long values[32];
264 register unsigned long *value = values;
265 unsigned int nvalues;
266
267 if (valuemask & CWBackPixmap)
268 *value++ = attributes->background_pixmap;
269
270 if (valuemask & CWBackPixel)
271 *value++ = attributes->background_pixel;
272
273 if (valuemask & CWBorderPixmap)
274 *value++ = attributes->border_pixmap;
275
276 if (valuemask & CWBorderPixel)
277 *value++ = attributes->border_pixel;
278
279 if (valuemask & CWBitGravity)
280 *value++ = attributes->bit_gravity;
281
282 if (valuemask & CWWinGravity)
283 *value++ = attributes->win_gravity;
284
285 if (valuemask & CWBackingStore)
286 *value++ = attributes->backing_store;
287
288 if (valuemask & CWBackingPlanes)
289 *value++ = attributes->backing_planes;
290
291 if (valuemask & CWBackingPixel)
292 *value++ = attributes->backing_pixel;
293
294 if (valuemask & CWOverrideRedirect)
295 *value++ = attributes->override_redirect;
296
297 if (valuemask & CWSaveUnder)
298 *value++ = attributes->save_under;
299
300 if (valuemask & CWEventMask)
301 *value++ = attributes->event_mask;
302
303 if (valuemask & CWDontPropagate)
304 *value++ = attributes->do_not_propagate_mask;
305
306 if (valuemask & CWColormap)
307 *value++ = attributes->colormap;
308
309 if (valuemask & CWCursor)
310 *value++ = attributes->cursor;
311
312 req->length += (nvalues = value - values);
313
314 nvalues <<= 2; /* watch out for macros... */
315 Data32 (dpy, (long *) values, (long)nvalues);
316
317 }
318
XScreenSaverSetAttributes(Display * dpy,Drawable drawable,int x,int y,unsigned int width,unsigned int height,unsigned int border_width,int depth,unsigned int class,Visual * visual,unsigned long valuemask,XSetWindowAttributes * attributes)319 void XScreenSaverSetAttributes (
320 Display *dpy,
321 Drawable drawable,
322 int x,
323 int y,
324 unsigned int width,
325 unsigned int height,
326 unsigned int border_width,
327 int depth,
328 unsigned int class,
329 Visual *visual,
330 unsigned long valuemask,
331 XSetWindowAttributes *attributes)
332 {
333 XExtDisplayInfo *info = find_display (dpy);
334 register xScreenSaverSetAttributesReq *req;
335
336 ScreenSaverSimpleCheckExtension (dpy, info);
337
338 LockDisplay (dpy);
339 GetReq (ScreenSaverSetAttributes, req);
340 req->reqType = info->codes->major_opcode;
341 req->saverReqType = X_ScreenSaverSetAttributes;
342 req->drawable = drawable;
343 req->x = x;
344 req->y = y;
345 req->width = width;
346 req->height = height;
347 req->borderWidth = border_width;
348 req->c_class = class;
349 req->depth = depth;
350 if (visual == (Visual *)CopyFromParent)
351 req->visualID = CopyFromParent;
352 else
353 req->visualID = visual->visualid;
354 /* abuse an Xlib internal interface - is this legal for us? */
355 if ((req->mask = valuemask))
356 XScreenSaverProcessWindowAttributes (dpy,
357 (xChangeWindowAttributesReq *)req,
358 valuemask, attributes);
359 UnlockDisplay (dpy);
360 SyncHandle ();
361 }
362
363
XScreenSaverUnsetAttributes(register Display * dpy,Drawable drawable)364 void XScreenSaverUnsetAttributes (
365 register Display *dpy,
366 Drawable drawable)
367 {
368 XExtDisplayInfo *info = find_display (dpy);
369 register xScreenSaverUnsetAttributesReq *req;
370
371 ScreenSaverSimpleCheckExtension (dpy, info);
372
373 LockDisplay (dpy);
374 GetReq (ScreenSaverUnsetAttributes, req);
375 req->reqType = info->codes->major_opcode;
376 req->saverReqType = X_ScreenSaverUnsetAttributes;
377 req->drawable = drawable;
378 UnlockDisplay (dpy);
379 SyncHandle ();
380 }
381
382
XScreenSaverRegister(Display * dpy,int screen,XID xid,Atom type)383 Status XScreenSaverRegister (
384 Display *dpy,
385 int screen,
386 XID xid,
387 Atom type)
388 {
389 Atom prop;
390 unsigned long ul;
391
392 prop = XInternAtom (dpy, ScreenSaverPropertyName, False);
393 if (!prop)
394 return 0;
395
396 ul = (unsigned long) xid;
397 XChangeProperty (dpy, RootWindow(dpy,screen), prop, type, 32,
398 PropModeReplace, (unsigned char *) &ul, 1);
399 return 1;
400 }
401
402
403
XScreenSaverUnregister(Display * dpy,int screen)404 Status XScreenSaverUnregister (
405 Display *dpy,
406 int screen)
407 {
408 Atom prop;
409
410 prop = XInternAtom (dpy, ScreenSaverPropertyName, False);
411 if (!prop)
412 return 0;
413
414 XDeleteProperty (dpy, RootWindow(dpy,screen), prop);
415 return 1;
416 }
417
418
419
XScreenSaverGetRegistered(Display * dpy,int screen,XID * xid,Atom * type)420 Status XScreenSaverGetRegistered (
421 Display *dpy,
422 int screen,
423 XID *xid,
424 Atom *type)
425 {
426 Atom actual_type = None;
427 int actual_format;
428 unsigned long nitems, bytesafter;
429 unsigned long *ulp = (unsigned long *) 0;
430 Atom prop;
431 int retval = 0;
432
433 prop = XInternAtom (dpy, ScreenSaverPropertyName, False);
434 if (!prop)
435 return retval;
436
437 if (XGetWindowProperty (dpy, RootWindow(dpy,screen), prop, 0L, 1L, False,
438 AnyPropertyType, &actual_type, &actual_format,
439 &nitems, &bytesafter, (unsigned char **) &ulp)
440 != Success)
441 return retval;
442
443 if (ulp) {
444 if (actual_format == 32) {
445 *xid = (XID) ulp[0];
446 *type = actual_type;
447 retval = 1;
448 }
449 XFree ((char *) ulp);
450 }
451 return retval;
452 }
453
454 void
XScreenSaverSuspend(Display * dpy,Bool suspend)455 XScreenSaverSuspend (Display *dpy, Bool suspend)
456 {
457 XExtDisplayInfo *info = find_display (dpy);
458 xScreenSaverSuspendReq *req;
459
460 ScreenSaverSimpleCheckExtension (dpy, info);
461
462 LockDisplay (dpy);
463 GetReq (ScreenSaverSuspend, req);
464 req->reqType = info->codes->major_opcode;
465 req->saverReqType = X_ScreenSaverSuspend;
466 req->suspend = suspend;
467 UnlockDisplay (dpy);
468 SyncHandle ();
469 }
470
471