Initial revision
[mikachu/openbox.git] / util / bsetroot.cc
1 #ifdef    HAVE_CONFIG_H
2 #  include "../config.h"
3 #endif // HAVE_CONFIG_H
4
5 #ifdef    STDC_HEADERS
6 #  include <string.h>
7 #  include <stdlib.h>
8 #endif // STDC_HEADERS
9
10 #ifdef    HAVE_STDIO_H
11 #  include <stdio.h>
12 #endif // HAVE_STDIO_H
13
14 #include "../src/i18n.h"
15 #include "bsetroot.h"
16
17
18 bsetroot::bsetroot(int argc, char **argv, char *dpy_name)
19   : BaseDisplay(argv[0], dpy_name)
20 {
21   pixmaps = (Pixmap *) 0;
22   grad = fore = back = (char *) 0;
23
24   Bool mod = False, sol = False, grd = False;
25   int mod_x = 0, mod_y = 0, i = 0;
26
27   img_ctrl = new BImageControl*[getNumberOfScreens()];
28   for (; i < getNumberOfScreens(); i++)
29     img_ctrl[i] = new BImageControl(this, getScreenInfo(i), True);
30
31   for (i = 1; i < argc; i++) {
32     if (! strcmp("-help", argv[i])) {
33       usage();
34     } else if ((! strcmp("-fg", argv[i])) ||
35                (! strcmp("-foreground", argv[i])) ||
36                (! strcmp("-from", argv[i]))) {
37       if ((++i) >= argc) usage(1);
38
39       fore = argv[i];
40     } else if ((! strcmp("-bg", argv[i])) ||
41                (! strcmp("-background", argv[i])) ||
42                (! strcmp("-to", argv[i]))) {
43       if ((++i) >= argc) usage(1);
44
45       back = argv[i];
46     } else if (! strcmp("-solid", argv[i])) {
47       if ((++i) >= argc) usage(1);
48
49       fore = argv[i];
50       sol = True;
51     } else if (! strcmp("-mod", argv[i])) {
52       if ((++i) >= argc) usage();
53
54       mod_x = atoi(argv[i]);
55
56       if ((++i) >= argc) usage();
57
58       mod_y = atoi(argv[i]);
59
60       if (mod_x < 1) mod_x = 1;
61       if (mod_y < 1) mod_y = 1;
62
63       mod = True;
64     } else if (! strcmp("-gradient", argv[i])) {
65       if ((++i) >= argc) usage();
66
67       grad = argv[i];
68       grd = True;
69     } else if (! strcmp("-display", argv[i])) {
70       // -display passed through tests ealier... we just skip it now
71       i++;
72     } else
73       usage();
74   }
75
76   if ((mod + sol + grd) != True) {
77     fprintf(stderr,
78             i18n->
79             getMessage(
80 #ifdef    NLS
81                        bsetrootSet, bsetrootMustSpecify,
82 #else // !NLS
83                        0, 0,
84 #endif // NLS
85                        "%s: error: must specify one of: -solid, -mod, -gradient\n"),
86             getApplicationName());
87     
88     usage(2);
89   }
90   
91   if (sol && fore) solid();
92   else if (mod && mod_x && mod_y && fore && back) modula(mod_x, mod_y);
93   else if (grd && grad && fore && back) gradient();
94   else usage();
95 }
96
97
98 bsetroot::~bsetroot(void) {
99   XKillClient(getXDisplay(), AllTemporary);
100
101   if (pixmaps) {
102     int i;
103     for (i = 0; i < getNumberOfScreens(); i++)
104       if (pixmaps[i] != None) {
105         XSetCloseDownMode(getXDisplay(), RetainTemporary);
106         break;
107       }
108
109     delete [] pixmaps;
110   }
111
112   if (img_ctrl) {
113     int i = 0;
114     for (; i < getNumberOfScreens(); i++)
115       delete img_ctrl[i];
116
117     delete [] img_ctrl;
118   }
119 }
120
121
122 void bsetroot::solid(void) {
123   register int screen = 0;
124
125   for (; screen < getNumberOfScreens(); screen++) {
126     BColor c;
127
128     img_ctrl[screen]->parseColor(&c, fore);
129     if (! c.isAllocated()) c.setPixel(BlackPixel(getXDisplay(), screen));
130
131     XSetWindowBackground(getXDisplay(), getScreenInfo(screen)->getRootWindow(),
132                          c.getPixel());
133     XClearWindow(getXDisplay(), getScreenInfo(screen)->getRootWindow());
134   }
135 }
136
137
138 void bsetroot::modula(int x, int y) {
139   char data[32];
140   long pattern;
141
142   register int screen, i;
143
144   pixmaps = new Pixmap[getNumberOfScreens()];
145
146   for (pattern = 0, screen = 0; screen < getNumberOfScreens(); screen++) {
147     for (i = 0; i < 16; i++) {
148       pattern <<= 1;
149       if ((i % x) == 0)
150         pattern |= 0x0001;
151     }
152
153     for (i = 0; i < 16; i++)
154       if ((i %  y) == 0) {
155         data[(i * 2)] = (char) 0xff;
156         data[(i * 2) + 1] = (char) 0xff;
157       } else {
158         data[(i * 2)] = pattern & 0xff;
159         data[(i * 2) + 1] = (pattern >> 8) & 0xff;
160       }
161
162     BColor f, b;
163     GC gc;
164     Pixmap bitmap;
165     XGCValues gcv;
166
167     bitmap =
168       XCreateBitmapFromData(getXDisplay(),
169                             getScreenInfo(screen)->getRootWindow(), data,
170                             16, 16);
171
172     img_ctrl[screen]->parseColor(&f, fore);
173     img_ctrl[screen]->parseColor(&b, back);
174
175     if (! f.isAllocated()) f.setPixel(WhitePixel(getXDisplay(), screen));
176     if (! b.isAllocated()) b.setPixel(BlackPixel(getXDisplay(), screen));
177
178     gcv.foreground = f.getPixel();
179     gcv.background = b.getPixel();
180
181     gc = XCreateGC(getXDisplay(), getScreenInfo(screen)->getRootWindow(),
182                    GCForeground | GCBackground, &gcv);
183
184     pixmaps[screen] =
185       XCreatePixmap(getXDisplay(), getScreenInfo(screen)->getRootWindow(),
186                     16, 16, getScreenInfo(screen)->getDepth());
187
188     XCopyPlane(getXDisplay(), bitmap, pixmaps[screen], gc,
189                0, 0, 16, 16, 0, 0, 1l);
190     XSetWindowBackgroundPixmap(getXDisplay(),
191                                getScreenInfo(screen)->getRootWindow(),
192                                pixmaps[screen]);
193     XClearWindow(getXDisplay(), getScreenInfo(screen)->getRootWindow());
194
195     XFreeGC(getXDisplay(), gc);
196     XFreePixmap(getXDisplay(), bitmap);
197
198     if (! (getScreenInfo(screen)->getVisual()->c_class & 1)) {
199       XFreePixmap(getXDisplay(), pixmaps[screen]);
200       pixmaps[screen] = None;
201     }
202   }
203 }
204
205
206 void bsetroot::gradient(void) {
207   register int screen;
208
209   pixmaps = new Pixmap[getNumberOfScreens()];
210
211   for (screen = 0; screen < getNumberOfScreens(); screen++) {
212     BTexture texture;
213     img_ctrl[screen]->parseTexture(&texture, grad);
214     img_ctrl[screen]->parseColor(texture.getColor(), fore);
215     img_ctrl[screen]->parseColor(texture.getColorTo(), back);
216
217     if (! texture.getColor()->isAllocated())
218       texture.getColor()->setPixel(WhitePixel(getXDisplay(), screen));
219     if (! texture.getColorTo()->isAllocated())
220       texture.getColorTo()->setPixel(BlackPixel(getXDisplay(), screen));
221
222     pixmaps[screen] =
223       img_ctrl[screen]->renderImage(getScreenInfo(screen)->getWidth(),
224                                     getScreenInfo(screen)->getHeight(),
225                                     &texture);
226
227     XSetWindowBackgroundPixmap(getXDisplay(),
228                                getScreenInfo(screen)->getRootWindow(),
229                                pixmaps[screen]);
230     XClearWindow(getXDisplay(), getScreenInfo(screen)->getRootWindow());
231
232     if (! (getScreenInfo(screen)->getVisual()->c_class & 1)) {
233       img_ctrl[screen]->removeImage(pixmaps[screen]);
234       img_ctrl[screen]->timeout();
235       pixmaps[screen] = None;
236     }
237   }
238 }
239
240
241 void bsetroot::usage(int exit_code) {
242   fprintf(stderr,
243           i18n->
244           getMessage(
245 #ifdef    NLS
246                      bsetrootSet, bsetrootUsage,
247 #else // !NLS
248                      0, 0,
249 #endif // NLS
250                      "%s 2.0 : (c) 1997-1999 Brad Hughes\n\n"
251                      "  -display <string>        display connection\n"
252                      "  -mod <x> <y>             modula pattern\n"
253                      "  -foreground, -fg <color> modula foreground color\n"
254                      "  -background, -bg <color> modula background color\n\n"
255                      "  -gradient <texture>      gradient texture\n"
256                      "  -from <color>            gradient start color\n"
257                      "  -to <color>              gradient end color\n\n"
258                      "  -solid <color>           solid color\n\n"
259                      "  -help                    print this help text and exit\n"),
260           getApplicationName());
261   
262   exit(exit_code);
263 }
264
265
266 int main(int argc, char **argv) {
267   char *display_name = (char *) 0;
268   int i = 1;
269   
270   NLSInit("openbox.cat");
271   
272   for (; i < argc; i++) {
273     if (! strcmp(argv[i], "-display")) {
274       // check for -display option
275       
276       if ((++i) >= argc) {
277         fprintf(stderr,
278                 i18n->getMessage(
279 #ifdef    NLS
280                                  mainSet, mainDISPLAYRequiresArg,
281 #else // !NLS
282                                  0, 0,
283 #endif // NLS
284                                  "error: '-display' requires an argument\n"));
285         
286         ::exit(1);
287       }
288       
289       display_name = argv[i];
290     }
291   }
292   
293   bsetroot app(argc, argv, display_name);
294   
295   return 0;
296 }