1 /* $Id: wmpal.c 35 2007-07-05 14:05:18Z danadocus $ */
2 /* -*- indent-tabs-mode: nil; tab-width: 4; c-basic-offset: 4; -*- */
3 /* wmpal - a useless DockApp
4 * Copyright (C) 2000 Hadess <hadess@writeme.com>
5 * Copyright (C) 2001-2004 A.Sleep <a.sleep@asleep.net>
6 * Copyright (C) 2007 Dana Jansens <danakj@orodu.net>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21
22 #include "xpms.h"
23
24 #include <X11/Xlib.h>
25 #include <X11/xpm.h>
26 #include <unistd.h> /* for sleep() */
27 #include <stdlib.h> /* for rand() */
28 #include <time.h> /* for time() */
29 #include <string.h>
30 #include <stdio.h>
31
32 #define MAX_SLEEP_TIME 5
33
34 char *displayName = NULL;
35 char *palName = "daemon";
36 int windowed = 0;
37 int nodecor = 0;
38 int below = 0;
39 int all = 0;
40
41 static void print_version();
42 static void print_help();
43 static void parse_args(int argc, char **argv);
44 static Window create_window(Display *d, const char *name, int w, int h,
45 int windowed, int nodecor, int below, int all);
46 static int load_pixmap(Display *d, char **data, Pixmap *xpm);
47
main(int argc,char ** argv)48 int main(int argc, char **argv)
49 {
50 Display *d;
51 Window win;
52 Pixmap bg;
53 Pixmap pixanim[3];
54
55 parse_args(argc, argv);
56 srand(time(NULL));
57
58 if (!(d = XOpenDisplay(displayName))) {
59 fprintf(stderr, "Unable to open the X display\n");
60 exit(EXIT_FAILURE);
61 }
62
63 win = create_window(d, "wmpal", 50, 50, windowed, nodecor, below, all);
64
65 switch (palName[0]) {
66 case 'd':
67 if (palName[1] == 'i') {
68 load_pixmap(d, dino1_xpm, &pixanim[0]);
69 load_pixmap(d, dino2_xpm, &pixanim[1]);
70 load_pixmap(d, dino3_xpm, &pixanim[2]);
71 }
72 else {
73 load_pixmap(d, demon1_xpm, &pixanim[0]);
74 load_pixmap(d, demon2_xpm, &pixanim[1]);
75 load_pixmap(d, demon3_xpm, &pixanim[2]);
76 }
77 break;
78 case 'g':
79 load_pixmap(d, grape1_xpm, &pixanim[0]);
80 load_pixmap(d, grape2_xpm, &pixanim[1]);
81 load_pixmap(d, grape3_xpm, &pixanim[2]);
82 break;
83 case 'p':
84 load_pixmap(d, pear1_xpm, &pixanim[0]);
85 load_pixmap(d, pear2_xpm, &pixanim[1]);
86 load_pixmap(d, pear3_xpm, &pixanim[2]);
87 break;
88 case 's':
89 if (palName[1] == 'u') {
90 load_pixmap(d, sun1_xpm, &pixanim[0]);
91 load_pixmap(d, sun2_xpm, &pixanim[1]);
92 load_pixmap(d, sun3_xpm, &pixanim[2]);
93 } else {
94 load_pixmap(d, snail1_xpm, &pixanim[0]);
95 load_pixmap(d, snail2_xpm, &pixanim[1]);
96 load_pixmap(d, snail1_xpm, &pixanim[2]);
97 }
98 break;
99 case 't':
100 load_pixmap(d, turtle1_xpm, &pixanim[0]);
101 load_pixmap(d, turtle2_xpm, &pixanim[1]);
102 load_pixmap(d, turtle3_xpm, &pixanim[2]);
103 break;
104 }
105
106 load_pixmap(d, bg_xpm, &bg);
107 XSetWindowBackgroundPixmap(d, win, bg);
108 XMapWindow(d, win);
109
110 while (1) {
111 static int anim_pos = -1;
112
113 if (anim_pos < 2) ++anim_pos;
114 else anim_pos = 0;
115
116 XCopyArea(d, pixanim[anim_pos], bg, DefaultGC(d, DefaultScreen(d)),
117 0, 0, 48, 48, 1, 1);
118 XClearWindow(d, win);
119 XFlush(d);
120
121 /* sleep for a random time */
122 sleep(rand() % (MAX_SLEEP_TIME-1) + 1);
123 }
124
125 return 0;
126 }
127
print_version()128 static void print_version()
129 {
130 const char *version =
131 "wmpal " VERSION "\n"
132 "\n"
133 "Copyright (C) 2007 Dana Jansens <danakj@orodu.net>\n"
134 "Copyright (C) 2001-2004 A.Sleep <a.sleep@asleep.net>\n"
135 "Copyright (C) 2000 Hadess <hadess@writeme.com>\n"
136 "\n";
137
138 printf("%s", version);
139 }
140
print_help()141 static void print_help()
142 {
143 const char *help =
144 "Usage: wmpal [OPTIONS]\n"
145 "\n"
146 " -d, --display <string> Display to use\n"
147 " -p, --pal <string> Which pal to use\n"
148 " -w, --windowed runs the application in windowed mode\n"
149 " -n, --nodecor removes any decorations in windowed mode\n"
150 " -b, --below keeps the window below others in windowed mode\n"
151 " -a, --all show wmpal on all desktops\n"
152 " -h, --help shows this help text and exit\n"
153 " -v, --version shows program version and exit\n"
154 "\n"
155 "Available pals are: demon, dino, grape, pear, snail, sun or turtle\n"
156 "\n";
157
158 printf("%s", help);
159 }
160
parse_args(int argc,char ** argv)161 static void parse_args(int argc, char **argv)
162 {
163 int i;
164 for (i = 1; i < argc; ++i) {
165 if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--display")) {
166 if (i == argc - 1) /* no args left */
167 /* not translated cuz it's sekret */
168 printf("--display requires an argument\n");
169 else
170 displayName = argv[++i];
171 }
172 else if (!strcmp(argv[i], "-p") || !strcmp(argv[i], "--pal")) {
173 if (i == argc - 1) /* no args left */
174 /* not translated cuz it's sekret */
175 printf("--pal requires an argument\n");
176 else
177 palName = argv[++i];
178 }
179 else if (!strcmp(argv[i], "-w") || !strcmp(argv[i], "--windowed")) {
180 windowed = 1;
181 }
182 else if (!strcmp(argv[i], "-n") || !strcmp(argv[i], "--nodecor")) {
183 nodecor = 1;
184 }
185 else if (!strcmp(argv[i], "-b") || !strcmp(argv[i], "--below")) {
186 below = 1;
187 }
188 else if (!strcmp(argv[i], "-a") || !strcmp(argv[i], "--all")) {
189 all = 1;
190 }
191 else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
192 print_help();
193 exit(EXIT_SUCCESS);
194 }
195 else if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--version")) {
196 print_version();
197 exit(EXIT_SUCCESS);
198 }
199 }
200 }
201
202 #define MWM_FLAG_FUNCTIONS (1 << 0)
203 #define MWM_FLAG_DECORATIONS (1 << 1)
204
create_window(Display * d,const char * name,int w,int h,int windowed,int nodecor,int below,int all)205 static Window create_window(Display *d, const char *name, int w, int h,
206 int windowed, int nodecor, int below, int all)
207 {
208 Window win;
209 int s = DefaultScreen(d);
210
211 win = XCreateWindow(d, RootWindow(d, s), 0, 0, w, h, 0,
212 DefaultDepth(d, s), InputOutput, DefaultVisual(d, s),
213 0, NULL);
214
215 if (!windowed) {
216 XWMHints *hint = XAllocWMHints();
217 hint->flags = StateHint;
218 hint->initial_state = WithdrawnState;
219 XSetWMHints(d, win, hint);
220 XFree(hint);
221 }
222 else {
223 long state[3];
224 int n = 0;
225
226 if (nodecor) {
227 long mwm[3];
228 mwm[0] = MWM_FLAG_DECORATIONS;
229 mwm[2] = 0; /* no decorations */
230 XChangeProperty(d, win,
231 XInternAtom(d, "_MOTIF_WM_HINTS", False),
232 XInternAtom(d, "_MOTIF_WM_HINTS", False),
233 32, PropModeReplace, (unsigned char*) mwm, 3);
234
235 /* set these when no decor is on */
236 state[n++] = XInternAtom(d, "_NET_WM_STATE_SKIP_TASKBAR", False);
237 state[n++] = XInternAtom(d, "_NET_WM_STATE_SKIP_PAGER", False);
238 }
239
240 if (below)
241 state[n++] = XInternAtom(d, "_NET_WM_STATE_BELOW", False);
242 if (n)
243 XChangeProperty(d, win,
244 XInternAtom(d, "_NET_WM_STATE", False),
245 XInternAtom(d, "ATOM", False),
246 32, PropModeReplace, (unsigned char*) state, n);
247
248 if (all) {
249 long a[1] = { 0xffffffff };
250 XChangeProperty(d, win,
251 XInternAtom(d, "_NET_WM_DESKTOP", False),
252 XInternAtom(d, "CARDINAL", False),
253 32, PropModeReplace, (unsigned char*) a, 1);
254 }
255 }
256
257 {
258 XClassHint c;
259 c.res_name = "wmpal";
260 c.res_class = "WMPal";
261 XSetClassHint(d, win, &c);
262 }
263
264 return win;
265 }
266
load_pixmap(Display * d,char ** data,Pixmap * xpm)267 static int load_pixmap(Display *d, char **data, Pixmap *xpm)
268 {
269 Pixmap mask;
270 unsigned short w, h;
271 XpmAttributes at;
272
273 at.valuemask = XpmCloseness;
274 at.closeness = 40000;
275
276 return XpmCreatePixmapFromData(d, RootWindow(d, DefaultScreen(d)),
277 data, xpm, &mask, &at) == 0;
278 }
279
280