1 /* wmsetbg.c- sets root window background image and also works as
2 * workspace background setting helper for wmaker
4 * WindowMaker window manager
6 * Copyright (c) 1998, 1999 Alfredo K. Kojima
7 * Copyright (c) 1998 Dan Pascu
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
26 * TODO: rewrite, too dirty
33 #include <X11/Xutil.h>
34 #include <X11/Xatom.h>
38 #include <sys/types.h>
41 #include "../src/config.h"
47 #include "../src/wconfig.h"
49 #include "../WINGs/WINGs.h"
50 #include "../WINGs/WUtil.h"
51 #include "../wrlib/wraster.h"
55 #define PROG_VERSION "wmsetbg (Window Maker) 2.1"
58 #define WORKSPACE_COUNT (MAX_WORKSPACES+1)
68 Pixmap CurrentPixmap
= None
;
69 char *PixmapPath
= NULL
;
72 extern Pixmap
LoadJPEG(RContext
*rc
, char *file_name
, int *width
, int *height
);
75 typedef struct BackgroundTexture
{
83 Pixmap pixmap
; /* for all textures, including solid */
84 int width
; /* size of the pixmap */
91 loadImage(RContext
*rc
, char *file
)
96 if (access(file
, F_OK
)!=0) {
97 path
= wfindfile(PixmapPath
, file
);
99 wwarning("%s:could not find image file used in texture", file
);
103 path
= wstrdup(file
);
106 image
= RLoadImage(rc
, path
, 0);
108 wwarning("%s:could not load image file used in texture:%s", path
,
109 RMessageForError(RErrorCode
));
118 parseTexture(RContext
*rc
, char *text
)
120 BackgroundTexture
*texture
= NULL
;
127 #define GETSTRORGOTO(val, str, i, label) \
128 val = PLGetArrayElement(texarray, i);\
129 if (!PLIsString(val)) {\
130 wwarning("could not parse texture %s", text);\
133 str = PLGetString(val)
135 texarray
= PLGetProplistWithDescription(text
);
136 if (!texarray
|| !PLIsArray(texarray
)
137 || (count
= PLGetNumberOfElements(texarray
)) < 2) {
139 wwarning("could not parse texture %s", text
);
145 texture
= wmalloc(sizeof(BackgroundTexture
));
146 memset(texture
, 0, sizeof(BackgroundTexture
));
148 GETSTRORGOTO(val
, type
, 0, error
);
150 if (strcasecmp(type
, "solid")==0) {
156 GETSTRORGOTO(val
, tmp
, 1, error
);
158 if (!XParseColor(dpy
, DefaultColormap(dpy
, scr
), tmp
, &color
)) {
159 wwarning("could not parse color %s in texture %s", tmp
, text
);
162 XAllocColor(dpy
, DefaultColormap(dpy
, scr
), &color
);
164 pixmap
= XCreatePixmap(dpy
, root
, 8, 8, DefaultDepth(dpy
, scr
));
165 XSetForeground(dpy
, DefaultGC(dpy
, scr
), color
.pixel
);
166 XFillRectangle(dpy
, pixmap
, DefaultGC(dpy
, scr
), 0, 0, 8, 8);
168 texture
->pixmap
= pixmap
;
169 texture
->color
= color
;
172 } else if (strcasecmp(type
, "vgradient")==0
173 || strcasecmp(type
, "dgradient")==0
174 || strcasecmp(type
, "hgradient")==0) {
176 RColor color1
, color2
;
182 GETSTRORGOTO(val
, tmp
, 1, error
);
184 if (!XParseColor(dpy
, DefaultColormap(dpy
, scr
), tmp
, &color
)) {
185 wwarning("could not parse color %s in texture %s", tmp
, text
);
189 color1
.red
= color
.red
>> 8;
190 color1
.green
= color
.green
>> 8;
191 color1
.blue
= color
.blue
>> 8;
193 GETSTRORGOTO(val
, tmp
, 2, error
);
195 if (!XParseColor(dpy
, DefaultColormap(dpy
, scr
), tmp
, &color
)) {
196 wwarning("could not parse color %s in texture %s", tmp
, text
);
200 color2
.red
= color
.red
>> 8;
201 color2
.green
= color
.green
>> 8;
202 color2
.blue
= color
.blue
>> 8;
207 gtype
= RHorizontalGradient
;
213 gtype
= RVerticalGradient
;
218 gtype
= RDiagonalGradient
;
224 image
= RRenderGradient(iwidth
, iheight
, &color1
, &color2
, gtype
);
227 wwarning("could not render gradient texture:%s",
228 RMessageForError(RErrorCode
));
232 if (!RConvertImage(rc
, image
, &pixmap
)) {
233 wwarning("could not convert texture:%s",
234 RMessageForError(RErrorCode
));
235 RDestroyImage(image
);
239 texture
->width
= image
->width
;
240 texture
->height
= image
->height
;
241 RDestroyImage(image
);
243 texture
->pixmap
= pixmap
;
244 } else if (strcasecmp(type
, "mvgradient")==0
245 || strcasecmp(type
, "mdgradient")==0
246 || strcasecmp(type
, "mhgradient")==0) {
255 colors
= malloc(sizeof(RColor
*)*(count
-1));
257 wwarning("out of memory while parsing texture");
260 memset(colors
, 0, sizeof(RColor
*)*(count
-1));
262 for (i
= 2; i
< count
; i
++) {
263 val
= PLGetArrayElement(texarray
, i
);
264 if (!PLIsString(val
)) {
265 wwarning("could not parse texture %s", text
);
267 for (j
= 0; colors
[j
]!=NULL
; j
++)
272 tmp
= PLGetString(val
);
274 if (!XParseColor(dpy
, DefaultColormap(dpy
, scr
), tmp
, &color
)) {
275 wwarning("could not parse color %s in texture %s",
278 for (j
= 0; colors
[j
]!=NULL
; j
++)
283 if (!(colors
[i
-2] = malloc(sizeof(RColor
)))) {
284 wwarning("out of memory while parsing texture");
286 for (j
= 0; colors
[j
]!=NULL
; j
++)
292 colors
[i
-2]->red
= color
.red
>> 8;
293 colors
[i
-2]->green
= color
.green
>> 8;
294 colors
[i
-2]->blue
= color
.blue
>> 8;
300 gtype
= RHorizontalGradient
;
306 gtype
= RVerticalGradient
;
311 gtype
= RDiagonalGradient
;
317 image
= RRenderMultiGradient(iwidth
, iheight
, colors
, gtype
);
319 for (j
= 0; colors
[j
]!=NULL
; j
++)
324 wwarning("could not render gradient texture:%s",
325 RMessageForError(RErrorCode
));
329 if (!RConvertImage(rc
, image
, &pixmap
)) {
330 wwarning("could not convert texture:%s",
331 RMessageForError(RErrorCode
));
332 RDestroyImage(image
);
336 texture
->width
= image
->width
;
337 texture
->height
= image
->height
;
338 RDestroyImage(image
);
340 texture
->pixmap
= pixmap
;
341 } else if (strcasecmp(type
, "cpixmap")==0
342 || strcasecmp(type
, "spixmap")==0
343 || strcasecmp(type
, "mpixmap")==0
344 || strcasecmp(type
, "tpixmap")==0) {
346 Pixmap pixmap
= None
;
347 RImage
*image
= NULL
;
351 GETSTRORGOTO(val
, tmp
, 1, error
);
353 if (toupper(type[0]) == 'T' || toupper(type[0]) == 'C')
354 pixmap = LoadJPEG(rc, tmp, &iwidth, &iheight);
358 image
= loadImage(rc
, tmp
);
362 iwidth
= image
->width
;
363 iheight
= image
->height
;
366 GETSTRORGOTO(val
, tmp
, 2, error
);
368 if (!XParseColor(dpy
, DefaultColormap(dpy
, scr
), tmp
, &color
)) {
369 wwarning("could not parse color %s in texture %s\n", tmp
, text
);
370 RDestroyImage(image
);
373 if (!XAllocColor(dpy
, DefaultColormap(dpy
, scr
), &color
)) {
376 rcolor
.red
= color
.red
>> 8;
377 rcolor
.green
= color
.green
>> 8;
378 rcolor
.blue
= color
.blue
>> 8;
379 RGetClosestXColor(rc
, &rcolor
, &color
);
381 switch (toupper(type
[0])) {
383 texture
->width
= iwidth
;
384 texture
->height
= iheight
;
385 if (!pixmap
&& !RConvertImage(rc
, image
, &pixmap
)) {
386 wwarning("could not convert texture:%s",
387 RMessageForError(RErrorCode
));
388 RDestroyImage(image
);
392 RDestroyImage(image
);
396 if (toupper(type
[0])=='S') {
400 if (iwidth
*scrHeight
> iheight
*scrWidth
) {
402 h
= (scrWidth
*iheight
)/iwidth
;
405 w
= (scrHeight
*iwidth
)/iheight
;
411 simage
= RScaleImage(image
, w
, h
);
413 wwarning("could not scale image:%s",
414 RMessageForError(RErrorCode
));
415 RDestroyImage(image
);
418 RDestroyImage(image
);
420 iwidth
= image
->width
;
421 iheight
= image
->height
;
428 if (!pixmap
&& !RConvertImage(rc
, image
, &pixmap
)) {
429 wwarning("could not convert texture:%s",
430 RMessageForError(RErrorCode
));
431 RDestroyImage(image
);
435 if (iwidth
!= scrWidth
|| iheight
!= scrHeight
) {
436 int x
, y
, sx
, sy
, w
, h
;
438 cpixmap
= XCreatePixmap(dpy
, root
, scrWidth
, scrHeight
,
439 DefaultDepth(dpy
, scr
));
441 XSetForeground(dpy
, DefaultGC(dpy
, scr
), color
.pixel
);
442 XFillRectangle(dpy
, cpixmap
, DefaultGC(dpy
, scr
),
443 0, 0, scrWidth
, scrHeight
);
445 if (iheight
< scrHeight
) {
447 y
= (scrHeight
- h
)/2;
450 sy
= (iheight
- scrHeight
)/2;
454 if (iwidth
< scrWidth
) {
456 x
= (scrWidth
- w
)/2;
459 sx
= (iwidth
- scrWidth
)/2;
464 XCopyArea(dpy
, pixmap
, cpixmap
, DefaultGC(dpy
, scr
),
466 XFreePixmap(dpy
, pixmap
);
470 RDestroyImage(image
);
472 texture
->width
= scrWidth
;
473 texture
->height
= scrHeight
;
478 texture
->pixmap
= pixmap
;
479 texture
->color
= color
;
480 } else if (strcasecmp(type
, "thgradient")==0
481 || strcasecmp(type
, "tvgradient")==0
482 || strcasecmp(type
, "tdgradient")==0) {
484 RColor color1
, color2
;
494 GETSTRORGOTO(val
, file
, 1, error
);
496 GETSTRORGOTO(val
, tmp
, 2, error
);
500 GETSTRORGOTO(val
, tmp
, 3, error
);
502 if (!XParseColor(dpy
, DefaultColormap(dpy
, scr
), tmp
, &color
)) {
503 wwarning("could not parse color %s in texture %s", tmp
, text
);
507 color1
.red
= color
.red
>> 8;
508 color1
.green
= color
.green
>> 8;
509 color1
.blue
= color
.blue
>> 8;
511 GETSTRORGOTO(val
, tmp
, 4, error
);
513 if (!XParseColor(dpy
, DefaultColormap(dpy
, scr
), tmp
, &color
)) {
514 wwarning("could not parse color %s in texture %s", tmp
, text
);
518 color2
.red
= color
.red
>> 8;
519 color2
.green
= color
.green
>> 8;
520 color2
.blue
= color
.blue
>> 8;
522 image
= loadImage(rc
, file
);
524 RDestroyImage(gradient
);
531 gtype
= RHorizontalGradient
;
533 theight
= image
->height
> scrHeight
? scrHeight
: image
->height
;
537 gtype
= RVerticalGradient
;
538 twidth
= image
->width
> scrWidth
? scrWidth
: image
->width
;
542 gtype
= RDiagonalGradient
;
547 gradient
= RRenderGradient(twidth
, theight
, &color1
, &color2
, gtype
);
550 wwarning("could not render texture:%s",
551 RMessageForError(RErrorCode
));
552 RDestroyImage(gradient
);
556 tiled
= RMakeTiledImage(image
, twidth
, theight
);
558 wwarning("could not render texture:%s",
559 RMessageForError(RErrorCode
));
560 RDestroyImage(gradient
);
561 RDestroyImage(image
);
564 RDestroyImage(image
);
566 RCombineImagesWithOpaqueness(tiled
, gradient
, opaq
);
567 RDestroyImage(gradient
);
569 if (!RConvertImage(rc
, tiled
, &pixmap
)) {
570 wwarning("could not convert texture:%s",
571 RMessageForError(RErrorCode
));
572 RDestroyImage(image
);
575 texture
->width
= tiled
->width
;
576 texture
->height
= tiled
->height
;
578 RDestroyImage(tiled
);
580 texture
->pixmap
= pixmap
;
581 } else if (strcasecmp(type
, "function")==0) {
583 void (*initFunc
) (Display
*, Colormap
);
584 RImage
* (*mainFunc
) (int, char**, int, int, int);
588 char *lib
, *func
, **argv
= 0;
593 goto function_cleanup
;
595 /* get the library name */
596 GETSTRORGOTO(val
, lib
, 1, function_cleanup
);
598 /* get the function name */
599 GETSTRORGOTO(val
, func
, 2, function_cleanup
);
602 argv
= (char**)wmalloc(argc
* sizeof(char*));
604 /* get the parameters */
606 for (i
=0; i
<argc
-1; i
++) {
607 GETSTRORGOTO(val
, tmp
, 3+i
, function_cleanup
);
608 argv
[i
+1] = wstrdup(tmp
);
611 handle
= dlopen(lib
, RTLD_LAZY
);
613 wwarning(_("could not find library %s"), lib
);
614 goto function_cleanup
;
617 initFunc
= dlsym(handle
, "initWindowMaker");
619 wwarning(_("could not initialize library %s"), lib
);
620 goto function_cleanup
;
622 initFunc(dpy
, DefaultColormap(dpy
, scr
));
624 mainFunc
= dlsym(handle
, func
);
626 wwarning(_("could not find function %s::%s"), lib
, func
);
627 goto function_cleanup
;
629 image
= mainFunc(argc
, argv
, scrWidth
, scrHeight
, 0);
631 if (!RConvertImage(rc
, image
, &pixmap
)) {
632 wwarning("could not convert texture:%s",
633 RMessageForError(RErrorCode
));
634 goto function_cleanup
;
636 texture
->width
= scrWidth
;
637 texture
->height
= scrHeight
;
638 texture
->pixmap
= pixmap
;
644 for (i
=0; i
<argc
; i
++) {
652 RDestroyImage(image
);
658 wwarning("function textures not supported");
662 wwarning("invalid texture type %s", text
);
666 texture
->spec
= wstrdup(text
);
681 freeTexture(BackgroundTexture
*texture
)
683 if (texture
->solid
) {
686 pixel
[0] = texture
->color
.pixel
;
687 /* dont free black/white pixels */
688 if (pixel
[0]!=BlackPixelOfScreen(DefaultScreenOfDisplay(dpy
))
689 && pixel
[0]!=WhitePixelOfScreen(DefaultScreenOfDisplay(dpy
)))
690 XFreeColors(dpy
, DefaultColormap(dpy
, scr
), pixel
, 1, 0);
698 setupTexture(RContext
*rc
, BackgroundTexture
**textures
, int *maxTextures
,
699 int workspace
, char *texture
)
701 BackgroundTexture
*newTexture
= NULL
;
704 /* unset the texture */
706 if (textures
[workspace
]!=NULL
) {
707 textures
[workspace
]->refcount
--;
709 if (textures
[workspace
]->refcount
== 0)
710 freeTexture(textures
[workspace
]);
712 textures
[workspace
] = NULL
;
716 if (textures
[workspace
]
717 && strcasecmp(textures
[workspace
]->spec
, texture
)==0) {
718 /* texture did not change */
722 /* check if the same texture is already created */
723 for (i
= 0; i
< *maxTextures
; i
++) {
724 if (textures
[i
] && strcasecmp(textures
[i
]->spec
, texture
)==0) {
725 newTexture
= textures
[i
];
731 /* create the texture */
732 newTexture
= parseTexture(rc
, texture
);
737 if (textures
[workspace
]!=NULL
) {
739 textures
[workspace
]->refcount
--;
741 if (textures
[workspace
]->refcount
== 0)
742 freeTexture(textures
[workspace
]);
745 newTexture
->refcount
++;
746 textures
[workspace
] = newTexture
;
748 if (*maxTextures
< workspace
)
749 *maxTextures
= workspace
;
755 duplicatePixmap(Pixmap pixmap
, int width
, int height
)
760 /* must open a new display or the RetainPermanent will
761 * leave stuff allocated in RContext unallocated after exit */
762 tmpDpy
= XOpenDisplay(display
);
764 wwarning("could not open display to update background image information");
770 copyP
= XCreatePixmap(tmpDpy
, root
, width
, height
,
771 DefaultDepth(tmpDpy
, scr
));
772 XCopyArea(tmpDpy
, pixmap
, copyP
, DefaultGC(tmpDpy
, scr
),
773 0, 0, width
, height
, 0, 0);
774 XSync(tmpDpy
, False
);
776 XSetCloseDownMode(tmpDpy
, RetainPermanent
);
777 XCloseDisplay(tmpDpy
);
785 dummyErrorHandler(Display
*dpy
, XErrorEvent
*err
)
791 setPixmapProperty(Pixmap pixmap
)
793 static Atom prop
= 0;
796 unsigned long length
, after
;
801 prop
= XInternAtom(dpy
, "_XROOTPMAP_ID", False
);
806 /* Clear out the old pixmap */
807 XGetWindowProperty(dpy
, root
, prop
, 0L, 1L, False
, AnyPropertyType
,
808 &type
, &format
, &length
, &after
, &data
);
810 if ((type
== XA_PIXMAP
) && (format
== 32) && (length
== 1)) {
811 XSetErrorHandler(dummyErrorHandler
);
812 XKillClient(dpy
, *((Pixmap
*)data
));
814 XSetErrorHandler(NULL
);
815 mode
= PropModeReplace
;
817 mode
= PropModeAppend
;
820 XChangeProperty(dpy
, root
, prop
, XA_PIXMAP
, 32, mode
,
821 (unsigned char *) &pixmap
, 1);
823 XDeleteProperty(dpy
, root
, prop
);
833 changeTexture(BackgroundTexture
*texture
)
838 if (texture
->solid
) {
839 XSetWindowBackground(dpy
, root
, texture
->color
.pixel
);
841 XSetWindowBackgroundPixmap(dpy
, root
, texture
->pixmap
);
843 XClearWindow(dpy
, root
);
850 pixmap
= duplicatePixmap(texture
->pixmap
, texture
->width
,
853 setPixmapProperty(pixmap
);
859 readmsg(int fd
, unsigned char *buffer
, int size
)
865 count
= read(fd
, buffer
, size
);
879 * sizeSntexture_spec - sets the texture for workspace n
880 * sizeCn - change background texture to the one for workspace n
881 * sizePpath - set the pixmap search path
884 * size = 4 bytes for length of the message data
887 helperLoop(RContext
*rc
)
889 BackgroundTexture
*textures
[WORKSPACE_COUNT
];
891 unsigned char buffer
[2048], buf
[8];
895 memset(textures
, 0, WORKSPACE_COUNT
*sizeof(BackgroundTexture
*));
901 /* get length of message */
902 if (readmsg(0, buffer
, 4) < 0) {
903 wsyserror("error reading message from Window Maker");
911 memcpy(buf
, buffer
, 4);
916 if (readmsg(0, buffer
, size
) < 0) {
917 wsyserror("error reading message from Window Maker");
926 printf("RECEIVED %s\n",buffer
);
928 if (buffer
[0]!='P' && buffer
[0]!='K') {
929 memcpy(buf
, &buffer
[1], 4);
931 workspace
= atoi(buf
);
932 if (workspace
< 0 || workspace
>= WORKSPACE_COUNT
) {
933 wwarning("received message with invalid workspace number %i\n",
942 printf("set texture %s\n", &buffer
[5]);
944 setupTexture(rc
, textures
, &maxTextures
, workspace
, &buffer
[5]);
949 printf("change texture %i\n", workspace
);
951 if (!textures
[workspace
])
952 changeTexture(textures
[0]);
954 changeTexture(textures
[workspace
]);
959 printf("change pixmappath %s\n", &buffer
[1]);
963 PixmapPath
= wstrdup(&buffer
[1]);
968 printf("unset workspace %i\n", workspace
);
970 setupTexture(rc
, textures
, &maxTextures
, workspace
, NULL
);
975 printf("exit command\n");
980 wwarning("unknown message received");
988 updateDomain(char *domain
, char *key
, char *texture
)
990 char *program
= "wdwrite";
992 execlp(program
, program
, domain
, key
, texture
, NULL
);
993 wwarning("warning could not run \"%s\"", program
);
999 globalDefaultsPathForDomain(char *domain
)
1003 sprintf(path
, "%s/%s", SYSCONFDIR
, domain
);
1005 return wstrdup(path
);
1010 getValueForKey(char *domain
, char *keyName
)
1017 key
= PLMakeString(keyName
);
1019 /* try to find PixmapPath in user defaults */
1020 path
= wdefaultspathfordomain(domain
);
1021 d
= PLGetProplistWithPath(path
);
1023 wwarning("could not open domain file %s", path
);
1027 if (d
&& !PLIsDictionary(d
)) {
1032 val
= PLGetDictionaryEntry(d
, key
);
1036 /* try to find PixmapPath in global defaults */
1038 path
= globalDefaultsPathForDomain(domain
);
1040 wwarning("could not locate file for domain %s", domain
);
1043 d
= PLGetProplistWithPath(path
);
1047 if (d
&& !PLIsDictionary(d
)) {
1052 val
= PLGetDictionaryEntry(d
, key
);
1070 getPixmapPath(char *domain
)
1076 val
= getValueForKey(domain
, "PixmapPath");
1078 if (!val
|| !PLIsArray(val
)) {
1084 count
= PLGetNumberOfElements(val
);
1086 for (i
=0; i
<count
; i
++) {
1089 v
= PLGetArrayElement(val
, i
);
1090 if (!v
|| !PLIsString(v
)) {
1093 len
+= strlen(PLGetString(v
))+1;
1096 ptr
= data
= wmalloc(len
+1);
1099 for (i
=0; i
<count
; i
++) {
1102 v
= PLGetArrayElement(val
, i
);
1103 if (!v
|| !PLIsString(v
)) {
1106 strcpy(ptr
, PLGetString(v
));
1108 ptr
+= strlen(PLGetString(v
));
1113 ptr
--; *(ptr
--) = 0;
1131 print_help(char *ProgName
)
1133 printf("Usage: %s [options] [image]\n", ProgName
);
1134 puts("Sets the workspace background to the specified image or a texture and optionally update Window Maker configuration");
1136 #define P(m) puts(m)
1137 P(" -display display to use");
1138 P(" -d, --dither dither image");
1139 P(" -m, --match match colors");
1140 P(" -b, --back-color <color> background color");
1141 P(" -t, --tile tile image");
1142 P(" -e, --center center image");
1143 P(" -s, --scale scale image (default)");
1144 P(" -a, --maxscale scale image and keep aspect ratio");
1145 P(" -u, --update-wmaker update WindowMaker domain database");
1146 P(" -D, --update-domain <domain> update <domain> database");
1147 P(" -c, --colors <cpc> colors per channel to use");
1148 P(" -p, --parse <texture> proplist style texture specification");
1149 P(" -w, --workspace <workspace> update background for the specified workspace");
1150 P(" --version show version of wmsetbg and exit");
1151 P(" --help show this help and exit");
1158 changeTextureForWorkspace(char *domain
, char *texture
, int workspace
)
1165 val
= PLGetProplistWithDescription(texture
);
1167 wwarning("could not parse texture %s", texture
);
1171 array
= getValueForKey("WindowMaker", "WorkspaceSpecificBack");
1174 array
= PLMakeArrayFromElements(NULL
, NULL
);
1177 j
= PLGetNumberOfElements(array
);
1178 if (workspace
>= j
) {
1181 empty
= PLMakeArrayFromElements(NULL
, NULL
);
1183 while (j
++ < workspace
-1) {
1184 PLAppendArrayElement(array
, empty
);
1186 PLAppendArrayElement(array
, val
);
1188 PLRemoveArrayElement(array
, workspace
);
1189 PLInsertArrayElement(array
, val
, workspace
);
1192 value
= PLGetDescription(array
);
1193 updateDomain(domain
, "WorkspaceSpecificBack", value
);
1198 main(int argc
, char **argv
)
1203 RContextAttributes rattr
;
1204 char *style
= "spixmap";
1205 char *back_color
= "gray20";
1206 char *image_name
= NULL
;
1207 char *domain
= "WindowMaker";
1208 int update
=0, cpc
=4, render_mode
=RM_DITHER
, obey_user
=0;
1209 char *texture
= NULL
;
1212 signal(SIGINT
, SIG_DFL
);
1213 signal(SIGTERM
, SIG_DFL
);
1214 signal(SIGQUIT
, SIG_DFL
);
1215 signal(SIGSEGV
, SIG_DFL
);
1216 signal(SIGBUS
, SIG_DFL
);
1217 signal(SIGFPE
, SIG_DFL
);
1218 signal(SIGABRT
, SIG_DFL
);
1219 signal(SIGHUP
, SIG_DFL
);
1220 signal(SIGPIPE
, SIG_DFL
);
1221 signal(SIGCHLD
, SIG_DFL
);
1223 WMInitializeApplication("wmsetbg", &argc
, argv
);
1225 for (i
=1; i
<argc
; i
++) {
1226 if (strcmp(argv
[i
], "-helper")==0) {
1228 } else if (strcmp(argv
[i
], "-display")==0) {
1231 wfatal("too few arguments for %s\n", argv
[i
-1]);
1235 } else if (strcmp(argv
[i
], "-s")==0
1236 || strcmp(argv
[i
], "--scale")==0) {
1238 } else if (strcmp(argv
[i
], "-t")==0
1239 || strcmp(argv
[i
], "--tile")==0) {
1241 } else if (strcmp(argv
[i
], "-e")==0
1242 || strcmp(argv
[i
], "--center")==0) {
1244 } else if (strcmp(argv
[i
], "-a")==0
1245 || strcmp(argv
[i
], "--maxscale")==0) {
1247 } else if (strcmp(argv
[i
], "-d")==0
1248 || strcmp(argv
[i
], "--dither")==0) {
1249 render_mode
= RM_DITHER
;
1251 } else if (strcmp(argv
[i
], "-m")==0
1252 || strcmp(argv
[i
], "--match")==0) {
1253 render_mode
= RM_MATCH
;
1255 } else if (strcmp(argv
[i
], "-u")==0
1256 || strcmp(argv
[i
], "--update-wmaker")==0) {
1258 } else if (strcmp(argv
[i
], "-D")==0
1259 || strcmp(argv
[i
], "--update-domain")==0) {
1263 wfatal("too few arguments for %s\n", argv
[i
-1]);
1266 domain
= wstrdup(argv
[i
]);
1267 } else if (strcmp(argv
[i
], "-c")==0
1268 || strcmp(argv
[i
], "--colors")==0) {
1271 wfatal("too few arguments for %s\n", argv
[i
-1]);
1274 if (sscanf(argv
[i
], "%i", &cpc
)!=1) {
1275 wfatal("bad value for colors per channel: \"%s\"\n", argv
[i
]);
1278 } else if (strcmp(argv
[i
], "-b")==0
1279 || strcmp(argv
[i
], "--back-color")==0) {
1282 wfatal("too few arguments for %s\n", argv
[i
-1]);
1285 back_color
= argv
[i
];
1286 } else if (strcmp(argv
[i
], "-p")==0
1287 || strcmp(argv
[i
], "--parse")==0) {
1290 wfatal("too few arguments for %s\n", argv
[i
-1]);
1294 } else if (strcmp(argv
[i
], "-w")==0
1295 || strcmp(argv
[i
], "--workspace")==0) {
1298 wfatal("too few arguments for %s\n", argv
[i
-1]);
1301 if (sscanf(argv
[i
], "%i", &workspace
)!=1) {
1302 wfatal("bad value for workspace number: \"%s\"",
1306 } else if (strcmp(argv
[i
], "--version")==0) {
1308 printf(PROG_VERSION
);
1311 } else if (strcmp(argv
[i
], "--help")==0) {
1312 print_help(argv
[0]);
1314 } else if (argv
[i
][0] != '-') {
1315 image_name
= argv
[i
];
1317 printf("%s: invalid argument '%s'\n", argv
[0], argv
[i
]);
1318 printf("Try '%s --help' for more information\n", argv
[0]);
1322 if (!image_name
&& !texture
&& !helperMode
) {
1323 printf("%s: you must specify a image file name or a texture\n",
1325 printf("Try '%s --help' for more information\n", argv
[0]);
1330 PixmapPath
= getPixmapPath(domain
);
1332 dpy
= XOpenDisplay(display
);
1334 wfatal("could not open display");
1338 XSynchronize(dpy
, 1);
1341 root
= DefaultRootWindow(dpy
);
1343 scr
= DefaultScreen(dpy
);
1345 scrWidth
= WidthOfScreen(DefaultScreenOfDisplay(dpy
));
1346 scrHeight
= HeightOfScreen(DefaultScreenOfDisplay(dpy
));
1348 if (!obey_user
&& DefaultDepth(dpy
, scr
) <= 8)
1349 render_mode
= RM_DITHER
;
1351 rattr
.flags
= RC_RenderMode
| RC_ColorsPerChannel
| RC_DefaultVisual
;
1352 rattr
.render_mode
= render_mode
;
1353 rattr
.colors_per_channel
= cpc
;
1355 rc
= RCreateContext(dpy
, scr
, &rattr
);
1358 /* lower priority, so that it wont use all the CPU */
1363 BackgroundTexture
*tex
;
1367 sprintf(buffer
, "(%s, \"%s\", %s)", style
, image_name
, back_color
);
1368 texture
= (char*)buffer
;
1371 if (update
&& workspace
< 0) {
1372 updateDomain(domain
, "WorkspaceBack", texture
);
1375 tex
= parseTexture(rc
, texture
);
1382 /* always update domain */
1383 changeTextureForWorkspace(domain
, texture
, workspace
-1);