Files
wmaker/util/wmsetbg.c
T

1570 lines
41 KiB
C
Raw Normal View History

1999-01-06 15:22:33 +00:00
/* wmsetbg.c- sets root window background image and also works as
* workspace background setting helper for wmaker
1998-09-29 22:36:29 +00:00
*
* WindowMaker window manager
2004-10-12 21:28:27 +00:00
*
2003-01-16 23:30:45 +00:00
* Copyright (c) 1998-2003 Alfredo K. Kojima
* Copyright (c) 1998-2003 Dan Pascu
2004-10-12 21:28:27 +00:00
*
1998-09-29 22:36:29 +00:00
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
2004-10-12 21:28:27 +00:00
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
1998-09-29 22:36:29 +00:00
* USA.
*/
/*
* TODO: rewrite, too dirty
*/
1998-09-29 22:36:29 +00:00
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <X11/Xlib.h>
#include <X11/Xutil.h>
#include <X11/Xatom.h>
#include <string.h>
#include <pwd.h>
1999-01-06 15:22:33 +00:00
#include <signal.h>
1998-09-29 22:36:29 +00:00
#include <sys/types.h>
1999-01-11 12:28:12 +00:00
#include <ctype.h>
1998-09-29 22:36:29 +00:00
#include "../src/config.h"
#ifdef XINERAMA
# ifdef SOLARIS_XINERAMA /* sucks */
# include <X11/extensions/xinerama.h>
# else
# include <X11/extensions/Xinerama.h>
# endif
#endif
#ifdef HAVE_DLFCN_H
#include <dlfcn.h>
#endif
1998-09-29 22:36:29 +00:00
#include "../src/wconfig.h"
#include <WINGs/WINGs.h>
1999-06-04 20:13:40 +00:00
#include <wraster.h>
1999-01-06 15:22:33 +00:00
1998-09-29 22:36:29 +00:00
typedef struct {
WMRect *screens;
int count; /* screen count, 0 = inactive */
} WXineramaInfo;
#define PROG_VERSION "wmsetbg (Window Maker) 2.8"
1999-01-25 19:06:50 +00:00
1998-09-29 22:36:29 +00:00
1999-01-06 15:22:33 +00:00
#define WORKSPACE_COUNT (MAX_WORKSPACES+1)
Display *dpy;
1999-01-25 19:06:50 +00:00
char *display = "";
1999-01-06 15:22:33 +00:00
Window root;
int scr;
int scrWidth;
int scrHeight;
int scrX, scrY;
1999-01-06 15:22:33 +00:00
WXineramaInfo xineInfo;
Bool smooth = False;
1999-01-06 15:22:33 +00:00
Pixmap CurrentPixmap = None;
char *PixmapPath = NULL;
1999-01-25 19:06:50 +00:00
extern Pixmap LoadJPEG(RContext *rc, char *file_name, int *width, int *height);
1999-01-06 15:22:33 +00:00
typedef struct BackgroundTexture {
int refcount;
1998-09-29 22:36:29 +00:00
1999-01-06 15:22:33 +00:00
int solid;
char *spec;
XColor color;
Pixmap pixmap; /* for all textures, including solid */
int width; /* size of the pixmap */
int height;
} BackgroundTexture;
void
initXinerama()
{
xineInfo.screens = NULL;
xineInfo.count = 0;
#ifdef XINERAMA
# ifdef SOLARIS_XINERAMA
if (XineramaGetState(dpy, scr)) {
XRectangle head[MAXFRAMEBUFFERS];
unsigned char hints[MAXFRAMEBUFFERS];
int i;
2004-10-12 21:28:27 +00:00
if (XineramaGetInfo(dpy, scr, head, hints,
&xineInfo.count)) {
xineInfo.screens = wmalloc(sizeof(WMRect)*(xineInfo.count+1));
2004-10-12 21:28:27 +00:00
for (i=0; i<xineInfo.count; i++) {
xineInfo.screens[i].pos.x = head[i].x;
xineInfo.screens[i].pos.y = head[i].y;
xineInfo.screens[i].size.width = head[i].width;
xineInfo.screens[i].size.height = head[i].height;
}
}
}
# else /* !SOLARIS_XINERAMA */
if (XineramaIsActive(dpy)) {
2003-06-06 04:11:00 +00:00
XineramaScreenInfo *xine_screens;
int i;
2004-10-12 21:28:27 +00:00
xine_screens = XineramaQueryScreens(dpy, &xineInfo.count);
xineInfo.screens = wmalloc(sizeof(WMRect)*(xineInfo.count+1));
2004-10-12 21:28:27 +00:00
for (i=0; i<xineInfo.count; i++) {
2003-06-06 04:11:00 +00:00
xineInfo.screens[i].pos.x = xine_screens[i].x_org;
xineInfo.screens[i].pos.y = xine_screens[i].y_org;
xineInfo.screens[i].size.width = xine_screens[i].width;
xineInfo.screens[i].size.height = xine_screens[i].height;
}
XFree(xine_screens);
}
# endif /* !SOLARIS_XINERAMA */
#endif /* XINERAMA */
}
1999-01-06 15:22:33 +00:00
RImage*
loadImage(RContext *rc, char *file)
1998-09-29 22:36:29 +00:00
{
1999-01-06 15:22:33 +00:00
char *path;
RImage *image;
1998-09-29 22:36:29 +00:00
1999-01-25 19:06:50 +00:00
if (access(file, F_OK)!=0) {
2004-10-12 21:28:27 +00:00
path = wfindfile(PixmapPath, file);
if (!path) {
wwarning("%s:could not find image file used in texture", file);
return NULL;
}
1999-01-25 19:06:50 +00:00
} else {
2004-10-12 21:28:27 +00:00
path = wstrdup(file);
1999-01-06 15:22:33 +00:00
}
1998-09-29 22:36:29 +00:00
1999-01-06 15:22:33 +00:00
image = RLoadImage(rc, path, 0);
if (!image) {
2004-10-12 21:28:27 +00:00
wwarning("%s:could not load image file used in texture:%s", path,
RMessageForError(RErrorCode));
1999-01-06 15:22:33 +00:00
}
wfree(path);
1998-09-29 22:36:29 +00:00
1999-01-06 15:22:33 +00:00
return image;
}
1998-09-29 22:36:29 +00:00
1999-01-06 15:22:33 +00:00
static void
applyImage(RContext *rc, BackgroundTexture *texture, RImage *image, char type,
int x, int y, int width, int height)
{
int w, h;
Bool fimage = False;
switch (toupper(type)) {
case 'S':
case 'M':
if (toupper(type) == 'S') {
w = width;
h = height;
} else {
if (image->width*height > image->height*width) {
w = width;
h = (width*image->height) / image->width;
} else {
w = (height*image->width) / image->height;
h = height;
}
}
if (w != image->width || h != image->height) {
RImage * simage;
if (smooth) {
simage = RSmoothScaleImage(image, w, h);
} else {
simage = RScaleImage(image, w, h);
}
if (!simage) {
wwarning("could not scale image:%s", RMessageForError(RErrorCode));
return;
}
fimage = True;
image = simage;
}
/* fall through */
case 'C':
{
Pixmap pixmap;
if (!RConvertImage(rc, image, &pixmap)) {
wwarning("could not convert texture:%s", RMessageForError(RErrorCode));
return;
}
if (image->width != width || image->height != height) {
int sx, sy, w, h;
if (image->height < height) {
h = image->height;
y += (height - h) / 2;
sy = 0;
} else {
sy = (image->height - height) / 2;
h = height;
}
if (image->width < width) {
w = image->width;
x += (width - w) / 2;
sx = 0;
} else {
sx = (image->width - width) / 2;
w = width;
}
XCopyArea(dpy, pixmap, texture->pixmap, DefaultGC(dpy, scr), sx, sy, w, h, x, y);
} else
XCopyArea(dpy, pixmap, texture->pixmap, DefaultGC(dpy, scr), 0, 0, width, height, x, y);
XFreePixmap(dpy, pixmap);
if (fimage) {
RReleaseImage( image);
}
}
break;
}
}
1999-01-06 15:22:33 +00:00
BackgroundTexture*
parseTexture(RContext *rc, char *text)
{
BackgroundTexture *texture = NULL;
WMPropList *texarray;
WMPropList *val;
1999-01-06 15:22:33 +00:00
int count;
char *tmp;
char *type;
#define GETSTRORGOTO(val, str, i, label) \
2004-10-12 21:28:27 +00:00
val = WMGetFromPLArray(texarray, i);\
if (!WMIsPLString(val)) {\
wwarning("could not parse texture %s", text);\
goto label;\
}\
str = WMGetFromPLString(val)
1999-01-06 15:22:33 +00:00
texarray = WMCreatePropListFromDescription(text);
2004-10-12 21:28:27 +00:00
if (!texarray || !WMIsPLArray(texarray)
|| (count = WMGetPropListItemCount(texarray)) < 2) {
1999-01-06 15:22:33 +00:00
2004-10-12 21:28:27 +00:00
wwarning("could not parse texture %s", text);
if (texarray)
WMReleasePropList(texarray);
return NULL;
1998-09-29 22:36:29 +00:00
}
1999-01-06 15:22:33 +00:00
texture = wmalloc(sizeof(BackgroundTexture));
memset(texture, 0, sizeof(BackgroundTexture));
GETSTRORGOTO(val, type, 0, error);
1999-01-06 15:22:33 +00:00
if (strcasecmp(type, "solid")==0) {
2004-10-12 21:28:27 +00:00
XColor color;
Pixmap pixmap;
texture->solid = 1;
GETSTRORGOTO(val, tmp, 1, error);
if (!XParseColor(dpy, DefaultColormap(dpy, scr), tmp, &color)) {
wwarning("could not parse color %s in texture %s", tmp, text);
goto error;
}
XAllocColor(dpy, DefaultColormap(dpy, scr), &color);
pixmap = XCreatePixmap(dpy, root, 8, 8, DefaultDepth(dpy, scr));
XSetForeground(dpy, DefaultGC(dpy, scr), color.pixel);
XFillRectangle(dpy, pixmap, DefaultGC(dpy, scr), 0, 0, 8, 8);
texture->pixmap = pixmap;
texture->color = color;
texture->width = 8;
texture->height = 8;
1999-01-06 15:22:33 +00:00
} else if (strcasecmp(type, "vgradient")==0
2004-10-12 21:28:27 +00:00
|| strcasecmp(type, "dgradient")==0
|| strcasecmp(type, "hgradient")==0) {
XColor color;
RColor color1, color2;
RImage *image;
Pixmap pixmap;
int gtype;
int iwidth, iheight;
GETSTRORGOTO(val, tmp, 1, error);
if (!XParseColor(dpy, DefaultColormap(dpy, scr), tmp, &color)) {
wwarning("could not parse color %s in texture %s", tmp, text);
goto error;
}
color1.red = color.red >> 8;
color1.green = color.green >> 8;
color1.blue = color.blue >> 8;
GETSTRORGOTO(val, tmp, 2, error);
if (!XParseColor(dpy, DefaultColormap(dpy, scr), tmp, &color)) {
wwarning("could not parse color %s in texture %s", tmp, text);
goto error;
}
color2.red = color.red >> 8;
color2.green = color.green >> 8;
color2.blue = color.blue >> 8;
switch (type[0]) {
case 'h':
case 'H':
gtype = RHorizontalGradient;
iwidth = scrWidth;
iheight = 32;
break;
case 'V':
case 'v':
gtype = RVerticalGradient;
iwidth = 32;
iheight = scrHeight;
break;
default:
gtype = RDiagonalGradient;
iwidth = scrWidth;
iheight = scrHeight;
break;
}
image = RRenderGradient(iwidth, iheight, &color1, &color2, gtype);
if (!image) {
wwarning("could not render gradient texture:%s",
RMessageForError(RErrorCode));
goto error;
}
if (!RConvertImage(rc, image, &pixmap)) {
wwarning("could not convert texture:%s",
RMessageForError(RErrorCode));
RReleaseImage(image);
goto error;
}
texture->width = image->width;
texture->height = image->height;
RReleaseImage(image);
texture->pixmap = pixmap;
1999-01-06 15:22:33 +00:00
} else if (strcasecmp(type, "mvgradient")==0
2004-10-12 21:28:27 +00:00
|| strcasecmp(type, "mdgradient")==0
|| strcasecmp(type, "mhgradient")==0) {
XColor color;
RColor **colors;
RImage *image;
Pixmap pixmap;
int i, j;
int gtype;
int iwidth, iheight;
colors = malloc(sizeof(RColor*)*(count-1));
if (!colors) {
wwarning("out of memory while parsing texture");
goto error;
}
memset(colors, 0, sizeof(RColor*)*(count-1));
for (i = 2; i < count; i++) {
val = WMGetFromPLArray(texarray, i);
if (!WMIsPLString(val)) {
wwarning("could not parse texture %s", text);
for (j = 0; colors[j]!=NULL; j++)
wfree(colors[j]);
wfree(colors);
goto error;
}
tmp = WMGetFromPLString(val);
if (!XParseColor(dpy, DefaultColormap(dpy, scr), tmp, &color)) {
wwarning("could not parse color %s in texture %s",
tmp, text);
for (j = 0; colors[j]!=NULL; j++)
wfree(colors[j]);
wfree(colors);
goto error;
}
if (!(colors[i-2] = malloc(sizeof(RColor)))) {
wwarning("out of memory while parsing texture");
for (j = 0; colors[j]!=NULL; j++)
wfree(colors[j]);
wfree(colors);
goto error;
}
colors[i-2]->red = color.red >> 8;
colors[i-2]->green = color.green >> 8;
colors[i-2]->blue = color.blue >> 8;
}
switch (type[1]) {
case 'h':
case 'H':
gtype = RHorizontalGradient;
iwidth = scrWidth;
iheight = 32;
break;
case 'V':
case 'v':
gtype = RVerticalGradient;
iwidth = 32;
iheight = scrHeight;
break;
default:
gtype = RDiagonalGradient;
iwidth = scrWidth;
iheight = scrHeight;
break;
}
image = RRenderMultiGradient(iwidth, iheight, colors, gtype);
for (j = 0; colors[j]!=NULL; j++)
wfree(colors[j]);
wfree(colors);
if (!image) {
wwarning("could not render gradient texture:%s",
RMessageForError(RErrorCode));
goto error;
}
if (!RConvertImage(rc, image, &pixmap)) {
wwarning("could not convert texture:%s",
RMessageForError(RErrorCode));
RReleaseImage(image);
goto error;
}
texture->width = image->width;
texture->height = image->height;
RReleaseImage(image);
texture->pixmap = pixmap;
1999-01-06 15:22:33 +00:00
} else if (strcasecmp(type, "cpixmap")==0
2004-10-12 21:28:27 +00:00
|| strcasecmp(type, "spixmap")==0
|| strcasecmp(type, "mpixmap")==0
|| strcasecmp(type, "tpixmap")==0) {
XColor color;
Pixmap pixmap = None;
RImage *image = NULL;
int iwidth, iheight;
RColor rcolor;
GETSTRORGOTO(val, tmp, 1, error);
/*
if (toupper(type[0]) == 'T' || toupper(type[0]) == 'C')
pixmap = LoadJPEG(rc, tmp, &iwidth, &iheight);
*/
if (!pixmap) {
image = loadImage(rc, tmp);
if (!image) {
goto error;
}
iwidth = image->width;
iheight = image->height;
}
GETSTRORGOTO(val, tmp, 2, error);
if (!XParseColor(dpy, DefaultColormap(dpy, scr), tmp, &color)) {
wwarning("could not parse color %s in texture %s\n", tmp, text);
RReleaseImage(image);
goto error;
}
if (!XAllocColor(dpy, DefaultColormap(dpy, scr), &color)) {
rcolor.red = color.red >> 8;
rcolor.green = color.green >> 8;
rcolor.blue = color.blue >> 8;
RGetClosestXColor(rc, &rcolor, &color);
} else {
rcolor.red = 0;
rcolor.green = 0;
rcolor.blue = 0;
}
/* for images with a transparent color */
if (image->data[3]) {
RCombineImageWithColor(image, &rcolor);
}
switch (toupper(type[0])) {
case 'T':
texture->width = iwidth;
texture->height = iheight;
if (!pixmap && !RConvertImage(rc, image, &pixmap)) {
wwarning("could not convert texture:%s",
RMessageForError(RErrorCode));
RReleaseImage(image);
goto error;
}
if (image)
RReleaseImage(image);
1999-01-06 15:22:33 +00:00
2003-02-13 16:27:45 +00:00
texture->pixmap = pixmap;
texture->color = color;
2004-10-12 21:28:27 +00:00
break;
case 'S':
case 'M':
case 'C':
{
Pixmap tpixmap = XCreatePixmap( dpy, root, scrWidth, scrHeight, DefaultDepth(dpy, scr));
XFillRectangle(dpy, tpixmap, DefaultGC(dpy, scr), 0, 0, scrWidth, scrHeight);
texture->pixmap = tpixmap;
texture->color = color;
texture->width = scrWidth;
texture->height = scrHeight;
#ifdef XINERAMA
2004-10-12 21:28:27 +00:00
if (xineInfo.count) {
int i;
2004-10-12 21:28:27 +00:00
for (i=0; i<xineInfo.count; ++i) {
applyImage(rc, texture, image, type[0],
xineInfo.screens[i].pos.x, xineInfo.screens[i].pos.y,
xineInfo.screens[i].size.width, xineInfo.screens[i].size.height);
2004-10-12 21:28:27 +00:00
}
} else {
applyImage(rc, texture, image, type[0], 0, 0, scrWidth, scrHeight);
}
2003-02-13 16:27:45 +00:00
#else /* !XINERAMA */
applyImage(rc, texture, image, type[0], 0, 0, scrWidth, scrHeight);
2003-02-13 16:27:45 +00:00
#endif /* !XINERAMA */
2004-10-12 21:28:27 +00:00
RReleaseImage(image);
}
break;
}
1999-01-06 15:22:33 +00:00
} else if (strcasecmp(type, "thgradient")==0
2004-10-12 21:28:27 +00:00
|| strcasecmp(type, "tvgradient")==0
|| strcasecmp(type, "tdgradient")==0) {
XColor color;
RColor color1, color2;
RImage *image;
RImage *gradient;
RImage *tiled;
Pixmap pixmap;
int opaq;
char *file;
int gtype;
int twidth, theight;
GETSTRORGOTO(val, file, 1, error);
GETSTRORGOTO(val, tmp, 2, error);
opaq = atoi(tmp);
GETSTRORGOTO(val, tmp, 3, error);
if (!XParseColor(dpy, DefaultColormap(dpy, scr), tmp, &color)) {
wwarning("could not parse color %s in texture %s", tmp, text);
goto error;
}
color1.red = color.red >> 8;
color1.green = color.green >> 8;
color1.blue = color.blue >> 8;
GETSTRORGOTO(val, tmp, 4, error);
if (!XParseColor(dpy, DefaultColormap(dpy, scr), tmp, &color)) {
wwarning("could not parse color %s in texture %s", tmp, text);
goto error;
}
color2.red = color.red >> 8;
color2.green = color.green >> 8;
color2.blue = color.blue >> 8;
image = loadImage(rc, file);
if (!image) {
goto error;
}
switch (type[1]) {
case 'h':
case 'H':
gtype = RHorizontalGradient;
twidth = scrWidth;
theight = image->height > scrHeight ? scrHeight : image->height;
break;
case 'V':
case 'v':
gtype = RVerticalGradient;
twidth = image->width > scrWidth ? scrWidth : image->width;
theight = scrHeight;
break;
default:
gtype = RDiagonalGradient;
twidth = scrWidth;
theight = scrHeight;
break;
}
gradient = RRenderGradient(twidth, theight, &color1, &color2, gtype);
if (!gradient) {
wwarning("could not render texture:%s",
RMessageForError(RErrorCode));
RReleaseImage(gradient);
RReleaseImage(image);
goto error;
}
tiled = RMakeTiledImage(image, twidth, theight);
if (!tiled) {
wwarning("could not render texture:%s",
RMessageForError(RErrorCode));
2001-04-21 07:12:21 +00:00
RReleaseImage(gradient);
RReleaseImage(image);
2004-10-12 21:28:27 +00:00
goto error;
}
RReleaseImage(image);
RCombineImagesWithOpaqueness(tiled, gradient, opaq);
RReleaseImage(gradient);
if (!RConvertImage(rc, tiled, &pixmap)) {
wwarning("could not convert texture:%s",
RMessageForError(RErrorCode));
RReleaseImage(tiled);
goto error;
}
texture->width = tiled->width;
texture->height = tiled->height;
RReleaseImage(tiled);
texture->pixmap = pixmap;
} else if (strcasecmp(type, "function")==0) {
#ifdef HAVE_DLFCN_H
2004-10-12 21:28:27 +00:00
void (*initFunc) (Display*, Colormap);
RImage* (*mainFunc) (int, char**, int, int, int);
Pixmap pixmap;
RImage *image = 0;
int success = 0;
char *lib, *func, **argv = 0;
void *handle = 0;
int i, argc;
if (count < 3)
2004-10-12 21:28:27 +00:00
goto function_cleanup;
2004-10-12 21:28:27 +00:00
/* get the library name */
GETSTRORGOTO(val, lib, 1, function_cleanup);
2004-10-12 21:28:27 +00:00
/* get the function name */
GETSTRORGOTO(val, func, 2, function_cleanup);
2004-10-12 21:28:27 +00:00
argc = count - 2;
argv = (char**)wmalloc(argc * sizeof(char*));
2004-10-12 21:28:27 +00:00
/* get the parameters */
argv[0] = func;
for (i=0; i<argc-1; i++) {
GETSTRORGOTO(val, tmp, 3+i, function_cleanup);
argv[i+1] = wstrdup(tmp);
}
2004-10-12 21:28:27 +00:00
handle = dlopen(lib, RTLD_LAZY);
if (!handle) {
wwarning("could not find library %s", lib);
2004-10-12 21:28:27 +00:00
goto function_cleanup;
}
2004-10-12 21:28:27 +00:00
initFunc = dlsym(handle, "initWindowMaker");
if (!initFunc) {
2004-10-12 21:28:27 +00:00
wwarning("could not initialize library %s", lib);
goto function_cleanup;
}
initFunc(dpy, DefaultColormap(dpy, scr));
mainFunc = dlsym(handle, func);
if (!mainFunc) {
wwarning("could not find function %s::%s", lib, func);
2004-10-12 21:28:27 +00:00
goto function_cleanup;
}
image = mainFunc(argc, argv, scrWidth, scrHeight, 0);
if (!RConvertImage(rc, image, &pixmap)) {
2004-10-12 21:28:27 +00:00
wwarning("could not convert texture:%s",
RMessageForError(RErrorCode));
goto function_cleanup;
}
texture->width = scrWidth;
texture->height = scrHeight;
2004-10-12 21:28:27 +00:00
texture->pixmap = pixmap;
success = 1;
2004-10-12 21:28:27 +00:00
function_cleanup:
if (argv) {
2004-10-12 21:28:27 +00:00
int i;
for (i=0; i<argc; i++) {
wfree(argv[i]);
}
}
if (handle) {
dlclose(handle);
}
if (image) {
2001-04-21 07:12:21 +00:00
RReleaseImage(image);
2004-10-12 21:28:27 +00:00
}
if (!success) {
goto error;
}
#else
2004-10-12 21:28:27 +00:00
wwarning("function textures not supported");
goto error;
#endif
1999-01-06 15:22:33 +00:00
} else {
2004-10-12 21:28:27 +00:00
wwarning("invalid texture type %s", text);
goto error;
1999-01-06 15:22:33 +00:00
}
texture->spec = wstrdup(text);
return texture;
error:
if (texture)
2004-10-12 21:28:27 +00:00
wfree(texture);
1999-01-06 15:22:33 +00:00
if (texarray)
2004-10-12 21:28:27 +00:00
WMReleasePropList(texarray);
1999-01-06 15:22:33 +00:00
return NULL;
1998-09-29 22:36:29 +00:00
}
1999-01-06 15:22:33 +00:00
void
freeTexture(BackgroundTexture *texture)
1998-09-29 22:36:29 +00:00
{
1999-01-06 15:22:33 +00:00
if (texture->solid) {
2004-10-12 21:28:27 +00:00
long pixel[1];
1999-01-06 15:22:33 +00:00
2004-10-12 21:28:27 +00:00
pixel[0] = texture->color.pixel;
/* dont free black/white pixels */
if (pixel[0]!=BlackPixelOfScreen(DefaultScreenOfDisplay(dpy))
&& pixel[0]!=WhitePixelOfScreen(DefaultScreenOfDisplay(dpy)))
XFreeColors(dpy, DefaultColormap(dpy, scr), pixel, 1, 0);
1998-09-29 22:36:29 +00:00
}
1999-04-19 00:27:47 +00:00
if (texture->pixmap) {
2004-10-12 21:28:27 +00:00
XFreePixmap(dpy, texture->pixmap);
1999-04-19 00:27:47 +00:00
}
wfree(texture->spec);
wfree(texture);
1998-09-29 22:36:29 +00:00
}
1999-01-06 15:22:33 +00:00
void
setupTexture(RContext *rc, BackgroundTexture **textures, int *maxTextures,
2004-10-12 21:28:27 +00:00
int workspace, char *texture)
1998-09-29 22:36:29 +00:00
{
1999-01-06 15:22:33 +00:00
BackgroundTexture *newTexture = NULL;
int i;
1998-09-29 22:36:29 +00:00
1999-01-06 15:22:33 +00:00
/* unset the texture */
if (!texture) {
2004-10-12 21:28:27 +00:00
if (textures[workspace]!=NULL) {
textures[workspace]->refcount--;
if (textures[workspace]->refcount == 0)
freeTexture(textures[workspace]);
}
textures[workspace] = NULL;
return;
1998-09-29 22:36:29 +00:00
}
1999-01-06 15:22:33 +00:00
2004-10-12 21:28:27 +00:00
if (textures[workspace]
&& strcasecmp(textures[workspace]->spec, texture)==0) {
/* texture did not change */
return;
1999-01-06 15:22:33 +00:00
}
/* check if the same texture is already created */
for (i = 0; i < *maxTextures; i++) {
2004-10-12 21:28:27 +00:00
if (textures[i] && strcasecmp(textures[i]->spec, texture)==0) {
newTexture = textures[i];
break;
}
1999-01-06 15:22:33 +00:00
}
if (!newTexture) {
2004-10-12 21:28:27 +00:00
/* create the texture */
newTexture = parseTexture(rc, texture);
1998-09-29 22:36:29 +00:00
}
1999-01-06 15:22:33 +00:00
if (!newTexture)
2004-10-12 21:28:27 +00:00
return;
1999-01-06 15:22:33 +00:00
if (textures[workspace]!=NULL) {
2004-10-12 21:28:27 +00:00
textures[workspace]->refcount--;
1999-01-06 15:22:33 +00:00
2004-10-12 21:28:27 +00:00
if (textures[workspace]->refcount == 0)
freeTexture(textures[workspace]);
1999-01-06 15:22:33 +00:00
}
newTexture->refcount++;
textures[workspace] = newTexture;
if (*maxTextures < workspace)
2004-10-12 21:28:27 +00:00
*maxTextures = workspace;
1998-09-29 22:36:29 +00:00
}
1999-01-06 15:22:33 +00:00
Pixmap
duplicatePixmap(Pixmap pixmap, int width, int height)
1998-09-29 22:36:29 +00:00
{
1999-01-06 15:22:33 +00:00
Display *tmpDpy;
Pixmap copyP;
2004-10-12 21:28:27 +00:00
1999-01-06 15:22:33 +00:00
/* must open a new display or the RetainPermanent will
* leave stuff allocated in RContext unallocated after exit */
1999-01-25 19:06:50 +00:00
tmpDpy = XOpenDisplay(display);
1999-01-06 15:22:33 +00:00
if (!tmpDpy) {
2004-10-12 21:28:27 +00:00
wwarning("could not open display to update background image information");
1999-01-06 15:22:33 +00:00
2004-10-12 21:28:27 +00:00
return None;
1999-01-06 15:22:33 +00:00
} else {
2004-10-12 21:28:27 +00:00
XSync(dpy, False);
1999-01-06 15:22:33 +00:00
2004-10-12 21:28:27 +00:00
copyP = XCreatePixmap(tmpDpy, root, width, height,
DefaultDepth(tmpDpy, scr));
XCopyArea(tmpDpy, pixmap, copyP, DefaultGC(tmpDpy, scr),
0, 0, width, height, 0, 0);
XSync(tmpDpy, False);
1999-01-06 15:22:33 +00:00
2004-10-12 21:28:27 +00:00
XSetCloseDownMode(tmpDpy, RetainPermanent);
XCloseDisplay(tmpDpy);
1999-01-06 15:22:33 +00:00
}
return copyP;
1998-09-29 22:36:29 +00:00
}
1999-03-09 14:58:01 +00:00
static int
dummyErrorHandler(Display *dpy, XErrorEvent *err)
{
return 0;
}
1998-09-29 22:36:29 +00:00
void
1999-01-06 15:22:33 +00:00
setPixmapProperty(Pixmap pixmap)
1998-09-29 22:36:29 +00:00
{
1999-01-06 15:22:33 +00:00
static Atom prop = 0;
Atom type;
int format;
unsigned long length, after;
unsigned char *data;
int mode;
2004-10-12 21:28:27 +00:00
1999-01-06 15:22:33 +00:00
if (!prop) {
2004-10-12 21:28:27 +00:00
prop = XInternAtom(dpy, "_XROOTPMAP_ID", False);
1999-01-06 15:22:33 +00:00
}
XGrabServer(dpy);
/* Clear out the old pixmap */
XGetWindowProperty(dpy, root, prop, 0L, 1L, False, AnyPropertyType,
&type, &format, &length, &after, &data);
if ((type == XA_PIXMAP) && (format == 32) && (length == 1)) {
2004-10-12 21:28:27 +00:00
XSetErrorHandler(dummyErrorHandler);
1999-01-06 15:22:33 +00:00
XKillClient(dpy, *((Pixmap *)data));
2004-10-12 21:28:27 +00:00
XSync(dpy, False);
XSetErrorHandler(NULL);
mode = PropModeReplace;
1999-01-06 15:22:33 +00:00
} else {
2004-10-12 21:28:27 +00:00
mode = PropModeAppend;
1999-01-06 15:22:33 +00:00
}
if (pixmap)
2004-10-12 21:28:27 +00:00
XChangeProperty(dpy, root, prop, XA_PIXMAP, 32, mode,
(unsigned char *) &pixmap, 1);
1999-01-06 15:22:33 +00:00
else
2004-10-12 21:28:27 +00:00
XDeleteProperty(dpy, root, prop);
1999-01-06 15:22:33 +00:00
XUngrabServer(dpy);
XFlush(dpy);
1998-09-29 22:36:29 +00:00
}
1999-01-06 15:22:33 +00:00
void
changeTexture(BackgroundTexture *texture)
1998-09-29 22:36:29 +00:00
{
1999-09-16 03:01:14 +00:00
if (!texture) {
2004-10-12 21:28:27 +00:00
return;
1999-09-16 03:01:14 +00:00
}
1998-09-29 22:36:29 +00:00
1999-01-06 15:22:33 +00:00
if (texture->solid) {
2004-10-12 21:28:27 +00:00
XSetWindowBackground(dpy, root, texture->color.pixel);
1998-09-29 22:36:29 +00:00
} else {
2004-10-12 21:28:27 +00:00
XSetWindowBackgroundPixmap(dpy, root, texture->pixmap);
1998-09-29 22:36:29 +00:00
}
1999-01-06 15:22:33 +00:00
XClearWindow(dpy, root);
XSync(dpy, False);
1998-09-29 22:36:29 +00:00
1999-01-06 15:22:33 +00:00
{
2004-10-12 21:28:27 +00:00
Pixmap pixmap;
pixmap = duplicatePixmap(texture->pixmap, texture->width,
texture->height);
1998-09-29 22:36:29 +00:00
2004-10-12 21:28:27 +00:00
setPixmapProperty(pixmap);
1999-01-06 15:22:33 +00:00
}
1998-09-29 22:36:29 +00:00
}
1999-01-06 15:22:33 +00:00
int
readmsg(int fd, unsigned char *buffer, int size)
1998-09-29 22:36:29 +00:00
{
1999-01-06 15:22:33 +00:00
int count;
2004-10-12 21:28:27 +00:00
1999-01-06 15:22:33 +00:00
count = 0;
while (size>0) {
2004-10-12 21:28:27 +00:00
count = read(fd, buffer, size);
if (count < 0)
return -1;
size -= count;
buffer += count;
*buffer = 0;
1999-01-06 15:22:33 +00:00
}
return size;
1998-09-29 22:36:29 +00:00
}
1999-01-06 15:22:33 +00:00
/*
* Message Format:
* sizeSntexture_spec - sets the texture for workspace n
* sizeCn - change background texture to the one for workspace n
* sizePpath - set the pixmap search path
2004-10-12 21:28:27 +00:00
*
1999-01-06 15:22:33 +00:00
* n is 4 bytes
* size = 4 bytes for length of the message data
*/
void
helperLoop(RContext *rc)
1998-09-29 22:36:29 +00:00
{
1999-01-06 15:22:33 +00:00
BackgroundTexture *textures[WORKSPACE_COUNT];
int maxTextures = 0;
unsigned char buffer[2048], buf[8];
int size;
int errcount = 4;
memset(textures, 0, WORKSPACE_COUNT*sizeof(BackgroundTexture*));
while (1) {
2004-10-12 21:28:27 +00:00
int workspace;
/* get length of message */
if (readmsg(0, buffer, 4) < 0) {
wsyserror("error reading message from Window Maker");
errcount--;
if (errcount == 0) {
wfatal("quitting");
exit(1);
}
continue;
}
memcpy(buf, buffer, 4);
buf[4] = 0;
size = atoi(buf);
/* get message */
if (readmsg(0, buffer, size) < 0) {
wsyserror("error reading message from Window Maker");
errcount--;
if (errcount == 0) {
wfatal("quitting");
exit(1);
}
continue;
}
1999-01-06 15:22:33 +00:00
#ifdef DEBUG
2004-10-12 21:28:27 +00:00
printf("RECEIVED %s\n",buffer);
1999-01-06 15:22:33 +00:00
#endif
2004-10-12 21:28:27 +00:00
if (buffer[0]!='P' && buffer[0]!='K') {
memcpy(buf, &buffer[1], 4);
buf[4] = 0;
workspace = atoi(buf);
if (workspace < 0 || workspace >= WORKSPACE_COUNT) {
wwarning("received message with invalid workspace number %i\n",
workspace);
continue;
}
}
switch (buffer[0]) {
case 'S':
1999-01-06 15:22:33 +00:00
#ifdef DEBUG
2004-10-12 21:28:27 +00:00
printf("set texture %s\n", &buffer[5]);
1999-01-06 15:22:33 +00:00
#endif
2004-10-12 21:28:27 +00:00
setupTexture(rc, textures, &maxTextures, workspace, &buffer[5]);
break;
1999-01-06 15:22:33 +00:00
2004-10-12 21:28:27 +00:00
case 'C':
1999-01-06 15:22:33 +00:00
#ifdef DEBUG
2004-10-12 21:28:27 +00:00
printf("change texture %i\n", workspace);
1999-01-06 15:22:33 +00:00
#endif
2004-10-12 21:28:27 +00:00
if (!textures[workspace]) {
changeTexture(textures[0]);
} else {
changeTexture(textures[workspace]);
}
break;
case 'P':
1999-01-06 15:22:33 +00:00
#ifdef DEBUG
2004-10-12 21:28:27 +00:00
printf("change pixmappath %s\n", &buffer[1]);
1999-01-06 15:22:33 +00:00
#endif
2004-10-12 21:28:27 +00:00
if (PixmapPath)
wfree(PixmapPath);
PixmapPath = wstrdup(&buffer[1]);
break;
1999-01-06 15:22:33 +00:00
2004-10-12 21:28:27 +00:00
case 'U':
1999-01-06 15:22:33 +00:00
#ifdef DEBUG
2004-10-12 21:28:27 +00:00
printf("unset workspace %i\n", workspace);
1999-01-06 15:22:33 +00:00
#endif
2004-10-12 21:28:27 +00:00
setupTexture(rc, textures, &maxTextures, workspace, NULL);
break;
1999-01-06 15:22:33 +00:00
2004-10-12 21:28:27 +00:00
case 'K':
1999-01-11 12:28:12 +00:00
#ifdef DEBUG
2004-10-12 21:28:27 +00:00
printf("exit command\n");
1999-01-11 12:28:12 +00:00
#endif
2004-10-12 21:28:27 +00:00
exit(0);
1999-01-11 12:28:12 +00:00
2004-10-12 21:28:27 +00:00
default:
wwarning("unknown message received");
break;
}
1999-01-06 15:22:33 +00:00
}
}
void
updateDomain(char *domain, char *key, char *texture)
1999-01-06 15:22:33 +00:00
{
char *program = "wdwrite";
/* here is a mem leak */
2004-10-12 21:28:27 +00:00
system(wstrconcat("wdwrite ",
wstrconcat(domain, smooth ? " SmoothWorkspaceBack YES"
: " SmoothWorkspaceBack NO")));
execlp(program, program, domain, key, texture, NULL);
1999-01-06 15:22:33 +00:00
wwarning("warning could not run \"%s\"", program);
}
char*
globalDefaultsPathForDomain(char *domain)
{
char path[1024];
1999-09-17 02:00:22 +00:00
sprintf(path, "%s/WindowMaker/%s", SYSCONFDIR, domain);
return wstrdup(path);
}
static WMPropList*
getValueForKey(char *domain, char *keyName)
1999-01-06 15:22:33 +00:00
{
char *path;
WMPropList *key, *val, *d;
1999-01-06 15:22:33 +00:00
key = WMCreatePLString(keyName);
1999-01-06 15:22:33 +00:00
/* try to find PixmapPath in user defaults */
1999-01-06 15:22:33 +00:00
path = wdefaultspathfordomain(domain);
d = WMReadPropListFromFile(path);
if (!d) {
2004-10-12 21:28:27 +00:00
wwarning("could not open domain file %s", path);
1999-01-06 15:22:33 +00:00
}
wfree(path);
1998-09-29 22:36:29 +00:00
if (d && !WMIsPLDictionary(d)) {
2004-10-12 21:28:27 +00:00
WMReleasePropList(d);
d = NULL;
}
if (d) {
2004-10-12 21:28:27 +00:00
val = WMGetFromPLDictionary(d, key);
} else {
2004-10-12 21:28:27 +00:00
val = NULL;
}
/* try to find PixmapPath in global defaults */
if (!val) {
2004-10-12 21:28:27 +00:00
path = globalDefaultsPathForDomain(domain);
if (!path) {
wwarning("could not locate file for domain %s", domain);
d = NULL;
} else {
d = WMReadPropListFromFile(path);
wfree(path);
}
if (d && !WMIsPLDictionary(d)) {
WMReleasePropList(d);
d = NULL;
}
if (d) {
val = WMGetFromPLDictionary(d, key);
} else {
val = NULL;
}
1999-01-06 15:22:33 +00:00
}
if (val)
2004-10-12 21:28:27 +00:00
WMRetainPropList(val);
WMReleasePropList(key);
if (d)
2004-10-12 21:28:27 +00:00
WMReleasePropList(d);
1999-01-06 15:22:33 +00:00
return val;
}
1999-01-06 15:22:33 +00:00
1999-04-19 00:27:47 +00:00
1999-01-06 15:22:33 +00:00
char*
getPixmapPath(char *domain)
1999-01-06 15:22:33 +00:00
{
WMPropList *val;
1999-01-06 15:22:33 +00:00
char *ptr, *data;
int len, i, count;
1998-09-29 22:36:29 +00:00
val = getValueForKey(domain, "PixmapPath");
2004-10-12 21:28:27 +00:00
if (!val || !WMIsPLArray(val)) {
2004-10-12 21:28:27 +00:00
if (val)
WMReleasePropList(val);
return wstrdup("");
1999-01-06 15:22:33 +00:00
}
1998-09-29 22:36:29 +00:00
count = WMGetPropListItemCount(val);
1999-01-06 15:22:33 +00:00
len = 0;
for (i=0; i<count; i++) {
2004-10-12 21:28:27 +00:00
WMPropList *v;
2004-10-12 21:28:27 +00:00
v = WMGetFromPLArray(val, i);
if (!v || !WMIsPLString(v)) {
continue;
}
len += strlen(WMGetFromPLString(v))+1;
1999-01-06 15:22:33 +00:00
}
1998-09-29 22:36:29 +00:00
1999-01-06 15:22:33 +00:00
ptr = data = wmalloc(len+1);
*ptr = 0;
1998-09-29 22:36:29 +00:00
for (i=0; i<count; i++) {
2004-10-12 21:28:27 +00:00
WMPropList *v;
2004-10-12 21:28:27 +00:00
v = WMGetFromPLArray(val, i);
if (!v || !WMIsPLString(v)) {
continue;
}
strcpy(ptr, WMGetFromPLString(v));
1999-01-06 15:22:33 +00:00
2004-10-12 21:28:27 +00:00
ptr += strlen(WMGetFromPLString(v));
*ptr = ':';
ptr++;
1998-09-29 22:36:29 +00:00
}
1999-01-06 15:22:33 +00:00
if (i>0)
2004-10-12 21:28:27 +00:00
ptr--; *(ptr--) = 0;
1999-01-06 15:22:33 +00:00
2004-10-12 21:28:27 +00:00
WMReleasePropList(val);
2004-10-12 21:28:27 +00:00
return data;
1998-09-29 22:36:29 +00:00
}
2000-03-09 18:50:26 +00:00
char*
getFullPixmapPath(char *file)
{
char *tmp;
if (!PixmapPath || !(tmp = wfindfile(PixmapPath, file))) {
2004-10-12 21:28:27 +00:00
int bsize = 512;
char *path = wmalloc(bsize);
while (!getcwd(path, bsize)) {
bsize += bsize/2;
path = wrealloc(path, bsize);
}
tmp = wstrconcat(path, "/");
wfree(path);
path = wstrconcat(tmp, file);
wfree(tmp);
return path;
2000-03-09 18:50:26 +00:00
}
2004-10-12 21:28:27 +00:00
2000-03-09 18:50:26 +00:00
/* the file is in the PixmapPath */
wfree(tmp);
2000-03-09 18:50:26 +00:00
2000-03-20 02:15:48 +00:00
return wstrdup(file);
2000-03-09 18:50:26 +00:00
}
1999-01-06 15:22:33 +00:00
void
wAbort()
{
wfatal("aborting");
exit(1);
}
1998-10-21 14:43:47 +00:00
1999-01-06 15:22:33 +00:00
void
print_help(char *ProgName)
{
1999-01-29 08:11:17 +00:00
printf("Usage: %s [options] [image]\n", ProgName);
puts("Sets the workspace background to the specified image or a texture and optionally update Window Maker configuration");
puts("");
1999-01-25 19:06:50 +00:00
#define P(m) puts(m)
2004-10-12 21:28:27 +00:00
P(" -display display to use");
P(" -d, --dither dither image");
P(" -m, --match match colors");
P(" -S, --smooth smooth scaled image");
P(" -b, --back-color <color> background color");
P(" -t, --tile tile image");
P(" -e, --center center image");
P(" -s, --scale scale image (default)");
P(" -a, --maxscale scale image and keep aspect ratio");
P(" -u, --update-wmaker update WindowMaker domain database");
P(" -D, --update-domain <domain> update <domain> database");
P(" -c, --colors <cpc> colors per channel to use");
P(" -p, --parse <texture> proplist style texture specification");
P(" -w, --workspace <workspace> update background for the specified workspace");
P(" --version show version of wmsetbg and exit");
P(" --help show this help and exit");
1999-01-25 19:06:50 +00:00
#undef P
1999-01-06 15:22:33 +00:00
}
void
changeTextureForWorkspace(char *domain, char *texture, int workspace)
1999-01-06 15:22:33 +00:00
{
WMPropList *array, *val;
char *value;
1999-01-06 15:22:33 +00:00
int j;
2004-10-12 21:28:27 +00:00
val = WMCreatePropListFromDescription(texture);
1999-01-06 15:22:33 +00:00
if (!val) {
2004-10-12 21:28:27 +00:00
wwarning("could not parse texture %s", texture);
return;
1999-01-06 15:22:33 +00:00
}
array = getValueForKey("WindowMaker", "WorkspaceSpecificBack");
1999-01-06 15:22:33 +00:00
if (!array) {
2004-10-12 21:28:27 +00:00
array = WMCreatePLArray(NULL, NULL);
1999-01-06 15:22:33 +00:00
}
j = WMGetPropListItemCount(array);
1999-01-06 15:22:33 +00:00
if (workspace >= j) {
2004-10-12 21:28:27 +00:00
WMPropList *empty;
1999-01-06 15:22:33 +00:00
2004-10-12 21:28:27 +00:00
empty = WMCreatePLArray(NULL, NULL);
1999-01-06 15:22:33 +00:00
2004-10-12 21:28:27 +00:00
while (j++ < workspace-1) {
WMAddToPLArray(array, empty);
}
WMAddToPLArray(array, val);
1999-01-06 15:22:33 +00:00
} else {
2004-10-12 21:28:27 +00:00
WMDeleteFromPLArray(array, workspace);
WMInsertInPLArray(array, workspace, val);
1999-01-06 15:22:33 +00:00
}
value = WMGetPropListDescription(array, False);
updateDomain(domain, "WorkspaceSpecificBack", value);
1999-01-06 15:22:33 +00:00
}
1998-10-21 14:43:47 +00:00
1998-09-29 22:36:29 +00:00
int
main(int argc, char **argv)
{
1999-01-06 15:22:33 +00:00
int i;
int helperMode = 0;
RContext *rc;
1998-09-29 22:36:29 +00:00
RContextAttributes rattr;
1999-01-06 15:22:33 +00:00
char *style = "spixmap";
char *back_color = "gray20";
1998-09-29 22:36:29 +00:00
char *image_name = NULL;
char *domain = "WindowMaker";
int update=0, cpc=4, render_mode=RDitheredRendering, obey_user=0;
1999-01-06 15:22:33 +00:00
char *texture = NULL;
int workspace = -1;
2004-10-12 21:28:27 +00:00
1999-01-06 15:22:33 +00:00
signal(SIGINT, SIG_DFL);
signal(SIGTERM, SIG_DFL);
signal(SIGQUIT, SIG_DFL);
signal(SIGSEGV, SIG_DFL);
signal(SIGBUS, SIG_DFL);
signal(SIGFPE, SIG_DFL);
signal(SIGABRT, SIG_DFL);
signal(SIGHUP, SIG_DFL);
signal(SIGPIPE, SIG_DFL);
signal(SIGCHLD, SIG_DFL);
2004-10-12 21:28:27 +00:00
1999-01-06 15:22:33 +00:00
WMInitializeApplication("wmsetbg", &argc, argv);
2004-10-12 21:28:27 +00:00
1999-01-25 19:06:50 +00:00
for (i=1; i<argc; i++) {
2004-10-12 21:28:27 +00:00
if (strcmp(argv[i], "-helper")==0) {
helperMode = 1;
} else if (strcmp(argv[i], "-display")==0) {
i++;
if (i>=argc) {
wfatal("too few arguments for %s\n", argv[i-1]);
exit(1);
}
display = argv[i];
} else if (strcmp(argv[i], "-s")==0
|| strcmp(argv[i], "--scale")==0) {
style = "spixmap";
} else if (strcmp(argv[i], "-t")==0
|| strcmp(argv[i], "--tile")==0) {
style = "tpixmap";
} else if (strcmp(argv[i], "-e")==0
|| strcmp(argv[i], "--center")==0) {
style = "cpixmap";
} else if (strcmp(argv[i], "-a")==0
|| strcmp(argv[i], "--maxscale")==0) {
style = "mpixmap";
} else if (strcmp(argv[i], "-d")==0
|| strcmp(argv[i], "--dither")==0) {
render_mode = RDitheredRendering;
obey_user++;
} else if (strcmp(argv[i], "-m")==0
|| strcmp(argv[i], "--match")==0) {
render_mode = RBestMatchRendering;
obey_user++;
} else if (strcmp(argv[i], "-S")==0
|| strcmp(argv[i], "--smooth")==0) {
smooth = True;
} else if (strcmp(argv[i], "-u")==0
|| strcmp(argv[i], "--update-wmaker")==0) {
update++;
} else if (strcmp(argv[i], "-D")==0
|| strcmp(argv[i], "--update-domain")==0) {
update++;
i++;
if (i>=argc) {
wfatal("too few arguments for %s\n", argv[i-1]);
exit(1);
}
domain = wstrdup(argv[i]);
} else if (strcmp(argv[i], "-c")==0
|| strcmp(argv[i], "--colors")==0) {
i++;
if (i>=argc) {
wfatal("too few arguments for %s\n", argv[i-1]);
exit(1);
}
if (sscanf(argv[i], "%i", &cpc)!=1) {
wfatal("bad value for colors per channel: \"%s\"\n", argv[i]);
exit(1);
}
} else if (strcmp(argv[i], "-b")==0
|| strcmp(argv[i], "--back-color")==0) {
i++;
if (i>=argc) {
wfatal("too few arguments for %s\n", argv[i-1]);
exit(1);
}
back_color = argv[i];
} else if (strcmp(argv[i], "-p")==0
|| strcmp(argv[i], "--parse")==0) {
i++;
if (i>=argc) {
wfatal("too few arguments for %s\n", argv[i-1]);
exit(1);
}
texture = argv[i];
} else if (strcmp(argv[i], "-w")==0
|| strcmp(argv[i], "--workspace")==0) {
i++;
if (i>=argc) {
wfatal("too few arguments for %s\n", argv[i-1]);
exit(1);
}
if (sscanf(argv[i], "%i", &workspace)!=1) {
wfatal("bad value for workspace number: \"%s\"",
argv[i]);
exit(1);
}
} else if (strcmp(argv[i], "--version")==0) {
printf(PROG_VERSION);
exit(0);
} else if (strcmp(argv[i], "--help")==0) {
print_help(argv[0]);
exit(0);
} else if (argv[i][0] != '-') {
image_name = argv[i];
} else {
printf("%s: invalid argument '%s'\n", argv[0], argv[i]);
printf("Try '%s --help' for more information\n", argv[0]);
exit(1);
}
1998-09-29 22:36:29 +00:00
}
if (!image_name && !texture && !helperMode) {
2004-10-12 21:28:27 +00:00
printf("%s: you must specify a image file name or a texture\n",
argv[0]);
printf("Try '%s --help' for more information\n", argv[0]);
exit(1);
1999-01-25 19:06:50 +00:00
}
1998-09-29 22:36:29 +00:00
2004-10-12 21:28:27 +00:00
PixmapPath = getPixmapPath(domain);
if (!smooth) {
2004-10-12 21:28:27 +00:00
WMPropList *val;
1999-09-16 03:01:14 +00:00
#if 0 /* some problem with Alpha... TODO: check if its right */
2004-10-12 21:28:27 +00:00
val = WMGetFromPLDictionary(domain,
WMCreatePLString("SmoothWorkspaceBack"));
1999-09-16 03:01:14 +00:00
#else
2004-10-12 21:28:27 +00:00
val = getValueForKey(domain, "SmoothWorkspaceBack");
1999-09-16 03:01:14 +00:00
#endif
2004-10-12 21:28:27 +00:00
if (val && WMIsPLString(val) && strcasecmp(WMGetFromPLString(val), "YES")==0)
smooth = True;
}
1998-09-29 22:36:29 +00:00
1999-01-25 19:06:50 +00:00
dpy = XOpenDisplay(display);
1998-09-29 22:36:29 +00:00
if (!dpy) {
2004-10-12 21:28:27 +00:00
wfatal("could not open display");
exit(1);
1998-09-29 22:36:29 +00:00
}
#if 0
1999-01-06 15:22:33 +00:00
XSynchronize(dpy, 1);
1999-03-30 22:14:17 +00:00
#endif
1999-01-06 15:22:33 +00:00
root = DefaultRootWindow(dpy);
1998-09-29 22:36:29 +00:00
1999-01-06 15:22:33 +00:00
scr = DefaultScreen(dpy);
2004-10-12 21:28:27 +00:00
1999-01-06 15:22:33 +00:00
scrWidth = WidthOfScreen(DefaultScreenOfDisplay(dpy));
scrHeight = HeightOfScreen(DefaultScreenOfDisplay(dpy));
scrX = scrY = 0;
initXinerama();
1999-01-06 15:22:33 +00:00
if (!obey_user && DefaultDepth(dpy, scr) <= 8)
render_mode = RDitheredRendering;
1998-09-29 22:36:29 +00:00
2000-01-14 16:48:16 +00:00
rattr.flags = RC_RenderMode | RC_ColorsPerChannel
2004-10-12 21:28:27 +00:00
| RC_StandardColormap | RC_DefaultVisual;
1998-09-29 22:36:29 +00:00
rattr.render_mode = render_mode;
rattr.colors_per_channel = cpc;
2000-01-14 16:48:16 +00:00
rattr.standard_colormap_mode = RCreateStdColormap;
1998-09-29 22:36:29 +00:00
1999-01-06 15:22:33 +00:00
rc = RCreateContext(dpy, scr, &rattr);
if (!rc) {
rattr.standard_colormap_mode = RIgnoreStdColormap;
rc = RCreateContext(dpy, scr, &rattr);
}
2004-10-12 21:28:27 +00:00
2000-01-14 16:48:16 +00:00
if (!rc) {
2004-10-12 21:28:27 +00:00
wfatal("could not initialize wrlib: %s",
RMessageForError(RErrorCode));
exit(1);
2000-01-14 16:48:16 +00:00
}
1998-09-29 22:36:29 +00:00
1999-01-06 15:22:33 +00:00
if (helperMode) {
2004-10-12 21:28:27 +00:00
/* lower priority, so that it wont use all the CPU */
nice(15);
1998-09-29 22:36:29 +00:00
2004-10-12 21:28:27 +00:00
helperLoop(rc);
1998-09-29 22:36:29 +00:00
} else {
2004-10-12 21:28:27 +00:00
BackgroundTexture *tex;
char buffer[4098];
if (!texture) {
char *image_path = getFullPixmapPath(image_name);
sprintf(buffer, "(%s, \"%s\", %s)", style, image_path, back_color);
wfree(image_path);
texture = (char*)buffer;
}
if (update && workspace < 0) {
updateDomain(domain, "WorkspaceBack", texture);
}
tex = parseTexture(rc, texture);
if (!tex)
exit(1);
if (workspace<0)
changeTexture(tex);
else {
/* always update domain */
changeTextureForWorkspace(domain, texture, workspace);
}
1998-09-29 22:36:29 +00:00
}
1999-01-06 15:22:33 +00:00
1999-01-25 19:06:50 +00:00
return 0;
1998-09-29 22:36:29 +00:00
}
1999-01-06 15:22:33 +00:00