Neale Pickett
·
2012-03-02
xsswin.c
1/* xsswin -- create a screensaver window
2 * Copyright (C) 2008 Neale Pickett <neale@woozle.org>
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or (at
7 * your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 */
17
18#include <sys/wait.h>
19#include <unistd.h>
20#include <stdio.h>
21
22#include <X11/Xlib.h>
23
24#include "obj.h"
25
26int
27main(int argc, char * const argv[])
28{
29 Display *display;
30 Pixmap pmap;
31 Window w;
32
33 if (argc < 2) {
34 (void)fprintf(stderr, "Usage: %s PROGRAM [ARGUMENT ...]\n", argv[0]);
35 return 64; /* EX_USAGE */
36 }
37
38 try {
39 int screen;
40 XSetWindowAttributes wa;
41 Window root;
42 int i;
43 char *nargv[argc + 1];
44 char id[50];
45
46 if (! (display = XOpenDisplay(NULL))) raise("cannot open display");
47 screen = DefaultScreen(display);
48 root = RootWindow(display, screen);
49
50 wa.override_redirect = 1;
51 wa.background_pixel = BlackPixel(display, screen);
52 {
53 XColor black;
54
55 pmap = XCreateBitmapFromData(display, root, "\0", 1, 1);
56 black.pixel = BlackPixel(display, screen);
57 wa.cursor = XCreatePixmapCursor(display, pmap, pmap, &black, &black, 0, 0);
58 if (! (XFreePixmap(display, pmap))) break;
59 }
60 w = XCreateWindow(display, root,
61 0, 0,
62 DisplayWidth(display, screen), DisplayHeight(display, screen), 0,
63 CopyFromParent, CopyFromParent, CopyFromParent,
64 CWOverrideRedirect | CWBackPixel | CWCursor,
65 &wa);
66 XMapRaised(display, w);
67 XSync(display, False);
68
69 (void)snprintf(id, sizeof(id), "0x%lx", (unsigned long)w);
70 (void)setenv("XSS_WINDOW", id, 1);
71 for (i = 0; i < argc; i += 1) {
72 if (0 == strcmp(argv[i], "XSS_WINDOW")) {
73 nargv[i] = id;
74 } else {
75 nargv[i] = argv[i];
76 }
77 }
78 nargv[argc] = NULL;
79
80 i = fork();
81 if (0 == i) {
82 (void)execvp(nargv[1], nargv + 1);
83 perror("exec");
84 return 1;
85 }
86 (void)waitpid(-1, NULL, 0);
87 }
88
89 if (display) {
90 (void)XUndefineCursor(display, w);
91 (void)XFreePixmap(display, pmap);
92 (void)XCloseDisplay(display);
93 }
94
95 except {
96 (void)fprintf(stderr, "Error: %s\n", exception);
97 return 69; /* EX_UNAVAILABLE */
98 }
99 return 0;
100}