wmpager: EWMH support
[dockapps.git] / wmweather+ / dock.c
blobe550dc83e5905065810032495968c39785cb2c86
1 #include "config.h"
3 /* Copyright (C) 2002 Brad Jorsch <anomie@users.sourceforge.net>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 #include <stdio.h>
21 #include <stdlib.h>
22 #if TM_IN_SYS_TIME
23 # if TIME_WITH_SYS_TIME
24 # include <sys/time.h>
25 # include <time.h>
26 # else
27 # if HAVE_SYS_TIME_H
28 # include <sys/time.h>
29 # else
30 # include <time.h>
31 # endif
32 # endif
33 #else
34 #include <time.h>
35 #endif
36 #include <ctype.h>
37 #include <unistd.h>
38 #include <signal.h>
39 #include <sys/types.h>
40 #include <errno.h>
42 #include <X11/Xlib.h>
43 #include <X11/xpm.h>
45 #include "wmgeneral/wmgeneral-x11.h"
46 #include "wmgeneral/mouse_regions.h"
47 #include "wmgeneral/xpm_trans.h"
49 #include "wmweather_master.xpm"
50 static int wmweather_mask_width;
51 static int wmweather_mask_height;
52 static char *wmweather_mask_bits;
54 #include "wmweather+.h"
55 #include "convert.h"
56 #include "metar.h"
57 #include "avn.h"
58 #include "eta.h"
59 #include "mrf.h"
60 #include "warnings.h"
61 #include "forecast.h"
62 #include "radar.h"
63 #include "animation.h"
64 #include "die.h"
65 #include "font.h"
67 /* Globals */
68 int current_mode;
69 struct forecast *cur_forecast;
70 int window_X, window_Y;
72 #define X 4
73 #define P 4
74 #define M (((100/P)+1)*X)
75 static struct forecast *last_fcst;
76 static int last_font=-1;
77 static time_t last_time=0;
78 static int but_stat=-1;
79 static int dclick=0;
80 static int dclick_counter=-1;
81 static time_t update_time;
82 static int forecast_priority, last_priority;
83 static struct animation anim;
84 static int counter_timer=0;
85 static int show_counter;
86 static int min_pct;
87 static int sigs=0;
90 /* Prototypes */
92 void DrawDisplay(int force);
95 /* Functions */
97 void sigusr2(int i){
98 sigs |= 2;
99 if(signal(SIGUSR2, sigusr2)==SIG_ERR)
100 warn("Error setting SIGUSR2 signal handler!");
103 void sigusr1(int i){
104 sigs |= 1;
105 if(signal(SIGUSR1, sigusr1)==SIG_ERR)
106 warn("Error setting SIGUSR1 signal handler!");
109 void sigfunc(int i){
110 sigs |= i<<8;
111 if(signal(i, sigfunc)==SIG_ERR)
112 warn("Error setting %d signal handler!", i);
115 void do_cleanup(void){
116 metar_cleanup();
117 warnings_cleanup();
118 avn_cleanup();
119 eta_cleanup();
120 mrf_cleanup();
121 radar_cleanup();
124 void init_dock(int argc, char **argv){
125 sscanf(wmweather_master_xpm[0], "%d %d %*s", &wmweather_mask_width, &wmweather_mask_height);
126 wmweather_mask_bits=malloc((wmweather_mask_width+7)/8*wmweather_mask_height);
127 if(!wmweather_mask_bits) die("malloc failed");
128 createXBMfromXPM(wmweather_mask_bits, wmweather_master_xpm, wmweather_mask_width, wmweather_mask_height);
129 openDockWindow(argc, argv, wmweather_master_xpm, wmweather_mask_bits, wmweather_mask_width, wmweather_mask_height);
131 AddMouseRegion(0, 5, 5, 23, 14); /* Cur button */
132 AddMouseRegion(1, 23, 5, 41, 14); /* Fcst burron */
133 AddMouseRegion(2, 41, 5, 59, 14); /* Map button */
134 AddMouseRegion(3, 5, 17, 59, 59); /* Large window */
135 AddMouseRegion(4, 5, 17, 11, 24); /* left forecast arrow */
136 AddMouseRegion(5, 53, 17, 59, 24); /* right forecast arrow */
137 AddMouseRegion(6, 14, 17, 50, 24); /* forecast little window */
138 AddMouseRegion(7, 5, 27, 59, 59); /* forecast big window */
140 init_metar();
141 if(warning_zones) init_warnings();
142 if(avn_station) init_avn();
143 if(eta_station) init_eta();
144 if(mrf_station) init_mrf();
145 init_radar();
146 errno=0;
147 if(atexit(do_cleanup)) warn("atexit() failed, files will not be cleaned up\n");
149 current_mode=starting_mode;
150 window_X=0; window_Y=0;
151 cur_forecast=NULL;
152 last_fcst=NULL;
153 last_font=-1;
154 last_time=0;
155 anim.do_animate=start_do_animation;
156 anim.show_counter=0;
157 anim.changed=1;
158 anim.min_pct=1;
159 anim.old_pct=0;
160 min_pct=20;
161 show_counter=0;
162 but_stat=-1;
163 dclick=0;
164 dclick_counter=-1;
165 update_time=0;
166 forecast_priority=4;
167 last_priority=-1;
169 if(signal(SIGUSR1, sigusr1)==SIG_ERR)
170 warn("Error setting SIGUSR1 signal handler!");
171 if(signal(SIGUSR2, sigusr2)==SIG_ERR)
172 warn("Error setting SIGUSR2 signal handler!");
173 if(signal(SIGHUP, sigfunc)==SIG_ERR)
174 warn("Error setting SIGHUP signal handler!");
175 if(signal(SIGINT, sigfunc)==SIG_ERR)
176 warn("Error setting SIGINT signal handler!");
177 if(signal(SIGPIPE, sigfunc)==SIG_ERR)
178 warn("Error setting SIGPIPE signal handler!");
179 if(signal(SIGTERM, sigfunc)==SIG_ERR)
180 warn("Error setting SIGTERM signal handler!");
182 DrawDisplay(1);
186 void update_dock(){
187 XEvent Event;
188 int i=0, j;
189 int exposeflag=0;
191 j=sigs;
192 sigs=0;
193 if(j){
194 if(j&~3) exit(j);
195 if(j&1) i=current_mode;
196 if(j&2) i=-1;
197 if(j&3){
198 switch(i){
199 case 0:
200 update_metar(1);
201 break;
202 case 1:
203 update_avn(1);
204 update_eta(1);
205 update_mrf(1);
206 break;
207 case 2:
208 update_radar(1);
209 break;
210 default:
211 update_metar(1);
212 update_avn(1);
213 update_eta(1);
214 update_mrf(1);
215 update_radar(1);
216 break;
221 if(update_time<time(NULL)){
222 update_time=time(NULL)+2;
223 update_metar(0);
224 update_avn(0);
225 update_eta(0);
226 update_mrf(0);
227 update_radar(0);
228 forecast_priority=(forecast_priority+1)%5;
229 DrawDisplay(0);
231 if(counter_timer>0) if(!--counter_timer){
232 anim.changed=1;
233 show_counter=anim.show_counter=0;
236 if(dclick_counter>-1) dclick_counter--;
238 while(XPending(display)){
239 XNextEvent(display, &Event);
240 switch (Event.type){
241 case GraphicsExpose:
242 case NoExpose:
243 case Expose:
244 exposeflag=1;
245 break;
246 case DestroyNotify:
247 XCloseDisplay(display);
248 exit(0);
249 break;
250 case ButtonPress:
251 but_stat = CheckMouseRegion(Event.xbutton.x, Event.xbutton.y);
252 if((dclick!=but_stat+1 && dclick!=-but_stat-1) || dclick_counter<0){
253 dclick=-but_stat-1;
254 dclick_counter=4;
255 } else if(dclick==-but_stat-1) dclick=but_stat+1;
257 switch(but_stat){
258 case 0:
259 case 1:
260 case 2:
261 if(current_mode!=but_stat){
262 current_mode=but_stat;
263 if(!anim.do_animate && !show_counter){
264 show_counter=1;
265 counter_timer=10;
267 DrawDisplay(1);
269 break;
270 case 3:
271 case 7:
272 switch(Event.xbutton.button){
273 case 2:
274 if(current_mode==2){
275 if(radar_cross!=NULL){
276 do_radar_cross=1;
277 DrawDisplay(1);
279 } else {
280 anim.changed=1;
281 anim.show_counter=0;
282 anim.do_animate=!anim.do_animate;
283 anim.min_pct=1;
284 if(!anim.do_animate && current_mode==1){
285 anim.min_pct=min_pct;
286 show_counter=anim.show_counter=1;
287 counter_timer=20;
290 break;
292 case 4:
293 if(current_mode==1 && !anim.do_animate && min_pct<100){
294 if(Event.xbutton.state&ShiftMask){
295 min_pct+=10;
296 if(min_pct>100) min_pct=100;
297 } else min_pct++;
298 anim.min_pct=min_pct;
299 show_counter=anim.show_counter=1;
300 counter_timer=20;
301 anim.changed=1;
303 break;
305 case 5:
306 if(current_mode==1 && !anim.do_animate && min_pct>0){
307 if(Event.xbutton.state&ShiftMask){
308 min_pct-=10;
309 if(min_pct<0) min_pct=0;
310 } else min_pct--;
311 anim.min_pct=min_pct;
312 anim.show_counter=1;
313 counter_timer=20;
314 anim.changed=1;
316 break;
318 case 6:
319 if(current_mode==1){
320 show_counter=anim.show_counter=1;
321 anim.changed=1;
322 counter_timer=0;
324 break;
326 break;
328 case 4:
329 copyPixmapArea(123, 96, 6, 7, 65, 17);
330 break;
331 case 5:
332 copyPixmapArea(129, 96, 6, 7, 113, 17);
333 break;
335 break;
337 case ButtonRelease:
338 i = CheckMouseRegion(Event.xbutton.x, Event.xbutton.y);
339 if(dclick_counter<0) dclick=0;
341 if(but_stat==4){
342 copyPixmapArea(123, 89, 6, 7, 65, 17);
344 if(but_stat==5){
345 copyPixmapArea(129, 89, 6, 7, 113, 17);
347 if(current_mode==2 && (but_stat==3 || but_stat==7)
348 && Event.xbutton.button==2){
349 do_radar_cross=0;
350 DrawDisplay(1);
353 if(but_stat == i && but_stat >= 0){
354 switch(but_stat){
355 case 3:
356 case 7:
357 if(Event.xbutton.button==1){
358 if(dclick==but_stat+1) kill(getpid(), SIGUSR1);
359 else if(warning_zones) output_warnings(0);
361 if(Event.xbutton.button==2){
362 if(dclick==but_stat+1 && current_mode==1){
363 show_counter=anim.show_counter=!anim.show_counter;
364 anim.changed=1;
365 counter_timer=0;
368 if(Event.xbutton.button==3 && warning_zones) output_warnings(1);
369 if(Event.xbutton.button==6){
370 show_counter=anim.show_counter=0;
371 anim.changed=1;
373 break;
374 case 4:
375 current_forecast_next(-1);
376 forecast_priority=4;
377 last_priority=0;
378 DrawDisplay(0);
379 break;
380 case 5:
381 current_forecast_next(1);
382 forecast_priority=4;
383 last_priority=0;
384 DrawDisplay(0);
385 break;
386 case 6:
387 if(Event.xbutton.button==3) current_forecast_next(-1);
388 if(Event.xbutton.button==2){{
389 struct forecast *f=current_forecast_get();
390 struct forecast *g;
391 current_forecast_next(1);
392 while((g=current_forecast_get())!=f){
393 if((f->hour<0 && g->hour>=0) ||
394 (f->hour>=0 && g->hour<0)) break;
395 current_forecast_next(1);
398 if(Event.xbutton.button==1) current_forecast_next(1);
399 forecast_priority=4;
400 last_priority=0;
401 DrawDisplay(0);
402 break;
404 but_stat=-1;
406 break;
409 if(exposeflag){
410 setMaskXY(-window_X, -window_Y);
411 RedrawWindowXY(window_X, window_Y);
413 DoAnimation(&anim);
417 void DrawDisplay(int force){
418 int font=0;
419 int x, y, z;
420 struct forecast *f;
421 time_t t;
422 struct tm *tm;
424 if(current_warnings) font=1;
425 if(force || last_font!=font) last_time=-1;
426 last_font=font;
428 switch(current_mode){
429 case 0:
430 if(last_time==current.last_update) break;
431 last_time=current.last_update;
432 EnableMouseRegion(3);
433 DisableMouseRegion(4);
434 DisableMouseRegion(5);
435 DisableMouseRegion(6);
436 DisableMouseRegion(7);
437 window_X=0; window_Y=0;
439 copyPixmapArea(124, 0, 54, 9, 5, 5);
440 copyPixmapArea(124, 9, 18, 9, 5, 5);
441 copyPixmapArea(124, 18, 54, 42, 5, 17);
443 DrawString(7, 17, metar_station, font+1);
444 if(current.month>0 && current.month<13 && current.date!=-1){
445 snprintf(bigbuf, BIGBUF_LEN, "%s %d", monthnames[(int)current.month], current.date);
446 DrawString(32, 17, bigbuf, font+1);
448 if(current.time!=-1){
449 snprintf(bigbuf, BIGBUF_LEN, "%04dL (%04dZ)", current.time, local2utc(current.time, NULL, NULL, NULL, NULL));
450 DrawString(7, 23, bigbuf, font+1);
452 if(current.temp!=999){
453 x=(temp_mode==0)?temp_C2F(current.temp):current.temp;
454 if(x<-99) x=-99;
455 if(x>199) x=199;
456 snprintf(bigbuf, BIGBUF_LEN, "%d", x);
457 DrawString(32, 29, bigbuf, font);
459 if(current.rh!=-1){
460 DrawChar(55, 29, '%', font);
461 DrawNumber(54, 29, current.rh, font);
463 if(current.windspeed==0){
464 x=GetStringWidth("CALM");
465 DrawString(32+(26-x)/2, 35, "CALM", font);
466 } else {
467 if(current.winddir>=0 && current.winddir<=16){
468 x=GetStringWidth(directions[current.winddir]);
469 DrawString(45-x, 35, directions[current.winddir], font);
471 switch(windspeed_mode){
472 case 0:
473 x=knots2mph(current.windspeed);
474 break;
475 case 1:
476 x=knots2kph(current.windspeed);
477 break;
478 case 3:
479 x=knots2mps(current.windspeed);
480 break;
481 case 4:
482 x=knots2beaufort(current.windspeed);
483 break;
485 if(x>=0 && x<1000)
486 DrawNumber(58, 35, x, font);
488 if(current.pressure>0){
489 switch(pressure_mode){
490 case 1:
491 snprintf(bigbuf, BIGBUF_LEN, "P:%4.0f", inHg2hPa(current.pressure));
492 break;
493 case 2:
494 snprintf(bigbuf, BIGBUF_LEN, "P:%5.1f", inHg2mmHg(current.pressure));
495 break;
496 case 3:
497 snprintf(bigbuf, BIGBUF_LEN, "P:%5.3f", inHg2atm(current.pressure));
498 break;
499 default:
500 snprintf(bigbuf, BIGBUF_LEN, "P:%5.2f", current.pressure);
501 break;
503 DrawString(32, 41, bigbuf, font);
505 if(current.heatindex!=999){
506 x=(temp_mode==0)?current.heatindex:temp_F2C(current.heatindex);
507 if(x<-99) x=-99;
508 if(x>199) x=199;
509 snprintf(bigbuf, BIGBUF_LEN, "HI: %d", x);
510 DrawString(32, 47, bigbuf, font);
512 if(current.windchill!=999){
513 x=(temp_mode==0)?current.windchill:temp_F2C(current.windchill);
514 if(x<-99) x=-99;
515 if(x>199) x=199;
516 snprintf(bigbuf, BIGBUF_LEN, "WC: %d", x);
517 DrawString(32, 53, bigbuf, font);
520 anim.show_counter=0;
521 anim.min_pct=1;
522 SetAnimation(&anim, 5, 28, current.sky, current.obs, current.vis,
523 current.frz, current.snow, current.rain, current.tstorm, 0,
524 current.moon);
526 break;
528 case 1:
529 f=current_forecast_get();
530 if(last_fcst!=f) last_time=-1;
531 last_fcst=f;
532 if(f!=NULL){
533 if(last_time==f->last_update)
534 goto case_1_end; /* still check bottom line priority */
535 else last_time=f->last_update;
538 DisableMouseRegion(3);
539 EnableMouseRegion(4);
540 EnableMouseRegion(5);
541 EnableMouseRegion(6);
542 EnableMouseRegion(7);
543 window_X=60; window_Y=0;
544 last_priority=-1;
546 copyPixmapArea(124, 0, 54, 9, 65, 5);
547 copyPixmapArea(142, 9, 18, 9, 83, 5);
548 copyPixmapArea(123, 89, 6, 7, 65, 17);
549 copyPixmapArea(129, 89, 6, 7, 113, 17);
550 copyPixmapArea(124, 18, 36, 7, 74, 17);
551 copyPixmapArea(124, 18, 54, 32, 65, 27);
553 if(f==NULL) break;
555 t=time(NULL);
556 tm=localtime(&t);
557 bigbuf[0]='\0';
558 if(tm->tm_mon+1==f->month && tm->tm_mday==f->day){
559 if(f->hour<0) snprintf(bigbuf, BIGBUF_LEN, "TODAY");
560 else snprintf(bigbuf, BIGBUF_LEN, "TODAY %dL", f->hour);
561 } else {
562 x=tm->tm_mon+1;
563 y=tm->tm_mday+1;
564 fix_date(&x, &y, NULL, NULL);
565 if(x==f->month && y==f->day){
566 if(f->hour<0) snprintf(bigbuf, BIGBUF_LEN, "TOMORROW");
567 else snprintf(bigbuf, BIGBUF_LEN, "TMRW %dL", f->hour);
568 } else {
569 z=0;
570 if(f->wday!=-1){
571 for(z=0; z<5; z++){
572 y++;
573 fix_date(&x, &y, NULL, NULL);
574 if(x==f->month && y==f->day){
575 if(f->hour<0) snprintf(bigbuf, BIGBUF_LEN, "%s",
576 wdaynames[(int)f->wday]);
577 else snprintf(bigbuf, BIGBUF_LEN, "%.3s %dL",
578 wdaynames[(int)f->wday], f->hour);
579 z=99;
583 if(z<99 && f->month>0 && f->day>0){
584 if(f->hour<0)
585 snprintf(bigbuf, BIGBUF_LEN, "%.3s %d",
586 monthnames[(int)f->month], f->day);
587 else snprintf(bigbuf, BIGBUF_LEN, "%.3s %d %dL",
588 monthnames[(int)f->month], f->day,
589 f->hour);
593 x=GetStringWidth(bigbuf);
594 DrawString(60+(64-x)/2, 18, bigbuf, font);
596 x=GetStringWidth(f->station);
597 DrawString(118-x, 28, f->station, font+1);
599 if(f->high!=999 || f->low!=999){
600 DrawChar(104, 35, '/', font);
601 if(f->high!=999){
602 x=(temp_mode==0)?f->high:temp_F2C(f->high);
603 if(x<-99) x=-99;
604 if(x>199) x=199;
605 DrawNumber(103, 35, x, font);
607 if(f->low!=999){
608 x=(temp_mode==0)?f->low:temp_F2C(f->low);
609 if(x<-99) x=-99;
610 if(x>199) x=199;
611 DrawNumber(118, 35, x, font);
614 if(f->temp!=999){
615 x=(temp_mode==0)?f->temp:temp_F2C(f->temp);
616 if(x<-99) x=-99;
617 if(x>199) x=199;
618 snprintf(bigbuf, BIGBUF_LEN, "%d", x);
619 DrawString(92, 41, bigbuf, font);
621 if(f->rh!=-1){
622 DrawChar(115, 41, '%', font);
623 DrawNumber(114, 41, f->rh, font);
625 if(f->windspeed==0){
626 x=GetStringWidth("CALM");
627 DrawString(92+(26-x)/2, 47, "CALM", font);
628 } else {
629 if(f->winddir>=0 && f->winddir<=16){
630 x=GetStringWidth(directions[f->winddir]);
631 DrawString(105-x, 47, directions[f->winddir], font);
633 switch(windspeed_mode){
634 case 0:
635 x=knots2mph(f->windspeed);
636 break;
637 case 1:
638 x=knots2kph(f->windspeed);
639 break;
640 case 3:
641 x=knots2mps(f->windspeed);
642 break;
643 case 4:
644 x=knots2beaufort(f->windspeed);
645 break;
647 if(x>=0 && x<1000)
648 DrawNumber(118, 47, x, font);
651 anim.show_counter=show_counter;
652 anim.min_pct=min_pct;
653 SetAnimation(&anim, 65, 28, f->sky, f->obs, f->vis,
654 f->frz, f->snow, f->rain, f->tstorm, f->svtstorm,
655 f->moon);
657 case_1_end:
658 if(f==NULL || forecast_priority==last_priority) break;
660 /* This is a little tricky. We use the switch as a calculated goto
661 * (ick) to determine which order to try things in. Fall-through is
662 * intended. */
663 switch(forecast_priority){
664 default:
665 /* WTF? Oh well, just start at the beginning */
667 case 0:
668 if(f->heatindex>=80 && f->heatindex!=999){
669 copyPixmapArea(124, 18, 26, 5, 92, 53);
670 x=(temp_mode==0)?f->heatindex:temp_F2C(f->heatindex);
671 snprintf(bigbuf, BIGBUF_LEN, "HI: %d", x);
672 DrawString(92, 53, bigbuf, font);
673 forecast_priority=0;
674 break;
677 case 1:
678 if(f->windchill<=40 && f->windchill!=999){
679 copyPixmapArea(124, 18, 26, 5, 92, 53);
680 x=(temp_mode==0)?f->windchill:temp_F2C(f->windchill);
681 snprintf(bigbuf, BIGBUF_LEN, "WC: %d", x);
682 DrawString(92, 53, bigbuf, font);
683 forecast_priority=1;
684 break;
687 case 2:
688 if(f->snowamt>0){
689 copyPixmapArea(124, 18, 26, 5, 92, 53);
690 if(f->snowamt==1){ x=1; y=2; }
691 else if(f->snowamt==8){ x=8; y=-1; }
692 else { x=f->snowamt; y=x+2; }
693 if(length_mode==1){
694 x=in2cm(x); y=in2cm(y);
696 if(x>9 && y>9) x=9;
697 if(y==-1) snprintf(bigbuf, BIGBUF_LEN, "SN:>%d", x);
698 else snprintf(bigbuf, BIGBUF_LEN, "SN:%d-%d", x, y);
699 DrawString(92, 53, bigbuf, font);
700 forecast_priority=2;
701 break;
704 case 3:
705 if(f->precipamt>0){
706 copyPixmapArea(124, 18, 26, 5, 92, 53);
707 switch(f->precipamt){
708 case 1:
709 if(length_mode==0) DrawString(92, 53, "P:.01-.1", font);
710 if(length_mode==1) DrawString(92, 53, "P: 0-.25", font);
711 break;
712 case 2:
713 if(length_mode==0) DrawString(92, 53, "P:.1-.25", font);
714 if(length_mode==1) DrawString(92, 53, "P:.25-.6", font);
715 break;
716 case 3:
717 if(length_mode==0) DrawString(92, 53, "P:.25-.5", font);
718 if(length_mode==1) DrawString(92, 53, "P:.6-1.3", font);
719 break;
720 case 4:
721 if(length_mode==0) DrawString(92, 53, "P: .5-1", font);
722 if(length_mode==1) DrawString(92, 53, "P: 1-2.5", font);
723 break;
724 case 5:
725 if(length_mode==0) DrawString(92, 53, "P: 1-2", font);
726 if(length_mode==1) DrawString(92, 53, "P: 2.5-5", font);
727 break;
728 case 6:
729 if(length_mode==0) DrawString(92, 53, "P: >2", font);
730 if(length_mode==1) DrawString(92, 53, "P: >5", font);
731 break;
732 case 7:
733 if(length_mode==0) DrawString(92, 53, "P: >3", font);
734 if(length_mode==1) DrawString(92, 53, "P: >7.6", font);
735 break;
737 forecast_priority=3;
738 break;
741 case 4:
742 copyPixmapArea(124, 18, 26, 5, 92, 53);
743 x=GetStringWidth("<")+1;
744 y=GetStringWidth(f->ID)+1;
745 z=GetStringWidth(">");
746 DrawChar(118-x-y-z, 53, '<', font+1);
747 DrawString(118-y-z, 53, f->ID, font+1);
748 DrawChar(118-z, 53, '>', font+1);
749 forecast_priority=4;
750 break;
752 last_priority=forecast_priority;
753 break;
755 case 2:
756 if(last_time==radar_update_time) break;
757 last_time=radar_update_time;
758 EnableMouseRegion(3);
759 DisableMouseRegion(4);
760 DisableMouseRegion(5);
761 DisableMouseRegion(6);
762 DisableMouseRegion(7);
763 window_X=0; window_Y=0;
765 copyPixmapArea(124, 0, 54, 9, 5, 5);
766 copyPixmapArea(160, 9, 18, 9, 41, 5);
767 put_radar(6, 18, font);
769 anim.active=0;
770 break;
772 DoAnimation(&anim);