xss

Screensaver utilities for the X Windowing System
git clone https://git.woozle.org/neale/xss.git

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}