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