add casts to zune macros to silence some warnings
[tangerine.git] / workbench / prefs / locale / page_timezone.c
blobc828334a7c655700551bf1365f4ed8a1ddc806a5
1 /*
2 Copyright © 1995-2001, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang: English
7 */
9 /*********************************************************************************************/
11 #include "global.h"
12 #include <stdio.h>
14 #include "earthmap_small_image.c"
15 #include "timezones_small_image.c"
17 /*********************************************************************************************/
19 #define DOUBLE_ARROWS 1
21 #define CONTINENT_RED 18
22 #define CONTINENT_GREEN 114
23 #define CONTINENT_BLUE 58
25 #define OCEAN_RED 21
26 #define OCEAN_GREEN 18
27 #define OCEAN_BLUE 114
29 #define SELECTED_INTENSITY_INC 80
31 #define GAD_DEC 1000
32 #define GAD_INC 1001
33 #define GAD_TEXT 1002
35 /*********************************************************************************************/
37 #define NUM_TIMEZONES 36
39 static struct timezone
41 WORD id;
42 WORD minoffset;
43 WORD pen;
45 timezone_table[NUM_TIMEZONES] =
47 { 0, 0 }, /* Z : 0:00 */
48 { 1, 1 * 60 }, /* A : + 1:00 */
49 { 2, 2 * 60 }, /* B : + 2:00 */
50 { 3, 3 * 60 }, /* C : + 3:00 */
51 { 4, 3 * 60 + 30 }, /* C*: + 3:30 */
52 { 5, 4 * 60 }, /* D : + 4:00 */
53 { 6, 4 * 60 + 30 }, /* D*: + 4:30 */
54 { 7, 5 * 60 }, /* E : + 5:00 */
55 { 8, 5 * 60 + 30 }, /* E*: + 5:30 */
56 { 9, 6 * 60 }, /* F : + 6:00 */
57 { 10, 6 * 60 + 30 }, /* F*: + 6:30 */
58 { 11, 7 * 60 }, /* G : + 7:00 */
59 { 12, 8 * 60 }, /* H : + 8:00 */
60 { 13, 9 * 60 }, /* I : + 9:00 */
61 { 14, 9 * 60 + 30 }, /* I*: + 9:30 */
62 { 15, 10 * 60 }, /* K : + 10:00 */
63 { 16, 10 * 60 + 30 }, /* K*: + 10:30 */
64 { 17, 11 * 60 }, /* L : + 11:00 */
65 { 18, 11 * 60 + 30 }, /* L*: + 11:30 */
66 { 19, 12 * 60 }, /* M : + 12:00 */
67 { 20, 13 * 60 }, /* M*: + 13:00 */
68 { 35, -12 * 60 }, /* Y : - 12:00 */
69 { 34, -11 * 60 }, /* X : - 11:00 */
70 { 33, -10 * 60 }, /* W : - 10:00 */
71 { 32, -9 * 60 - 30 }, /* V*: - 9:30 */
72 { 31, -9 * 60 }, /* V : - 9:00 */
73 { 30, -8 * 60 - 30 }, /* U*: - 8:30 */
74 { 29, -8 * 60 }, /* U : - 8:00 */
75 { 28, -7 * 60 }, /* T : - 7:00 */
76 { 27, -6 * 60 }, /* S : - 6:00 */
77 { 26, -5 * 60 }, /* R : - 5:00 */
78 { 25, -4 * 60 }, /* Q : - 4:00 */
79 { 24, -3 * 60 - 30 }, /* P*: - 3:30 */
80 { 23, -3 * 60 }, /* P : - 3:00 */
81 { 22, -2 * 60 }, /* O : - 2:00 */
82 { 21, -1 * 60 }, /* N : - 1:00 */
86 /*********************************************************************************************/
88 static struct Gadget *gadlist, *textgad, *gad;
89 static WORD minwidth, minheight;
90 static WORD domleft, domtop, domwidth, domheight;
91 static WORD active_timezone;
92 static BOOL init_done;
94 static UBYTE timezones_chunky[TIMEZONES_SMALL_WIDTH * TIMEZONES_SMALL_HEIGHT];
95 static UBYTE earthmap_chunky[EARTHMAP_SMALL_WIDTH * EARTHMAP_SMALL_HEIGHT];
96 static UBYTE *earthmap_chunky_remapped;
98 static ULONG earthmap_coltab[256];
99 static WORD remaptable[256];
100 static UBYTE timezone_text[256];
101 static WORD pen2index[NUM_TIMEZONES];
103 static BOOL pens_alloced, page_active;
105 /*********************************************************************************************/
107 #if EARTHMAP_SMALL_PACKED || TIMEZONES_SMALL_PACKED
109 static UBYTE *unpack_byterun1(UBYTE *source, UBYTE *dest, LONG unpackedsize)
111 UBYTE r;
112 BYTE c;
114 for(;;)
116 c = (BYTE)(*source++);
117 if (c >= 0)
119 while(c-- >= 0)
121 *dest++ = *source++;
122 if (--unpackedsize <= 0) return source;
125 else if (c != -128)
127 c = -c;
128 r = *source++;
130 while(c-- >= 0)
132 *dest++ = r;
133 if (--unpackedsize <= 0) return source;
140 #endif
142 /*********************************************************************************************/
144 static LONG timezone_init(void)
146 WORD i;
148 if (!truecolor)
150 earthmap_chunky_remapped = AllocVec(EARTHMAP_SMALL_WIDTH * EARTHMAP_SMALL_HEIGHT, MEMF_PUBLIC);
151 if (!earthmap_chunky_remapped) return FALSE;
154 #if EARTHMAP_SMALL_PACKED
155 unpack_byterun1(earthmap_small_data, earthmap_chunky, EARTHMAP_SMALL_WIDTH * EARTHMAP_SMALL_HEIGHT);
156 #endif
157 #if TIMEZONES_SMALL_PACKED
158 unpack_byterun1(timezones_small_data, timezones_chunky, TIMEZONES_SMALL_WIDTH * TIMEZONES_SMALL_HEIGHT);
159 #endif
162 for(i = 0; i < EARTHMAP_SMALL_COLORS; i++)
164 static struct TagItem obp_tags[] =
166 {OBP_Precision, PRECISION_IMAGE },
167 {OBP_FailIfBad, FALSE },
168 {TAG_DONE }
170 ULONG rgb = earthmap_small_pal[i];
171 ULONG r = (rgb & 0xFF0000) >> 16;
172 ULONG g = (rgb & 0x00FF00) >> 8;
173 ULONG b = (rgb & 0x0000FF);
174 ULONG a = (r + g + b) / 3;
176 r = (a * OCEAN_RED + (255 - a) * CONTINENT_RED ) / 255;
177 g = (a * OCEAN_GREEN + (255 - a) * CONTINENT_GREEN) / 255;
178 b = (a * OCEAN_BLUE + (255 - a) * CONTINENT_BLUE ) / 255;
180 rgb = (r << 16) + (g << 8) + b;
182 earthmap_coltab[i] = rgb;
184 if (!truecolor)
186 remaptable[i] = ObtainBestPenA(scr->ViewPort.ColorMap,
187 r * 0x01010101,
188 g * 0x01010101,
189 b * 0x01010101,
190 obp_tags);
193 r += SELECTED_INTENSITY_INC; if (r > 255) r = 255;
194 g += SELECTED_INTENSITY_INC; if (g > 255) g = 255;
195 b += SELECTED_INTENSITY_INC; if (b > 255) b = 255;
197 rgb = (r << 16) + (g << 8) + b;
199 earthmap_coltab[128 + i] = rgb;
201 if (!truecolor)
203 remaptable[128 + i] = ObtainBestPenA(scr->ViewPort.ColorMap,
204 r * 0x01010101,
205 g * 0x01010101,
206 b * 0x01010101,
207 obp_tags);
212 if (!truecolor) pens_alloced = TRUE;
214 /* For each timezone find out, with which pen (index) it is
215 represented in the timezones image */
217 for(i = 0; i < NUM_TIMEZONES; i++)
219 WORD id = timezone_table[i].id;
220 WORD i2;
221 ULONG r = ((id & 0x30) >> 4) * 64;
222 ULONG g = ((id & 0x0C) >> 2) * 64;
223 ULONG b = ((id & 0x03) ) * 64;
224 ULONG rgb = (r << 16) + (g << 8) + b;
226 timezone_table[i].pen = -1;
227 for(i2 = 0; i2 < TIMEZONES_SMALL_COLORS; i2++)
229 if (timezones_small_pal[i2] == rgb)
231 timezone_table[i].pen = i2;
232 break;
236 pen2index[id] = i;
239 init_done = TRUE;
241 return TRUE;
244 /*********************************************************************************************/
246 static void ClearEarthmapSelection(void)
248 LONG l;
250 for(l = 0; l < EARTHMAP_SMALL_WIDTH * EARTHMAP_SMALL_HEIGHT; l++)
252 earthmap_chunky[l] &= 127;
256 /*********************************************************************************************/
258 static void SetEarthmapSelection(UBYTE timezonespen)
260 LONG l;
262 for(l = 0; l < EARTHMAP_SMALL_WIDTH * EARTHMAP_SMALL_HEIGHT; l++)
264 if (timezones_chunky[l] == timezonespen) earthmap_chunky[l] |= 128;
268 /*********************************************************************************************/
270 static void RepaintEarthmap(void)
272 if (page_active)
274 CONST_STRPTR fmt;
275 WORD minoffset;
277 minoffset = timezone_table[active_timezone].minoffset;
278 if (minoffset < 0) minoffset = -minoffset;
280 if (truecolor)
282 WriteLUTPixelArray(earthmap_chunky,
285 EARTHMAP_SMALL_WIDTH,
286 win->RPort,
287 earthmap_coltab,
288 domleft + 1,
289 domtop + 1,
290 EARTHMAP_SMALL_WIDTH,
291 EARTHMAP_SMALL_HEIGHT,
292 CTABFMT_XRGB8);
294 else
296 LONG l;
298 for(l = 0; l < EARTHMAP_SMALL_WIDTH * EARTHMAP_SMALL_HEIGHT; l++)
300 earthmap_chunky_remapped[l] = remaptable[earthmap_chunky[l]];
303 WriteChunkyPixels(win->RPort,
304 domleft + 1,
305 domtop + 1,
306 domleft + 1 + EARTHMAP_SMALL_WIDTH - 1,
307 domtop + 1 + EARTHMAP_SMALL_HEIGHT - 1,
308 earthmap_chunky_remapped,
309 EARTHMAP_SMALL_WIDTH);
312 if (minoffset == 60)
314 fmt = MSG(MSG_TIMEZONE_1HOUR);
316 else if (minoffset % 60)
318 fmt = MSG(MSG_TIMEZONE_HOURSMINS);
320 else
322 fmt = MSG(MSG_TIMEZONE_HOURS);
325 sprintf(timezone_text, fmt, minoffset / 60, minoffset % 60);
327 GT_SetGadgetAttrs(textgad, win, NULL, GTTX_Text, (IPTR)timezone_text,
328 TAG_DONE);
330 } /* if (page_active) */
333 /*********************************************************************************************/
335 static void scroll_timezone(WORD delta)
337 active_timezone += delta;
339 if (active_timezone < 0)
341 active_timezone = NUM_TIMEZONES - 1;
343 else if (active_timezone >= NUM_TIMEZONES)
345 active_timezone = 0;
348 ClearEarthmapSelection();
349 SetEarthmapSelection(timezone_table[active_timezone].pen);
350 RepaintEarthmap();
353 /*********************************************************************************************/
355 static LONG timezone_input(struct IntuiMessage *msg)
357 LONG retval = FALSE;
359 if ((msg->Class == IDCMP_MOUSEBUTTONS) && (msg->Code == SELECTDOWN))
361 WORD x = msg->MouseX - (domleft + 1);
362 WORD y = msg->MouseY - (domtop + 1);
364 if ((x >= 0) &&
365 (y >= 0) &&
366 (x <= domwidth - 2) &&
367 (y <= domheight - 2))
369 ULONG timezonergb;
370 LONG timezoneid;
371 UBYTE timezonepen;
373 retval = TRUE;
375 timezonepen = timezones_chunky[y * TIMEZONES_SMALL_WIDTH + x];
376 timezonergb = timezones_small_pal[timezonepen];
377 timezoneid = (timezonergb & 0xC00000) >> (16 + 2);
378 timezoneid += (timezonergb & 0x00C000) >> (8 + 4);
379 timezoneid += (timezonergb & 0x0000C0) >> (0 + 6);
381 if ((timezoneid >= 0) && (timezoneid < NUM_TIMEZONES))
383 active_timezone = pen2index[timezoneid];
385 /* AmigaOS seems to have the sign the other way round, therefore the "-" */
387 localeprefs.lp_GMTOffset = -timezone_table[active_timezone].minoffset;
389 ClearEarthmapSelection();
390 SetEarthmapSelection(timezonepen);
391 RepaintEarthmap();
398 else if ((msg->Class == IDCMP_RAWKEY))
400 switch(msg->Code)
402 case CURSORLEFT:
403 scroll_timezone(-1);
404 retval = TRUE;
405 break;
407 case CURSORRIGHT:
408 scroll_timezone(1);
409 retval = TRUE;
410 break;
414 else if ((msg->Class == IDCMP_GADGETUP))
416 struct Gadget *gad = (struct Gadget *)msg->IAddress;
418 switch(gad->GadgetID)
420 case GAD_DEC:
421 scroll_timezone(-1);
422 retval = TRUE;
423 break;
425 case GAD_INC:
426 scroll_timezone(1);
427 retval = TRUE;
428 break;
432 return retval;
435 /*********************************************************************************************/
437 static void timezone_cleanup(void)
439 WORD i;
441 if (earthmap_chunky_remapped)
443 FreeVec(earthmap_chunky_remapped);
444 earthmap_chunky_remapped = NULL;
447 if (pens_alloced)
449 for(i = 0; i < EARTHMAP_SMALL_COLORS; i++)
451 if (remaptable[i] != -1) ReleasePen(scr->ViewPort.ColorMap, remaptable[i]);
452 if (remaptable[128 + i] != -1) ReleasePen(scr->ViewPort.ColorMap, remaptable[128 + i]);
454 pens_alloced = FALSE;
457 if (gadlist) FreeGadgets(gadlist);
458 gadlist = NULL;
461 /*********************************************************************************************/
463 static LONG timezone_makegadgets(void)
465 struct NewGadget ng;
466 WORD w;
468 w = dri->dri_Font->tf_XSize + 8;
470 gad = CreateContext(&gadlist);
472 ng.ng_LeftEdge = domleft;
473 ng.ng_TopEdge = domtop + EARTHMAP_SMALL_HEIGHT + 2 + SPACE_Y;
474 ng.ng_Width = w;
475 ng.ng_Height = dri->dri_Font->tf_YSize + BUTTON_EXTRAHEIGHT;
476 ng.ng_GadgetText = "<";
477 ng.ng_TextAttr = 0;
478 ng.ng_GadgetID = GAD_DEC;
479 ng.ng_Flags = 0;
480 ng.ng_VisualInfo = vi;
482 gad = CreateGadgetA(BUTTON_KIND, gad, &ng, NULL);
484 #if DOUBLE_ARROWS
485 ng.ng_LeftEdge = domleft + domwidth - w - w;
487 gad = CreateGadgetA(BUTTON_KIND, gad, &ng, NULL);
488 #endif
490 ng.ng_LeftEdge = domleft + domwidth - w;
491 ng.ng_GadgetText = ">";
492 ng.ng_GadgetID = GAD_INC;
494 gad = CreateGadgetA(BUTTON_KIND, gad, &ng, NULL);
496 #if DOUBLE_ARROWS
497 ng.ng_LeftEdge = domleft + w;
499 gad = CreateGadgetA(BUTTON_KIND, gad, &ng, NULL);
500 #endif
503 #if DOUBLE_ARROWS
504 ng.ng_LeftEdge = domleft + w * 2 + SPACE_X;
505 ng.ng_Width = domwidth - w * 4 - SPACE_X * 2;
506 #else
507 ng.ng_LeftEdge = domleft + w + SPACE_X;
508 ng.ng_Width = domwidth - w * 2 - SPACE_X * 2;
509 #endif
510 ng.ng_GadgetID = GAD_TEXT;
511 ng.ng_GadgetText = NULL;
513 gad = textgad = CreateGadget(TEXT_KIND, gad, &ng, GTTX_Border , TRUE ,
514 GTTX_Clipped , TRUE ,
515 GTTX_Text , (IPTR)"hello" ,
516 GTTX_Justification, GTJ_CENTER ,
517 TAG_DONE);
518 return gad ? TRUE : FALSE;
521 /*********************************************************************************************/
523 static void timezone_prefs_changed(void)
525 WORD i;
527 for(i = 0; i < NUM_TIMEZONES; i++)
529 /* AmigaOS seems to have the sign the other way round, therefore the "-" */
531 if (-localeprefs.lp_GMTOffset == timezone_table[i].minoffset)
533 active_timezone = i;
534 break;
538 if (init_done)
540 ClearEarthmapSelection();
541 SetEarthmapSelection(timezone_table[active_timezone].pen);
542 RepaintEarthmap();
547 /*********************************************************************************************/
549 static void DrawEarthmapFrame(void)
551 SetDrMd(win->RPort, JAM1);
553 SetAPen(win->RPort, dri->dri_Pens[SHADOWPEN]);
555 RectFill(win->RPort, domleft,
556 domtop,
557 domleft + domwidth - 2,
558 domtop);
560 RectFill(win->RPort, domleft,
561 domtop + 1,
562 domleft,
563 domtop + EARTHMAP_SMALL_HEIGHT + 2 - 1);
565 SetAPen(win->RPort, dri->dri_Pens[SHINEPEN]);
567 RectFill(win->RPort, domleft + domwidth - 1,
568 domtop,
569 domleft + domwidth - 1,
570 domtop + EARTHMAP_SMALL_HEIGHT + 2 - 1);
572 RectFill(win->RPort, domleft + 1,
573 domtop + EARTHMAP_SMALL_HEIGHT + 2 - 1,
574 domleft + domwidth - 2,
575 domtop + EARTHMAP_SMALL_HEIGHT + 2 - 1);
578 /*********************************************************************************************/
580 LONG page_timezone_handler(LONG cmd, IPTR param)
582 LONG retval = TRUE;
584 switch(cmd)
586 case PAGECMD_INIT:
587 retval = timezone_init();
588 break;
590 case PAGECMD_LAYOUT:
591 minwidth = EARTHMAP_SMALL_WIDTH + 2;
592 minheight = EARTHMAP_SMALL_HEIGHT + 2 + dri->dri_Font->tf_YSize + BUTTON_EXTRAHEIGHT + SPACE_Y;
593 break;
595 case PAGECMD_GETMINWIDTH:
596 retval = minwidth;
597 break;
599 case PAGECMD_GETMINHEIGHT:
600 retval = minheight;
601 break;
603 case PAGECMD_SETDOMLEFT:
604 domleft = param;
605 break;
607 case PAGECMD_SETDOMTOP:
608 domtop = param;
609 break;
611 case PAGECMD_SETDOMWIDTH:
612 /* domwidth = param; */
613 domwidth = minwidth;
614 domleft += (param - minwidth ) /2;
615 break;
617 case PAGECMD_SETDOMHEIGHT:
618 /* domheight = param; */
619 domheight = minheight;
620 domtop += (param - minheight) / 2;
621 break;
623 case PAGECMD_MAKEGADGETS:
624 retval = timezone_makegadgets();
625 break;
627 case PAGECMD_ADDGADGETS:
628 if (!page_active)
630 DrawEarthmapFrame();
632 AddGList(win, gadlist, -1, -1, NULL);
633 GT_RefreshWindow(win, NULL);
634 RefreshGList(gadlist, win, NULL, -1);
636 ClearEarthmapSelection();
637 SetEarthmapSelection(timezone_table[active_timezone].pen);
639 page_active = TRUE;
641 RepaintEarthmap();
643 break;
645 case PAGECMD_REMGADGETS:
646 if (page_active)
648 if (gadlist) RemoveGList(win, gadlist, -1);
650 page_active = FALSE;
652 break;
654 case PAGECMD_REFRESH:
655 DrawEarthmapFrame();
656 RepaintEarthmap();
657 break;
659 case PAGECMD_HANDLEINPUT:
660 retval = timezone_input((struct IntuiMessage *)param);
661 break;
663 case PAGECMD_PREFS_CHANGED:
664 timezone_prefs_changed();
665 break;
667 case PAGECMD_CLEANUP:
668 timezone_cleanup();
669 break;
672 return retval;