1 /* WMGlobe 1.3 - All the Earth on a WMaker Icon
2 * copyright (C) 1998,99,2000,01 Jerome Dumonteil <jerome.dumonteil@linuxfr.org>
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
17 ***************************************************************************/
18 /*
19 * I used many functions of wmgeneral.c ("openXwindow")
20 * for the main function of wmglobe.c
21 * wmgeneral.c was taken from wmaker applet wmtune-1.0 :
22 * Author: Martijn Pieterse (pieterse@xs4all.nl)
23 *
24 * wmglobe.c uses functions of : Xglobe, Xearth, wmgeneral, wmaker/wrlib
25 ***************************************************************************/
26
27 #include "wmglobe.h"
28
29 #include "cadre0.xbm"
30 #include "cadre1.xbm"
31 #include "cadre2.xbm"
32
33 #ifdef DEFMAPOK
34 #include "defmap.xpm"
35 #include "defnimap.xpm"
36 #endif
37
38 /*
39 * variables globales
40 */
41
42 Display *dpy;
43 Pixmap pix, pixmask;
44 XEvent Event;
45 RImage *map, *small, *mapnight;
46 Window iconwin, win;
47 GC NormalGC;
48 double marker[MAX_MARKERS][3];
49
50
51
main(int argc,char * argv[])52 int main(int argc, char *argv[])
53 {
54 unsigned int borderwidth = 1;
55 XClassHint classHint;
56 char *wname = argv[0];
57 XTextProperty name;
58
59 XGCValues gcv;
60 unsigned long gcm;
61 XWindowAttributes attributes;
62 XColor color;
63
64 RContext *ctx;
65
66 XSizeHints mysizehints;
67 XWMHints mywmhints;
68 Pixel back_pix, fore_pix;
69 char Geometry[256];
70
71 char *rond_bits;
72
73 int dummy = 0;
74 int ok, redoaction, wait_release, move_lat_flag;
75 int xx, yy;
76
77 /** initialisation *********************/
78
79 xx = 0;
80 yy = 0;
81 ok = FALSE;
82 move_lat_flag = FALSE;
83 redoaction = 0;
84 wait_release = 0;
85
86 setlocale(LC_TIME, "");
87
88 #ifdef DEBUG
89 fprintf(stdout, "%s\n", setlocale(LC_TIME, ""));
90 #endif
91
92 set_defaults();
93
94 cmdline(argc, argv);
95
96 #if WITH_MARKERS
97 if (nb_marker) {
98 int i;
99 for (i = 0; i < nb_marker; i++)
100 if (i != moon_marker && i != sun_marker) {
101 marker[i][0] = marker[i][0] * PI / 180.;
102 marker[i][1] = marker[i][1] * PI / 180.;
103 transform_marker(i);
104 }
105 }
106 #endif
107
108 switch (typecadre) {
109 case 1:
110 rond_bits = cadre1_bits;
111 break;
112 case 2:
113 rond_bits = cadre2_bits;
114 break;
115 default:
116 rond_bits = cadre0_bits;
117 }
118 if (p_type == PTRANDOM) {
119 dlat = 0;
120 dlong = 0;
121 }
122
123 /* setup long term mem allocation */
124 initmyconvert();
125
126
127 tdelay.tv_sec = (int) floor(delay);
128 tdelay.tv_usec = (int) ((delay - tdelay.tv_sec) * 1000000);
129 aml = (int) floor(ambient_light * 256);
130
131
132 /* ctx initialization */
133
134 if (!(dpy = XOpenDisplay(dpy_name))) {
135 fprintf(stderr, "%s: can't open display \"%s\"\n",
136 wname, XDisplayName(dpy_name));
137 exit(1);
138 }
139 ctx = myRCreateContext(dpy, DefaultScreen(dpy), NULL);
140
141 if (ctx->attribs->use_shared_memory) {
142 #ifdef DEBUG
143 fprintf(stdout, "remove flags use_shared_memory\n");
144 #endif
145 ctx->attribs->flags ^= RC_UseSharedMemory;
146 ctx->attribs->use_shared_memory = FALSE;
147 ctx->flags.use_shared_pixmap = 0;
148 }
149 #ifdef DEBUG
150 fprintf(stdout, "depth %d\n", ctx->depth);
151 fflush(stdout);
152 #endif
153
154 /*
155 * loading maps .............
156 */
157
158 if (dayfile != NULL) {
159 map = RLoadImage(ctx, dayfile, 0);
160 if (!use_default_nightmap)
161 use_nightmap = FALSE;
162 ripalpha(map);
163 if (!map) {
164 fprintf(stdout, "pb map ! file not found ?\n");
165 exit(1);
166 }
167 } else {
168 #ifdef DEFMAPOK
169 map = RGetImageFromXPMData(ctx, defmap_xpm);
170 use_default_nightmap = TRUE;
171 ripalpha(map);
172 if (!map) {
173 fprintf(stdout, "pb def map ! file not found ?\n");
174 exit(1);
175 }
176 }
177 #else
178 fprintf(stdout, "need a map !\n");
179 exit(1);
180 }
181 #endif
182 if (!oknimap) {
183 use_nightmap = FALSE;
184 use_default_nightmap = FALSE;
185 }
186 if (use_nightmap) {
187 if (nightfile != NULL) {
188 mapnight = RLoadImage(ctx, nightfile, 0);
189 ripalpha(mapnight);
190 if (!mapnight) {
191 fprintf(stdout, "pb map night! file not found ?\n");
192 exit(1);
193 }
194 } else {
195 #ifdef DEFMAPOK
196 if (use_default_nightmap) {
197 mapnight = RGetImageFromXPMData(ctx, defnimap_xpm);
198 ripalpha(mapnight);
199 if (!mapnight) {
200 fprintf(stdout,
201 "pb def map night ! file not found ?\n");
202 exit(1);
203 }
204 }
205 }
206 #else
207 use_nightmap = FALSE;
208 }
209 #endif
210 }
211
212 use_nmap_ini = use_nightmap;
213
214 /* we need a night map of same size as day map */
215 if (mapnight) {
216 if ((mapnight->width != map->width)
217 || (mapnight->height != map->height)) {
218 RImage *tmp;
219 tmp = mapnight;
220 mapnight = RScaleImage(tmp, map->width, map->height);
221 RReleaseImage(tmp);
222 ripalpha(mapnight);
223 }
224 }
225
226 /* some other init ..................................... */
227 ratiox = (double) map->width / (2 * PI);
228 ratioy = (double) map->height / PI;
229 mratiox = (int) floor(ratiox * 256);
230 mratioy = (int) floor(ratioy * 256);
231 loadxpm(ctx->drawable);
232
233 small = RCreateImage(DIAMETRE, DIAMETRE, 0);
234
235 calcDistance();
236
237 /*
238 * first rendering of the earth
239 */
240 rotation_terre(DIAMETRE / 2, DIAMETRE / 2, 0);
241 recalc(0);
242 do_something = FALSE;
243
244 /*************************************************************************
245 * well, here the problems begin : this code is a merge from wmgeneral and
246 * some stuff of wmaker, should be rewritten ...
247 ************************************************************************/
248
249 XGetWindowAttributes(dpy, ctx->drawable, &attributes);
250
251 if (!RConvertImage(ctx, small, &pix)) {
252 fprintf(stdout, "error small->&pix\n");
253 puts(RMessageForError(RErrorCode));
254 exit(1);
255 }
256 wmg.pixmap = pix;
257 wmg.mask = pix;
258
259 mysizehints.flags = USSize | USPosition;
260 mysizehints.x = 0;
261 mysizehints.y = 0;
262
263 color.pixel = 0;
264 if (!XParseColor(dpy, attributes.colormap, "white", &color)) {
265 fprintf(stdout, "wmglobe: can't parse white\n");
266 } else if (!XAllocColor(dpy, attributes.colormap, &color)) {
267 fprintf(stdout, "wmglobe: can't allocate white\n");
268 }
269 back_pix = color.pixel;
270
271 XGetWindowAttributes(dpy, ctx->drawable, &attributes);
272
273 color.pixel = 0;
274 if (!XParseColor(dpy, attributes.colormap, "black", &color)) {
275 fprintf(stdout, "wmglobe: can't parse black\n");
276 } else if (!XAllocColor(dpy, attributes.colormap, &color)) {
277 fprintf(stdout, "wmglobe: can't allocate black\n");
278 }
279 fore_pix = color.pixel;
280
281
282 XWMGeometry(dpy, ctx->screen_number, Geometry, NULL, borderwidth,
283 &mysizehints, &mysizehints.x, &mysizehints.y,
284 &mysizehints.width, &mysizehints.height, &dummy);
285 mysizehints.width = DIAMETRE;
286 mysizehints.height = DIAMETRE;
287
288 win =
289 XCreateSimpleWindow(dpy, ctx->drawable, mysizehints.x,
290 mysizehints.y, mysizehints.width,
291 mysizehints.height, borderwidth, fore_pix,
292 back_pix);
293
294 iconwin = XCreateSimpleWindow(dpy, win, mysizehints.x, mysizehints.y,
295 mysizehints.width, mysizehints.height,
296 borderwidth, fore_pix, back_pix);
297
298 /* Activate hints */
299 XSetWMNormalHints(dpy, win, &mysizehints);
300 classHint.res_name = wname;
301 classHint.res_class = wname;
302 XSetClassHint(dpy, win, &classHint);
303
304 XSelectInput(dpy, win,
305 ButtonPressMask | ExposureMask | ButtonReleaseMask |
306 PointerMotionMask | StructureNotifyMask);
307 XSelectInput(dpy, iconwin,
308 ButtonPressMask | ExposureMask | ButtonReleaseMask |
309 PointerMotionMask | StructureNotifyMask);
310
311 if (XStringListToTextProperty(&wname, 1, &name) == 0) {
312 fprintf(stdout, "%s: can't allocate window name\n", wname);
313 exit(1);
314 }
315 XSetWMName(dpy, win, &name);
316
317 /* Create GC for drawing */
318
319 gcm = GCForeground | GCBackground | GCGraphicsExposures;
320 gcv.foreground = fore_pix;
321 gcv.background = back_pix;
322 gcv.graphics_exposures = 0;
323 NormalGC = XCreateGC(dpy, ctx->drawable, gcm, &gcv);
324
325 /* ONLYSHAPE ON */
326 if (onlyshape) {
327 pixmask =
328 XCreateBitmapFromData(dpy, win, rond_bits, DIAMETRE, DIAMETRE);
329 XShapeCombineMask(dpy, win, ShapeBounding, 0, 0, pixmask,
330 ShapeSet);
331 XShapeCombineMask(dpy, iconwin, ShapeBounding, 0, 0, pixmask,
332 ShapeSet);
333 }
334 /* ONLYSHAPE OFF */
335
336 mywmhints.initial_state = option_iw;
337 mywmhints.icon_window = iconwin;
338 mywmhints.icon_x = mysizehints.x;
339 mywmhints.icon_y = mysizehints.y;
340 mywmhints.window_group = win;
341 mywmhints.flags =
342 StateHint | IconWindowHint | IconPositionHint | WindowGroupHint;
343
344 XSetWMHints(dpy, win, &mywmhints);
345
346 XSetCommand(dpy, win, argv, argc);
347 XMapWindow(dpy, win);
348
349
350 XCopyArea(dpy, wmg.pixmap, win, NormalGC, 0, 0, DIAMETRE, DIAMETRE, 0,
351 0);
352
353 RedrawWindowXYWH(0, 0, DIAMETRE, DIAMETRE);
354
355 /*
356 * ================= MAIN LOOP ==================
357 */
358 while (1) {
359 while (XPending(dpy)) {
360 XNextEvent(dpy, &Event);
361 switch (Event.type) {
362 case Expose:
363 RedrawWindowXYWH(0, 0, DIAMETRE, DIAMETRE);
364 break;
365 case DestroyNotify:
366 XCloseDisplay(dpy);
367 exit(0);
368 break;
369 case ButtonPress:
370 /*
371 * earth rotate when clic left (1) , zooming when middle (2)
372 * change screen to longitude / latitude when (3)
373 */
374 switch (Event.xbutton.button) {
375 case 1:
376 #ifdef MOUSE_LAT_NO_SHIFT
377 move_lat_flag = TRUE;
378 #else
379 if (Event.xbutton.state & ShiftMask)
380 move_lat_flag = TRUE;
381 else
382 move_lat_flag = FALSE;
383 #endif
384 redoaction = 1;
385 wait_release = 1;
386 break;
387 case 2:
388 if (Event.xbutton.state & ShiftMask)
389 redoaction = 2;
390 else
391 redoaction = 3;
392 wait_release = 1;
393 break;
394 case 3:
395 wait_release = 0;
396 redoaction = 0;
397 screen_back();
398 ok = TRUE;
399 break;
400 default:
401 break;
402 }
403 break;
404 case ButtonRelease:
405 wait_release = 0;
406 redoaction = 0;
407 break;
408 default:
409 break;
410 }
411 }
412 if (wait_release) {
413 usleep(2 * VAL_USLEEP_SHORT);
414 if (redoaction == 1)
415 rotation_terre(Event.xbutton.x, Event.xbutton.y,
416 move_lat_flag);
417 else
418 zooming(Event.xbutton.state & ShiftMask);
419 ok = TRUE;
420 }
421 if (diftimev(tnext, getimev()).tv_sec < 0 || ok) {
422 ok = FALSE;
423 recalc(redoaction == 1);
424 if (do_something) {
425 if (!myRConvertImage(ctx, small, &pix)) {
426 fprintf(stderr, "crash !?\n");
427 fprintf(stderr, "%s", RMessageForError(RErrorCode));
428 exit(1);
429 }
430 wmg.pixmap = pix;
431 wmg.mask = pix;
432 RedrawWindowXYWH(0, 0, DIAMETRE, DIAMETRE);
433 #ifdef DEBUG
434 fprintf(stdout, "draw\n");
435 #endif
436 do_something = FALSE;
437 }
438 }
439 usleep(VAL_USLEEP);
440 }
441 return 0;
442 }
443