libXScrnSaver should not try to build into a pure wayland platform.
[platform/upstream/libXScrnSaver.git] / src / XScrnSaver.c
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
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->window = 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
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
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
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
199 XScreenSaverInfo *XScreenSaverAllocInfo (void)
200 {
201     return (XScreenSaverInfo *) Xmalloc (sizeof (XScreenSaverInfo));
202 }
203
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
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
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
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
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
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
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
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
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