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/wconfig.h"
43 #include "../WINGs/WINGs.h"
44 #include "../WINGs/WUtil.h"
45 #include "../wrlib/wraster.h"
49 #define PROG_VERSION "wmsetbg (Window Maker) 2.1"
52 #define WORKSPACE_COUNT (MAX_WORKSPACES+1)
62 Pixmap CurrentPixmap
= None
;
63 char *PixmapPath
= NULL
;
66 extern Pixmap
LoadJPEG(RContext
*rc
, char *file_name
, int *width
, int *height
);
69 typedef struct BackgroundTexture
{
77 Pixmap pixmap
; /* for all textures, including solid */
78 int width
; /* size of the pixmap */
85 loadImage(RContext
*rc
, char *file
)
90 if (access(file
, F_OK
)!=0) {
91 path
= wfindfile(PixmapPath
, file
);
93 wwarning("%s:could not find image file used in texture", file
);
100 image
= RLoadImage(rc
, path
, 0);
102 wwarning("%s:could not load image file used in texture:%s", path
,
103 RMessageForError(RErrorCode
));
112 parseTexture(RContext
*rc
, char *text
)
114 BackgroundTexture
*texture
= NULL
;
121 #define GETSTR(val, str, i) \
122 val = PLGetArrayElement(texarray, i);\
123 if (!PLIsString(val)) {\
124 wwarning("could not parse texture %s", text);\
127 str = PLGetString(val)
130 texarray
= PLGetProplistWithDescription(text
);
131 if (!texarray
|| !PLIsArray(texarray
)
132 || (count
= PLGetNumberOfElements(texarray
)) < 2) {
134 wwarning("could not parse texture %s", text
);
140 texture
= wmalloc(sizeof(BackgroundTexture
));
141 memset(texture
, 0, sizeof(BackgroundTexture
));
143 GETSTR(val
, type
, 0);
145 if (strcasecmp(type
, "solid")==0) {
153 if (!XParseColor(dpy
, DefaultColormap(dpy
, scr
), tmp
, &color
)) {
154 wwarning("could not parse color %s in texture %s", tmp
, text
);
157 XAllocColor(dpy
, DefaultColormap(dpy
, scr
), &color
);
159 pixmap
= XCreatePixmap(dpy
, root
, 32, 32, DefaultDepth(dpy
, scr
));
160 XSetForeground(dpy
, DefaultGC(dpy
, scr
), color
.pixel
);
161 XFillRectangle(dpy
, pixmap
, DefaultGC(dpy
, scr
), 0, 0, 32, 32);
163 texture
->pixmap
= pixmap
;
164 texture
->color
= color
;
166 texture
->height
= 32;
167 } else if (strcasecmp(type
, "vgradient")==0
168 || strcasecmp(type
, "dgradient")==0
169 || strcasecmp(type
, "hgradient")==0) {
171 RColor color1
, color2
;
179 if (!XParseColor(dpy
, DefaultColormap(dpy
, scr
), tmp
, &color
)) {
180 wwarning("could not parse color %s in texture %s", tmp
, text
);
184 color1
.red
= color
.red
>> 8;
185 color1
.green
= color
.green
>> 8;
186 color1
.blue
= color
.blue
>> 8;
190 if (!XParseColor(dpy
, DefaultColormap(dpy
, scr
), tmp
, &color
)) {
191 wwarning("could not parse color %s in texture %s", tmp
, text
);
195 color2
.red
= color
.red
>> 8;
196 color2
.green
= color
.green
>> 8;
197 color2
.blue
= color
.blue
>> 8;
202 gtype
= RHorizontalGradient
;
208 gtype
= RVerticalGradient
;
213 gtype
= RDiagonalGradient
;
219 image
= RRenderGradient(iwidth
, iheight
, &color1
, &color2
, gtype
);
222 wwarning("could not render gradient texture:%s",
223 RMessageForError(RErrorCode
));
227 if (!RConvertImage(rc
, image
, &pixmap
)) {
228 wwarning("could not convert texture:%s",
229 RMessageForError(RErrorCode
));
230 RDestroyImage(image
);
234 texture
->width
= image
->width
;
235 texture
->height
= image
->height
;
236 RDestroyImage(image
);
238 texture
->pixmap
= pixmap
;
239 } else if (strcasecmp(type
, "mvgradient")==0
240 || strcasecmp(type
, "mdgradient")==0
241 || strcasecmp(type
, "mhgradient")==0) {
250 colors
= malloc(sizeof(RColor
*)*(count
-1));
252 wwarning("out of memory while parsing texture");
255 memset(colors
, 0, sizeof(RColor
*)*(count
-1));
257 for (i
= 2; i
< count
; i
++) {
258 val
= PLGetArrayElement(texarray
, i
);
259 if (!PLIsString(val
)) {
260 wwarning("could not parse texture %s", text
);
262 for (j
= 0; colors
[j
]!=NULL
; j
++)
267 tmp
= PLGetString(val
);
269 if (!XParseColor(dpy
, DefaultColormap(dpy
, scr
), tmp
, &color
)) {
270 wwarning("could not parse color %s in texture %s",
273 for (j
= 0; colors
[j
]!=NULL
; j
++)
278 if (!(colors
[i
-2] = malloc(sizeof(RColor
)))) {
279 wwarning("out of memory while parsing texture");
281 for (j
= 0; colors
[j
]!=NULL
; j
++)
287 colors
[i
-2]->red
= color
.red
>> 8;
288 colors
[i
-2]->green
= color
.green
>> 8;
289 colors
[i
-2]->blue
= color
.blue
>> 8;
295 gtype
= RHorizontalGradient
;
301 gtype
= RVerticalGradient
;
306 gtype
= RDiagonalGradient
;
312 image
= RRenderMultiGradient(iwidth
, iheight
, colors
, gtype
);
314 for (j
= 0; colors
[j
]!=NULL
; j
++)
319 wwarning("could not render gradient texture:%s",
320 RMessageForError(RErrorCode
));
324 if (!RConvertImage(rc
, image
, &pixmap
)) {
325 wwarning("could not convert texture:%s",
326 RMessageForError(RErrorCode
));
327 RDestroyImage(image
);
331 texture
->width
= image
->width
;
332 texture
->height
= image
->height
;
333 RDestroyImage(image
);
335 texture
->pixmap
= pixmap
;
336 } else if (strcasecmp(type
, "cpixmap")==0
337 || strcasecmp(type
, "spixmap")==0
338 || strcasecmp(type
, "mpixmap")==0
339 || strcasecmp(type
, "tpixmap")==0) {
341 Pixmap pixmap
= None
;
342 RImage
*image
= NULL
;
348 if (toupper(type[0]) == 'T' || toupper(type[0]) == 'C')
349 pixmap = LoadJPEG(rc, tmp, &iwidth, &iheight);
353 image
= loadImage(rc
, tmp
);
357 iwidth
= image
->width
;
358 iheight
= image
->height
;
363 if (!XParseColor(dpy
, DefaultColormap(dpy
, scr
), tmp
, &color
)) {
364 wwarning("could not parse color %s in texture %s\n", tmp
, text
);
365 RDestroyImage(image
);
368 if (!XAllocColor(dpy
, DefaultColormap(dpy
, scr
), &color
)) {
371 rcolor
.red
= color
.red
>> 8;
372 rcolor
.green
= color
.green
>> 8;
373 rcolor
.blue
= color
.blue
>> 8;
374 RGetClosestXColor(rc
, &rcolor
, &color
);
376 switch (toupper(type
[0])) {
378 texture
->width
= iwidth
;
379 texture
->height
= iheight
;
380 if (!pixmap
&& !RConvertImage(rc
, image
, &pixmap
)) {
381 wwarning("could not convert texture:%s",
382 RMessageForError(RErrorCode
));
383 RDestroyImage(image
);
387 RDestroyImage(image
);
391 if (toupper(type
[0])=='S') {
395 if (iwidth
*scrHeight
> iheight
*scrWidth
) {
397 h
= (scrWidth
*iheight
)/iwidth
;
400 w
= (scrHeight
*iwidth
)/iheight
;
406 simage
= RScaleImage(image
, w
, h
);
408 wwarning("could not scale image:%s",
409 RMessageForError(RErrorCode
));
410 RDestroyImage(image
);
413 RDestroyImage(image
);
415 iwidth
= image
->width
;
416 iheight
= image
->height
;
423 if (!pixmap
&& !RConvertImage(rc
, image
, &pixmap
)) {
424 wwarning("could not convert texture:%s",
425 RMessageForError(RErrorCode
));
426 RDestroyImage(image
);
430 if (iwidth
!= scrWidth
|| iheight
!= scrHeight
) {
431 int x
, y
, sx
, sy
, w
, h
;
433 cpixmap
= XCreatePixmap(dpy
, root
, scrWidth
, scrHeight
,
434 DefaultDepth(dpy
, scr
));
436 XSetForeground(dpy
, DefaultGC(dpy
, scr
), color
.pixel
);
437 XFillRectangle(dpy
, cpixmap
, DefaultGC(dpy
, scr
),
438 0, 0, scrWidth
, scrHeight
);
440 if (iheight
< scrHeight
) {
442 y
= (scrHeight
- h
)/2;
445 sy
= (iheight
- scrHeight
)/2;
449 if (iwidth
< scrWidth
) {
451 x
= (scrWidth
- w
)/2;
454 sx
= (iwidth
- scrWidth
)/2;
459 XCopyArea(dpy
, pixmap
, cpixmap
, DefaultGC(dpy
, scr
),
461 XFreePixmap(dpy
, pixmap
);
465 RDestroyImage(image
);
467 texture
->width
= scrWidth
;
468 texture
->height
= scrHeight
;
473 texture
->pixmap
= pixmap
;
474 texture
->color
= color
;
475 } else if (strcasecmp(type
, "thgradient")==0
476 || strcasecmp(type
, "tvgradient")==0
477 || strcasecmp(type
, "tdgradient")==0) {
479 RColor color1
, color2
;
489 GETSTR(val
, file
, 1);
497 if (!XParseColor(dpy
, DefaultColormap(dpy
, scr
), tmp
, &color
)) {
498 wwarning("could not parse color %s in texture %s", tmp
, text
);
502 color1
.red
= color
.red
>> 8;
503 color1
.green
= color
.green
>> 8;
504 color1
.blue
= color
.blue
>> 8;
508 if (!XParseColor(dpy
, DefaultColormap(dpy
, scr
), tmp
, &color
)) {
509 wwarning("could not parse color %s in texture %s", tmp
, text
);
513 color2
.red
= color
.red
>> 8;
514 color2
.green
= color
.green
>> 8;
515 color2
.blue
= color
.blue
>> 8;
517 image
= loadImage(rc
, file
);
519 RDestroyImage(gradient
);
526 gtype
= RHorizontalGradient
;
528 theight
= image
->height
> scrHeight
? scrHeight
: image
->height
;
532 gtype
= RVerticalGradient
;
533 twidth
= image
->width
> scrWidth
? scrWidth
: image
->width
;
537 gtype
= RDiagonalGradient
;
542 gradient
= RRenderGradient(twidth
, theight
, &color1
, &color2
, gtype
);
545 wwarning("could not render texture:%s",
546 RMessageForError(RErrorCode
));
547 RDestroyImage(gradient
);
551 tiled
= RMakeTiledImage(image
, twidth
, theight
);
553 wwarning("could not render texture:%s",
554 RMessageForError(RErrorCode
));
555 RDestroyImage(gradient
);
556 RDestroyImage(image
);
559 RDestroyImage(image
);
561 RCombineImagesWithOpaqueness(tiled
, gradient
, opaq
);
562 RDestroyImage(gradient
);
564 if (!RConvertImage(rc
, tiled
, &pixmap
)) {
565 wwarning("could not convert texture:%s",
566 RMessageForError(RErrorCode
));
567 RDestroyImage(image
);
570 texture
->width
= tiled
->width
;
571 texture
->height
= tiled
->height
;
573 RDestroyImage(tiled
);
575 texture
->pixmap
= pixmap
;
577 wwarning("invalid texture type %s", text
);
581 texture
->spec
= wstrdup(text
);
596 freeTexture(BackgroundTexture
*texture
)
598 if (texture
->solid
) {
601 pixel
[0] = texture
->color
.pixel
;
602 /* dont free black/white pixels */
603 if (pixel
[0]!=BlackPixelOfScreen(DefaultScreenOfDisplay(dpy
))
604 && pixel
[0]!=WhitePixelOfScreen(DefaultScreenOfDisplay(dpy
)))
605 XFreeColors(dpy
, DefaultColormap(dpy
, scr
), pixel
, 1, 0);
613 setupTexture(RContext
*rc
, BackgroundTexture
**textures
, int *maxTextures
,
614 int workspace
, char *texture
)
616 BackgroundTexture
*newTexture
= NULL
;
619 /* unset the texture */
621 if (textures
[workspace
]!=NULL
) {
622 textures
[workspace
]->refcount
--;
624 if (textures
[workspace
]->refcount
== 0)
625 freeTexture(textures
[workspace
]);
627 textures
[workspace
] = NULL
;
631 if (textures
[workspace
]
632 && strcasecmp(textures
[workspace
]->spec
, texture
)==0) {
633 /* texture did not change */
637 /* check if the same texture is already created */
638 for (i
= 0; i
< *maxTextures
; i
++) {
639 if (textures
[i
] && strcasecmp(textures
[i
]->spec
, texture
)==0) {
640 newTexture
= textures
[i
];
646 /* create the texture */
647 newTexture
= parseTexture(rc
, texture
);
652 if (textures
[workspace
]!=NULL
) {
654 textures
[workspace
]->refcount
--;
656 if (textures
[workspace
]->refcount
== 0)
657 freeTexture(textures
[workspace
]);
660 newTexture
->refcount
++;
661 textures
[workspace
] = newTexture
;
663 if (*maxTextures
< workspace
)
664 *maxTextures
= workspace
;
670 duplicatePixmap(Pixmap pixmap
, int width
, int height
)
675 /* must open a new display or the RetainPermanent will
676 * leave stuff allocated in RContext unallocated after exit */
677 tmpDpy
= XOpenDisplay(display
);
679 wwarning("could not open display to update background image information");
685 copyP
= XCreatePixmap(tmpDpy
, root
, width
, height
,
686 DefaultDepth(tmpDpy
, scr
));
687 XCopyArea(tmpDpy
, pixmap
, copyP
, DefaultGC(tmpDpy
, scr
),
688 0, 0, width
, height
, 0, 0);
689 XSync(tmpDpy
, False
);
691 XSetCloseDownMode(tmpDpy
, RetainPermanent
);
692 XCloseDisplay(tmpDpy
);
700 dummyErrorHandler(Display
*dpy
, XErrorEvent
*err
)
706 setPixmapProperty(Pixmap pixmap
)
708 static Atom prop
= 0;
711 unsigned long length
, after
;
716 prop
= XInternAtom(dpy
, "_XROOTPMAP_ID", False
);
721 /* Clear out the old pixmap */
722 XGetWindowProperty(dpy
, root
, prop
, 0L, 1L, False
, AnyPropertyType
,
723 &type
, &format
, &length
, &after
, &data
);
725 if ((type
== XA_PIXMAP
) && (format
== 32) && (length
== 1)) {
726 XSetErrorHandler(dummyErrorHandler
);
727 XKillClient(dpy
, *((Pixmap
*)data
));
729 XSetErrorHandler(NULL
);
730 mode
= PropModeReplace
;
732 mode
= PropModeAppend
;
735 XChangeProperty(dpy
, root
, prop
, XA_PIXMAP
, 32, mode
,
736 (unsigned char *) &pixmap
, 1);
738 XDeleteProperty(dpy
, root
, prop
);
748 changeTexture(BackgroundTexture
*texture
)
753 if (texture
->solid
) {
754 XSetWindowBackground(dpy
, root
, texture
->color
.pixel
);
756 XSetWindowBackgroundPixmap(dpy
, root
, texture
->pixmap
);
758 XClearWindow(dpy
, root
);
765 pixmap
= duplicatePixmap(texture
->pixmap
, texture
->width
,
768 setPixmapProperty(pixmap
);
774 readmsg(int fd
, unsigned char *buffer
, int size
)
780 count
= read(fd
, buffer
, size
);
794 * sizeSntexture_spec - sets the texture for workspace n
795 * sizeCn - change background texture to the one for workspace n
796 * sizePpath - set the pixmap search path
799 * size = 4 bytes for length of the message data
802 helperLoop(RContext
*rc
)
804 BackgroundTexture
*textures
[WORKSPACE_COUNT
];
806 unsigned char buffer
[2048], buf
[8];
810 memset(textures
, 0, WORKSPACE_COUNT
*sizeof(BackgroundTexture
*));
816 /* get length of message */
817 if (readmsg(0, buffer
, 4) < 0) {
818 wsyserror("error reading message from Window Maker");
826 memcpy(buf
, buffer
, 4);
831 if (readmsg(0, buffer
, size
) < 0) {
832 wsyserror("error reading message from Window Maker");
841 printf("RECEIVED %s\n",buffer
);
843 if (buffer
[0]!='P' && buffer
[0]!='K') {
844 memcpy(buf
, &buffer
[1], 4);
846 workspace
= atoi(buf
);
847 if (workspace
< 0 || workspace
>= WORKSPACE_COUNT
) {
848 wwarning("received message with invalid workspace number %i\n",
857 printf("set texture %s\n", &buffer
[5]);
859 setupTexture(rc
, textures
, &maxTextures
, workspace
, &buffer
[5]);
864 printf("change texture %i\n", workspace
);
866 if (!textures
[workspace
])
867 changeTexture(textures
[0]);
869 changeTexture(textures
[workspace
]);
874 printf("change pixmappath %s\n", &buffer
[1]);
878 PixmapPath
= wstrdup(&buffer
[1]);
883 printf("unset workspace %i\n", workspace
);
885 setupTexture(rc
, textures
, &maxTextures
, workspace
, NULL
);
890 printf("exit command\n");
895 wwarning("unknown message received");
903 updateDomain(char *domain
, char *key
, char *texture
)
905 char *program
= "wdwrite";
907 execlp(program
, program
, domain
, key
, texture
, NULL
);
908 wwarning("warning could not run \"%s\"", program
);
914 globalDefaultsPathForDomain(char *domain
)
918 sprintf(path
, "%s/%s", SYSCONFDIR
, domain
);
920 return wstrdup(path
);
925 getValueForKey(char *domain
, char *keyName
)
932 key
= PLMakeString(keyName
);
934 /* try to find PixmapPath in user defaults */
935 path
= wdefaultspathfordomain(domain
);
936 d
= PLGetProplistWithPath(path
);
938 wwarning("could not open domain file %s", path
);
942 if (d
&& !PLIsDictionary(d
)) {
947 val
= PLGetDictionaryEntry(d
, key
);
951 /* try to find PixmapPath in global defaults */
953 path
= globalDefaultsPathForDomain(domain
);
955 wwarning("could not locate file for domain %s", domain
);
958 d
= PLGetProplistWithPath(path
);
962 if (d
&& !PLIsDictionary(d
)) {
967 val
= PLGetDictionaryEntry(d
, key
);
985 getPixmapPath(char *domain
)
991 val
= getValueForKey(domain
, "PixmapPath");
993 if (!val
|| !PLIsArray(val
)) {
999 count
= PLGetNumberOfElements(val
);
1001 for (i
=0; i
<count
; i
++) {
1004 v
= PLGetArrayElement(val
, i
);
1005 if (!v
|| !PLIsString(v
)) {
1008 len
+= strlen(PLGetString(v
))+1;
1011 ptr
= data
= wmalloc(len
+1);
1014 for (i
=0; i
<count
; i
++) {
1017 v
= PLGetArrayElement(val
, i
);
1018 if (!v
|| !PLIsString(v
)) {
1021 strcpy(ptr
, PLGetString(v
));
1023 ptr
+= strlen(PLGetString(v
));
1028 ptr
--; *(ptr
--) = 0;
1046 print_help(char *ProgName
)
1048 printf("Usage: %s [options] [image]\n", ProgName
);
1049 puts("Sets the workspace background to the specified image or a texture and optionally update Window Maker configuration");
1051 #define P(m) puts(m)
1052 P(" -display display to use");
1053 P(" -d, --dither dither image");
1054 P(" -m, --match match colors");
1055 P(" -b, --back-color <color> background color");
1056 P(" -t, --tile tile image");
1057 P(" -e, --center center image");
1058 P(" -s, --scale scale image (default)");
1059 P(" -a, --maxscale scale image and keep aspect ratio");
1060 P(" -u, --update-wmaker update WindowMaker domain database");
1061 P(" -D, --update-domain <domain> update <domain> database");
1062 P(" -c, --colors <cpc> colors per channel to use");
1063 P(" -p, --parse <texture> proplist style texture specification");
1064 P(" -w, --workspace <workspace> update background for the specified workspace");
1065 P(" --version show version of wmsetbg and exit");
1066 P(" --help show this help and exit");
1073 changeTextureForWorkspace(char *domain
, char *texture
, int workspace
)
1082 val
= PLGetProplistWithDescription(texture
);
1084 wwarning("could not parse texture %s", texture
);
1088 array
= getValueForKey("WindowMaker", "WorkspaceSpecificBack");
1091 array
= PLMakeArrayFromElements(NULL
, NULL
);
1094 j
= PLGetNumberOfElements(array
);
1095 if (workspace
>= j
) {
1098 empty
= PLMakeArrayFromElements(NULL
, NULL
);
1100 while (j
++ < workspace
-1) {
1101 PLAppendArrayElement(array
, empty
);
1103 PLAppendArrayElement(array
, val
);
1105 PLRemoveArrayElement(array
, workspace
);
1106 PLInsertArrayElement(array
, val
, workspace
);
1109 value
= PLGetDescription(array
);
1110 updateDomain(domain
, "WorkspaceSpecificBack", value
);
1115 main(int argc
, char **argv
)
1120 RContextAttributes rattr
;
1121 char *style
= "spixmap";
1122 char *back_color
= "gray20";
1123 char *image_name
= NULL
;
1124 char *domain
= "WindowMaker";
1125 int update
=0, cpc
=4, render_mode
=RM_DITHER
, obey_user
=0;
1126 char *texture
= NULL
;
1129 signal(SIGINT
, SIG_DFL
);
1130 signal(SIGTERM
, SIG_DFL
);
1131 signal(SIGQUIT
, SIG_DFL
);
1132 signal(SIGSEGV
, SIG_DFL
);
1133 signal(SIGBUS
, SIG_DFL
);
1134 signal(SIGFPE
, SIG_DFL
);
1135 signal(SIGABRT
, SIG_DFL
);
1136 signal(SIGHUP
, SIG_DFL
);
1137 signal(SIGPIPE
, SIG_DFL
);
1138 signal(SIGCHLD
, SIG_DFL
);
1140 WMInitializeApplication("wmsetbg", &argc
, argv
);
1142 for (i
=1; i
<argc
; i
++) {
1143 if (strcmp(argv
[i
], "-helper")==0) {
1145 } else if (strcmp(argv
[i
], "-display")==0) {
1148 wfatal("too few arguments for %s\n", argv
[i
-1]);
1152 } else if (strcmp(argv
[i
], "-s")==0
1153 || strcmp(argv
[i
], "--scale")==0) {
1155 } else if (strcmp(argv
[i
], "-t")==0
1156 || strcmp(argv
[i
], "--tile")==0) {
1158 } else if (strcmp(argv
[i
], "-e")==0
1159 || strcmp(argv
[i
], "--center")==0) {
1161 } else if (strcmp(argv
[i
], "-a")==0
1162 || strcmp(argv
[i
], "--maxscale")==0) {
1164 } else if (strcmp(argv
[i
], "-d")==0
1165 || strcmp(argv
[i
], "--dither")==0) {
1166 render_mode
= RM_DITHER
;
1168 } else if (strcmp(argv
[i
], "-m")==0
1169 || strcmp(argv
[i
], "--match")==0) {
1170 render_mode
= RM_MATCH
;
1172 } else if (strcmp(argv
[i
], "-u")==0
1173 || strcmp(argv
[i
], "--update-wmaker")==0) {
1175 } else if (strcmp(argv
[i
], "-D")==0
1176 || strcmp(argv
[i
], "--update-domain")==0) {
1180 wfatal("too few arguments for %s\n", argv
[i
-1]);
1183 domain
= wstrdup(argv
[i
]);
1184 } else if (strcmp(argv
[i
], "-c")==0
1185 || strcmp(argv
[i
], "--colors")==0) {
1188 wfatal("too few arguments for %s\n", argv
[i
-1]);
1191 if (sscanf(argv
[i
], "%i", &cpc
)!=1) {
1192 wfatal("bad value for colors per channel: \"%s\"\n", argv
[i
]);
1195 } else if (strcmp(argv
[i
], "-b")==0
1196 || strcmp(argv
[i
], "--back-color")==0) {
1199 wfatal("too few arguments for %s\n", argv
[i
-1]);
1202 back_color
= argv
[i
];
1203 } else if (strcmp(argv
[i
], "-p")==0
1204 || strcmp(argv
[i
], "--parse")==0) {
1207 wfatal("too few arguments for %s\n", argv
[i
-1]);
1211 } else if (strcmp(argv
[i
], "-w")==0
1212 || strcmp(argv
[i
], "--workspace")==0) {
1215 wfatal("too few arguments for %s\n", argv
[i
-1]);
1218 if (sscanf(argv
[i
], "%i", &workspace
)!=1) {
1219 wfatal("bad value for workspace number: \"%s\"",
1223 } else if (strcmp(argv
[i
], "--version")==0) {
1225 printf(PROG_VERSION
);
1228 } else if (strcmp(argv
[i
], "--help")==0) {
1229 print_help(argv
[0]);
1231 } else if (argv
[i
][0] != '-') {
1232 image_name
= argv
[i
];
1234 printf("%s: invalid argument '%s'\n", argv
[0], argv
[i
]);
1235 printf("Try '%s --help' for more information\n", argv
[0]);
1239 if (!image_name
&& !texture
&& !helperMode
) {
1240 printf("%s: you must specify a image file name or a texture\n",
1242 printf("Try '%s --help' for more information\n", argv
[0]);
1247 PixmapPath
= getPixmapPath(domain
);
1249 dpy
= XOpenDisplay(display
);
1251 wfatal("could not open display");
1254 XSynchronize(dpy
, 1);
1256 root
= DefaultRootWindow(dpy
);
1258 scr
= DefaultScreen(dpy
);
1260 scrWidth
= WidthOfScreen(DefaultScreenOfDisplay(dpy
));
1261 scrHeight
= HeightOfScreen(DefaultScreenOfDisplay(dpy
));
1263 if (!obey_user
&& DefaultDepth(dpy
, scr
) <= 8)
1264 render_mode
= RM_DITHER
;
1266 rattr
.flags
= RC_RenderMode
| RC_ColorsPerChannel
| RC_DefaultVisual
;
1267 rattr
.render_mode
= render_mode
;
1268 rattr
.colors_per_channel
= cpc
;
1270 rc
= RCreateContext(dpy
, scr
, &rattr
);
1273 /* lower priority, so that it wont use all the CPU */
1278 BackgroundTexture
*tex
;
1282 sprintf(buffer
, "(%s, \"%s\", %s)", style
, image_name
, back_color
);
1283 texture
= (char*)buffer
;
1286 if (update
&& workspace
< 0) {
1287 updateDomain(domain
, "WorkspaceBack", texture
);
1290 tex
= parseTexture(rc
, texture
);
1297 /* always update domain */
1298 changeTextureForWorkspace(domain
, texture
, workspace
-1);